commit e853e661fe3db950a242b4412e9a21e665bf3c04
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Tue May 22 15:27:52 2007 -0400

    rename bug: return EXDEV when destinations parent is opaque at a branch to 
the left of
    
    source's start branch

diff --git a/fs/unionfs/rename.c b/fs/unionfs/rename.c
index 9f0214e..b5ebc5a 100644
--- a/fs/unionfs/rename.c
+++ b/fs/unionfs/rename.c
@@ -176,6 +176,12 @@ static int do_unionfs_rename(struct inode *old_dir,
                }
        }
 
+       /* dont try to rename past new_dir's opaque branch */
+       if (new_opaque != -1 && new_opaque < old_bend) {
+               old_bend = new_opaque;
+               whiteout = 1;
+       }
+
        /* Rename source to destination. */
        for (bindex = old_bstart; bindex <= old_bend; bindex++) {
                err = __unionfs_rename(old_dir, old_dentry, new_dir, 
new_dentry, bindex);
@@ -302,18 +308,24 @@ revert_out:
  * be bad, so instead we let the user-space recurse and ask us
  * to copy up each file separately
  */
-static int may_rename_dir(struct dentry *dentry)
+static int may_rename_dir(struct dentry *dentry, struct dentry *new_dir)
 {
-       int err, bstart;
+       int err, bstart, opaque;
 
+       bstart = dbstart(dentry);
        err = check_empty(dentry, NULL);
        if (err == -ENOTEMPTY) {
                if (is_robranch(dentry))
                        return -EXDEV;
+
+               /* if new dir is opaque we may have to copyup */
+               opaque = odf_get_opaque(new_dir->d_sb, new_dir);
+               if (opaque != -1 && opaque < bstart)
+                       return -EXDEV;
+
        } else if (err)
                return err;
 
-       bstart = dbstart(dentry);
        if (dbend(dentry) == bstart || odf_get_opaque(dentry->d_sb, dentry) == 
bstart)
                return 0;
 
@@ -339,7 +351,7 @@ int unionfs_rename(struct inode *old_dir, struct dentry 
*old_dentry,
        if (!S_ISDIR(old_dentry->d_inode->i_mode))
                err = unionfs_partial_lookup(old_dentry);
        else
-               err = may_rename_dir(old_dentry);
+               err = may_rename_dir(old_dentry, new_dentry->d_parent);
 
        if (err)
                goto out;
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to