commit 5c00508032ab5dac881588ef8329ef31e9a1edcf
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Mon Feb 5 13:21:45 2007 -0500

    More code cleanup as per jeff's comments
    
    Added functions for set/get opaqueness (now using bits 24-30 of i_flags)

diff --git a/fs/unionfs/main.c b/fs/unionfs/main.c
index b2dc55c..6db077e 100644
--- a/fs/unionfs/main.c
+++ b/fs/unionfs/main.c
@@ -70,11 +70,10 @@ int unionfs_interpose(struct dentry *dentry, struct 
super_block *sb, int flag)
                }
        } else {
                ino_t ino;
-
                /* get unique inode number for unionfs */
                if ( !UNIONFS_D(dentry)->odf_info )
-                       UNIONFS_D(dentry)->odf_info = 
odf_lookup(dentry->d_parent, dentry, odf_flag);
-
+                       UNIONFS_D(dentry)->odf_info = 
+                               odf_lookup(dentry->d_parent, dentry, odf_flag);
                ino = UNIONFS_D(dentry)->odf_info->inum;
 
                inode = iget(sb, ino);
@@ -438,7 +437,7 @@ static struct unionfs_dentry_info 
*unionfs_parse_options(struct super_block *sb,
                        }
                        err = parse_dirs_option(sb, hidden_root_info, optarg);
                        if (err)
-                               dirsfound--; //goto out_error;
+                               goto out_error;
                        continue;
                }
 
@@ -459,8 +458,8 @@ static struct unionfs_dentry_info 
*unionfs_parse_options(struct super_block *sb,
        }
        if (dirsfound != 1) {
                printk(KERN_WARNING "unionfs: dirs option (not) required\n");
-               //err = -EINVAL;
-               //goto out_error;
+               err = -EINVAL;
+               goto out_error;
        }
        goto out;
 
@@ -541,7 +540,6 @@ static int unionfs_read_super(struct super_block *sb, void 
*raw_data,
                goto out;
        }
 
-
        UNIONFS_SB(sb)->bend = -1;
        atomic_set(&UNIONFS_SB(sb)->generation, 1);
        init_rwsem(&UNIONFS_SB(sb)->rwsem);
@@ -572,11 +570,9 @@ 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(1) ) {
-                odf_putoptions(sb, hidden_root_info);
-        }
-       
-       
+       if (odf_is_new(1))
+               odf_putoptions(sb, hidden_root_info);
+
        /* set the hidden superblock field of upper superblock */
        bstart = hidden_root_info->bstart;
        BUG_ON(bstart != 0);
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index 4e2e576..4d27aa1 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -1,9 +1,9 @@
 #include "union.h"
 
-
+static int sss = 0;
 /*
-       Initialize any odf data we might need
-*/
+ *     Initialize any odf data we might need
+ */
 struct vfsmount* odf_read_super(char *odffile)
 {
        struct nameidata nd;
@@ -34,8 +34,8 @@ out:
 }
 
 /*
-       Clean any alloc'd odf data
-*/
+ *     Clean any alloc'd odf data
+ */
 void odf_put_super(struct super_block *sb)
 {
        dput(UNIONFS_SB(sb)->odf_mnt->mnt_sb->s_root);
@@ -43,8 +43,8 @@ void odf_put_super(struct super_block *sb)
 }
 
 /*
-       Returns the dentry of /odf/ns
-*/
+ *     Returns the dentry of /odf/ns
+ */
 struct odf_dentry_info* odf_getns(void)
 {
        struct nameidata nd;
@@ -57,7 +57,6 @@ struct odf_dentry_info* odf_getns(void)
                odi = ERR_PTR(err);
                goto out;
        }
-       
        odi = odf_fill_info(nd.dentry);
        path_release(&nd);
        
