Message ID | 51E65F5A.6050501@giantdisaster.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Jul 17, 2013 at 11:09:46AM +0200, Stefan Behrens wrote: > On Wed, 17 Jul 2013 16:29:05 +0800, Anand Jain wrote: > > 'btrfs fi label /btrfs' will hang until balance is completed. > > (and probably even set label would hang). This is because we > > are trying to hold volume_mutex lock which balance will hold > > during its tenure. > > > > ------- > > static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) > > :: > > mutex_lock(&root->fs_info->volume_mutex); > > ret = copy_to_user(arg, label, len); > > mutex_unlock(&root->fs_info->volume_mutex); > > -------- > > > > I doubt if get label would need such a heavy weight lock? > > Do we have any other lock which could fit better here ? > > Any comments ? > > Just use the uuid_mutex instead of the volume_mutex. I wouldn't copy_to_user() with the lock held. That nests all of readpage and mkwrite under the mutex creating more possibilities for deadlocks. Whatever lock is chosen, I'd have get copy the label onto the kernel stack before sending it to user space. - z -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 2177bea..30a8126 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -4043,15 +4043,16 @@ static int btrfs_ioctl_get_fslabel(struct file *file, vo { struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; const char *label = root->fs_info->super_copy->label; - size_t len = strnlen(label, BTRFS_LABEL_SIZE); + size_t len; int ret; + mutex_lock(&root->fs_info->volume_mutex); + len = strnlen(label, BTRFS_LABEL_SIZE); if (len == BTRFS_LABEL_SIZE) { pr_warn("btrfs: label is too long, return the first %zu bytes\n" --len); } - mutex_lock(&root->fs_info->volume_mutex); ret = copy_to_user(arg, label, len);