commit 6b1e537d50e76c03a4d8b23b60a0b9e9bcb2cc14
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Tue Apr 10 13:36:47 2007 -0400

    whiteouts as hardlinks, removed ext2 dependancy

diff --git a/fs/unionfs/Makefile b/fs/unionfs/Makefile
index 3a52717..167e74f 100644
--- a/fs/unionfs/Makefile
+++ b/fs/unionfs/Makefile
@@ -3,6 +3,6 @@ obj-$(CONFIG_UNION_FS) += unionfs.o
 unionfs-y := subr.o dentry.o file.o inode.o main.o super.o \
        branchman.o rdstate.o copyup.o dirhelper.o rename.o \
        unlink.o lookup.o commonfops.o dirfops.o sioq.o odf.o \
-       config.o ../ext2/ext2.o
+       config.o
 
 unionfs-$(CONFIG_UNION_FS_XATTR) += xattr.o
diff --git a/fs/unionfs/copyup.c b/fs/unionfs/copyup.c
index ce67381..7fe6728 100644
--- a/fs/unionfs/copyup.c
+++ b/fs/unionfs/copyup.c
@@ -435,7 +435,7 @@ static int copyup_named_dentry(struct inode *dir, struct 
dentry *dentry,
        if (!d_deleted(dentry))
                unionfs_reinterpose(dentry);
 
-       err = odf_copyup_link(sb, old_hidden_dentry, new_hidden_dentry, 
old_bindex, new_bindex);
+//     err = odf_copyup_link(sb, old_hidden_dentry, new_hidden_dentry, 
old_bindex, new_bindex);
 
        goto out_unlock;
        /****/
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index 3a545ef..867099b 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -39,26 +39,36 @@ struct odf_sb_info* odf_read_super(char *options)
                err = PTR_ERR(osi->odi_ns);
                osi->odi_ns = NULL;
                goto out_free;
