@@ -1815,7 +1815,6 @@ static int ext4_journalled_write_end(struct file *file,
*/
static int ext4_da_reserve_space(struct inode *inode, sector_t lblock)
{
- int retries = 0;
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
struct ext4_inode_info *ei = EXT4_I(inode);
unsigned long md_needed, md_reserved;
@@ -1825,7 +1824,6 @@ static int ext4_da_reserve_space(struct inode *inode, sector_t lblock)
* in order to allocate nrblocks
* worse case is one extent per block
*/
-repeat:
spin_lock(&ei->i_block_reservation_lock);
md_reserved = ei->i_reserved_meta_blocks;
md_needed = ext4_calc_metadata_amount(inode, lblock);
@@ -1836,27 +1834,11 @@ repeat:
* later. Real quota accounting is done at pages writeout
* time.
*/
- if (vfs_dq_reserve_block(inode, md_needed + 1)) {
- /*
- * We tend to badly over-estimate the amount of
- * metadata blocks which are needed, so if we have
- * reserved any metadata blocks, try to force out the
- * inode and see if we have any better luck.
- */
- if (md_reserved && retries++ <= 3)
- goto retry;
+ if (vfs_dq_reserve_block(inode, md_needed + 1))
return -EDQUOT;
- }
if (ext4_claim_free_blocks(sbi, md_needed + 1)) {
vfs_dq_release_reservation_block(inode, md_needed + 1);
- if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
- retry:
- if (md_reserved)
- write_inode_now(inode, (retries == 3));
- yield();
- goto repeat;
- }
return -ENOSPC;
}
spin_lock(&ei->i_block_reservation_lock);
@@ -3033,7 +3015,7 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
- int ret, retries = 0;
+ int ret, dqretry, retries = 0;
struct page *page;
pgoff_t index;
unsigned from, to;
@@ -3090,9 +3072,22 @@ retry:
ext4_truncate_failed_write(inode);
}
- if (!(flags & EXT4_AOP_FLAG_NORETRY) &&
- ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
- goto retry;
+ dqretry = (ret == -EDQUOT) || EXT4_I(inode)->i_reserved_meta_blocks;
+ if ( !(flags & EXT4_AOP_FLAG_NORETRY) &&
+ (ret == -ENOSPC || dqretry) &&
+ ext4_should_retry_alloc(inode->i_sb, &retries)) {
+ if (dqretry) {
+ /*
+ * We tend to badly over-estimate the amount of
+ * metadata blocks which are needed, so if we have
+ * reserved any metadata blocks, try to force out the
+ * inode and see if we have any better luck.
+ */
+ write_inode_now(inode, (retries == 3));
+ }
+ yield();
+ goto retry;
+ }
out:
return ret;
}