diff options
author | Theodore Ts'o <tytso@mit.edu> | 2014-07-15 06:02:38 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2014-07-15 06:02:38 -0400 |
commit | 71d4f7d032149b935a26eb3ff85c6c837f3714e1 (patch) | |
tree | 86a356c9e02e69e609e0226435258f634620574d /fs | |
parent | d5e03cbb0c88cd1be39f2adc37d602230045964b (diff) |
ext4: remove metadata reservation checks
Commit 27dd43854227b ("ext4: introduce reserved space") reserves 2% of
the file system space to make sure metadata allocations will always
succeed. Given that, tracking the reservation of metadata blocks is
no longer necessary.
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext4/balloc.c | 1 | ||||
-rw-r--r-- | fs/ext4/ext4.h | 1 | ||||
-rw-r--r-- | fs/ext4/extents.c | 3 | ||||
-rw-r--r-- | fs/ext4/inode.c | 128 | ||||
-rw-r--r-- | fs/ext4/mballoc.c | 15 |
5 files changed, 7 insertions, 141 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index fca382037ddd..581ef40fbe90 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -639,7 +639,6 @@ ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, | |||
639 | if (!(*errp) && | 639 | if (!(*errp) && |
640 | ext4_test_inode_state(inode, EXT4_STATE_DELALLOC_RESERVED)) { | 640 | ext4_test_inode_state(inode, EXT4_STATE_DELALLOC_RESERVED)) { |
641 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); | 641 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); |
642 | EXT4_I(inode)->i_allocated_meta_blocks += ar.len; | ||
643 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); | 642 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); |
644 | dquot_alloc_block_nofail(inode, | 643 | dquot_alloc_block_nofail(inode, |
645 | EXT4_C2B(EXT4_SB(inode->i_sb), ar.len)); | 644 | EXT4_C2B(EXT4_SB(inode->i_sb), ar.len)); |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 7cc5a0e23688..d35c78c96184 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -591,7 +591,6 @@ enum { | |||
591 | #define EXT4_FREE_BLOCKS_NO_QUOT_UPDATE 0x0008 | 591 | #define EXT4_FREE_BLOCKS_NO_QUOT_UPDATE 0x0008 |
592 | #define EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER 0x0010 | 592 | #define EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER 0x0010 |
593 | #define EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER 0x0020 | 593 | #define EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER 0x0020 |
594 | #define EXT4_FREE_BLOCKS_RESERVE 0x0040 | ||
595 | 594 | ||
596 | /* | 595 | /* |
597 | * ioctl commands | 596 | * ioctl commands |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 4da228a0e6d0..b30172dd55eb 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -1808,8 +1808,7 @@ static void ext4_ext_try_to_merge_up(handle_t *handle, | |||
1808 | 1808 | ||
1809 | brelse(path[1].p_bh); | 1809 | brelse(path[1].p_bh); |
1810 | ext4_free_blocks(handle, inode, NULL, blk, 1, | 1810 | ext4_free_blocks(handle, inode, NULL, blk, 1, |
1811 | EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET | | 1811 | EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET); |
1812 | EXT4_FREE_BLOCKS_RESERVE); | ||
1813 | } | 1812 | } |
1814 | 1813 | ||
1815 | /* | 1814 | /* |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 8a064734e6eb..027ee8c40470 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -325,18 +325,6 @@ qsize_t *ext4_get_reserved_space(struct inode *inode) | |||
325 | #endif | 325 | #endif |
326 | 326 | ||
327 | /* | 327 | /* |
328 | * Calculate the number of metadata blocks need to reserve | ||
329 | * to allocate a block located at @lblock | ||
330 | */ | ||
331 | static int ext4_calc_metadata_amount(struct inode *inode, ext4_lblk_t lblock) | ||
332 | { | ||
333 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) | ||
334 | return ext4_ext_calc_metadata_amount(inode, lblock); | ||
335 | |||
336 | return ext4_ind_calc_metadata_amount(inode, lblock); | ||
337 | } | ||
338 | |||
339 | /* | ||
340 | * Called with i_data_sem down, which is important since we can call | 328 | * Called with i_data_sem down, which is important since we can call |
341 | * ext4_discard_preallocations() from here. | 329 | * ext4_discard_preallocations() from here. |
342 | */ | 330 | */ |
@@ -357,35 +345,10 @@ void ext4_da_update_reserve_space(struct inode *inode, | |||
357 | used = ei->i_reserved_data_blocks; | 345 | used = ei->i_reserved_data_blocks; |
358 | } | 346 | } |
359 | 347 | ||
360 | if (unlikely(ei->i_allocated_meta_blocks > ei->i_reserved_meta_blocks)) { | ||
361 | ext4_warning(inode->i_sb, "ino %lu, allocated %d " | ||
362 | "with only %d reserved metadata blocks " | ||
363 | "(releasing %d blocks with reserved %d data blocks)", | ||
364 | inode->i_ino, ei->i_allocated_meta_blocks, | ||
365 | ei->i_reserved_meta_blocks, used, | ||
366 | ei->i_reserved_data_blocks); | ||
367 | WARN_ON(1); | ||
368 | ei->i_allocated_meta_blocks = ei->i_reserved_meta_blocks; | ||
369 | } | ||
370 | |||
371 | /* Update per-inode reservations */ | 348 | /* Update per-inode reservations */ |
372 | ei->i_reserved_data_blocks -= used; | 349 | ei->i_reserved_data_blocks -= used; |
373 | ei->i_reserved_meta_blocks -= ei->i_allocated_meta_blocks; | 350 | percpu_counter_sub(&sbi->s_dirtyclusters_counter, used); |
374 | percpu_counter_sub(&sbi->s_dirtyclusters_counter, | ||
375 | used + ei->i_allocated_meta_blocks); | ||
376 | ei->i_allocated_meta_blocks = 0; | ||
377 | 351 | ||
378 | if (ei->i_reserved_data_blocks == 0) { | ||
379 | /* | ||
380 | * We can release all of the reserved metadata blocks | ||
381 | * only when we have written all of the delayed | ||
382 | * allocation blocks. | ||
383 | */ | ||
384 | percpu_counter_sub(&sbi->s_dirtyclusters_counter, | ||
385 | ei->i_reserved_meta_blocks); | ||
386 | ei->i_reserved_meta_blocks = 0; | ||
387 | ei->i_da_metadata_calc_len = 0; | ||
388 | } | ||
389 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); | 352 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); |
390 | 353 | ||
391 | /* Update quota subsystem for data blocks */ | 354 | /* Update quota subsystem for data blocks */ |
@@ -1222,49 +1185,6 @@ static int ext4_journalled_write_end(struct file *file, | |||
1222 | } | 1185 | } |
1223 | 1186 | ||
1224 | /* | 1187 | /* |
1225 | * Reserve a metadata for a single block located at lblock | ||
1226 | */ | ||
1227 | static int ext4_da_reserve_metadata(struct inode *inode, ext4_lblk_t lblock) | ||
1228 | { | ||
1229 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | ||
1230 | struct ext4_inode_info *ei = EXT4_I(inode); | ||
1231 | unsigned int md_needed; | ||
1232 | ext4_lblk_t save_last_lblock; | ||
1233 | int save_len; | ||
1234 | |||
1235 | /* | ||
1236 | * recalculate the amount of metadata blocks to reserve | ||
1237 | * in order to allocate nrblocks | ||
1238 | * worse case is one extent per block | ||
1239 | */ | ||
1240 | spin_lock(&ei->i_block_reservation_lock); | ||
1241 | /* | ||
1242 | * ext4_calc_metadata_amount() has side effects, which we have | ||
1243 | * to be prepared undo if we fail to claim space. | ||
1244 | */ | ||
1245 | save_len = ei->i_da_metadata_calc_len; | ||
1246 | save_last_lblock = ei->i_da_metadata_calc_last_lblock; | ||
1247 | md_needed = EXT4_NUM_B2C(sbi, | ||
1248 | ext4_calc_metadata_amount(inode, lblock)); | ||
1249 | trace_ext4_da_reserve_space(inode, md_needed); | ||
1250 | |||
1251 | /* | ||
1252 | * We do still charge estimated metadata to the sb though; | ||
1253 | * we cannot afford to run out of free blocks. | ||
1254 | */ | ||
1255 | if (ext4_claim_free_clusters(sbi, md_needed, 0)) { | ||
1256 | ei->i_da_metadata_calc_len = save_len; | ||
1257 | ei->i_da_metadata_calc_last_lblock = save_last_lblock; | ||
1258 | spin_unlock(&ei->i_block_reservation_lock); | ||
1259 | return -ENOSPC; | ||
1260 | } | ||
1261 | ei->i_reserved_meta_blocks += md_needed; | ||
1262 | spin_unlock(&ei->i_block_reservation_lock); | ||
1263 | |||
1264 | return 0; /* success */ | ||
1265 | } | ||
1266 | |||
1267 | /* | ||
1268 | * Reserve a single cluster located at lblock | 1188 | * Reserve a single cluster located at lblock |
1269 | */ | 1189 | */ |
1270 | static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock) | 1190 | static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock) |
@@ -1273,8 +1193,6 @@ static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock) | |||
1273 | struct ext4_inode_info *ei = EXT4_I(inode); | 1193 | struct ext4_inode_info *ei = EXT4_I(inode); |
1274 | unsigned int md_needed; | 1194 | unsigned int md_needed; |
1275 | int ret; | 1195 | int ret; |
1276 | ext4_lblk_t save_last_lblock; | ||
1277 | int save_len; | ||
1278 | 1196 | ||
1279 | /* | 1197 | /* |
1280 | * We will charge metadata quota at writeout time; this saves | 1198 | * We will charge metadata quota at writeout time; this saves |
@@ -1295,25 +1213,15 @@ static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock) | |||
1295 | * ext4_calc_metadata_amount() has side effects, which we have | 1213 | * ext4_calc_metadata_amount() has side effects, which we have |
1296 | * to be prepared undo if we fail to claim space. | 1214 | * to be prepared undo if we fail to claim space. |
1297 | */ | 1215 | */ |
1298 | save_len = ei->i_da_metadata_calc_len; | 1216 | md_needed = 0; |
1299 | save_last_lblock = ei->i_da_metadata_calc_last_lblock; | 1217 | trace_ext4_da_reserve_space(inode, 0); |
1300 | md_needed = EXT4_NUM_B2C(sbi, | ||
1301 | ext4_calc_metadata_amount(inode, lblock)); | ||
1302 | trace_ext4_da_reserve_space(inode, md_needed); | ||
1303 | 1218 | ||
1304 | /* | 1219 | if (ext4_claim_free_clusters(sbi, 1, 0)) { |
1305 | * We do still charge estimated metadata to the sb though; | ||
1306 | * we cannot afford to run out of free blocks. | ||
1307 | */ | ||
1308 | if (ext4_claim_free_clusters(sbi, md_needed + 1, 0)) { | ||
1309 | ei->i_da_metadata_calc_len = save_len; | ||
1310 | ei->i_da_metadata_calc_last_lblock = save_last_lblock; | ||
1311 | spin_unlock(&ei->i_block_reservation_lock); | 1220 | spin_unlock(&ei->i_block_reservation_lock); |
1312 | dquot_release_reservation_block(inode, EXT4_C2B(sbi, 1)); | 1221 | dquot_release_reservation_block(inode, EXT4_C2B(sbi, 1)); |
1313 | return -ENOSPC; | 1222 | return -ENOSPC; |
1314 | } | 1223 | } |
1315 | ei->i_reserved_data_blocks++; | 1224 | ei->i_reserved_data_blocks++; |
1316 | ei->i_reserved_meta_blocks += md_needed; | ||
1317 | spin_unlock(&ei->i_block_reservation_lock); | 1225 | spin_unlock(&ei->i_block_reservation_lock); |
1318 | 1226 | ||
1319 | return 0; /* success */ | 1227 | return 0; /* success */ |
@@ -1346,20 +1254,6 @@ static void ext4_da_release_space(struct inode *inode, int to_free) | |||
1346 | } | 1254 | } |
1347 | ei->i_reserved_data_blocks -= to_free; | 1255 | ei->i_reserved_data_blocks -= to_free; |
1348 | 1256 | ||
1349 | if (ei->i_reserved_data_blocks == 0) { | ||
1350 | /* | ||
1351 | * We can release all of the reserved metadata blocks | ||
1352 | * only when we have written all of the delayed | ||
1353 | * allocation blocks. | ||
1354 | * Note that in case of bigalloc, i_reserved_meta_blocks, | ||
1355 | * i_reserved_data_blocks, etc. refer to number of clusters. | ||
1356 | */ | ||
1357 | percpu_counter_sub(&sbi->s_dirtyclusters_counter, | ||
1358 | ei->i_reserved_meta_blocks); | ||
1359 | ei->i_reserved_meta_blocks = 0; | ||
1360 | ei->i_da_metadata_calc_len = 0; | ||
1361 | } | ||
1362 | |||
1363 | /* update fs dirty data blocks counter */ | 1257 | /* update fs dirty data blocks counter */ |
1364 | percpu_counter_sub(&sbi->s_dirtyclusters_counter, to_free); | 1258 | percpu_counter_sub(&sbi->s_dirtyclusters_counter, to_free); |
1365 | 1259 | ||
@@ -1500,10 +1394,6 @@ static void ext4_print_free_blocks(struct inode *inode) | |||
1500 | ext4_msg(sb, KERN_CRIT, "Block reservation details"); | 1394 | ext4_msg(sb, KERN_CRIT, "Block reservation details"); |
1501 | ext4_msg(sb, KERN_CRIT, "i_reserved_data_blocks=%u", | 1395 | ext4_msg(sb, KERN_CRIT, "i_reserved_data_blocks=%u", |
1502 | ei->i_reserved_data_blocks); | 1396 | ei->i_reserved_data_blocks); |
1503 | ext4_msg(sb, KERN_CRIT, "i_reserved_meta_blocks=%u", | ||
1504 | ei->i_reserved_meta_blocks); | ||
1505 | ext4_msg(sb, KERN_CRIT, "i_allocated_meta_blocks=%u", | ||
1506 | ei->i_allocated_meta_blocks); | ||
1507 | return; | 1397 | return; |
1508 | } | 1398 | } |
1509 | 1399 | ||
@@ -1620,13 +1510,6 @@ add_delayed: | |||
1620 | retval = ret; | 1510 | retval = ret; |
1621 | goto out_unlock; | 1511 | goto out_unlock; |
1622 | } | 1512 | } |
1623 | } else { | ||
1624 | ret = ext4_da_reserve_metadata(inode, iblock); | ||
1625 | if (ret) { | ||
1626 | /* not enough space to reserve */ | ||
1627 | retval = ret; | ||
1628 | goto out_unlock; | ||
1629 | } | ||
1630 | } | 1513 | } |
1631 | 1514 | ||
1632 | ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len, | 1515 | ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len, |
@@ -2843,8 +2726,7 @@ int ext4_alloc_da_blocks(struct inode *inode) | |||
2843 | { | 2726 | { |
2844 | trace_ext4_alloc_da_blocks(inode); | 2727 | trace_ext4_alloc_da_blocks(inode); |
2845 | 2728 | ||
2846 | if (!EXT4_I(inode)->i_reserved_data_blocks && | 2729 | if (!EXT4_I(inode)->i_reserved_data_blocks) |
2847 | !EXT4_I(inode)->i_reserved_meta_blocks) | ||
2848 | return 0; | 2730 | return 0; |
2849 | 2731 | ||
2850 | /* | 2732 | /* |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 2dcb936be90e..18a16191249a 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -4627,7 +4627,6 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, | |||
4627 | struct buffer_head *gd_bh; | 4627 | struct buffer_head *gd_bh; |
4628 | ext4_group_t block_group; | 4628 | ext4_group_t block_group; |
4629 | struct ext4_sb_info *sbi; | 4629 | struct ext4_sb_info *sbi; |
4630 | struct ext4_inode_info *ei = EXT4_I(inode); | ||
4631 | struct ext4_buddy e4b; | 4630 | struct ext4_buddy e4b; |
4632 | unsigned int count_clusters; | 4631 | unsigned int count_clusters; |
4633 | int err = 0; | 4632 | int err = 0; |
@@ -4838,19 +4837,7 @@ do_more: | |||
4838 | &sbi->s_flex_groups[flex_group].free_clusters); | 4837 | &sbi->s_flex_groups[flex_group].free_clusters); |
4839 | } | 4838 | } |
4840 | 4839 | ||
4841 | if (flags & EXT4_FREE_BLOCKS_RESERVE && ei->i_reserved_data_blocks) { | 4840 | if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE)) |
4842 | percpu_counter_add(&sbi->s_dirtyclusters_counter, | ||
4843 | count_clusters); | ||
4844 | spin_lock(&ei->i_block_reservation_lock); | ||
4845 | if (flags & EXT4_FREE_BLOCKS_METADATA) | ||
4846 | ei->i_reserved_meta_blocks += count_clusters; | ||
4847 | else | ||
4848 | ei->i_reserved_data_blocks += count_clusters; | ||
4849 | spin_unlock(&ei->i_block_reservation_lock); | ||
4850 | if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE)) | ||
4851 | dquot_reclaim_block(inode, | ||
4852 | EXT4_C2B(sbi, count_clusters)); | ||
4853 | } else if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE)) | ||
4854 | dquot_free_block(inode, EXT4_C2B(sbi, count_clusters)); | 4841 | dquot_free_block(inode, EXT4_C2B(sbi, count_clusters)); |
4855 | percpu_counter_add(&sbi->s_freeclusters_counter, count_clusters); | 4842 | percpu_counter_add(&sbi->s_freeclusters_counter, count_clusters); |
4856 | 4843 | ||