commit 462071d4477739dd7c343002fc61814ecb17a009
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Sat Mar 17 20:40:58 2007 -0400

    cleanup thread to always cleanup odf/ic whenever it wakes up.
    
    odf_lookup wakes up cleanup thread when out of space
    added an odf_sb_info field to odf_dentry_info (for locking whole odf)

diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c
index 988f703..2abb6f3 100644
--- a/fs/unionfs/dirhelper.c
+++ b/fs/unionfs/dirhelper.c
@@ -60,6 +60,8 @@ struct unionfs_rmdir_callback {
        int filldir_called;
        struct dentry *dir;
        struct vfsmount *mnt;
+       int isleaf;
+       int mode;
 };
 static int rmdir_util_callback(void *dirent, const char *name, int namelen,
                                 loff_t offset, u64 ino, unsigned int d_type)
@@ -837,12 +839,15 @@ out:
 }
 
 /* This function recursively rermoves all the entries of a lower directory
- * at a specific branch and then the directory itself if rm_parent is set. It
- * does not cross branches, and does nothing visible to the union. It should
- * only be used when both a whiteout and a dir at top branch exists
- * and we need to create a new dentry or in the odf
+ * at a specific branch and then the directory itself. It does not cross
+ * branches, and does nothing visible to the union. It should only be used
+ * when both a whiteout and a dir at top branch exists and we need to create
+ * create a new dentry or in the odf for cleanup
+ * Flags:      RMV_ALL : removes all entries
+ *             RMV_LEAF : removes dirs only if they are leaves (dont have 
subdirs)
+ *             RMV_NOTPARENT : can be set with both flags above, does not rmv 
base dir
  */