@@ -66,14 +65,15 @@ out:
 }
 
 /*
-       Lookup an entry in the odf, create it if not found,
-       else check for whiteouts
-       Handle hard links
-*/
+ *     Lookup an entry in the odf, create it if not found,
+ *     else check for whiteouts
+ *     Handle hard links
+ */
 struct odf_dentry_info *odf_lookup(struct dentry *parent, struct dentry 
*dentry, int flags)
 {
        struct dentry *odf_dentry = NULL;
        struct odf_dentry_info *odi = NULL;
+       struct inode *odf_i_dir = UNIONFS_D(parent)->odf_info->dentry->d_inode;
        int err = 0;
 
        if (UNIONFS_D(dentry)->odf_info) {
@@ -84,23 +84,25 @@ struct odf_dentry_info *odf_lookup(struct dentry *parent, 
struct dentry *dentry,
        odf_dentry = lookup_one_len(dentry->d_name.name, 
                                UNIONFS_D(parent)->odf_info->dentry,
                                dentry->d_name.len);
-
+       
        /* create inode in odf if dont exist */
        /* XXX: should we fail if res is ERR? */
        if (IS_ERR(odf_dentry) || !odf_dentry->d_inode) {
                
                /* FIXME need to check hardlinks before create */
                if (flags & ODF_LOOKUP_FILE)
-                       err = 
vfs_create(UNIONFS_D(parent)->odf_info->dentry->d_inode, odf_dentry, S_IRWXUGO, 
0 );
+                       err = vfs_create(odf_i_dir, odf_dentry, S_IRWXUGO, 0 );
 
                else if (flags & ODF_LOOKUP_DIR)
-                       err = 
vfs_mkdir(UNIONFS_D(parent)->odf_info->dentry->d_inode, odf_dentry, S_IRWXUGO);
+                       err = vfs_mkdir(odf_i_dir, odf_dentry, S_IRWXUGO);
 
                else {
                        dput(odf_dentry);
                        goto out;
                }
-
+               odf_set_opaque_i(odf_dentry->d_inode, -1);
+               odf_set_wh_i(odf_dentry->d_inode,0);
+               
                /* XXX */
                if (err)
                        printk(KERN_WARNING "could not create odf dentry" );
@@ -110,28 +112,107 @@ struct odf_dentry_info *odf_lookup(struct dentry 
*parent, struct dentry *dentry,
        }
        
        odi = odf_fill_info(odf_dentry);
+       dput(odf_dentry); /* since we dget in fill_info */
 
 out:
        return odi;
 }
 
-int odf_create_wh(struct dentry *dentry)
+
+/*
+ * Sets the whiteout flag
+ * The dentry version takes a UnionFS dentry, the inode one an ODF inode
+ */
+int odf_set_wh(struct dentry *dentry, int boolean)
+{
+       return odf_set_wh_i(UNIONFS_D(dentry)->odf_info->dentry->d_inode, 
boolean);
+}
+int odf_set_wh_i(struct inode *i, int boolean)
 {
-       struct inode *i = UNIONFS_D(dentry)->odf_info->dentry->d_inode;
        int err = 0;
-       EXT2_I(i)->i_flags |= ODF_WHITEOUT;
+       if (boolean)
+               EXT2_I(i)->i_flags |= ODF_WHITEOUT;
+       else
+               EXT2_I(i)->i_flags &= !ODF_WHITEOUT;
        err = ext2_write_inode(i, 1);
        return err;
 }
+
+/*
+ * Checks if the whiteout flag is set for a dentry
+ * The dentry version takes a UnionFS dentry, the inode one an ODF inode
+ */
 int odf_is_wh(struct dentry *dentry)
 {
-       struct inode *i = UNIONFS_D(dentry)->odf_info->dentry->d_inode;
+       return odf_is_wh_i(UNIONFS_D(dentry)->odf_info->dentry->d_inode);
+}
+int odf_is_wh_i(struct inode *i)
+{
        return EXT2_I(i)->i_flags & ODF_WHITEOUT;
 }
 
+/*
+ * Checks if a dentry is opaque
+ * The dentry version takes a UnionFS dentry, the inode one an ODF inode
+ */
+int odf_is_opaque(struct dentry *dentry) 
+{
+       return odf_is_opaque_i(UNIONFS_D(dentry)->odf_info->dentry->d_inode);
+}
+int odf_is_opaque_i(struct inode *i) 
+{
+       if (!S_ISDIR(i->i_mode))
+               return 0;
+       return EXT2_I(i)->i_flags & ODF_OPAQUE;
+}
+/*
+ * Gets opaque branch of a dentry, -1 if not opaque
+ * The dentry version takes a UnionFS dentry, the inode one an ODF inode
+ */
+int odf_get_opaque(struct dentry *dentry) 
+{
+       return odf_get_opaque_i(UNIONFS_D(dentry)->odf_info->dentry->d_inode);
+}
+int odf_get_opaque_i(struct inode *i) 
+{
+       u32 res = 0;
+       if (!odf_is_opaque_i(i))
+               return -1;
+
+       /* get bits 26-30 */
+       res = EXT2_I(i)->i_flags;
+       res <<= 1;
+       res >>= (ODF_OPQ_BASE + 1);
+       return res;
+}
+
+/*
+ * Sets a dentry as opaque, if not use -1 for branch
+ * The dentry version takes a UnionFS dentry, the inode one an ODF inode
+ */
+int odf_set_opaque(struct dentry *dentry, int branch)
+{
+       return odf_set_opaque_i(UNIONFS_D(dentry)->odf_info->dentry->d_inode, 
branch);
+}
+int odf_set_opaque_i(struct inode *i, int branch) 
+{
+       u32 b = branch;
+       int err = 0;
+
+       if (branch < 0)
+               EXT2_I(i)->i_flags &= !ODF_OPAQUE;
+       else {
+               b <<= ODF_OPQ_BASE + 1;
+               b >>= 1;
+               EXT2_I(i)->i_flags |= (ODF_OPAQUE|b);
+       }
+       err = ext2_write_inode(i, 1);
+       return err;
+}
+
 /* 
-       returns the dirs= part of the mount options 
-*/
+ *     returns the dirs= part of the mount options 
+ */
 char *odf_getoptions(void)
 {
        int err = 0;
@@ -146,26 +227,24 @@ char *odf_getoptions(void)
                mm_segment_t oldfs;
                int perms = 0, len = 0;
 
-               options = kzalloc(255, GFP_KERNEL); /*XXX*/
-               branch_entry = kzalloc(255, GFP_KERNEL);
-               if ( !options || !branch_entry ) {
+               options = kzalloc(ODF_OPTIONS_LEN, GFP_KERNEL); /*XXX*/
+               branch_entry = kzalloc(ODF_BRANCH_PATH, GFP_KERNEL);
+               if (!options || !branch_entry)
                        goto out_err;
-               }
 
                ptr = options;
                sprintf(ptr,"dirs=");
                ptr+=strlen(ptr);
-               while ( 1 ) {
+               while (1) {
                        sprintf(branch_entry,"%s%d", ODF_SB, i);
                        err = path_lookup(branch_entry, LOOKUP_FOLLOW, &nd_br);
-                       if ( err ) {
+                       if (err)
                                break;
-                       }
 
                        dget(nd_br.dentry);
                        mntget(nd_br.mnt);
                        file = dentry_open(nd_br.dentry, nd_br.mnt, O_RDONLY);
-                       if ( IS_ERR(file) ) {
+                       if (IS_ERR(file)) {
                                mntput(nd_br.mnt);
                                dput(nd_br.dentry);
                                path_release(&nd_br);
@@ -202,7 +281,9 @@ out:
        return options;
 }
 
-/* checks the newbit, unset is a boolean, whether to unset the bit if it set */
+/* 
+ * checks the newbit, unset is a boolean, whether to unset the bit if it set 
+ */
 int odf_is_new(int unset)
 {
        int err = 0;
@@ -211,21 +292,19 @@ int odf_is_new(int unset)
        
        /* check the new bit, for now check if file newbit exists */
        err = path_lookup(ODF_NEWBIT, LOOKUP_FOLLOW, &nd);      
-       if (err) {
+       if (err) 
                return 0; /* is not new */
-       }
-       else {
-               newbit = nd.dentry;
-               path_release(&nd);
-               if (unset)
-                       vfs_unlink(newbit->d_parent->d_inode, newbit);
-               return 1;
-       }
+
+       newbit = nd.dentry;
+       path_release(&nd);
+       if (unset)
+               vfs_unlink(newbit->d_parent->d_inode, newbit);
+       return 1;
 }
 
 /*
-       Writes the superblock data for new odf's, generates branch UUID's
-*/
+ *     Writes the superblock data for new odf's, generates branch UUID's
+ */
 int odf_putoptions(struct super_block* sb_union, struct unionfs_dentry_info 
*hidden_root)
 {
        struct nameidata nd_sb, nd_br;
@@ -236,8 +315,8 @@ int odf_putoptions(struct super_block* sb_union, struct 
unionfs_dentry_info *hid
        char *name;
        int perms, len, bindex;
        int err = 0;
-       char *branch_entry = kmalloc(255, GFP_KERNEL);
-       char *branch_path = kmalloc(255, GFP_KERNEL); /*XXX*/
+       char *branch_entry = kmalloc(ODF_BRANCH_PATH, GFP_KERNEL);
+       char *branch_path = kmalloc(ODF_BRANCH_PATH, GFP_KERNEL);
        mm_segment_t oldfs;
 
        if (!branch_entry || !branch_path) {
@@ -248,10 +327,17 @@ int odf_putoptions(struct super_block* sb_union, struct 
unionfs_dentry_info *hid
        err = path_lookup(ODF_SB, LOOKUP_FOLLOW, &nd_sb);       
        if (err)
                goto out;       
+       
+       /* FIXME: This function should check all the branches, generate fs UUID
+        * for each branch, and save the path and permissions of each branch.
+        * Right now only the latter part is implemented and the UUID's are 
simply
+        * the branch index. So we need to gen UUIDs
+        */
 
        for (bindex = hidden_root->bstart;
                        bindex >= 0 && bindex <= hidden_root->bend;
                        bindex++) {
+
                /* for now, create a file per branch and 
                   use bindex as UUID                   */
                
@@ -259,7 +345,7 @@ int odf_putoptions(struct super_block* sb_union, struct 
unionfs_dentry_info *hid
                m = hidden_root->lower_paths[bindex].mnt;
                sprintf(branch_entry,"%s%d", ODF_SB, bindex);
                err = path_lookup(branch_entry, LOOKUP_FOLLOW, &nd_br); 
-               if ( !err ) {
+               if (!err) {
                        path_release(&nd_br);
                        path_release(&nd_sb);
                        err = -EINVAL;
@@ -271,12 +357,12 @@ int odf_putoptions(struct super_block* sb_union, struct 
unionfs_dentry_info *hid
                                d_new,
                                0,
                                &nd_br );
-               if ( err ) {
+               if (err) {
                        path_release(&nd_sb);
                        goto out;
                }
                err = path_lookup(branch_entry, LOOKUP_FOLLOW, &nd_br); 
-               if ( err ) {
+               if (err) {
                        path_release(&nd_br);
                        path_release(&nd_sb);
                        goto out;
@@ -293,7 +379,7 @@ int odf_putoptions(struct super_block* sb_union, struct 
unionfs_dentry_info *hid
                dget(d_new);
 
                file = dentry_open(d_new, nd_br.mnt, O_WRONLY);
-               if ( IS_ERR(file) ) {
+               if (IS_ERR(file)) {
                        dput(d_new);
                        mntput(nd_br.mnt);
                        path_release(&nd_br);
@@ -319,8 +405,9 @@ out:
        return err;
 }
 
-
-/* Allocates an odi and fills it with inode and dentry */
+/* 
+ * Allocates an odi and fills it with inode and dentry 
+ */
 struct odf_dentry_info *odf_fill_info(struct dentry *odf_dentry)
 {
        struct odf_dentry_info *odi = kzalloc(sizeof(struct 
odf_dentry_info),GFP_KERNEL);
@@ -330,14 +417,16 @@ struct odf_dentry_info *odf_fill_info(struct dentry 
*odf_dentry)
        return odi;
 }
 
-/* Clears the odf_info data */
+/* 
+ * Clears the odf_info data 
+ */
 void odf_clear_info(struct odf_dentry_info *odi)
 {
-       if (odi) {
-               if (odi->dentry)
-                       dput(odi->dentry);
-               kfree(odi);
-       }
+       if (!odi)
+               return;
+       if (odi->dentry)
+               dput(odi->dentry);
+       kfree(odi);
 }
 
 
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index 08f0cb0..6d15dc7 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -10,12 +10,19 @@
 #define ODF_NS ODF_MOUNT "ns/"
 #define ODF_NEWBIT ODF_SB "newbit"
 
+/* Some string constants */
+#define ODF_BRANCH_PATH 255
+#define ODF_OPTIONS_LEN 255
+
 /* Lookup flags (what to create if lookup fails) */
 #define ODF_LOOKUP_FILE        1 
 #define ODF_LOOKUP_DIR 2
 
 /* Inode flags */ 
 #define ODF_WHITEOUT 0x01000000
+#define ODF_OPAQUE 0x02000000
+#define ODF_OPQ_BASE 26 /* 0x04000000, bits 26 - 30 */
+#define ODF_OPQ_BITS 5
 
 /* super */
 struct vfsmount* odf_read_super(char *odffile);
@@ -31,8 +38,18 @@ struct odf_dentry_info *odf_fill_info(struct dentry 
*odf_dentry);
 void odf_clear_info(struct odf_dentry_info *odi);
 
 /* whiteouts */
-int odf_create_wh(struct dentry *dentry);
+int odf_set_wh(struct dentry *dentry, int boolean);
 int odf_is_wh(struct dentry *dentry);
+int odf_set_wh_i(struct inode *i, int boolean);
+int odf_is_wh_i(struct inode *i);
+
+/* opaque */
+int odf_is_opaque(struct dentry *dentry);
+int odf_get_opaque(struct dentry *dentry);
+int odf_set_opaque(struct dentry *dentry, int branch);
+int odf_is_opaque_i(struct inode *i);
+int odf_get_opaque_i(struct inode *i);
+int odf_set_opaque_i(struct inode *i, int branch);
+
 
-extern int ext2_write_inode (struct inode *, int);
 #endif /* _ODF_H_ */
diff --git a/fs/unionfs/subr.c b/fs/unionfs/subr.c
index 412c6aa..f0869c2 100644
--- a/fs/unionfs/subr.c
+++ b/fs/unionfs/subr.c
@@ -37,7 +37,7 @@ int create_whiteout(struct dentry *dentry, int start)
        bend = dbend(dentry);
 
        /* odf whiteout */
-       odf_create_wh(dentry);
+       odf_set_wh(dentry,1);
 
        /* create dentry's whiteout equivalent */
        name = alloc_whname(dentry->d_name.name, dentry->d_name.len);
diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h
index bbd7238..6256aa0 100644
--- a/fs/unionfs/union.h
+++ b/fs/unionfs/union.h
@@ -86,6 +86,18 @@ struct unionfs_file_info {
        int *saved_branch_ids; /* IDs of branches when file was opened */
 };
 
+/* odf dentry data in memory */
+struct odf_dentry_info {
+       /* The odf dentry info should contain info on the location of 
+        * the data in the odf file. Right now i keep a dentry for easy
+        * lookup in the underlying ext2 
+        */
+       u64 inum;
+       int whiteout;
+       int opaque;
+       struct dentry *dentry;
+};
+
 /* unionfs inode data in memory */
 struct unionfs_inode_info {
        int bstart;
@@ -107,16 +119,6 @@ struct unionfs_inode_info {
        struct inode vfs_inode;
 };
 
-/* odf dentry data */
-struct odf_dentry_info {
-       /* The odf dentry info should contain info on the location of 
-        * the data in the odf file. Right now i keep a dentry for easy
-        * lookup in the underlying ext2 
-        */
-       u64 inum;
-       struct dentry *dentry;
-};
-
 /* unionfs dentry data in memory */
 struct unionfs_dentry_info {
        /* The semaphore is used to lock the dentry as soon as we get into a
@@ -499,6 +501,7 @@ static inline void unionfs_mntput(struct dentry *dentry, 
int bindex)
        mntput(mnt);
 }
 
+/* keep everything odf related separate for now */
 #include "odf.h"
 
 #endif /* not _UNION_H_ */
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to