commit c13631e0f366c99b64a2e6a852900cf8f9272f1f
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Sun Mar 4 20:03:40 2007 -0500

    silly rename and other rename fixes

diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c
index a8b59ec..5ebdd8f 100644
--- a/fs/unionfs/dirhelper.c
+++ b/fs/unionfs/dirhelper.c
@@ -893,3 +893,91 @@ out:
 
        return err;
 }
+
+/* Remove the hidden dentry by:
+ *     a) rmdir if its a physically empty dir
+ *     b) silly rename if its not physically empty
+ *     c) unlink if not a dir
+ */
+int unionfs_force_rm(struct dentry *dentry, struct dentry **hidden_dentry, int 
bindex) 
+{
+       struct file *hidden_file;
+       struct super_block *sb;
+       struct unionfs_rdutil_callback *buf = NULL;
+       int err;
+
+       sb = dentry->d_sb;
+       if (!S_ISDIR((*hidden_dentry)->d_inode->i_mode)) {
+               err = vfs_unlink((*hidden_dentry)->d_parent->d_inode, 
+                                               (*hidden_dentry));
+               if (err)
+                       goto out;
+               goto refresh;
+       }
+
+       /* check if dir is empty */
+       buf = kmalloc(sizeof(struct unionfs_rdutil_callback), GFP_KERNEL);
+       if (!buf) {
+               err = -ENOMEM;
+               goto out;
+       }
+       buf->err = 0;
+       buf->mode = RD_CHECK_HD_EMPTY;
+       buf->rdstate = NULL;
+       buf->dir = NULL;
+       buf->filp = NULL;
+
+       dget(*hidden_dentry);
+       mntget(unionfs_lower_mnt_idx(dentry, bindex));
+       branchget(sb, bindex);
+       hidden_file = dentry_open(*hidden_dentry, 
+                       unionfs_lower_mnt_idx(dentry, bindex),
+                       O_RDONLY);
+       if (IS_ERR(hidden_file)) {
+               err = PTR_ERR(hidden_file);
+               dput(*hidden_dentry);
+               branchput(sb, bindex);
+               goto out;
+       }
+
+       do {
+               buf->filldir_called = 0;
+               err = vfs_readdir(hidden_file,
+                                 readdir_util_callback, buf);
+                       if (buf->err)
+                               err = buf->err;
+       } while ((err >= 0) && buf->filldir_called);
+
+       /* fput calls dput for hidden_dentry */
+       fput(hidden_file);
+       branchput(sb, bindex);
+
+       if (err == 0)
+               err = vfs_rmdir((*hidden_dentry)->d_parent->d_inode, 
*hidden_dentry);
+       
+       else if (err == -ENOTEMPTY)
+               err = unionfs_silly_rename(dentry, *hidden_dentry);
+
+       if (err)
+               goto out;
+
+refresh:
+       *hidden_dentry = lookup_one_len(dentry->d_name.name, 
+                               (*hidden_dentry)->d_parent,
+                               dentry->d_name.len);
+       if (IS_ERR(*hidden_dentry)) {
+               err = PTR_ERR(*hidden_dentry);
+               goto out;
+       }
+       BUG_ON((*hidden_dentry)->d_inode);
+       dput(unionfs_lower_dentry_idx(dentry, bindex));
+       if (dentry->d_inode) {
+               iput(unionfs_lower_inode_idx(dentry->d_inode, bindex));
+               unionfs_set_lower_inode_idx(dentry->d_inode, bindex, NULL);
+       }
+       unionfs_set_lower_dentry_idx(dentry, bindex, *hidden_dentry);
+out:
+       if (buf)
+               kfree(buf);
+       return err;
+}
diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c
index fea2514..acf8a6f 100644
--- a/fs/unionfs/inode.c
+++ b/fs/unionfs/inode.c
@@ -18,24 +18,6 @@
 
 #include "union.h"
 
-static int do_force_rm(struct dentry *dentry, struct dentry *hidden_dentry, 
int bindex)
-{
-       int err;
-
-       /* this should only happen if its a wh */
-       BUG_ON(!UNIONFS_D(dentry)->odf_info->whiteout);
-               
-       /* try to remove it! */
-       if (S_ISDIR(hidden_dentry->d_inode->i_mode))
-               err = unionfs_force_rmdir(unionfs_lower_mnt_idx(dentry, 
bindex), 
-                                       hidden_dentry, bindex);
-
-       else
-               err = vfs_unlink(hidden_dentry->d_parent->d_inode,
-                                               hidden_dentry);
-       return err;
-}
-
 static int unionfs_create(struct inode *parent, struct dentry *dentry,
                          int mode, struct nameidata *nd)
 {
diff --git a/fs/unionfs/rename.c b/fs/unionfs/rename.c
index d9d082e..730e96f 100644
--- a/fs/unionfs/rename.c
+++ b/fs/unionfs/rename.c
@@ -230,7 +230,6 @@ out:
 
 revert:
        /* Do revert here. */
-       /* FIXME: revert odf also? only if create_wh_fails? */
        local_err = unionfs_refresh_hidden_dentry(new_dentry, old_bstart);
        if (local_err) {
                printk(KERN_WARNING "Revert failed in rename: the new refresh "
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to