aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/btrfs.txt4
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/extent-tree.c34
-rw-r--r--fs/btrfs/extent_io.c27
-rw-r--r--fs/btrfs/free-space-cache.c2
-rw-r--r--fs/btrfs/inode.c2
-rw-r--r--fs/btrfs/ioctl.c2
-rw-r--r--fs/btrfs/scrub.c5
-rw-r--r--fs/btrfs/super.c6
9 files changed, 60 insertions, 25 deletions
diff --git a/Documentation/filesystems/btrfs.txt b/Documentation/filesystems/btrfs.txt
index 64087c34327f..7671352216f1 100644
--- a/Documentation/filesystems/btrfs.txt
+++ b/Documentation/filesystems/btrfs.txt
@@ -63,8 +63,8 @@ IRC network.
63Userspace tools for creating and manipulating Btrfs file systems are 63Userspace tools for creating and manipulating Btrfs file systems are
64available from the git repository at the following location: 64available from the git repository at the following location:
65 65
66 http://git.kernel.org/?p=linux/kernel/git/mason/btrfs-progs-unstable.git 66 http://git.kernel.org/?p=linux/kernel/git/mason/btrfs-progs.git
67 git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-progs-unstable.git 67 git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-progs.git
68 68
69These include the following tools: 69These include the following tools:
70 70
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,
2369int btrfs_block_rsv_refill(struct btrfs_root *root, 2369int 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);
2372int btrfs_block_rsv_refill_noflush(struct btrfs_root *root,
2373 struct btrfs_block_rsv *block_rsv,
2374 u64 min_reserved);
2372int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv, 2375int 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
3891int btrfs_block_rsv_refill(struct btrfs_root *root, 3891static 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
3921int 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
3928int 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
3921int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv, 3935int 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) {
2303error_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;