commit 7de01cabadbb93cc5ed7aecd76150eb59be783b5
Author: Erez_Zadok <[EMAIL PROTECTED]>
Date: Wed May 30 20:14:07 2007 -0400
bugfix: ensure dentry/inode/mnt validity after a successful ioctl
We call unionfs_partial_lookup in our queryfile ioctl method, so we can find
all instances of a lower object to report back to a suer. This can violate
the fanout invariants (e.g., a regular file should have only one lower
object active at a time). So we have to re-establish the invariants on the
lower dentries, inodes, and mnts.
Signed-off-by: Erez Zadok <[EMAIL PROTECTED]>
diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c
index
db77412ddf550bb9dc0cf35087559f1ad4845f65..8ef583684d7699fa0f0ddb6db6bfbac325962e48
100644
--- a/fs/unionfs/commonfops.c
+++ b/fs/unionfs/commonfops.c
@@ -757,10 +757,14 @@ static int unionfs_ioctl_queryfile(struc
int err = 0;
fd_set branchlist;
int bstart = 0, bend = 0, bindex = 0;
+ int orig_bstart, orig_bend;
struct dentry *dentry, *hidden_dentry;
+ struct vfsmount *mnt;
dentry = file->f_dentry;
unionfs_lock_dentry(dentry);
+ orig_bstart = dbstart(dentry);
+ orig_bend = dbend(dentry);
if ((err = unionfs_partial_lookup(dentry)))
goto out;
bstart = dbstart(dentry);
@@ -774,7 +778,24 @@ static int unionfs_ioctl_queryfile(struc
continue;
if (hidden_dentry->d_inode)
FD_SET(bindex, &branchlist);
+ /* purge any lower objects after partial_lookup */
+ if (bindex < orig_bstart || bindex > orig_bend) {
+ dput(hidden_dentry);
+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
+ iput(unionfs_lower_inode_idx(dentry->d_inode, bindex));
+ unionfs_set_lower_inode_idx(dentry->d_inode, bindex,
+ NULL);
+ mnt = unionfs_lower_mnt_idx(dentry, bindex);
+ if (!mnt)
+ continue;
+ unionfs_mntput(dentry, bindex);
+ unionfs_set_lower_mnt_idx(dentry, bindex, NULL);
+ }
}
+ /* restore original dentry's offsets */
+ set_dbstart(dentry, orig_bstart);
+ set_dbend(dentry, orig_bend);
+ ibstart(dentry->d_inode) = ibend(dentry->d_inode) = orig_bend;
err = copy_to_user((void __user *)arg, &branchlist, sizeof(fd_set));
if (err)
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs