commit 3e58adda5417a9759a9a7ab69da525eac889ba85
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Tue May 29 20:41:43 2007 -0400

    cleanup thread to clean until both blocks and inodes are below threshhold
    
    added new cleanup flags

diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c
index 83b006d..a424789 100644
--- a/fs/unionfs/dirhelper.c
+++ b/fs/unionfs/dirhelper.c
@@ -53,7 +53,7 @@ struct unionfs_rdutil_callback {
 struct unionfs_cleanup_callback {
        int err;
        int filldir_called;
-       int reclaim;
+       int mode;
        struct dentry *dir;
        struct vfsmount *mnt;
        struct dentry_stack *stack;
@@ -61,6 +61,11 @@ struct unionfs_cleanup_callback {
        u64 inodes;
 };
 
+/* modes for cleanup_callback - what type of dir we are cleaning */
+#define CLN_IC 0   /* /odf/ic */
+#define CLN_RC 1   /* /odf/reclaim */
+#define CLN_SR 2   /* /odf/sr */
+
 /* odf_cleanup callback */
 static int cleanup_util_callback(void *dirent, const char *name, int namelen,
                                 loff_t offset, u64 ino, unsigned int d_type)
@@ -77,8 +82,10 @@ static int cleanup_util_callback(void *dirent, const char 
*name, int namelen,
                (namelen == 1 || (name[1] == '.' && namelen == 2)))
                        goto out;
 
-       /* remove dir cache files or all if files if cleaning /reclaim */
-       if ((d_type == DT_REG && buf->reclaim) ||
+       /* remove dir cache files or all if files if cleaning 
+        * /odf/reclaim nad /odf/sr
+        */
+       if ((d_type == DT_REG && buf->mode != CLN_IC) ||
                (namelen == ODF_CONTENT_LEN &&
                !strncmp(name, ODF_CONTENT, namelen))) {
 
@@ -542,24 +549,26 @@ out:
  * First cleans up the dir caches in odf/ic and then everything
  * in odf/reclaim. It stops once the requested blocks/inodes
  * were freed.
- * size contains the requested amount of inodes/blocks to be freed
- * MULTIPLIED BY 100
- * Modes :
- *     ODF_CLEAN_ALL: cleans all the dir caches and odf/reclaim
- *     ODF_CLEAN_CACHE: cleans all the dir caches and odf/sr
- *     ODF_CLEAN_BLOCKS: clean until size blocks are freed
- *     ODF_CLEAN_INODES: clean until size inodes are freed
+ *
+ * b_to_free and i_to_free contains the requested amount of blocks
+ * and inodes to be freed MULTIPLIED BY 100
+ *
+ * Flags :
+ *     ODF_CLEAN_DEFAULT: clean all caches but /odf/sr
+ *     ODF_CLEAN_SR: clean /odf/sr
+ *     ODF_CLEAN_FULL: clean /odf/ic and /odf/reclaim ignoring
+                       thresholds
  * Returns 1 if it manages to bring inodes/block below requested,
  * threshold and 0 if not.
  */
-int odf_cleanup(struct odf_sb_info *odf, int mode, u64 size)
+int odf_cleanup(struct odf_sb_info *odf, int mode, u64 b_to_free, u64 
i_to_free)
 {
        int err = 0;
        struct file *file;
        struct unionfs_cleanup_callback *buf = NULL;
        struct dentry *dentry;
        struct dentry_stack stack;
-       int success = 0, reclaim = 0;
+       int success = 0;
        loff_t bytes, isize;
        int blocks;
 
@@ -568,7 +577,6 @@ int odf_cleanup(struct odf_sb_info *odf, int mode, u64 size)
                err = -ENOMEM;
                goto out;
        }
-
        buf = kmalloc(sizeof(struct unionfs_cleanup_callback), GFP_KERNEL);
        if (!buf) {
                err = -ENOMEM;
@@ -576,7 +584,7 @@ int odf_cleanup(struct odf_sb_info *odf, int mode, u64 size)
        }
        buf->err = 0;
        buf->mnt = odf->mnt;
-       buf->reclaim = reclaim;
+       buf->mode = CLN_IC;
        buf->blocks = 0;
        buf->inodes = 0;
        buf->stack = &stack;
@@ -585,7 +593,6 @@ int odf_cleanup(struct odf_sb_info *odf, int mode, u64 size)
        dget(odf->ic);
        stack.item[stack.n++] = odf->ic;
 
-
 cleanup_loop:
        /* The cleanup loop pops a dentry off the stack, reads all
         * its entries, unlinking dir cache files and files in
@@ -594,10 +601,10 @@ cleanup_loop:
        while (err >= 0 && stack.n > 0 && !success) {
                dentry = __ds_pop(&stack);
 
-               /* we need to dget /reclaim dirs again since we need
-                * them after we close the file
+               /* we need to dget /odf/reclaim and /odf/sr dirs again since 
+                * we need them after we close the file
                 */
-               if (reclaim)
+               if (buf->mode != CLN_IC)
                        dget(dentry);
                mntget(odf->mnt);
 
@@ -617,7 +624,7 @@ cleanup_loop:
                } while ((err >= 0) && buf->filldir_called);
                fput(file);
 
-               if (!err && reclaim) {
+               if (!err && buf->mode != CLN_IC) {
                        /* remove all directories in odf/reclaim or odf/sr
                         * This assumes that the odf/reclaim dir structure
                         * is entirely flat, ie only odf/reclaim contains
@@ -640,42 +647,39 @@ cleanup_loop:
                }
 
                /* check if we have reached the threshold */
-               if (mode == ODF_CLEAN_BLOCKS && buf->blocks * 100 >= size)
-                       success = 1;
-               else if (mode == ODF_CLEAN_INODES && buf->inodes * 100 >= size)
+               if ((mode & ODF_CLEAN_DEFAULT) &&
+                       (buf->blocks * 100 >= b_to_free) &&
+                       (buf->inodes * 100 >= i_to_free))
                        success = 1;
        }
 
        if (err < 0)
                goto out;
 
-       if (mode == ODF_CLEAN_CACHE && !reclaim) {
-               /* cleanup odf/sr as well */
-               reclaim = 1;
-               buf->reclaim = 1;
-               dget(odf->sr);
-               stack.item[stack.n++] = odf->sr;
-               goto cleanup_loop;
-       }
-       else if (mode == ODF_CLEAN_CACHE && reclaim)
-               success = 1;
-
-       if (!success) {
+       if (!success && ((mode & ODF_CLEAN_DEFAULT) || (mode & 
ODF_CLEAN_FULL))) {
                BUG_ON(stack.n);
 
                /* if we did not succeed, clean up odf/reclaim as well */
-               if (!reclaim) {
-                       reclaim = 1;
-                       buf->reclaim = 1;
+               if (buf->mode == CLN_IC) {
+                       buf->mode = CLN_RC;
                        dget(odf->rc);
                        stack.item[stack.n++] = odf->rc;
                        goto cleanup_loop;
                }
        }
 
-       if (mode == ODF_CLEAN_ALL)
-               success = 1;
+       /* cleanup /odf/sr */
+       if ((mode & ODF_CLEAN_SR) && (buf->mode != CLN_SR)) {
+               buf->mode = CLN_SR;
+               dget(odf->sr);
+               stack.item[stack.n++] = odf->sr;
+               goto cleanup_loop;
+       }
 
+       if (mode & ODF_CLEAN_DEFAULT)
+               err = success;
+       else
+               err = 1;
 out:
        BUG_ON(stack.n < 0);
        while(stack.n)
@@ -683,7 +687,5 @@ out:
 
        kfree(buf);
        kfree(stack.item);
-       if (!err)
-               err = success;
        return err;
 }
diff --git a/fs/unionfs/main.c b/fs/unionfs/main.c
index 70ddb22..79ceae7 100644
--- a/fs/unionfs/main.c
+++ b/fs/unionfs/main.c
@@ -482,7 +482,7 @@ static struct unionfs_dentry_info *unionfs_parse_options(
                        *optarg++ = '\0';
 
                /* taken care of in odf_parse_options */
-               if (!strcmp("odfforce", optname))
+               if (!strcmp("odf_keepcache", optname))
                        continue;
 
                /*
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index 2a7791d..18b88ff 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -184,7 +184,8 @@ int odf_read_super(struct super_block *sb, char *data)
        }
        sioa->cleanup.odf = osi;
        sioa->cleanup.attr = get_attributes();
-       sioa->cleanup.force = !(options & ODF_OPT_KEEPCACHE);
+       sioa->cleanup.flags = (options & ODF_OPT_KEEPCACHE)?
+                               ODF_CLEAN_DEFAULT:ODF_CLEAN_SR|ODF_CLEAN_FULL;
        osi->cleanup = sioa;
        osi->mnt = nd.mnt;
        mntget(osi->mnt);
@@ -222,6 +223,10 @@ void odf_put_super(struct odf_sb_info *osi)
 {
        struct dentry *odf_root = NULL;
 
+       if (osi->cleanup)
+               complete_sioa(osi->cleanup);
+       kfree(osi->cleanup);
+
        if (osi->sb)
                odf_root = osi->sb->d_parent;
 
@@ -242,9 +247,6 @@ void odf_put_super(struct odf_sb_info *osi)
 
        dput(odf_root);
        mntput(osi->mnt);
-       if (osi->cleanup)
-               complete_sioa(osi->cleanup);
-       kfree(osi->cleanup);
 }
 
 /*
@@ -305,6 +307,7 @@ int odf_parse_options(const char *options, char **odf_path)
                                goto out_error;
                        }
                        err |= ODF_OPT_KEEPCACHE;
+                       continue;
                }
 
                if (!optarg) {
@@ -1971,9 +1974,8 @@ void __odf_cleanup(void *args)
        struct sioa_args *sioa_args = args;
        struct cleanup_args *cl = &sioa_args->cleanup;
        struct kstatfs stat;
-       int cleanup = 0;
-       u64 size = 0;
-       int err = 0;
+       u64 b_size = 0, i_size = 0;
+       int cleanup = 0, err = 0;
 
        /* update timeout */
        sioa_args->timeout = msecs_to_jiffies(cl->attr->timeout->val * 1000);
@@ -1981,33 +1983,37 @@ void __odf_cleanup(void *args)
        /* LOCK: need to lock ic/reclaim/sr? */
 
        vfs_statfs(cl->odf->sb, &stat);
-       if (cl->force) {
-               cl->force = 0;
-               cleanup = ODF_CLEAN_CACHE;
-       }
-       else if (stat.f_bavail * 100 < stat.f_blocks * (100 - 
cl->attr->thresh_b_high->val)) {
-               cleanup = ODF_CLEAN_BLOCKS;
-               size =  stat.f_blocks * (100 - cl->attr->thresh_b_low->val) -
-                               (stat.f_bavail * 100);
-       }
-       else if (stat.f_ffree * 100 < stat.f_files * (100 - 
cl->attr->thresh_i_high->val)) {
-               cleanup = ODF_CLEAN_INODES;
-               size = stat.f_files * (100 - cl->attr->thresh_i_low->val) -
+       if (cl->flags & ODF_CLEAN_DEFAULT) {
+
+               /* check if blocks is above threshold */
+               if (stat.f_bavail * 100 < stat.f_blocks
+                       * (100 - cl->attr->thresh_b_high->val)) {
+                       cleanup = 1;
+                       b_size = stat.f_blocks *
+                                (100 - cl->attr->thresh_b_low->val) -
+                                (stat.f_bavail * 100);
+               }
+
+               /* check if inodes is above threshold */
+               if (stat.f_ffree * 100 < stat.f_files
+                       * (100 - cl->attr->thresh_i_high->val)) {
+                       cleanup = 1;
+                       i_size = stat.f_files *
+                               (100 - cl->attr->thresh_i_low->val) -
                                (stat.f_ffree * 100);
+               }
        }
+
+       if (cl->flags & ODF_CLEAN_FULL || cl->flags & ODF_CLEAN_SR)
+               cleanup = 1;
+
        if (cleanup)
-               err = odf_cleanup(cl->odf, cleanup, size);
+               err = odf_cleanup(cl->odf, cl->flags, b_size, i_size);
        if (err < 0)
                printk(KERN_WARNING "unionfs cleanup thread: error %d\n", err);
-       else {
-               if (err == 0 && cl->success == 1) {
-                       if (cleanup == ODF_CLEAN_BLOCKS)
-                               printk(KERN_WARNING
-                                      "unionfs: failed to bring free odf data 
blocks below threshold\n");
-                       else if (cleanup == ODF_CLEAN_INODES)
-                               printk(KERN_WARNING
-                                      "unionfs: failed to bring free odf 
inodes below threshold\n");
-               }
-               cl->success = err;
-       }
+       else if (err == 0 && cl->success == 1)
+               printk(KERN_WARNING
+                      "unionfs: cleanup failed to bring odf below 
threshold\n");
+       cl->success = err;
+       cl->flags = ODF_CLEAN_DEFAULT;
 }
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index 29d1f9e..cca6c48 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -33,10 +33,10 @@
 
 #define ODF_DIRENT_MAGIC 0x0DFD1300
 
-#define ODF_CLEAN_ALL 1
-#define ODF_CLEAN_CACHE 2
-#define ODF_CLEAN_INODES 3
-#define ODF_CLEAN_BLOCKS 4
+/* cleanup thread flags */
+#define ODF_CLEAN_DEFAULT      0x01
+#define ODF_CLEAN_SR           0x02
+#define ODF_CLEAN_FULL         0x04
 
 /* Options flags */
 #define ODF_OPT_KEEPCACHE 0x01
@@ -97,7 +97,7 @@ int __odf_set_opaque(struct dentry *d, int branch);
 
 /* cleanup thread functions */
 extern void __odf_cleanup(void *args);
-int odf_cleanup(struct odf_sb_info *odf, int mode, u64 size);
+int odf_cleanup(struct odf_sb_info *odf, int mode, u64 b_to_free, u64 
i_to_free);
 
 extern void generate_random_uuid(unsigned char uuid_out[16]);
 
diff --git a/fs/unionfs/sioq.h b/fs/unionfs/sioq.h
index bc80a8a..f618840 100644
--- a/fs/unionfs/sioq.h
+++ b/fs/unionfs/sioq.h
@@ -54,7 +54,7 @@ struct unlink_args {
 struct cleanup_args {
        struct odf_sb_info *odf;
        struct unionfs_attributes *attr;
-       int force;
+       int flags;
        int success;
 };
 
diff --git a/fs/unionfs/super.c b/fs/unionfs/super.c
index 38fbb7b..f62d2e6 100644
--- a/fs/unionfs/super.c
+++ b/fs/unionfs/super.c
@@ -425,7 +425,7 @@ static int unionfs_remount_fs(struct super_block *sb, int 
*flags,
        struct inode **new_lower_inodes = NULL;
        int new_high_branch_id; /* new high branch ID */
        struct odf_sb_info *odf = &UNIONFS_SB(sb)->odf;
-       int odfforce = 0 ;      /* whether the odfforce option was provided */
+       int odf_keepcache = 0 ; /* whether the odf_keepcache option was 
provided */
        int old_ibstart, old_ibend;
        int size;               /* memory allocation size, temp var */
 
@@ -558,13 +558,13 @@ static int unionfs_remount_fs(struct super_block *sb, int 
*flags,
                        goto out_no_change;
                }
 
-               if (!strcmp("odfforce", optname)) {
+               if (!strcmp("odf_keepcache", optname)) {
                        if (optarg) {
                                printk("unionfs: %s does not take an 
argument\n", optname);
                                err = -EINVAL;
                                goto out_release;
                        }
-                       odfforce = 1;
+                       odf_keepcache = 1;
                        continue;
                }
 
@@ -693,11 +693,11 @@ out_no_change:
                goto out_release;
        odf->opaque_branch_id = new_data[0].branch_id;
 
-       /* if odfforce is not set, wake up the cleanup thread and force it to
-        * cleanup everything
+       /* if odf_keepcache is not set, wake up the cleanup thread and force
+        * it to cleanup everything
        */
-       if (!odfforce) {
-               odf->cleanup->cleanup.force = 1;
+       if (!odf_keepcache) {
+               odf->cleanup->cleanup.flags = ODF_CLEAN_FULL;
                wake_up_and_wait_sioa(odf->cleanup);
        }
 
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to