diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 14 |
1 files changed, 11 insertions, 3 deletions
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); |