Skip to content

Commit 3d9ea25

Browse files
jankaraMark Fasheh
authored andcommitted
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 <[email protected]> Signed-off-by: Mark Fasheh <[email protected]>
1 parent 571b46e commit 3d9ea25

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

fs/dquot.c

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,6 @@ static struct hlist_head *dquot_hash;
211211

212212
struct dqstats dqstats;
213213

214-
static void dqput(struct dquot *dquot);
215-
216214
static inline unsigned int
217215
hashfn(const struct super_block *sb, unsigned int id, int type)
218216
{
@@ -568,7 +566,7 @@ static struct shrinker dqcache_shrinker = {
568566
* NOTE: If you change this function please check whether dqput_blocks() works right...
569567
* MUST be called with either dqptr_sem or dqonoff_mutex held
570568
*/
571-
static void dqput(struct dquot *dquot)
569+
void dqput(struct dquot *dquot)
572570
{
573571
int ret;
574572

@@ -661,11 +659,29 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type)
661659
return dquot;
662660
}
663661

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+
664680
/*
665681
* Get reference to dquot
666682
* MUST be called with either dqptr_sem or dqonoff_mutex held
667683
*/
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)
669685
{
670686
unsigned int hashent = hashfn(sb, id, type);
671687
struct dquot *dquot, *empty = NODQUOT;
@@ -1184,17 +1200,23 @@ int dquot_initialize(struct inode *inode, int type)
11841200
* Release all quotas referenced by inode
11851201
* Transaction must be started at an entry
11861202
*/
1187-
int dquot_drop(struct inode *inode)
1203+
int dquot_drop_locked(struct inode *inode)
11881204
{
11891205
int cnt;
11901206

1191-
down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
11921207
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
11931208
if (inode->i_dquot[cnt] != NODQUOT) {
11941209
dqput(inode->i_dquot[cnt]);
11951210
inode->i_dquot[cnt] = NODQUOT;
11961211
}
11971212
}
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);
11981220
up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
11991221
return 0;
12001222
}
@@ -2308,7 +2330,11 @@ EXPORT_SYMBOL(dquot_release);
23082330
EXPORT_SYMBOL(dquot_mark_dquot_dirty);
23092331
EXPORT_SYMBOL(dquot_initialize);
23102332
EXPORT_SYMBOL(dquot_drop);
2333+
EXPORT_SYMBOL(dquot_drop_locked);
23112334
EXPORT_SYMBOL(vfs_dq_drop);
2335+
EXPORT_SYMBOL(dqget);
2336+
EXPORT_SYMBOL(dqput);
2337+
EXPORT_SYMBOL(dquot_is_cached);
23122338
EXPORT_SYMBOL(dquot_alloc_space);
23132339
EXPORT_SYMBOL(dquot_alloc_inode);
23142340
EXPORT_SYMBOL(dquot_free_space);

include/linux/quotaops.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ void sync_dquots(struct super_block *sb, int type);
2424

2525
int dquot_initialize(struct inode *inode, int type);
2626
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);
2731

2832
int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc);
2933
int dquot_alloc_inode(const struct inode *inode, qsize_t number);

0 commit comments

Comments
 (0)