diff options
| -rw-r--r-- | fs/btrfs/file.c | 18 | ||||
| -rw-r--r-- | fs/btrfs/free-space-cache.c | 8 |
2 files changed, 19 insertions, 7 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 8eb1f3c1b647..870150547f5c 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -1291,7 +1291,8 @@ out: | |||
| 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, | |||
| 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, | |||
| 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, | |||
| 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 | } |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 7a91770d8bb2..f331ef7d573a 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
| @@ -2972,7 +2972,7 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group, | |||
| 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, | |||
| 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); |
