diff options
| -rw-r--r-- | fs/btrfs/acl.c | 9 | ||||
| -rw-r--r-- | fs/btrfs/ctree.h | 9 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 2 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 125 | ||||
| -rw-r--r-- | fs/btrfs/extent_io.c | 82 | ||||
| -rw-r--r-- | fs/btrfs/extent_io.h | 2 | ||||
| -rw-r--r-- | fs/btrfs/file.c | 21 | ||||
| -rw-r--r-- | fs/btrfs/free-space-cache.c | 119 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 165 | ||||
| -rw-r--r-- | fs/btrfs/ioctl.c | 2 | ||||
| -rw-r--r-- | fs/btrfs/super.c | 42 | ||||
| -rw-r--r-- | fs/btrfs/transaction.c | 48 | ||||
| -rw-r--r-- | fs/btrfs/transaction.h | 4 | ||||
| -rw-r--r-- | fs/btrfs/xattr.c | 33 |
14 files changed, 430 insertions, 233 deletions
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index de34bfad9ec3..5d505aaa72fb 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c | |||
| @@ -178,16 +178,17 @@ static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, | |||
| 178 | 178 | ||
| 179 | if (value) { | 179 | if (value) { |
| 180 | acl = posix_acl_from_xattr(value, size); | 180 | acl = posix_acl_from_xattr(value, size); |
| 181 | if (acl == NULL) { | 181 | if (acl) { |
| 182 | value = NULL; | 182 | ret = posix_acl_valid(acl); |
| 183 | size = 0; | 183 | if (ret) |
| 184 | goto out; | ||
| 184 | } else if (IS_ERR(acl)) { | 185 | } else if (IS_ERR(acl)) { |
| 185 | return PTR_ERR(acl); | 186 | return PTR_ERR(acl); |
| 186 | } | 187 | } |
| 187 | } | 188 | } |
| 188 | 189 | ||
| 189 | ret = btrfs_set_acl(NULL, dentry->d_inode, acl, type); | 190 | ret = btrfs_set_acl(NULL, dentry->d_inode, acl, type); |
| 190 | 191 | out: | |
| 191 | posix_acl_release(acl); | 192 | posix_acl_release(acl); |
| 192 | 193 | ||
| 193 | return ret; | 194 | return ret; |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 3458b5725540..2e61fe1b6b8c 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -740,8 +740,10 @@ struct btrfs_space_info { | |||
| 740 | */ | 740 | */ |
| 741 | unsigned long reservation_progress; | 741 | unsigned long reservation_progress; |
| 742 | 742 | ||
| 743 | int full; /* indicates that we cannot allocate any more | 743 | int full:1; /* indicates that we cannot allocate any more |
| 744 | chunks for this space */ | 744 | chunks for this space */ |
| 745 | int chunk_alloc:1; /* set if we are allocating a chunk */ | ||
| 746 | |||
| 745 | int force_alloc; /* set if we need to force a chunk alloc for | 747 | int force_alloc; /* set if we need to force a chunk alloc for |
| 746 | this space */ | 748 | this space */ |
| 747 | 749 | ||
| @@ -2576,6 +2578,11 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, | |||
| 2576 | int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, | 2578 | int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, |
| 2577 | struct inode *inode, u64 start, u64 end); | 2579 | struct inode *inode, u64 start, u64 end); |
| 2578 | int btrfs_release_file(struct inode *inode, struct file *file); | 2580 | int btrfs_release_file(struct inode *inode, struct file *file); |
| 2581 | void btrfs_drop_pages(struct page **pages, size_t num_pages); | ||
| 2582 | int btrfs_dirty_pages(struct btrfs_root *root, struct inode *inode, | ||
| 2583 | struct page **pages, size_t num_pages, | ||
| 2584 | loff_t pos, size_t write_bytes, | ||
| 2585 | struct extent_state **cached); | ||
| 2579 | 2586 | ||
| 2580 | /* tree-defrag.c */ | 2587 | /* tree-defrag.c */ |
| 2581 | int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, | 2588 | int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 8f1d44ba332f..68c84c8c24bd 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -3057,7 +3057,7 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root) | |||
| 3057 | btrfs_destroy_pinned_extent(root, | 3057 | btrfs_destroy_pinned_extent(root, |
| 3058 | root->fs_info->pinned_extents); | 3058 | root->fs_info->pinned_extents); |
| 3059 | 3059 | ||
| 3060 | t->use_count = 0; | 3060 | atomic_set(&t->use_count, 0); |
| 3061 | list_del_init(&t->list); | 3061 | list_del_init(&t->list); |
| 3062 | memset(t, 0, sizeof(*t)); | 3062 | memset(t, 0, sizeof(*t)); |
| 3063 | kmem_cache_free(btrfs_transaction_cachep, t); | 3063 | kmem_cache_free(btrfs_transaction_cachep, t); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index f619c3cb13b7..31f33ba56fe8 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -33,6 +33,25 @@ | |||
| 33 | #include "locking.h" | 33 | #include "locking.h" |
| 34 | #include "free-space-cache.h" | 34 | #include "free-space-cache.h" |
| 35 | 35 | ||
| 36 | /* control flags for do_chunk_alloc's force field | ||
| 37 | * CHUNK_ALLOC_NO_FORCE means to only allocate a chunk | ||
| 38 | * if we really need one. | ||
| 39 | * | ||
| 40 | * CHUNK_ALLOC_FORCE means it must try to allocate one | ||
| 41 | * | ||
| 42 | * CHUNK_ALLOC_LIMITED means to only try and allocate one | ||
| 43 | * if we have very few chunks already allocated. This is | ||
| 44 | * used as part of the clustering code to help make sure | ||
| 45 | * we have a good pool of storage to cluster in, without | ||
| 46 | * filling the FS with empty chunks | ||
| 47 | * | ||
| 48 | */ | ||
| 49 | enum { | ||
| 50 | CHUNK_ALLOC_NO_FORCE = 0, | ||
| 51 | CHUNK_ALLOC_FORCE = 1, | ||
| 52 | CHUNK_ALLOC_LIMITED = 2, | ||
| 53 | }; | ||
| 54 | |||
| 36 | static int update_block_group(struct btrfs_trans_handle *trans, | 55 | static int update_block_group(struct btrfs_trans_handle *trans, |
| 37 | struct btrfs_root *root, | 56 | struct btrfs_root *root, |
| 38 | u64 bytenr, u64 num_bytes, int alloc); | 57 | u64 bytenr, u64 num_bytes, int alloc); |
| @@ -3019,7 +3038,8 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, | |||
| 3019 | found->bytes_readonly = 0; | 3038 | found->bytes_readonly = 0; |
| 3020 | found->bytes_may_use = 0; | 3039 | found->bytes_may_use = 0; |
| 3021 | found->full = 0; | 3040 | found->full = 0; |
| 3022 | found->force_alloc = 0; | 3041 | found->force_alloc = CHUNK_ALLOC_NO_FORCE; |
| 3042 | found->chunk_alloc = 0; | ||
| 3023 | *space_info = found; | 3043 | *space_info = found; |
| 3024 | list_add_rcu(&found->list, &info->space_info); | 3044 | list_add_rcu(&found->list, &info->space_info); |
| 3025 | atomic_set(&found->caching_threads, 0); | 3045 | atomic_set(&found->caching_threads, 0); |
| @@ -3150,7 +3170,7 @@ again: | |||
| 3150 | if (!data_sinfo->full && alloc_chunk) { | 3170 | if (!data_sinfo->full && alloc_chunk) { |
| 3151 | u64 alloc_target; | 3171 | u64 alloc_target; |
| 3152 | 3172 | ||
| 3153 | data_sinfo->force_alloc = 1; | 3173 | data_sinfo->force_alloc = CHUNK_ALLOC_FORCE; |
| 3154 | spin_unlock(&data_sinfo->lock); | 3174 | spin_unlock(&data_sinfo->lock); |
| 3155 | alloc: | 3175 | alloc: |
| 3156 | alloc_target = btrfs_get_alloc_profile(root, 1); | 3176 | alloc_target = btrfs_get_alloc_profile(root, 1); |
| @@ -3160,7 +3180,8 @@ alloc: | |||
| 3160 | 3180 | ||
| 3161 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | 3181 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, |
| 3162 | bytes + 2 * 1024 * 1024, | 3182 | bytes + 2 * 1024 * 1024, |
| 3163 | alloc_target, 0); | 3183 | alloc_target, |
| 3184 | CHUNK_ALLOC_NO_FORCE); | ||
| 3164 | btrfs_end_transaction(trans, root); | 3185 | btrfs_end_transaction(trans, root); |
| 3165 | if (ret < 0) { | 3186 | if (ret < 0) { |
| 3166 | if (ret != -ENOSPC) | 3187 | if (ret != -ENOSPC) |
| @@ -3239,31 +3260,56 @@ static void force_metadata_allocation(struct btrfs_fs_info *info) | |||
| 3239 | rcu_read_lock(); | 3260 | rcu_read_lock(); |
| 3240 | list_for_each_entry_rcu(found, head, list) { | 3261 | list_for_each_entry_rcu(found, head, list) { |
| 3241 | if (found->flags & BTRFS_BLOCK_GROUP_METADATA) | 3262 | if (found->flags & BTRFS_BLOCK_GROUP_METADATA) |
| 3242 | found->force_alloc = 1; | 3263 | found->force_alloc = CHUNK_ALLOC_FORCE; |
| 3243 | } | 3264 | } |
| 3244 | rcu_read_unlock(); | 3265 | rcu_read_unlock(); |
| 3245 | } | 3266 | } |
| 3246 | 3267 | ||
| 3247 | static int should_alloc_chunk(struct btrfs_root *root, | 3268 | static int should_alloc_chunk(struct btrfs_root *root, |
| 3248 | struct btrfs_space_info *sinfo, u64 alloc_bytes) | 3269 | struct btrfs_space_info *sinfo, u64 alloc_bytes, |
| 3270 | int force) | ||
| 3249 | { | 3271 | { |
| 3250 | u64 num_bytes = sinfo->total_bytes - sinfo->bytes_readonly; | 3272 | u64 num_bytes = sinfo->total_bytes - sinfo->bytes_readonly; |
| 3273 | u64 num_allocated = sinfo->bytes_used + sinfo->bytes_reserved; | ||
| 3251 | u64 thresh; | 3274 | u64 thresh; |
| 3252 | 3275 | ||
| 3253 | if (sinfo->bytes_used + sinfo->bytes_reserved + | 3276 | if (force == CHUNK_ALLOC_FORCE) |
| 3254 | alloc_bytes + 256 * 1024 * 1024 < num_bytes) | 3277 | return 1; |
| 3278 | |||
| 3279 | /* | ||
| 3280 | * in limited mode, we want to have some free space up to | ||
| 3281 | * about 1% of the FS size. | ||
| 3282 | */ | ||
| 3283 | if (force == CHUNK_ALLOC_LIMITED) { | ||
| 3284 | thresh = btrfs_super_total_bytes(&root->fs_info->super_copy); | ||
| 3285 | thresh = max_t(u64, 64 * 1024 * 1024, | ||
| 3286 | div_factor_fine(thresh, 1)); | ||
| 3287 | |||
| 3288 | if (num_bytes - num_allocated < thresh) | ||
| 3289 | return 1; | ||
| 3290 | } | ||
| 3291 | |||
| 3292 | /* | ||
| 3293 | * we have two similar checks here, one based on percentage | ||
| 3294 | * and once based on a hard number of 256MB. The idea | ||
| 3295 | * is that if we have a good amount of free | ||
| 3296 | * room, don't allocate a chunk. A good mount is | ||
| 3297 | * less than 80% utilized of the chunks we have allocated, | ||
| 3298 | * or more than 256MB free | ||
| 3299 | */ | ||
| 3300 | if (num_allocated + alloc_bytes + 256 * 1024 * 1024 < num_bytes) | ||
| 3255 | return 0; | 3301 | return 0; |
| 3256 | 3302 | ||
| 3257 | if (sinfo->bytes_used + sinfo->bytes_reserved + | 3303 | if (num_allocated + alloc_bytes < div_factor(num_bytes, 8)) |
| 3258 | alloc_bytes < div_factor(num_bytes, 8)) | ||
| 3259 | return 0; | 3304 | return 0; |
| 3260 | 3305 | ||
| 3261 | thresh = btrfs_super_total_bytes(&root->fs_info->super_copy); | 3306 | thresh = btrfs_super_total_bytes(&root->fs_info->super_copy); |
| 3307 | |||
| 3308 | /* 256MB or 5% of the FS */ | ||
| 3262 | thresh = max_t(u64, 256 * 1024 * 1024, div_factor_fine(thresh, 5)); | 3309 | thresh = max_t(u64, 256 * 1024 * 1024, div_factor_fine(thresh, 5)); |
| 3263 | 3310 | ||
| 3264 | if (num_bytes > thresh && sinfo->bytes_used < div_factor(num_bytes, 3)) | 3311 | if (num_bytes > thresh && sinfo->bytes_used < div_factor(num_bytes, 3)) |
| 3265 | return 0; | 3312 | return 0; |
| 3266 | |||
| 3267 | return 1; | 3313 | return 1; |
| 3268 | } | 3314 | } |
| 3269 | 3315 | ||
| @@ -3273,10 +3319,9 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, | |||
| 3273 | { | 3319 | { |
| 3274 | struct btrfs_space_info *space_info; | 3320 | struct btrfs_space_info *space_info; |
| 3275 | struct btrfs_fs_info *fs_info = extent_root->fs_info; | 3321 | struct btrfs_fs_info *fs_info = extent_root->fs_info; |
| 3322 | int wait_for_alloc = 0; | ||
| 3276 | int ret = 0; | 3323 | int ret = 0; |
| 3277 | 3324 | ||
| 3278 | mutex_lock(&fs_info->chunk_mutex); | ||
| 3279 | |||
| 3280 | flags = btrfs_reduce_alloc_profile(extent_root, flags); | 3325 | flags = btrfs_reduce_alloc_profile(extent_root, flags); |
| 3281 | 3326 | ||
| 3282 | space_info = __find_space_info(extent_root->fs_info, flags); | 3327 | space_info = __find_space_info(extent_root->fs_info, flags); |
| @@ -3287,21 +3332,40 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, | |||
| 3287 | } | 3332 | } |
| 3288 | BUG_ON(!space_info); | 3333 | BUG_ON(!space_info); |
| 3289 | 3334 | ||
| 3335 | again: | ||
| 3290 | spin_lock(&space_info->lock); | 3336 | spin_lock(&space_info->lock); |
| 3291 | if (space_info->force_alloc) | 3337 | if (space_info->force_alloc) |
| 3292 | force = 1; | 3338 | force = space_info->force_alloc; |
| 3293 | if (space_info->full) { | 3339 | if (space_info->full) { |
| 3294 | spin_unlock(&space_info->lock); | 3340 | spin_unlock(&space_info->lock); |
| 3295 | goto out; | 3341 | return 0; |
| 3296 | } | 3342 | } |
| 3297 | 3343 | ||
| 3298 | if (!force && !should_alloc_chunk(extent_root, space_info, | 3344 | if (!should_alloc_chunk(extent_root, space_info, alloc_bytes, force)) { |
| 3299 | alloc_bytes)) { | ||
| 3300 | spin_unlock(&space_info->lock); | 3345 | spin_unlock(&space_info->lock); |
| 3301 | goto out; | 3346 | return 0; |
| 3347 | } else if (space_info->chunk_alloc) { | ||
| 3348 | wait_for_alloc = 1; | ||
| 3349 | } else { | ||
| 3350 | space_info->chunk_alloc = 1; | ||
| 3302 | } | 3351 | } |
| 3352 | |||
| 3303 | spin_unlock(&space_info->lock); | 3353 | spin_unlock(&space_info->lock); |
| 3304 | 3354 | ||
| 3355 | mutex_lock(&fs_info->chunk_mutex); | ||
| 3356 | |||
| 3357 | /* | ||
| 3358 | * The chunk_mutex is held throughout the entirety of a chunk | ||
| 3359 | * allocation, so once we've acquired the chunk_mutex we know that the | ||
| 3360 | * other guy is done and we need to recheck and see if we should | ||
| 3361 | * allocate. | ||
| 3362 | */ | ||
| 3363 | if (wait_for_alloc) { | ||
| 3364 | mutex_unlock(&fs_info->chunk_mutex); | ||
| 3365 | wait_for_alloc = 0; | ||
| 3366 | goto again; | ||
| 3367 | } | ||
| 3368 | |||
| 3305 | /* | 3369 | /* |
| 3306 | * If we have mixed data/metadata chunks we want to make sure we keep | 3370 | * If we have mixed data/metadata chunks we want to make sure we keep |
| 3307 | * allocating mixed chunks instead of individual chunks. | 3371 | * allocating mixed chunks instead of individual chunks. |
| @@ -3327,9 +3391,10 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, | |||
| 3327 | space_info->full = 1; | 3391 | space_info->full = 1; |
| 3328 | else | 3392 | else |
| 3329 | ret = 1; | 3393 | ret = 1; |
| 3330 | space_info->force_alloc = 0; | 3394 | |
| 3395 | space_info->force_alloc = CHUNK_ALLOC_NO_FORCE; | ||
| 3396 | space_info->chunk_alloc = 0; | ||
| 3331 | spin_unlock(&space_info->lock); | 3397 | spin_unlock(&space_info->lock); |
| 3332 | out: | ||
| 3333 | mutex_unlock(&extent_root->fs_info->chunk_mutex); | 3398 | mutex_unlock(&extent_root->fs_info->chunk_mutex); |
| 3334 | return ret; | 3399 | return ret; |
| 3335 | } | 3400 | } |
| @@ -5303,11 +5368,13 @@ loop: | |||
| 5303 | 5368 | ||
| 5304 | if (allowed_chunk_alloc) { | 5369 | if (allowed_chunk_alloc) { |
| 5305 | ret = do_chunk_alloc(trans, root, num_bytes + | 5370 | ret = do_chunk_alloc(trans, root, num_bytes + |
| 5306 | 2 * 1024 * 1024, data, 1); | 5371 | 2 * 1024 * 1024, data, |
| 5372 | CHUNK_ALLOC_LIMITED); | ||
| 5307 | allowed_chunk_alloc = 0; | 5373 | allowed_chunk_alloc = 0; |
| 5308 | done_chunk_alloc = 1; | 5374 | done_chunk_alloc = 1; |
| 5309 | } else if (!done_chunk_alloc) { | 5375 | } else if (!done_chunk_alloc && |
| 5310 | space_info->force_alloc = 1; | 5376 | space_info->force_alloc == CHUNK_ALLOC_NO_FORCE) { |
| 5377 | space_info->force_alloc = CHUNK_ALLOC_LIMITED; | ||
| 5311 | } | 5378 | } |
| 5312 | 5379 | ||
| 5313 | if (loop < LOOP_NO_EMPTY_SIZE) { | 5380 | if (loop < LOOP_NO_EMPTY_SIZE) { |
| @@ -5393,7 +5460,8 @@ again: | |||
| 5393 | */ | 5460 | */ |
| 5394 | if (empty_size || root->ref_cows) | 5461 | if (empty_size || root->ref_cows) |
| 5395 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | 5462 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, |
| 5396 | num_bytes + 2 * 1024 * 1024, data, 0); | 5463 | num_bytes + 2 * 1024 * 1024, data, |
| 5464 | CHUNK_ALLOC_NO_FORCE); | ||
| 5397 | 5465 | ||
| 5398 | WARN_ON(num_bytes < root->sectorsize); | 5466 | WARN_ON(num_bytes < root->sectorsize); |
| 5399 | ret = find_free_extent(trans, root, num_bytes, empty_size, | 5467 | ret = find_free_extent(trans, root, num_bytes, empty_size, |
| @@ -5405,7 +5473,7 @@ again: | |||
| 5405 | num_bytes = num_bytes & ~(root->sectorsize - 1); | 5473 | num_bytes = num_bytes & ~(root->sectorsize - 1); |
| 5406 | num_bytes = max(num_bytes, min_alloc_size); | 5474 | num_bytes = max(num_bytes, min_alloc_size); |
| 5407 | do_chunk_alloc(trans, root->fs_info->extent_root, | 5475 | do_chunk_alloc(trans, root->fs_info->extent_root, |
| 5408 | num_bytes, data, 1); | 5476 | num_bytes, data, CHUNK_ALLOC_FORCE); |
| 5409 | goto again; | 5477 | goto again; |
| 5410 | } | 5478 | } |
| 5411 | if (ret == -ENOSPC && btrfs_test_opt(root, ENOSPC_DEBUG)) { | 5479 | if (ret == -ENOSPC && btrfs_test_opt(root, ENOSPC_DEBUG)) { |
| @@ -8109,13 +8177,15 @@ int btrfs_set_block_group_ro(struct btrfs_root *root, | |||
| 8109 | 8177 | ||
| 8110 | alloc_flags = update_block_group_flags(root, cache->flags); | 8178 | alloc_flags = update_block_group_flags(root, cache->flags); |
| 8111 | if (alloc_flags != cache->flags) | 8179 | if (alloc_flags != cache->flags) |
| 8112 | do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, 1); | 8180 | do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, |
| 8181 | CHUNK_ALLOC_FORCE); | ||
| 8113 | 8182 | ||
| 8114 | ret = set_block_group_ro(cache); | 8183 | ret = set_block_group_ro(cache); |
| 8115 | if (!ret) | 8184 | if (!ret) |
| 8116 | goto out; | 8185 | goto out; |
| 8117 | alloc_flags = get_alloc_profile(root, cache->space_info->flags); | 8186 | alloc_flags = get_alloc_profile(root, cache->space_info->flags); |
| 8118 | ret = do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, 1); | 8187 | ret = do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, |
| 8188 | CHUNK_ALLOC_FORCE); | ||
| 8119 | if (ret < 0) | 8189 | if (ret < 0) |
| 8120 | goto out; | 8190 | goto out; |
| 8121 | ret = set_block_group_ro(cache); | 8191 | ret = set_block_group_ro(cache); |
| @@ -8128,7 +8198,8 @@ int btrfs_force_chunk_alloc(struct btrfs_trans_handle *trans, | |||
| 8128 | struct btrfs_root *root, u64 type) | 8198 | struct btrfs_root *root, u64 type) |
| 8129 | { | 8199 | { |
| 8130 | u64 alloc_flags = get_alloc_profile(root, type); | 8200 | u64 alloc_flags = get_alloc_profile(root, type); |
| 8131 | return do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, 1); | 8201 | return do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, |
| 8202 | CHUNK_ALLOC_FORCE); | ||
| 8132 | } | 8203 | } |
| 8133 | 8204 | ||
| 8134 | /* | 8205 | /* |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 20ddb28602a8..315138605088 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
| @@ -690,6 +690,15 @@ static void cache_state(struct extent_state *state, | |||
| 690 | } | 690 | } |
| 691 | } | 691 | } |
| 692 | 692 | ||
| 693 | static void uncache_state(struct extent_state **cached_ptr) | ||
| 694 | { | ||
| 695 | if (cached_ptr && (*cached_ptr)) { | ||
| 696 | struct extent_state *state = *cached_ptr; | ||
| 697 | *cached_ptr = NULL; | ||
| 698 | free_extent_state(state); | ||
| 699 | } | ||
| 700 | } | ||
| 701 | |||
| 693 | /* | 702 | /* |
| 694 | * set some bits on a range in the tree. This may require allocations or | 703 | * set some bits on a range in the tree. This may require allocations or |
| 695 | * sleeping, so the gfp mask is used to indicate what is allowed. | 704 | * sleeping, so the gfp mask is used to indicate what is allowed. |
| @@ -940,10 +949,10 @@ static int clear_extent_new(struct extent_io_tree *tree, u64 start, u64 end, | |||
| 940 | } | 949 | } |
| 941 | 950 | ||
| 942 | int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, | 951 | int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, |
| 943 | gfp_t mask) | 952 | struct extent_state **cached_state, gfp_t mask) |
| 944 | { | 953 | { |
| 945 | return set_extent_bit(tree, start, end, EXTENT_UPTODATE, 0, NULL, | 954 | return set_extent_bit(tree, start, end, EXTENT_UPTODATE, 0, |
| 946 | NULL, mask); | 955 | NULL, cached_state, mask); |
| 947 | } | 956 | } |
| 948 | 957 | ||
| 949 | static int clear_extent_uptodate(struct extent_io_tree *tree, u64 start, | 958 | static int clear_extent_uptodate(struct extent_io_tree *tree, u64 start, |
| @@ -1012,8 +1021,7 @@ int unlock_extent_cached(struct extent_io_tree *tree, u64 start, u64 end, | |||
| 1012 | mask); | 1021 | mask); |
| 1013 | } | 1022 | } |
| 1014 | 1023 | ||
| 1015 | int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end, | 1024 | int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask) |
| 1016 | gfp_t mask) | ||
| 1017 | { | 1025 | { |
| 1018 | return clear_extent_bit(tree, start, end, EXTENT_LOCKED, 1, 0, NULL, | 1026 | return clear_extent_bit(tree, start, end, EXTENT_LOCKED, 1, 0, NULL, |
| 1019 | mask); | 1027 | mask); |
| @@ -1735,6 +1743,9 @@ static void end_bio_extent_readpage(struct bio *bio, int err) | |||
| 1735 | 1743 | ||
| 1736 | do { | 1744 | do { |
| 1737 | struct page *page = bvec->bv_page; | 1745 | struct page *page = bvec->bv_page; |
| 1746 | struct extent_state *cached = NULL; | ||
| 1747 | struct extent_state *state; | ||
| 1748 | |||
| 1738 | tree = &BTRFS_I(page->mapping->host)->io_tree; | 1749 | tree = &BTRFS_I(page->mapping->host)->io_tree; |
| 1739 | 1750 | ||
| 1740 | start = ((u64)page->index << PAGE_CACHE_SHIFT) + | 1751 | start = ((u64)page->index << PAGE_CACHE_SHIFT) + |
| @@ -1749,9 +1760,20 @@ static void end_bio_extent_readpage(struct bio *bio, int err) | |||
| 1749 | if (++bvec <= bvec_end) | 1760 | if (++bvec <= bvec_end) |
| 1750 | prefetchw(&bvec->bv_page->flags); | 1761 | prefetchw(&bvec->bv_page->flags); |
| 1751 | 1762 | ||
| 1763 | spin_lock(&tree->lock); | ||
| 1764 | state = find_first_extent_bit_state(tree, start, EXTENT_LOCKED); | ||
| 1765 | if (state && state->start == start) { | ||
| 1766 | /* | ||
| 1767 | * take a reference on the state, unlock will drop | ||
| 1768 | * the ref | ||
| 1769 | */ | ||
| 1770 | cache_state(state, &cached); | ||
| 1771 | } | ||
| 1772 | spin_unlock(&tree->lock); | ||
| 1773 | |||
| 1752 | if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) { | 1774 | if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) { |
| 1753 | ret = tree->ops->readpage_end_io_hook(page, start, end, | 1775 | ret = tree->ops->readpage_end_io_hook(page, start, end, |
| 1754 | NULL); | 1776 | state); |
| 1755 | if (ret) | 1777 | if (ret) |
| 1756 | uptodate = 0; | 1778 | uptodate = 0; |
| 1757 | } | 1779 | } |
| @@ -1764,15 +1786,16 @@ static void end_bio_extent_readpage(struct bio *bio, int err) | |||
| 1764 | test_bit(BIO_UPTODATE, &bio->bi_flags); | 1786 | test_bit(BIO_UPTODATE, &bio->bi_flags); |
| 1765 | if (err) | 1787 | if (err) |
| 1766 | uptodate = 0; | 1788 | uptodate = 0; |
| 1789 | uncache_state(&cached); | ||
| 1767 | continue; | 1790 | continue; |
| 1768 | } | 1791 | } |
| 1769 | } | 1792 | } |
| 1770 | 1793 | ||
| 1771 | if (uptodate) { | 1794 | if (uptodate) { |
| 1772 | set_extent_uptodate(tree, start, end, | 1795 | set_extent_uptodate(tree, start, end, &cached, |
| 1773 | GFP_ATOMIC); | 1796 | GFP_ATOMIC); |
| 1774 | } | 1797 | } |
| 1775 | unlock_extent(tree, start, end, GFP_ATOMIC); | 1798 | unlock_extent_cached(tree, start, end, &cached, GFP_ATOMIC); |
| 1776 | 1799 | ||
| 1777 | if (whole_page) { | 1800 | if (whole_page) { |
| 1778 | if (uptodate) { | 1801 | if (uptodate) { |
| @@ -1811,6 +1834,7 @@ static void end_bio_extent_preparewrite(struct bio *bio, int err) | |||
| 1811 | 1834 | ||
| 1812 | do { | 1835 | do { |
| 1813 | struct page *page = bvec->bv_page; | 1836 | struct page *page = bvec->bv_page; |
| 1837 | struct extent_state *cached = NULL; | ||
| 1814 | tree = &BTRFS_I(page->mapping->host)->io_tree; | 1838 | tree = &BTRFS_I(page->mapping->host)->io_tree; |
| 1815 | 1839 | ||
| 1816 | start = ((u64)page->index << PAGE_CACHE_SHIFT) + | 1840 | start = ((u64)page->index << PAGE_CACHE_SHIFT) + |
| @@ -1821,13 +1845,14 @@ static void end_bio_extent_preparewrite(struct bio *bio, int err) | |||
| 1821 | prefetchw(&bvec->bv_page->flags); | 1845 | prefetchw(&bvec->bv_page->flags); |
| 1822 | 1846 | ||
| 1823 | if (uptodate) { | 1847 | if (uptodate) { |
| 1824 | set_extent_uptodate(tree, start, end, GFP_ATOMIC); | 1848 | set_extent_uptodate(tree, start, end, &cached, |
| 1849 | GFP_ATOMIC); | ||
| 1825 | } else { | 1850 | } else { |
| 1826 | ClearPageUptodate(page); | 1851 | ClearPageUptodate(page); |
| 1827 | SetPageError(page); | 1852 | SetPageError(page); |
| 1828 | } | 1853 | } |
| 1829 | 1854 | ||
| 1830 | unlock_extent(tree, start, end, GFP_ATOMIC); | 1855 | unlock_extent_cached(tree, start, end, &cached, GFP_ATOMIC); |
| 1831 | 1856 | ||
| 1832 | } while (bvec >= bio->bi_io_vec); | 1857 | } while (bvec >= bio->bi_io_vec); |
| 1833 | 1858 | ||
| @@ -2016,14 +2041,17 @@ static int __extent_read_full_page(struct extent_io_tree *tree, | |||
| 2016 | while (cur <= end) { | 2041 | while (cur <= end) { |
| 2017 | if (cur >= last_byte) { | 2042 | if (cur >= last_byte) { |
| 2018 | char *userpage; | 2043 | char *userpage; |
| 2044 | struct extent_state *cached = NULL; | ||
| 2045 | |||
| 2019 | iosize = PAGE_CACHE_SIZE - page_offset; | 2046 | iosize = PAGE_CACHE_SIZE - page_offset; |
| 2020 | userpage = kmap_atomic(page, KM_USER0); | 2047 | userpage = kmap_atomic(page, KM_USER0); |
| 2021 | memset(userpage + page_offset, 0, iosize); | 2048 | memset(userpage + page_offset, 0, iosize); |
| 2022 | flush_dcache_page(page); | 2049 | flush_dcache_page(page); |
| 2023 | kunmap_atomic(userpage, KM_USER0); | 2050 | kunmap_atomic(userpage, KM_USER0); |
| 2024 | set_extent_uptodate(tree, cur, cur + iosize - 1, | 2051 | set_extent_uptodate(tree, cur, cur + iosize - 1, |
| 2025 | GFP_NOFS); | 2052 | &cached, GFP_NOFS); |
| 2026 | unlock_extent(tree, cur, cur + iosize - 1, GFP_NOFS); | 2053 | unlock_extent_cached(tree, cur, cur + iosize - 1, |
| 2054 | &cached, GFP_NOFS); | ||
| 2027 | break; | 2055 | break; |
| 2028 | } | 2056 | } |
| 2029 | em = get_extent(inode, page, page_offset, cur, | 2057 | em = get_extent(inode, page, page_offset, cur, |
| @@ -2063,14 +2091,17 @@ static int __extent_read_full_page(struct extent_io_tree *tree, | |||
| 2063 | /* we've found a hole, just zero and go on */ | 2091 | /* we've found a hole, just zero and go on */ |
| 2064 | if (block_start == EXTENT_MAP_HOLE) { | 2092 | if (block_start == EXTENT_MAP_HOLE) { |
| 2065 | char *userpage; | 2093 | char *userpage; |
| 2094 | struct extent_state *cached = NULL; | ||
| 2095 | |||
| 2066 | userpage = kmap_atomic(page, KM_USER0); | 2096 | userpage = kmap_atomic(page, KM_USER0); |
| 2067 | memset(userpage + page_offset, 0, iosize); | 2097 | memset(userpage + page_offset, 0, iosize); |
| 2068 | flush_dcache_page(page); | 2098 | flush_dcache_page(page); |
| 2069 | kunmap_atomic(userpage, KM_USER0); | 2099 | kunmap_atomic(userpage, KM_USER0); |
| 2070 | 2100 | ||
| 2071 | set_extent_uptodate(tree, cur, cur + iosize - 1, | 2101 | set_extent_uptodate(tree, cur, cur + iosize - 1, |
| 2072 | GFP_NOFS); | 2102 | &cached, GFP_NOFS); |
| 2073 | unlock_extent(tree, cur, cur + iosize - 1, GFP_NOFS); | 2103 | unlock_extent_cached(tree, cur, cur + iosize - 1, |
| 2104 | &cached, GFP_NOFS); | ||
| 2074 | cur = cur + iosize; | 2105 | cur = cur + iosize; |
| 2075 | page_offset += iosize; | 2106 | page_offset += iosize; |
| 2076 | continue; | 2107 | continue; |
| @@ -2789,9 +2820,12 @@ int extent_prepare_write(struct extent_io_tree *tree, | |||
| 2789 | iocount++; | 2820 | iocount++; |
| 2790 | block_start = block_start + iosize; | 2821 | block_start = block_start + iosize; |
| 2791 | } else { | 2822 | } else { |
| 2792 | set_extent_uptodate(tree, block_start, cur_end, | 2823 | struct extent_state *cached = NULL; |
| 2824 | |||
| 2825 | set_extent_uptodate(tree, block_start, cur_end, &cached, | ||
| 2793 | GFP_NOFS); | 2826 | GFP_NOFS); |
| 2794 | unlock_extent(tree, block_start, cur_end, GFP_NOFS); | 2827 | unlock_extent_cached(tree, block_start, cur_end, |
| 2828 | &cached, GFP_NOFS); | ||
| 2795 | block_start = cur_end + 1; | 2829 | block_start = cur_end + 1; |
| 2796 | } | 2830 | } |
| 2797 | page_offset = block_start & (PAGE_CACHE_SIZE - 1); | 2831 | page_offset = block_start & (PAGE_CACHE_SIZE - 1); |
| @@ -3457,7 +3491,7 @@ int set_extent_buffer_uptodate(struct extent_io_tree *tree, | |||
| 3457 | num_pages = num_extent_pages(eb->start, eb->len); | 3491 | num_pages = num_extent_pages(eb->start, eb->len); |
| 3458 | 3492 | ||
| 3459 | set_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, | 3493 | set_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, |
| 3460 | GFP_NOFS); | 3494 | NULL, GFP_NOFS); |
| 3461 | for (i = 0; i < num_pages; i++) { | 3495 | for (i = 0; i < num_pages; i++) { |
| 3462 | page = extent_buffer_page(eb, i); | 3496 | page = extent_buffer_page(eb, i); |
| 3463 | if ((i == 0 && (eb->start & (PAGE_CACHE_SIZE - 1))) || | 3497 | if ((i == 0 && (eb->start & (PAGE_CACHE_SIZE - 1))) || |
| @@ -3885,6 +3919,12 @@ static void move_pages(struct page *dst_page, struct page *src_page, | |||
| 3885 | kunmap_atomic(dst_kaddr, KM_USER0); | 3919 | kunmap_atomic(dst_kaddr, KM_USER0); |
| 3886 | } | 3920 | } |
| 3887 | 3921 | ||
| 3922 | static inline bool areas_overlap(unsigned long src, unsigned long dst, unsigned long len) | ||
| 3923 | { | ||
| 3924 | unsigned long distance = (src > dst) ? src - dst : dst - src; | ||
| 3925 | return distance < len; | ||
| 3926 | } | ||
| 3927 | |||
| 3888 | static void copy_pages(struct page *dst_page, struct page *src_page, | 3928 | static void copy_pages(struct page *dst_page, struct page *src_page, |
| 3889 | unsigned long dst_off, unsigned long src_off, | 3929 | unsigned long dst_off, unsigned long src_off, |
| 3890 | unsigned long len) | 3930 | unsigned long len) |
| @@ -3892,10 +3932,12 @@ static void copy_pages(struct page *dst_page, struct page *src_page, | |||
| 3892 | char *dst_kaddr = kmap_atomic(dst_page, KM_USER0); | 3932 | char *dst_kaddr = kmap_atomic(dst_page, KM_USER0); |
| 3893 | char *src_kaddr; | 3933 | char *src_kaddr; |
| 3894 | 3934 | ||
| 3895 | if (dst_page != src_page) | 3935 | if (dst_page != src_page) { |
| 3896 | src_kaddr = kmap_atomic(src_page, KM_USER1); | 3936 | src_kaddr = kmap_atomic(src_page, KM_USER1); |
| 3897 | else | 3937 | } else { |
| 3898 | src_kaddr = dst_kaddr; | 3938 | src_kaddr = dst_kaddr; |
| 3939 | BUG_ON(areas_overlap(src_off, dst_off, len)); | ||
| 3940 | } | ||
| 3899 | 3941 | ||
| 3900 | memcpy(dst_kaddr + dst_off, src_kaddr + src_off, len); | 3942 | memcpy(dst_kaddr + dst_off, src_kaddr + src_off, len); |
| 3901 | kunmap_atomic(dst_kaddr, KM_USER0); | 3943 | kunmap_atomic(dst_kaddr, KM_USER0); |
| @@ -3970,7 +4012,7 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, | |||
| 3970 | "len %lu len %lu\n", dst_offset, len, dst->len); | 4012 | "len %lu len %lu\n", dst_offset, len, dst->len); |
| 3971 | BUG_ON(1); | 4013 | BUG_ON(1); |
| 3972 | } | 4014 | } |
| 3973 | if (dst_offset < src_offset) { | 4015 | if (!areas_overlap(src_offset, dst_offset, len)) { |
| 3974 | memcpy_extent_buffer(dst, dst_offset, src_offset, len); | 4016 | memcpy_extent_buffer(dst, dst_offset, src_offset, len); |
| 3975 | return; | 4017 | return; |
| 3976 | } | 4018 | } |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index f62c5442835d..af2d7179c372 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
| @@ -208,7 +208,7 @@ int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, | |||
| 208 | int bits, int exclusive_bits, u64 *failed_start, | 208 | int bits, int exclusive_bits, u64 *failed_start, |
| 209 | struct extent_state **cached_state, gfp_t mask); | 209 | struct extent_state **cached_state, gfp_t mask); |
| 210 | int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, | 210 | int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, |
| 211 | gfp_t mask); | 211 | struct extent_state **cached_state, gfp_t mask); |
| 212 | int set_extent_new(struct extent_io_tree *tree, u64 start, u64 end, | 212 | int set_extent_new(struct extent_io_tree *tree, u64 start, u64 end, |
| 213 | gfp_t mask); | 213 | gfp_t mask); |
| 214 | int set_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, | 214 | int set_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index e621ea54a3fd..75899a01dded 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -104,7 +104,7 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, | |||
| 104 | /* | 104 | /* |
| 105 | * unlocks pages after btrfs_file_write is done with them | 105 | * unlocks pages after btrfs_file_write is done with them |
| 106 | */ | 106 | */ |
| 107 | static noinline void btrfs_drop_pages(struct page **pages, size_t num_pages) | 107 | void btrfs_drop_pages(struct page **pages, size_t num_pages) |
| 108 | { | 108 | { |
| 109 | size_t i; | 109 | size_t i; |
| 110 | for (i = 0; i < num_pages; i++) { | 110 | for (i = 0; i < num_pages; i++) { |
| @@ -127,16 +127,13 @@ static noinline void btrfs_drop_pages(struct page **pages, size_t num_pages) | |||
| 127 | * this also makes the decision about creating an inline extent vs | 127 | * this also makes the decision about creating an inline extent vs |
| 128 | * doing real data extents, marking pages dirty and delalloc as required. | 128 | * doing real data extents, marking pages dirty and delalloc as required. |
| 129 | */ | 129 | */ |
| 130 | static noinline int dirty_and_release_pages(struct btrfs_root *root, | 130 | int btrfs_dirty_pages(struct btrfs_root *root, struct inode *inode, |
| 131 | struct file *file, | 131 | struct page **pages, size_t num_pages, |
| 132 | struct page **pages, | 132 | loff_t pos, size_t write_bytes, |
| 133 | size_t num_pages, | 133 | struct extent_state **cached) |
| 134 | loff_t pos, | ||
| 135 | size_t write_bytes) | ||
| 136 | { | 134 | { |
| 137 | int err = 0; | 135 | int err = 0; |
| 138 | int i; | 136 | int i; |
| 139 | struct inode *inode = fdentry(file)->d_inode; | ||
| 140 | u64 num_bytes; | 137 | u64 num_bytes; |
| 141 | u64 start_pos; | 138 | u64 start_pos; |
| 142 | u64 end_of_last_block; | 139 | u64 end_of_last_block; |
| @@ -149,7 +146,7 @@ static noinline int dirty_and_release_pages(struct btrfs_root *root, | |||
| 149 | 146 | ||
| 150 | end_of_last_block = start_pos + num_bytes - 1; | 147 | end_of_last_block = start_pos + num_bytes - 1; |
| 151 | err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, | 148 | err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, |
| 152 | NULL); | 149 | cached); |
| 153 | if (err) | 150 | if (err) |
| 154 | return err; | 151 | return err; |
| 155 | 152 | ||
| @@ -992,9 +989,9 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, | |||
| 992 | } | 989 | } |
| 993 | 990 | ||
| 994 | if (copied > 0) { | 991 | if (copied > 0) { |
| 995 | ret = dirty_and_release_pages(root, file, pages, | 992 | ret = btrfs_dirty_pages(root, inode, pages, |
| 996 | dirty_pages, pos, | 993 | dirty_pages, pos, copied, |
| 997 | copied); | 994 | NULL); |
| 998 | if (ret) { | 995 | if (ret) { |
| 999 | btrfs_delalloc_release_space(inode, | 996 | btrfs_delalloc_release_space(inode, |
| 1000 | dirty_pages << PAGE_CACHE_SHIFT); | 997 | dirty_pages << PAGE_CACHE_SHIFT); |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index f561c953205b..11d2e9cea09e 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
| @@ -508,6 +508,7 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 508 | struct inode *inode; | 508 | struct inode *inode; |
| 509 | struct rb_node *node; | 509 | struct rb_node *node; |
| 510 | struct list_head *pos, *n; | 510 | struct list_head *pos, *n; |
| 511 | struct page **pages; | ||
| 511 | struct page *page; | 512 | struct page *page; |
| 512 | struct extent_state *cached_state = NULL; | 513 | struct extent_state *cached_state = NULL; |
| 513 | struct btrfs_free_cluster *cluster = NULL; | 514 | struct btrfs_free_cluster *cluster = NULL; |
| @@ -517,13 +518,13 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 517 | u64 start, end, len; | 518 | u64 start, end, len; |
| 518 | u64 bytes = 0; | 519 | u64 bytes = 0; |
| 519 | u32 *crc, *checksums; | 520 | u32 *crc, *checksums; |
| 520 | pgoff_t index = 0, last_index = 0; | ||
| 521 | unsigned long first_page_offset; | 521 | unsigned long first_page_offset; |
| 522 | int num_checksums; | 522 | int index = 0, num_pages = 0; |
| 523 | int entries = 0; | 523 | int entries = 0; |
| 524 | int bitmaps = 0; | 524 | int bitmaps = 0; |
| 525 | int ret = 0; | 525 | int ret = 0; |
| 526 | bool next_page = false; | 526 | bool next_page = false; |
| 527 | bool out_of_space = false; | ||
| 527 | 528 | ||
| 528 | root = root->fs_info->tree_root; | 529 | root = root->fs_info->tree_root; |
| 529 | 530 | ||
| @@ -551,24 +552,31 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 551 | return 0; | 552 | return 0; |
| 552 | } | 553 | } |
| 553 | 554 | ||
| 554 | last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT; | 555 | num_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> |
| 556 | PAGE_CACHE_SHIFT; | ||
| 555 | filemap_write_and_wait(inode->i_mapping); | 557 | filemap_write_and_wait(inode->i_mapping); |
| 556 | btrfs_wait_ordered_range(inode, inode->i_size & | 558 | btrfs_wait_ordered_range(inode, inode->i_size & |
| 557 | ~(root->sectorsize - 1), (u64)-1); | 559 | ~(root->sectorsize - 1), (u64)-1); |
| 558 | 560 | ||
| 559 | /* We need a checksum per page. */ | 561 | /* We need a checksum per page. */ |
| 560 | num_checksums = i_size_read(inode) / PAGE_CACHE_SIZE; | 562 | crc = checksums = kzalloc(sizeof(u32) * num_pages, GFP_NOFS); |
| 561 | crc = checksums = kzalloc(sizeof(u32) * num_checksums, GFP_NOFS); | ||
| 562 | if (!crc) { | 563 | if (!crc) { |
| 563 | iput(inode); | 564 | iput(inode); |
| 564 | return 0; | 565 | return 0; |
| 565 | } | 566 | } |
| 566 | 567 | ||
| 568 | pages = kzalloc(sizeof(struct page *) * num_pages, GFP_NOFS); | ||
| 569 | if (!pages) { | ||
| 570 | kfree(crc); | ||
| 571 | iput(inode); | ||
| 572 | return 0; | ||
| 573 | } | ||
| 574 | |||
| 567 | /* Since the first page has all of our checksums and our generation we | 575 | /* Since the first page has all of our checksums and our generation we |
| 568 | * need to calculate the offset into the page that we can start writing | 576 | * need to calculate the offset into the page that we can start writing |
| 569 | * our entries. | 577 | * our entries. |
| 570 | */ | 578 | */ |
| 571 | first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64); | 579 | first_page_offset = (sizeof(u32) * num_pages) + sizeof(u64); |
| 572 | 580 | ||
| 573 | /* Get the cluster for this block_group if it exists */ | 581 | /* Get the cluster for this block_group if it exists */ |
| 574 | if (!list_empty(&block_group->cluster_list)) | 582 | if (!list_empty(&block_group->cluster_list)) |
| @@ -590,20 +598,18 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 590 | * after find_get_page at this point. Just putting this here so people | 598 | * after find_get_page at this point. Just putting this here so people |
| 591 | * know and don't freak out. | 599 | * know and don't freak out. |
| 592 | */ | 600 | */ |
| 593 | while (index <= last_index) { | 601 | while (index < num_pages) { |
| 594 | page = grab_cache_page(inode->i_mapping, index); | 602 | page = grab_cache_page(inode->i_mapping, index); |
| 595 | if (!page) { | 603 | if (!page) { |
| 596 | pgoff_t i = 0; | 604 | int i; |
| 597 | 605 | ||
| 598 | while (i < index) { | 606 | for (i = 0; i < num_pages; i++) { |
| 599 | page = find_get_page(inode->i_mapping, i); | 607 | unlock_page(pages[i]); |
| 600 | unlock_page(page); | 608 | page_cache_release(pages[i]); |
| 601 | page_cache_release(page); | ||
| 602 | page_cache_release(page); | ||
| 603 | i++; | ||
| 604 | } | 609 | } |
| 605 | goto out_free; | 610 | goto out_free; |
| 606 | } | 611 | } |
| 612 | pages[index] = page; | ||
| 607 | index++; | 613 | index++; |
| 608 | } | 614 | } |
| 609 | 615 | ||
| @@ -631,7 +637,12 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 631 | offset = start_offset; | 637 | offset = start_offset; |
| 632 | } | 638 | } |
| 633 | 639 | ||
| 634 | page = find_get_page(inode->i_mapping, index); | 640 | if (index >= num_pages) { |
| 641 | out_of_space = true; | ||
| 642 | break; | ||
| 643 | } | ||
| 644 | |||
| 645 | page = pages[index]; | ||
| 635 | 646 | ||
| 636 | addr = kmap(page); | 647 | addr = kmap(page); |
| 637 | entry = addr + start_offset; | 648 | entry = addr + start_offset; |
| @@ -708,23 +719,6 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 708 | 719 | ||
| 709 | bytes += PAGE_CACHE_SIZE; | 720 | bytes += PAGE_CACHE_SIZE; |
| 710 | 721 | ||
| 711 | ClearPageChecked(page); | ||
| 712 | set_page_extent_mapped(page); | ||
| 713 | SetPageUptodate(page); | ||
| 714 | set_page_dirty(page); | ||
| 715 | |||
| 716 | /* | ||
| 717 | * We need to release our reference we got for grab_cache_page, | ||
| 718 | * except for the first page which will hold our checksums, we | ||
| 719 | * do that below. | ||
| 720 | */ | ||
| 721 | if (index != 0) { | ||
| 722 | unlock_page(page); | ||
| 723 | page_cache_release(page); | ||
| 724 | } | ||
| 725 | |||
| 726 | page_cache_release(page); | ||
| 727 | |||
| 728 | index++; | 722 | index++; |
| 729 | } while (node || next_page); | 723 | } while (node || next_page); |
| 730 | 724 | ||
| @@ -734,7 +728,11 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 734 | struct btrfs_free_space *entry = | 728 | struct btrfs_free_space *entry = |
| 735 | list_entry(pos, struct btrfs_free_space, list); | 729 | list_entry(pos, struct btrfs_free_space, list); |
| 736 | 730 | ||
| 737 | page = find_get_page(inode->i_mapping, index); | 731 | if (index >= num_pages) { |
| 732 | out_of_space = true; | ||
| 733 | break; | ||
| 734 | } | ||
| 735 | page = pages[index]; | ||
| 738 | 736 | ||
| 739 | addr = kmap(page); | 737 | addr = kmap(page); |
| 740 | memcpy(addr, entry->bitmap, PAGE_CACHE_SIZE); | 738 | memcpy(addr, entry->bitmap, PAGE_CACHE_SIZE); |
| @@ -745,64 +743,58 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 745 | crc++; | 743 | crc++; |
| 746 | bytes += PAGE_CACHE_SIZE; | 744 | bytes += PAGE_CACHE_SIZE; |
| 747 | 745 | ||
| 748 | ClearPageChecked(page); | ||
| 749 | set_page_extent_mapped(page); | ||
| 750 | SetPageUptodate(page); | ||
| 751 | set_page_dirty(page); | ||
| 752 | unlock_page(page); | ||
| 753 | page_cache_release(page); | ||
| 754 | page_cache_release(page); | ||
| 755 | list_del_init(&entry->list); | 746 | list_del_init(&entry->list); |
| 756 | index++; | 747 | index++; |
| 757 | } | 748 | } |
| 758 | 749 | ||
| 750 | if (out_of_space) { | ||
| 751 | btrfs_drop_pages(pages, num_pages); | ||
| 752 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, | ||
| 753 | i_size_read(inode) - 1, &cached_state, | ||
| 754 | GFP_NOFS); | ||
| 755 | ret = 0; | ||
| 756 | goto out_free; | ||
| 757 | } | ||
| 758 | |||
| 759 | /* Zero out the rest of the pages just to make sure */ | 759 | /* Zero out the rest of the pages just to make sure */ |
| 760 | while (index <= last_index) { | 760 | while (index < num_pages) { |
| 761 | void *addr; | 761 | void *addr; |
| 762 | 762 | ||
| 763 | page = find_get_page(inode->i_mapping, index); | 763 | page = pages[index]; |
| 764 | |||
| 765 | addr = kmap(page); | 764 | addr = kmap(page); |
| 766 | memset(addr, 0, PAGE_CACHE_SIZE); | 765 | memset(addr, 0, PAGE_CACHE_SIZE); |
| 767 | kunmap(page); | 766 | kunmap(page); |
| 768 | ClearPageChecked(page); | ||
| 769 | set_page_extent_mapped(page); | ||
| 770 | SetPageUptodate(page); | ||
| 771 | set_page_dirty(page); | ||
| 772 | unlock_page(page); | ||
| 773 | page_cache_release(page); | ||
| 774 | page_cache_release(page); | ||
| 775 | bytes += PAGE_CACHE_SIZE; | 767 | bytes += PAGE_CACHE_SIZE; |
| 776 | index++; | 768 | index++; |
| 777 | } | 769 | } |
| 778 | 770 | ||
| 779 | btrfs_set_extent_delalloc(inode, 0, bytes - 1, &cached_state); | ||
| 780 | |||
| 781 | /* Write the checksums and trans id to the first page */ | 771 | /* Write the checksums and trans id to the first page */ |
| 782 | { | 772 | { |
| 783 | void *addr; | 773 | void *addr; |
| 784 | u64 *gen; | 774 | u64 *gen; |
| 785 | 775 | ||
| 786 | page = find_get_page(inode->i_mapping, 0); | 776 | page = pages[0]; |
| 787 | 777 | ||
| 788 | addr = kmap(page); | 778 | addr = kmap(page); |
| 789 | memcpy(addr, checksums, sizeof(u32) * num_checksums); | 779 | memcpy(addr, checksums, sizeof(u32) * num_pages); |
| 790 | gen = addr + (sizeof(u32) * num_checksums); | 780 | gen = addr + (sizeof(u32) * num_pages); |
| 791 | *gen = trans->transid; | 781 | *gen = trans->transid; |
| 792 | kunmap(page); | 782 | kunmap(page); |
| 793 | ClearPageChecked(page); | ||
| 794 | set_page_extent_mapped(page); | ||
| 795 | SetPageUptodate(page); | ||
| 796 | set_page_dirty(page); | ||
| 797 | unlock_page(page); | ||
| 798 | page_cache_release(page); | ||
| 799 | page_cache_release(page); | ||
| 800 | } | 783 | } |
| 801 | BTRFS_I(inode)->generation = trans->transid; | ||
| 802 | 784 | ||
| 785 | ret = btrfs_dirty_pages(root, inode, pages, num_pages, 0, | ||
| 786 | bytes, &cached_state); | ||
| 787 | btrfs_drop_pages(pages, num_pages); | ||
| 803 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, | 788 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, |
| 804 | i_size_read(inode) - 1, &cached_state, GFP_NOFS); | 789 | i_size_read(inode) - 1, &cached_state, GFP_NOFS); |
| 805 | 790 | ||
| 791 | if (ret) { | ||
| 792 | ret = 0; | ||
| 793 | goto out_free; | ||
| 794 | } | ||
| 795 | |||
| 796 | BTRFS_I(inode)->generation = trans->transid; | ||
| 797 | |||
| 806 | filemap_write_and_wait(inode->i_mapping); | 798 | filemap_write_and_wait(inode->i_mapping); |
| 807 | 799 | ||
| 808 | key.objectid = BTRFS_FREE_SPACE_OBJECTID; | 800 | key.objectid = BTRFS_FREE_SPACE_OBJECTID; |
| @@ -853,6 +845,7 @@ out_free: | |||
| 853 | BTRFS_I(inode)->generation = 0; | 845 | BTRFS_I(inode)->generation = 0; |
| 854 | } | 846 | } |
| 855 | kfree(checksums); | 847 | kfree(checksums); |
| 848 | kfree(pages); | ||
| 856 | btrfs_update_inode(trans, root, inode); | 849 | btrfs_update_inode(trans, root, inode); |
| 857 | iput(inode); | 850 | iput(inode); |
| 858 | return ret; | 851 | return ret; |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5cc64ab9c485..fcd66b6a8086 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -1770,9 +1770,12 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
| 1770 | add_pending_csums(trans, inode, ordered_extent->file_offset, | 1770 | add_pending_csums(trans, inode, ordered_extent->file_offset, |
| 1771 | &ordered_extent->list); | 1771 | &ordered_extent->list); |
| 1772 | 1772 | ||
| 1773 | btrfs_ordered_update_i_size(inode, 0, ordered_extent); | 1773 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); |
| 1774 | ret = btrfs_update_inode(trans, root, inode); | 1774 | if (!ret) { |
| 1775 | BUG_ON(ret); | 1775 | ret = btrfs_update_inode(trans, root, inode); |
| 1776 | BUG_ON(ret); | ||
| 1777 | } | ||
| 1778 | ret = 0; | ||
| 1776 | out: | 1779 | out: |
| 1777 | if (nolock) { | 1780 | if (nolock) { |
| 1778 | if (trans) | 1781 | if (trans) |
| @@ -2590,6 +2593,13 @@ static void fill_inode_item(struct btrfs_trans_handle *trans, | |||
| 2590 | struct btrfs_inode_item *item, | 2593 | struct btrfs_inode_item *item, |
| 2591 | struct inode *inode) | 2594 | struct inode *inode) |
| 2592 | { | 2595 | { |
| 2596 | if (!leaf->map_token) | ||
| 2597 | map_private_extent_buffer(leaf, (unsigned long)item, | ||
| 2598 | sizeof(struct btrfs_inode_item), | ||
| 2599 | &leaf->map_token, &leaf->kaddr, | ||
| 2600 | &leaf->map_start, &leaf->map_len, | ||
| 2601 | KM_USER1); | ||
| 2602 | |||
| 2593 | btrfs_set_inode_uid(leaf, item, inode->i_uid); | 2603 | btrfs_set_inode_uid(leaf, item, inode->i_uid); |
| 2594 | btrfs_set_inode_gid(leaf, item, inode->i_gid); | 2604 | btrfs_set_inode_gid(leaf, item, inode->i_gid); |
| 2595 | btrfs_set_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size); | 2605 | btrfs_set_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size); |
| @@ -2618,6 +2628,11 @@ static void fill_inode_item(struct btrfs_trans_handle *trans, | |||
| 2618 | btrfs_set_inode_rdev(leaf, item, inode->i_rdev); | 2628 | btrfs_set_inode_rdev(leaf, item, inode->i_rdev); |
| 2619 | btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags); | 2629 | btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags); |
| 2620 | btrfs_set_inode_block_group(leaf, item, BTRFS_I(inode)->block_group); | 2630 | btrfs_set_inode_block_group(leaf, item, BTRFS_I(inode)->block_group); |
| 2631 | |||
| 2632 | if (leaf->map_token) { | ||
| 2633 | unmap_extent_buffer(leaf, leaf->map_token, KM_USER1); | ||
| 2634 | leaf->map_token = NULL; | ||
| 2635 | } | ||
| 2621 | } | 2636 | } |
| 2622 | 2637 | ||
| 2623 | /* | 2638 | /* |
| @@ -4207,10 +4222,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
| 4207 | struct btrfs_key found_key; | 4222 | struct btrfs_key found_key; |
| 4208 | struct btrfs_path *path; | 4223 | struct btrfs_path *path; |
| 4209 | int ret; | 4224 | int ret; |
| 4210 | u32 nritems; | ||
| 4211 | struct extent_buffer *leaf; | 4225 | struct extent_buffer *leaf; |
| 4212 | int slot; | 4226 | int slot; |
| 4213 | int advance; | ||
| 4214 | unsigned char d_type; | 4227 | unsigned char d_type; |
| 4215 | int over = 0; | 4228 | int over = 0; |
| 4216 | u32 di_cur; | 4229 | u32 di_cur; |
| @@ -4253,27 +4266,19 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
| 4253 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 4266 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
| 4254 | if (ret < 0) | 4267 | if (ret < 0) |
| 4255 | goto err; | 4268 | goto err; |
| 4256 | advance = 0; | ||
| 4257 | 4269 | ||
| 4258 | while (1) { | 4270 | while (1) { |
| 4259 | leaf = path->nodes[0]; | 4271 | leaf = path->nodes[0]; |
| 4260 | nritems = btrfs_header_nritems(leaf); | ||
| 4261 | slot = path->slots[0]; | 4272 | slot = path->slots[0]; |
| 4262 | if (advance || slot >= nritems) { | 4273 | if (slot >= btrfs_header_nritems(leaf)) { |
| 4263 | if (slot >= nritems - 1) { | 4274 | ret = btrfs_next_leaf(root, path); |
| 4264 | ret = btrfs_next_leaf(root, path); | 4275 | if (ret < 0) |
| 4265 | if (ret) | 4276 | goto err; |
| 4266 | break; | 4277 | else if (ret > 0) |
| 4267 | leaf = path->nodes[0]; | 4278 | break; |
| 4268 | nritems = btrfs_header_nritems(leaf); | 4279 | continue; |
| 4269 | slot = path->slots[0]; | ||
| 4270 | } else { | ||
| 4271 | slot++; | ||
| 4272 | path->slots[0]++; | ||
| 4273 | } | ||
| 4274 | } | 4280 | } |
| 4275 | 4281 | ||
| 4276 | advance = 1; | ||
| 4277 | item = btrfs_item_nr(leaf, slot); | 4282 | item = btrfs_item_nr(leaf, slot); |
| 4278 | btrfs_item_key_to_cpu(leaf, &found_key, slot); | 4283 | btrfs_item_key_to_cpu(leaf, &found_key, slot); |
| 4279 | 4284 | ||
| @@ -4282,7 +4287,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
| 4282 | if (btrfs_key_type(&found_key) != key_type) | 4287 | if (btrfs_key_type(&found_key) != key_type) |
| 4283 | break; | 4288 | break; |
| 4284 | if (found_key.offset < filp->f_pos) | 4289 | if (found_key.offset < filp->f_pos) |
| 4285 | continue; | 4290 | goto next; |
| 4286 | 4291 | ||
| 4287 | filp->f_pos = found_key.offset; | 4292 | filp->f_pos = found_key.offset; |
| 4288 | 4293 | ||
| @@ -4335,6 +4340,8 @@ skip: | |||
| 4335 | di_cur += di_len; | 4340 | di_cur += di_len; |
| 4336 | di = (struct btrfs_dir_item *)((char *)di + di_len); | 4341 | di = (struct btrfs_dir_item *)((char *)di + di_len); |
| 4337 | } | 4342 | } |
| 4343 | next: | ||
| 4344 | path->slots[0]++; | ||
| 4338 | } | 4345 | } |
| 4339 | 4346 | ||
| 4340 | /* Reached end of directory/root. Bump pos past the last item. */ | 4347 | /* Reached end of directory/root. Bump pos past the last item. */ |
| @@ -4527,14 +4534,17 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
| 4527 | BUG_ON(!path); | 4534 | BUG_ON(!path); |
| 4528 | 4535 | ||
| 4529 | inode = new_inode(root->fs_info->sb); | 4536 | inode = new_inode(root->fs_info->sb); |
| 4530 | if (!inode) | 4537 | if (!inode) { |
| 4538 | btrfs_free_path(path); | ||
| 4531 | return ERR_PTR(-ENOMEM); | 4539 | return ERR_PTR(-ENOMEM); |
| 4540 | } | ||
| 4532 | 4541 | ||
| 4533 | if (dir) { | 4542 | if (dir) { |
| 4534 | trace_btrfs_inode_request(dir); | 4543 | trace_btrfs_inode_request(dir); |
| 4535 | 4544 | ||
| 4536 | ret = btrfs_set_inode_index(dir, index); | 4545 | ret = btrfs_set_inode_index(dir, index); |
| 4537 | if (ret) { | 4546 | if (ret) { |
| 4547 | btrfs_free_path(path); | ||
| 4538 | iput(inode); | 4548 | iput(inode); |
| 4539 | return ERR_PTR(ret); | 4549 | return ERR_PTR(ret); |
| 4540 | } | 4550 | } |
| @@ -4834,9 +4844,6 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 4834 | if (inode->i_nlink == ~0U) | 4844 | if (inode->i_nlink == ~0U) |
| 4835 | return -EMLINK; | 4845 | return -EMLINK; |
| 4836 | 4846 | ||
| 4837 | btrfs_inc_nlink(inode); | ||
| 4838 | inode->i_ctime = CURRENT_TIME; | ||
| 4839 | |||
| 4840 | err = btrfs_set_inode_index(dir, &index); | 4847 | err = btrfs_set_inode_index(dir, &index); |
| 4841 | if (err) | 4848 | if (err) |
| 4842 | goto fail; | 4849 | goto fail; |
| @@ -4852,6 +4859,9 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 4852 | goto fail; | 4859 | goto fail; |
| 4853 | } | 4860 | } |
| 4854 | 4861 | ||
| 4862 | btrfs_inc_nlink(inode); | ||
| 4863 | inode->i_ctime = CURRENT_TIME; | ||
| 4864 | |||
| 4855 | btrfs_set_trans_block_group(trans, dir); | 4865 | btrfs_set_trans_block_group(trans, dir); |
| 4856 | ihold(inode); | 4866 | ihold(inode); |
| 4857 | 4867 | ||
| @@ -5221,7 +5231,7 @@ again: | |||
| 5221 | btrfs_mark_buffer_dirty(leaf); | 5231 | btrfs_mark_buffer_dirty(leaf); |
| 5222 | } | 5232 | } |
| 5223 | set_extent_uptodate(io_tree, em->start, | 5233 | set_extent_uptodate(io_tree, em->start, |
| 5224 | extent_map_end(em) - 1, GFP_NOFS); | 5234 | extent_map_end(em) - 1, NULL, GFP_NOFS); |
| 5225 | goto insert; | 5235 | goto insert; |
| 5226 | } else { | 5236 | } else { |
| 5227 | printk(KERN_ERR "btrfs unknown found_type %d\n", found_type); | 5237 | printk(KERN_ERR "btrfs unknown found_type %d\n", found_type); |
| @@ -5428,17 +5438,30 @@ out: | |||
| 5428 | } | 5438 | } |
| 5429 | 5439 | ||
| 5430 | static struct extent_map *btrfs_new_extent_direct(struct inode *inode, | 5440 | static struct extent_map *btrfs_new_extent_direct(struct inode *inode, |
| 5441 | struct extent_map *em, | ||
| 5431 | u64 start, u64 len) | 5442 | u64 start, u64 len) |
| 5432 | { | 5443 | { |
| 5433 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5444 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 5434 | struct btrfs_trans_handle *trans; | 5445 | struct btrfs_trans_handle *trans; |
| 5435 | struct extent_map *em; | ||
| 5436 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 5446 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
| 5437 | struct btrfs_key ins; | 5447 | struct btrfs_key ins; |
| 5438 | u64 alloc_hint; | 5448 | u64 alloc_hint; |
| 5439 | int ret; | 5449 | int ret; |
| 5450 | bool insert = false; | ||
| 5440 | 5451 | ||
| 5441 | btrfs_drop_extent_cache(inode, start, start + len - 1, 0); | 5452 | /* |
| 5453 | * Ok if the extent map we looked up is a hole and is for the exact | ||
| 5454 | * range we want, there is no reason to allocate a new one, however if | ||
| 5455 | * it is not right then we need to free this one and drop the cache for | ||
| 5456 | * our range. | ||
| 5457 | */ | ||
| 5458 | if (em->block_start != EXTENT_MAP_HOLE || em->start != start || | ||
| 5459 | em->len != len) { | ||
| 5460 | free_extent_map(em); | ||
| 5461 | em = NULL; | ||
| 5462 | insert = true; | ||
| 5463 | btrfs_drop_extent_cache(inode, start, start + len - 1, 0); | ||
| 5464 | } | ||
| 5442 | 5465 | ||
| 5443 | trans = btrfs_join_transaction(root, 0); | 5466 | trans = btrfs_join_transaction(root, 0); |
| 5444 | if (IS_ERR(trans)) | 5467 | if (IS_ERR(trans)) |
| @@ -5454,10 +5477,12 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode, | |||
| 5454 | goto out; | 5477 | goto out; |
| 5455 | } | 5478 | } |
| 5456 | 5479 | ||
| 5457 | em = alloc_extent_map(GFP_NOFS); | ||
| 5458 | if (!em) { | 5480 | if (!em) { |
| 5459 | em = ERR_PTR(-ENOMEM); | 5481 | em = alloc_extent_map(GFP_NOFS); |
| 5460 | goto out; | 5482 | if (!em) { |
| 5483 | em = ERR_PTR(-ENOMEM); | ||
| 5484 | goto out; | ||
| 5485 | } | ||
| 5461 | } | 5486 | } |
| 5462 | 5487 | ||
| 5463 | em->start = start; | 5488 | em->start = start; |
| @@ -5467,9 +5492,15 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode, | |||
| 5467 | em->block_start = ins.objectid; | 5492 | em->block_start = ins.objectid; |
| 5468 | em->block_len = ins.offset; | 5493 | em->block_len = ins.offset; |
| 5469 | em->bdev = root->fs_info->fs_devices->latest_bdev; | 5494 | em->bdev = root->fs_info->fs_devices->latest_bdev; |
| 5495 | |||
| 5496 | /* | ||
| 5497 | * We need to do this because if we're using the original em we searched | ||
| 5498 | * for, we could have EXTENT_FLAG_VACANCY set, and we don't want that. | ||
| 5499 | */ | ||
| 5500 | em->flags = 0; | ||
| 5470 | set_bit(EXTENT_FLAG_PINNED, &em->flags); | 5501 | set_bit(EXTENT_FLAG_PINNED, &em->flags); |
| 5471 | 5502 | ||
| 5472 | while (1) { | 5503 | while (insert) { |
| 5473 | write_lock(&em_tree->lock); | 5504 | write_lock(&em_tree->lock); |
| 5474 | ret = add_extent_mapping(em_tree, em); | 5505 | ret = add_extent_mapping(em_tree, em); |
| 5475 | write_unlock(&em_tree->lock); | 5506 | write_unlock(&em_tree->lock); |
| @@ -5687,8 +5718,7 @@ must_cow: | |||
| 5687 | * it above | 5718 | * it above |
| 5688 | */ | 5719 | */ |
| 5689 | len = bh_result->b_size; | 5720 | len = bh_result->b_size; |
| 5690 | free_extent_map(em); | 5721 | em = btrfs_new_extent_direct(inode, em, start, len); |
| 5691 | em = btrfs_new_extent_direct(inode, start, len); | ||
| 5692 | if (IS_ERR(em)) | 5722 | if (IS_ERR(em)) |
| 5693 | return PTR_ERR(em); | 5723 | return PTR_ERR(em); |
| 5694 | len = min(len, em->len - (start - em->start)); | 5724 | len = min(len, em->len - (start - em->start)); |
| @@ -5851,8 +5881,10 @@ again: | |||
| 5851 | } | 5881 | } |
| 5852 | 5882 | ||
| 5853 | add_pending_csums(trans, inode, ordered->file_offset, &ordered->list); | 5883 | add_pending_csums(trans, inode, ordered->file_offset, &ordered->list); |
| 5854 | btrfs_ordered_update_i_size(inode, 0, ordered); | 5884 | ret = btrfs_ordered_update_i_size(inode, 0, ordered); |
| 5855 | btrfs_update_inode(trans, root, inode); | 5885 | if (!ret) |
| 5886 | btrfs_update_inode(trans, root, inode); | ||
| 5887 | ret = 0; | ||
| 5856 | out_unlock: | 5888 | out_unlock: |
| 5857 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, ordered->file_offset, | 5889 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, ordered->file_offset, |
| 5858 | ordered->file_offset + ordered->len - 1, | 5890 | ordered->file_offset + ordered->len - 1, |
| @@ -5938,7 +5970,7 @@ static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev, | |||
| 5938 | 5970 | ||
| 5939 | static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | 5971 | static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, |
| 5940 | int rw, u64 file_offset, int skip_sum, | 5972 | int rw, u64 file_offset, int skip_sum, |
| 5941 | u32 *csums) | 5973 | u32 *csums, int async_submit) |
| 5942 | { | 5974 | { |
| 5943 | int write = rw & REQ_WRITE; | 5975 | int write = rw & REQ_WRITE; |
| 5944 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5976 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| @@ -5949,13 +5981,24 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | |||
| 5949 | if (ret) | 5981 | if (ret) |
| 5950 | goto err; | 5982 | goto err; |
| 5951 | 5983 | ||
| 5952 | if (write && !skip_sum) { | 5984 | if (skip_sum) |
| 5985 | goto map; | ||
| 5986 | |||
| 5987 | if (write && async_submit) { | ||
| 5953 | ret = btrfs_wq_submit_bio(root->fs_info, | 5988 | ret = btrfs_wq_submit_bio(root->fs_info, |
| 5954 | inode, rw, bio, 0, 0, | 5989 | inode, rw, bio, 0, 0, |
| 5955 | file_offset, | 5990 | file_offset, |
| 5956 | __btrfs_submit_bio_start_direct_io, | 5991 | __btrfs_submit_bio_start_direct_io, |
| 5957 | __btrfs_submit_bio_done); | 5992 | __btrfs_submit_bio_done); |
| 5958 | goto err; | 5993 | goto err; |
| 5994 | } else if (write) { | ||
| 5995 | /* | ||
| 5996 | * If we aren't doing async submit, calculate the csum of the | ||
| 5997 | * bio now. | ||
| 5998 | */ | ||
| 5999 | ret = btrfs_csum_one_bio(root, inode, bio, file_offset, 1); | ||
| 6000 | if (ret) | ||
| 6001 | goto err; | ||
| 5959 | } else if (!skip_sum) { | 6002 | } else if (!skip_sum) { |
| 5960 | ret = btrfs_lookup_bio_sums_dio(root, inode, bio, | 6003 | ret = btrfs_lookup_bio_sums_dio(root, inode, bio, |
| 5961 | file_offset, csums); | 6004 | file_offset, csums); |
| @@ -5963,7 +6006,8 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | |||
| 5963 | goto err; | 6006 | goto err; |
| 5964 | } | 6007 | } |
| 5965 | 6008 | ||
| 5966 | ret = btrfs_map_bio(root, rw, bio, 0, 1); | 6009 | map: |
| 6010 | ret = btrfs_map_bio(root, rw, bio, 0, async_submit); | ||
| 5967 | err: | 6011 | err: |
| 5968 | bio_put(bio); | 6012 | bio_put(bio); |
| 5969 | return ret; | 6013 | return ret; |
| @@ -5985,15 +6029,9 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
| 5985 | int nr_pages = 0; | 6029 | int nr_pages = 0; |
| 5986 | u32 *csums = dip->csums; | 6030 | u32 *csums = dip->csums; |
| 5987 | int ret = 0; | 6031 | int ret = 0; |
| 6032 | int async_submit = 0; | ||
| 5988 | int write = rw & REQ_WRITE; | 6033 | int write = rw & REQ_WRITE; |
| 5989 | 6034 | ||
| 5990 | bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); | ||
| 5991 | if (!bio) | ||
| 5992 | return -ENOMEM; | ||
| 5993 | bio->bi_private = dip; | ||
| 5994 | bio->bi_end_io = btrfs_end_dio_bio; | ||
| 5995 | atomic_inc(&dip->pending_bios); | ||
| 5996 | |||
| 5997 | map_length = orig_bio->bi_size; | 6035 | map_length = orig_bio->bi_size; |
| 5998 | ret = btrfs_map_block(map_tree, READ, start_sector << 9, | 6036 | ret = btrfs_map_block(map_tree, READ, start_sector << 9, |
| 5999 | &map_length, NULL, 0); | 6037 | &map_length, NULL, 0); |
| @@ -6002,6 +6040,19 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
| 6002 | return -EIO; | 6040 | return -EIO; |
| 6003 | } | 6041 | } |
| 6004 | 6042 | ||
| 6043 | if (map_length >= orig_bio->bi_size) { | ||
| 6044 | bio = orig_bio; | ||
| 6045 | goto submit; | ||
| 6046 | } | ||
| 6047 | |||
| 6048 | async_submit = 1; | ||
| 6049 | bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); | ||
| 6050 | if (!bio) | ||
| 6051 | return -ENOMEM; | ||
| 6052 | bio->bi_private = dip; | ||
| 6053 | bio->bi_end_io = btrfs_end_dio_bio; | ||
| 6054 | atomic_inc(&dip->pending_bios); | ||
| 6055 | |||
| 6005 | while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) { | 6056 | while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) { |
| 6006 | if (unlikely(map_length < submit_len + bvec->bv_len || | 6057 | if (unlikely(map_length < submit_len + bvec->bv_len || |
| 6007 | bio_add_page(bio, bvec->bv_page, bvec->bv_len, | 6058 | bio_add_page(bio, bvec->bv_page, bvec->bv_len, |
| @@ -6015,7 +6066,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
| 6015 | atomic_inc(&dip->pending_bios); | 6066 | atomic_inc(&dip->pending_bios); |
| 6016 | ret = __btrfs_submit_dio_bio(bio, inode, rw, | 6067 | ret = __btrfs_submit_dio_bio(bio, inode, rw, |
| 6017 | file_offset, skip_sum, | 6068 | file_offset, skip_sum, |
| 6018 | csums); | 6069 | csums, async_submit); |
| 6019 | if (ret) { | 6070 | if (ret) { |
| 6020 | bio_put(bio); | 6071 | bio_put(bio); |
| 6021 | atomic_dec(&dip->pending_bios); | 6072 | atomic_dec(&dip->pending_bios); |
| @@ -6052,8 +6103,9 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
| 6052 | } | 6103 | } |
| 6053 | } | 6104 | } |
| 6054 | 6105 | ||
| 6106 | submit: | ||
| 6055 | ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum, | 6107 | ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum, |
| 6056 | csums); | 6108 | csums, async_submit); |
| 6057 | if (!ret) | 6109 | if (!ret) |
| 6058 | return 0; | 6110 | return 0; |
| 6059 | 6111 | ||
| @@ -6148,6 +6200,7 @@ static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *io | |||
| 6148 | unsigned long nr_segs) | 6200 | unsigned long nr_segs) |
| 6149 | { | 6201 | { |
| 6150 | int seg; | 6202 | int seg; |
| 6203 | int i; | ||
| 6151 | size_t size; | 6204 | size_t size; |
| 6152 | unsigned long addr; | 6205 | unsigned long addr; |
| 6153 | unsigned blocksize_mask = root->sectorsize - 1; | 6206 | unsigned blocksize_mask = root->sectorsize - 1; |
| @@ -6162,8 +6215,22 @@ static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *io | |||
| 6162 | addr = (unsigned long)iov[seg].iov_base; | 6215 | addr = (unsigned long)iov[seg].iov_base; |
| 6163 | size = iov[seg].iov_len; | 6216 | size = iov[seg].iov_len; |
| 6164 | end += size; | 6217 | end += size; |
| 6165 | if ((addr & blocksize_mask) || (size & blocksize_mask)) | 6218 | if ((addr & blocksize_mask) || (size & blocksize_mask)) |
| 6166 | goto out; | 6219 | goto out; |
| 6220 | |||
| 6221 | /* If this is a write we don't need to check anymore */ | ||
| 6222 | if (rw & WRITE) | ||
| 6223 | continue; | ||
| 6224 | |||
| 6225 | /* | ||
| 6226 | * Check to make sure we don't have duplicate iov_base's in this | ||
| 6227 | * iovec, if so return EINVAL, otherwise we'll get csum errors | ||
| 6228 | * when reading back. | ||
| 6229 | */ | ||
| 6230 | for (i = seg + 1; i < nr_segs; i++) { | ||
| 6231 | if (iov[seg].iov_base == iov[i].iov_base) | ||
| 6232 | goto out; | ||
| 6233 | } | ||
| 6167 | } | 6234 | } |
| 6168 | retval = 0; | 6235 | retval = 0; |
| 6169 | out: | 6236 | out: |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index cfc264fefdb0..ffb48d6c5433 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -2287,7 +2287,7 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) | |||
| 2287 | struct btrfs_ioctl_space_info space; | 2287 | struct btrfs_ioctl_space_info space; |
| 2288 | struct btrfs_ioctl_space_info *dest; | 2288 | struct btrfs_ioctl_space_info *dest; |
| 2289 | struct btrfs_ioctl_space_info *dest_orig; | 2289 | struct btrfs_ioctl_space_info *dest_orig; |
| 2290 | struct btrfs_ioctl_space_info *user_dest; | 2290 | struct btrfs_ioctl_space_info __user *user_dest; |
| 2291 | struct btrfs_space_info *info; | 2291 | struct btrfs_space_info *info; |
| 2292 | u64 types[] = {BTRFS_BLOCK_GROUP_DATA, | 2292 | u64 types[] = {BTRFS_BLOCK_GROUP_DATA, |
| 2293 | BTRFS_BLOCK_GROUP_SYSTEM, | 2293 | BTRFS_BLOCK_GROUP_SYSTEM, |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 58e7de9cc90c..0ac712efcdf2 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -159,7 +159,7 @@ enum { | |||
| 159 | Opt_compress_type, Opt_compress_force, Opt_compress_force_type, | 159 | Opt_compress_type, Opt_compress_force, Opt_compress_force_type, |
| 160 | Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, | 160 | Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, |
| 161 | Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed, | 161 | Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed, |
| 162 | Opt_enospc_debug, Opt_err, | 162 | Opt_enospc_debug, Opt_subvolrootid, Opt_err, |
| 163 | }; | 163 | }; |
| 164 | 164 | ||
| 165 | static match_table_t tokens = { | 165 | static match_table_t tokens = { |
| @@ -189,6 +189,7 @@ static match_table_t tokens = { | |||
| 189 | {Opt_clear_cache, "clear_cache"}, | 189 | {Opt_clear_cache, "clear_cache"}, |
| 190 | {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, | 190 | {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, |
| 191 | {Opt_enospc_debug, "enospc_debug"}, | 191 | {Opt_enospc_debug, "enospc_debug"}, |
| 192 | {Opt_subvolrootid, "subvolrootid=%d"}, | ||
| 192 | {Opt_err, NULL}, | 193 | {Opt_err, NULL}, |
| 193 | }; | 194 | }; |
| 194 | 195 | ||
| @@ -232,6 +233,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
| 232 | break; | 233 | break; |
| 233 | case Opt_subvol: | 234 | case Opt_subvol: |
| 234 | case Opt_subvolid: | 235 | case Opt_subvolid: |
| 236 | case Opt_subvolrootid: | ||
| 235 | case Opt_device: | 237 | case Opt_device: |
| 236 | /* | 238 | /* |
| 237 | * These are parsed by btrfs_parse_early_options | 239 | * These are parsed by btrfs_parse_early_options |
| @@ -388,7 +390,7 @@ out: | |||
| 388 | */ | 390 | */ |
| 389 | static int btrfs_parse_early_options(const char *options, fmode_t flags, | 391 | static int btrfs_parse_early_options(const char *options, fmode_t flags, |
| 390 | void *holder, char **subvol_name, u64 *subvol_objectid, | 392 | void *holder, char **subvol_name, u64 *subvol_objectid, |
| 391 | struct btrfs_fs_devices **fs_devices) | 393 | u64 *subvol_rootid, struct btrfs_fs_devices **fs_devices) |
| 392 | { | 394 | { |
| 393 | substring_t args[MAX_OPT_ARGS]; | 395 | substring_t args[MAX_OPT_ARGS]; |
| 394 | char *opts, *orig, *p; | 396 | char *opts, *orig, *p; |
| @@ -429,6 +431,18 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags, | |||
| 429 | *subvol_objectid = intarg; | 431 | *subvol_objectid = intarg; |
| 430 | } | 432 | } |
| 431 | break; | 433 | break; |
| 434 | case Opt_subvolrootid: | ||
| 435 | intarg = 0; | ||
| 436 | error = match_int(&args[0], &intarg); | ||
| 437 | if (!error) { | ||
| 438 | /* we want the original fs_tree */ | ||
| 439 | if (!intarg) | ||
| 440 | *subvol_rootid = | ||
| 441 | BTRFS_FS_TREE_OBJECTID; | ||
| 442 | else | ||
| 443 | *subvol_rootid = intarg; | ||
| 444 | } | ||
| 445 | break; | ||
| 432 | case Opt_device: | 446 | case Opt_device: |
| 433 | error = btrfs_scan_one_device(match_strdup(&args[0]), | 447 | error = btrfs_scan_one_device(match_strdup(&args[0]), |
| 434 | flags, holder, fs_devices); | 448 | flags, holder, fs_devices); |
| @@ -736,6 +750,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 736 | fmode_t mode = FMODE_READ; | 750 | fmode_t mode = FMODE_READ; |
| 737 | char *subvol_name = NULL; | 751 | char *subvol_name = NULL; |
| 738 | u64 subvol_objectid = 0; | 752 | u64 subvol_objectid = 0; |
| 753 | u64 subvol_rootid = 0; | ||
| 739 | int error = 0; | 754 | int error = 0; |
| 740 | 755 | ||
| 741 | if (!(flags & MS_RDONLY)) | 756 | if (!(flags & MS_RDONLY)) |
| @@ -743,7 +758,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 743 | 758 | ||
| 744 | error = btrfs_parse_early_options(data, mode, fs_type, | 759 | error = btrfs_parse_early_options(data, mode, fs_type, |
| 745 | &subvol_name, &subvol_objectid, | 760 | &subvol_name, &subvol_objectid, |
| 746 | &fs_devices); | 761 | &subvol_rootid, &fs_devices); |
| 747 | if (error) | 762 | if (error) |
| 748 | return ERR_PTR(error); | 763 | return ERR_PTR(error); |
| 749 | 764 | ||
| @@ -807,15 +822,17 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 807 | s->s_flags |= MS_ACTIVE; | 822 | s->s_flags |= MS_ACTIVE; |
| 808 | } | 823 | } |
| 809 | 824 | ||
| 810 | root = get_default_root(s, subvol_objectid); | ||
| 811 | if (IS_ERR(root)) { | ||
| 812 | error = PTR_ERR(root); | ||
| 813 | deactivate_locked_super(s); | ||
| 814 | goto error_free_subvol_name; | ||
| 815 | } | ||
| 816 | /* if they gave us a subvolume name bind mount into that */ | 825 | /* if they gave us a subvolume name bind mount into that */ |
| 817 | if (strcmp(subvol_name, ".")) { | 826 | if (strcmp(subvol_name, ".")) { |
| 818 | struct dentry *new_root; | 827 | struct dentry *new_root; |
| 828 | |||
| 829 | root = get_default_root(s, subvol_rootid); | ||
| 830 | if (IS_ERR(root)) { | ||
| 831 | error = PTR_ERR(root); | ||
| 832 | deactivate_locked_super(s); | ||
| 833 | goto error_free_subvol_name; | ||
| 834 | } | ||
| 835 | |||
| 819 | mutex_lock(&root->d_inode->i_mutex); | 836 | mutex_lock(&root->d_inode->i_mutex); |
| 820 | new_root = lookup_one_len(subvol_name, root, | 837 | new_root = lookup_one_len(subvol_name, root, |
| 821 | strlen(subvol_name)); | 838 | strlen(subvol_name)); |
| @@ -836,6 +853,13 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 836 | } | 853 | } |
| 837 | dput(root); | 854 | dput(root); |
| 838 | root = new_root; | 855 | root = new_root; |
| 856 | } else { | ||
| 857 | root = get_default_root(s, subvol_objectid); | ||
| 858 | if (IS_ERR(root)) { | ||
| 859 | error = PTR_ERR(root); | ||
| 860 | deactivate_locked_super(s); | ||
| 861 | goto error_free_subvol_name; | ||
| 862 | } | ||
| 839 | } | 863 | } |
| 840 | 864 | ||
| 841 | kfree(subvol_name); | 865 | kfree(subvol_name); |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 5b158da7e0bb..c571734d5e5a 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -32,10 +32,8 @@ | |||
| 32 | 32 | ||
| 33 | static noinline void put_transaction(struct btrfs_transaction *transaction) | 33 | static noinline void put_transaction(struct btrfs_transaction *transaction) |
| 34 | { | 34 | { |
| 35 | WARN_ON(transaction->use_count == 0); | 35 | WARN_ON(atomic_read(&transaction->use_count) == 0); |
| 36 | transaction->use_count--; | 36 | if (atomic_dec_and_test(&transaction->use_count)) { |
| 37 | if (transaction->use_count == 0) { | ||
| 38 | list_del_init(&transaction->list); | ||
| 39 | memset(transaction, 0, sizeof(*transaction)); | 37 | memset(transaction, 0, sizeof(*transaction)); |
| 40 | kmem_cache_free(btrfs_transaction_cachep, transaction); | 38 | kmem_cache_free(btrfs_transaction_cachep, transaction); |
| 41 | } | 39 | } |
| @@ -60,14 +58,14 @@ static noinline int join_transaction(struct btrfs_root *root) | |||
| 60 | if (!cur_trans) | 58 | if (!cur_trans) |
| 61 | return -ENOMEM; | 59 | return -ENOMEM; |
| 62 | root->fs_info->generation++; | 60 | root->fs_info->generation++; |
| 63 | cur_trans->num_writers = 1; | 61 | atomic_set(&cur_trans->num_writers, 1); |
| 64 | cur_trans->num_joined = 0; | 62 | cur_trans->num_joined = 0; |
| 65 | cur_trans->transid = root->fs_info->generation; | 63 | cur_trans->transid = root->fs_info->generation; |
| 66 | init_waitqueue_head(&cur_trans->writer_wait); | 64 | init_waitqueue_head(&cur_trans->writer_wait); |
| 67 | init_waitqueue_head(&cur_trans->commit_wait); | 65 | init_waitqueue_head(&cur_trans->commit_wait); |
| 68 | cur_trans->in_commit = 0; | 66 | cur_trans->in_commit = 0; |
| 69 | cur_trans->blocked = 0; | 67 | cur_trans->blocked = 0; |
| 70 | cur_trans->use_count = 1; | 68 | atomic_set(&cur_trans->use_count, 1); |
| 71 | cur_trans->commit_done = 0; | 69 | cur_trans->commit_done = 0; |
| 72 | cur_trans->start_time = get_seconds(); | 70 | cur_trans->start_time = get_seconds(); |
| 73 | 71 | ||
| @@ -88,7 +86,7 @@ static noinline int join_transaction(struct btrfs_root *root) | |||
| 88 | root->fs_info->running_transaction = cur_trans; | 86 | root->fs_info->running_transaction = cur_trans; |
| 89 | spin_unlock(&root->fs_info->new_trans_lock); | 87 | spin_unlock(&root->fs_info->new_trans_lock); |
| 90 | } else { | 88 | } else { |
| 91 | cur_trans->num_writers++; | 89 | atomic_inc(&cur_trans->num_writers); |
| 92 | cur_trans->num_joined++; | 90 | cur_trans->num_joined++; |
| 93 | } | 91 | } |
| 94 | 92 | ||
| @@ -145,7 +143,7 @@ static void wait_current_trans(struct btrfs_root *root) | |||
| 145 | cur_trans = root->fs_info->running_transaction; | 143 | cur_trans = root->fs_info->running_transaction; |
| 146 | if (cur_trans && cur_trans->blocked) { | 144 | if (cur_trans && cur_trans->blocked) { |
| 147 | DEFINE_WAIT(wait); | 145 | DEFINE_WAIT(wait); |
| 148 | cur_trans->use_count++; | 146 | atomic_inc(&cur_trans->use_count); |
| 149 | while (1) { | 147 | while (1) { |
| 150 | prepare_to_wait(&root->fs_info->transaction_wait, &wait, | 148 | prepare_to_wait(&root->fs_info->transaction_wait, &wait, |
| 151 | TASK_UNINTERRUPTIBLE); | 149 | TASK_UNINTERRUPTIBLE); |
| @@ -181,6 +179,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, | |||
| 181 | { | 179 | { |
| 182 | struct btrfs_trans_handle *h; | 180 | struct btrfs_trans_handle *h; |
| 183 | struct btrfs_transaction *cur_trans; | 181 | struct btrfs_transaction *cur_trans; |
| 182 | int retries = 0; | ||
| 184 | int ret; | 183 | int ret; |
| 185 | 184 | ||
| 186 | if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) | 185 | if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) |
| @@ -204,7 +203,7 @@ again: | |||
| 204 | } | 203 | } |
| 205 | 204 | ||
| 206 | cur_trans = root->fs_info->running_transaction; | 205 | cur_trans = root->fs_info->running_transaction; |
| 207 | cur_trans->use_count++; | 206 | atomic_inc(&cur_trans->use_count); |
| 208 | if (type != TRANS_JOIN_NOLOCK) | 207 | if (type != TRANS_JOIN_NOLOCK) |
| 209 | mutex_unlock(&root->fs_info->trans_mutex); | 208 | mutex_unlock(&root->fs_info->trans_mutex); |
| 210 | 209 | ||
| @@ -224,10 +223,18 @@ again: | |||
| 224 | 223 | ||
| 225 | if (num_items > 0) { | 224 | if (num_items > 0) { |
| 226 | ret = btrfs_trans_reserve_metadata(h, root, num_items); | 225 | ret = btrfs_trans_reserve_metadata(h, root, num_items); |
| 227 | if (ret == -EAGAIN) { | 226 | if (ret == -EAGAIN && !retries) { |
| 227 | retries++; | ||
| 228 | btrfs_commit_transaction(h, root); | 228 | btrfs_commit_transaction(h, root); |
| 229 | goto again; | 229 | goto again; |
| 230 | } else if (ret == -EAGAIN) { | ||
| 231 | /* | ||
| 232 | * We have already retried and got EAGAIN, so really we | ||
| 233 | * don't have space, so set ret to -ENOSPC. | ||
| 234 | */ | ||
| 235 | ret = -ENOSPC; | ||
| 230 | } | 236 | } |
| 237 | |||
| 231 | if (ret < 0) { | 238 | if (ret < 0) { |
| 232 | btrfs_end_transaction(h, root); | 239 | btrfs_end_transaction(h, root); |
| 233 | return ERR_PTR(ret); | 240 | return ERR_PTR(ret); |
| @@ -327,7 +334,7 @@ int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid) | |||
| 327 | goto out_unlock; /* nothing committing|committed */ | 334 | goto out_unlock; /* nothing committing|committed */ |
| 328 | } | 335 | } |
| 329 | 336 | ||
| 330 | cur_trans->use_count++; | 337 | atomic_inc(&cur_trans->use_count); |
| 331 | mutex_unlock(&root->fs_info->trans_mutex); | 338 | mutex_unlock(&root->fs_info->trans_mutex); |
| 332 | 339 | ||
| 333 | wait_for_commit(root, cur_trans); | 340 | wait_for_commit(root, cur_trans); |
| @@ -457,18 +464,14 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
| 457 | wake_up_process(info->transaction_kthread); | 464 | wake_up_process(info->transaction_kthread); |
| 458 | } | 465 | } |
| 459 | 466 | ||
| 460 | if (lock) | ||
| 461 | mutex_lock(&info->trans_mutex); | ||
| 462 | WARN_ON(cur_trans != info->running_transaction); | 467 | WARN_ON(cur_trans != info->running_transaction); |
| 463 | WARN_ON(cur_trans->num_writers < 1); | 468 | WARN_ON(atomic_read(&cur_trans->num_writers) < 1); |
| 464 | cur_trans->num_writers--; | 469 | atomic_dec(&cur_trans->num_writers); |
| 465 | 470 | ||
| 466 | smp_mb(); | 471 | smp_mb(); |
| 467 | if (waitqueue_active(&cur_trans->writer_wait)) | 472 | if (waitqueue_active(&cur_trans->writer_wait)) |
| 468 | wake_up(&cur_trans->writer_wait); | 473 | wake_up(&cur_trans->writer_wait); |
| 469 | put_transaction(cur_trans); | 474 | put_transaction(cur_trans); |
| 470 | if (lock) | ||
| 471 | mutex_unlock(&info->trans_mutex); | ||
| 472 | 475 | ||
| 473 | if (current->journal_info == trans) | 476 | if (current->journal_info == trans) |
| 474 | current->journal_info = NULL; | 477 | current->journal_info = NULL; |
| @@ -1178,7 +1181,7 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans, | |||
| 1178 | /* take transaction reference */ | 1181 | /* take transaction reference */ |
| 1179 | mutex_lock(&root->fs_info->trans_mutex); | 1182 | mutex_lock(&root->fs_info->trans_mutex); |
| 1180 | cur_trans = trans->transaction; | 1183 | cur_trans = trans->transaction; |
| 1181 | cur_trans->use_count++; | 1184 | atomic_inc(&cur_trans->use_count); |
| 1182 | mutex_unlock(&root->fs_info->trans_mutex); | 1185 | mutex_unlock(&root->fs_info->trans_mutex); |
| 1183 | 1186 | ||
| 1184 | btrfs_end_transaction(trans, root); | 1187 | btrfs_end_transaction(trans, root); |
| @@ -1237,7 +1240,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
| 1237 | 1240 | ||
| 1238 | mutex_lock(&root->fs_info->trans_mutex); | 1241 | mutex_lock(&root->fs_info->trans_mutex); |
| 1239 | if (cur_trans->in_commit) { | 1242 | if (cur_trans->in_commit) { |
| 1240 | cur_trans->use_count++; | 1243 | atomic_inc(&cur_trans->use_count); |
| 1241 | mutex_unlock(&root->fs_info->trans_mutex); | 1244 | mutex_unlock(&root->fs_info->trans_mutex); |
| 1242 | btrfs_end_transaction(trans, root); | 1245 | btrfs_end_transaction(trans, root); |
| 1243 | 1246 | ||
| @@ -1259,7 +1262,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
| 1259 | prev_trans = list_entry(cur_trans->list.prev, | 1262 | prev_trans = list_entry(cur_trans->list.prev, |
| 1260 | struct btrfs_transaction, list); | 1263 | struct btrfs_transaction, list); |
| 1261 | if (!prev_trans->commit_done) { | 1264 | if (!prev_trans->commit_done) { |
| 1262 | prev_trans->use_count++; | 1265 | atomic_inc(&prev_trans->use_count); |
| 1263 | mutex_unlock(&root->fs_info->trans_mutex); | 1266 | mutex_unlock(&root->fs_info->trans_mutex); |
| 1264 | 1267 | ||
| 1265 | wait_for_commit(root, prev_trans); | 1268 | wait_for_commit(root, prev_trans); |
| @@ -1300,14 +1303,14 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
| 1300 | TASK_UNINTERRUPTIBLE); | 1303 | TASK_UNINTERRUPTIBLE); |
| 1301 | 1304 | ||
| 1302 | smp_mb(); | 1305 | smp_mb(); |
| 1303 | if (cur_trans->num_writers > 1) | 1306 | if (atomic_read(&cur_trans->num_writers) > 1) |
| 1304 | schedule_timeout(MAX_SCHEDULE_TIMEOUT); | 1307 | schedule_timeout(MAX_SCHEDULE_TIMEOUT); |
| 1305 | else if (should_grow) | 1308 | else if (should_grow) |
| 1306 | schedule_timeout(1); | 1309 | schedule_timeout(1); |
| 1307 | 1310 | ||
| 1308 | mutex_lock(&root->fs_info->trans_mutex); | 1311 | mutex_lock(&root->fs_info->trans_mutex); |
| 1309 | finish_wait(&cur_trans->writer_wait, &wait); | 1312 | finish_wait(&cur_trans->writer_wait, &wait); |
| 1310 | } while (cur_trans->num_writers > 1 || | 1313 | } while (atomic_read(&cur_trans->num_writers) > 1 || |
| 1311 | (should_grow && cur_trans->num_joined != joined)); | 1314 | (should_grow && cur_trans->num_joined != joined)); |
| 1312 | 1315 | ||
| 1313 | ret = create_pending_snapshots(trans, root->fs_info); | 1316 | ret = create_pending_snapshots(trans, root->fs_info); |
| @@ -1394,6 +1397,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
| 1394 | 1397 | ||
| 1395 | wake_up(&cur_trans->commit_wait); | 1398 | wake_up(&cur_trans->commit_wait); |
| 1396 | 1399 | ||
| 1400 | list_del_init(&cur_trans->list); | ||
| 1397 | put_transaction(cur_trans); | 1401 | put_transaction(cur_trans); |
| 1398 | put_transaction(cur_trans); | 1402 | put_transaction(cur_trans); |
| 1399 | 1403 | ||
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index 229a594cacd5..e441acc6c584 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
| @@ -27,11 +27,11 @@ struct btrfs_transaction { | |||
| 27 | * total writers in this transaction, it must be zero before the | 27 | * total writers in this transaction, it must be zero before the |
| 28 | * transaction can end | 28 | * transaction can end |
| 29 | */ | 29 | */ |
| 30 | unsigned long num_writers; | 30 | atomic_t num_writers; |
| 31 | 31 | ||
| 32 | unsigned long num_joined; | 32 | unsigned long num_joined; |
| 33 | int in_commit; | 33 | int in_commit; |
| 34 | int use_count; | 34 | atomic_t use_count; |
| 35 | int commit_done; | 35 | int commit_done; |
| 36 | int blocked; | 36 | int blocked; |
| 37 | struct list_head list; | 37 | struct list_head list; |
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index a5303b871b13..cfd660550ded 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c | |||
| @@ -180,11 +180,10 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
| 180 | struct btrfs_path *path; | 180 | struct btrfs_path *path; |
| 181 | struct extent_buffer *leaf; | 181 | struct extent_buffer *leaf; |
| 182 | struct btrfs_dir_item *di; | 182 | struct btrfs_dir_item *di; |
| 183 | int ret = 0, slot, advance; | 183 | int ret = 0, slot; |
| 184 | size_t total_size = 0, size_left = size; | 184 | size_t total_size = 0, size_left = size; |
| 185 | unsigned long name_ptr; | 185 | unsigned long name_ptr; |
| 186 | size_t name_len; | 186 | size_t name_len; |
| 187 | u32 nritems; | ||
| 188 | 187 | ||
| 189 | /* | 188 | /* |
| 190 | * ok we want all objects associated with this id. | 189 | * ok we want all objects associated with this id. |
| @@ -204,34 +203,24 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
| 204 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 203 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
| 205 | if (ret < 0) | 204 | if (ret < 0) |
| 206 | goto err; | 205 | goto err; |
| 207 | advance = 0; | 206 | |
| 208 | while (1) { | 207 | while (1) { |
| 209 | leaf = path->nodes[0]; | 208 | leaf = path->nodes[0]; |
| 210 | nritems = btrfs_header_nritems(leaf); | ||
| 211 | slot = path->slots[0]; | 209 | slot = path->slots[0]; |
| 212 | 210 | ||
| 213 | /* this is where we start walking through the path */ | 211 | /* this is where we start walking through the path */ |
| 214 | if (advance || slot >= nritems) { | 212 | if (slot >= btrfs_header_nritems(leaf)) { |
| 215 | /* | 213 | /* |
| 216 | * if we've reached the last slot in this leaf we need | 214 | * if we've reached the last slot in this leaf we need |
| 217 | * to go to the next leaf and reset everything | 215 | * to go to the next leaf and reset everything |
| 218 | */ | 216 | */ |
| 219 | if (slot >= nritems-1) { | 217 | ret = btrfs_next_leaf(root, path); |
| 220 | ret = btrfs_next_leaf(root, path); | 218 | if (ret < 0) |
| 221 | if (ret) | 219 | goto err; |
| 222 | break; | 220 | else if (ret > 0) |
| 223 | leaf = path->nodes[0]; | 221 | break; |
| 224 | nritems = btrfs_header_nritems(leaf); | 222 | continue; |
| 225 | slot = path->slots[0]; | ||
| 226 | } else { | ||
| 227 | /* | ||
| 228 | * just walking through the slots on this leaf | ||
| 229 | */ | ||
| 230 | slot++; | ||
| 231 | path->slots[0]++; | ||
| 232 | } | ||
| 233 | } | 223 | } |
| 234 | advance = 1; | ||
| 235 | 224 | ||
| 236 | btrfs_item_key_to_cpu(leaf, &found_key, slot); | 225 | btrfs_item_key_to_cpu(leaf, &found_key, slot); |
| 237 | 226 | ||
| @@ -250,7 +239,7 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
| 250 | 239 | ||
| 251 | /* we are just looking for how big our buffer needs to be */ | 240 | /* we are just looking for how big our buffer needs to be */ |
| 252 | if (!size) | 241 | if (!size) |
| 253 | continue; | 242 | goto next; |
| 254 | 243 | ||
| 255 | if (!buffer || (name_len + 1) > size_left) { | 244 | if (!buffer || (name_len + 1) > size_left) { |
| 256 | ret = -ERANGE; | 245 | ret = -ERANGE; |
| @@ -263,6 +252,8 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
| 263 | 252 | ||
| 264 | size_left -= name_len + 1; | 253 | size_left -= name_len + 1; |
| 265 | buffer += name_len + 1; | 254 | buffer += name_len + 1; |
| 255 | next: | ||
| 256 | path->slots[0]++; | ||
| 266 | } | 257 | } |
| 267 | ret = total_size; | 258 | ret = total_size; |
| 268 | 259 | ||
