commit 0971579b5b512c52f6f3cc1623e9f1670d222387
Author: Erez_Zadok <[EMAIL PROTECTED]>
Date: Sat Nov 17 22:34:55 2007 -0500
Unionfs: cache coherency after lower objects are removed
Prevent an oops if a lower file is deleted and then it is stat'ed from the
upper layer. Ensure that we return a negative dentry so the user will get
an ENOENT. Properly dput/mntput so we don't leak references at the lower
file system.
Signed-off-by: Erez Zadok <[EMAIL PROTECTED]>
diff --git a/fs/unionfs/lookup.c b/fs/unionfs/lookup.c
index 92f7f3b..91a36a9 100644
--- a/fs/unionfs/lookup.c
+++ b/fs/unionfs/lookup.c
@@ -41,7 +41,7 @@ struct dentry *unionfs_lookup_backend(struct dentry *dentry,
struct dentry *lower_dir_dentry = NULL;
struct dentry *parent_dentry = NULL;
struct dentry *d_interposed = NULL;
- int bindex, bstart, bend, bopaque = -1;
+ int bindex, bstart = -1, bend, bopaque = -1;
int dentry_count = 0; /* Number of positive dentries. */
int first_dentry_offset = -1; /* -1 is uninitialized */
struct dentry *first_dentry = NULL;
@@ -347,7 +347,14 @@ out:
if (!err && UNIONFS_D(dentry)) {
BUG_ON(dbend(dentry) > UNIONFS_D(dentry)->bcount);
BUG_ON(dbend(dentry) > sbmax(dentry->d_sb));
- BUG_ON(dbstart(dentry) < 0);
+ if (dbstart(dentry) < 0 &&
+ dentry->d_inode && bstart >= 0 &&
+ (!UNIONFS_I(dentry->d_inode) ||
+ !UNIONFS_I(dentry->d_inode)->lower_inodes)) {
+ unionfs_mntput(dentry->d_sb->s_root, bstart);
+ dput(first_lower_dentry);
+ UNIONFS_I(dentry->d_inode)->stale = 1;
+ }
}
if (locked_parent)
unionfs_unlock_dentry(parent_dentry);
@@ -356,6 +363,9 @@ out:
unionfs_unlock_dentry(dentry);
if (!err && d_interposed)
return d_interposed;
+ if (dentry->d_inode && UNIONFS_I(dentry->d_inode)->stale &&
+ first_dentry_offset >= 0)
+ unionfs_mntput(dentry->d_sb->s_root, first_dentry_offset);
return ERR_PTR(err);
}
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs