diff options
-rw-r--r-- | fs/dquot.c | 36 | ||||
-rw-r--r-- | include/linux/quotaops.h | 3 |
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 */ | ||
480 | int 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); | ||
508 | out: | ||
509 | dqput(old_dquot); | ||
510 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | ||
511 | return ret; | ||
512 | } | ||
513 | |||
479 | int vfs_quota_sync(struct super_block *sb, int type) | 514 | int 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); | |||
2318 | EXPORT_SYMBOL(vfs_quota_on_mount); | 2353 | EXPORT_SYMBOL(vfs_quota_on_mount); |
2319 | EXPORT_SYMBOL(vfs_quota_disable); | 2354 | EXPORT_SYMBOL(vfs_quota_disable); |
2320 | EXPORT_SYMBOL(vfs_quota_off); | 2355 | EXPORT_SYMBOL(vfs_quota_off); |
2356 | EXPORT_SYMBOL(dquot_scan_active); | ||
2321 | EXPORT_SYMBOL(vfs_quota_sync); | 2357 | EXPORT_SYMBOL(vfs_quota_sync); |
2322 | EXPORT_SYMBOL(vfs_get_dqinfo); | 2358 | EXPORT_SYMBOL(vfs_get_dqinfo); |
2323 | EXPORT_SYMBOL(vfs_set_dqinfo); | 2359 | EXPORT_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); | |||
28 | struct dquot *dqget(struct super_block *sb, unsigned int id, int type); | 28 | struct dquot *dqget(struct super_block *sb, unsigned int id, int type); |
29 | void dqput(struct dquot *dquot); | 29 | void dqput(struct dquot *dquot); |
30 | int dquot_is_cached(struct super_block *sb, unsigned int id, int type); | 30 | int dquot_is_cached(struct super_block *sb, unsigned int id, int type); |
31 | int dquot_scan_active(struct super_block *sb, | ||
32 | int (*fn)(struct dquot *dquot, unsigned long priv), | ||
33 | unsigned long priv); | ||
31 | 34 | ||
32 | int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc); | 35 | int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc); |
33 | int dquot_alloc_inode(const struct inode *inode, qsize_t number); | 36 | int dquot_alloc_inode(const struct inode *inode, qsize_t number); |