aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2010-11-19 15:36:10 -0500
committerChris Mason <chris.mason@oracle.com>2010-11-21 22:26:09 -0500
commit495e86779f4f319828bc10dfc0c9ac2161868077 (patch)
tree62729f2b65c9565fadb551bd8d343d6c57d7cb85
parent6a912213046ecb6511fdf35531a0c7de3de963c9 (diff)
Btrfs: hold i_mutex when calling btrfs_log_dentry_safe
Since we walk up the path logging all of the parts of the inode's path, we need to hold i_mutex to make sure that the inode is not renamed while we're logging everything. btrfs_log_dentry_safe does dget_parent and all of that jazz, but we may get unexpected results if the rename changes the inode's location while we're higher up the path logging those dentries, so do this for safety reasons. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/file.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index e354c33df082..c1faded5fca0 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1047,8 +1047,14 @@ out:
1047 1047
1048 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { 1048 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
1049 trans = btrfs_start_transaction(root, 0); 1049 trans = btrfs_start_transaction(root, 0);
1050 if (IS_ERR(trans)) {
1051 num_written = PTR_ERR(trans);
1052 goto done;
1053 }
1054 mutex_lock(&inode->i_mutex);
1050 ret = btrfs_log_dentry_safe(trans, root, 1055 ret = btrfs_log_dentry_safe(trans, root,
1051 file->f_dentry); 1056 file->f_dentry);
1057 mutex_unlock(&inode->i_mutex);
1052 if (ret == 0) { 1058 if (ret == 0) {
1053 ret = btrfs_sync_log(trans, root); 1059 ret = btrfs_sync_log(trans, root);
1054 if (ret == 0) 1060 if (ret == 0)
@@ -1067,6 +1073,7 @@ out:
1067 (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT); 1073 (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT);
1068 } 1074 }
1069 } 1075 }
1076done:
1070 current->backing_dev_info = NULL; 1077 current->backing_dev_info = NULL;
1071 return num_written ? num_written : err; 1078 return num_written ? num_written : err;
1072} 1079}