aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnand Jain <Anand.Jain@oracle.com>2013-07-19 05:39:32 -0400
committerChris Mason <chris.mason@fusionio.com>2013-09-01 08:04:15 -0400
commita1b83ac52d23c85581b87836c346fb5cb90f6bfd (patch)
tree2c4a8512cc3c6e8f464082b3c98c20fc98fd08ba
parentd4c34f6bffe246bcf05a1471873667d678a47a54 (diff)
btrfs: fix get set label blocking against balance
btrfs_ioctl_get_fslabel() and btrfs_ioctl_set_fslabel() used root->fs_info->volume_mutex mutex which caused operations like balance to block set/get label operation until its completion and generally balance operation takes a long time to complete, so it will be annoying to the user when cli appears hung also this patch will add a bit of optimization within the btrfs_ioctl_get_falabel() function. v1->v2: use fs_info->super_lock instead of uuid_mutex Signed-off-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
-rw-r--r--fs/btrfs/ioctl.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index f856c97952db..556b3d5b18da 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -4042,18 +4042,22 @@ out:
4042static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) 4042static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg)
4043{ 4043{
4044 struct btrfs_root *root = BTRFS_I(file_inode(file))->root; 4044 struct btrfs_root *root = BTRFS_I(file_inode(file))->root;
4045 const char *label = root->fs_info->super_copy->label; 4045 size_t len;
4046 size_t len = strnlen(label, BTRFS_LABEL_SIZE);
4047 int ret; 4046 int ret;
4047 char label[BTRFS_LABEL_SIZE];
4048
4049 spin_lock(&root->fs_info->super_lock);
4050 memcpy(label, root->fs_info->super_copy->label, BTRFS_LABEL_SIZE);
4051 spin_unlock(&root->fs_info->super_lock);
4052
4053 len = strnlen(label, BTRFS_LABEL_SIZE);
4048 4054
4049 if (len == BTRFS_LABEL_SIZE) { 4055 if (len == BTRFS_LABEL_SIZE) {
4050 pr_warn("btrfs: label is too long, return the first %zu bytes\n", 4056 pr_warn("btrfs: label is too long, return the first %zu bytes\n",
4051 --len); 4057 --len);
4052 } 4058 }
4053 4059
4054 mutex_lock(&root->fs_info->volume_mutex);
4055 ret = copy_to_user(arg, label, len); 4060 ret = copy_to_user(arg, label, len);
4056 mutex_unlock(&root->fs_info->volume_mutex);
4057 4061
4058 return ret ? -EFAULT : 0; 4062 return ret ? -EFAULT : 0;
4059} 4063}
@@ -4082,18 +4086,18 @@ static int btrfs_ioctl_set_fslabel(struct file *file, void __user *arg)
4082 if (ret) 4086 if (ret)
4083 return ret; 4087 return ret;
4084 4088
4085 mutex_lock(&root->fs_info->volume_mutex);
4086 trans = btrfs_start_transaction(root, 0); 4089 trans = btrfs_start_transaction(root, 0);
4087 if (IS_ERR(trans)) { 4090 if (IS_ERR(trans)) {
4088 ret = PTR_ERR(trans); 4091 ret = PTR_ERR(trans);
4089 goto out_unlock; 4092 goto out_unlock;
4090 } 4093 }
4091 4094
4095 spin_lock(&root->fs_info->super_lock);
4092 strcpy(super_block->label, label); 4096 strcpy(super_block->label, label);
4097 spin_unlock(&root->fs_info->super_lock);
4093 ret = btrfs_end_transaction(trans, root); 4098 ret = btrfs_end_transaction(trans, root);
4094 4099
4095out_unlock: 4100out_unlock:
4096 mutex_unlock(&root->fs_info->volume_mutex);
4097 mnt_drop_write_file(file); 4101 mnt_drop_write_file(file);
4098 return ret; 4102 return ret;
4099} 4103}