aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inode.c
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2010-01-22 17:06:20 -0500
committerTheodore Ts'o <tytso@mit.edu>2010-01-22 17:06:20 -0500
commit1db913823c0f8360fccbd24ca67eb073966a5ffd (patch)
treeec5f7be2cfa884b04ca3d26c2dee53283fe16ca7 /fs/ext4/inode.c
parent74d2e4f8d79ae0c4b6ec027958d5b18058662eea (diff)
ext4: Handle -EDQUOT error on write
We need to release the journal before we do a write_inode. Otherwise we could deadlock. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r--fs/ext4/inode.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c818972c8302..60b3a19e9927 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1835,24 +1835,12 @@ repeat:
1835 * later. Real quota accounting is done at pages writeout 1835 * later. Real quota accounting is done at pages writeout
1836 * time. 1836 * time.
1837 */ 1837 */
1838 if (vfs_dq_reserve_block(inode, md_needed + 1)) { 1838 if (vfs_dq_reserve_block(inode, md_needed + 1))
1839 /*
1840 * We tend to badly over-estimate the amount of
1841 * metadata blocks which are needed, so if we have
1842 * reserved any metadata blocks, try to force out the
1843 * inode and see if we have any better luck.
1844 */
1845 if (md_reserved && retries++ <= 3)
1846 goto retry;
1847 return -EDQUOT; 1839 return -EDQUOT;
1848 }
1849 1840
1850 if (ext4_claim_free_blocks(sbi, md_needed + 1)) { 1841 if (ext4_claim_free_blocks(sbi, md_needed + 1)) {
1851 vfs_dq_release_reservation_block(inode, md_needed + 1); 1842 vfs_dq_release_reservation_block(inode, md_needed + 1);
1852 if (ext4_should_retry_alloc(inode->i_sb, &retries)) { 1843 if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
1853 retry:
1854 if (md_reserved)
1855 write_inode_now(inode, (retries == 3));
1856 yield(); 1844 yield();
1857 goto repeat; 1845 goto repeat;
1858 } 1846 }
@@ -3032,7 +3020,7 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
3032 loff_t pos, unsigned len, unsigned flags, 3020 loff_t pos, unsigned len, unsigned flags,
3033 struct page **pagep, void **fsdata) 3021 struct page **pagep, void **fsdata)
3034{ 3022{
3035 int ret, retries = 0; 3023 int ret, retries = 0, quota_retries = 0;
3036 struct page *page; 3024 struct page *page;
3037 pgoff_t index; 3025 pgoff_t index;
3038 unsigned from, to; 3026 unsigned from, to;
@@ -3091,6 +3079,22 @@ retry:
3091 3079
3092 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) 3080 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
3093 goto retry; 3081 goto retry;
3082
3083 if ((ret == -EDQUOT) &&
3084 EXT4_I(inode)->i_reserved_meta_blocks &&
3085 (quota_retries++ < 3)) {
3086 /*
3087 * Since we often over-estimate the number of meta
3088 * data blocks required, we may sometimes get a
3089 * spurios out of quota error even though there would
3090 * be enough space once we write the data blocks and
3091 * find out how many meta data blocks were _really_
3092 * required. So try forcing the inode write to see if
3093 * that helps.
3094 */
3095 write_inode_now(inode, (quota_retries == 3));
3096 goto retry;
3097 }
3094out: 3098out:
3095 return ret; 3099 return ret;
3096} 3100}