aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2008-10-20 11:05:00 -0400
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:40:23 -0500
commit12c77527e4138bc3b17d17b0e0c909e4fc84924f (patch)
tree2776bbc914ebf8db7bdc2e450abf6a1504f50abe
parent3d9ea253a0e73dccaa869888ec2ceb17ea76c810 (diff)
quota: Implement function for scanning active dquots
OCFS2 needs to scan all active dquots once in a while and sync quota information among cluster nodes. Provide a helper function for it so that it does not have to reimplement internally a list which VFS already has. Moreover this function is probably going to be useful for other clustered filesystems if they decide to use VFS quotas. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
-rw-r--r--fs/dquot.c36
-rw-r--r--include/linux/quotaops.h3
2 files changed, 39 insertions, 0 deletions
diff --git a/fs/dquot.c b/fs/dquot.c
index ae8fd9e645cc..075dc76904e7 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -476,6 +476,41 @@ restart:
476 spin_unlock(&dq_list_lock); 476 spin_unlock(&dq_list_lock);
477} 477}
478 478
479/* Call callback for every active dquot on given filesystem */
480int dquot_scan_active(struct super_block *sb,
481 int (*fn)(struct dquot *dquot, unsigned long priv),
482 unsigned long priv)
483{
484 struct dquot *dquot, *old_dquot = NULL;
485 int ret = 0;
486
487 mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
488 spin_lock(&dq_list_lock);
489 list_for_each_entry(dquot, &inuse_list, dq_inuse) {
490 if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
491 continue;
492 if (dquot->dq_sb != sb)
493 continue;
494 /* Now we have active dquot so we can just increase use count */
495 atomic_inc(&dquot->dq_count);
496 dqstats.lookups++;
497 spin_unlock(&dq_list_lock);
498 dqput(old_dquot);
499 old_dquot = dquot;
500 ret = fn(dquot, priv);
501 if (ret < 0)
502 goto out;
503 spin_lock(&dq_list_lock);
504 /* We are safe to continue now because our dquot could not
505 * be moved out of the inuse list while we hold the reference */
506 }
507 spin_unlock(&dq_list_lock);
508out:
509 dqput(old_dquot);
510 mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
511 return ret;
512}
513
479int vfs_quota_sync(struct super_block *sb, int type) 514int vfs_quota_sync(struct super_block *sb, int type)
480{ 515{
481 struct list_head *dirty; 516 struct list_head *dirty;
@@ -2318,6 +2353,7 @@ EXPORT_SYMBOL(vfs_quota_on_path);
2318EXPORT_SYMBOL(vfs_quota_on_mount); 2353EXPORT_SYMBOL(vfs_quota_on_mount);
2319EXPORT_SYMBOL(vfs_quota_disable); 2354EXPORT_SYMBOL(vfs_quota_disable);
2320EXPORT_SYMBOL(vfs_quota_off); 2355EXPORT_SYMBOL(vfs_quota_off);
2356EXPORT_SYMBOL(dquot_scan_active);
2321EXPORT_SYMBOL(vfs_quota_sync); 2357EXPORT_SYMBOL(vfs_quota_sync);
2322EXPORT_SYMBOL(vfs_get_dqinfo); 2358EXPORT_SYMBOL(vfs_get_dqinfo);
2323EXPORT_SYMBOL(vfs_set_dqinfo); 2359EXPORT_SYMBOL(vfs_set_dqinfo);
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index e3a10272d471..f4913948c305 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -28,6 +28,9 @@ int dquot_drop_locked(struct inode *inode);
28struct dquot *dqget(struct super_block *sb, unsigned int id, int type); 28struct dquot *dqget(struct super_block *sb, unsigned int id, int type);
29void dqput(struct dquot *dquot); 29void dqput(struct dquot *dquot);
30int dquot_is_cached(struct super_block *sb, unsigned int id, int type); 30int dquot_is_cached(struct super_block *sb, unsigned int id, int type);
31int dquot_scan_active(struct super_block *sb,
32 int (*fn)(struct dquot *dquot, unsigned long priv),
33 unsigned long priv);
31 34
32int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc); 35int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc);
33int dquot_alloc_inode(const struct inode *inode, qsize_t number); 36int dquot_alloc_inode(const struct inode *inode, qsize_t number);