commit f30d3663d49424c9f83744a7703332bb92828ab7
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Sun Mar 25 13:52:14 2007 -0400

    added check for no of odf supported branches at mount time

diff --git a/fs/unionfs/main.c b/fs/unionfs/main.c
index 27b26ee..c200f3a 100644
--- a/fs/unionfs/main.c
+++ b/fs/unionfs/main.c
@@ -572,7 +572,7 @@ static int unionfs_read_super(struct super_block *sb, void 
*raw_data,
                goto out_free;
        }
        put_ns = 1;
-       if (!odf_is_new(UNIONFS_SB(sb)->odf, 0)) {
+       if (!odf_is_new(UNIONFS_SB(sb)->odf)) {
                odf_options = odf_get_options(UNIONFS_SB(sb)->odf);
                if (!odf_options) {
                        printk(KERN_WARNING "unionfs_read_super: could not load 
options from odf\n");
@@ -599,8 +599,13 @@ static int unionfs_read_super(struct super_block *sb, void 
*raw_data,
        }
 
        /* if new bit set, unset it and save branch conf */           
-       if (odf_is_new(UNIONFS_SB(sb)->odf, 1))
-               odf_put_options(sb, hidden_root_info);
+       if (odf_is_new(UNIONFS_SB(sb)->odf)) {
+               err = odf_put_options(sb, hidden_root_info);
+               if (err)
+                       goto out_free;
+               /* here we can safely mark the odf as not new */
+               odf_unset_newbit(UNIONFS_SB(sb)->odf);
+       }
 
        /* set the hidden superblock field of upper superblock */
        bstart = hidden_root_info->bstart;
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index c695498..f11af8f 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -1006,9 +1006,9 @@ out:
 }
 
 /* 
- * checks the newbit, unset is a boolean, whether to unset the bit if it set 
+ * checks the newbit 
  */
-int odf_is_new(struct odf_sb_info *osi, int unset)
+int odf_is_new(struct odf_sb_info *osi)
 {
        struct dentry *newbit;
 
@@ -1021,11 +1021,29 @@ int odf_is_new(struct odf_sb_info *osi, int unset)
                return 0;
        }
 
-       if (unset)
-               vfs_unlink(newbit->d_parent->d_inode, newbit);
        dput(newbit);
        return 1;
 }
+
+/*
+ * Unsets the newbit
+ */
+void odf_unset_newbit(struct odf_sb_info *osi)
+{
+       struct dentry *newbit;
+
+       /* check the new bit, for now check if file newbit exists */
+       newbit = lookup_one_len(ODF_NEWBIT, osi->odi_sb->dentry, 
strlen(ODF_NEWBIT));
+       if (IS_ERR(newbit) || !newbit)
+               return;
+       else if (unlikely(!newbit->d_inode)) {
+               dput(newbit);
+               return;
+       }
+       vfs_unlink(newbit->d_parent->d_inode, newbit);
+       dput(newbit);
+}
+
 /*
  *     Writes the superblock data for new odf's, generates branch UUID's
  */
@@ -1052,6 +1070,16 @@ int odf_put_options(struct super_block* sb_union, struct 
unionfs_dentry_info *hi
        d_odf_sb = UNIONFS_SB(sb_union)->odf->odi_sb->dentry;
        odf_mnt = UNIONFS_SB(sb_union)->odf->mnt;
 
+       /* check the number of branches */
+       count = hidden_root->bend - hidden_root->bstart + 1;
+       if (count >= (1 << ODF_OPQ_BITS)) {
+               printk(KERN_WARNING "unionfs: too many branches (%d), "
+                       "odf can only support %d branches\n",
+                       count, (1 << ODF_OPQ_BITS) - 1);
+               err = -EINVAL;
+               goto out;
+       }
+
        d_content = lookup_one_len(ODF_CONTENT, d_odf_sb, ODF_CONTENT_LEN);
        if (IS_ERR(d_content) || !d_content) {
                err = -EINVAL;
@@ -1085,7 +1113,6 @@ int odf_put_options(struct super_block* sb_union, struct 
unionfs_dentry_info *hi
        file->f_op->write(file, (char*)&le32, sizeof(__le32), &file->f_pos);
 
        /* number of branches */
-       count = hidden_root->bend - hidden_root->bstart + 1;
        le32 = cpu_to_le32(count);
        file->f_op->write(file, (char*)&le32, sizeof(__le32), &file->f_pos);
 
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index 50dc681..6a2d1fa 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -51,7 +51,8 @@
 /* super */
 struct odf_sb_info* odf_read_super(char *options);
 void odf_put_super(struct odf_sb_info *osi);
-int odf_is_new(struct odf_sb_info *osi, int unset);
+int odf_is_new(struct odf_sb_info *osi);
+void odf_unset_newbit(struct odf_sb_info *osi);
 char *odf_get_options(struct odf_sb_info *odf_sb);
 int odf_put_options(struct super_block* sb_union, struct unionfs_dentry_info 
*hidden_root);
 int odf_parse_options(char *options, char **odf_path);
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to