diff options
author | Chris Mason <chris.mason@oracle.com> | 2009-09-02 16:24:52 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2009-09-11 13:31:05 -0400 |
commit | 890871be854b5f5e43e7ba2475f706209906cc24 (patch) | |
tree | 9d087adf7a28bb910992d07d93ea2a992e394110 /fs/btrfs/inode.c | |
parent | 57fd5a5ff8b48b99e90b22fc143082aba755c6c0 (diff) |
Btrfs: switch extent_map to a rw lock
There are two main users of the extent_map tree. The
first is regular file inodes, where it is evenly spread
between readers and writers.
The second is the chunk allocation tree, which maps blocks from
logical addresses to phyiscal ones, and it is 99.99% reads.
The mapping tree is a point of lock contention during heavy IO
workloads, so this commit switches things to a rw lock.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 04b53b5ebe59..f1df11718618 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -612,9 +612,9 @@ static noinline int submit_compressed_extents(struct inode *inode, | |||
612 | set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); | 612 | set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); |
613 | 613 | ||
614 | while (1) { | 614 | while (1) { |
615 | spin_lock(&em_tree->lock); | 615 | write_lock(&em_tree->lock); |
616 | ret = add_extent_mapping(em_tree, em); | 616 | ret = add_extent_mapping(em_tree, em); |
617 | spin_unlock(&em_tree->lock); | 617 | write_unlock(&em_tree->lock); |
618 | if (ret != -EEXIST) { | 618 | if (ret != -EEXIST) { |
619 | free_extent_map(em); | 619 | free_extent_map(em); |
620 | break; | 620 | break; |
@@ -748,9 +748,9 @@ static noinline int cow_file_range(struct inode *inode, | |||
748 | set_bit(EXTENT_FLAG_PINNED, &em->flags); | 748 | set_bit(EXTENT_FLAG_PINNED, &em->flags); |
749 | 749 | ||
750 | while (1) { | 750 | while (1) { |
751 | spin_lock(&em_tree->lock); | 751 | write_lock(&em_tree->lock); |
752 | ret = add_extent_mapping(em_tree, em); | 752 | ret = add_extent_mapping(em_tree, em); |
753 | spin_unlock(&em_tree->lock); | 753 | write_unlock(&em_tree->lock); |
754 | if (ret != -EEXIST) { | 754 | if (ret != -EEXIST) { |
755 | free_extent_map(em); | 755 | free_extent_map(em); |
756 | break; | 756 | break; |
@@ -1081,9 +1081,9 @@ out_check: | |||
1081 | em->bdev = root->fs_info->fs_devices->latest_bdev; | 1081 | em->bdev = root->fs_info->fs_devices->latest_bdev; |
1082 | set_bit(EXTENT_FLAG_PINNED, &em->flags); | 1082 | set_bit(EXTENT_FLAG_PINNED, &em->flags); |
1083 | while (1) { | 1083 | while (1) { |
1084 | spin_lock(&em_tree->lock); | 1084 | write_lock(&em_tree->lock); |
1085 | ret = add_extent_mapping(em_tree, em); | 1085 | ret = add_extent_mapping(em_tree, em); |
1086 | spin_unlock(&em_tree->lock); | 1086 | write_unlock(&em_tree->lock); |
1087 | if (ret != -EEXIST) { | 1087 | if (ret != -EEXIST) { |
1088 | free_extent_map(em); | 1088 | free_extent_map(em); |
1089 | break; | 1089 | break; |
@@ -1670,13 +1670,13 @@ static int btrfs_io_failed_hook(struct bio *failed_bio, | |||
1670 | failrec->last_mirror = 0; | 1670 | failrec->last_mirror = 0; |
1671 | failrec->bio_flags = 0; | 1671 | failrec->bio_flags = 0; |
1672 | 1672 | ||
1673 | spin_lock(&em_tree->lock); | 1673 | read_lock(&em_tree->lock); |
1674 | em = lookup_extent_mapping(em_tree, start, failrec->len); | 1674 | em = lookup_extent_mapping(em_tree, start, failrec->len); |
1675 | if (em->start > start || em->start + em->len < start) { | 1675 | if (em->start > start || em->start + em->len < start) { |
1676 | free_extent_map(em); | 1676 | free_extent_map(em); |
1677 | em = NULL; | 1677 | em = NULL; |
1678 | } | 1678 | } |
1679 | spin_unlock(&em_tree->lock); | 1679 | read_unlock(&em_tree->lock); |
1680 | 1680 | ||
1681 | if (!em || IS_ERR(em)) { | 1681 | if (!em || IS_ERR(em)) { |
1682 | kfree(failrec); | 1682 | kfree(failrec); |
@@ -4069,11 +4069,11 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, | |||
4069 | int compressed; | 4069 | int compressed; |
4070 | 4070 | ||
4071 | again: | 4071 | again: |
4072 | spin_lock(&em_tree->lock); | 4072 | read_lock(&em_tree->lock); |
4073 | em = lookup_extent_mapping(em_tree, start, len); | 4073 | em = lookup_extent_mapping(em_tree, start, len); |
4074 | if (em) | 4074 | if (em) |
4075 | em->bdev = root->fs_info->fs_devices->latest_bdev; | 4075 | em->bdev = root->fs_info->fs_devices->latest_bdev; |
4076 | spin_unlock(&em_tree->lock); | 4076 | read_unlock(&em_tree->lock); |
4077 | 4077 | ||
4078 | if (em) { | 4078 | if (em) { |
4079 | if (em->start > start || em->start + em->len <= start) | 4079 | if (em->start > start || em->start + em->len <= start) |
@@ -4264,7 +4264,7 @@ insert: | |||
4264 | } | 4264 | } |
4265 | 4265 | ||
4266 | err = 0; | 4266 | err = 0; |
4267 | spin_lock(&em_tree->lock); | 4267 | write_lock(&em_tree->lock); |
4268 | ret = add_extent_mapping(em_tree, em); | 4268 | ret = add_extent_mapping(em_tree, em); |
4269 | /* it is possible that someone inserted the extent into the tree | 4269 | /* it is possible that someone inserted the extent into the tree |
4270 | * while we had the lock dropped. It is also possible that | 4270 | * while we had the lock dropped. It is also possible that |
@@ -4304,7 +4304,7 @@ insert: | |||
4304 | err = 0; | 4304 | err = 0; |
4305 | } | 4305 | } |
4306 | } | 4306 | } |
4307 | spin_unlock(&em_tree->lock); | 4307 | write_unlock(&em_tree->lock); |
4308 | out: | 4308 | out: |
4309 | if (path) | 4309 | if (path) |
4310 | btrfs_free_path(path); | 4310 | btrfs_free_path(path); |