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