blob: c2b5d69044c61abdbfc24c5a2ead0077c6066e8e [file] [log] [blame]
David Teiglandb3b94fa2006-01-16 16:50:04 +00001/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2005 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 v.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>
Steven Whitehouse5c676f62006-02-27 17:23:27 -050017#include <linux/gfs2_ondisk.h>
David Teiglandb3b94fa2006-01-16 16:50:04 +000018#include <asm/semaphore.h>
19
20#include "gfs2.h"
Steven Whitehouse5c676f62006-02-27 17:23:27 -050021#include "lm_interface.h"
22#include "incore.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000023#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 "unlinked.h"
Steven Whitehouse5c676f62006-02-27 17:23:27 -050030#include "util.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000031
32/* This uses schedule_timeout() instead of msleep() because it's good for
33 the daemons to wake up more often than the timeout when unmounting so
34 the user's unmount doesn't sit there forever.
35
36 The kthread functions used to start these daemons block and flush signals. */
37
38/**
39 * gfs2_scand - Look for cached glocks and inodes to toss from memory
40 * @sdp: Pointer to GFS2 superblock
41 *
42 * One of these daemons runs, finding candidates to add to sd_reclaim_list.
43 * See gfs2_glockd()
44 */
45
46int gfs2_scand(void *data)
47{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -040048 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +000049 unsigned long t;
50
51 while (!kthread_should_stop()) {
52 gfs2_scand_internal(sdp);
53 t = gfs2_tune_get(sdp, gt_scand_secs) * HZ;
54 schedule_timeout_interruptible(t);
55 }
56
57 return 0;
58}
59
60/**
61 * gfs2_glockd - Reclaim unused glock structures
62 * @sdp: Pointer to GFS2 superblock
63 *
64 * One or more of these daemons run, reclaiming glocks on sd_reclaim_list.
65 * Number of daemons can be set by user, with num_glockd mount option.
66 */
67
68int gfs2_glockd(void *data)
69{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -040070 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +000071
72 while (!kthread_should_stop()) {
73 while (atomic_read(&sdp->sd_reclaim_count))
74 gfs2_reclaim_glock(sdp);
75
Steven Whitehouseb800a1c2006-04-24 13:13:56 -040076 wait_event_interruptible(sdp->sd_reclaim_wq,
77 (atomic_read(&sdp->sd_reclaim_count) ||
78 kthread_should_stop()));
David Teiglandb3b94fa2006-01-16 16:50:04 +000079 }
80
81 return 0;
82}
83
84/**
85 * gfs2_recoverd - Recover dead machine's journals
86 * @sdp: Pointer to GFS2 superblock
87 *
88 */
89
90int gfs2_recoverd(void *data)
91{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -040092 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +000093 unsigned long t;
94
95 while (!kthread_should_stop()) {
96 gfs2_check_journals(sdp);
97 t = gfs2_tune_get(sdp, gt_recoverd_secs) * HZ;
98 schedule_timeout_interruptible(t);
99 }
100
101 return 0;
102}
103
104/**
105 * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks
106 * @sdp: Pointer to GFS2 superblock
107 *
108 * Also, periodically check to make sure that we're using the most recent
109 * journal index.
110 */
111
112int gfs2_logd(void *data)
113{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -0400114 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000115 struct gfs2_holder ji_gh;
116 unsigned long t;
117
118 while (!kthread_should_stop()) {
119 /* Advance the log tail */
120
121 t = sdp->sd_log_flush_time +
122 gfs2_tune_get(sdp, gt_log_flush_secs) * HZ;
123
124 gfs2_ail1_empty(sdp, DIO_ALL);
125
126 if (time_after_eq(jiffies, t)) {
Steven Whitehouseb09e5932006-04-07 11:17:32 -0400127 gfs2_log_flush(sdp, NULL);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000128 sdp->sd_log_flush_time = jiffies;
129 }
130
131 /* Check for latest journal index */
132
133 t = sdp->sd_jindex_refresh_time +
134 gfs2_tune_get(sdp, gt_jindex_refresh_secs) * HZ;
135
136 if (time_after_eq(jiffies, t)) {
137 if (!gfs2_jindex_hold(sdp, &ji_gh))
138 gfs2_glock_dq_uninit(&ji_gh);
139 sdp->sd_jindex_refresh_time = jiffies;
140 }
141
142 t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;
143 schedule_timeout_interruptible(t);
144 }
145
146 return 0;
147}
148
149/**
150 * gfs2_quotad - Write cached quota changes into the quota file
151 * @sdp: Pointer to GFS2 superblock
152 *
153 */
154
155int gfs2_quotad(void *data)
156{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -0400157 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000158 unsigned long t;
159 int error;
160
161 while (!kthread_should_stop()) {
162 /* Update the master statfs file */
163
164 t = sdp->sd_statfs_sync_time +
165 gfs2_tune_get(sdp, gt_statfs_quantum) * HZ;
166
167 if (time_after_eq(jiffies, t)) {
168 error = gfs2_statfs_sync(sdp);
169 if (error &&
170 error != -EROFS &&
171 !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
172 fs_err(sdp, "quotad: (1) error=%d\n", error);
173 sdp->sd_statfs_sync_time = jiffies;
174 }
175
176 /* Update quota file */
177
178 t = sdp->sd_quota_sync_time +
179 gfs2_tune_get(sdp, gt_quota_quantum) * HZ;
180
181 if (time_after_eq(jiffies, t)) {
182 error = gfs2_quota_sync(sdp);
183 if (error &&
184 error != -EROFS &&
185 !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
186 fs_err(sdp, "quotad: (2) error=%d\n", error);
187 sdp->sd_quota_sync_time = jiffies;
188 }
189
190 gfs2_quota_scan(sdp);
191
192 t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ;
193 schedule_timeout_interruptible(t);
194 }
195
196 return 0;
197}
198
199/**
200 * gfs2_inoded - Deallocate unlinked inodes
201 * @sdp: Pointer to GFS2 superblock
202 *
203 */
204
205int gfs2_inoded(void *data)
206{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -0400207 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000208 unsigned long t;
209 int error;
210
211 while (!kthread_should_stop()) {
212 error = gfs2_unlinked_dealloc(sdp);
213 if (error &&
214 error != -EROFS &&
215 !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
216 fs_err(sdp, "inoded: error = %d\n", error);
217
218 t = gfs2_tune_get(sdp, gt_inoded_secs) * HZ;
219 schedule_timeout_interruptible(t);
220 }
221
222 return 0;
223}
224