From: Erez Zadok <[EMAIL PROTECTED]>

Properly update lower objects, and release lower mnts upon ioctl success or
failure.

Signed-off-by: Erez Zadok <[EMAIL PROTECTED]>
Signed-off-by: Josef 'Jeff' Sipek <[EMAIL PROTECTED]>
---
 fs/unionfs/commonfops.c |   25 +++++++++++++++++++++++--
 1 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c
index 1050c49..eee68b8 100644
--- a/fs/unionfs/commonfops.c
+++ b/fs/unionfs/commonfops.c
@@ -684,12 +684,15 @@ static int unionfs_ioctl_queryfile(struct file *file, 
unsigned int cmd,
 {
        int err = 0;
        fd_set branchlist;
-
        int bstart = 0, bend = 0, bindex = 0;
+       int orig_bstart, orig_bend;
        struct dentry *dentry, *lower_dentry;
+       struct vfsmount *mnt;
 
-       dentry = file->f_dentry;
+       dentry = file->f_path.dentry;
        unionfs_lock_dentry(dentry);
+       orig_bstart = dbstart(dentry);
+       orig_bend = dbend(dentry);
        if ((err = unionfs_partial_lookup(dentry)))
                goto out;
        bstart = dbstart(dentry);
@@ -703,7 +706,25 @@ static int unionfs_ioctl_queryfile(struct file *file, 
unsigned int cmd,
                        continue;
                if (lower_dentry->d_inode)
                        FD_SET(bindex, &branchlist);
+               /* purge any lower objects after partial_lookup */
+               if (bindex < orig_bstart || bindex > orig_bend) {
+                       dput(lower_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) = orig_bstart;
+       ibend(dentry->d_inode) = orig_bend;
 
        err = copy_to_user((void __user *)arg, &branchlist, sizeof(fd_set));
        if (err)
-- 
1.5.2.2.238.g7cbf2f2

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to