]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.suse/ocfs2-Implement-quota-syncing-thread.patch
Updated xen patches taken from suse.
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.suse / ocfs2-Implement-quota-syncing-thread.patch
1 From: Jan Kara <jack@suse.cz>
2 References: fate#302681
3 Subject: [PATCH 27/28] ocfs2: Implement quota syncing thread
4 Patch-mainline: 2.6.29?
5
6 This patch implements functions and timer setup which handles periodic
7 syncing of locally cached quota information to global quota file.
8
9 Signed-off-by: Jan Kara <jack@suse.cz>
10 ---
11 fs/ocfs2/quota.h | 3 ++
12 fs/ocfs2/quota_global.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++
13 fs/ocfs2/quota_local.c | 4 ++
14 mm/pdflush.c | 1
15 4 files changed, 79 insertions(+)
16
17 --- a/fs/ocfs2/quota.h
18 +++ b/fs/ocfs2/quota.h
19 @@ -14,6 +14,7 @@
20 #include <linux/quota.h>
21 #include <linux/list.h>
22 #include <linux/dqblk_qtree.h>
23 +#include <linux/timer.h>
24
25 #include "ocfs2.h"
26
27 @@ -43,6 +44,7 @@ struct ocfs2_mem_dqinfo {
28 unsigned int dqi_chunks; /* Number of chunks in local quota file */
29 unsigned int dqi_blocks; /* Number of blocks allocated for local quota file */
30 unsigned int dqi_syncms; /* How often should we sync with other nodes */
31 + unsigned int dqi_syncjiff; /* Precomputed dqi_syncms in jiffies */
32 struct list_head dqi_chunk; /* List of chunks */
33 struct inode *dqi_gqinode; /* Global quota file inode */
34 struct ocfs2_lock_res dqi_gqlock; /* Lock protecting quota information structure */
35 @@ -51,6 +53,7 @@ struct ocfs2_mem_dqinfo {
36 struct buffer_head *dqi_lqi_bh; /* Buffer head with local quota file inode */
37 struct buffer_head *dqi_ibh; /* Buffer with information header */
38 struct qtree_mem_dqinfo dqi_gi; /* Info about global file */
39 + struct timer_list dqi_sync_timer; /* Timer for syncing dquots */
40 };
41
42 static inline struct ocfs2_dquot *OCFS2_DQUOT(struct dquot *dquot)
43 --- a/fs/ocfs2/quota_global.c
44 +++ b/fs/ocfs2/quota_global.c
45 @@ -1,10 +1,14 @@
46 /*
47 * Implementation of operations over global quota file
48 */
49 +#include <linux/spinlock.h>
50 #include <linux/fs.h>
51 #include <linux/quota.h>
52 #include <linux/quotaops.h>
53 #include <linux/dqblk_qtree.h>
54 +#include <linux/jiffies.h>
55 +#include <linux/timer.h>
56 +#include <linux/writeback.h>
57
58 #define MLOG_MASK_PREFIX ML_QUOTA
59 #include <cluster/masklog.h>
60 @@ -19,6 +23,8 @@
61 #include "dlmglue.h"
62 #include "quota.h"
63
64 +static void qsync_timer_fn(unsigned long oinfo_ptr);
65 +
66 static void ocfs2_global_disk2memdqb(struct dquot *dquot, void *dp)
67 {
68 struct ocfs2_global_disk_dqblk *d = dp;
69 @@ -269,6 +275,7 @@ int ocfs2_global_read_info(struct super_
70 info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
71 info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);
72 oinfo->dqi_syncms = le32_to_cpu(dinfo.dqi_syncms);
73 + oinfo->dqi_syncjiff = msecs_to_jiffies(oinfo->dqi_syncms);
74 oinfo->dqi_gi.dqi_blocks = le32_to_cpu(dinfo.dqi_blocks);
75 oinfo->dqi_gi.dqi_free_blk = le32_to_cpu(dinfo.dqi_free_blk);
76 oinfo->dqi_gi.dqi_free_entry = le32_to_cpu(dinfo.dqi_free_entry);
77 @@ -276,6 +283,10 @@ int ocfs2_global_read_info(struct super_
78 oinfo->dqi_gi.dqi_usable_bs = sb->s_blocksize -
79 OCFS2_QBLK_RESERVED_SPACE;
80 oinfo->dqi_gi.dqi_qtree_depth = qtree_depth(&oinfo->dqi_gi);
81 + setup_timer(&oinfo->dqi_sync_timer, qsync_timer_fn,
82 + (unsigned long)oinfo);
83 + mod_timer(&oinfo->dqi_sync_timer,
84 + round_jiffies(jiffies + oinfo->dqi_syncjiff));
85 out_err:
86 mlog_exit(status);
87 return status;
88 @@ -463,6 +474,66 @@ out:
89 }
90
91 /*
92 + * Functions for periodic syncing of dquots with global file
93 + */
94 +static int ocfs2_sync_dquot_helper(struct dquot *dquot, unsigned long type)
95 +{
96 + handle_t *handle;
97 + struct super_block *sb = dquot->dq_sb;
98 + struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;
99 + struct ocfs2_super *osb = OCFS2_SB(sb);
100 + int status = 0;
101 +
102 + mlog_entry("id=%u qtype=%u type=%lu device=%s\n", dquot->dq_id,
103 + dquot->dq_type, type, sb->s_id);
104 + if (type != dquot->dq_type)
105 + goto out;
106 + status = ocfs2_lock_global_qf(oinfo, 1);
107 + if (status < 0)
108 + goto out;
109 +
110 + handle = ocfs2_start_trans(osb, OCFS2_QSYNC_CREDITS);
111 + if (IS_ERR(handle)) {
112 + status = PTR_ERR(handle);
113 + mlog_errno(status);
114 + goto out_ilock;
115 + }
116 + mutex_lock(&sb_dqopt(sb)->dqio_mutex);
117 + status = ocfs2_sync_dquot(dquot);
118 + mutex_unlock(&sb_dqopt(sb)->dqio_mutex);
119 + if (status < 0)
120 + mlog_errno(status);
121 + /* We have to write local structure as well... */
122 + dquot_mark_dquot_dirty(dquot);
123 + status = dquot_commit(dquot);
124 + if (status < 0)
125 + mlog_errno(status);
126 + ocfs2_commit_trans(osb, handle);
127 +out_ilock:
128 + ocfs2_unlock_global_qf(oinfo, 1);
129 +out:
130 + mlog_exit(status);
131 + return status;
132 +}
133 +
134 +static void ocfs2_do_qsync(unsigned long oinfo_ptr)
135 +{
136 + struct ocfs2_mem_dqinfo *oinfo = (struct ocfs2_mem_dqinfo *)oinfo_ptr;
137 + struct super_block *sb = oinfo->dqi_gqinode->i_sb;
138 +
139 + dquot_scan_active(sb, ocfs2_sync_dquot_helper, oinfo->dqi_type);
140 +}
141 +
142 +static void qsync_timer_fn(unsigned long oinfo_ptr)
143 +{
144 + struct ocfs2_mem_dqinfo *oinfo = (struct ocfs2_mem_dqinfo *)oinfo_ptr;
145 +
146 + pdflush_operation(ocfs2_do_qsync, oinfo_ptr);
147 + mod_timer(&oinfo->dqi_sync_timer,
148 + round_jiffies(jiffies + oinfo->dqi_syncjiff));
149 +}
150 +
151 +/*
152 * Wrappers for generic quota functions
153 */
154
155 --- a/fs/ocfs2/quota_local.c
156 +++ b/fs/ocfs2/quota_local.c
157 @@ -368,6 +368,10 @@ static int ocfs2_local_free_info(struct
158 int mark_clean = 1, len;
159 int status;
160
161 + /* At this point we know there are no more dquots and thus
162 + * even if there's some sync in the pdflush queue, it won't
163 + * find any dquots and return without doing anything */
164 + del_timer_sync(&oinfo->dqi_sync_timer);
165 iput(oinfo->dqi_gqinode);
166 ocfs2_simple_drop_lockres(OCFS2_SB(sb), &oinfo->dqi_gqlock);
167 ocfs2_lock_res_free(&oinfo->dqi_gqlock);
168 --- a/mm/pdflush.c
169 +++ b/mm/pdflush.c
170 @@ -225,6 +225,7 @@ int pdflush_operation(void (*fn)(unsigne
171
172 return ret;
173 }
174 +EXPORT_SYMBOL(pdflush_operation);
175
176 static void start_one_pdflush_thread(void)
177 {