]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.suse/quota-Introduce-DQUOT_QUOTA_SYS_FILE-flag.patch
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.suse / quota-Introduce-DQUOT_QUOTA_SYS_FILE-flag.patch
CommitLineData
2cb7cef9
BS
1From: Jan Kara <jack@suse.cz>
2References: fate#302681
3Subject: [PATCH 10/28] quota: Introduce DQUOT_QUOTA_SYS_FILE flag
4Patch-mainline: 2.6.29?
5
6If filesystem can handle quota files as system files hidden from users, we can
7skip a lot of cache invalidation, syncing, inode flags setting etc. when
8turning quotas on, off and quota_sync. Allow filesystem to indicate that it is
9hiding quota files from users by DQUOT_QUOTA_SYS_FILE flag.
10
11Signed-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
18diff --git a/fs/dquot.c b/fs/dquot.c
19index 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);
101diff --git a/fs/quota.c b/fs/quota.c
102index 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... */
115diff --git a/include/linux/quota.h b/include/linux/quota.h
116index 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--
1341.5.2.4
135