diff options
author | Jan Kara <jack@suse.cz> | 2008-08-20 11:50:32 -0400 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2009-01-05 11:36:56 -0500 |
commit | f55abc0fb9c3189de3da829adf3220322c0da43e (patch) | |
tree | 0db4b838b0b90f27401783e8e7e45842ec91f90a /include/linux | |
parent | e4bc7b4b7ff783779b6928d55a9308910bf180a3 (diff) |
quota: Allow to separately enable quota accounting and enforcing limits
Split DQUOT_USR_ENABLED (and DQUOT_GRP_ENABLED) into DQUOT_USR_USAGE_ENABLED
and DQUOT_USR_LIMITS_ENABLED. This way we are able to separately enable /
disable whether we should:
1) ignore quotas completely
2) just keep uptodate information about usage
3) actually enforce quota limits
This is going to be useful when quota is treated as filesystem metadata - we
then want to keep quota information uptodate all the time and just enable /
disable limits enforcement.
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/quota.h | 30 | ||||
-rw-r--r-- | include/linux/quotaops.h | 91 |
2 files changed, 97 insertions, 24 deletions
diff --git a/include/linux/quota.h b/include/linux/quota.h index 9ea468363f9f..93717abcd35b 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h | |||
@@ -318,12 +318,34 @@ struct quota_format_type { | |||
318 | struct quota_format_type *qf_next; | 318 | struct quota_format_type *qf_next; |
319 | }; | 319 | }; |
320 | 320 | ||
321 | #define DQUOT_USR_ENABLED 0x01 /* User diskquotas enabled */ | 321 | /* Quota state flags - they actually come in two flavors - for users and groups */ |
322 | #define DQUOT_GRP_ENABLED 0x02 /* Group diskquotas enabled */ | 322 | enum { |
323 | #define DQUOT_USR_SUSPENDED 0x04 /* User diskquotas are off, but | 323 | _DQUOT_USAGE_ENABLED = 0, /* Track disk usage for users */ |
324 | _DQUOT_LIMITS_ENABLED, /* Enforce quota limits for users */ | ||
325 | _DQUOT_SUSPENDED, /* User diskquotas are off, but | ||
324 | * we have necessary info in | 326 | * we have necessary info in |
325 | * memory to turn them on */ | 327 | * memory to turn them on */ |
326 | #define DQUOT_GRP_SUSPENDED 0x08 /* The same for group quotas */ | 328 | _DQUOT_STATE_FLAGS |
329 | }; | ||
330 | #define DQUOT_USAGE_ENABLED (1 << _DQUOT_USAGE_ENABLED) | ||
331 | #define DQUOT_LIMITS_ENABLED (1 << _DQUOT_LIMITS_ENABLED) | ||
332 | #define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED) | ||
333 | #define DQUOT_STATE_FLAGS (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED | \ | ||
334 | DQUOT_SUSPENDED) | ||
335 | |||
336 | static inline unsigned int dquot_state_flag(unsigned int flags, int type) | ||
337 | { | ||
338 | if (type == USRQUOTA) | ||
339 | return flags; | ||
340 | return flags << _DQUOT_STATE_FLAGS; | ||
341 | } | ||
342 | |||
343 | static inline unsigned int dquot_generic_flag(unsigned int flags, int type) | ||
344 | { | ||
345 | if (type == USRQUOTA) | ||
346 | return flags; | ||
347 | return flags >> _DQUOT_STATE_FLAGS; | ||
348 | } | ||
327 | 349 | ||
328 | struct quota_info { | 350 | struct quota_info { |
329 | unsigned int flags; /* Flags for diskquotas on this device */ | 351 | unsigned int flags; /* Flags for diskquotas on this device */ |
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index ffd97071cd1e..3b3346fa657c 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h | |||
@@ -40,11 +40,14 @@ int dquot_mark_dquot_dirty(struct dquot *dquot); | |||
40 | 40 | ||
41 | int vfs_quota_on(struct super_block *sb, int type, int format_id, | 41 | int vfs_quota_on(struct super_block *sb, int type, int format_id, |
42 | char *path, int remount); | 42 | char *path, int remount); |
43 | int vfs_quota_enable(struct inode *inode, int type, int format_id, | ||
44 | unsigned int flags); | ||
43 | int vfs_quota_on_path(struct super_block *sb, int type, int format_id, | 45 | int vfs_quota_on_path(struct super_block *sb, int type, int format_id, |
44 | struct path *path); | 46 | struct path *path); |
45 | int vfs_quota_on_mount(struct super_block *sb, char *qf_name, | 47 | int vfs_quota_on_mount(struct super_block *sb, char *qf_name, |
46 | int format_id, int type); | 48 | int format_id, int type); |
47 | int vfs_quota_off(struct super_block *sb, int type, int remount); | 49 | int vfs_quota_off(struct super_block *sb, int type, int remount); |
50 | int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags); | ||
48 | int vfs_quota_sync(struct super_block *sb, int type); | 51 | int vfs_quota_sync(struct super_block *sb, int type); |
49 | int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); | 52 | int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); |
50 | int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); | 53 | int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); |
@@ -64,26 +67,22 @@ static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type) | |||
64 | * Functions for checking status of quota | 67 | * Functions for checking status of quota |
65 | */ | 68 | */ |
66 | 69 | ||
67 | static inline int sb_has_quota_enabled(struct super_block *sb, int type) | 70 | static inline int sb_has_quota_usage_enabled(struct super_block *sb, int type) |
68 | { | 71 | { |
69 | if (type == USRQUOTA) | 72 | return sb_dqopt(sb)->flags & |
70 | return (sb_dqopt(sb)->flags & DQUOT_USR_ENABLED) | 73 | dquot_state_flag(DQUOT_USAGE_ENABLED, type); |
71 | && !(sb_dqopt(sb)->flags & DQUOT_USR_SUSPENDED); | ||
72 | return (sb_dqopt(sb)->flags & DQUOT_GRP_ENABLED) | ||
73 | && !(sb_dqopt(sb)->flags & DQUOT_GROUP_SUSPENDED); | ||
74 | } | 74 | } |
75 | 75 | ||
76 | static inline int sb_any_quota_enabled(struct super_block *sb) | 76 | static inline int sb_has_quota_limits_enabled(struct super_block *sb, int type) |
77 | { | 77 | { |
78 | return sb_has_quota_enabled(sb, USRQUOTA) || | 78 | return sb_dqopt(sb)->flags & |
79 | sb_has_quota_enabled(sb, GRPQUOTA); | 79 | dquot_state_flag(DQUOT_LIMITS_ENABLED, type); |
80 | } | 80 | } |
81 | 81 | ||
82 | static inline int sb_has_quota_suspended(struct super_block *sb, int type) | 82 | static inline int sb_has_quota_suspended(struct super_block *sb, int type) |
83 | { | 83 | { |
84 | if (type == USRQUOTA) | 84 | return sb_dqopt(sb)->flags & |
85 | return sb_dqopt(sb)->flags & DQUOT_USR_SUSPENDED; | 85 | dquot_state_flag(DQUOT_SUSPENDED, type); |
86 | return sb_dqopt(sb)->flags & DQUOT_GRP_SUSPENDED; | ||
87 | } | 86 | } |
88 | 87 | ||
89 | static inline int sb_any_quota_suspended(struct super_block *sb) | 88 | static inline int sb_any_quota_suspended(struct super_block *sb) |
@@ -92,6 +91,34 @@ static inline int sb_any_quota_suspended(struct super_block *sb) | |||
92 | sb_has_quota_suspended(sb, GRPQUOTA); | 91 | sb_has_quota_suspended(sb, GRPQUOTA); |
93 | } | 92 | } |
94 | 93 | ||
94 | /* Does kernel know about any quota information for given sb + type? */ | ||
95 | static inline int sb_has_quota_loaded(struct super_block *sb, int type) | ||
96 | { | ||
97 | /* Currently if anything is on, then quota usage is on as well */ | ||
98 | return sb_has_quota_usage_enabled(sb, type); | ||
99 | } | ||
100 | |||
101 | static inline int sb_any_quota_loaded(struct super_block *sb) | ||
102 | { | ||
103 | return sb_has_quota_loaded(sb, USRQUOTA) || | ||
104 | sb_has_quota_loaded(sb, GRPQUOTA); | ||
105 | } | ||
106 | |||
107 | static inline int sb_has_quota_active(struct super_block *sb, int type) | ||
108 | { | ||
109 | return sb_has_quota_loaded(sb, type) && | ||
110 | !sb_has_quota_suspended(sb, type); | ||
111 | } | ||
112 | |||
113 | static inline int sb_any_quota_active(struct super_block *sb) | ||
114 | { | ||
115 | return sb_has_quota_active(sb, USRQUOTA) || | ||
116 | sb_has_quota_active(sb, GRPQUOTA); | ||
117 | } | ||
118 | |||
119 | /* For backward compatibility until we remove all users */ | ||
120 | #define sb_any_quota_enabled(sb) sb_any_quota_active(sb) | ||
121 | |||
95 | /* | 122 | /* |
96 | * Operations supported for diskquotas. | 123 | * Operations supported for diskquotas. |
97 | */ | 124 | */ |
@@ -106,7 +133,7 @@ extern struct quotactl_ops vfs_quotactl_ops; | |||
106 | static inline void vfs_dq_init(struct inode *inode) | 133 | static inline void vfs_dq_init(struct inode *inode) |
107 | { | 134 | { |
108 | BUG_ON(!inode->i_sb); | 135 | BUG_ON(!inode->i_sb); |
109 | if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode)) | 136 | if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) |
110 | inode->i_sb->dq_op->initialize(inode, -1); | 137 | inode->i_sb->dq_op->initialize(inode, -1); |
111 | } | 138 | } |
112 | 139 | ||
@@ -114,7 +141,7 @@ static inline void vfs_dq_init(struct inode *inode) | |||
114 | * a transaction (deadlocks possible otherwise) */ | 141 | * a transaction (deadlocks possible otherwise) */ |
115 | static inline int vfs_dq_prealloc_space_nodirty(struct inode *inode, qsize_t nr) | 142 | static inline int vfs_dq_prealloc_space_nodirty(struct inode *inode, qsize_t nr) |
116 | { | 143 | { |
117 | if (sb_any_quota_enabled(inode->i_sb)) { | 144 | if (sb_any_quota_active(inode->i_sb)) { |
118 | /* Used space is updated in alloc_space() */ | 145 | /* Used space is updated in alloc_space() */ |
119 | if (inode->i_sb->dq_op->alloc_space(inode, nr, 1) == NO_QUOTA) | 146 | if (inode->i_sb->dq_op->alloc_space(inode, nr, 1) == NO_QUOTA) |
120 | return 1; | 147 | return 1; |
@@ -134,7 +161,7 @@ static inline int vfs_dq_prealloc_space(struct inode *inode, qsize_t nr) | |||
134 | 161 | ||
135 | static inline int vfs_dq_alloc_space_nodirty(struct inode *inode, qsize_t nr) | 162 | static inline int vfs_dq_alloc_space_nodirty(struct inode *inode, qsize_t nr) |
136 | { | 163 | { |
137 | if (sb_any_quota_enabled(inode->i_sb)) { | 164 | if (sb_any_quota_active(inode->i_sb)) { |
138 | /* Used space is updated in alloc_space() */ | 165 | /* Used space is updated in alloc_space() */ |
139 | if (inode->i_sb->dq_op->alloc_space(inode, nr, 0) == NO_QUOTA) | 166 | if (inode->i_sb->dq_op->alloc_space(inode, nr, 0) == NO_QUOTA) |
140 | return 1; | 167 | return 1; |
@@ -154,7 +181,7 @@ static inline int vfs_dq_alloc_space(struct inode *inode, qsize_t nr) | |||
154 | 181 | ||
155 | static inline int vfs_dq_alloc_inode(struct inode *inode) | 182 | static inline int vfs_dq_alloc_inode(struct inode *inode) |
156 | { | 183 | { |
157 | if (sb_any_quota_enabled(inode->i_sb)) { | 184 | if (sb_any_quota_active(inode->i_sb)) { |
158 | vfs_dq_init(inode); | 185 | vfs_dq_init(inode); |
159 | if (inode->i_sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) | 186 | if (inode->i_sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) |
160 | return 1; | 187 | return 1; |
@@ -164,7 +191,7 @@ static inline int vfs_dq_alloc_inode(struct inode *inode) | |||
164 | 191 | ||
165 | static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr) | 192 | static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr) |
166 | { | 193 | { |
167 | if (sb_any_quota_enabled(inode->i_sb)) | 194 | if (sb_any_quota_active(inode->i_sb)) |
168 | inode->i_sb->dq_op->free_space(inode, nr); | 195 | inode->i_sb->dq_op->free_space(inode, nr); |
169 | else | 196 | else |
170 | inode_sub_bytes(inode, nr); | 197 | inode_sub_bytes(inode, nr); |
@@ -178,7 +205,7 @@ static inline void vfs_dq_free_space(struct inode *inode, qsize_t nr) | |||
178 | 205 | ||
179 | static inline void vfs_dq_free_inode(struct inode *inode) | 206 | static inline void vfs_dq_free_inode(struct inode *inode) |
180 | { | 207 | { |
181 | if (sb_any_quota_enabled(inode->i_sb)) | 208 | if (sb_any_quota_active(inode->i_sb)) |
182 | inode->i_sb->dq_op->free_inode(inode, 1); | 209 | inode->i_sb->dq_op->free_inode(inode, 1); |
183 | } | 210 | } |
184 | 211 | ||
@@ -199,12 +226,12 @@ static inline int vfs_dq_off(struct super_block *sb, int remount) | |||
199 | 226 | ||
200 | #else | 227 | #else |
201 | 228 | ||
202 | static inline int sb_has_quota_enabled(struct super_block *sb, int type) | 229 | static inline int sb_has_quota_usage_enabled(struct super_block *sb, int type) |
203 | { | 230 | { |
204 | return 0; | 231 | return 0; |
205 | } | 232 | } |
206 | 233 | ||
207 | static inline int sb_any_quota_enabled(struct super_block *sb) | 234 | static inline int sb_has_quota_limits_enabled(struct super_block *sb, int type) |
208 | { | 235 | { |
209 | return 0; | 236 | return 0; |
210 | } | 237 | } |
@@ -219,6 +246,30 @@ static inline int sb_any_quota_suspended(struct super_block *sb) | |||
219 | return 0; | 246 | return 0; |
220 | } | 247 | } |
221 | 248 | ||
249 | /* Does kernel know about any quota information for given sb + type? */ | ||
250 | static inline int sb_has_quota_loaded(struct super_block *sb, int type) | ||
251 | { | ||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | static inline int sb_any_quota_loaded(struct super_block *sb) | ||
256 | { | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | static inline int sb_has_quota_active(struct super_block *sb, int type) | ||
261 | { | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | static inline int sb_any_quota_active(struct super_block *sb) | ||
266 | { | ||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | /* For backward compatibility until we remove all users */ | ||
271 | #define sb_any_quota_enabled(sb) sb_any_quota_active(sb) | ||
272 | |||
222 | /* | 273 | /* |
223 | * NO-OP when quota not configured. | 274 | * NO-OP when quota not configured. |
224 | */ | 275 | */ |