From 3d52f6a327227cfeab5e5f02e55a3593f5601d30 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 20 Oct 2008 17:05:00 +0200 Subject: [PATCH] --- yaml --- r: 125834 b: refs/heads/master c: 12c77527e4138bc3b17d17b0e0c909e4fc84924f h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/dquot.c | 36 ++++++++++++++++++++++++++++++++++ trunk/include/linux/quotaops.h | 3 +++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 6d119e1d480a..bc83ff1e27fc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3d9ea253a0e73dccaa869888ec2ceb17ea76c810 +refs/heads/master: 12c77527e4138bc3b17d17b0e0c909e4fc84924f diff --git a/trunk/fs/dquot.c b/trunk/fs/dquot.c index ae8fd9e645cc..075dc76904e7 100644 --- a/trunk/fs/dquot.c +++ b/trunk/fs/dquot.c @@ -476,6 +476,41 @@ static void invalidate_dquots(struct super_block *sb, int type) spin_unlock(&dq_list_lock); } +/* Call callback for every active dquot on given filesystem */ +int dquot_scan_active(struct super_block *sb, + int (*fn)(struct dquot *dquot, unsigned long priv), + unsigned long priv) +{ + struct dquot *dquot, *old_dquot = NULL; + int ret = 0; + + mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); + spin_lock(&dq_list_lock); + list_for_each_entry(dquot, &inuse_list, dq_inuse) { + if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) + continue; + if (dquot->dq_sb != sb) + continue; + /* Now we have active dquot so we can just increase use count */ + atomic_inc(&dquot->dq_count); + dqstats.lookups++; + spin_unlock(&dq_list_lock); + dqput(old_dquot); + old_dquot = dquot; + ret = fn(dquot, priv); + if (ret < 0) + goto out; + spin_lock(&dq_list_lock); + /* We are safe to continue now because our dquot could not + * be moved out of the inuse list while we hold the reference */ + } + spin_unlock(&dq_list_lock); +out: + dqput(old_dquot); + mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); + return ret; +} + int vfs_quota_sync(struct super_block *sb, int type) { struct list_head *dirty; @@ -2318,6 +2353,7 @@ EXPORT_SYMBOL(vfs_quota_on_path); EXPORT_SYMBOL(vfs_quota_on_mount); EXPORT_SYMBOL(vfs_quota_disable); EXPORT_SYMBOL(vfs_quota_off); +EXPORT_SYMBOL(dquot_scan_active); EXPORT_SYMBOL(vfs_quota_sync); EXPORT_SYMBOL(vfs_get_dqinfo); EXPORT_SYMBOL(vfs_set_dqinfo); diff --git a/trunk/include/linux/quotaops.h b/trunk/include/linux/quotaops.h index e3a10272d471..f4913948c305 100644 --- a/trunk/include/linux/quotaops.h +++ b/trunk/include/linux/quotaops.h @@ -28,6 +28,9 @@ int dquot_drop_locked(struct inode *inode); struct dquot *dqget(struct super_block *sb, unsigned int id, int type); void dqput(struct dquot *dquot); int dquot_is_cached(struct super_block *sb, unsigned int id, int type); +int dquot_scan_active(struct super_block *sb, + int (*fn)(struct dquot *dquot, unsigned long priv), + unsigned long priv); int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc); int dquot_alloc_inode(const struct inode *inode, qsize_t number);