aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_io.c
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2013-08-07 14:54:37 -0400
committerChris Mason <chris.mason@fusionio.com>2013-09-01 08:04:49 -0400
commitdb7f3436c1c186f8271018751fcb338cf3706e8d (patch)
tree100757837210358af57b870c5e54d1731692940b /fs/btrfs/extent_io.c
parentebdad913aa9c86a63d3be28b4610e143204c6f3c (diff)
Btrfs: deal with enomem in the rewind path
We can get ENOMEM trying to allocate dummy bufs for the rewind operation of the tree mod log. Instead of BUG_ON()'ing in this case pass up ENOMEM. I looked back through the callers and I'm pretty sure I got everybody who did BUG_ON(ret) in this path. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r--fs/btrfs/extent_io.c145
1 files changed, 74 insertions, 71 deletions
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;