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