commit ff4bba69102e8edbe15f9a4d928756e8633bad2a
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Sun Mar 25 20:10:40 2007 -0400

    fixed opaqueness with remounts
    
    store opaque branch no in gid instead of inode flags
    removed old dbopaque code

diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c
index 327c8f7..e84b699 100644
--- a/fs/unionfs/dirhelper.c
+++ b/fs/unionfs/dirhelper.c
@@ -754,7 +754,7 @@ retry:
 
        bstart = dbstart(d_upper);
        bend = dbend(d_upper);
-       bopaque = dbopaque(d_upper);
+       bopaque = odf_get_opaque(sb, d_upper);
        if (0 <= bopaque && bopaque < bend)
                bend = bopaque;
 
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index ebbc34f..417ee33 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -1396,7 +1396,7 @@ struct odf_dentry_info *odf_ic_dir(struct dentry *dir)
 
        memset(name,0,6);
        sprintf(name, "%x", breakdown[0]);
-       odis[0] = __odf_lookup(odi_ic, osi, name, strlen(name), ODF_LOOKUP_DIR, 
NULL);
+       odis[0] = __odf_lookup(osi, odi_ic, name, strlen(name), ODF_LOOKUP_DIR, 
NULL);
        if (IS_ERR(odis[0])) {
                err = PTR_ERR(odis[0]);
                odis[0] = NULL;
@@ -1405,7 +1405,7 @@ struct odf_dentry_info *odf_ic_dir(struct dentry *dir)
        for (i = 1; i < 4; i++) {
                memset(name,0,6);
                sprintf(name, "%x", breakdown[i]);
-               odis[i] = __odf_lookup(odis[i-1], osi, name, strlen(name), 
ODF_LOOKUP_DIR, NULL);
+               odis[i] = __odf_lookup(osi, odis[i-1], name, strlen(name), 
ODF_LOOKUP_DIR, NULL);
                if (IS_ERR(odis[i])) {
                        err = PTR_ERR(odis[i]);
                        odis[i] = NULL;
@@ -1413,7 +1413,7 @@ struct odf_dentry_info *odf_ic_dir(struct dentry *dir)
                }
        }
        
-       odi_ret = __odf_lookup(odis[3], osi, ODF_CONTENT, ODF_CONTENT_LEN, 
ODF_LOOKUP_FILE, NULL);
+       odi_ret = __odf_lookup(osi, odis[3], ODF_CONTENT, ODF_CONTENT_LEN, 
ODF_LOOKUP_FILE, NULL);
        if (IS_ERR(odi_ret)) {
                err = PTR_ERR(odi_ret);
                odi_ret = NULL;
@@ -1724,6 +1724,31 @@ 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
+ */
+int odf_get_opaque(struct super_block *sb, struct dentry *dentry) 
+{
+       int i, opaque = UNIONFS_D(dentry)->odf_info->opaque;
+       
+       if (opaque == -1)
+               return -1;
+
+       /* now check all branches for the branch id */
+       for (i = 0; i < sbmax(sb); i++) {
+               if (branch_id(sb, i) == opaque)
+                       return i;
+       }
+
+       /* if this is reached then the opaque branch was deleted, so dentry
+        * can no longer be considered opaque
+        */
+       odf_set_opaque(dentry, -1);
+       return -1;
+}
+
 int __odf_is_opaque(struct inode *i) 
 {
        if (!S_ISDIR(i->i_mode))
@@ -1732,25 +1757,16 @@ int __odf_is_opaque(struct inode *i)
                return 1;
        return 0;
 }
+
 /*
- * Gets opaque branch of a dentry, -1 if not opaque
- * The dentry version takes a UnionFS dentry, the inode one an ODF inode
+ * Gets opaque branch id from an inode, -1 if not opaque
  */
-int odf_get_opaque(struct dentry *dentry) 
-{
-       return __odf_get_opaque(UNIONFS_D(dentry)->odf_info->dentry->d_inode);
-}
 int __odf_get_opaque(struct inode *i) 
 {
-       u32 res = 0;
        if (!__odf_is_opaque(i))
                return -1;
 
-       /* get bits 26-30 */
-       res = EXT2_I(i)->i_flags;
-       res <<= 1;
-       res >>= (ODF_OPQ_BASE + 1);
-       return res;
+       return i->i_gid;
 }
 
 /*
@@ -1768,14 +1784,12 @@ int odf_set_opaque(struct dentry *dentry, int branch)
 
 int __odf_set_opaque(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);
+               EXT2_I(i)->i_flags |= ODF_OPAQUE;
+               i->i_gid = branch;
        }
        err = ext2_write_inode(i, 1);
        return err;
@@ -1905,15 +1919,6 @@ int odf_write_sb_data(struct odf_sb_info* osi, struct 
unionfs_data *data, struct
        d_odf_sb = osi->odi_sb->dentry;
        odf_mnt = osi->mnt;
 
-       /* check the number of branches */
-       if (branches >= (1 << ODF_OPQ_BITS)) {
-               printk(KERN_WARNING "unionfs: too many branches (%d), "
-                       "odf can only support %d branches\n",
-                       branches, (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;
diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h
index d819f56..81b32b0 100644
--- a/fs/unionfs/union.h
+++ b/fs/unionfs/union.h
@@ -123,6 +123,7 @@ struct odf_sb_info {
        struct odf_dentry_info *odi_rc;
        struct odf_dentry_info *odi_ic;
        struct sioa_args *cleanup;
+       int opaque_branch_id; /* should always be the branch id of branch 0*/
 };
 
 /* unionfs inode data in memory */
diff --git a/fs/unionfs/unlink.c b/fs/unionfs/unlink.c
index 5fb8088..6f0c032 100644
--- a/fs/unionfs/unlink.c
+++ b/fs/unionfs/unlink.c
@@ -145,7 +145,7 @@ out:
                dentry->d_inode->i_nlink--;
 
        /* We don't want to leave negative leftover dentries for revalidate. */
-       if (!err && (dbopaque(dentry) != -1))
+       if (!err && (odf_get_opaque(dentry->d_sb,dentry) != -1))
                update_bstart(dentry);
 
        return err;
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to