diff options
| -rw-r--r-- | Documentation/filesystems/btrfs.txt | 4 | ||||
| -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 |
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. | |||
| 63 | Userspace tools for creating and manipulating Btrfs file systems are | 63 | Userspace tools for creating and manipulating Btrfs file systems are |
| 64 | available from the git repository at the following location: | 64 | available 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 | ||
| 69 | These include the following tools: | 69 | These 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, | |||
| 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++; |
