diff options
-rw-r--r-- | fs/dquot.c | 38 | ||||
-rw-r--r-- | include/linux/quotaops.h | 4 |
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 | ||
212 | struct dqstats dqstats; | 212 | struct dqstats dqstats; |
213 | 213 | ||
214 | static void dqput(struct dquot *dquot); | ||
215 | |||
216 | static inline unsigned int | 214 | static inline unsigned int |
217 | hashfn(const struct super_block *sb, unsigned int id, int type) | 215 | hashfn(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 | */ |
571 | static void dqput(struct dquot *dquot) | 569 | void 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 | */ | ||
666 | int 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 | */ |
668 | static struct dquot *dqget(struct super_block *sb, unsigned int id, int type) | 684 | struct 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 | */ |
1187 | int dquot_drop(struct inode *inode) | 1203 | int 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 | |||
1216 | int 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); | |||
2308 | EXPORT_SYMBOL(dquot_mark_dquot_dirty); | 2330 | EXPORT_SYMBOL(dquot_mark_dquot_dirty); |
2309 | EXPORT_SYMBOL(dquot_initialize); | 2331 | EXPORT_SYMBOL(dquot_initialize); |
2310 | EXPORT_SYMBOL(dquot_drop); | 2332 | EXPORT_SYMBOL(dquot_drop); |
2333 | EXPORT_SYMBOL(dquot_drop_locked); | ||
2311 | EXPORT_SYMBOL(vfs_dq_drop); | 2334 | EXPORT_SYMBOL(vfs_dq_drop); |
2335 | EXPORT_SYMBOL(dqget); | ||
2336 | EXPORT_SYMBOL(dqput); | ||
2337 | EXPORT_SYMBOL(dquot_is_cached); | ||
2312 | EXPORT_SYMBOL(dquot_alloc_space); | 2338 | EXPORT_SYMBOL(dquot_alloc_space); |
2313 | EXPORT_SYMBOL(dquot_alloc_inode); | 2339 | EXPORT_SYMBOL(dquot_alloc_inode); |
2314 | EXPORT_SYMBOL(dquot_free_space); | 2340 | EXPORT_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 | ||
25 | int dquot_initialize(struct inode *inode, int type); | 25 | int dquot_initialize(struct inode *inode, int type); |
26 | int dquot_drop(struct inode *inode); | 26 | int dquot_drop(struct inode *inode); |
27 | int dquot_drop_locked(struct inode *inode); | ||
28 | struct dquot *dqget(struct super_block *sb, unsigned int id, int type); | ||
29 | void dqput(struct dquot *dquot); | ||
30 | int dquot_is_cached(struct super_block *sb, unsigned int id, int type); | ||
27 | 31 | ||
28 | int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc); | 32 | int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc); |
29 | int dquot_alloc_inode(const struct inode *inode, qsize_t number); | 33 | int dquot_alloc_inode(const struct inode *inode, qsize_t number); |