diff options
author | Wang Shilong <wangsl-fnst@cn.fujitsu.com> | 2013-03-19 06:57:14 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-03-21 19:24:32 -0400 |
commit | 6113077cd319e747875ec71227d2b5cb54e08c76 (patch) | |
tree | dca81060451d10a7c2904ad7802d3cadbe4b65a5 | |
parent | 835d974fabfa9bff4d173ad03c054ac2f673263f (diff) |
Btrfs: fix missing qgroup reservation before fallocating
Steps to reproduce:
mkfs.btrfs <disk>
mount <disk> <mnt>
btrfs quota enable <mnt>
btrfs sub create <mnt>/subv
btrfs qgroup limit 10M <mnt>/subv
fallocate --length 20M <mnt>/subv/data
For the above example, fallocating will return successfully which
is not expected, we try to fix it by doing qgroup reservation before
fallocating.
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Reviewed-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
-rw-r--r-- | fs/btrfs/file.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 7bdb47faa12e..1be25b92d63c 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -2142,6 +2142,7 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
2142 | { | 2142 | { |
2143 | struct inode *inode = file->f_path.dentry->d_inode; | 2143 | struct inode *inode = file->f_path.dentry->d_inode; |
2144 | struct extent_state *cached_state = NULL; | 2144 | struct extent_state *cached_state = NULL; |
2145 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
2145 | u64 cur_offset; | 2146 | u64 cur_offset; |
2146 | u64 last_byte; | 2147 | u64 last_byte; |
2147 | u64 alloc_start; | 2148 | u64 alloc_start; |
@@ -2169,6 +2170,11 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
2169 | ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start); | 2170 | ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start); |
2170 | if (ret) | 2171 | if (ret) |
2171 | return ret; | 2172 | return ret; |
2173 | if (root->fs_info->quota_enabled) { | ||
2174 | ret = btrfs_qgroup_reserve(root, alloc_end - alloc_start); | ||
2175 | if (ret) | ||
2176 | goto out_reserve_fail; | ||
2177 | } | ||
2172 | 2178 | ||
2173 | /* | 2179 | /* |
2174 | * wait for ordered IO before we have any locks. We'll loop again | 2180 | * wait for ordered IO before we have any locks. We'll loop again |
@@ -2272,6 +2278,9 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
2272 | &cached_state, GFP_NOFS); | 2278 | &cached_state, GFP_NOFS); |
2273 | out: | 2279 | out: |
2274 | mutex_unlock(&inode->i_mutex); | 2280 | mutex_unlock(&inode->i_mutex); |
2281 | if (root->fs_info->quota_enabled) | ||
2282 | btrfs_qgroup_free(root, alloc_end - alloc_start); | ||
2283 | out_reserve_fail: | ||
2275 | /* Let go of our reservation. */ | 2284 | /* Let go of our reservation. */ |
2276 | btrfs_free_reserved_data_space(inode, alloc_end - alloc_start); | 2285 | btrfs_free_reserved_data_space(inode, alloc_end - alloc_start); |
2277 | return ret; | 2286 | return ret; |