ocfs2: manually d_move() during ocfs2_rename()
authorMark Fasheh <mark.fasheh@oracle.com>
Fri, 8 Sep 2006 21:22:54 +0000 (14:22 -0700)
committerMark Fasheh <mark.fasheh@oracle.com>
Sun, 24 Sep 2006 20:50:45 +0000 (13:50 -0700)
Make use of FS_RENAME_DOES_D_MOVE to avoid a race condition that can occur
during ->rename() if we d_move() outside of the parent directory cluster
locks, and another node discovers the new name (created during the rename)
and unlinks it. d_move() will unconditionally rehash a dentry - which will
leave stale data in the system.

Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
fs/ocfs2/dcache.c
fs/ocfs2/super.c

index 09efe24..18a3190 100644 (file)
@@ -414,7 +414,7 @@ void ocfs2_dentry_move(struct dentry *dentry, struct dentry *target,
         * XXX: Is there any advantage to dropping the lock here?
         */
        if (old_dir == new_dir)
-               return;
+               goto out_move;
 
        ocfs2_dentry_lock_put(osb, dentry->d_fsdata);
 
@@ -423,6 +423,9 @@ void ocfs2_dentry_move(struct dentry *dentry, struct dentry *target,
                                       OCFS2_I(new_dir)->ip_blkno, 0);
        if (ret)
                mlog_errno(ret);
+
+out_move:
+       d_move(dentry, target);
 }
 
 struct dentry_operations ocfs2_dentry_ops = {
index d17e33e..33a6de6 100644 (file)
@@ -682,7 +682,7 @@ static struct file_system_type ocfs2_fs_type = {
        .kill_sb        = kill_block_super, /* set to the generic one
                                             * right now, but do we
                                             * need to change that? */
-       .fs_flags       = FS_REQUIRES_DEV,
+       .fs_flags       = FS_REQUIRES_DEV|FS_RENAME_DOES_D_MOVE,
        .next           = NULL
 };