aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/ext4.h2
-rw-r--r--fs/ext4/extents.c21
-rw-r--r--fs/ext4/inode.c44
3 files changed, 54 insertions, 13 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index af7b62699ea9..b98de17e542a 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1443,6 +1443,8 @@ extern int ext4_block_truncate_page(handle_t *handle,
1443extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); 1443extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
1444extern qsize_t *ext4_get_reserved_space(struct inode *inode); 1444extern qsize_t *ext4_get_reserved_space(struct inode *inode);
1445extern int flush_aio_dio_completed_IO(struct inode *inode); 1445extern int flush_aio_dio_completed_IO(struct inode *inode);
1446extern void ext4_da_update_reserve_space(struct inode *inode,
1447 int used, int quota_claim);
1446/* ioctl.c */ 1448/* ioctl.c */
1447extern long ext4_ioctl(struct file *, unsigned int, unsigned long); 1449extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
1448extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long); 1450extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
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
3136map_out: 3148map_out:
3137 set_buffer_mapped(bh_result); 3149 set_buffer_mapped(bh_result);
3138out1: 3150out1:
@@ -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 */
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 60b3a19e9927..c955f6490b78 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1053,11 +1053,12 @@ static int ext4_calc_metadata_amount(struct inode *inode, sector_t lblock)
1053 * Called with i_data_sem down, which is important since we can call 1053 * Called with i_data_sem down, which is important since we can call
1054 * ext4_discard_preallocations() from here. 1054 * ext4_discard_preallocations() from here.
1055 */ 1055 */
1056static void ext4_da_update_reserve_space(struct inode *inode, int used) 1056void ext4_da_update_reserve_space(struct inode *inode,
1057 int used, int quota_claim)
1057{ 1058{
1058 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 1059 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
1059 struct ext4_inode_info *ei = EXT4_I(inode); 1060 struct ext4_inode_info *ei = EXT4_I(inode);
1060 int mdb_free = 0; 1061 int mdb_free = 0, allocated_meta_blocks = 0;
1061 1062
1062 spin_lock(&ei->i_block_reservation_lock); 1063 spin_lock(&ei->i_block_reservation_lock);
1063 if (unlikely(used > ei->i_reserved_data_blocks)) { 1064 if (unlikely(used > ei->i_reserved_data_blocks)) {
@@ -1073,6 +1074,7 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used)
1073 ei->i_reserved_data_blocks -= used; 1074 ei->i_reserved_data_blocks -= used;
1074 used += ei->i_allocated_meta_blocks; 1075 used += ei->i_allocated_meta_blocks;
1075 ei->i_reserved_meta_blocks -= ei->i_allocated_meta_blocks; 1076 ei->i_reserved_meta_blocks -= ei->i_allocated_meta_blocks;
1077 allocated_meta_blocks = ei->i_allocated_meta_blocks;
1076 ei->i_allocated_meta_blocks = 0; 1078 ei->i_allocated_meta_blocks = 0;
1077 percpu_counter_sub(&sbi->s_dirtyblocks_counter, used); 1079 percpu_counter_sub(&sbi->s_dirtyblocks_counter, used);
1078 1080
@@ -1090,9 +1092,23 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used)
1090 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); 1092 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1091 1093
1092 /* Update quota subsystem */ 1094 /* Update quota subsystem */
1093 vfs_dq_claim_block(inode, used); 1095 if (quota_claim) {
1094 if (mdb_free) 1096 vfs_dq_claim_block(inode, used);
1095 vfs_dq_release_reservation_block(inode, mdb_free); 1097 if (mdb_free)
1098 vfs_dq_release_reservation_block(inode, mdb_free);
1099 } else {
1100 /*
1101 * We did fallocate with an offset that is already delayed
1102 * allocated. So on delayed allocated writeback we should
1103 * not update the quota for allocated blocks. But then
1104 * converting an fallocate region to initialized region would
1105 * have caused a metadata allocation. So claim quota for
1106 * that
1107 */
1108 if (allocated_meta_blocks)
1109 vfs_dq_claim_block(inode, allocated_meta_blocks);
1110 vfs_dq_release_reservation_block(inode, mdb_free + used);
1111 }
1096 1112
1097 /* 1113 /*
1098 * If we have done all the pending block allocations and if 1114 * If we have done all the pending block allocations and if
@@ -1292,18 +1308,20 @@ int ext4_get_blocks(handle_t *handle, struct inode *inode, sector_t block,
1292 */ 1308 */
1293 EXT4_I(inode)->i_state &= ~EXT4_STATE_EXT_MIGRATE; 1309 EXT4_I(inode)->i_state &= ~EXT4_STATE_EXT_MIGRATE;
1294 } 1310 }
1295 }
1296 1311
1312 /*
1313 * Update reserved blocks/metadata blocks after successful
1314 * block allocation which had been deferred till now. We don't
1315 * support fallocate for non extent files. So we can update
1316 * reserve space here.
1317 */
1318 if ((retval > 0) &&
1319 (flags & EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE))
1320 ext4_da_update_reserve_space(inode, retval, 1);
1321 }
1297 if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) 1322 if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)
1298 EXT4_I(inode)->i_delalloc_reserved_flag = 0; 1323 EXT4_I(inode)->i_delalloc_reserved_flag = 0;
1299 1324
1300 /*
1301 * Update reserved blocks/metadata blocks after successful
1302 * block allocation which had been deferred till now.
1303 */
1304 if ((retval > 0) && (flags & EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE))
1305 ext4_da_update_reserve_space(inode, retval);
1306
1307 up_write((&EXT4_I(inode)->i_data_sem)); 1325 up_write((&EXT4_I(inode)->i_data_sem));
1308 if (retval > 0 && buffer_mapped(bh)) { 1326 if (retval > 0 && buffer_mapped(bh)) {
1309 int ret = check_block_validity(inode, "file system " 1327 int ret = check_block_validity(inode, "file system "