diff options
Diffstat (limited to 'fs/btrfs/inode.c')
| -rw-r--r-- | fs/btrfs/inode.c | 60 |
1 files changed, 5 insertions, 55 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 02bb099845fd..2bfdc641d4e3 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include <linux/xattr.h> | 36 | #include <linux/xattr.h> |
| 37 | #include <linux/posix_acl.h> | 37 | #include <linux/posix_acl.h> |
| 38 | #include <linux/falloc.h> | 38 | #include <linux/falloc.h> |
| 39 | #include <linux/slab.h> | ||
| 39 | #include "compat.h" | 40 | #include "compat.h" |
| 40 | #include "ctree.h" | 41 | #include "ctree.h" |
| 41 | #include "disk-io.h" | 42 | #include "disk-io.h" |
| @@ -796,7 +797,7 @@ static noinline int cow_file_range(struct inode *inode, | |||
| 796 | while (disk_num_bytes > 0) { | 797 | while (disk_num_bytes > 0) { |
| 797 | unsigned long op; | 798 | unsigned long op; |
| 798 | 799 | ||
| 799 | cur_alloc_size = min(disk_num_bytes, root->fs_info->max_extent); | 800 | cur_alloc_size = disk_num_bytes; |
| 800 | ret = btrfs_reserve_extent(trans, root, cur_alloc_size, | 801 | ret = btrfs_reserve_extent(trans, root, cur_alloc_size, |
| 801 | root->sectorsize, 0, alloc_hint, | 802 | root->sectorsize, 0, alloc_hint, |
| 802 | (u64)-1, &ins, 1); | 803 | (u64)-1, &ins, 1); |
| @@ -1227,30 +1228,9 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page, | |||
| 1227 | static int btrfs_split_extent_hook(struct inode *inode, | 1228 | static int btrfs_split_extent_hook(struct inode *inode, |
| 1228 | struct extent_state *orig, u64 split) | 1229 | struct extent_state *orig, u64 split) |
| 1229 | { | 1230 | { |
| 1230 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
| 1231 | u64 size; | ||
| 1232 | |||
| 1233 | if (!(orig->state & EXTENT_DELALLOC)) | 1231 | if (!(orig->state & EXTENT_DELALLOC)) |
| 1234 | return 0; | 1232 | return 0; |
| 1235 | 1233 | ||
| 1236 | size = orig->end - orig->start + 1; | ||
| 1237 | if (size > root->fs_info->max_extent) { | ||
| 1238 | u64 num_extents; | ||
| 1239 | u64 new_size; | ||
| 1240 | |||
| 1241 | new_size = orig->end - split + 1; | ||
| 1242 | num_extents = div64_u64(size + root->fs_info->max_extent - 1, | ||
| 1243 | root->fs_info->max_extent); | ||
| 1244 | |||
| 1245 | /* | ||
| 1246 | * if we break a large extent up then leave oustanding_extents | ||
| 1247 | * be, since we've already accounted for the large extent. | ||
| 1248 | */ | ||
| 1249 | if (div64_u64(new_size + root->fs_info->max_extent - 1, | ||
| 1250 | root->fs_info->max_extent) < num_extents) | ||
| 1251 | return 0; | ||
| 1252 | } | ||
| 1253 | |||
| 1254 | spin_lock(&BTRFS_I(inode)->accounting_lock); | 1234 | spin_lock(&BTRFS_I(inode)->accounting_lock); |
| 1255 | BTRFS_I(inode)->outstanding_extents++; | 1235 | BTRFS_I(inode)->outstanding_extents++; |
| 1256 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | 1236 | spin_unlock(&BTRFS_I(inode)->accounting_lock); |
| @@ -1268,38 +1248,10 @@ static int btrfs_merge_extent_hook(struct inode *inode, | |||
| 1268 | struct extent_state *new, | 1248 | struct extent_state *new, |
| 1269 | struct extent_state *other) | 1249 | struct extent_state *other) |
| 1270 | { | 1250 | { |
| 1271 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
| 1272 | u64 new_size, old_size; | ||
| 1273 | u64 num_extents; | ||
| 1274 | |||
| 1275 | /* not delalloc, ignore it */ | 1251 | /* not delalloc, ignore it */ |
| 1276 | if (!(other->state & EXTENT_DELALLOC)) | 1252 | if (!(other->state & EXTENT_DELALLOC)) |
| 1277 | return 0; | 1253 | return 0; |
| 1278 | 1254 | ||
| 1279 | old_size = other->end - other->start + 1; | ||
| 1280 | if (new->start < other->start) | ||
| 1281 | new_size = other->end - new->start + 1; | ||
| 1282 | else | ||
| 1283 | new_size = new->end - other->start + 1; | ||
| 1284 | |||
| 1285 | /* we're not bigger than the max, unreserve the space and go */ | ||
| 1286 | if (new_size <= root->fs_info->max_extent) { | ||
| 1287 | spin_lock(&BTRFS_I(inode)->accounting_lock); | ||
| 1288 | BTRFS_I(inode)->outstanding_extents--; | ||
| 1289 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | ||
| 1290 | return 0; | ||
| 1291 | } | ||
| 1292 | |||
| 1293 | /* | ||
| 1294 | * If we grew by another max_extent, just return, we want to keep that | ||
| 1295 | * reserved amount. | ||
| 1296 | */ | ||
| 1297 | num_extents = div64_u64(old_size + root->fs_info->max_extent - 1, | ||
| 1298 | root->fs_info->max_extent); | ||
| 1299 | if (div64_u64(new_size + root->fs_info->max_extent - 1, | ||
| 1300 | root->fs_info->max_extent) > num_extents) | ||
| 1301 | return 0; | ||
| 1302 | |||
| 1303 | spin_lock(&BTRFS_I(inode)->accounting_lock); | 1255 | spin_lock(&BTRFS_I(inode)->accounting_lock); |
| 1304 | BTRFS_I(inode)->outstanding_extents--; | 1256 | BTRFS_I(inode)->outstanding_extents--; |
| 1305 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | 1257 | spin_unlock(&BTRFS_I(inode)->accounting_lock); |
| @@ -1328,6 +1280,7 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end, | |||
| 1328 | BTRFS_I(inode)->outstanding_extents++; | 1280 | BTRFS_I(inode)->outstanding_extents++; |
| 1329 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | 1281 | spin_unlock(&BTRFS_I(inode)->accounting_lock); |
| 1330 | btrfs_delalloc_reserve_space(root, inode, end - start + 1); | 1282 | btrfs_delalloc_reserve_space(root, inode, end - start + 1); |
| 1283 | |||
| 1331 | spin_lock(&root->fs_info->delalloc_lock); | 1284 | spin_lock(&root->fs_info->delalloc_lock); |
| 1332 | BTRFS_I(inode)->delalloc_bytes += end - start + 1; | 1285 | BTRFS_I(inode)->delalloc_bytes += end - start + 1; |
| 1333 | root->fs_info->delalloc_bytes += end - start + 1; | 1286 | root->fs_info->delalloc_bytes += end - start + 1; |
| @@ -1356,6 +1309,7 @@ static int btrfs_clear_bit_hook(struct inode *inode, | |||
| 1356 | 1309 | ||
| 1357 | if (bits & EXTENT_DO_ACCOUNTING) { | 1310 | if (bits & EXTENT_DO_ACCOUNTING) { |
| 1358 | spin_lock(&BTRFS_I(inode)->accounting_lock); | 1311 | spin_lock(&BTRFS_I(inode)->accounting_lock); |
| 1312 | WARN_ON(!BTRFS_I(inode)->outstanding_extents); | ||
| 1359 | BTRFS_I(inode)->outstanding_extents--; | 1313 | BTRFS_I(inode)->outstanding_extents--; |
| 1360 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | 1314 | spin_unlock(&BTRFS_I(inode)->accounting_lock); |
| 1361 | btrfs_unreserve_metadata_for_delalloc(root, inode, 1); | 1315 | btrfs_unreserve_metadata_for_delalloc(root, inode, 1); |
| @@ -5384,7 +5338,6 @@ free: | |||
| 5384 | void btrfs_drop_inode(struct inode *inode) | 5338 | void btrfs_drop_inode(struct inode *inode) |
| 5385 | { | 5339 | { |
| 5386 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5340 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 5387 | |||
| 5388 | if (inode->i_nlink > 0 && btrfs_root_refs(&root->root_item) == 0) | 5341 | if (inode->i_nlink > 0 && btrfs_root_refs(&root->root_item) == 0) |
| 5389 | generic_delete_inode(inode); | 5342 | generic_delete_inode(inode); |
| 5390 | else | 5343 | else |
| @@ -5788,18 +5741,15 @@ static int prealloc_file_range(struct inode *inode, u64 start, u64 end, | |||
| 5788 | struct btrfs_trans_handle *trans; | 5741 | struct btrfs_trans_handle *trans; |
| 5789 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5742 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 5790 | struct btrfs_key ins; | 5743 | struct btrfs_key ins; |
| 5791 | u64 alloc_size; | ||
| 5792 | u64 cur_offset = start; | 5744 | u64 cur_offset = start; |
| 5793 | u64 num_bytes = end - start; | 5745 | u64 num_bytes = end - start; |
| 5794 | int ret = 0; | 5746 | int ret = 0; |
| 5795 | u64 i_size; | 5747 | u64 i_size; |
| 5796 | 5748 | ||
| 5797 | while (num_bytes > 0) { | 5749 | while (num_bytes > 0) { |
| 5798 | alloc_size = min(num_bytes, root->fs_info->max_extent); | ||
| 5799 | |||
| 5800 | trans = btrfs_start_transaction(root, 1); | 5750 | trans = btrfs_start_transaction(root, 1); |
| 5801 | 5751 | ||
| 5802 | ret = btrfs_reserve_extent(trans, root, alloc_size, | 5752 | ret = btrfs_reserve_extent(trans, root, num_bytes, |
| 5803 | root->sectorsize, 0, alloc_hint, | 5753 | root->sectorsize, 0, alloc_hint, |
| 5804 | (u64)-1, &ins, 1); | 5754 | (u64)-1, &ins, 1); |
| 5805 | if (ret) { | 5755 | if (ret) { |
