blob: 9e7b9f296786dd47067e4061014840435a4e5f71 [file] [log] [blame]
David Teiglandb3b94fa2006-01-16 16:50:04 +00001/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
Steven Whitehouse3a8a9a12006-05-18 15:09:15 -04003 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
David Teiglandb3b94fa2006-01-16 16:50:04 +00004 *
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
19#include "gfs2.h"
Steven Whitehouse5c676f62006-02-27 17:23:27 -050020#include "lm_interface.h"
21#include "incore.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000022#include "daemon.h"
23#include "glock.h"
24#include "log.h"
25#include "quota.h"
26#include "recovery.h"
27#include "super.h"
28#include "unlinked.h"
Steven Whitehouse5c676f62006-02-27 17:23:27 -050029#include "util.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000030
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
45int gfs2_scand(void *data)
46{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -040047 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +000048 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 schedule_timeout_interruptible(t);
54 }
55
56 return 0;
57}
58
59/**
60 * gfs2_glockd - Reclaim unused glock structures
61 * @sdp: Pointer to GFS2 superblock
62 *
63 * One or more of these daemons run, reclaiming glocks on sd_reclaim_list.
64 * Number of daemons can be set by user, with num_glockd mount option.
65 */
66
67int gfs2_glockd(void *data)
68{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -040069 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +000070
71 while (!kthread_should_stop()) {
72 while (atomic_read(&sdp->sd_reclaim_count))
73 gfs2_reclaim_glock(sdp);
74
Steven Whitehouseb800a1c2006-04-24 13:13:56 -040075 wait_event_interruptible(sdp->sd_reclaim_wq,
76 (atomic_read(&sdp->sd_reclaim_count) ||
77 kthread_should_stop()));
David Teiglandb3b94fa2006-01-16 16:50:04 +000078 }
79
80 return 0;
81}
82
83/**
84 * gfs2_recoverd - Recover dead machine's journals
85 * @sdp: Pointer to GFS2 superblock
86 *
87 */
88
89int gfs2_recoverd(void *data)
90{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -040091 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +000092 unsigned long t;
93
94 while (!kthread_should_stop()) {
95 gfs2_check_journals(sdp);
96 t = gfs2_tune_get(sdp, gt_recoverd_secs) * HZ;
97 schedule_timeout_interruptible(t);
98 }
99
100 return 0;
101}
102
103/**
104 * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks
105 * @sdp: Pointer to GFS2 superblock
106 *
107 * Also, periodically check to make sure that we're using the most recent
108 * journal index.
109 */
110
111int gfs2_logd(void *data)
112{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -0400113 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000114 struct gfs2_holder ji_gh;
115 unsigned long t;
116
117 while (!kthread_should_stop()) {
118 /* Advance the log tail */
119
120 t = sdp->sd_log_flush_time +
121 gfs2_tune_get(sdp, gt_log_flush_secs) * HZ;
122
123 gfs2_ail1_empty(sdp, DIO_ALL);
124
125 if (time_after_eq(jiffies, t)) {
Steven Whitehouseb09e5932006-04-07 11:17:32 -0400126 gfs2_log_flush(sdp, NULL);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000127 sdp->sd_log_flush_time = jiffies;
128 }
129
130 /* Check for latest journal index */
131
132 t = sdp->sd_jindex_refresh_time +
133 gfs2_tune_get(sdp, gt_jindex_refresh_secs) * HZ;
134
135 if (time_after_eq(jiffies, t)) {
136 if (!gfs2_jindex_hold(sdp, &ji_gh))
137 gfs2_glock_dq_uninit(&ji_gh);
138 sdp->sd_jindex_refresh_time = jiffies;
139 }
140
141 t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;
142 schedule_timeout_interruptible(t);
143 }
144
145 return 0;
146}
147
148/**
149 * gfs2_quotad - Write cached quota changes into the quota file
150 * @sdp: Pointer to GFS2 superblock
151 *
152 */
153
154int gfs2_quotad(void *data)
155{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -0400156 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000157 unsigned long t;
158 int error;
159
160 while (!kthread_should_stop()) {
161 /* Update the master statfs file */
162
163 t = sdp->sd_statfs_sync_time +
164 gfs2_tune_get(sdp, gt_statfs_quantum) * HZ;
165
166 if (time_after_eq(jiffies, t)) {
167 error = gfs2_statfs_sync(sdp);
168 if (error &&
169 error != -EROFS &&
170 !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
171 fs_err(sdp, "quotad: (1) error=%d\n", error);
172 sdp->sd_statfs_sync_time = jiffies;
173 }
174
175 /* Update quota file */
176
177 t = sdp->sd_quota_sync_time +
178 gfs2_tune_get(sdp, gt_quota_quantum) * HZ;
179
180 if (time_after_eq(jiffies, t)) {
181 error = gfs2_quota_sync(sdp);
182 if (error &&
183 error != -EROFS &&
184 !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
185 fs_err(sdp, "quotad: (2) error=%d\n", error);
186 sdp->sd_quota_sync_time = jiffies;
187 }
188
189 gfs2_quota_scan(sdp);
190
191 t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ;
192 schedule_timeout_interruptible(t);
193 }
194
195 return 0;
196}
197
198/**
199 * gfs2_inoded - Deallocate unlinked inodes
200 * @sdp: Pointer to GFS2 superblock
201 *
202 */
203
204int gfs2_inoded(void *data)
205{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -0400206 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000207 unsigned long t;
208 int error;
209
210 while (!kthread_should_stop()) {
211 error = gfs2_unlinked_dealloc(sdp);
212 if (error &&
213 error != -EROFS &&
214 !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
215 fs_err(sdp, "inoded: error = %d\n", error);
216
217 t = gfs2_tune_get(sdp, gt_inoded_secs) * HZ;
218 schedule_timeout_interruptible(t);
219 }
220
221 return 0;
222}
223