aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/inode.c63
1 files changed, 61 insertions, 2 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 48fc023ab0a2..65bbc9339aca 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1305,6 +1305,55 @@ static int ext4_journalled_write_end(struct file *file,
1305} 1305}
1306 1306
1307/* 1307/*
1308 * Reserve a metadata for a single block located at lblock
1309 */
1310static int ext4_da_reserve_metadata(struct inode *inode, ext4_lblk_t lblock)
1311{
1312 int retries = 0;
1313 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
1314 struct ext4_inode_info *ei = EXT4_I(inode);
1315 unsigned int md_needed;
1316 ext4_lblk_t save_last_lblock;
1317 int save_len;
1318
1319 /*
1320 * recalculate the amount of metadata blocks to reserve
1321 * in order to allocate nrblocks
1322 * worse case is one extent per block
1323 */
1324repeat:
1325 spin_lock(&ei->i_block_reservation_lock);
1326 /*
1327 * ext4_calc_metadata_amount() has side effects, which we have
1328 * to be prepared undo if we fail to claim space.
1329 */
1330 save_len = ei->i_da_metadata_calc_len;
1331 save_last_lblock = ei->i_da_metadata_calc_last_lblock;
1332 md_needed = EXT4_NUM_B2C(sbi,
1333 ext4_calc_metadata_amount(inode, lblock));
1334 trace_ext4_da_reserve_space(inode, md_needed);
1335
1336 /*
1337 * We do still charge estimated metadata to the sb though;
1338 * we cannot afford to run out of free blocks.
1339 */
1340 if (ext4_claim_free_clusters(sbi, md_needed, 0)) {
1341 ei->i_da_metadata_calc_len = save_len;
1342 ei->i_da_metadata_calc_last_lblock = save_last_lblock;
1343 spin_unlock(&ei->i_block_reservation_lock);
1344 if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
1345 cond_resched();
1346 goto repeat;
1347 }
1348 return -ENOSPC;
1349 }
1350 ei->i_reserved_meta_blocks += md_needed;
1351 spin_unlock(&ei->i_block_reservation_lock);
1352
1353 return 0; /* success */
1354}
1355
1356/*
1308 * Reserve a single cluster located at lblock 1357 * Reserve a single cluster located at lblock
1309 */ 1358 */
1310static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock) 1359static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock)
@@ -1940,8 +1989,11 @@ add_delayed:
1940 * XXX: __block_prepare_write() unmaps passed block, 1989 * XXX: __block_prepare_write() unmaps passed block,
1941 * is it OK? 1990 * is it OK?
1942 */ 1991 */
1943 /* If the block was allocated from previously allocated cluster, 1992 /*
1944 * then we dont need to reserve it again. */ 1993 * If the block was allocated from previously allocated cluster,
1994 * then we don't need to reserve it again. However we still need
1995 * to reserve metadata for every block we're going to write.
1996 */
1945 if (!(map->m_flags & EXT4_MAP_FROM_CLUSTER)) { 1997 if (!(map->m_flags & EXT4_MAP_FROM_CLUSTER)) {
1946 ret = ext4_da_reserve_space(inode, iblock); 1998 ret = ext4_da_reserve_space(inode, iblock);
1947 if (ret) { 1999 if (ret) {
@@ -1949,6 +2001,13 @@ add_delayed:
1949 retval = ret; 2001 retval = ret;
1950 goto out_unlock; 2002 goto out_unlock;
1951 } 2003 }
2004 } else {
2005 ret = ext4_da_reserve_metadata(inode, iblock);
2006 if (ret) {
2007 /* not enough space to reserve */
2008 retval = ret;
2009 goto out_unlock;
2010 }
1952 } 2011 }
1953 2012
1954 ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len, 2013 ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len,