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