-int unionfs_force_rmdir(struct vfsmount *mnt, struct dentry *hidden_dentry, 
int rm_parent)
+int unionfs_force_rmdir(struct vfsmount *mnt, struct dentry *hidden_dentry, 
int flags)
 {
        int err = 0;
        struct file *hidden_file;
@@ -856,6 +861,11 @@ int unionfs_force_rmdir(struct vfsmount *mnt, struct 
dentry *hidden_dentry, int
        buf->err = 0;
        buf->dir = hidden_dentry;
        buf->mnt = mnt;
+       buf->isleaf = 1;
+       if (flags & FRMV_LEAF)
+               buf->mode = RM_LEAF;
+       else
+               buf->mode = RM_ALL;
 
        if (!hidden_dentry->d_inode)
                goto out;
@@ -877,15 +887,16 @@ int unionfs_force_rmdir(struct vfsmount *mnt, struct 
dentry *hidden_dentry, int
                if (buf->err)
                        err = buf->err;
        } while ((err >= 0) && buf->filldir_called);
-
+       
        /* fput calls dput for hidden_dentry */
        fput(hidden_file);
 
        if (err < 0)
                goto out;
        
-       if (rm_parent)
-               err = vfs_rmdir(hidden_dentry->d_parent->d_inode, 
hidden_dentry);
+       if ((flags & FRMV_NOTPARENT) || ((flags & FRMV_LEAF) && !buf->isleaf))
+               goto out;
+       err = vfs_rmdir(hidden_dentry->d_parent->d_inode, hidden_dentry);
 
 out:
        kfree(buf);
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index 8ab7d3b..e0dadd1 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -1369,6 +1369,7 @@ out:
 struct odf_dentry_info *odf_ic_dir(struct dentry *dir)
 {
        struct odf_dentry_info *odi_dir, *odis[4], *odi_ic, *odi_ret = NULL;
+       struct odf_sb_info *osi;
        u64 ino;
        int breakdown[4];
        char name[6];
@@ -1378,7 +1379,8 @@ struct odf_dentry_info *odf_ic_dir(struct dentry *dir)
                err = -ENOTDIR;
                goto out;
        }
-       odi_ic = UNIONFS_SB(dir->d_sb)->odf->odi_ic;
+       osi = UNIONFS_SB(dir->d_sb)->odf;
+       odi_ic = osi->odi_ic;
        odi_dir = UNIONFS_D(dir)->odf_info;
        if (!odi_dir) {
                err = -ENOENT;
@@ -1394,7 +1396,7 @@ struct odf_dentry_info *odf_ic_dir(struct dentry *dir)
 
        memset(name,0,6);
        sprintf(name, "%x", breakdown[0]);
-       odis[0] = __odf_lookup(odi_ic, name, strlen(name), ODF_LOOKUP_DIR, 
NULL);
+       odis[0] = __odf_lookup(odi_ic, osi, name, strlen(name), ODF_LOOKUP_DIR, 
NULL);
        if (IS_ERR(odis[0])) {
                err = PTR_ERR(odis[0]);
                odis[0] = NULL;
@@ -1403,7 +1405,7 @@ struct odf_dentry_info *odf_ic_dir(struct dentry *dir)
        for (i = 1; i < 4; i++) {
                memset(name,0,6);
                sprintf(name, "%x", breakdown[i]);
-               odis[i] = __odf_lookup(odis[i-1], name, strlen(name), 
ODF_LOOKUP_DIR, NULL);
+               odis[i] = __odf_lookup(odis[i-1], osi, name, strlen(name), 
ODF_LOOKUP_DIR, NULL);
                if (IS_ERR(odis[i])) {
                        err = PTR_ERR(odis[i]);
                        odis[i] = NULL;
@@ -1411,7 +1413,7 @@ struct odf_dentry_info *odf_ic_dir(struct dentry *dir)
                }
        }
        
-       odi_ret = __odf_lookup(odis[3], "content", 7, ODF_LOOKUP_FILE, NULL);
+       odi_ret = __odf_lookup(odis[3], osi, "content", 7, ODF_LOOKUP_FILE, 
NULL);
        if (IS_ERR(odi_ret)) {
                err = PTR_ERR(odi_ret);
                odi_ret = NULL;
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index 699f745..8e75657 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -159,8 +159,8 @@ static inline void odf_unlock(struct odf_dentry_info *odi)
 extern void generate_random_uuid(unsigned char uuid_out[16]);
 
 /* cleanup thread functions */
-extern void __odf_reclaim_w(void *args);
-extern int __odf_reclaim_d(void *args);
+extern void __odf_cleanup_w(void *args);
+extern int __odf_cleanup_d(void *args);
 
 /* Macros for locking an odf dentry info. */
 static inline void odf_lock(struct odf_dentry_info *odi)
diff --git a/fs/unionfs/sioq.h b/fs/unionfs/sioq.h
index f97b594..91109a3 100644
--- a/fs/unionfs/sioq.h
+++ b/fs/unionfs/sioq.h
@@ -63,7 +63,7 @@ struct sioa_args {
        int (*done) (void*);
 
        union {
-               struct reclaim_args reclaim;
+               struct cleanup_args cleanup;
        };
 };
 
diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h
index 78cdb22..d819f56 100644
--- a/fs/unionfs/union.h
+++ b/fs/unionfs/union.h
@@ -122,7 +122,7 @@ struct odf_sb_info {
        struct odf_dentry_info *odi_sb;
        struct odf_dentry_info *odi_rc;
        struct odf_dentry_info *odi_ic;
-       struct sioa_args *sioa;
+       struct sioa_args *cleanup;
 };
 
 /* unionfs inode data in memory */
@@ -331,6 +331,11 @@ int __unionfs_d_revalidate_chain(struct dentry *dentry, 
struct nameidata *nd);
 int unionfs_force_rm(struct dentry *dentry, struct dentry **hidden_dentry, int 
bindex);
 int unionfs_silly_rename(struct dentry *dentry, struct dentry *hidden_dentry);
 
+/* Force rmv flags */
+#define FRMV_ALL         0
+#define FRMV_NOTPARENT   1
+#define FRMV_LEAF        2
+
 /* The values for unionfs_interpose's flag. */
 #define INTERPOSE_DEFAULT      0
 #define INTERPOSE_LOOKUP       1
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to