diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ctree.h | 3 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 34 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 27 | ||||
-rw-r--r-- | fs/btrfs/free-space-cache.c | 2 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 2 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 2 | ||||
-rw-r--r-- | fs/btrfs/scrub.c | 5 | ||||
-rw-r--r-- | fs/btrfs/super.c | 6 |
8 files changed, 58 insertions, 23 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 04a5dfcee5a1..50634abef9b4 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -2369,6 +2369,9 @@ int btrfs_block_rsv_check(struct btrfs_root *root, | |||
2369 | int btrfs_block_rsv_refill(struct btrfs_root *root, | 2369 | int btrfs_block_rsv_refill(struct btrfs_root *root, |
2370 | struct btrfs_block_rsv *block_rsv, | 2370 | struct btrfs_block_rsv *block_rsv, |
2371 | u64 min_reserved); | 2371 | u64 min_reserved); |
2372 | int btrfs_block_rsv_refill_noflush(struct btrfs_root *root, | ||
2373 | struct btrfs_block_rsv *block_rsv, | ||
2374 | u64 min_reserved); | ||
2372 | int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv, | 2375 | int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv, |
2373 | struct btrfs_block_rsv *dst_rsv, | 2376 | struct btrfs_block_rsv *dst_rsv, |
2374 | u64 num_bytes); | 2377 | u64 num_bytes); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 930ae8949737..f0d5718d2587 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3888,9 +3888,9 @@ int btrfs_block_rsv_check(struct btrfs_root *root, | |||
3888 | return ret; | 3888 | return ret; |
3889 | } | 3889 | } |
3890 | 3890 | ||
3891 | int btrfs_block_rsv_refill(struct btrfs_root *root, | 3891 | static inline int __btrfs_block_rsv_refill(struct btrfs_root *root, |
3892 | struct btrfs_block_rsv *block_rsv, | 3892 | struct btrfs_block_rsv *block_rsv, |
3893 | u64 min_reserved) | 3893 | u64 min_reserved, int flush) |
3894 | { | 3894 | { |
3895 | u64 num_bytes = 0; | 3895 | u64 num_bytes = 0; |
3896 | int ret = -ENOSPC; | 3896 | int ret = -ENOSPC; |
@@ -3909,7 +3909,7 @@ int btrfs_block_rsv_refill(struct btrfs_root *root, | |||
3909 | if (!ret) | 3909 | if (!ret) |
3910 | return 0; | 3910 | return 0; |
3911 | 3911 | ||
3912 | ret = reserve_metadata_bytes(root, block_rsv, num_bytes, 1); | 3912 | ret = reserve_metadata_bytes(root, block_rsv, num_bytes, flush); |
3913 | if (!ret) { | 3913 | if (!ret) { |
3914 | block_rsv_add_bytes(block_rsv, num_bytes, 0); | 3914 | block_rsv_add_bytes(block_rsv, num_bytes, 0); |
3915 | return 0; | 3915 | return 0; |
@@ -3918,6 +3918,20 @@ int btrfs_block_rsv_refill(struct btrfs_root *root, | |||
3918 | return ret; | 3918 | return ret; |
3919 | } | 3919 | } |
3920 | 3920 | ||
3921 | int btrfs_block_rsv_refill(struct btrfs_root *root, | ||
3922 | struct btrfs_block_rsv *block_rsv, | ||
3923 | u64 min_reserved) | ||
3924 | { | ||
3925 | return __btrfs_block_rsv_refill(root, block_rsv, min_reserved, 1); | ||
3926 | } | ||
3927 | |||
3928 | int btrfs_block_rsv_refill_noflush(struct btrfs_root *root, | ||
3929 | struct btrfs_block_rsv *block_rsv, | ||
3930 | u64 min_reserved) | ||
3931 | { | ||
3932 | return __btrfs_block_rsv_refill(root, block_rsv, min_reserved, 0); | ||
3933 | } | ||
3934 | |||
3921 | int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv, | 3935 | int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv, |
3922 | struct btrfs_block_rsv *dst_rsv, | 3936 | struct btrfs_block_rsv *dst_rsv, |
3923 | u64 num_bytes) | 3937 | u64 num_bytes) |
@@ -5265,7 +5279,7 @@ alloc: | |||
5265 | spin_lock(&block_group->free_space_ctl->tree_lock); | 5279 | spin_lock(&block_group->free_space_ctl->tree_lock); |
5266 | if (cached && | 5280 | if (cached && |
5267 | block_group->free_space_ctl->free_space < | 5281 | block_group->free_space_ctl->free_space < |
5268 | num_bytes + empty_size) { | 5282 | num_bytes + empty_cluster + empty_size) { |
5269 | spin_unlock(&block_group->free_space_ctl->tree_lock); | 5283 | spin_unlock(&block_group->free_space_ctl->tree_lock); |
5270 | goto loop; | 5284 | goto loop; |
5271 | } | 5285 | } |
@@ -5286,12 +5300,10 @@ alloc: | |||
5286 | * people trying to start a new cluster | 5300 | * people trying to start a new cluster |
5287 | */ | 5301 | */ |
5288 | spin_lock(&last_ptr->refill_lock); | 5302 | spin_lock(&last_ptr->refill_lock); |
5289 | if (last_ptr->block_group && | 5303 | if (!last_ptr->block_group || |
5290 | (last_ptr->block_group->ro || | 5304 | last_ptr->block_group->ro || |
5291 | !block_group_bits(last_ptr->block_group, data))) { | 5305 | !block_group_bits(last_ptr->block_group, data)) |
5292 | offset = 0; | ||
5293 | goto refill_cluster; | 5306 | goto refill_cluster; |
5294 | } | ||
5295 | 5307 | ||
5296 | offset = btrfs_alloc_from_cluster(block_group, last_ptr, | 5308 | offset = btrfs_alloc_from_cluster(block_group, last_ptr, |
5297 | num_bytes, search_start); | 5309 | num_bytes, search_start); |
@@ -5342,7 +5354,7 @@ refill_cluster: | |||
5342 | /* allocate a cluster in this block group */ | 5354 | /* allocate a cluster in this block group */ |
5343 | ret = btrfs_find_space_cluster(trans, root, | 5355 | ret = btrfs_find_space_cluster(trans, root, |
5344 | block_group, last_ptr, | 5356 | block_group, last_ptr, |
5345 | offset, num_bytes, | 5357 | search_start, num_bytes, |
5346 | empty_cluster + empty_size); | 5358 | empty_cluster + empty_size); |
5347 | if (ret == 0) { | 5359 | if (ret == 0) { |
5348 | /* | 5360 | /* |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 9472d3de5e52..be1bf627a14b 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -2287,14 +2287,20 @@ static void end_bio_extent_readpage(struct bio *bio, int err) | |||
2287 | if (!uptodate) { | 2287 | if (!uptodate) { |
2288 | int failed_mirror; | 2288 | int failed_mirror; |
2289 | failed_mirror = (int)(unsigned long)bio->bi_bdev; | 2289 | failed_mirror = (int)(unsigned long)bio->bi_bdev; |
2290 | if (tree->ops && tree->ops->readpage_io_failed_hook) | 2290 | /* |
2291 | ret = tree->ops->readpage_io_failed_hook( | 2291 | * The generic bio_readpage_error handles errors the |
2292 | bio, page, start, end, | 2292 | * following way: If possible, new read requests are |
2293 | failed_mirror, state); | 2293 | * created and submitted and will end up in |
2294 | else | 2294 | * end_bio_extent_readpage as well (if we're lucky, not |
2295 | ret = bio_readpage_error(bio, page, start, end, | 2295 | * in the !uptodate case). In that case it returns 0 and |
2296 | failed_mirror, NULL); | 2296 | * we just go on with the next page in our bio. If it |
2297 | * can't handle the error it will return -EIO and we | ||
2298 | * remain responsible for that page. | ||
2299 | */ | ||
2300 | ret = bio_readpage_error(bio, page, start, end, | ||
2301 | failed_mirror, NULL); | ||
2297 | if (ret == 0) { | 2302 | if (ret == 0) { |
2303 | error_handled: | ||
2298 | uptodate = | 2304 | uptodate = |
2299 | test_bit(BIO_UPTODATE, &bio->bi_flags); | 2305 | test_bit(BIO_UPTODATE, &bio->bi_flags); |
2300 | if (err) | 2306 | if (err) |
@@ -2302,6 +2308,13 @@ static void end_bio_extent_readpage(struct bio *bio, int err) | |||
2302 | uncache_state(&cached); | 2308 | uncache_state(&cached); |
2303 | continue; | 2309 | continue; |
2304 | } | 2310 | } |
2311 | if (tree->ops && tree->ops->readpage_io_failed_hook) { | ||
2312 | ret = tree->ops->readpage_io_failed_hook( | ||
2313 | bio, page, start, end, | ||
2314 | failed_mirror, state); | ||
2315 | if (ret == 0) | ||
2316 | goto error_handled; | ||
2317 | } | ||
2305 | } | 2318 | } |
2306 | 2319 | ||
2307 | if (uptodate) { | 2320 | if (uptodate) { |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 6e5b7e463698..ec23d43d0c35 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -1470,6 +1470,7 @@ static void add_new_bitmap(struct btrfs_free_space_ctl *ctl, | |||
1470 | { | 1470 | { |
1471 | info->offset = offset_to_bitmap(ctl, offset); | 1471 | info->offset = offset_to_bitmap(ctl, offset); |
1472 | info->bytes = 0; | 1472 | info->bytes = 0; |
1473 | INIT_LIST_HEAD(&info->list); | ||
1473 | link_free_space(ctl, info); | 1474 | link_free_space(ctl, info); |
1474 | ctl->total_bitmaps++; | 1475 | ctl->total_bitmaps++; |
1475 | 1476 | ||
@@ -2319,6 +2320,7 @@ again: | |||
2319 | 2320 | ||
2320 | if (!found) { | 2321 | if (!found) { |
2321 | start = i; | 2322 | start = i; |
2323 | cluster->max_size = 0; | ||
2322 | found = true; | 2324 | found = true; |
2323 | } | 2325 | } |
2324 | 2326 | ||
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 526dd51a1966..2c984f7d4c2a 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -3490,7 +3490,7 @@ void btrfs_evict_inode(struct inode *inode) | |||
3490 | * doing the truncate. | 3490 | * doing the truncate. |
3491 | */ | 3491 | */ |
3492 | while (1) { | 3492 | while (1) { |
3493 | ret = btrfs_block_rsv_refill(root, rsv, min_size); | 3493 | ret = btrfs_block_rsv_refill_noflush(root, rsv, min_size); |
3494 | 3494 | ||
3495 | /* | 3495 | /* |
3496 | * Try and steal from the global reserve since we will | 3496 | * Try and steal from the global reserve since we will |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index a90e749ed6d2..72d461656f60 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -1278,7 +1278,7 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root, | |||
1278 | } | 1278 | } |
1279 | ret = btrfs_grow_device(trans, device, new_size); | 1279 | ret = btrfs_grow_device(trans, device, new_size); |
1280 | btrfs_commit_transaction(trans, root); | 1280 | btrfs_commit_transaction(trans, root); |
1281 | } else { | 1281 | } else if (new_size < old_size) { |
1282 | ret = btrfs_shrink_device(device, new_size); | 1282 | ret = btrfs_shrink_device(device, new_size); |
1283 | } | 1283 | } |
1284 | 1284 | ||
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index fab420db5121..c27bcb67f330 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -256,6 +256,11 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root, void *ctx) | |||
256 | btrfs_release_path(swarn->path); | 256 | btrfs_release_path(swarn->path); |
257 | 257 | ||
258 | ipath = init_ipath(4096, local_root, swarn->path); | 258 | ipath = init_ipath(4096, local_root, swarn->path); |
259 | if (IS_ERR(ipath)) { | ||
260 | ret = PTR_ERR(ipath); | ||
261 | ipath = NULL; | ||
262 | goto err; | ||
263 | } | ||
259 | ret = paths_from_inode(inum, ipath); | 264 | ret = paths_from_inode(inum, ipath); |
260 | 265 | ||
261 | if (ret < 0) | 266 | if (ret < 0) |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 17ee7fc5e64e..e28ad4baf483 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -1057,7 +1057,7 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes) | |||
1057 | int i = 0, nr_devices; | 1057 | int i = 0, nr_devices; |
1058 | int ret; | 1058 | int ret; |
1059 | 1059 | ||
1060 | nr_devices = fs_info->fs_devices->rw_devices; | 1060 | nr_devices = fs_info->fs_devices->open_devices; |
1061 | BUG_ON(!nr_devices); | 1061 | BUG_ON(!nr_devices); |
1062 | 1062 | ||
1063 | devices_info = kmalloc(sizeof(*devices_info) * nr_devices, | 1063 | devices_info = kmalloc(sizeof(*devices_info) * nr_devices, |
@@ -1079,8 +1079,8 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes) | |||
1079 | else | 1079 | else |
1080 | min_stripe_size = BTRFS_STRIPE_LEN; | 1080 | min_stripe_size = BTRFS_STRIPE_LEN; |
1081 | 1081 | ||
1082 | list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { | 1082 | list_for_each_entry(device, &fs_devices->devices, dev_list) { |
1083 | if (!device->in_fs_metadata) | 1083 | if (!device->in_fs_metadata || !device->bdev) |
1084 | continue; | 1084 | continue; |
1085 | 1085 | ||
1086 | avail_space = device->total_bytes - device->bytes_used; | 1086 | avail_space = device->total_bytes - device->bytes_used; |