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++;