]>
Commit | Line | Data |
---|---|---|
1 | From: Jan Kara <jack@suse.cz> | |
2 | References: fate#302681 | |
3 | Subject: [PATCH 16/28] quota: Add helpers to allow ocfs2 specific quota initialization, freeing and recovery | |
4 | Patch-mainline: 2.6.29? | |
5 | ||
6 | OCFS2 needs to peek whether quota structure is already in memory so | |
7 | that it can avoid expensive cluster locking in that case. Similarly | |
8 | when freeing dquots, it checks whether it is the last quota structure | |
9 | user or not. Finally, it needs to get reference to dquot structure for | |
10 | specified id and quota type when recovering quota file after crash. | |
11 | ||
12 | Signed-off-by: Jan Kara <jack@suse.cz> | |
13 | --- | |
14 | fs/dquot.c | 38 ++++++++++++++++++++++++++++++++------ | |
15 | include/linux/quotaops.h | 4 ++++ | |
16 | 2 files changed, 36 insertions(+), 6 deletions(-) | |
17 | ||
18 | diff --git a/fs/dquot.c b/fs/dquot.c | |
19 | index 3fde18b..9fb1d71 100644 | |
20 | --- a/fs/dquot.c | |
21 | +++ b/fs/dquot.c | |
22 | @@ -213,8 +213,6 @@ static struct hlist_head *dquot_hash; | |
23 | ||
24 | struct dqstats dqstats; | |
25 | ||
26 | -static void dqput(struct dquot *dquot); | |
27 | - | |
28 | static inline unsigned int | |
29 | hashfn(const struct super_block *sb, unsigned int id, int type) | |
30 | { | |
31 | @@ -568,7 +566,7 @@ static struct shrinker dqcache_shrinker = { | |
32 | * NOTE: If you change this function please check whether dqput_blocks() works right... | |
33 | * MUST be called with either dqptr_sem or dqonoff_mutex held | |
34 | */ | |
35 | -static void dqput(struct dquot *dquot) | |
36 | +void dqput(struct dquot *dquot) | |
37 | { | |
38 | int ret; | |
39 | ||
40 | @@ -660,10 +658,28 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) | |
41 | } | |
42 | ||
43 | /* | |
44 | + * Check whether dquot is in memory. | |
45 | + * MUST be called with either dqptr_sem or dqonoff_mutex held | |
46 | + */ | |
47 | +int dquot_is_cached(struct super_block *sb, unsigned int id, int type) | |
48 | +{ | |
49 | + unsigned int hashent = hashfn(sb, id, type); | |
50 | + int ret = 0; | |
51 | + | |
52 | + if (!sb_has_quota_active(sb, type)) | |
53 | + return 0; | |
54 | + spin_lock(&dq_list_lock); | |
55 | + if (find_dquot(hashent, sb, id, type) != NODQUOT) | |
56 | + ret = 1; | |
57 | + spin_unlock(&dq_list_lock); | |
58 | + return ret; | |
59 | +} | |
60 | + | |
61 | +/* | |
62 | * Get reference to dquot | |
63 | * MUST be called with either dqptr_sem or dqonoff_mutex held | |
64 | */ | |
65 | -static struct dquot *dqget(struct super_block *sb, unsigned int id, int type) | |
66 | +struct dquot *dqget(struct super_block *sb, unsigned int id, int type) | |
67 | { | |
68 | unsigned int hashent = hashfn(sb, id, type); | |
69 | struct dquot *dquot, *empty = NODQUOT; | |
70 | @@ -1184,17 +1200,23 @@ out_err: | |
71 | * Release all quotas referenced by inode | |
72 | * Transaction must be started at an entry | |
73 | */ | |
74 | -int dquot_drop(struct inode *inode) | |
75 | +int dquot_drop_locked(struct inode *inode) | |
76 | { | |
77 | int cnt; | |
78 | ||
79 | - down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | |
80 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | |
81 | if (inode->i_dquot[cnt] != NODQUOT) { | |
82 | dqput(inode->i_dquot[cnt]); | |
83 | inode->i_dquot[cnt] = NODQUOT; | |
84 | } | |
85 | } | |
86 | + return 0; | |
87 | +} | |
88 | + | |
89 | +int dquot_drop(struct inode *inode) | |
90 | +{ | |
91 | + down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | |
92 | + dquot_drop_locked(inode); | |
93 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | |
94 | return 0; | |
95 | } | |
96 | @@ -2306,7 +2328,11 @@ EXPORT_SYMBOL(dquot_release); | |
97 | EXPORT_SYMBOL(dquot_mark_dquot_dirty); | |
98 | EXPORT_SYMBOL(dquot_initialize); | |
99 | EXPORT_SYMBOL(dquot_drop); | |
100 | +EXPORT_SYMBOL(dquot_drop_locked); | |
101 | EXPORT_SYMBOL(vfs_dq_drop); | |
102 | +EXPORT_SYMBOL(dqget); | |
103 | +EXPORT_SYMBOL(dqput); | |
104 | +EXPORT_SYMBOL(dquot_is_cached); | |
105 | EXPORT_SYMBOL(dquot_alloc_space); | |
106 | EXPORT_SYMBOL(dquot_alloc_inode); | |
107 | EXPORT_SYMBOL(dquot_free_space); | |
108 | diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h | |
109 | index 94f00ec..1f990f2 100644 | |
110 | --- a/include/linux/quotaops.h | |
111 | +++ b/include/linux/quotaops.h | |
112 | @@ -27,6 +27,10 @@ void sync_dquots(struct super_block *sb, int type); | |
113 | ||
114 | int dquot_initialize(struct inode *inode, int type); | |
115 | int dquot_drop(struct inode *inode); | |
116 | +int dquot_drop_locked(struct inode *inode); | |
117 | +struct dquot *dqget(struct super_block *sb, unsigned int id, int type); | |
118 | +void dqput(struct dquot *dquot); | |
119 | +int dquot_is_cached(struct super_block *sb, unsigned int id, int type); | |
120 | ||
121 | int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc); | |
122 | int dquot_alloc_inode(const struct inode *inode, qsize_t number); | |
123 | -- | |
124 | 1.5.2.4 | |
125 |