aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.c16
-rw-r--r--fs/btrfs/extent_io.c145
2 files changed, 88 insertions, 73 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 0d5c686f2b98..1dd8a71f567d 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1211,7 +1211,11 @@ tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct extent_buffer *eb,
1211 BUG_ON(tm->slot != 0); 1211 BUG_ON(tm->slot != 0);
1212 eb_rewin = alloc_dummy_extent_buffer(eb->start, 1212 eb_rewin = alloc_dummy_extent_buffer(eb->start,
1213 fs_info->tree_root->nodesize); 1213 fs_info->tree_root->nodesize);
1214 BUG_ON(!eb_rewin); 1214 if (!eb_rewin) {
1215 btrfs_tree_read_unlock(eb);
1216 free_extent_buffer(eb);
1217 return NULL;
1218 }
1215 btrfs_set_header_bytenr(eb_rewin, eb->start); 1219 btrfs_set_header_bytenr(eb_rewin, eb->start);
1216 btrfs_set_header_backref_rev(eb_rewin, 1220 btrfs_set_header_backref_rev(eb_rewin,
1217 btrfs_header_backref_rev(eb)); 1221 btrfs_header_backref_rev(eb));
@@ -1219,7 +1223,11 @@ tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct extent_buffer *eb,
1219 btrfs_set_header_level(eb_rewin, btrfs_header_level(eb)); 1223 btrfs_set_header_level(eb_rewin, btrfs_header_level(eb));
1220 } else { 1224 } else {
1221 eb_rewin = btrfs_clone_extent_buffer(eb); 1225 eb_rewin = btrfs_clone_extent_buffer(eb);
1222 BUG_ON(!eb_rewin); 1226 if (!eb_rewin) {
1227 btrfs_tree_read_unlock(eb);
1228 free_extent_buffer(eb);
1229 return NULL;
1230 }
1223 } 1231 }
1224 1232
1225 btrfs_tree_read_unlock(eb); 1233 btrfs_tree_read_unlock(eb);
@@ -2772,6 +2780,10 @@ again:
2772 BTRFS_READ_LOCK); 2780 BTRFS_READ_LOCK);
2773 } 2781 }
2774 b = tree_mod_log_rewind(root->fs_info, b, time_seq); 2782 b = tree_mod_log_rewind(root->fs_info, b, time_seq);
2783 if (!b) {
2784 ret = -ENOMEM;
2785 goto done;
2786 }
2775 p->locks[level] = BTRFS_READ_LOCK; 2787 p->locks[level] = BTRFS_READ_LOCK;
2776 p->nodes[level] = b; 2788 p->nodes[level] = b;
2777 } else { 2789 } else {
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index c137f98fbd24..ef25c7d048e2 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -4222,6 +4222,76 @@ static void __free_extent_buffer(struct extent_buffer *eb)
4222 kmem_cache_free(extent_buffer_cache, eb); 4222 kmem_cache_free(extent_buffer_cache, eb);
4223} 4223}
4224 4224
4225static int extent_buffer_under_io(struct extent_buffer *eb)
4226{
4227 return (atomic_read(&eb->io_pages) ||
4228 test_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags) ||
4229 test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags));
4230}
4231
4232/*
4233 * Helper for releasing extent buffer page.
4234 */
4235static void btrfs_release_extent_buffer_page(struct extent_buffer *eb,
4236 unsigned long start_idx)
4237{
4238 unsigned long index;
4239 unsigned long num_pages;
4240 struct page *page;
4241 int mapped = !test_bit(EXTENT_BUFFER_DUMMY, &eb->bflags);
4242
4243 BUG_ON(extent_buffer_under_io(eb));
4244
4245 num_pages = num_extent_pages(eb->start, eb->len);
4246 index = start_idx + num_pages;
4247 if (start_idx >= index)
4248 return;
4249
4250 do {
4251 index--;
4252 page = extent_buffer_page(eb, index);
4253 if (page && mapped) {
4254 spin_lock(&page->mapping->private_lock);
4255 /*
4256 * We do this since we'll remove the pages after we've
4257 * removed the eb from the radix tree, so we could race
4258 * and have this page now attached to the new eb. So
4259 * only clear page_private if it's still connected to
4260 * this eb.
4261 */
4262 if (PagePrivate(page) &&
4263 page->private == (unsigned long)eb) {
4264 BUG_ON(test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags));
4265 BUG_ON(PageDirty(page));
4266 BUG_ON(PageWriteback(page));
4267 /*
4268 * We need to make sure we haven't be attached
4269 * to a new eb.
4270 */
4271 ClearPagePrivate(page);
4272 set_page_private(page, 0);
4273 /* One for the page private */
4274 page_cache_release(page);
4275 }
4276 spin_unlock(&page->mapping->private_lock);
4277
4278 }
4279 if (page) {
4280 /* One for when we alloced the page */
4281 page_cache_release(page);
4282 }
4283 } while (index != start_idx);
4284}
4285
4286/*
4287 * Helper for releasing the extent buffer.
4288 */
4289static inline void btrfs_release_extent_buffer(struct extent_buffer *eb)
4290{
4291 btrfs_release_extent_buffer_page(eb, 0);
4292 __free_extent_buffer(eb);
4293}
4294
4225static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree, 4295static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree,
4226 u64 start, 4296 u64 start,
4227 unsigned long len, 4297 unsigned long len,
@@ -4276,7 +4346,10 @@ struct extent_buffer *btrfs_clone_extent_buffer(struct extent_buffer *src)
4276 4346
4277 for (i = 0; i < num_pages; i++) { 4347 for (i = 0; i < num_pages; i++) {
4278 p = alloc_page(GFP_ATOMIC); 4348 p = alloc_page(GFP_ATOMIC);
4279 BUG_ON(!p); 4349 if (!p) {
4350 btrfs_release_extent_buffer(new);
4351 return NULL;
4352 }
4280 attach_extent_buffer_page(new, p); 4353 attach_extent_buffer_page(new, p);
4281 WARN_ON(PageDirty(p)); 4354 WARN_ON(PageDirty(p));
4282 SetPageUptodate(p); 4355 SetPageUptodate(p);
@@ -4317,76 +4390,6 @@ err:
4317 return NULL; 4390 return NULL;
4318} 4391}
4319 4392
4320static int extent_buffer_under_io(struct extent_buffer *eb)
4321{
4322 return (atomic_read(&eb->io_pages) ||
4323 test_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags) ||
4324 test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags));
4325}
4326
4327/*
4328 * Helper for releasing extent buffer page.
4329 */
4330static void btrfs_release_extent_buffer_page(struct extent_buffer *eb,
4331 unsigned long start_idx)
4332{
4333 unsigned long index;
4334 unsigned long num_pages;
4335 struct page *page;
4336 int mapped = !test_bit(EXTENT_BUFFER_DUMMY, &eb->bflags);
4337
4338 BUG_ON(extent_buffer_under_io(eb));
4339
4340 num_pages = num_extent_pages(eb->start, eb->len);
4341 index = start_idx + num_pages;
4342 if (start_idx >= index)
4343 return;
4344
4345 do {
4346 index--;
4347 page = extent_buffer_page(eb, index);
4348 if (page && mapped) {
4349 spin_lock(&page->mapping->private_lock);
4350 /*
4351 * We do this since we'll remove the pages after we've
4352 * removed the eb from the radix tree, so we could race
4353 * and have this page now attached to the new eb. So
4354 * only clear page_private if it's still connected to
4355 * this eb.
4356 */
4357 if (PagePrivate(page) &&
4358 page->private == (unsigned long)eb) {
4359 BUG_ON(test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags));
4360 BUG_ON(PageDirty(page));
4361 BUG_ON(PageWriteback(page));
4362 /*
4363 * We need to make sure we haven't be attached
4364 * to a new eb.
4365 */
4366 ClearPagePrivate(page);
4367 set_page_private(page, 0);
4368 /* One for the page private */
4369 page_cache_release(page);
4370 }
4371 spin_unlock(&page->mapping->private_lock);
4372
4373 }
4374 if (page) {
4375 /* One for when we alloced the page */
4376 page_cache_release(page);
4377 }
4378 } while (index != start_idx);
4379}
4380
4381/*
4382 * Helper for releasing the extent buffer.
4383 */
4384static inline void btrfs_release_extent_buffer(struct extent_buffer *eb)
4385{
4386 btrfs_release_extent_buffer_page(eb, 0);
4387 __free_extent_buffer(eb);
4388}
4389
4390static void check_buffer_tree_ref(struct extent_buffer *eb) 4393static void check_buffer_tree_ref(struct extent_buffer *eb)
4391{ 4394{
4392 int refs; 4395 int refs;