diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-02-25 17:03:39 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-02-25 17:03:39 -0500 |
commit | 4660ba63f1c4e07c20a435e084f12ba48a82bd2b (patch) | |
tree | 494973a1dd4102eede20298f478574801af31b86 | |
parent | 958ede7f1b72b29cd0d29ec88ee2bcb4c87dab61 (diff) | |
parent | ec29ed5b407d618a8128f5942aade9e1758aa14b (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
* git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable:
Btrfs: fix fiemap bugs with delalloc
Btrfs: set FMODE_EXCL in btrfs_device->mode
Btrfs: make btrfs_rm_device() fail gracefully
Btrfs: Avoid accessing unmapped kernel address
Btrfs: Fix BTRFS_IOC_SUBVOL_SETFLAGS ioctl
Btrfs: allow balance to explicitly allocate chunks as it relocates
Btrfs: put ENOSPC debugging under a mount option
-rw-r--r-- | fs/btrfs/ctree.h | 3 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 9 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 138 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 2 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 126 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 7 | ||||
-rw-r--r-- | fs/btrfs/lzo.c | 21 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 13 | ||||
-rw-r--r-- | fs/btrfs/super.c | 7 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 13 |
10 files changed, 282 insertions, 57 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 2c98b3af6052..6f820fa23df4 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1254,6 +1254,7 @@ struct btrfs_root { | |||
1254 | #define BTRFS_MOUNT_SPACE_CACHE (1 << 12) | 1254 | #define BTRFS_MOUNT_SPACE_CACHE (1 << 12) |
1255 | #define BTRFS_MOUNT_CLEAR_CACHE (1 << 13) | 1255 | #define BTRFS_MOUNT_CLEAR_CACHE (1 << 13) |
1256 | #define BTRFS_MOUNT_USER_SUBVOL_RM_ALLOWED (1 << 14) | 1256 | #define BTRFS_MOUNT_USER_SUBVOL_RM_ALLOWED (1 << 14) |
1257 | #define BTRFS_MOUNT_ENOSPC_DEBUG (1 << 15) | ||
1257 | 1258 | ||
1258 | #define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt) | 1259 | #define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt) |
1259 | #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt) | 1260 | #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt) |
@@ -2218,6 +2219,8 @@ int btrfs_error_unpin_extent_range(struct btrfs_root *root, | |||
2218 | u64 start, u64 end); | 2219 | u64 start, u64 end); |
2219 | int btrfs_error_discard_extent(struct btrfs_root *root, u64 bytenr, | 2220 | int btrfs_error_discard_extent(struct btrfs_root *root, u64 bytenr, |
2220 | u64 num_bytes); | 2221 | u64 num_bytes); |
2222 | int btrfs_force_chunk_alloc(struct btrfs_trans_handle *trans, | ||
2223 | struct btrfs_root *root, u64 type); | ||
2221 | 2224 | ||
2222 | /* ctree.c */ | 2225 | /* ctree.c */ |
2223 | int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key, | 2226 | int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key, |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index f3c96fc01439..588ff9849873 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -5376,7 +5376,7 @@ again: | |||
5376 | num_bytes, data, 1); | 5376 | num_bytes, data, 1); |
5377 | goto again; | 5377 | goto again; |
5378 | } | 5378 | } |
5379 | if (ret == -ENOSPC) { | 5379 | if (ret == -ENOSPC && btrfs_test_opt(root, ENOSPC_DEBUG)) { |
5380 | struct btrfs_space_info *sinfo; | 5380 | struct btrfs_space_info *sinfo; |
5381 | 5381 | ||
5382 | sinfo = __find_space_info(root->fs_info, data); | 5382 | sinfo = __find_space_info(root->fs_info, data); |
@@ -8065,6 +8065,13 @@ out: | |||
8065 | return ret; | 8065 | return ret; |
8066 | } | 8066 | } |
8067 | 8067 | ||
8068 | int btrfs_force_chunk_alloc(struct btrfs_trans_handle *trans, | ||
8069 | struct btrfs_root *root, u64 type) | ||
8070 | { | ||
8071 | u64 alloc_flags = get_alloc_profile(root, type); | ||
8072 | return do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, 1); | ||
8073 | } | ||
8074 | |||
8068 | /* | 8075 | /* |
8069 | * helper to account the unused space of all the readonly block group in the | 8076 | * helper to account the unused space of all the readonly block group in the |
8070 | * list. takes mirrors into account. | 8077 | * list. takes mirrors into account. |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 92ac5192c518..fd3f172e94e6 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -1433,12 +1433,13 @@ int extent_clear_unlock_delalloc(struct inode *inode, | |||
1433 | */ | 1433 | */ |
1434 | u64 count_range_bits(struct extent_io_tree *tree, | 1434 | u64 count_range_bits(struct extent_io_tree *tree, |
1435 | u64 *start, u64 search_end, u64 max_bytes, | 1435 | u64 *start, u64 search_end, u64 max_bytes, |
1436 | unsigned long bits) | 1436 | unsigned long bits, int contig) |
1437 | { | 1437 | { |
1438 | struct rb_node *node; | 1438 | struct rb_node *node; |
1439 | struct extent_state *state; | 1439 | struct extent_state *state; |
1440 | u64 cur_start = *start; | 1440 | u64 cur_start = *start; |
1441 | u64 total_bytes = 0; | 1441 | u64 total_bytes = 0; |
1442 | u64 last = 0; | ||
1442 | int found = 0; | 1443 | int found = 0; |
1443 | 1444 | ||
1444 | if (search_end <= cur_start) { | 1445 | if (search_end <= cur_start) { |
@@ -1463,7 +1464,9 @@ u64 count_range_bits(struct extent_io_tree *tree, | |||
1463 | state = rb_entry(node, struct extent_state, rb_node); | 1464 | state = rb_entry(node, struct extent_state, rb_node); |
1464 | if (state->start > search_end) | 1465 | if (state->start > search_end) |
1465 | break; | 1466 | break; |
1466 | if (state->end >= cur_start && (state->state & bits)) { | 1467 | if (contig && found && state->start > last + 1) |
1468 | break; | ||
1469 | if (state->end >= cur_start && (state->state & bits) == bits) { | ||
1467 | total_bytes += min(search_end, state->end) + 1 - | 1470 | total_bytes += min(search_end, state->end) + 1 - |
1468 | max(cur_start, state->start); | 1471 | max(cur_start, state->start); |
1469 | if (total_bytes >= max_bytes) | 1472 | if (total_bytes >= max_bytes) |
@@ -1472,6 +1475,9 @@ u64 count_range_bits(struct extent_io_tree *tree, | |||
1472 | *start = state->start; | 1475 | *start = state->start; |
1473 | found = 1; | 1476 | found = 1; |
1474 | } | 1477 | } |
1478 | last = state->end; | ||
1479 | } else if (contig && found) { | ||
1480 | break; | ||
1475 | } | 1481 | } |
1476 | node = rb_next(node); | 1482 | node = rb_next(node); |
1477 | if (!node) | 1483 | if (!node) |
@@ -2912,6 +2918,46 @@ out: | |||
2912 | return sector; | 2918 | return sector; |
2913 | } | 2919 | } |
2914 | 2920 | ||
2921 | /* | ||
2922 | * helper function for fiemap, which doesn't want to see any holes. | ||
2923 | * This maps until we find something past 'last' | ||
2924 | */ | ||
2925 | static struct extent_map *get_extent_skip_holes(struct inode *inode, | ||
2926 | u64 offset, | ||
2927 | u64 last, | ||
2928 | get_extent_t *get_extent) | ||
2929 | { | ||
2930 | u64 sectorsize = BTRFS_I(inode)->root->sectorsize; | ||
2931 | struct extent_map *em; | ||
2932 | u64 len; | ||
2933 | |||
2934 | if (offset >= last) | ||
2935 | return NULL; | ||
2936 | |||
2937 | while(1) { | ||
2938 | len = last - offset; | ||
2939 | if (len == 0) | ||
2940 | break; | ||
2941 | len = (len + sectorsize - 1) & ~(sectorsize - 1); | ||
2942 | em = get_extent(inode, NULL, 0, offset, len, 0); | ||
2943 | if (!em || IS_ERR(em)) | ||
2944 | return em; | ||
2945 | |||
2946 | /* if this isn't a hole return it */ | ||
2947 | if (!test_bit(EXTENT_FLAG_VACANCY, &em->flags) && | ||
2948 | em->block_start != EXTENT_MAP_HOLE) { | ||
2949 | return em; | ||
2950 | } | ||
2951 | |||
2952 | /* this is a hole, advance to the next extent */ | ||
2953 | offset = extent_map_end(em); | ||
2954 | free_extent_map(em); | ||
2955 | if (offset >= last) | ||
2956 | break; | ||
2957 | } | ||
2958 | return NULL; | ||
2959 | } | ||
2960 | |||
2915 | int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 2961 | int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
2916 | __u64 start, __u64 len, get_extent_t *get_extent) | 2962 | __u64 start, __u64 len, get_extent_t *get_extent) |
2917 | { | 2963 | { |
@@ -2921,16 +2967,19 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
2921 | u32 flags = 0; | 2967 | u32 flags = 0; |
2922 | u32 found_type; | 2968 | u32 found_type; |
2923 | u64 last; | 2969 | u64 last; |
2970 | u64 last_for_get_extent = 0; | ||
2924 | u64 disko = 0; | 2971 | u64 disko = 0; |
2972 | u64 isize = i_size_read(inode); | ||
2925 | struct btrfs_key found_key; | 2973 | struct btrfs_key found_key; |
2926 | struct extent_map *em = NULL; | 2974 | struct extent_map *em = NULL; |
2927 | struct extent_state *cached_state = NULL; | 2975 | struct extent_state *cached_state = NULL; |
2928 | struct btrfs_path *path; | 2976 | struct btrfs_path *path; |
2929 | struct btrfs_file_extent_item *item; | 2977 | struct btrfs_file_extent_item *item; |
2930 | int end = 0; | 2978 | int end = 0; |
2931 | u64 em_start = 0, em_len = 0; | 2979 | u64 em_start = 0; |
2980 | u64 em_len = 0; | ||
2981 | u64 em_end = 0; | ||
2932 | unsigned long emflags; | 2982 | unsigned long emflags; |
2933 | int hole = 0; | ||
2934 | 2983 | ||
2935 | if (len == 0) | 2984 | if (len == 0) |
2936 | return -EINVAL; | 2985 | return -EINVAL; |
@@ -2940,6 +2989,10 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
2940 | return -ENOMEM; | 2989 | return -ENOMEM; |
2941 | path->leave_spinning = 1; | 2990 | path->leave_spinning = 1; |
2942 | 2991 | ||
2992 | /* | ||
2993 | * lookup the last file extent. We're not using i_size here | ||
2994 | * because there might be preallocation past i_size | ||
2995 | */ | ||
2943 | ret = btrfs_lookup_file_extent(NULL, BTRFS_I(inode)->root, | 2996 | ret = btrfs_lookup_file_extent(NULL, BTRFS_I(inode)->root, |
2944 | path, inode->i_ino, -1, 0); | 2997 | path, inode->i_ino, -1, 0); |
2945 | if (ret < 0) { | 2998 | if (ret < 0) { |
@@ -2953,18 +3006,38 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
2953 | btrfs_item_key_to_cpu(path->nodes[0], &found_key, path->slots[0]); | 3006 | btrfs_item_key_to_cpu(path->nodes[0], &found_key, path->slots[0]); |
2954 | found_type = btrfs_key_type(&found_key); | 3007 | found_type = btrfs_key_type(&found_key); |
2955 | 3008 | ||
2956 | /* No extents, just return */ | 3009 | /* No extents, but there might be delalloc bits */ |
2957 | if (found_key.objectid != inode->i_ino || | 3010 | if (found_key.objectid != inode->i_ino || |
2958 | found_type != BTRFS_EXTENT_DATA_KEY) { | 3011 | found_type != BTRFS_EXTENT_DATA_KEY) { |
2959 | btrfs_free_path(path); | 3012 | /* have to trust i_size as the end */ |
2960 | return 0; | 3013 | last = (u64)-1; |
3014 | last_for_get_extent = isize; | ||
3015 | } else { | ||
3016 | /* | ||
3017 | * remember the start of the last extent. There are a | ||
3018 | * bunch of different factors that go into the length of the | ||
3019 | * extent, so its much less complex to remember where it started | ||
3020 | */ | ||
3021 | last = found_key.offset; | ||
3022 | last_for_get_extent = last + 1; | ||
2961 | } | 3023 | } |
2962 | last = found_key.offset; | ||
2963 | btrfs_free_path(path); | 3024 | btrfs_free_path(path); |
2964 | 3025 | ||
3026 | /* | ||
3027 | * we might have some extents allocated but more delalloc past those | ||
3028 | * extents. so, we trust isize unless the start of the last extent is | ||
3029 | * beyond isize | ||
3030 | */ | ||
3031 | if (last < isize) { | ||
3032 | last = (u64)-1; | ||
3033 | last_for_get_extent = isize; | ||
3034 | } | ||
3035 | |||
2965 | lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0, | 3036 | lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0, |
2966 | &cached_state, GFP_NOFS); | 3037 | &cached_state, GFP_NOFS); |
2967 | em = get_extent(inode, NULL, 0, off, max - off, 0); | 3038 | |
3039 | em = get_extent_skip_holes(inode, off, last_for_get_extent, | ||
3040 | get_extent); | ||
2968 | if (!em) | 3041 | if (!em) |
2969 | goto out; | 3042 | goto out; |
2970 | if (IS_ERR(em)) { | 3043 | if (IS_ERR(em)) { |
@@ -2973,19 +3046,14 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
2973 | } | 3046 | } |
2974 | 3047 | ||
2975 | while (!end) { | 3048 | while (!end) { |
2976 | hole = 0; | 3049 | off = extent_map_end(em); |
2977 | off = em->start + em->len; | ||
2978 | if (off >= max) | 3050 | if (off >= max) |
2979 | end = 1; | 3051 | end = 1; |
2980 | 3052 | ||
2981 | if (em->block_start == EXTENT_MAP_HOLE) { | ||
2982 | hole = 1; | ||
2983 | goto next; | ||
2984 | } | ||
2985 | |||
2986 | em_start = em->start; | 3053 | em_start = em->start; |
2987 | em_len = em->len; | 3054 | em_len = em->len; |
2988 | 3055 | em_end = extent_map_end(em); | |
3056 | emflags = em->flags; | ||
2989 | disko = 0; | 3057 | disko = 0; |
2990 | flags = 0; | 3058 | flags = 0; |
2991 | 3059 | ||
@@ -3004,37 +3072,29 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
3004 | if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) | 3072 | if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) |
3005 | flags |= FIEMAP_EXTENT_ENCODED; | 3073 | flags |= FIEMAP_EXTENT_ENCODED; |
3006 | 3074 | ||
3007 | next: | ||
3008 | emflags = em->flags; | ||
3009 | free_extent_map(em); | 3075 | free_extent_map(em); |
3010 | em = NULL; | 3076 | em = NULL; |
3011 | if (!end) { | 3077 | if ((em_start >= last) || em_len == (u64)-1 || |
3012 | em = get_extent(inode, NULL, 0, off, max - off, 0); | 3078 | (last == (u64)-1 && isize <= em_end)) { |
3013 | if (!em) | ||
3014 | goto out; | ||
3015 | if (IS_ERR(em)) { | ||
3016 | ret = PTR_ERR(em); | ||
3017 | goto out; | ||
3018 | } | ||
3019 | emflags = em->flags; | ||
3020 | } | ||
3021 | |||
3022 | if (test_bit(EXTENT_FLAG_VACANCY, &emflags)) { | ||
3023 | flags |= FIEMAP_EXTENT_LAST; | 3079 | flags |= FIEMAP_EXTENT_LAST; |
3024 | end = 1; | 3080 | end = 1; |
3025 | } | 3081 | } |
3026 | 3082 | ||
3027 | if (em_start == last) { | 3083 | /* now scan forward to see if this is really the last extent. */ |
3084 | em = get_extent_skip_holes(inode, off, last_for_get_extent, | ||
3085 | get_extent); | ||
3086 | if (IS_ERR(em)) { | ||
3087 | ret = PTR_ERR(em); | ||
3088 | goto out; | ||
3089 | } | ||
3090 | if (!em) { | ||
3028 | flags |= FIEMAP_EXTENT_LAST; | 3091 | flags |= FIEMAP_EXTENT_LAST; |
3029 | end = 1; | 3092 | end = 1; |
3030 | } | 3093 | } |
3031 | 3094 | ret = fiemap_fill_next_extent(fieinfo, em_start, disko, | |
3032 | if (!hole) { | 3095 | em_len, flags); |
3033 | ret = fiemap_fill_next_extent(fieinfo, em_start, disko, | 3096 | if (ret) |
3034 | em_len, flags); | 3097 | goto out_free; |
3035 | if (ret) | ||
3036 | goto out_free; | ||
3037 | } | ||
3038 | } | 3098 | } |
3039 | out_free: | 3099 | out_free: |
3040 | free_extent_map(em); | 3100 | free_extent_map(em); |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 7083cfafd061..9318dfefd59c 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
@@ -191,7 +191,7 @@ void extent_io_exit(void); | |||
191 | 191 | ||
192 | u64 count_range_bits(struct extent_io_tree *tree, | 192 | u64 count_range_bits(struct extent_io_tree *tree, |
193 | u64 *start, u64 search_end, | 193 | u64 *start, u64 search_end, |
194 | u64 max_bytes, unsigned long bits); | 194 | u64 max_bytes, unsigned long bits, int contig); |
195 | 195 | ||
196 | void free_extent_state(struct extent_state *state); | 196 | void free_extent_state(struct extent_state *state); |
197 | int test_range_bit(struct extent_io_tree *tree, u64 start, u64 end, | 197 | int test_range_bit(struct extent_io_tree *tree, u64 start, u64 end, |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index fb9bd7832b6d..0efdb65953c5 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1913,7 +1913,7 @@ static int btrfs_clean_io_failures(struct inode *inode, u64 start) | |||
1913 | 1913 | ||
1914 | private = 0; | 1914 | private = 0; |
1915 | if (count_range_bits(&BTRFS_I(inode)->io_failure_tree, &private, | 1915 | if (count_range_bits(&BTRFS_I(inode)->io_failure_tree, &private, |
1916 | (u64)-1, 1, EXTENT_DIRTY)) { | 1916 | (u64)-1, 1, EXTENT_DIRTY, 0)) { |
1917 | ret = get_state_private(&BTRFS_I(inode)->io_failure_tree, | 1917 | ret = get_state_private(&BTRFS_I(inode)->io_failure_tree, |
1918 | start, &private_failure); | 1918 | start, &private_failure); |
1919 | if (ret == 0) { | 1919 | if (ret == 0) { |
@@ -5280,6 +5280,128 @@ out: | |||
5280 | return em; | 5280 | return em; |
5281 | } | 5281 | } |
5282 | 5282 | ||
5283 | struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *page, | ||
5284 | size_t pg_offset, u64 start, u64 len, | ||
5285 | int create) | ||
5286 | { | ||
5287 | struct extent_map *em; | ||
5288 | struct extent_map *hole_em = NULL; | ||
5289 | u64 range_start = start; | ||
5290 | u64 end; | ||
5291 | u64 found; | ||
5292 | u64 found_end; | ||
5293 | int err = 0; | ||
5294 | |||
5295 | em = btrfs_get_extent(inode, page, pg_offset, start, len, create); | ||
5296 | if (IS_ERR(em)) | ||
5297 | return em; | ||
5298 | if (em) { | ||
5299 | /* | ||
5300 | * if our em maps to a hole, there might | ||
5301 | * actually be delalloc bytes behind it | ||
5302 | */ | ||
5303 | if (em->block_start != EXTENT_MAP_HOLE) | ||
5304 | return em; | ||
5305 | else | ||
5306 | hole_em = em; | ||
5307 | } | ||
5308 | |||
5309 | /* check to see if we've wrapped (len == -1 or similar) */ | ||
5310 | end = start + len; | ||
5311 | if (end < start) | ||
5312 | end = (u64)-1; | ||
5313 | else | ||
5314 | end -= 1; | ||
5315 | |||
5316 | em = NULL; | ||
5317 | |||
5318 | /* ok, we didn't find anything, lets look for delalloc */ | ||
5319 | found = count_range_bits(&BTRFS_I(inode)->io_tree, &range_start, | ||
5320 | end, len, EXTENT_DELALLOC, 1); | ||
5321 | found_end = range_start + found; | ||
5322 | if (found_end < range_start) | ||
5323 | found_end = (u64)-1; | ||
5324 | |||
5325 | /* | ||
5326 | * we didn't find anything useful, return | ||
5327 | * the original results from get_extent() | ||
5328 | */ | ||
5329 | if (range_start > end || found_end <= start) { | ||
5330 | em = hole_em; | ||
5331 | hole_em = NULL; | ||
5332 | goto out; | ||
5333 | } | ||
5334 | |||
5335 | /* adjust the range_start to make sure it doesn't | ||
5336 | * go backwards from the start they passed in | ||
5337 | */ | ||
5338 | range_start = max(start,range_start); | ||
5339 | found = found_end - range_start; | ||
5340 | |||
5341 | if (found > 0) { | ||
5342 | u64 hole_start = start; | ||
5343 | u64 hole_len = len; | ||
5344 | |||
5345 | em = alloc_extent_map(GFP_NOFS); | ||
5346 | if (!em) { | ||
5347 | err = -ENOMEM; | ||
5348 | goto out; | ||
5349 | } | ||
5350 | /* | ||
5351 | * when btrfs_get_extent can't find anything it | ||
5352 | * returns one huge hole | ||
5353 | * | ||
5354 | * make sure what it found really fits our range, and | ||
5355 | * adjust to make sure it is based on the start from | ||
5356 | * the caller | ||
5357 | */ | ||
5358 | if (hole_em) { | ||
5359 | u64 calc_end = extent_map_end(hole_em); | ||
5360 | |||
5361 | if (calc_end <= start || (hole_em->start > end)) { | ||
5362 | free_extent_map(hole_em); | ||
5363 | hole_em = NULL; | ||
5364 | } else { | ||
5365 | hole_start = max(hole_em->start, start); | ||
5366 | hole_len = calc_end - hole_start; | ||
5367 | } | ||
5368 | } | ||
5369 | em->bdev = NULL; | ||
5370 | if (hole_em && range_start > hole_start) { | ||
5371 | /* our hole starts before our delalloc, so we | ||
5372 | * have to return just the parts of the hole | ||
5373 | * that go until the delalloc starts | ||
5374 | */ | ||
5375 | em->len = min(hole_len, | ||
5376 | range_start - hole_start); | ||
5377 | em->start = hole_start; | ||
5378 | em->orig_start = hole_start; | ||
5379 | /* | ||
5380 | * don't adjust block start at all, | ||
5381 | * it is fixed at EXTENT_MAP_HOLE | ||
5382 | */ | ||
5383 | em->block_start = hole_em->block_start; | ||
5384 | em->block_len = hole_len; | ||
5385 | } else { | ||
5386 | em->start = range_start; | ||
5387 | em->len = found; | ||
5388 | em->orig_start = range_start; | ||
5389 | em->block_start = EXTENT_MAP_DELALLOC; | ||
5390 | em->block_len = found; | ||
5391 | } | ||
5392 | } else if (hole_em) { | ||
5393 | return hole_em; | ||
5394 | } | ||
5395 | out: | ||
5396 | |||
5397 | free_extent_map(hole_em); | ||
5398 | if (err) { | ||
5399 | free_extent_map(em); | ||
5400 | return ERR_PTR(err); | ||
5401 | } | ||
5402 | return em; | ||
5403 | } | ||
5404 | |||
5283 | static struct extent_map *btrfs_new_extent_direct(struct inode *inode, | 5405 | static struct extent_map *btrfs_new_extent_direct(struct inode *inode, |
5284 | u64 start, u64 len) | 5406 | u64 start, u64 len) |
5285 | { | 5407 | { |
@@ -6102,7 +6224,7 @@ out: | |||
6102 | static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 6224 | static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
6103 | __u64 start, __u64 len) | 6225 | __u64 start, __u64 len) |
6104 | { | 6226 | { |
6105 | return extent_fiemap(inode, fieinfo, start, len, btrfs_get_extent); | 6227 | return extent_fiemap(inode, fieinfo, start, len, btrfs_get_extent_fiemap); |
6106 | } | 6228 | } |
6107 | 6229 | ||
6108 | int btrfs_readpage(struct file *file, struct page *page) | 6230 | int btrfs_readpage(struct file *file, struct page *page) |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index be2d4f6aaa5e..5fdb2abc4fa7 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -1071,12 +1071,15 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file, | |||
1071 | if (copy_from_user(&flags, arg, sizeof(flags))) | 1071 | if (copy_from_user(&flags, arg, sizeof(flags))) |
1072 | return -EFAULT; | 1072 | return -EFAULT; |
1073 | 1073 | ||
1074 | if (flags & ~BTRFS_SUBVOL_CREATE_ASYNC) | 1074 | if (flags & BTRFS_SUBVOL_CREATE_ASYNC) |
1075 | return -EINVAL; | 1075 | return -EINVAL; |
1076 | 1076 | ||
1077 | if (flags & ~BTRFS_SUBVOL_RDONLY) | 1077 | if (flags & ~BTRFS_SUBVOL_RDONLY) |
1078 | return -EOPNOTSUPP; | 1078 | return -EOPNOTSUPP; |
1079 | 1079 | ||
1080 | if (!is_owner_or_cap(inode)) | ||
1081 | return -EACCES; | ||
1082 | |||
1080 | down_write(&root->fs_info->subvol_sem); | 1083 | down_write(&root->fs_info->subvol_sem); |
1081 | 1084 | ||
1082 | /* nothing to do */ | 1085 | /* nothing to do */ |
@@ -1097,7 +1100,7 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file, | |||
1097 | goto out_reset; | 1100 | goto out_reset; |
1098 | } | 1101 | } |
1099 | 1102 | ||
1100 | ret = btrfs_update_root(trans, root, | 1103 | ret = btrfs_update_root(trans, root->fs_info->tree_root, |
1101 | &root->root_key, &root->root_item); | 1104 | &root->root_key, &root->root_item); |
1102 | 1105 | ||
1103 | btrfs_commit_transaction(trans, root); | 1106 | btrfs_commit_transaction(trans, root); |
diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index cc9b450399df..a178f5ebea78 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c | |||
@@ -280,6 +280,7 @@ static int lzo_decompress_biovec(struct list_head *ws, | |||
280 | unsigned long tot_out; | 280 | unsigned long tot_out; |
281 | unsigned long tot_len; | 281 | unsigned long tot_len; |
282 | char *buf; | 282 | char *buf; |
283 | bool may_late_unmap, need_unmap; | ||
283 | 284 | ||
284 | data_in = kmap(pages_in[0]); | 285 | data_in = kmap(pages_in[0]); |
285 | tot_len = read_compress_length(data_in); | 286 | tot_len = read_compress_length(data_in); |
@@ -300,11 +301,13 @@ static int lzo_decompress_biovec(struct list_head *ws, | |||
300 | 301 | ||
301 | tot_in += in_len; | 302 | tot_in += in_len; |
302 | working_bytes = in_len; | 303 | working_bytes = in_len; |
304 | may_late_unmap = need_unmap = false; | ||
303 | 305 | ||
304 | /* fast path: avoid using the working buffer */ | 306 | /* fast path: avoid using the working buffer */ |
305 | if (in_page_bytes_left >= in_len) { | 307 | if (in_page_bytes_left >= in_len) { |
306 | buf = data_in + in_offset; | 308 | buf = data_in + in_offset; |
307 | bytes = in_len; | 309 | bytes = in_len; |
310 | may_late_unmap = true; | ||
308 | goto cont; | 311 | goto cont; |
309 | } | 312 | } |
310 | 313 | ||
@@ -329,14 +332,17 @@ cont: | |||
329 | if (working_bytes == 0 && tot_in >= tot_len) | 332 | if (working_bytes == 0 && tot_in >= tot_len) |
330 | break; | 333 | break; |
331 | 334 | ||
332 | kunmap(pages_in[page_in_index]); | 335 | if (page_in_index + 1 >= total_pages_in) { |
333 | page_in_index++; | ||
334 | if (page_in_index >= total_pages_in) { | ||
335 | ret = -1; | 336 | ret = -1; |
336 | data_in = NULL; | ||
337 | goto done; | 337 | goto done; |
338 | } | 338 | } |
339 | data_in = kmap(pages_in[page_in_index]); | 339 | |
340 | if (may_late_unmap) | ||
341 | need_unmap = true; | ||
342 | else | ||
343 | kunmap(pages_in[page_in_index]); | ||
344 | |||
345 | data_in = kmap(pages_in[++page_in_index]); | ||
340 | 346 | ||
341 | in_page_bytes_left = PAGE_CACHE_SIZE; | 347 | in_page_bytes_left = PAGE_CACHE_SIZE; |
342 | in_offset = 0; | 348 | in_offset = 0; |
@@ -346,6 +352,8 @@ cont: | |||
346 | out_len = lzo1x_worst_compress(PAGE_CACHE_SIZE); | 352 | out_len = lzo1x_worst_compress(PAGE_CACHE_SIZE); |
347 | ret = lzo1x_decompress_safe(buf, in_len, workspace->buf, | 353 | ret = lzo1x_decompress_safe(buf, in_len, workspace->buf, |
348 | &out_len); | 354 | &out_len); |
355 | if (need_unmap) | ||
356 | kunmap(pages_in[page_in_index - 1]); | ||
349 | if (ret != LZO_E_OK) { | 357 | if (ret != LZO_E_OK) { |
350 | printk(KERN_WARNING "btrfs decompress failed\n"); | 358 | printk(KERN_WARNING "btrfs decompress failed\n"); |
351 | ret = -1; | 359 | ret = -1; |
@@ -363,8 +371,7 @@ cont: | |||
363 | break; | 371 | break; |
364 | } | 372 | } |
365 | done: | 373 | done: |
366 | if (data_in) | 374 | kunmap(pages_in[page_in_index]); |
367 | kunmap(pages_in[page_in_index]); | ||
368 | return ret; | 375 | return ret; |
369 | } | 376 | } |
370 | 377 | ||
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 0825e4ed9447..31ade5802ae8 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -3654,6 +3654,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) | |||
3654 | u32 item_size; | 3654 | u32 item_size; |
3655 | int ret; | 3655 | int ret; |
3656 | int err = 0; | 3656 | int err = 0; |
3657 | int progress = 0; | ||
3657 | 3658 | ||
3658 | path = btrfs_alloc_path(); | 3659 | path = btrfs_alloc_path(); |
3659 | if (!path) | 3660 | if (!path) |
@@ -3666,9 +3667,10 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) | |||
3666 | } | 3667 | } |
3667 | 3668 | ||
3668 | while (1) { | 3669 | while (1) { |
3670 | progress++; | ||
3669 | trans = btrfs_start_transaction(rc->extent_root, 0); | 3671 | trans = btrfs_start_transaction(rc->extent_root, 0); |
3670 | BUG_ON(IS_ERR(trans)); | 3672 | BUG_ON(IS_ERR(trans)); |
3671 | 3673 | restart: | |
3672 | if (update_backref_cache(trans, &rc->backref_cache)) { | 3674 | if (update_backref_cache(trans, &rc->backref_cache)) { |
3673 | btrfs_end_transaction(trans, rc->extent_root); | 3675 | btrfs_end_transaction(trans, rc->extent_root); |
3674 | continue; | 3676 | continue; |
@@ -3781,6 +3783,15 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) | |||
3781 | } | 3783 | } |
3782 | } | 3784 | } |
3783 | } | 3785 | } |
3786 | if (trans && progress && err == -ENOSPC) { | ||
3787 | ret = btrfs_force_chunk_alloc(trans, rc->extent_root, | ||
3788 | rc->block_group->flags); | ||
3789 | if (ret == 0) { | ||
3790 | err = 0; | ||
3791 | progress = 0; | ||
3792 | goto restart; | ||
3793 | } | ||
3794 | } | ||
3784 | 3795 | ||
3785 | btrfs_release_path(rc->extent_root, path); | 3796 | btrfs_release_path(rc->extent_root, path); |
3786 | clear_extent_bits(&rc->processed_blocks, 0, (u64)-1, EXTENT_DIRTY, | 3797 | clear_extent_bits(&rc->processed_blocks, 0, (u64)-1, EXTENT_DIRTY, |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index a004008f7d28..d39a9895d932 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -155,7 +155,8 @@ enum { | |||
155 | Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress, | 155 | Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress, |
156 | Opt_compress_type, Opt_compress_force, Opt_compress_force_type, | 156 | Opt_compress_type, Opt_compress_force, Opt_compress_force_type, |
157 | Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, | 157 | Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, |
158 | Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed, Opt_err, | 158 | Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed, |
159 | Opt_enospc_debug, Opt_err, | ||
159 | }; | 160 | }; |
160 | 161 | ||
161 | static match_table_t tokens = { | 162 | static match_table_t tokens = { |
@@ -184,6 +185,7 @@ static match_table_t tokens = { | |||
184 | {Opt_space_cache, "space_cache"}, | 185 | {Opt_space_cache, "space_cache"}, |
185 | {Opt_clear_cache, "clear_cache"}, | 186 | {Opt_clear_cache, "clear_cache"}, |
186 | {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, | 187 | {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, |
188 | {Opt_enospc_debug, "enospc_debug"}, | ||
187 | {Opt_err, NULL}, | 189 | {Opt_err, NULL}, |
188 | }; | 190 | }; |
189 | 191 | ||
@@ -358,6 +360,9 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
358 | case Opt_user_subvol_rm_allowed: | 360 | case Opt_user_subvol_rm_allowed: |
359 | btrfs_set_opt(info->mount_opt, USER_SUBVOL_RM_ALLOWED); | 361 | btrfs_set_opt(info->mount_opt, USER_SUBVOL_RM_ALLOWED); |
360 | break; | 362 | break; |
363 | case Opt_enospc_debug: | ||
364 | btrfs_set_opt(info->mount_opt, ENOSPC_DEBUG); | ||
365 | break; | ||
361 | case Opt_err: | 366 | case Opt_err: |
362 | printk(KERN_INFO "btrfs: unrecognized mount option " | 367 | printk(KERN_INFO "btrfs: unrecognized mount option " |
363 | "'%s'\n", p); | 368 | "'%s'\n", p); |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index af7dbca15276..dd13eb81ee40 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1338,11 +1338,11 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1338 | 1338 | ||
1339 | ret = btrfs_shrink_device(device, 0); | 1339 | ret = btrfs_shrink_device(device, 0); |
1340 | if (ret) | 1340 | if (ret) |
1341 | goto error_brelse; | 1341 | goto error_undo; |
1342 | 1342 | ||
1343 | ret = btrfs_rm_dev_item(root->fs_info->chunk_root, device); | 1343 | ret = btrfs_rm_dev_item(root->fs_info->chunk_root, device); |
1344 | if (ret) | 1344 | if (ret) |
1345 | goto error_brelse; | 1345 | goto error_undo; |
1346 | 1346 | ||
1347 | device->in_fs_metadata = 0; | 1347 | device->in_fs_metadata = 0; |
1348 | 1348 | ||
@@ -1416,6 +1416,13 @@ out: | |||
1416 | mutex_unlock(&root->fs_info->volume_mutex); | 1416 | mutex_unlock(&root->fs_info->volume_mutex); |
1417 | mutex_unlock(&uuid_mutex); | 1417 | mutex_unlock(&uuid_mutex); |
1418 | return ret; | 1418 | return ret; |
1419 | error_undo: | ||
1420 | if (device->writeable) { | ||
1421 | list_add(&device->dev_alloc_list, | ||
1422 | &root->fs_info->fs_devices->alloc_list); | ||
1423 | root->fs_info->fs_devices->rw_devices++; | ||
1424 | } | ||
1425 | goto error_brelse; | ||
1419 | } | 1426 | } |
1420 | 1427 | ||
1421 | /* | 1428 | /* |
@@ -1633,7 +1640,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
1633 | device->dev_root = root->fs_info->dev_root; | 1640 | device->dev_root = root->fs_info->dev_root; |
1634 | device->bdev = bdev; | 1641 | device->bdev = bdev; |
1635 | device->in_fs_metadata = 1; | 1642 | device->in_fs_metadata = 1; |
1636 | device->mode = 0; | 1643 | device->mode = FMODE_EXCL; |
1637 | set_blocksize(device->bdev, 4096); | 1644 | set_blocksize(device->bdev, 4096); |
1638 | 1645 | ||
1639 | if (seeding_dev) { | 1646 | if (seeding_dev) { |