blob: 3548d9f31e0d5c6918d74115a5fd0f9f2b133f48 [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
Steven Whitehousee9fc2aa2006-09-01 11:05:15 -04007 * of the GNU General Public License version 2.
David Teiglandb3b94fa2006-01-16 16:50:04 +00008 */
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>
Fabio Massimo Di Nitto7d308592006-09-19 07:56:29 +020018#include <linux/lm_interface.h>
Abhijith Dasb3657622007-06-27 11:06:19 -050019#include <linux/freezer.h>
David Teiglandb3b94fa2006-01-16 16:50:04 +000020
21#include "gfs2.h"
Steven Whitehouse5c676f62006-02-27 17:23:27 -050022#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"
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.
Steven Whitehouse907b9bc2006-09-25 09:26:04 -040034
David Teiglandb3b94fa2006-01-16 16:50:04 +000035 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;
Abhijith Dasb3657622007-06-27 11:06:19 -050053 if (freezing(current))
54 refrigerator();
David Teiglandb3b94fa2006-01-16 16:50:04 +000055 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
69int gfs2_glockd(void *data)
70{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -040071 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +000072
73 while (!kthread_should_stop()) {
74 while (atomic_read(&sdp->sd_reclaim_count))
75 gfs2_reclaim_glock(sdp);
76
Steven Whitehouseb800a1c2006-04-24 13:13:56 -040077 wait_event_interruptible(sdp->sd_reclaim_wq,
78 (atomic_read(&sdp->sd_reclaim_count) ||
79 kthread_should_stop()));
Abhijith Dasb3657622007-06-27 11:06:19 -050080 if (freezing(current))
81 refrigerator();
David Teiglandb3b94fa2006-01-16 16:50:04 +000082 }
83
84 return 0;
85}
86
87/**
88 * gfs2_recoverd - Recover dead machine's journals
89 * @sdp: Pointer to GFS2 superblock
90 *
91 */
92
93int gfs2_recoverd(void *data)
94{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -040095 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +000096 unsigned long t;
97
98 while (!kthread_should_stop()) {
99 gfs2_check_journals(sdp);
100 t = gfs2_tune_get(sdp, gt_recoverd_secs) * HZ;
Abhijith Dasb3657622007-06-27 11:06:19 -0500101 if (freezing(current))
102 refrigerator();
David Teiglandb3b94fa2006-01-16 16:50:04 +0000103 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
117int gfs2_logd(void *data)
118{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -0400119 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000120 struct gfs2_holder ji_gh;
121 unsigned long t;
Steven Whitehouseb0041572006-11-23 10:51:34 -0500122 int need_flush;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000123
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);
Steven Whitehouseb0041572006-11-23 10:51:34 -0500131 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)) {
Steven Whitehouseb09e5932006-04-07 11:17:32 -0400135 gfs2_log_flush(sdp, NULL);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000136 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;
Abhijith Dasb3657622007-06-27 11:06:19 -0500151 if (freezing(current))
152 refrigerator();
David Teiglandb3b94fa2006-01-16 16:50:04 +0000153 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
165int gfs2_quotad(void *data)
166{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -0400167 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000168 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;
Abhijith Dasb3657622007-06-27 11:06:19 -0500203 if (freezing(current))
204 refrigerator();
David Teiglandb3b94fa2006-01-16 16:50:04 +0000205 schedule_timeout_interruptible(t);
206 }
207
208 return 0;
209}
210