commit e7cc3e49cc78202090879340af8a5934cd8a2c7c
Author: Erez Zadok <[EMAIL PROTECTED]>
Date:   Mon Jul 28 02:38:41 2008 -0400

    Unionfs: create and consolidate helpers to iput lower objects
    
    Signed-off-by: Erez Zadok <[EMAIL PROTECTED]>

diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c
index c90c8b8..b499f13 100644
--- a/fs/unionfs/commonfops.c
+++ b/fs/unionfs/commonfops.c
@@ -279,16 +279,11 @@ static int do_delayed_copyup(struct file *file)
                        unionfs_set_lower_mnt_idx(dentry, bindex, NULL);
                }
                if (unionfs_lower_dentry_idx(dentry, bindex)) {
-                       BUG_ON(!dentry->d_inode);
-                       iput(unionfs_lower_inode_idx(dentry->d_inode, bindex));
-                       unionfs_set_lower_inode_idx(dentry->d_inode, bindex,
-                                                   NULL);
                        dput(unionfs_lower_dentry_idx(dentry, bindex));
                        unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
                }
-               /* regular files have only one open lower file */
-               fbend(file) = fbstart(file);
        }
+       iput_lowers(dentry->d_inode, bstart, bend, false);
        /* for reg file, we only open it "once" */
        fbend(file) = fbstart(file);
        dbend(dentry) = dbstart(dentry);
diff --git a/fs/unionfs/copyup.c b/fs/unionfs/copyup.c
index 53343bf..1c5b28f 100644
--- a/fs/unionfs/copyup.c
+++ b/fs/unionfs/copyup.c
@@ -874,11 +874,10 @@ void unionfs_postcopyup_release(struct dentry *dentry)
                if (unionfs_lower_dentry_idx(dentry, bindex)) {
                        dput(unionfs_lower_dentry_idx(dentry, bindex));
                        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);
                }
        }
+       iput_lowers(dentry->d_inode, dbstart(dentry)+1, dbend(dentry), false);
+
        bindex = dbstart(dentry);
        dbend(dentry) = bindex;
        ibend(dentry->d_inode) = ibstart(dentry->d_inode) = bindex;
diff --git a/fs/unionfs/dentry.c b/fs/unionfs/dentry.c
index c450f14..7780f3d 100644
--- a/fs/unionfs/dentry.c
+++ b/fs/unionfs/dentry.c
@@ -35,22 +35,6 @@ static inline void __dput_lowers(struct dentry *dentry, int 
start, int end)
        }
 }
 
-static inline void __iput_lowers(struct inode *inode, int start, int end)
-{
-       struct inode *lower_inode;
-       int bindex;
-
-       if (start < 0)
-               return;
-       for (bindex = start; bindex <= end; bindex++) {
-               lower_inode = unionfs_lower_inode_idx(inode, bindex);
-               if (!lower_inode)
-                       continue;
-               unionfs_set_lower_inode_idx(inode, bindex, NULL);
-               iput(lower_inode);
-       }
-}
-
 /*
  * Revalidate a single dentry.
  * Assume that dentry's info node is locked.
@@ -111,14 +95,7 @@ static bool __unionfs_d_revalidate_one(struct dentry 
*dentry,
                interpose_flag = INTERPOSE_REVAL_NEG;
                if (positive) {
                        interpose_flag = INTERPOSE_REVAL;
-
-                       bstart = ibstart(dentry->d_inode);
-                       bend = ibend(dentry->d_inode);
-                       __iput_lowers(dentry->d_inode, bstart, bend);
-                       kfree(UNIONFS_I(dentry->d_inode)->lower_inodes);
-                       UNIONFS_I(dentry->d_inode)->lower_inodes = NULL;
-                       ibstart(dentry->d_inode) = -1;
-                       ibend(dentry->d_inode) = -1;
+                       iput_lowers_all(dentry->d_inode, true);
                }
 
                result = unionfs_lookup_backend(dentry, &lowernd,
diff --git a/fs/unionfs/fanout.h b/fs/unionfs/fanout.h
index 3667d24..7495da8 100644
--- a/fs/unionfs/fanout.h
+++ b/fs/unionfs/fanout.h
@@ -278,4 +278,53 @@ static inline void verify_locked(struct dentry *d)
        BUG_ON(!mutex_is_locked(&UNIONFS_D(d)->lock));
 }
 
+/* macros to put lower objects */
+
+/*
+ * iput lower inodes of an unionfs dentry, from bstart to bend.  If
+ * @free_lower is true, then also kfree the memory used to hold the lower
+ * object pointers.
+ */
+static inline void iput_lowers(struct inode *inode,
+                              int bstart, int bend, bool free_lower)
+{
+       struct inode *lower_inode;
+       int bindex;
+
+       BUG_ON(!inode);
+       BUG_ON(!UNIONFS_I(inode));
+       BUG_ON(bstart < 0);
+
+       for (bindex = bstart; bindex <= bend; bindex++) {
+               lower_inode = unionfs_lower_inode_idx(inode, bindex);
+               if (lower_inode) {
+                       unionfs_set_lower_inode_idx(inode, bindex, NULL);
+                       /* see Documentation/filesystems/unionfs/issues.txt */
+                       lockdep_off();
+                       iput(lower_inode);
+                       lockdep_on();
+               }
+       }
+
+       if (free_lower) {
+               kfree(UNIONFS_I(inode)->lower_inodes);
+               UNIONFS_I(inode)->lower_inodes = NULL;
+       }
+}
+
+/* iput all lower inodes, and reset start/end branch indices to -1 */
+static inline void iput_lowers_all(struct inode *inode, bool free_lower)
+{
+       int bstart, bend;
+
+       BUG_ON(!inode);
+       BUG_ON(!UNIONFS_I(inode));
+       bstart = ibstart(inode);
+       bend = ibend(inode);
+       BUG_ON(bstart < 0);
+
+       iput_lowers(inode, bstart, bend, free_lower);
+       ibstart(inode) = ibend(inode) = -1;
+}
+
 #endif /* not _FANOUT_H */
