commit 68bd159590c6b1e0668f0884a8464cd4adf24f59
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Wed May 30 19:49:25 2007 -0400

    export: bugfix, oopsing in d_revalidate when client gets ESTALE
    
    with nfs exporting, when the cache is dropped on the server decode_fh will
    most likely return ESTALE to the client. On such cases the server can get
    a disconnected dentry in unionfs_open and a connected dentry in d_revalidate
    but with ibstart to -1. This fix just detects those cases and returns an err
    in order to stop the oopsing. However the file becomes unusable in the 
client,
    any attempt to read it will return ESTALE. The best way to fix this will
    be to implement decode_fh and make sure invariants are kept when an inode
    becomes stale

diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c
index 
b9bc33badf65ab710078b78cded2b051f4425d89..52b01438ade66ad5fe8c6e1a36dd295bf5c1fc99
 100644
--- a/fs/unionfs/commonfops.c
+++ b/fs/unionfs/commonfops.c
@@ -611,6 +611,17 @@ int unionfs_open(struct inode *inode, st
        }
 
        dentry = file->f_dentry;
+
+       /* FIXME: With nfs exporting we can get a disconnected dentry here.
+        * This can happen if the dcache is dropped on the server while the
+        * client is working, and export ops decodefh returns ESTALE to the
+        * user. It would best to catch this by implementing decodefh
+        * or maybe we could connect the dentry ourselves using getparent?
+        */
+       if (dentry->d_flags & DCACHE_DISCONNECTED) {
+               err = -ESTALE;
+               goto out;
+       }
        unionfs_lock_dentry(dentry);
 
        bstart = fbstart(file) = dbstart(dentry);
diff --git a/fs/unionfs/dentry.c b/fs/unionfs/dentry.c
index 
c9ff88676db211d7daaf2819349400a67b020a20..f84911cdde8b2b7dcb2fd7c8fbb1d92ef5b46906
 100644
--- a/fs/unionfs/dentry.c
+++ b/fs/unionfs/dentry.c
@@ -37,6 +37,20 @@ static int __unionfs_d_revalidate_one(st
        int interpose_flag;
        struct nameidata lowernd; /* TODO: be gentler to the stack */
 
+       /* FIXME: with nfs exporting, if export ops fails to connect a dentry
+        * and returns ESTALE to the client, we can end up with an inode that
+        * has ibstart -1. This fix only stops the oopsing but the dentry will
+        * become unusable on the client, it will keep getting ESTALE on any
+        * attempt to fix it. The best way to fix this is by implementing
+        * decode_fh and making sure no inode gets left with -1 ibstart
+        */
+       if (dentry->d_inode && ibstart(dentry->d_inode) < 0) {
+               valid = 0;
+               make_bad_inode(dentry->d_inode);
+               d_drop(dentry);
+               goto out;
+       }
+
        if (nd)
                memcpy(&lowernd, nd, sizeof(struct nameidata));
        else
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to