-       }       
+       }
        osi->odi_sb = odf_getpath(nd.dentry, osi, ODF_SB);
        if (IS_ERR(osi->odi_sb)){
                err = PTR_ERR(osi->odi_sb);
                osi->odi_sb = NULL;
                goto out_free;
-       }       
+       }
        osi->odi_rc = odf_getpath(nd.dentry, osi, ODF_RC);
        if (IS_ERR(osi->odi_rc)){
                err = PTR_ERR(osi->odi_rc);
                osi->odi_rc = NULL;
                goto out_free;
-       }       
+       }
        osi->odi_ic = odf_getpath(nd.dentry, osi, ODF_IC);
        if (IS_ERR(osi->odi_ic)){
                err = PTR_ERR(osi->odi_ic);
                osi->odi_ic = NULL;
                goto out_free;
-       }       
-       
+       }
+       osi->whiteout = lookup_one_len(ODF_WH_NAME, osi->odi_sb->dentry, 
ODF_WH_LEN);
+       if (IS_ERR(osi->whiteout)) {
+               err = PTR_ERR(osi->whiteout);
+               osi->whiteout = NULL;
+               goto out_free;
+       }
+       if (!osi->whiteout->d_inode) {
+               err = vfs_create(osi->odi_sb->dentry->d_inode, osi->whiteout, 
S_IRWXUGO, NULL );
+               if (err)
+                       goto out_free;
+       }
        /* start the reclaim sioa */
        sioa = kmalloc(sizeof(struct sioa_args), GFP_KERNEL);
        if (!sioa) {
@@ -80,6 +90,7 @@ out_free:
        odf_put_info(osi->odi_rc);
        odf_put_info(osi->odi_sb);
        odf_put_info(osi->odi_ic);
+       dput(osi->whiteout);
        kfree(osi->branch_uuids);
        kfree(osi);
        osi = ERR_PTR(err);
@@ -101,6 +112,7 @@ void odf_put_super(struct odf_sb_info *osi)
        odf_put_info(osi->odi_sb);
        odf_put_info(osi->odi_ic);
        dput(osi->mnt->mnt_sb->s_root);
+       dput(osi->whiteout);
        mntput(osi->mnt);
        if (osi->cleanup)
                complete_sioa(osi->cleanup);
@@ -851,7 +863,7 @@ struct odf_dentry_info *__odf_lookup(struct odf_sb_info 
*osi,
        struct dentry *odf_dentry;
        struct odf_dentry_info *odi = old_odi;
        struct inode *odf_i_dir = parent->dentry->d_inode;
-       int opaque, whiteout, err = 0, cleaned = 0;
+       int opaque, err = 0, cleaned = 0;
        uid_t olduid;
        gid_t oldgid;
        
@@ -870,16 +882,16 @@ struct odf_dentry_info *__odf_lookup(struct odf_sb_info 
*osi,
        
        /* if create flags are set, remove existing whiteout */
        if (odf_dentry->d_inode && (flags & ODF_LOOKUP_RMV_WH)) {
-               if (__odf_is_wh(odf_dentry->d_inode)){
+               if (__odf_is_wh(osi, odf_dentry)){
                        vfs_unlink(odf_i_dir, odf_dentry);
                        dput(odf_dentry);
                        odf_dentry = lookup_one_len(name, parent->dentry, len);
                }
        }
        
-       /* if we should not lookup_wh if a non-wh entry exists */
+       /* we should not lookup_wh if a non-wh entry exists */
        if (flags & ODF_LOOKUP_WH)
-               BUG_ON(odf_dentry->d_inode && 
!__odf_is_wh(odf_dentry->d_inode));
+               BUG_ON(odf_dentry->d_inode && !__odf_is_wh(osi, odf_dentry));
 
        /* create inode in odf if dont exist */
        if (!odf_dentry->d_inode) {
@@ -901,13 +913,18 @@ retry:
 
                if (link && (flags & (ODF_LOOKUP_FILE | ODF_LOOKUP_LINK))) {
                        /* link to the given dentry */
-                       vfs_link(link, parent->dentry->d_inode, odf_dentry);
+                       vfs_link(link, odf_dentry->d_parent->d_inode, 
odf_dentry);
                }
-               else if (flags & ODF_LOOKUP_FILE || flags & ODF_LOOKUP_WH) {
+               else if (flags & ODF_LOOKUP_FILE) {
                        current->fsuid = 0;
                        current->fsgid = 0;
                        err = vfs_create(odf_i_dir, odf_dentry, S_IRWXUGO, 0 );
                }
+               else if (flags & ODF_LOOKUP_WH) {
+                       current->fsuid = 0;
+                       current->fsgid = 0;
+                       err = vfs_link(osi->whiteout, odf_i_dir, odf_dentry);
+               }
                else if (flags & ODF_LOOKUP_DIR) {
                        current->fsuid = 0;
                        current->fsgid = 0;
@@ -953,9 +970,7 @@ retry:
 
                /* set opaqueness to 0 or -1 */
                opaque = (flags & ODF_LOOKUP_OPQ) ? osi->opaque_branch_id : -1;
-               whiteout = (flags & ODF_LOOKUP_WH) ? 1 : 0;
                __odf_set_opaque(odf_dentry->d_inode, opaque);
-               __odf_set_wh(odf_dentry->d_inode,whiteout);
        }
        else {
                /* hardlinks, check if link inode is same as odf_dentry inode,
@@ -1205,20 +1220,18 @@ int odf_create_wh(struct dentry *dentry)
        struct dentry *odf_dentry;
        if (UNIONFS_D(dentry)->odf_info) {
                odf_dentry = UNIONFS_D(dentry)->odf_info->dentry;
-               if (__odf_is_wh(odf_dentry->d_inode))
+               if (__odf_is_wh(UNIONFS_D(dentry)->odf_info->osi, odf_dentry))
                        goto out;       /* nothing to be done */        
-       
                /* remove entry if existed */
                err = odf_remove(dentry, ODF_RMV_ANY);
                if (err)
                        goto out;
        }
        /* now create a new file and make it a whiteout */
-       err = odf_lookup(dentry->d_parent, dentry, ODF_LOOKUP_FILE);
+       err = odf_lookup(dentry->d_parent, dentry, ODF_LOOKUP_WH);
+
        if (err)
                goto out;
-       
-       err = odf_set_wh(dentry,1);
        odf_put_info(UNIONFS_D(dentry)->odf_info);
        UNIONFS_D(dentry)->odf_info = NULL;
 out:
@@ -1245,14 +1258,12 @@ int odf_remove(struct dentry *dentry, int flags)
                odi = NULL;
                goto out;
        }
-
        BUG_ON(!UNIONFS_D(dentry)->odf_info);
        odi = UNIONFS_D(dentry)->odf_info;
        if (!odi)
                goto out;
-       
        /* should we remove? */
-       if (odf_is_wh(dentry)) {
+       if (__odf_is_wh(odi->osi, odi->dentry)) {
                if (flags & ODF_RMV_WH)
                        rmv = 1;
        }
@@ -1260,7 +1271,6 @@ int odf_remove(struct dentry *dentry, int flags)
                if (flags & ODF_RMV_NOTWH)
                        rmv = 1;
        }
-
        if (!rmv)
                goto out;
        
@@ -1272,7 +1282,6 @@ int odf_remove(struct dentry *dentry, int flags)
                err = odf_reclaim(dentry);
        else 
                err = vfs_unlink(odi->dentry->d_parent->d_inode, odi->dentry);
-
        if (err)
                goto out_unlock;
 
@@ -1285,53 +1294,6 @@ out:
        return err;
 }
 
-/*
- * Sets the whiteout flag, the boolean decides whether to set whiteout on/off
- * The dentry version takes a UnionFS dentry, the inode one an ODF inode
- */
-/* FIXME: for the following functions can we count on EXT2 to do the locking? 
*/
-int odf_set_wh(struct dentry *dentry, int boolean)
-{
-       int err = __odf_set_wh(UNIONFS_D(dentry)->odf_info->dentry->d_inode, 
boolean);
-       if (!err) 
-               UNIONFS_D(dentry)->odf_info->whiteout = boolean;
-       return err;
-}
-int __odf_set_wh(struct inode *i, int boolean)
-{
-       int err = 0;
-       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)
-{
-       return __odf_is_wh(UNIONFS_D(dentry)->odf_info->dentry->d_inode);
-}
-int __odf_is_wh(struct inode *i)
-{
-       if (EXT2_I(i)->i_flags & ODF_WHITEOUT)
-               return 1;
-       return 0;
-}
-
-/*
- * 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(UNIONFS_D(dentry)->odf_info->dentry->d_inode);
-}
-
 /* The opaque number stored with the odf inode is that of the branch id
  * which is not necessarily the same as the branch position, so we need to
  * convert the branch id to the branch position
@@ -1357,28 +1319,9 @@ int odf_get_opaque(struct super_block *sb, struct dentry 
*dentry)
        return i;
 }
 
-int __odf_is_opaque(struct inode *i) 
-{
-       if (!S_ISDIR(i->i_mode))
-               return 0;
-       if (EXT2_I(i)->i_flags & ODF_OPAQUE)
-               return 1;
-       return 0;
-}
-
-/*
- * Gets opaque branch id from an inode, -1 if not opaque
- */
-int __odf_get_opaque(struct inode *i) 
-{
-       if (!__odf_is_opaque(i))
-               return -1;
-
-       return i->i_gid;
-}
-
 /*
- * Sets a dentry as opaque, if not use -1 for branch
+ * Sets a dentry as opaque. The branch must be the branch_id as stored in 
unionfs sb.
+ * If the dentry is not to be opaque, then branch must be -1
  * The dentry version takes a UnionFS dentry, the inode one an ODF inode
  */
 int odf_set_opaque(struct dentry *dentry, int branch)
@@ -1392,15 +1335,10 @@ int odf_set_opaque(struct dentry *dentry, int branch)
 
 int __odf_set_opaque(struct inode *i, int branch) 
 {
-       int err = 0;
-       if (branch < 0)
-               EXT2_I(i)->i_flags &= ~ODF_OPAQUE;
-       else {
-               EXT2_I(i)->i_flags |= ODF_OPAQUE;
-               i->i_gid = branch;
-       }
-       err = ext2_write_inode(i, 1);
-       return err;
+       struct iattr ia;
+       ia.ia_valid = ATTR_GID;
+       ia.ia_gid = branch + 1;  /* since gid is unsigned */
+       return inode_setattr(i, &ia);
 }
 
 /* 
@@ -1540,7 +1478,7 @@ int odf_write_sb_data(struct odf_sb_info* osi, struct 
unionfs_data *data, struct
                }
        }
        else {
-               err = vfs_create(d_odf_sb->d_inode, d_content, 0, NULL );
+               err = vfs_create(d_odf_sb->d_inode, d_content, S_IRWXUGO, NULL 
);
                if (err)
                        goto out;
        }
@@ -1806,7 +1744,7 @@ struct odf_dentry_info *odf_alloc_info(struct odf_sb_info 
*osi, struct dentry *o
 {
        struct odf_dentry_info *odi = 
                        kzalloc(sizeof(struct odf_dentry_info),GFP_KERNEL);
-       odi->whiteout = __odf_is_wh(odf_dentry->d_inode);
+       odi->whiteout = __odf_is_wh(osi, odf_dentry);
        odi->opaque = __odf_get_opaque(odf_dentry->d_inode);
        odi->dentry = odf_dentry;
        odi->inum = odf_dentry->d_inode->i_ino;
@@ -1819,7 +1757,7 @@ struct odf_dentry_info *odf_fill_info(struct 
odf_dentry_info *odi, struct odf_sb
 {
        if (!odi)
                return odf_alloc_info(osi, odf_dentry);
-       odi->whiteout = __odf_is_wh(odf_dentry->d_inode);
+       odi->whiteout = __odf_is_wh(osi, odf_dentry);
        odi->opaque = __odf_get_opaque(odf_dentry->d_inode);
        dget(odf_dentry);
        dput(odi->dentry);
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index 8126cc5..03ebbee 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -39,8 +39,11 @@
 
 #define ODF_DIRENT_MAGIC 0x0DFD1300
 
+/* special filenames */
 #define ODF_CONTENT "content"
 #define ODF_CONTENT_LEN 7
+#define ODF_WH_NAME "whiteout"
+#define ODF_WH_LEN 8
 
 #define ODF_CLEAN_ALL 1
 #define ODF_CLEAN_CACHE 2
@@ -100,19 +103,26 @@ int odf_remove(struct dentry *dentry, int flags);
 int odf_reclaim(struct dentry *dentry);
 
 /* whiteouts */
-int odf_set_wh(struct dentry *dentry, int boolean);
-int odf_is_wh(struct dentry *dentry);
-int __odf_set_wh(struct inode *i, int boolean);
-int __odf_is_wh(struct inode *i);
 int odf_create_wh(struct dentry *dentry);
+static inline int __odf_is_wh(struct odf_sb_info *osi, struct dentry *dentry)
+{
+       if (!osi->whiteout)
+               return 0;
+       return osi->whiteout->d_inode->i_ino == dentry->d_inode->i_ino;
+}
+static inline int odf_is_wh(struct odf_dentry_info *odi)
+{
+       return __odf_is_wh(odi->osi, odi->dentry);
+}
 
 /* opaque */
 int odf_is_opaque(struct dentry *dentry);
 int odf_get_opaque(struct super_block *sb, struct dentry *dentry);
 int odf_set_opaque(struct dentry *dentry, int branch);
 int __odf_is_opaque(struct inode *i);
-int __odf_get_opaque(struct inode *i);
+//int __odf_get_opaque(struct inode *i);
 int __odf_set_opaque(struct inode *i, int branch);
+#define __odf_get_opaque(i) (i->i_gid -1)
 
 /* cleanup thread functions */
 extern void __odf_cleanup(void *args);
diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h
index 05dd8b2..c1b5f27 100644
--- a/fs/unionfs/union.h
+++ b/fs/unionfs/union.h
@@ -112,6 +112,7 @@ struct odf_sb_info {
        struct sioa_args *cleanup;      /* our cleanup thread */
        char *branch_uuids;   /* not null terminated string of all branch 
uuids*/
        int opaque_branch_id; /* should always be the branch id of branch 0*/
+       struct dentry *whiteout;
 };
 
 /* unionfs inode data in memory */
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to