diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-06-25 16:01:30 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:03 -0400 |
commit | a213501153fd66e2359e091b1612841305ba6551 (patch) | |
tree | 1f4c316c9d3cad0eb6d9be14cb0e67e46e815dce /fs/btrfs/ioctl.c | |
parent | 925baeddc5b0764a53f2214a1253251bab0e0324 (diff) |
Btrfs: Replace the big fs_mutex with a collection of other locks
Extent alloctions are still protected by a large alloc_mutex.
Objectid allocations are covered by a objectid mutex
Other btree operations are protected by a lock on individual btree nodes
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 24 |
1 files changed, 6 insertions, 18 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 3fbf74e93dba..6002eb64daf9 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -63,7 +63,6 @@ static noinline int create_subvol(struct btrfs_root *root, char *name, | |||
63 | u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; | 63 | u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; |
64 | unsigned long nr = 1; | 64 | unsigned long nr = 1; |
65 | 65 | ||
66 | mutex_lock(&root->fs_info->fs_mutex); | ||
67 | ret = btrfs_check_free_space(root, 1, 0); | 66 | ret = btrfs_check_free_space(root, 1, 0); |
68 | if (ret) | 67 | if (ret) |
69 | goto fail_commit; | 68 | goto fail_commit; |
@@ -164,7 +163,6 @@ fail: | |||
164 | if (err && !ret) | 163 | if (err && !ret) |
165 | ret = err; | 164 | ret = err; |
166 | fail_commit: | 165 | fail_commit: |
167 | mutex_unlock(&root->fs_info->fs_mutex); | ||
168 | btrfs_btree_balance_dirty(root, nr); | 166 | btrfs_btree_balance_dirty(root, nr); |
169 | btrfs_throttle(root); | 167 | btrfs_throttle(root); |
170 | return ret; | 168 | return ret; |
@@ -181,7 +179,6 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
181 | if (!root->ref_cows) | 179 | if (!root->ref_cows) |
182 | return -EINVAL; | 180 | return -EINVAL; |
183 | 181 | ||
184 | mutex_lock(&root->fs_info->fs_mutex); | ||
185 | ret = btrfs_check_free_space(root, 1, 0); | 182 | ret = btrfs_check_free_space(root, 1, 0); |
186 | if (ret) | 183 | if (ret) |
187 | goto fail_unlock; | 184 | goto fail_unlock; |
@@ -208,7 +205,6 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
208 | err = btrfs_commit_transaction(trans, root); | 205 | err = btrfs_commit_transaction(trans, root); |
209 | 206 | ||
210 | fail_unlock: | 207 | fail_unlock: |
211 | mutex_unlock(&root->fs_info->fs_mutex); | ||
212 | btrfs_btree_balance_dirty(root, nr); | 208 | btrfs_btree_balance_dirty(root, nr); |
213 | btrfs_throttle(root); | 209 | btrfs_throttle(root); |
214 | return ret; | 210 | return ret; |
@@ -228,9 +224,7 @@ int btrfs_defrag_file(struct file *file) | |||
228 | unsigned long i; | 224 | unsigned long i; |
229 | int ret; | 225 | int ret; |
230 | 226 | ||
231 | mutex_lock(&root->fs_info->fs_mutex); | ||
232 | ret = btrfs_check_free_space(root, inode->i_size, 0); | 227 | ret = btrfs_check_free_space(root, inode->i_size, 0); |
233 | mutex_unlock(&root->fs_info->fs_mutex); | ||
234 | if (ret) | 228 | if (ret) |
235 | return -ENOSPC; | 229 | return -ENOSPC; |
236 | 230 | ||
@@ -315,7 +309,8 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) | |||
315 | goto out; | 309 | goto out; |
316 | } | 310 | } |
317 | 311 | ||
318 | mutex_lock(&root->fs_info->fs_mutex); | 312 | mutex_lock(&root->fs_info->alloc_mutex); |
313 | mutex_lock(&root->fs_info->chunk_mutex); | ||
319 | sizestr = vol_args->name; | 314 | sizestr = vol_args->name; |
320 | devstr = strchr(sizestr, ':'); | 315 | devstr = strchr(sizestr, ':'); |
321 | if (devstr) { | 316 | if (devstr) { |
@@ -385,7 +380,8 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) | |||
385 | } | 380 | } |
386 | 381 | ||
387 | out_unlock: | 382 | out_unlock: |
388 | mutex_unlock(&root->fs_info->fs_mutex); | 383 | mutex_lock(&root->fs_info->alloc_mutex); |
384 | mutex_lock(&root->fs_info->chunk_mutex); | ||
389 | out: | 385 | out: |
390 | kfree(vol_args); | 386 | kfree(vol_args); |
391 | return ret; | 387 | return ret; |
@@ -428,11 +424,9 @@ static noinline int btrfs_ioctl_snap_create(struct btrfs_root *root, | |||
428 | } | 424 | } |
429 | 425 | ||
430 | root_dirid = root->fs_info->sb->s_root->d_inode->i_ino, | 426 | root_dirid = root->fs_info->sb->s_root->d_inode->i_ino, |
431 | mutex_lock(&root->fs_info->fs_mutex); | ||
432 | di = btrfs_lookup_dir_item(NULL, root->fs_info->tree_root, | 427 | di = btrfs_lookup_dir_item(NULL, root->fs_info->tree_root, |
433 | path, root_dirid, | 428 | path, root_dirid, |
434 | vol_args->name, namelen, 0); | 429 | vol_args->name, namelen, 0); |
435 | mutex_unlock(&root->fs_info->fs_mutex); | ||
436 | btrfs_free_path(path); | 430 | btrfs_free_path(path); |
437 | 431 | ||
438 | if (di && !IS_ERR(di)) { | 432 | if (di && !IS_ERR(di)) { |
@@ -445,10 +439,12 @@ static noinline int btrfs_ioctl_snap_create(struct btrfs_root *root, | |||
445 | goto out; | 439 | goto out; |
446 | } | 440 | } |
447 | 441 | ||
442 | mutex_lock(&root->fs_info->drop_mutex); | ||
448 | if (root == root->fs_info->tree_root) | 443 | if (root == root->fs_info->tree_root) |
449 | ret = create_subvol(root, vol_args->name, namelen); | 444 | ret = create_subvol(root, vol_args->name, namelen); |
450 | else | 445 | else |
451 | ret = create_snapshot(root, vol_args->name, namelen); | 446 | ret = create_snapshot(root, vol_args->name, namelen); |
447 | mutex_unlock(&root->fs_info->drop_mutex); | ||
452 | out: | 448 | out: |
453 | kfree(vol_args); | 449 | kfree(vol_args); |
454 | return ret; | 450 | return ret; |
@@ -461,10 +457,8 @@ static int btrfs_ioctl_defrag(struct file *file) | |||
461 | 457 | ||
462 | switch (inode->i_mode & S_IFMT) { | 458 | switch (inode->i_mode & S_IFMT) { |
463 | case S_IFDIR: | 459 | case S_IFDIR: |
464 | mutex_lock(&root->fs_info->fs_mutex); | ||
465 | btrfs_defrag_root(root, 0); | 460 | btrfs_defrag_root(root, 0); |
466 | btrfs_defrag_root(root->fs_info->extent_root, 0); | 461 | btrfs_defrag_root(root->fs_info->extent_root, 0); |
467 | mutex_unlock(&root->fs_info->fs_mutex); | ||
468 | break; | 462 | break; |
469 | case S_IFREG: | 463 | case S_IFREG: |
470 | btrfs_defrag_file(file); | 464 | btrfs_defrag_file(file); |
@@ -588,7 +582,6 @@ long btrfs_ioctl_clone(struct file *file, unsigned long src_fd) | |||
588 | unlock_extent(&BTRFS_I(src)->io_tree, 0, (u64)-1, GFP_NOFS); | 582 | unlock_extent(&BTRFS_I(src)->io_tree, 0, (u64)-1, GFP_NOFS); |
589 | } | 583 | } |
590 | 584 | ||
591 | mutex_lock(&root->fs_info->fs_mutex); | ||
592 | trans = btrfs_start_transaction(root, 0); | 585 | trans = btrfs_start_transaction(root, 0); |
593 | path = btrfs_alloc_path(); | 586 | path = btrfs_alloc_path(); |
594 | if (!path) { | 587 | if (!path) { |
@@ -685,7 +678,6 @@ out: | |||
685 | unlock_extent(&BTRFS_I(src)->io_tree, 0, (u64)-1, GFP_NOFS); | 678 | unlock_extent(&BTRFS_I(src)->io_tree, 0, (u64)-1, GFP_NOFS); |
686 | 679 | ||
687 | btrfs_end_transaction(trans, root); | 680 | btrfs_end_transaction(trans, root); |
688 | mutex_unlock(&root->fs_info->fs_mutex); | ||
689 | 681 | ||
690 | out_unlock: | 682 | out_unlock: |
691 | mutex_unlock(&src->i_mutex); | 683 | mutex_unlock(&src->i_mutex); |
@@ -711,7 +703,6 @@ long btrfs_ioctl_trans_start(struct file *file) | |||
711 | if (!capable(CAP_SYS_ADMIN)) | 703 | if (!capable(CAP_SYS_ADMIN)) |
712 | return -EPERM; | 704 | return -EPERM; |
713 | 705 | ||
714 | mutex_lock(&root->fs_info->fs_mutex); | ||
715 | if (file->private_data) { | 706 | if (file->private_data) { |
716 | ret = -EINPROGRESS; | 707 | ret = -EINPROGRESS; |
717 | goto out; | 708 | goto out; |
@@ -723,7 +714,6 @@ long btrfs_ioctl_trans_start(struct file *file) | |||
723 | ret = -ENOMEM; | 714 | ret = -ENOMEM; |
724 | /*printk(KERN_INFO "btrfs_ioctl_trans_start on %p\n", file);*/ | 715 | /*printk(KERN_INFO "btrfs_ioctl_trans_start on %p\n", file);*/ |
725 | out: | 716 | out: |
726 | mutex_unlock(&root->fs_info->fs_mutex); | ||
727 | return ret; | 717 | return ret; |
728 | } | 718 | } |
729 | 719 | ||
@@ -740,7 +730,6 @@ long btrfs_ioctl_trans_end(struct file *file) | |||
740 | struct btrfs_trans_handle *trans; | 730 | struct btrfs_trans_handle *trans; |
741 | int ret = 0; | 731 | int ret = 0; |
742 | 732 | ||
743 | mutex_lock(&root->fs_info->fs_mutex); | ||
744 | trans = file->private_data; | 733 | trans = file->private_data; |
745 | if (!trans) { | 734 | if (!trans) { |
746 | ret = -EINVAL; | 735 | ret = -EINVAL; |
@@ -749,7 +738,6 @@ long btrfs_ioctl_trans_end(struct file *file) | |||
749 | btrfs_end_transaction(trans, root); | 738 | btrfs_end_transaction(trans, root); |
750 | file->private_data = 0; | 739 | file->private_data = 0; |
751 | out: | 740 | out: |
752 | mutex_unlock(&root->fs_info->fs_mutex); | ||
753 | return ret; | 741 | return ret; |
754 | } | 742 | } |
755 | 743 | ||