diff options
Diffstat (limited to 'fs/btrfs/extent_io.c')
| -rw-r--r-- | fs/btrfs/extent_io.c | 75 |
1 files changed, 58 insertions, 17 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index aaa12c1eb348..45c81bb4ac82 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
| @@ -929,7 +929,8 @@ int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int bits, | |||
| 929 | 929 | ||
| 930 | 930 | ||
| 931 | /** | 931 | /** |
| 932 | * convert_extent - convert all bits in a given range from one bit to another | 932 | * convert_extent_bit - convert all bits in a given range from one bit to |
| 933 | * another | ||
| 933 | * @tree: the io tree to search | 934 | * @tree: the io tree to search |
| 934 | * @start: the start offset in bytes | 935 | * @start: the start offset in bytes |
| 935 | * @end: the end offset in bytes (inclusive) | 936 | * @end: the end offset in bytes (inclusive) |
| @@ -1918,7 +1919,7 @@ int repair_io_failure(struct btrfs_mapping_tree *map_tree, u64 start, | |||
| 1918 | return -EIO; | 1919 | return -EIO; |
| 1919 | } | 1920 | } |
| 1920 | 1921 | ||
| 1921 | printk_in_rcu(KERN_INFO "btrfs read error corrected: ino %lu off %llu " | 1922 | printk_ratelimited_in_rcu(KERN_INFO "btrfs read error corrected: ino %lu off %llu " |
| 1922 | "(dev %s sector %llu)\n", page->mapping->host->i_ino, | 1923 | "(dev %s sector %llu)\n", page->mapping->host->i_ino, |
| 1923 | start, rcu_str_deref(dev->name), sector); | 1924 | start, rcu_str_deref(dev->name), sector); |
| 1924 | 1925 | ||
| @@ -3077,8 +3078,15 @@ static int lock_extent_buffer_for_io(struct extent_buffer *eb, | |||
| 3077 | } | 3078 | } |
| 3078 | } | 3079 | } |
| 3079 | 3080 | ||
| 3081 | /* | ||
| 3082 | * We need to do this to prevent races in people who check if the eb is | ||
| 3083 | * under IO since we can end up having no IO bits set for a short period | ||
| 3084 | * of time. | ||
| 3085 | */ | ||
| 3086 | spin_lock(&eb->refs_lock); | ||
| 3080 | if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) { | 3087 | if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) { |
| 3081 | set_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags); | 3088 | set_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags); |
| 3089 | spin_unlock(&eb->refs_lock); | ||
| 3082 | btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN); | 3090 | btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN); |
| 3083 | spin_lock(&fs_info->delalloc_lock); | 3091 | spin_lock(&fs_info->delalloc_lock); |
| 3084 | if (fs_info->dirty_metadata_bytes >= eb->len) | 3092 | if (fs_info->dirty_metadata_bytes >= eb->len) |
| @@ -3087,6 +3095,8 @@ static int lock_extent_buffer_for_io(struct extent_buffer *eb, | |||
| 3087 | WARN_ON(1); | 3095 | WARN_ON(1); |
| 3088 | spin_unlock(&fs_info->delalloc_lock); | 3096 | spin_unlock(&fs_info->delalloc_lock); |
| 3089 | ret = 1; | 3097 | ret = 1; |
| 3098 | } else { | ||
| 3099 | spin_unlock(&eb->refs_lock); | ||
| 3090 | } | 3100 | } |
| 3091 | 3101 | ||
| 3092 | btrfs_tree_unlock(eb); | 3102 | btrfs_tree_unlock(eb); |
| @@ -3324,6 +3334,7 @@ static int extent_write_cache_pages(struct extent_io_tree *tree, | |||
| 3324 | writepage_t writepage, void *data, | 3334 | writepage_t writepage, void *data, |
| 3325 | void (*flush_fn)(void *)) | 3335 | void (*flush_fn)(void *)) |
| 3326 | { | 3336 | { |
| 3337 | struct inode *inode = mapping->host; | ||
| 3327 | int ret = 0; | 3338 | int ret = 0; |
| 3328 | int done = 0; | 3339 | int done = 0; |
| 3329 | int nr_to_write_done = 0; | 3340 | int nr_to_write_done = 0; |
| @@ -3334,6 +3345,18 @@ static int extent_write_cache_pages(struct extent_io_tree *tree, | |||
| 3334 | int scanned = 0; | 3345 | int scanned = 0; |
| 3335 | int tag; | 3346 | int tag; |
| 3336 | 3347 | ||
| 3348 | /* | ||
| 3349 | * We have to hold onto the inode so that ordered extents can do their | ||
| 3350 | * work when the IO finishes. The alternative to this is failing to add | ||
| 3351 | * an ordered extent if the igrab() fails there and that is a huge pain | ||
| 3352 | * to deal with, so instead just hold onto the inode throughout the | ||
| 3353 | * writepages operation. If it fails here we are freeing up the inode | ||
| 3354 | * anyway and we'd rather not waste our time writing out stuff that is | ||
| 3355 | * going to be truncated anyway. | ||
| 3356 | */ | ||
| 3357 | if (!igrab(inode)) | ||
| 3358 | return 0; | ||
| 3359 | |||
| 3337 | pagevec_init(&pvec, 0); | 3360 | pagevec_init(&pvec, 0); |
| 3338 | if (wbc->range_cyclic) { | 3361 | if (wbc->range_cyclic) { |
| 3339 | index = mapping->writeback_index; /* Start from prev offset */ | 3362 | index = mapping->writeback_index; /* Start from prev offset */ |
| @@ -3428,6 +3451,7 @@ retry: | |||
| 3428 | index = 0; | 3451 | index = 0; |
| 3429 | goto retry; | 3452 | goto retry; |
| 3430 | } | 3453 | } |
| 3454 | btrfs_add_delayed_iput(inode); | ||
| 3431 | return ret; | 3455 | return ret; |
| 3432 | } | 3456 | } |
| 3433 | 3457 | ||
| @@ -3543,19 +3567,38 @@ int extent_readpages(struct extent_io_tree *tree, | |||
| 3543 | struct bio *bio = NULL; | 3567 | struct bio *bio = NULL; |
| 3544 | unsigned page_idx; | 3568 | unsigned page_idx; |
| 3545 | unsigned long bio_flags = 0; | 3569 | unsigned long bio_flags = 0; |
| 3570 | struct page *pagepool[16]; | ||
| 3571 | struct page *page; | ||
| 3572 | int i = 0; | ||
| 3573 | int nr = 0; | ||
| 3546 | 3574 | ||
| 3547 | for (page_idx = 0; page_idx < nr_pages; page_idx++) { | 3575 | for (page_idx = 0; page_idx < nr_pages; page_idx++) { |
| 3548 | struct page *page = list_entry(pages->prev, struct page, lru); | 3576 | page = list_entry(pages->prev, struct page, lru); |
| 3549 | 3577 | ||
| 3550 | prefetchw(&page->flags); | 3578 | prefetchw(&page->flags); |
| 3551 | list_del(&page->lru); | 3579 | list_del(&page->lru); |
| 3552 | if (!add_to_page_cache_lru(page, mapping, | 3580 | if (add_to_page_cache_lru(page, mapping, |
| 3553 | page->index, GFP_NOFS)) { | 3581 | page->index, GFP_NOFS)) { |
| 3554 | __extent_read_full_page(tree, page, get_extent, | 3582 | page_cache_release(page); |
| 3555 | &bio, 0, &bio_flags); | 3583 | continue; |
| 3556 | } | 3584 | } |
| 3557 | page_cache_release(page); | 3585 | |
| 3586 | pagepool[nr++] = page; | ||
| 3587 | if (nr < ARRAY_SIZE(pagepool)) | ||
| 3588 | continue; | ||
| 3589 | for (i = 0; i < nr; i++) { | ||
| 3590 | __extent_read_full_page(tree, pagepool[i], get_extent, | ||
| 3591 | &bio, 0, &bio_flags); | ||
| 3592 | page_cache_release(pagepool[i]); | ||
| 3593 | } | ||
| 3594 | nr = 0; | ||
| 3595 | } | ||
| 3596 | for (i = 0; i < nr; i++) { | ||
| 3597 | __extent_read_full_page(tree, pagepool[i], get_extent, | ||
| 3598 | &bio, 0, &bio_flags); | ||
| 3599 | page_cache_release(pagepool[i]); | ||
| 3558 | } | 3600 | } |
| 3601 | |||
| 3559 | BUG_ON(!list_empty(pages)); | 3602 | BUG_ON(!list_empty(pages)); |
| 3560 | if (bio) | 3603 | if (bio) |
| 3561 | return submit_one_bio(READ, bio, 0, bio_flags); | 3604 | return submit_one_bio(READ, bio, 0, bio_flags); |
| @@ -4109,11 +4152,10 @@ static void check_buffer_tree_ref(struct extent_buffer *eb) | |||
| 4109 | * So bump the ref count first, then set the bit. If someone | 4152 | * So bump the ref count first, then set the bit. If someone |
| 4110 | * beat us to it, drop the ref we added. | 4153 | * beat us to it, drop the ref we added. |
| 4111 | */ | 4154 | */ |
| 4112 | if (!test_bit(EXTENT_BUFFER_TREE_REF, &eb->bflags)) { | 4155 | spin_lock(&eb->refs_lock); |
| 4156 | if (!test_and_set_bit(EXTENT_BUFFER_TREE_REF, &eb->bflags)) | ||
| 4113 | atomic_inc(&eb->refs); | 4157 | atomic_inc(&eb->refs); |
| 4114 | if (test_and_set_bit(EXTENT_BUFFER_TREE_REF, &eb->bflags)) | 4158 | spin_unlock(&eb->refs_lock); |
| 4115 | atomic_dec(&eb->refs); | ||
| 4116 | } | ||
| 4117 | } | 4159 | } |
| 4118 | 4160 | ||
| 4119 | static void mark_extent_buffer_accessed(struct extent_buffer *eb) | 4161 | static void mark_extent_buffer_accessed(struct extent_buffer *eb) |
| @@ -4225,9 +4267,7 @@ again: | |||
| 4225 | goto free_eb; | 4267 | goto free_eb; |
| 4226 | } | 4268 | } |
| 4227 | /* add one reference for the tree */ | 4269 | /* add one reference for the tree */ |
| 4228 | spin_lock(&eb->refs_lock); | ||
| 4229 | check_buffer_tree_ref(eb); | 4270 | check_buffer_tree_ref(eb); |
| 4230 | spin_unlock(&eb->refs_lock); | ||
| 4231 | spin_unlock(&tree->buffer_lock); | 4271 | spin_unlock(&tree->buffer_lock); |
| 4232 | radix_tree_preload_end(); | 4272 | radix_tree_preload_end(); |
| 4233 | 4273 | ||
| @@ -4286,7 +4326,7 @@ static inline void btrfs_release_extent_buffer_rcu(struct rcu_head *head) | |||
| 4286 | } | 4326 | } |
| 4287 | 4327 | ||
| 4288 | /* Expects to have eb->eb_lock already held */ | 4328 | /* Expects to have eb->eb_lock already held */ |
| 4289 | static void release_extent_buffer(struct extent_buffer *eb, gfp_t mask) | 4329 | static int release_extent_buffer(struct extent_buffer *eb, gfp_t mask) |
| 4290 | { | 4330 | { |
| 4291 | WARN_ON(atomic_read(&eb->refs) == 0); | 4331 | WARN_ON(atomic_read(&eb->refs) == 0); |
| 4292 | if (atomic_dec_and_test(&eb->refs)) { | 4332 | if (atomic_dec_and_test(&eb->refs)) { |
| @@ -4307,9 +4347,11 @@ static void release_extent_buffer(struct extent_buffer *eb, gfp_t mask) | |||
| 4307 | btrfs_release_extent_buffer_page(eb, 0); | 4347 | btrfs_release_extent_buffer_page(eb, 0); |
| 4308 | 4348 | ||
| 4309 | call_rcu(&eb->rcu_head, btrfs_release_extent_buffer_rcu); | 4349 | call_rcu(&eb->rcu_head, btrfs_release_extent_buffer_rcu); |
| 4310 | return; | 4350 | return 1; |
| 4311 | } | 4351 | } |
| 4312 | spin_unlock(&eb->refs_lock); | 4352 | spin_unlock(&eb->refs_lock); |
| 4353 | |||
| 4354 | return 0; | ||
| 4313 | } | 4355 | } |
| 4314 | 4356 | ||
| 4315 | void free_extent_buffer(struct extent_buffer *eb) | 4357 | void free_extent_buffer(struct extent_buffer *eb) |
| @@ -4948,7 +4990,6 @@ int try_release_extent_buffer(struct page *page, gfp_t mask) | |||
| 4948 | spin_unlock(&eb->refs_lock); | 4990 | spin_unlock(&eb->refs_lock); |
| 4949 | return 0; | 4991 | return 0; |
| 4950 | } | 4992 | } |
| 4951 | release_extent_buffer(eb, mask); | ||
| 4952 | 4993 | ||
| 4953 | return 1; | 4994 | return release_extent_buffer(eb, mask); |
| 4954 | } | 4995 | } |
