aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2008-04-28 05:14:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-28 11:58:33 -0400
commit0ff5af8340aa6be44220d7237ef4a654314cf795 (patch)
treea9536ea573725931cd4eb3139f4885887e3f8bf8 /include/linux
parent03f6e92bdd467aed9d7571a571868563ae6ad288 (diff)
quota: quota core changes for quotaon on remount
Currently, we just turn quotas off on remount of filesystem to read-only state. The patch below adds necessary framework so that we can turn quotas off on remount RO but we are able to automatically reenable them again when filesystem is remounted to RW state. All we need to do is to keep references to inodes of quota files when remounting RO and using these references to reenable quotas when remounting RW. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/quota.h14
-rw-r--r--include/linux/quotaops.h29
2 files changed, 35 insertions, 8 deletions
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 48556b039b1c..52e49dce6584 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -202,6 +202,8 @@ struct quota_format_type;
202 202
203struct mem_dqinfo { 203struct mem_dqinfo {
204 struct quota_format_type *dqi_format; 204 struct quota_format_type *dqi_format;
205 int dqi_fmt_id; /* Id of the dqi_format - used when turning
206 * quotas on after remount RW */
205 struct list_head dqi_dirty_list; /* List of dirty dquots */ 207 struct list_head dqi_dirty_list; /* List of dirty dquots */
206 unsigned long dqi_flags; 208 unsigned long dqi_flags;
207 unsigned int dqi_bgrace; 209 unsigned int dqi_bgrace;
@@ -298,8 +300,8 @@ struct dquot_operations {
298 300
299/* Operations handling requests from userspace */ 301/* Operations handling requests from userspace */
300struct quotactl_ops { 302struct quotactl_ops {
301 int (*quota_on)(struct super_block *, int, int, char *); 303 int (*quota_on)(struct super_block *, int, int, char *, int);
302 int (*quota_off)(struct super_block *, int); 304 int (*quota_off)(struct super_block *, int, int);
303 int (*quota_sync)(struct super_block *, int); 305 int (*quota_sync)(struct super_block *, int);
304 int (*get_info)(struct super_block *, int, struct if_dqinfo *); 306 int (*get_info)(struct super_block *, int, struct if_dqinfo *);
305 int (*set_info)(struct super_block *, int, struct if_dqinfo *); 307 int (*set_info)(struct super_block *, int, struct if_dqinfo *);
@@ -320,6 +322,10 @@ struct quota_format_type {
320 322
321#define DQUOT_USR_ENABLED 0x01 /* User diskquotas enabled */ 323#define DQUOT_USR_ENABLED 0x01 /* User diskquotas enabled */
322#define DQUOT_GRP_ENABLED 0x02 /* Group diskquotas enabled */ 324#define DQUOT_GRP_ENABLED 0x02 /* Group diskquotas enabled */
325#define DQUOT_USR_SUSPENDED 0x04 /* User diskquotas are off, but
326 * we have necessary info in
327 * memory to turn them on */
328#define DQUOT_GRP_SUSPENDED 0x08 /* The same for group quotas */
323 329
324struct quota_info { 330struct quota_info {
325 unsigned int flags; /* Flags for diskquotas on this device */ 331 unsigned int flags; /* Flags for diskquotas on this device */
@@ -337,6 +343,10 @@ struct quota_info {
337#define sb_any_quota_enabled(sb) (sb_has_quota_enabled(sb, USRQUOTA) | \ 343#define sb_any_quota_enabled(sb) (sb_has_quota_enabled(sb, USRQUOTA) | \
338 sb_has_quota_enabled(sb, GRPQUOTA)) 344 sb_has_quota_enabled(sb, GRPQUOTA))
339 345
346#define sb_has_quota_suspended(sb, type) \
347 ((type) == USRQUOTA ? (sb_dqopt(sb)->flags & DQUOT_USR_SUSPENDED) : \
348 (sb_dqopt(sb)->flags & DQUOT_GRP_SUSPENDED))
349
340int register_quota_format(struct quota_format_type *fmt); 350int register_quota_format(struct quota_format_type *fmt);
341void unregister_quota_format(struct quota_format_type *fmt); 351void unregister_quota_format(struct quota_format_type *fmt);
342 352
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 1aac25511f07..c97c8f3fa6ee 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -37,10 +37,11 @@ extern int dquot_release(struct dquot *dquot);
37extern int dquot_commit_info(struct super_block *sb, int type); 37extern int dquot_commit_info(struct super_block *sb, int type);
38extern int dquot_mark_dquot_dirty(struct dquot *dquot); 38extern int dquot_mark_dquot_dirty(struct dquot *dquot);
39 39
40extern int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path); 40extern int vfs_quota_on(struct super_block *sb, int type, int format_id,
41 char *path, int remount);
41extern int vfs_quota_on_mount(struct super_block *sb, char *qf_name, 42extern int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
42 int format_id, int type); 43 int format_id, int type);
43extern int vfs_quota_off(struct super_block *sb, int type); 44extern int vfs_quota_off(struct super_block *sb, int type, int remount);
44extern int vfs_quota_sync(struct super_block *sb, int type); 45extern int vfs_quota_sync(struct super_block *sb, int type);
45extern int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); 46extern int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
46extern int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); 47extern int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
@@ -175,12 +176,27 @@ static inline void DQUOT_SYNC(struct super_block *sb)
175 sync_dquots(sb, -1); 176 sync_dquots(sb, -1);
176} 177}
177 178
178static inline int DQUOT_OFF(struct super_block *sb) 179static inline int DQUOT_OFF(struct super_block *sb, int remount)
179{ 180{
180 int ret = -ENOSYS; 181 int ret = -ENOSYS;
181 182
182 if (sb_any_quota_enabled(sb) && sb->s_qcop && sb->s_qcop->quota_off) 183 if (sb->s_qcop && sb->s_qcop->quota_off)
183 ret = sb->s_qcop->quota_off(sb, -1); 184 ret = sb->s_qcop->quota_off(sb, -1, remount);
185 return ret;
186}
187
188static inline int DQUOT_ON_REMOUNT(struct super_block *sb)
189{
190 int cnt;
191 int ret = 0, err;
192
193 if (!sb->s_qcop || !sb->s_qcop->quota_on)
194 return -ENOSYS;
195 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
196 err = sb->s_qcop->quota_on(sb, cnt, 0, NULL, 1);
197 if (err < 0 && !ret)
198 ret = err;
199 }
184 return ret; 200 return ret;
185} 201}
186 202
@@ -196,7 +212,8 @@ static inline int DQUOT_OFF(struct super_block *sb)
196#define DQUOT_ALLOC_INODE(inode) (0) 212#define DQUOT_ALLOC_INODE(inode) (0)
197#define DQUOT_FREE_INODE(inode) do { } while(0) 213#define DQUOT_FREE_INODE(inode) do { } while(0)
198#define DQUOT_SYNC(sb) do { } while(0) 214#define DQUOT_SYNC(sb) do { } while(0)
199#define DQUOT_OFF(sb) (0) 215#define DQUOT_OFF(sb, remount) (0)
216#define DQUOT_ON_REMOUNT(sb) (0)
200#define DQUOT_TRANSFER(inode, iattr) (0) 217#define DQUOT_TRANSFER(inode, iattr) (0)
201static inline int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr) 218static inline int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
202{ 219{