blob: 683cb5bda870fc372e79500c105ddf16c9ab93b9 [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>
David Teiglandb3b94fa2006-01-16 16:50:04 +000019
20#include "gfs2.h"
Steven Whitehouse5c676f62006-02-27 17:23:27 -050021#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"
Steven Whitehouse5c676f62006-02-27 17:23:27 -050028#include "util.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000029
30/* This uses schedule_timeout() instead of msleep() because it's good for
31 the daemons to wake up more often than the timeout when unmounting so
32 the user's unmount doesn't sit there forever.
Steven Whitehouse907b9bc2006-09-25 09:26:04 -040033
David Teiglandb3b94fa2006-01-16 16:50:04 +000034 The kthread functions used to start these daemons block and flush signals. */
35
36/**
37 * gfs2_scand - Look for cached glocks and inodes to toss from memory
38 * @sdp: Pointer to GFS2 superblock
39 *
40 * One of these daemons runs, finding candidates to add to sd_reclaim_list.
41 * See gfs2_glockd()
42 */
43
44int gfs2_scand(void *data)
45{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -040046 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +000047 unsigned long t;
48
49 while (!kthread_should_stop()) {
50 gfs2_scand_internal(sdp);
51 t = gfs2_tune_get(sdp, gt_scand_secs) * HZ;
52 schedule_timeout_interruptible(t);
53 }
54
55 return 0;
56}
57
58/**
59 * gfs2_glockd - Reclaim unused glock structures
60 * @sdp: Pointer to GFS2 superblock
61 *
62 * One or more of these daemons run, reclaiming glocks on sd_reclaim_list.
63 * Number of daemons can be set by user, with num_glockd mount option.
64 */
65
66int gfs2_glockd(void *data)
67{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -040068 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +000069
70 while (!kthread_should_stop()) {
71 while (atomic_read(&sdp->sd_reclaim_count))
72 gfs2_reclaim_glock(sdp);
73
Steven Whitehouseb800a1c2006-04-24 13:13:56 -040074 wait_event_interruptible(sdp->sd_reclaim_wq,
75 (atomic_read(&sdp->sd_reclaim_count) ||
76 kthread_should_stop()));
David Teiglandb3b94fa2006-01-16 16:50:04 +000077 }
78
79 return 0;
80}
81
82/**
83 * gfs2_recoverd - Recover dead machine's journals
84 * @sdp: Pointer to GFS2 superblock
85 *
86 */
87
88int gfs2_recoverd(void *data)
89{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -040090 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +000091 unsigned long t;
92
93 while (!kthread_should_stop()) {
94 gfs2_check_journals(sdp);
95 t = gfs2_tune_get(sdp, gt_recoverd_secs) * HZ;
96 schedule_timeout_interruptible(t);
97 }
98
99 return 0;
100}
101
102/**
103 * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks
104 * @sdp: Pointer to GFS2 superblock
105 *
106 * Also, periodically check to make sure that we're using the most recent
107 * journal index.
108 */
109
110int gfs2_logd(void *data)
111{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -0400112 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000113 struct gfs2_holder ji_gh;
114 unsigned long t;
Steven Whitehouseb0041572006-11-23 10:51:34 -0500115 int need_flush;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000116
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);
Steven Whitehouseb0041572006-11-23 10:51:34 -0500124 gfs2_log_lock(sdp);
125 need_flush = sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks);
126 gfs2_log_unlock(sdp);
127 if (need_flush || time_after_eq(jiffies, t)) {
Steven Whitehouseb09e5932006-04-07 11:17:32 -0400128 gfs2_log_flush(sdp, NULL);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000129 sdp->sd_log_flush_time = jiffies;
130 }
131
132 /* Check for latest journal index */
133
134 t = sdp->sd_jindex_refresh_time +
135 gfs2_tune_get(sdp, gt_jindex_refresh_secs) * HZ;
136
137 if (time_after_eq(jiffies, t)) {
138 if (!gfs2_jindex_hold(sdp, &ji_gh))
139 gfs2_glock_dq_uninit(&ji_gh);
140 sdp->sd_jindex_refresh_time = jiffies;
141 }
142
143 t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;
144 schedule_timeout_interruptible(t);
145 }
146
147 return 0;
148}
149
150/**
151 * gfs2_quotad - Write cached quota changes into the quota file
152 * @sdp: Pointer to GFS2 superblock
153 *
154 */
155
156int gfs2_quotad(void *data)
157{
Steven Whitehouseb800a1c2006-04-24 13:13:56 -0400158 struct gfs2_sbd *sdp = data;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000159 unsigned long t;
160 int error;
161
162 while (!kthread_should_stop()) {
163 /* Update the master statfs file */
164
165 t = sdp->sd_statfs_sync_time +
166 gfs2_tune_get(sdp, gt_statfs_quantum) * HZ;
167
168 if (time_after_eq(jiffies, t)) {
169 error = gfs2_statfs_sync(sdp);
170 if (error &&
171 error != -EROFS &&
172 !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
173 fs_err(sdp, "quotad: (1) error=%d\n", error);
174 sdp->sd_statfs_sync_time = jiffies;
175 }
176
177 /* Update quota file */
178
179 t = sdp->sd_quota_sync_time +
180 gfs2_tune_get(sdp, gt_quota_quantum) * HZ;
181
182 if (time_after_eq(jiffies, t)) {
183 error = gfs2_quota_sync(sdp);
184 if (error &&
185 error != -EROFS &&
186 !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
187 fs_err(sdp, "quotad: (2) error=%d\n", error);
188 sdp->sd_quota_sync_time = jiffies;
189 }
190
191 gfs2_quota_scan(sdp);
192
193 t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ;
194 schedule_timeout_interruptible(t);
195 }
196
197 return 0;
198}
199