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