diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2010-01-25 04:00:31 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2010-01-25 04:00:31 -0500 |
commit | 5f634d064c709ea02c3cdaa850a08323a4a4bf28 (patch) | |
tree | 3f81e9c56cd8348b7bb94f1d54efff696374c929 /fs/ext4/extents.c | |
parent | 1db913823c0f8360fccbd24ca67eb073966a5ffd (diff) |
ext4: Fix quota accounting error with fallocate
When we fallocate a region of the file which we had recently written,
and which is still in the page cache marked as delayed allocated blocks
we need to make sure we don't do the quota update on writepage path.
This is because the needed quota updated would have already be done
by fallocate.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r-- | fs/ext4/extents.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 7d7b74e94687..3b6ff72026f0 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -3132,7 +3132,19 @@ out: | |||
3132 | unmap_underlying_metadata_blocks(inode->i_sb->s_bdev, | 3132 | unmap_underlying_metadata_blocks(inode->i_sb->s_bdev, |
3133 | newblock + max_blocks, | 3133 | newblock + max_blocks, |
3134 | allocated - max_blocks); | 3134 | allocated - max_blocks); |
3135 | allocated = max_blocks; | ||
3135 | } | 3136 | } |
3137 | |||
3138 | /* | ||
3139 | * If we have done fallocate with the offset that is already | ||
3140 | * delayed allocated, we would have block reservation | ||
3141 | * and quota reservation done in the delayed write path. | ||
3142 | * But fallocate would have already updated quota and block | ||
3143 | * count for this offset. So cancel these reservation | ||
3144 | */ | ||
3145 | if (flags & EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE) | ||
3146 | ext4_da_update_reserve_space(inode, allocated, 0); | ||
3147 | |||
3136 | map_out: | 3148 | map_out: |
3137 | set_buffer_mapped(bh_result); | 3149 | set_buffer_mapped(bh_result); |
3138 | out1: | 3150 | out1: |
@@ -3368,9 +3380,18 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
3368 | /* previous routine could use block we allocated */ | 3380 | /* previous routine could use block we allocated */ |
3369 | newblock = ext_pblock(&newex); | 3381 | newblock = ext_pblock(&newex); |
3370 | allocated = ext4_ext_get_actual_len(&newex); | 3382 | allocated = ext4_ext_get_actual_len(&newex); |
3383 | if (allocated > max_blocks) | ||
3384 | allocated = max_blocks; | ||
3371 | set_buffer_new(bh_result); | 3385 | set_buffer_new(bh_result); |
3372 | 3386 | ||
3373 | /* | 3387 | /* |
3388 | * Update reserved blocks/metadata blocks after successful | ||
3389 | * block allocation which had been deferred till now. | ||
3390 | */ | ||
3391 | if (flags & EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE) | ||
3392 | ext4_da_update_reserve_space(inode, allocated, 1); | ||
3393 | |||
3394 | /* | ||
3374 | * Cache the extent and update transaction to commit on fdatasync only | 3395 | * Cache the extent and update transaction to commit on fdatasync only |
3375 | * when it is _not_ an uninitialized extent. | 3396 | * when it is _not_ an uninitialized extent. |
3376 | */ | 3397 | */ |