diff options
Diffstat (limited to 'fs/btrfs/inode.c')
| -rw-r--r-- | fs/btrfs/inode.c | 62 | 
1 files changed, 16 insertions, 46 deletions
| diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3cee77ae03c8..7d4f948bc22a 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -102,34 +102,6 @@ static int btrfs_init_inode_security(struct inode *inode, struct inode *dir) | |||
| 102 | } | 102 | } | 
| 103 | 103 | ||
| 104 | /* | 104 | /* | 
| 105 | * a very lame attempt at stopping writes when the FS is 85% full. There | ||
| 106 | * are countless ways this is incorrect, but it is better than nothing. | ||
| 107 | */ | ||
| 108 | int btrfs_check_free_space(struct btrfs_root *root, u64 num_required, | ||
| 109 | int for_del) | ||
| 110 | { | ||
| 111 | u64 total; | ||
| 112 | u64 used; | ||
| 113 | u64 thresh; | ||
| 114 | int ret = 0; | ||
| 115 | |||
| 116 | spin_lock(&root->fs_info->delalloc_lock); | ||
| 117 | total = btrfs_super_total_bytes(&root->fs_info->super_copy); | ||
| 118 | used = btrfs_super_bytes_used(&root->fs_info->super_copy); | ||
| 119 | if (for_del) | ||
| 120 | thresh = total * 90; | ||
| 121 | else | ||
| 122 | thresh = total * 85; | ||
| 123 | |||
| 124 | do_div(thresh, 100); | ||
| 125 | |||
| 126 | if (used + root->fs_info->delalloc_bytes + num_required > thresh) | ||
| 127 | ret = -ENOSPC; | ||
| 128 | spin_unlock(&root->fs_info->delalloc_lock); | ||
| 129 | return ret; | ||
| 130 | } | ||
| 131 | |||
| 132 | /* | ||
| 133 | * this does all the hard work for inserting an inline extent into | 105 | * this does all the hard work for inserting an inline extent into | 
| 134 | * the btree. The caller should have done a btrfs_drop_extents so that | 106 | * the btree. The caller should have done a btrfs_drop_extents so that | 
| 135 | * no overlapping inline items exist in the btree | 107 | * no overlapping inline items exist in the btree | 
| @@ -1190,6 +1162,7 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end, | |||
| 1190 | */ | 1162 | */ | 
| 1191 | if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { | 1163 | if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { | 
| 1192 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1164 | struct btrfs_root *root = BTRFS_I(inode)->root; | 
| 1165 | btrfs_delalloc_reserve_space(root, inode, end - start + 1); | ||
| 1193 | spin_lock(&root->fs_info->delalloc_lock); | 1166 | spin_lock(&root->fs_info->delalloc_lock); | 
| 1194 | BTRFS_I(inode)->delalloc_bytes += end - start + 1; | 1167 | BTRFS_I(inode)->delalloc_bytes += end - start + 1; | 
| 1195 | root->fs_info->delalloc_bytes += end - start + 1; | 1168 | root->fs_info->delalloc_bytes += end - start + 1; | 
| @@ -1223,9 +1196,12 @@ static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end, | |||
| 1223 | (unsigned long long)end - start + 1, | 1196 | (unsigned long long)end - start + 1, | 
| 1224 | (unsigned long long) | 1197 | (unsigned long long) | 
| 1225 | root->fs_info->delalloc_bytes); | 1198 | root->fs_info->delalloc_bytes); | 
| 1199 | btrfs_delalloc_free_space(root, inode, (u64)-1); | ||
| 1226 | root->fs_info->delalloc_bytes = 0; | 1200 | root->fs_info->delalloc_bytes = 0; | 
| 1227 | BTRFS_I(inode)->delalloc_bytes = 0; | 1201 | BTRFS_I(inode)->delalloc_bytes = 0; | 
| 1228 | } else { | 1202 | } else { | 
| 1203 | btrfs_delalloc_free_space(root, inode, | ||
| 1204 | end - start + 1); | ||
| 1229 | root->fs_info->delalloc_bytes -= end - start + 1; | 1205 | root->fs_info->delalloc_bytes -= end - start + 1; | 
| 1230 | BTRFS_I(inode)->delalloc_bytes -= end - start + 1; | 1206 | BTRFS_I(inode)->delalloc_bytes -= end - start + 1; | 
| 1231 | } | 1207 | } | 
| @@ -2245,10 +2221,6 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 2245 | 2221 | ||
| 2246 | root = BTRFS_I(dir)->root; | 2222 | root = BTRFS_I(dir)->root; | 
| 2247 | 2223 | ||
| 2248 | ret = btrfs_check_free_space(root, 1, 1); | ||
| 2249 | if (ret) | ||
| 2250 | goto fail; | ||
| 2251 | |||
| 2252 | trans = btrfs_start_transaction(root, 1); | 2224 | trans = btrfs_start_transaction(root, 1); | 
| 2253 | 2225 | ||
| 2254 | btrfs_set_trans_block_group(trans, dir); | 2226 | btrfs_set_trans_block_group(trans, dir); | 
| @@ -2261,7 +2233,6 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 2261 | nr = trans->blocks_used; | 2233 | nr = trans->blocks_used; | 
| 2262 | 2234 | ||
| 2263 | btrfs_end_transaction_throttle(trans, root); | 2235 | btrfs_end_transaction_throttle(trans, root); | 
| 2264 | fail: | ||
| 2265 | btrfs_btree_balance_dirty(root, nr); | 2236 | btrfs_btree_balance_dirty(root, nr); | 
| 2266 | return ret; | 2237 | return ret; | 
| 2267 | } | 2238 | } | 
| @@ -2284,10 +2255,6 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 2284 | return -ENOTEMPTY; | 2255 | return -ENOTEMPTY; | 
| 2285 | } | 2256 | } | 
| 2286 | 2257 | ||
| 2287 | ret = btrfs_check_free_space(root, 1, 1); | ||
| 2288 | if (ret) | ||
| 2289 | goto fail; | ||
| 2290 | |||
| 2291 | trans = btrfs_start_transaction(root, 1); | 2258 | trans = btrfs_start_transaction(root, 1); | 
| 2292 | btrfs_set_trans_block_group(trans, dir); | 2259 | btrfs_set_trans_block_group(trans, dir); | 
| 2293 | 2260 | ||
| @@ -2304,7 +2271,6 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 2304 | fail_trans: | 2271 | fail_trans: | 
| 2305 | nr = trans->blocks_used; | 2272 | nr = trans->blocks_used; | 
| 2306 | ret = btrfs_end_transaction_throttle(trans, root); | 2273 | ret = btrfs_end_transaction_throttle(trans, root); | 
| 2307 | fail: | ||
| 2308 | btrfs_btree_balance_dirty(root, nr); | 2274 | btrfs_btree_balance_dirty(root, nr); | 
| 2309 | 2275 | ||
| 2310 | if (ret && !err) | 2276 | if (ret && !err) | 
| @@ -2818,7 +2784,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) | |||
| 2818 | if (size <= hole_start) | 2784 | if (size <= hole_start) | 
| 2819 | return 0; | 2785 | return 0; | 
| 2820 | 2786 | ||
| 2821 | err = btrfs_check_free_space(root, 1, 0); | 2787 | err = btrfs_check_metadata_free_space(root); | 
| 2822 | if (err) | 2788 | if (err) | 
| 2823 | return err; | 2789 | return err; | 
| 2824 | 2790 | ||
| @@ -3014,6 +2980,7 @@ static noinline void init_btrfs_i(struct inode *inode) | |||
| 3014 | bi->last_trans = 0; | 2980 | bi->last_trans = 0; | 
| 3015 | bi->logged_trans = 0; | 2981 | bi->logged_trans = 0; | 
| 3016 | bi->delalloc_bytes = 0; | 2982 | bi->delalloc_bytes = 0; | 
| 2983 | bi->reserved_bytes = 0; | ||
| 3017 | bi->disk_i_size = 0; | 2984 | bi->disk_i_size = 0; | 
| 3018 | bi->flags = 0; | 2985 | bi->flags = 0; | 
| 3019 | bi->index_cnt = (u64)-1; | 2986 | bi->index_cnt = (u64)-1; | 
| @@ -3035,6 +3002,7 @@ static int btrfs_init_locked_inode(struct inode *inode, void *p) | |||
| 3035 | inode->i_ino = args->ino; | 3002 | inode->i_ino = args->ino; | 
| 3036 | init_btrfs_i(inode); | 3003 | init_btrfs_i(inode); | 
| 3037 | BTRFS_I(inode)->root = args->root; | 3004 | BTRFS_I(inode)->root = args->root; | 
| 3005 | btrfs_set_inode_space_info(args->root, inode); | ||
| 3038 | return 0; | 3006 | return 0; | 
| 3039 | } | 3007 | } | 
| 3040 | 3008 | ||
| @@ -3455,6 +3423,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
| 3455 | BTRFS_I(inode)->index_cnt = 2; | 3423 | BTRFS_I(inode)->index_cnt = 2; | 
| 3456 | BTRFS_I(inode)->root = root; | 3424 | BTRFS_I(inode)->root = root; | 
| 3457 | BTRFS_I(inode)->generation = trans->transid; | 3425 | BTRFS_I(inode)->generation = trans->transid; | 
| 3426 | btrfs_set_inode_space_info(root, inode); | ||
| 3458 | 3427 | ||
| 3459 | if (mode & S_IFDIR) | 3428 | if (mode & S_IFDIR) | 
| 3460 | owner = 0; | 3429 | owner = 0; | 
| @@ -3602,7 +3571,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
| 3602 | if (!new_valid_dev(rdev)) | 3571 | if (!new_valid_dev(rdev)) | 
| 3603 | return -EINVAL; | 3572 | return -EINVAL; | 
| 3604 | 3573 | ||
| 3605 | err = btrfs_check_free_space(root, 1, 0); | 3574 | err = btrfs_check_metadata_free_space(root); | 
| 3606 | if (err) | 3575 | if (err) | 
| 3607 | goto fail; | 3576 | goto fail; | 
| 3608 | 3577 | ||
| @@ -3665,7 +3634,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
| 3665 | u64 objectid; | 3634 | u64 objectid; | 
| 3666 | u64 index = 0; | 3635 | u64 index = 0; | 
| 3667 | 3636 | ||
| 3668 | err = btrfs_check_free_space(root, 1, 0); | 3637 | err = btrfs_check_metadata_free_space(root); | 
| 3669 | if (err) | 3638 | if (err) | 
| 3670 | goto fail; | 3639 | goto fail; | 
| 3671 | trans = btrfs_start_transaction(root, 1); | 3640 | trans = btrfs_start_transaction(root, 1); | 
| @@ -3733,7 +3702,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 3733 | return -ENOENT; | 3702 | return -ENOENT; | 
| 3734 | 3703 | ||
| 3735 | btrfs_inc_nlink(inode); | 3704 | btrfs_inc_nlink(inode); | 
| 3736 | err = btrfs_check_free_space(root, 1, 0); | 3705 | err = btrfs_check_metadata_free_space(root); | 
| 3737 | if (err) | 3706 | if (err) | 
| 3738 | goto fail; | 3707 | goto fail; | 
| 3739 | err = btrfs_set_inode_index(dir, &index); | 3708 | err = btrfs_set_inode_index(dir, &index); | 
| @@ -3779,7 +3748,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 3779 | u64 index = 0; | 3748 | u64 index = 0; | 
| 3780 | unsigned long nr = 1; | 3749 | unsigned long nr = 1; | 
| 3781 | 3750 | ||
| 3782 | err = btrfs_check_free_space(root, 1, 0); | 3751 | err = btrfs_check_metadata_free_space(root); | 
| 3783 | if (err) | 3752 | if (err) | 
| 3784 | goto out_unlock; | 3753 | goto out_unlock; | 
| 3785 | 3754 | ||
| @@ -4336,7 +4305,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page) | |||
| 4336 | u64 page_start; | 4305 | u64 page_start; | 
| 4337 | u64 page_end; | 4306 | u64 page_end; | 
| 4338 | 4307 | ||
| 4339 | ret = btrfs_check_free_space(root, PAGE_CACHE_SIZE, 0); | 4308 | ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE); | 
| 4340 | if (ret) | 4309 | if (ret) | 
| 4341 | goto out; | 4310 | goto out; | 
| 4342 | 4311 | ||
| @@ -4349,6 +4318,7 @@ again: | |||
| 4349 | 4318 | ||
| 4350 | if ((page->mapping != inode->i_mapping) || | 4319 | if ((page->mapping != inode->i_mapping) || | 
| 4351 | (page_start >= size)) { | 4320 | (page_start >= size)) { | 
| 4321 | btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE); | ||
| 4352 | /* page got truncated out from underneath us */ | 4322 | /* page got truncated out from underneath us */ | 
| 4353 | goto out_unlock; | 4323 | goto out_unlock; | 
| 4354 | } | 4324 | } | 
| @@ -4631,7 +4601,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 4631 | if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) | 4601 | if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) | 
| 4632 | return -EXDEV; | 4602 | return -EXDEV; | 
| 4633 | 4603 | ||
| 4634 | ret = btrfs_check_free_space(root, 1, 0); | 4604 | ret = btrfs_check_metadata_free_space(root); | 
| 4635 | if (ret) | 4605 | if (ret) | 
| 4636 | goto out_unlock; | 4606 | goto out_unlock; | 
| 4637 | 4607 | ||
| @@ -4749,7 +4719,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 4749 | if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(root)) | 4719 | if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(root)) | 
| 4750 | return -ENAMETOOLONG; | 4720 | return -ENAMETOOLONG; | 
| 4751 | 4721 | ||
| 4752 | err = btrfs_check_free_space(root, 1, 0); | 4722 | err = btrfs_check_metadata_free_space(root); | 
| 4753 | if (err) | 4723 | if (err) | 
| 4754 | goto out_fail; | 4724 | goto out_fail; | 
| 4755 | 4725 | ||
