commit e635b39bf167604dd1b83ef9ff7e3783a503d0f3
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date: Tue Feb 6 18:59:05 2007 -0500
Fixed unlink and rmdir to go L->R removing and create wh only on failure
Fixed inode create to remove wh
+ some other whiteout related fixes
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index 1926eed..ec33a01 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -1891,7 +1891,7 @@ struct odf_dentry_info *odf_fill_info(struct
odf_dentry_info *odi, struct odf_sb
*/
void odf_put_info(struct odf_dentry_info *odi)
{
- if (!odi)
+ if (!(*odi))
return;
dput(odi->dentry);
kfree(odi);
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index a04284e..12271af 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -36,6 +36,11 @@
#define ODF_RMV_NOTWH 2
#define ODF_RMV_ANY (ODF_RMV_WH|ODF_RMV_NOTWH)
+/* Unlink/Remove flags */
+#define ODF_RMV_WH 1
+#define ODF_RMV_NOTWH 2
+#define ODF_RMV_ANY (ODF_RMV_WH|ODF_RMV_NOTWH)
+
/* Inode flags */
#define ODF_WHITEOUT FS_SECRM_FL //0x01000000
#define ODF_OPAQUE FS_COMPR_FL // 0x02000000
diff --git a/fs/unionfs/unlink.c b/fs/unionfs/unlink.c
index 88fd6b6..823e54c 100644
--- a/fs/unionfs/unlink.c
+++ b/fs/unionfs/unlink.c
@@ -86,6 +86,56 @@ out:
return err;
}
+static int unionfs_do_unlink(struct inode *dir, struct dentry *dentry)
+{
+ struct dentry *hidden_dentry;
+ struct dentry *hidden_dir_dentry;
+ int bstart, bend, bindex;
+ int err = 0;
+
+ if ((err = unionfs_partial_lookup(dentry)))
+ goto out;
+
+ bstart = dbstart(dentry);
+ bend = dbend(dentry);
+
+ for (bindex = bstart; bindex <= bend; bindex++) {
+ hidden_dentry = unionfs_lower_dentry_idx(dentry, bindex);
+ if (!hidden_dentry)
+ continue;
+
+ hidden_dir_dentry = lock_parent(hidden_dentry);
+
+ /* avoid destroying the hidden inode if the file is in use */
+ dget(hidden_dentry);
+ if (!(err = is_robranch_super(dentry->d_sb, bindex)))
+ err = vfs_unlink(hidden_dir_dentry->d_inode,
hidden_dentry);
+ else
+ err = -EROFS;
+ dput(hidden_dentry);
+ fsstack_copy_attr_times(dir, hidden_dir_dentry->d_inode);
+ unlock_dir(hidden_dir_dentry);
+
+ if (err)
+ break;
+ }
+
+ if (err) {
+ if (err == -EIO)
+ printk(KERN_WARNING "unionfs_unlink: IO error unlinking
from branch %d\n", bindex);
+ err = odf_create_wh(dentry);
+ }
+
+out:
+ if (!err)
+ dentry->d_inode->i_nlink--;
+
+ /* We don't want to leave negative leftover dentries for revalidate. */
+ if (!err && (dbopaque(dentry) != -1))
+ update_bstart(dentry);
+
+ return err;
+}
int unionfs_unlink(struct inode *dir, struct dentry *dentry)
{
@@ -178,7 +228,7 @@ out:
int unionfs_rmdir(struct inode *dir, struct dentry *dentry)
{
int err = 0;
- struct unionfs_dir_state *namelist = NULL;
+ struct unionfs_dir_state *namelist = NULL; /* FIXME: dont need this now
*/
BUG_ON(!is_valid_dentry(dentry));
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs