ACPI: thinkpad-acpi: keep track of module state
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / fs / gfs2 / daemon.c
blob3548d9f31e0d5c6918d74115a5fd0f9f2b133f48
1 /*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
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 */
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>
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"
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.
35 The kthread functions used to start these daemons block and flush signals. */
37 /**
38 * gfs2_scand - Look for cached glocks and inodes to toss from memory
39 * @sdp: Pointer to GFS2 superblock
41 * One of these daemons runs, finding candidates to add to sd_reclaim_list.
42 * See gfs2_glockd()
45 int gfs2_scand(void *data)
47 struct gfs2_sbd *sdp = data;
48 unsigned long t;
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);
58 return 0;
61 /**
62 * gfs2_glockd - Reclaim unused glock structures
63 * @sdp: Pointer to GFS2 superblock
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.
69 int gfs2_glockd(void *data)
71 struct gfs2_sbd *sdp = data;
73 while (!kthread_should_stop()) {
74 while (atomic_read(&sdp->sd_reclaim_count))
75 gfs2_reclaim_glock(sdp);
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();
84 return 0;
87 /**
88 * gfs2_recoverd - Recover dead machine's journals
89 * @sdp: Pointer to GFS2 superblock
93 int gfs2_recoverd(void *data)
95 struct gfs2_sbd *sdp = data;
96 unsigned long t;
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);
106 return 0;
110 * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks
111 * @sdp: Pointer to GFS2 superblock
113 * Also, periodically check to make sure that we're using the most recent
114 * journal index.
117 int gfs2_logd(void *data)
119 struct gfs2_sbd *sdp = data;
120 struct gfs2_holder ji_gh;
121 unsigned long t;
122 int need_flush;
124 while (!kthread_should_stop()) {
125 /* Advance the log tail */
127 t = sdp->sd_log_flush_time +
128 gfs2_tune_get(sdp, gt_log_flush_secs) * HZ;
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;
139 /* Check for latest journal index */
141 t = sdp->sd_jindex_refresh_time +
142 gfs2_tune_get(sdp, gt_jindex_refresh_secs) * HZ;
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;
150 t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;
151 if (freezing(current))
152 refrigerator();
153 schedule_timeout_interruptible(t);
156 return 0;
160 * gfs2_quotad - Write cached quota changes into the quota file
161 * @sdp: Pointer to GFS2 superblock
165 int gfs2_quotad(void *data)
167 struct gfs2_sbd *sdp = data;
168 unsigned long t;
169 int error;
171 while (!kthread_should_stop()) {
172 /* Update the master statfs file */
174 t = sdp->sd_statfs_sync_time +
175 gfs2_tune_get(sdp, gt_statfs_quantum) * HZ;
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;
186 /* Update quota file */
188 t = sdp->sd_quota_sync_time +
189 gfs2_tune_get(sdp, gt_quota_quantum) * HZ;
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;
200 gfs2_quota_scan(sdp);
202 t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ;
203 if (freezing(current))
204 refrigerator();
205 schedule_timeout_interruptible(t);
208 return 0;