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

Reply via email to