diff options
-rw-r--r-- | fs/ext4/balloc.c | 8 | ||||
-rw-r--r-- | fs/ext4/inode.c | 14 | ||||
-rw-r--r-- | fs/ext4/mballoc.c | 7 |
3 files changed, 24 insertions, 5 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 1707850301d6..57909882c084 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -1738,10 +1738,16 @@ ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode, | |||
1738 | /* | 1738 | /* |
1739 | * With delalloc we already reserved the blocks | 1739 | * With delalloc we already reserved the blocks |
1740 | */ | 1740 | */ |
1741 | if (ext4_claim_free_blocks(sbi, *count)) { | 1741 | while (*count && ext4_claim_free_blocks(sbi, *count)) { |
1742 | /* let others to free the space */ | ||
1743 | yield(); | ||
1744 | *count = *count >> 1; | ||
1745 | } | ||
1746 | if (!*count) { | ||
1742 | *errp = -ENOSPC; | 1747 | *errp = -ENOSPC; |
1743 | return 0; /*return with ENOSPC error */ | 1748 | return 0; /*return with ENOSPC error */ |
1744 | } | 1749 | } |
1750 | num = *count; | ||
1745 | } | 1751 | } |
1746 | /* | 1752 | /* |
1747 | * Check quota for allocation of this block. | 1753 | * Check quota for allocation of this block. |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index b778d5a33ea7..eb9d449817d0 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -1521,6 +1521,7 @@ static int ext4_journalled_write_end(struct file *file, | |||
1521 | 1521 | ||
1522 | static int ext4_da_reserve_space(struct inode *inode, int nrblocks) | 1522 | static int ext4_da_reserve_space(struct inode *inode, int nrblocks) |
1523 | { | 1523 | { |
1524 | int retries = 0; | ||
1524 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | 1525 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
1525 | unsigned long md_needed, mdblocks, total = 0; | 1526 | unsigned long md_needed, mdblocks, total = 0; |
1526 | 1527 | ||
@@ -1529,6 +1530,7 @@ static int ext4_da_reserve_space(struct inode *inode, int nrblocks) | |||
1529 | * in order to allocate nrblocks | 1530 | * in order to allocate nrblocks |
1530 | * worse case is one extent per block | 1531 | * worse case is one extent per block |
1531 | */ | 1532 | */ |
1533 | repeat: | ||
1532 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); | 1534 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); |
1533 | total = EXT4_I(inode)->i_reserved_data_blocks + nrblocks; | 1535 | total = EXT4_I(inode)->i_reserved_data_blocks + nrblocks; |
1534 | mdblocks = ext4_calc_metadata_amount(inode, total); | 1536 | mdblocks = ext4_calc_metadata_amount(inode, total); |
@@ -1539,6 +1541,10 @@ static int ext4_da_reserve_space(struct inode *inode, int nrblocks) | |||
1539 | 1541 | ||
1540 | if (ext4_claim_free_blocks(sbi, total)) { | 1542 | if (ext4_claim_free_blocks(sbi, total)) { |
1541 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); | 1543 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); |
1544 | if (ext4_should_retry_alloc(inode->i_sb, &retries)) { | ||
1545 | yield(); | ||
1546 | goto repeat; | ||
1547 | } | ||
1542 | return -ENOSPC; | 1548 | return -ENOSPC; |
1543 | } | 1549 | } |
1544 | EXT4_I(inode)->i_reserved_data_blocks += nrblocks; | 1550 | EXT4_I(inode)->i_reserved_data_blocks += nrblocks; |
@@ -1825,20 +1831,18 @@ static void ext4_da_block_invalidatepages(struct mpage_da_data *mpd, | |||
1825 | static int mpage_da_map_blocks(struct mpage_da_data *mpd) | 1831 | static int mpage_da_map_blocks(struct mpage_da_data *mpd) |
1826 | { | 1832 | { |
1827 | int err = 0; | 1833 | int err = 0; |
1834 | struct buffer_head new; | ||
1828 | struct buffer_head *lbh = &mpd->lbh; | 1835 | struct buffer_head *lbh = &mpd->lbh; |
1829 | sector_t next = lbh->b_blocknr; | 1836 | sector_t next = lbh->b_blocknr; |
1830 | struct buffer_head new; | ||
1831 | 1837 | ||
1832 | /* | 1838 | /* |
1833 | * We consider only non-mapped and non-allocated blocks | 1839 | * We consider only non-mapped and non-allocated blocks |
1834 | */ | 1840 | */ |
1835 | if (buffer_mapped(lbh) && !buffer_delay(lbh)) | 1841 | if (buffer_mapped(lbh) && !buffer_delay(lbh)) |
1836 | return 0; | 1842 | return 0; |
1837 | |||
1838 | new.b_state = lbh->b_state; | 1843 | new.b_state = lbh->b_state; |
1839 | new.b_blocknr = 0; | 1844 | new.b_blocknr = 0; |
1840 | new.b_size = lbh->b_size; | 1845 | new.b_size = lbh->b_size; |
1841 | |||
1842 | /* | 1846 | /* |
1843 | * If we didn't accumulate anything | 1847 | * If we didn't accumulate anything |
1844 | * to write simply return | 1848 | * to write simply return |
@@ -1871,6 +1875,10 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd) | |||
1871 | lbh->b_size >> mpd->inode->i_blkbits, err); | 1875 | lbh->b_size >> mpd->inode->i_blkbits, err); |
1872 | printk(KERN_EMERG "This should not happen.!! " | 1876 | printk(KERN_EMERG "This should not happen.!! " |
1873 | "Data will be lost\n"); | 1877 | "Data will be lost\n"); |
1878 | if (err == -ENOSPC) { | ||
1879 | printk(KERN_CRIT "Total free blocks count %lld\n", | ||
1880 | ext4_count_free_blocks(mpd->inode->i_sb)); | ||
1881 | } | ||
1874 | /* invlaidate all the pages */ | 1882 | /* invlaidate all the pages */ |
1875 | ext4_da_block_invalidatepages(mpd, next, | 1883 | ext4_da_block_invalidatepages(mpd, next, |
1876 | lbh->b_size >> mpd->inode->i_blkbits); | 1884 | lbh->b_size >> mpd->inode->i_blkbits); |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 2c10b5058a8d..e4f30de11a9d 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -4395,7 +4395,12 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, | |||
4395 | /* | 4395 | /* |
4396 | * With delalloc we already reserved the blocks | 4396 | * With delalloc we already reserved the blocks |
4397 | */ | 4397 | */ |
4398 | if (ext4_claim_free_blocks(sbi, ar->len)) { | 4398 | while (ar->len && ext4_claim_free_blocks(sbi, ar->len)) { |
4399 | /* let others to free the space */ | ||
4400 | yield(); | ||
4401 | ar->len = ar->len >> 1; | ||
4402 | } | ||
4403 | if (!ar->len) { | ||
4399 | *errp = -ENOSPC; | 4404 | *errp = -ENOSPC; |
4400 | return 0; | 4405 | return 0; |
4401 | } | 4406 | } |