Post-copyup helper functions
authorErez Zadok <ezk@bigvaio.(none)>
Fri, 18 May 2007 05:31:14 +0000 (01:31 -0400)
committerErez Zadok <ezk@cs.sunysb.edu>
Mon, 12 Jan 2009 23:20:25 +0000 (18:20 -0500)
Two functions which are very useful to execute common actions needed after a
copy-up had taken place.

fs/unionfs/copyup.c
fs/unionfs/union.h

index bed2419fd7c851aa665fdfa61f06b3b2a671ca71..2cf1878237a1a3e5989ef8c7056394f6f48ab0c4 100644 (file)
@@ -798,3 +798,51 @@ out:
        kfree(path);
        return hidden_dentry;
 }
+
+/* set lower mnt of dentry+parents to the first parent node that has an mnt */
+void unionfs_inherit_mnt(struct dentry *dentry)
+{
+       struct dentry *parent, *hasone;
+       int bindex = dbstart(dentry);
+
+       if (unionfs_lower_mnt_idx(dentry, bindex))
+               return;
+       hasone = dentry->d_parent;
+       /* this loop should stop at root dentry */
+       while (!unionfs_lower_mnt_idx(hasone, bindex)) {
+               hasone = hasone->d_parent;
+       }
+       parent = dentry;
+       while (!unionfs_lower_mnt_idx(parent, bindex)) {
+               unionfs_set_lower_mnt_idx(parent, bindex,
+                                         unionfs_mntget(hasone, bindex));
+               parent = parent->d_parent;
+       }
+}
+
+/*
+ * Regular files should have only one lower object(s).  On copyup, we may
+ * have leftover objects from previous branches.  So purge all such extra
+ * objects and keep only the most recent, leftmost, copied-up one.
+ */
+void unionfs_purge_extras(struct dentry *dentry)
+{
+       int bindex;
+
+       BUG_ON(S_ISDIR(dentry->d_inode->i_mode));
+       for (bindex=dbstart(dentry)+1; bindex<=dbend(dentry); bindex++) {
+               if (unionfs_lower_mnt_idx(dentry, bindex)) {
+                       unionfs_mntput(dentry, bindex);
+                       unionfs_set_lower_mnt_idx(dentry, bindex, NULL);
+               }
+               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);
+               }
+       }
+       bindex = dbstart(dentry);
+       set_dbend(dentry, bindex);
+       ibend(dentry->d_inode) = ibstart(dentry->d_inode) = bindex;
+}
index f645d5375e762232f3a1d0af49511fa7830367a2..7a4f62786955f9cd51ec8ad9f93267543631d856 100644 (file)
@@ -268,6 +268,9 @@ extern int copyup_named_file(struct inode *dir, struct file *file,
 extern int copyup_dentry(struct inode *dir, struct dentry *dentry, int bstart,
                         int new_bindex, struct file **copyup_file,
                         loff_t len);
+/* helper functions for post-copyup cleanup */
+extern void unionfs_inherit_mnt(struct dentry *dentry);
+extern void unionfs_purge_extras(struct dentry *dentry);
 
 extern int remove_whiteouts(struct dentry *dentry,
                            struct dentry *hidden_dentry, int bindex);