commit 7f358bef4fcba7991c5d84ffe288c9047d1d21e0
Author: Rachita Kothiyal <[EMAIL PROTECTED]>
Date: Wed Mar 26 17:39:09 2008 -0400
Unionfs: lock_rename related locking fixes
CC: Mike Halcrow <[EMAIL PROTECTED]>
Signed-off-by: Erez Zadok <[EMAIL PROTECTED]>
diff --git a/fs/unionfs/rename.c b/fs/unionfs/rename.c
index 05867f4..19c8fe7 100644
--- a/fs/unionfs/rename.c
+++ b/fs/unionfs/rename.c
@@ -77,6 +77,7 @@ static int __unionfs_rename(struct inode *old_dir, struct
dentry *old_dentry,
struct dentry *lower_new_dentry;
struct dentry *lower_old_dir_dentry;
struct dentry *lower_new_dir_dentry;
+ struct dentry *trap;
lower_new_dentry = unionfs_lower_dentry_idx(new_dentry, bindex);
lower_old_dentry = unionfs_lower_dentry_idx(old_dentry, bindex);
@@ -104,20 +105,34 @@ static int __unionfs_rename(struct inode *old_dir, struct
dentry *old_dentry,
goto out;
dget(lower_old_dentry);
+ dget(lower_new_dentry);
lower_old_dir_dentry = dget_parent(lower_old_dentry);
lower_new_dir_dentry = dget_parent(lower_new_dentry);
/* see Documentation/filesystems/unionfs/issues.txt */
lockdep_off();
- lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
+ trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
+ /* source should not be ancenstor of target */
+ if (trap == lower_old_dentry) {
+ err = -EINVAL;
+ goto out_err_unlock;
+ }
+ /* target should not be ancenstor of source */
+ if (trap == lower_new_dentry) {
+ err = -ENOTEMPTY;
+ goto out_err_unlock;
+ }
err = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
lower_new_dir_dentry->d_inode, lower_new_dentry);
+
+out_err_unlock:
unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
lockdep_on();
dput(lower_old_dir_dentry);
dput(lower_new_dir_dentry);
dput(lower_old_dentry);
+ dput(lower_new_dentry);
out:
if (!err) {
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs