Pull btrfs fixes from Chris Mason: "A couple of small fixes" * 'for-linus-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: Btrfs: check prepare_uptodate_page() error code earlier Btrfs: check for empty bitmap list in setup_cluster_bitmaps btrfs: fix misleading warning when space cache failed to load Btrfs: fix transaction handle leak in balance Btrfs: fix unprotected list move from unused_bgs to deleted_bgs list
Unified · Split
| @@ -10480,11 +10480,15 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) · 10479 unmodified lines | |||
| 10480 | * until transaction commit to do the actual discard. | 10480 | * until transaction commit to do the actual discard. |
| 10481 | */ | 10481 | */ |
| 10482 | if (trimming) { | 10482 | if (trimming) { |
| 10483 | WARN_ON(!list_empty(&block_group->bg_list)); | 10483 | spin_lock(&fs_info->unused_bgs_lock); |
| 10484 | spin_lock(&trans->transaction->deleted_bgs_lock); | 10484 | /* |
| 10485 | * A concurrent scrub might have added us to the list | ||
| 10486 | * fs_info->unused_bgs, so use a list_move operation | ||
| 10487 | * to add the block group to the deleted_bgs list. | ||
| 10488 | */ | ||
| 10485 | list_move(&block_group->bg_list, | 10489 | list_move(&block_group->bg_list, |
| 10486 | &trans->transaction->deleted_bgs); | 10490 | &trans->transaction->deleted_bgs); |
| 10487 | spin_unlock(&trans->transaction->deleted_bgs_lock); | 10491 | spin_unlock(&fs_info->unused_bgs_lock); |
| 10488 | btrfs_get_block_group(block_group); | 10492 | btrfs_get_block_group(block_group); |
| 10489 | } | 10493 | } |
| 10490 | end_trans: | 10494 | end_trans: |
| @@ -1291,7 +1291,8 @@ out: · 1290 unmodified lines | |||
| 1291 | * on error we return an unlocked page and the error value | 1291 | * on error we return an unlocked page and the error value |
| 1292 | * on success we return a locked page and 0 | 1292 | * on success we return a locked page and 0 |
| 1293 | */ | 1293 | */ |
| 1294 | static int prepare_uptodate_page(struct page *page, u64 pos, | 1294 | static int prepare_uptodate_page(struct inode *inode, |
| 1295 | struct page *page, u64 pos, | ||
| 1295 | bool force_uptodate) | 1296 | bool force_uptodate) |
| 1296 | { | 1297 | { |
| 1297 | int ret = 0; | 1298 | int ret = 0; |
| @@ -1306,6 +1307,10 @@ static int prepare_uptodate_page(struct page *page, u64 pos, · 8 unmodified lines | |||
| 1306 | unlock_page(page); | 1307 | unlock_page(page); |
| 1307 | return -EIO; | 1308 | return -EIO; |
| 1308 | } | 1309 | } |
| 1310 | if (page->mapping != inode->i_mapping) { | ||
| 1311 | unlock_page(page); | ||
| 1312 | return -EAGAIN; | ||
| 1313 | } | ||
| 1309 | } | 1314 | } |
| 1310 | return 0; | 1315 | return 0; |
| 1311 | } | 1316 | } |
| @@ -1324,6 +1329,7 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages, · 12 unmodified lines | |||
| 1324 | int faili; | 1329 | int faili; |
| 1325 | 1330 | ||
| 1326 | for (i = 0; i < num_pages; i++) { | 1331 | for (i = 0; i < num_pages; i++) { |
| 1332 | again: | ||
| 1327 | pages[i] = find_or_create_page(inode->i_mapping, index + i, | 1333 | pages[i] = find_or_create_page(inode->i_mapping, index + i, |
| 1328 | mask | __GFP_WRITE); | 1334 | mask | __GFP_WRITE); |
| 1329 | if (!pages[i]) { | 1335 | if (!pages[i]) { |
| @@ -1333,13 +1339,17 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages, · 3 unmodified lines | |||
| 1333 | } | 1339 | } |
| 1334 | 1340 | ||
| 1335 | if (i == 0) | 1341 | if (i == 0) |
| 1336 | err = prepare_uptodate_page(pages[i], pos, | 1342 | err = prepare_uptodate_page(inode, pages[i], pos, |
| 1337 | force_uptodate); | 1343 | force_uptodate); |
| 1338 | if (i == num_pages - 1) | 1344 | if (!err && i == num_pages - 1) |
| 1339 | err = prepare_uptodate_page(pages[i], | 1345 | err = prepare_uptodate_page(inode, pages[i], |
| 1340 | pos + write_bytes, false); | 1346 | pos + write_bytes, false); |
| 1341 | if (err) { | 1347 | if (err) { |
| 1342 | page_cache_release(pages[i]); | 1348 | page_cache_release(pages[i]); |
| 1349 | if (err == -EAGAIN) { | ||
| 1350 | err = 0; | ||
| 1351 | goto again; | ||
| 1352 | } | ||
| 1343 | faili = i - 1; | 1353 | faili = i - 1; |
| 1344 | goto fail; | 1354 | goto fail; |
| 1345 | } | 1355 | } |
| @@ -891,7 +891,7 @@ out: · 890 unmodified lines | |||
| 891 | spin_unlock(&block_group->lock); | 891 | spin_unlock(&block_group->lock); |
| 892 | ret = 0; | 892 | ret = 0; |
| 893 | 893 | ||
| 894 | btrfs_warn(fs_info, "failed to load free space cache for block group %llu, rebuild it now", | 894 | btrfs_warn(fs_info, "failed to load free space cache for block group %llu, rebuilding it now", |
| 895 | block_group->key.objectid); | 895 | block_group->key.objectid); |
| 896 | } | 896 | } |
| 897 | 897 | ||
| @@ -2972,7 +2972,7 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group, · 2074 unmodified lines | |||
| 2972 | u64 cont1_bytes, u64 min_bytes) | 2972 | u64 cont1_bytes, u64 min_bytes) |
| 2973 | { | 2973 | { |
| 2974 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; | 2974 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; |
| 2975 | struct btrfs_free_space *entry; | 2975 | struct btrfs_free_space *entry = NULL; |
| 2976 | int ret = -ENOSPC; | 2976 | int ret = -ENOSPC; |
| 2977 | u64 bitmap_offset = offset_to_bitmap(ctl, offset); | 2977 | u64 bitmap_offset = offset_to_bitmap(ctl, offset); |
| 2978 | 2978 | ||
| @@ -2983,8 +2983,10 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group, · 4 unmodified lines | |||
| 2983 | * The bitmap that covers offset won't be in the list unless offset | 2983 | * The bitmap that covers offset won't be in the list unless offset |
| 2984 | * is just its start offset. | 2984 | * is just its start offset. |
| 2985 | */ | 2985 | */ |
| 2986 | entry = list_first_entry(bitmaps, struct btrfs_free_space, list); | 2986 | if (!list_empty(bitmaps)) |
| 2987 | if (entry->offset != bitmap_offset) { | 2987 | entry = list_first_entry(bitmaps, struct btrfs_free_space, list); |
| 2988 | |||
| 2989 | if (!entry || entry->offset != bitmap_offset) { | ||
| 2988 | entry = tree_search_offset(ctl, bitmap_offset, 1, 0); | 2990 | entry = tree_search_offset(ctl, bitmap_offset, 1, 0); |
| 2989 | if (entry && list_empty(&entry->list)) | 2991 | if (entry && list_empty(&entry->list)) |
| 2990 | list_add(&entry->list, bitmaps); | 2992 | list_add(&entry->list, bitmaps); |
| @@ -274,7 +274,6 @@ loop: · 273 unmodified lines | |||
| 274 | cur_trans->num_dirty_bgs = 0; | 274 | cur_trans->num_dirty_bgs = 0; |
| 275 | spin_lock_init(&cur_trans->dirty_bgs_lock); | 275 | spin_lock_init(&cur_trans->dirty_bgs_lock); |
| 276 | INIT_LIST_HEAD(&cur_trans->deleted_bgs); | 276 | INIT_LIST_HEAD(&cur_trans->deleted_bgs); |
| 277 | spin_lock_init(&cur_trans->deleted_bgs_lock); | ||
| 278 | spin_lock_init(&cur_trans->dropped_roots_lock); | 277 | spin_lock_init(&cur_trans->dropped_roots_lock); |
| 279 | list_add_tail(&cur_trans->list, &fs_info->trans_list); | 278 | list_add_tail(&cur_trans->list, &fs_info->trans_list); |
| 280 | extent_io_tree_init(&cur_trans->dirty_pages, | 279 | extent_io_tree_init(&cur_trans->dirty_pages, |
| @@ -77,8 +77,8 @@ struct btrfs_transaction { · 76 unmodified lines | |||
| 77 | */ | 77 | */ |
| 78 | struct mutex cache_write_mutex; | 78 | struct mutex cache_write_mutex; |
| 79 | spinlock_t dirty_bgs_lock; | 79 | spinlock_t dirty_bgs_lock; |
| 80 | /* Protected by spin lock fs_info->unused_bgs_lock. */ | ||
| 80 | struct list_head deleted_bgs; | 81 | struct list_head deleted_bgs; |
| 81 | spinlock_t deleted_bgs_lock; | ||
| 82 | spinlock_t dropped_roots_lock; | 82 | spinlock_t dropped_roots_lock; |
| 83 | struct btrfs_delayed_ref_root delayed_refs; | 83 | struct btrfs_delayed_ref_root delayed_refs; |
| 84 | int aborted; | 84 | int aborted; |
| @@ -3548,12 +3548,11 @@ again: · 3547 unmodified lines | |||
| 3548 | 3548 | ||
| 3549 | ret = btrfs_force_chunk_alloc(trans, chunk_root, | 3549 | ret = btrfs_force_chunk_alloc(trans, chunk_root, |
| 3550 | BTRFS_BLOCK_GROUP_DATA); | 3550 | BTRFS_BLOCK_GROUP_DATA); |
| 3551 | btrfs_end_transaction(trans, chunk_root); | ||
| 3551 | if (ret < 0) { | 3552 | if (ret < 0) { |
| 3552 | mutex_unlock(&fs_info->delete_unused_bgs_mutex); | 3553 | mutex_unlock(&fs_info->delete_unused_bgs_mutex); |
| 3553 | goto error; | 3554 | goto error; |
| 3554 | } | 3555 | } |
| 3555 | |||
| 3556 | btrfs_end_transaction(trans, chunk_root); | ||
| 3557 | chunk_reserved = 1; | 3556 | chunk_reserved = 1; |
| 3558 | } | 3557 | } |
| 3559 | 3558 | ||