aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2008-10-10 10:12:23 -0400
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:40:22 -0500
commit3d9ea253a0e73dccaa869888ec2ceb17ea76c810 (patch)
tree0a107f919605f68335bf55176b062facebcd51c9
parent571b46e40bebb0d57130ca24c4a84dfd553adb91 (diff)
quota: Add helpers to allow ocfs2 specific quota initialization, freeing and recovery
OCFS2 needs to peek whether quota structure is already in memory so that it can avoid expensive cluster locking in that case. Similarly when freeing dquots, it checks whether it is the last quota structure user or not. Finally, it needs to get reference to dquot structure for specified id and quota type when recovering quota file after crash. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
-rw-r--r--fs/dquot.c38
-rw-r--r--include/linux/quotaops.h4
2 files changed, 36 insertions, 6 deletions
diff --git a/fs/dquot.c b/fs/dquot.c
index 89226726daa8..ae8fd9e645cc 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -211,8 +211,6 @@ static struct hlist_head *dquot_hash;
211 211
212struct dqstats dqstats; 212struct dqstats dqstats;
213 213
214static void dqput(struct dquot *dquot);
215
216static inline unsigned int 214static inline unsigned int
217hashfn(const struct super_block *sb, unsigned int id, int type) 215hashfn(const struct super_block *sb, unsigned int id, int type)
218{ 216{
@@ -568,7 +566,7 @@ static struct shrinker dqcache_shrinker = {
568 * NOTE: If you change this function please check whether dqput_blocks() works right... 566 * NOTE: If you change this function please check whether dqput_blocks() works right...
569 * MUST be called with either dqptr_sem or dqonoff_mutex held 567 * MUST be called with either dqptr_sem or dqonoff_mutex held
570 */ 568 */
571static void dqput(struct dquot *dquot) 569void dqput(struct dquot *dquot)
572{ 570{
573 int ret; 571 int ret;
574 572
@@ -662,10 +660,28 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type)
662} 660}
663 661
664/* 662/*
663 * Check whether dquot is in memory.
664 * MUST be called with either dqptr_sem or dqonoff_mutex held
665 */
666int dquot_is_cached(struct super_block *sb, unsigned int id, int type)
667{
668 unsigned int hashent = hashfn(sb, id, type);
669 int ret = 0;
670
671 if (!sb_has_quota_active(sb, type))
672 return 0;
673 spin_lock(&dq_list_lock);
674 if (find_dquot(hashent, sb, id, type) != NODQUOT)
675 ret = 1;
676 spin_unlock(&dq_list_lock);
677 return ret;
678}
679
680/*
665 * Get reference to dquot 681 * Get reference to dquot
666 * MUST be called with either dqptr_sem or dqonoff_mutex held 682 * MUST be called with either dqptr_sem or dqonoff_mutex held
667 */ 683 */
668static struct dquot *dqget(struct super_block *sb, unsigned int id, int type) 684struct dquot *dqget(struct super_block *sb, unsigned int id, int type)
669{ 685{
670 unsigned int hashent = hashfn(sb, id, type); 686 unsigned int hashent = hashfn(sb, id, type);
671 struct dquot *dquot, *empty = NODQUOT; 687 struct dquot *dquot, *empty = NODQUOT;
@@ -1184,17 +1200,23 @@ out_err:
1184 * Release all quotas referenced by inode 1200 * Release all quotas referenced by inode
1185 * Transaction must be started at an entry 1201 * Transaction must be started at an entry
1186 */ 1202 */
1187int dquot_drop(struct inode *inode) 1203int dquot_drop_locked(struct inode *inode)
1188{ 1204{
1189 int cnt; 1205 int cnt;
1190 1206
1191 down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
1192 for (cnt = 0; cnt < MAXQUOTAS; cnt++) { 1207 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1193 if (inode->i_dquot[cnt] != NODQUOT) { 1208 if (inode->i_dquot[cnt] != NODQUOT) {
1194 dqput(inode->i_dquot[cnt]); 1209 dqput(inode->i_dquot[cnt]);
1195 inode->i_dquot[cnt] = NODQUOT; 1210 inode->i_dquot[cnt] = NODQUOT;
1196 } 1211 }
1197 } 1212 }
1213 return 0;
1214}
1215
1216int dquot_drop(struct inode *inode)
1217{
1218 down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
1219 dquot_drop_locked(inode);
1198 up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); 1220 up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
1199 return 0; 1221 return 0;
1200} 1222}
@@ -2308,7 +2330,11 @@ EXPORT_SYMBOL(dquot_release);
2308EXPORT_SYMBOL(dquot_mark_dquot_dirty); 2330EXPORT_SYMBOL(dquot_mark_dquot_dirty);
2309EXPORT_SYMBOL(dquot_initialize); 2331EXPORT_SYMBOL(dquot_initialize);
2310EXPORT_SYMBOL(dquot_drop); 2332EXPORT_SYMBOL(dquot_drop);
2333EXPORT_SYMBOL(dquot_drop_locked);
2311EXPORT_SYMBOL(vfs_dq_drop); 2334EXPORT_SYMBOL(vfs_dq_drop);
2335EXPORT_SYMBOL(dqget);
2336EXPORT_SYMBOL(dqput);
2337EXPORT_SYMBOL(dquot_is_cached);
2312EXPORT_SYMBOL(dquot_alloc_space); 2338EXPORT_SYMBOL(dquot_alloc_space);
2313EXPORT_SYMBOL(dquot_alloc_inode); 2339EXPORT_SYMBOL(dquot_alloc_inode);
2314EXPORT_SYMBOL(dquot_free_space); 2340EXPORT_SYMBOL(dquot_free_space);
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index e840ca523175..e3a10272d471 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -24,6 +24,10 @@ void sync_dquots(struct super_block *sb, int type);
24 24
25int dquot_initialize(struct inode *inode, int type); 25int dquot_initialize(struct inode *inode, int type);
26int dquot_drop(struct inode *inode); 26int dquot_drop(struct inode *inode);
27int dquot_drop_locked(struct inode *inode);
28struct dquot *dqget(struct super_block *sb, unsigned int id, int type);
29void dqput(struct dquot *dquot);
30int dquot_is_cached(struct super_block *sb, unsigned int id, int type);
27 31
28int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc); 32int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc);
29int dquot_alloc_inode(const struct inode *inode, qsize_t number); 33int dquot_alloc_inode(const struct inode *inode, qsize_t number);