diff --git a/fs/unionfs/super.c b/fs/unionfs/super.c
index ed9eff5..5ae6ede 100644
--- a/fs/unionfs/super.c
+++ b/fs/unionfs/super.c
@@ -778,11 +778,7 @@ out_no_change:
                new_lower_inodes[i] = lower_dentry->d_inode;
        }
        /* 2. release reference on all older lower inodes */
-       for (i = old_ibstart; i <= old_ibend; i++) {
-               iput(unionfs_lower_inode_idx(sb->s_root->d_inode, i));
-               unionfs_set_lower_inode_idx(sb->s_root->d_inode, i, NULL);
-       }
-       kfree(UNIONFS_I(sb->s_root->d_inode)->lower_inodes);
+       iput_lowers(sb->s_root->d_inode, old_ibstart, old_ibend, true);
        /* 3. update root dentry's inode to new lower_inodes array */
        UNIONFS_I(sb->s_root->d_inode)->lower_inodes = new_lower_inodes;
        new_lower_inodes = NULL;
diff --git a/fs/unionfs/unlink.c b/fs/unionfs/unlink.c
index cad0386..3d6ca5f 100644
--- a/fs/unionfs/unlink.c
+++ b/fs/unionfs/unlink.c
@@ -146,12 +146,8 @@ int unionfs_unlink(struct inode *dir, struct dentry 
*dentry)
        /* call d_drop so the system "forgets" about us */
        if (!err) {
                unionfs_postcopyup_release(dentry);
-               if (inode->i_nlink == 0) {
-                       /* drop lower inodes */
-                       iput(unionfs_lower_inode(inode));
-                       unionfs_set_lower_inode(inode, NULL);
-                       ibstart(inode) = ibend(inode) = -1;
-               }
+               if (inode->i_nlink == 0) /* drop lower inodes */
+                       iput_lowers_all(inode, false);
                d_drop(dentry);
                /*
                 * if unlink/whiteout succeeded, parent dir mtime has
@@ -264,21 +260,9 @@ out:
         * about us.
         */
        if (!err) {
-               struct inode *inode = dentry->d_inode;
-               BUG_ON(!inode);
-               iput(unionfs_lower_inode_idx(inode, dstart));
-               unionfs_set_lower_inode_idx(inode, dstart, NULL);
+               iput_lowers_all(dentry->d_inode, false);
                dput(unionfs_lower_dentry_idx(dentry, dstart));
                unionfs_set_lower_dentry_idx(dentry, dstart, NULL);
-               /*
-                * If the last directory is unlinked, then mark istart/end
-                * as -1, (to maintain the invariant that if there are no
-                * lower objects, then branch index start and end are set to
-                * -1).
-                */
-               if (!unionfs_lower_inode_idx(inode, dstart) &&
-                   !unionfs_lower_inode_idx(inode, dend))
-                       ibstart(inode) = ibend(inode) = -1;
                d_drop(dentry);
                /* update our lower vfsmnts, in case a copyup took place */
                unionfs_postcopyup_setmnt(dentry);
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to