]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Jan Kara <jack@suse.cz> |
2 | References: fate#302681 | |
3 | Subject: [PATCH 17/28] quota: Implement function for scanning active dquots | |
4 | Patch-mainline: 2.6.29? | |
5 | ||
6 | OCFS2 needs to scan all active dquots once in a while and sync quota | |
7 | information among cluster nodes. Provide a helper function for it so | |
8 | that it does not have to reimplement internally a list which VFS | |
9 | already has. Moreover this function is probably going to be useful | |
10 | for other clustered filesystems if they decide to use VFS quotas. | |
11 | ||
12 | Signed-off-by: Jan Kara <jack@suse.cz> | |
13 | --- | |
14 | fs/dquot.c | 36 ++++++++++++++++++++++++++++++++++++ | |
15 | include/linux/quotaops.h | 3 +++ | |
16 | 2 files changed, 39 insertions(+), 0 deletions(-) | |
17 | ||
18 | diff --git a/fs/dquot.c b/fs/dquot.c | |
19 | index 9fb1d71..6a17416 100644 | |
20 | --- a/fs/dquot.c | |
21 | +++ b/fs/dquot.c | |
22 | @@ -476,6 +476,41 @@ restart: | |
23 | spin_unlock(&dq_list_lock); | |
24 | } | |
25 | ||
26 | +/* Call callback for every active dquot on given filesystem */ | |
27 | +int dquot_scan_active(struct super_block *sb, | |
28 | + int (*fn)(struct dquot *dquot, unsigned long priv), | |
29 | + unsigned long priv) | |
30 | +{ | |
31 | + struct dquot *dquot, *old_dquot = NULL; | |
32 | + int ret = 0; | |
33 | + | |
34 | + mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); | |
35 | + spin_lock(&dq_list_lock); | |
36 | + list_for_each_entry(dquot, &inuse_list, dq_inuse) { | |
37 | + if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) | |
38 | + continue; | |
39 | + if (dquot->dq_sb != sb) | |
40 | + continue; | |
41 | + /* Now we have active dquot so we can just increase use count */ | |
42 | + atomic_inc(&dquot->dq_count); | |
43 | + dqstats.lookups++; | |
44 | + spin_unlock(&dq_list_lock); | |
45 | + dqput(old_dquot); | |
46 | + old_dquot = dquot; | |
47 | + ret = fn(dquot, priv); | |
48 | + if (ret < 0) | |
49 | + goto out; | |
50 | + spin_lock(&dq_list_lock); | |
51 | + /* We are safe to continue now because our dquot could not | |
52 | + * be moved out of the inuse list while we hold the reference */ | |
53 | + } | |
54 | + spin_unlock(&dq_list_lock); | |
55 | +out: | |
56 | + dqput(old_dquot); | |
57 | + mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | |
58 | + return ret; | |
59 | +} | |
60 | + | |
61 | int vfs_quota_sync(struct super_block *sb, int type) | |
62 | { | |
63 | struct list_head *dirty; | |
64 | @@ -2316,6 +2351,7 @@ EXPORT_SYMBOL(vfs_quota_on_path); | |
65 | EXPORT_SYMBOL(vfs_quota_on_mount); | |
66 | EXPORT_SYMBOL(vfs_quota_disable); | |
67 | EXPORT_SYMBOL(vfs_quota_off); | |
68 | +EXPORT_SYMBOL(dquot_scan_active); | |
69 | EXPORT_SYMBOL(vfs_quota_sync); | |
70 | EXPORT_SYMBOL(vfs_get_dqinfo); | |
71 | EXPORT_SYMBOL(vfs_set_dqinfo); | |
72 | diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h | |
73 | index 1f990f2..f2147eb 100644 | |
74 | --- a/include/linux/quotaops.h | |
75 | +++ b/include/linux/quotaops.h | |
76 | @@ -31,6 +31,9 @@ int dquot_drop_locked(struct inode *inode); | |
77 | struct dquot *dqget(struct super_block *sb, unsigned int id, int type); | |
78 | void dqput(struct dquot *dquot); | |
79 | int dquot_is_cached(struct super_block *sb, unsigned int id, int type); | |
80 | +int dquot_scan_active(struct super_block *sb, | |
81 | + int (*fn)(struct dquot *dquot, unsigned long priv), | |
82 | + unsigned long priv); | |
83 | ||
84 | int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc); | |
85 | int dquot_alloc_inode(const struct inode *inode, qsize_t number); | |
86 | -- | |
87 | 1.5.2.4 | |
88 |