commit a6bedff1dfbb1e60b179ae1ce60a81b7105665e7
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Tue May 22 12:33:10 2007 -0400

    link and rename invariants when new_dentry is negative and link/rename 
happens on
    
    a branch other than leftmost

diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c
index b5d4a2e..4f4650e 100644
--- a/fs/unionfs/inode.c
+++ b/fs/unionfs/inode.c
@@ -177,9 +177,16 @@ static int unionfs_link(struct dentry *old_dentry, struct 
inode *dir,
                        dbstart(new_dentry) == dbend(new_dentry) &&
                        (!unionfs_lower_dentry_idx(new_dentry, 0) ||
                        !unionfs_lower_dentry_idx(new_dentry, 0)->d_inode)) {
+
                        set_dbstart(new_dentry, dbstart(old_dentry));
                        set_dbend(new_dentry, dbstart(old_dentry));
                        create_p = 1;
+                       dput(unionfs_lower_dentry_idx(new_dentry, 0));
+                       unionfs_set_lower_dentry_idx(new_dentry, 0, NULL);
+                       if (unionfs_lower_mnt_idx(new_dentry, 0)) {
+                               unionfs_mntput(new_dentry, 0);
+                               unionfs_set_lower_mnt_idx(new_dentry, 0, NULL);
+                       }
 
                }
                else {
diff --git a/fs/unionfs/rename.c b/fs/unionfs/rename.c
index 986ff11..9f0214e 100644
--- a/fs/unionfs/rename.c
+++ b/fs/unionfs/rename.c
@@ -30,7 +30,7 @@ int copyup_empty_dir(struct inode *parent, struct dentry 
*dentry, int mode)
 
        hidden_dentry = unionfs_lower_dentry_idx(dentry, bindex);
        if (!hidden_dentry) {
-               hidden_dentry = create_parents(parent, dentry, 
+               hidden_dentry = create_parents(parent, dentry,
                                                dentry->d_name.name, bindex);
                if (!hidden_dentry || IS_ERR(hidden_dentry)) {
                        printk(KERN_DEBUG "hidden dentry NULL for "
@@ -167,6 +167,12 @@ static int do_unionfs_rename(struct inode *old_dir,
                        set_dbend(new_dentry, old_bend);
                        new_bstart = old_bstart;
                        new_bend = old_bend;
+                       dput(unionfs_lower_dentry_idx(new_dentry, 0));
+                       unionfs_set_lower_dentry_idx(new_dentry, 0, NULL);
+                       if (unionfs_lower_mnt_idx(new_dentry, 0)) {
+                               unionfs_mntput(new_dentry, 0);
+                               unionfs_set_lower_mnt_idx(new_dentry, 0, NULL);
+                       }
                }
        }
 
@@ -222,22 +228,6 @@ static int do_unionfs_rename(struct inode *old_dir,
                /* else, a whiteout will take care of everything */
        }
 
-       /* if new dentry did not exist but was succesfully renamed at a branch 
-        * other than branch 0, we must clear any dentries/mntgets before bstart
-        */
-       for (bindex = 0; bindex < dbstart(new_dentry); bindex++) {
-               if (unionfs_lower_dentry_idx(new_dentry, bindex)) {
-                       /* all dentries must be negative */
-                       BUG_ON(unionfs_lower_dentry_idx(new_dentry, 
bindex)->d_inode);
-                       dput(unionfs_lower_dentry_idx(new_dentry, bindex));
-                       unionfs_set_lower_dentry_idx(new_dentry, bindex, NULL);
-               }
-               if (unionfs_lower_mnt_idx(new_dentry, bindex)) {
-                       unionfs_mntput(new_dentry, bindex);
-                       unionfs_set_lower_mnt_idx(new_dentry, bindex, NULL);
-               }
-       }
-
        /* if all ok, rename in odf */
        err = odf_rename(old_dentry, new_dentry);
        BUG_ON(err);    /* odf should not fail */
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to