]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.suse/quota-Introduce-DQUOT_QUOTA_SYS_FILE-flag.patch
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.suse / quota-Introduce-DQUOT_QUOTA_SYS_FILE-flag.patch
1 From: Jan Kara <jack@suse.cz>
2 References: fate#302681
3 Subject: [PATCH 10/28] quota: Introduce DQUOT_QUOTA_SYS_FILE flag
4 Patch-mainline: 2.6.29?
5
6 If filesystem can handle quota files as system files hidden from users, we can
7 skip a lot of cache invalidation, syncing, inode flags setting etc. when
8 turning quotas on, off and quota_sync. Allow filesystem to indicate that it is
9 hiding quota files from users by DQUOT_QUOTA_SYS_FILE flag.
10
11 Signed-off-by: Jan Kara <jack@suse.cz>
12 ---
13 fs/dquot.c | 45 ++++++++++++++++++++++++++++++---------------
14 fs/quota.c | 3 +++
15 include/linux/quota.h | 7 +++++++
16 3 files changed, 40 insertions(+), 15 deletions(-)
17
18 diff --git a/fs/dquot.c b/fs/dquot.c
19 index bdfae7d..904bd67 100644
20 --- a/fs/dquot.c
21 +++ b/fs/dquot.c
22 @@ -1629,6 +1629,11 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags)
23 dqopt->ops[cnt] = NULL;
24 }
25 mutex_unlock(&dqopt->dqonoff_mutex);
26 +
27 + /* Skip syncing and setting flags if quota files are hidden */
28 + if (dqopt->flags & DQUOT_QUOTA_SYS_FILE)
29 + goto put_inodes;
30 +
31 /* Sync the superblock so that buffers with quota data are written to
32 * disk (and so userspace sees correct data afterwards). */
33 if (sb->s_op->sync_fs)
34 @@ -1653,6 +1658,12 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags)
35 mark_inode_dirty(toputinode[cnt]);
36 }
37 mutex_unlock(&dqopt->dqonoff_mutex);
38 + }
39 + if (sb->s_bdev)
40 + invalidate_bdev(sb->s_bdev);
41 +put_inodes:
42 + for (cnt = 0; cnt < MAXQUOTAS; cnt++)
43 + if (toputinode[cnt]) {
44 /* On remount RO, we keep the inode pointer so that we
45 * can reenable quota on the subsequent remount RW. We
46 * have to check 'flags' variable and not use sb_has_
47 @@ -1665,8 +1676,6 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags)
48 else if (!toputinode[cnt]->i_nlink)
49 ret = -EBUSY;
50 }
51 - if (sb->s_bdev)
52 - invalidate_bdev(sb->s_bdev);
53 return ret;
54 }
55
56 @@ -1713,25 +1722,31 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
57 goto out_fmt;
58 }
59
60 - /* As we bypass the pagecache we must now flush the inode so that
61 - * we see all the changes from userspace... */
62 - write_inode_now(inode, 1);
63 - /* And now flush the block cache so that kernel sees the changes */
64 - invalidate_bdev(sb->s_bdev);
65 + if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
66 + /* As we bypass the pagecache we must now flush the inode so
67 + * that we see all the changes from userspace... */
68 + write_inode_now(inode, 1);
69 + /* And now flush the block cache so that kernel sees the
70 + * changes */
71 + invalidate_bdev(sb->s_bdev);
72 + }
73 mutex_lock(&inode->i_mutex);
74 mutex_lock(&dqopt->dqonoff_mutex);
75 if (sb_has_quota_loaded(sb, type)) {
76 error = -EBUSY;
77 goto out_lock;
78 }
79 - /* We don't want quota and atime on quota files (deadlocks possible)
80 - * Also nobody should write to the file - we use special IO operations
81 - * which ignore the immutable bit. */
82 - down_write(&dqopt->dqptr_sem);
83 - oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA);
84 - inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
85 - up_write(&dqopt->dqptr_sem);
86 - sb->dq_op->drop(inode);
87 +
88 + if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
89 + /* We don't want quota and atime on quota files (deadlocks
90 + * possible) Also nobody should write to the file - we use
91 + * special IO operations which ignore the immutable bit. */
92 + down_write(&dqopt->dqptr_sem);
93 + oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA);
94 + inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
95 + up_write(&dqopt->dqptr_sem);
96 + sb->dq_op->drop(inode);
97 + }
98
99 error = -EIO;
100 dqopt->files[type] = igrab(inode);
101 diff --git a/fs/quota.c b/fs/quota.c
102 index a8026f1..2c6ea78 100644
103 --- a/fs/quota.c
104 +++ b/fs/quota.c
105 @@ -160,6 +160,9 @@ static void quota_sync_sb(struct super_block *sb, int type)
106 int cnt;
107
108 sb->s_qcop->quota_sync(sb, type);
109 +
110 + if (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE)
111 + return;
112 /* This is not very clever (and fast) but currently I don't know about
113 * any other simple way of getting quota data to disk and we must get
114 * them there for userspace to be visible... */
115 diff --git a/include/linux/quota.h b/include/linux/quota.h
116 index 0e4b550..8dd5333 100644
117 --- a/include/linux/quota.h
118 +++ b/include/linux/quota.h
119 @@ -334,6 +334,13 @@ enum {
120 #define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED)
121 #define DQUOT_STATE_FLAGS (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED | \
122 DQUOT_SUSPENDED)
123 +/* Other quota flags */
124 +#define DQUOT_QUOTA_SYS_FILE (1 << 6) /* Quota file is a special
125 + * system file and user cannot
126 + * touch it. Filesystem is
127 + * responsible for setting
128 + * S_NOQUOTA, S_NOATIME flags
129 + */
130
131 static inline unsigned int dquot_state_flag(unsigned int flags, int type)
132 {
133 --
134 1.5.2.4
135