diff options
Diffstat (limited to 'fs/quota')
-rw-r--r-- | fs/quota/dquot.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 6244bca45c9d..3c0a7e0dff78 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -230,6 +230,7 @@ struct dqstats dqstats; | |||
230 | EXPORT_SYMBOL(dqstats); | 230 | EXPORT_SYMBOL(dqstats); |
231 | 231 | ||
232 | static qsize_t inode_get_rsv_space(struct inode *inode); | 232 | static qsize_t inode_get_rsv_space(struct inode *inode); |
233 | static void __dquot_initialize(struct inode *inode, int type); | ||
233 | 234 | ||
234 | static inline unsigned int | 235 | static inline unsigned int |
235 | hashfn(const struct super_block *sb, unsigned int id, int type) | 236 | hashfn(const struct super_block *sb, unsigned int id, int type) |
@@ -890,7 +891,7 @@ static void add_dquot_ref(struct super_block *sb, int type) | |||
890 | spin_unlock(&inode_lock); | 891 | spin_unlock(&inode_lock); |
891 | 892 | ||
892 | iput(old_inode); | 893 | iput(old_inode); |
893 | sb->dq_op->initialize(inode, type); | 894 | __dquot_initialize(inode, type); |
894 | /* We hold a reference to 'inode' so it couldn't have been | 895 | /* We hold a reference to 'inode' so it couldn't have been |
895 | * removed from s_inodes list while we dropped the inode_lock. | 896 | * removed from s_inodes list while we dropped the inode_lock. |
896 | * We cannot iput the inode now as we can be holding the last | 897 | * We cannot iput the inode now as we can be holding the last |
@@ -1293,22 +1294,26 @@ static int info_bdq_free(struct dquot *dquot, qsize_t space) | |||
1293 | } | 1294 | } |
1294 | 1295 | ||
1295 | /* | 1296 | /* |
1296 | * Initialize quota pointers in inode | 1297 | * Initialize quota pointers in inode |
1297 | * We do things in a bit complicated way but by that we avoid calling | 1298 | * |
1298 | * dqget() and thus filesystem callbacks under dqptr_sem. | 1299 | * We do things in a bit complicated way but by that we avoid calling |
1300 | * dqget() and thus filesystem callbacks under dqptr_sem. | ||
1301 | * | ||
1302 | * It is better to call this function outside of any transaction as it | ||
1303 | * might need a lot of space in journal for dquot structure allocation. | ||
1299 | */ | 1304 | */ |
1300 | int dquot_initialize(struct inode *inode, int type) | 1305 | static void __dquot_initialize(struct inode *inode, int type) |
1301 | { | 1306 | { |
1302 | unsigned int id = 0; | 1307 | unsigned int id = 0; |
1303 | int cnt, ret = 0; | 1308 | int cnt; |
1304 | struct dquot *got[MAXQUOTAS]; | 1309 | struct dquot *got[MAXQUOTAS]; |
1305 | struct super_block *sb = inode->i_sb; | 1310 | struct super_block *sb = inode->i_sb; |
1306 | qsize_t rsv; | 1311 | qsize_t rsv; |
1307 | 1312 | ||
1308 | /* First test before acquiring mutex - solves deadlocks when we | 1313 | /* First test before acquiring mutex - solves deadlocks when we |
1309 | * re-enter the quota code and are already holding the mutex */ | 1314 | * re-enter the quota code and are already holding the mutex */ |
1310 | if (IS_NOQUOTA(inode)) | 1315 | if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) |
1311 | return 0; | 1316 | return; |
1312 | 1317 | ||
1313 | /* First get references to structures we might need. */ | 1318 | /* First get references to structures we might need. */ |
1314 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1319 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
@@ -1351,7 +1356,11 @@ out_err: | |||
1351 | up_write(&sb_dqopt(sb)->dqptr_sem); | 1356 | up_write(&sb_dqopt(sb)->dqptr_sem); |
1352 | /* Drop unused references */ | 1357 | /* Drop unused references */ |
1353 | dqput_all(got); | 1358 | dqput_all(got); |
1354 | return ret; | 1359 | } |
1360 | |||
1361 | void dquot_initialize(struct inode *inode) | ||
1362 | { | ||
1363 | __dquot_initialize(inode, -1); | ||
1355 | } | 1364 | } |
1356 | EXPORT_SYMBOL(dquot_initialize); | 1365 | EXPORT_SYMBOL(dquot_initialize); |
1357 | 1366 | ||
@@ -1783,7 +1792,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) | |||
1783 | chid[GRPQUOTA] = iattr->ia_gid; | 1792 | chid[GRPQUOTA] = iattr->ia_gid; |
1784 | } | 1793 | } |
1785 | if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) { | 1794 | if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) { |
1786 | vfs_dq_init(inode); | 1795 | dquot_initialize(inode); |
1787 | if (__dquot_transfer(inode, chid, mask) == NO_QUOTA) | 1796 | if (__dquot_transfer(inode, chid, mask) == NO_QUOTA) |
1788 | return -EDQUOT; | 1797 | return -EDQUOT; |
1789 | } | 1798 | } |
@@ -1810,7 +1819,6 @@ EXPORT_SYMBOL(dquot_commit_info); | |||
1810 | * Definitions of diskquota operations. | 1819 | * Definitions of diskquota operations. |
1811 | */ | 1820 | */ |
1812 | const struct dquot_operations dquot_operations = { | 1821 | const struct dquot_operations dquot_operations = { |
1813 | .initialize = dquot_initialize, | ||
1814 | .write_dquot = dquot_commit, | 1822 | .write_dquot = dquot_commit, |
1815 | .acquire_dquot = dquot_acquire, | 1823 | .acquire_dquot = dquot_acquire, |
1816 | .release_dquot = dquot_release, | 1824 | .release_dquot = dquot_release, |
@@ -1829,7 +1837,7 @@ int dquot_file_open(struct inode *inode, struct file *file) | |||
1829 | 1837 | ||
1830 | error = generic_file_open(inode, file); | 1838 | error = generic_file_open(inode, file); |
1831 | if (!error && (file->f_mode & FMODE_WRITE)) | 1839 | if (!error && (file->f_mode & FMODE_WRITE)) |
1832 | vfs_dq_init(inode); | 1840 | dquot_initialize(inode); |
1833 | return error; | 1841 | return error; |
1834 | } | 1842 | } |
1835 | EXPORT_SYMBOL(dquot_file_open); | 1843 | EXPORT_SYMBOL(dquot_file_open); |