Merge git://git.infradead.org/~dwmw2/battery-2.6
[deliverable/linux.git] / fs / gfs2 / daemon.c
1 /*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
4 *
5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions
7 * of the GNU General Public License version 2.
8 */
9
10 #include <linux/sched.h>
11 #include <linux/slab.h>
12 #include <linux/spinlock.h>
13 #include <linux/completion.h>
14 #include <linux/buffer_head.h>
15 #include <linux/kthread.h>
16 #include <linux/delay.h>
17 #include <linux/gfs2_ondisk.h>
18 #include <linux/lm_interface.h>
19 #include <linux/freezer.h>
20
21 #include "gfs2.h"
22 #include "incore.h"
23 #include "daemon.h"
24 #include "glock.h"
25 #include "log.h"
26 #include "quota.h"
27 #include "recovery.h"
28 #include "super.h"
29 #include "util.h"
30
31 /* This uses schedule_timeout() instead of msleep() because it's good for
32 the daemons to wake up more often than the timeout when unmounting so
33 the user's unmount doesn't sit there forever.
34
35 The kthread functions used to start these daemons block and flush signals. */
36
37 /**
38 * gfs2_scand - Look for cached glocks and inodes to toss from memory
39 * @sdp: Pointer to GFS2 superblock
40 *
41 * One of these daemons runs, finding candidates to add to sd_reclaim_list.
42 * See gfs2_glockd()
43 */
44
45 int gfs2_scand(void *data)
46 {
47 struct gfs2_sbd *sdp = data;
48 unsigned long t;
49
50 while (!kthread_should_stop()) {
51 gfs2_scand_internal(sdp);
52 t = gfs2_tune_get(sdp, gt_scand_secs) * HZ;
53 if (freezing(current))
54 refrigerator();
55 schedule_timeout_interruptible(t);
56 }
57
58 return 0;
59 }
60
61 /**
62 * gfs2_glockd - Reclaim unused glock structures
63 * @sdp: Pointer to GFS2 superblock
64 *
65 * One or more of these daemons run, reclaiming glocks on sd_reclaim_list.
66 * Number of daemons can be set by user, with num_glockd mount option.
67 */
68
69 int gfs2_glockd(void *data)
70 {
71 struct gfs2_sbd *sdp = data;
72
73 while (!kthread_should_stop()) {
74 while (atomic_read(&sdp->sd_reclaim_count))
75 gfs2_reclaim_glock(sdp);
76
77 wait_event_interruptible(sdp->sd_reclaim_wq,
78 (atomic_read(&sdp->sd_reclaim_count) ||
79 kthread_should_stop()));
80 if (freezing(current))
81 refrigerator();
82 }
83
84 return 0;
85 }
86
87 /**
88 * gfs2_recoverd - Recover dead machine's journals
89 * @sdp: Pointer to GFS2 superblock
90 *
91 */
92
93 int gfs2_recoverd(void *data)
94 {
95 struct gfs2_sbd *sdp = data;
96 unsigned long t;
97
98 while (!kthread_should_stop()) {
99 gfs2_check_journals(sdp);
100 t = gfs2_tune_get(sdp, gt_recoverd_secs) * HZ;
101 if (freezing(current))
102 refrigerator();
103 schedule_timeout_interruptible(t);
104 }
105
106 return 0;
107 }
108
109 /**
110 * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks
111 * @sdp: Pointer to GFS2 superblock
112 *
113 * Also, periodically check to make sure that we're using the most recent
114 * journal index.
115 */
116
117 int gfs2_logd(void *data)
118 {
119 struct gfs2_sbd *sdp = data;
120 struct gfs2_holder ji_gh;
121 unsigned long t;
122 int need_flush;
123
124 while (!kthread_should_stop()) {
125 /* Advance the log tail */
126
127 t = sdp->sd_log_flush_time +
128 gfs2_tune_get(sdp, gt_log_flush_secs) * HZ;
129
130 gfs2_ail1_empty(sdp, DIO_ALL);
131 gfs2_log_lock(sdp);
132 need_flush = sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks);
133 gfs2_log_unlock(sdp);
134 if (need_flush || time_after_eq(jiffies, t)) {
135 gfs2_log_flush(sdp, NULL);
136 sdp->sd_log_flush_time = jiffies;
137 }
138
139 /* Check for latest journal index */
140
141 t = sdp->sd_jindex_refresh_time +
142 gfs2_tune_get(sdp, gt_jindex_refresh_secs) * HZ;
143
144 if (time_after_eq(jiffies, t)) {
145 if (!gfs2_jindex_hold(sdp, &ji_gh))
146 gfs2_glock_dq_uninit(&ji_gh);
147 sdp->sd_jindex_refresh_time = jiffies;
148 }
149
150 t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;
151 if (freezing(current))
152 refrigerator();
153 schedule_timeout_interruptible(t);
154 }
155
156 return 0;
157 }
158
159 /**
160 * gfs2_quotad - Write cached quota changes into the quota file
161 * @sdp: Pointer to GFS2 superblock
162 *
163 */
164
165 int gfs2_quotad(void *data)
166 {
167 struct gfs2_sbd *sdp = data;
168 unsigned long t;
169 int error;
170
171 while (!kthread_should_stop()) {
172 /* Update the master statfs file */
173
174 t = sdp->sd_statfs_sync_time +
175 gfs2_tune_get(sdp, gt_statfs_quantum) * HZ;
176
177 if (time_after_eq(jiffies, t)) {
178 error = gfs2_statfs_sync(sdp);
179 if (error &&
180 error != -EROFS &&
181 !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
182 fs_err(sdp, "quotad: (1) error=%d\n", error);
183 sdp->sd_statfs_sync_time = jiffies;
184 }
185
186 /* Update quota file */
187
188 t = sdp->sd_quota_sync_time +
189 gfs2_tune_get(sdp, gt_quota_quantum) * HZ;
190
191 if (time_after_eq(jiffies, t)) {
192 error = gfs2_quota_sync(sdp);
193 if (error &&
194 error != -EROFS &&
195 !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
196 fs_err(sdp, "quotad: (2) error=%d\n", error);
197 sdp->sd_quota_sync_time = jiffies;
198 }
199
200 gfs2_quota_scan(sdp);
201
202 t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ;
203 if (freezing(current))
204 refrigerator();
205 schedule_timeout_interruptible(t);
206 }
207
208 return 0;
209 }
210
This page took 0.060191 seconds and 6 git commands to generate.