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.
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>
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.
34 The kthread functions used to start these daemons block and flush signals. */
37 * gfs2_scand - Look for cached glocks and inodes to toss from memory
38 * @sdp: Pointer to GFS2 superblock
40 * One of these daemons runs, finding candidates to add to sd_reclaim_list.
44 int gfs2_scand(void *data
)
46 struct gfs2_sbd
*sdp
= data
;
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
);
59 * gfs2_glockd - Reclaim unused glock structures
60 * @sdp: Pointer to GFS2 superblock
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.
66 int gfs2_glockd(void *data
)
68 struct gfs2_sbd
*sdp
= data
;
70 while (!kthread_should_stop()) {
71 while (atomic_read(&sdp
->sd_reclaim_count
))
72 gfs2_reclaim_glock(sdp
);
74 wait_event_interruptible(sdp
->sd_reclaim_wq
,
75 (atomic_read(&sdp
->sd_reclaim_count
) ||
76 kthread_should_stop()));
83 * gfs2_recoverd - Recover dead machine's journals
84 * @sdp: Pointer to GFS2 superblock
88 int gfs2_recoverd(void *data
)
90 struct gfs2_sbd
*sdp
= data
;
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
);
103 * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks
104 * @sdp: Pointer to GFS2 superblock
106 * Also, periodically check to make sure that we're using the most recent
110 int gfs2_logd(void *data
)
112 struct gfs2_sbd
*sdp
= data
;
113 struct gfs2_holder ji_gh
;
116 while (!kthread_should_stop()) {
117 /* Advance the log tail */
119 t
= sdp
->sd_log_flush_time
+
120 gfs2_tune_get(sdp
, gt_log_flush_secs
) * HZ
;
122 gfs2_ail1_empty(sdp
, DIO_ALL
);
124 if (time_after_eq(jiffies
, t
)) {
125 gfs2_log_flush(sdp
, NULL
);
126 sdp
->sd_log_flush_time
= jiffies
;
129 /* Check for latest journal index */
131 t
= sdp
->sd_jindex_refresh_time
+
132 gfs2_tune_get(sdp
, gt_jindex_refresh_secs
) * HZ
;
134 if (time_after_eq(jiffies
, t
)) {
135 if (!gfs2_jindex_hold(sdp
, &ji_gh
))
136 gfs2_glock_dq_uninit(&ji_gh
);
137 sdp
->sd_jindex_refresh_time
= jiffies
;
140 t
= gfs2_tune_get(sdp
, gt_logd_secs
) * HZ
;
141 schedule_timeout_interruptible(t
);
148 * gfs2_quotad - Write cached quota changes into the quota file
149 * @sdp: Pointer to GFS2 superblock
153 int gfs2_quotad(void *data
)
155 struct gfs2_sbd
*sdp
= data
;
159 while (!kthread_should_stop()) {
160 /* Update the master statfs file */
162 t
= sdp
->sd_statfs_sync_time
+
163 gfs2_tune_get(sdp
, gt_statfs_quantum
) * HZ
;
165 if (time_after_eq(jiffies
, t
)) {
166 error
= gfs2_statfs_sync(sdp
);
169 !test_bit(SDF_SHUTDOWN
, &sdp
->sd_flags
))
170 fs_err(sdp
, "quotad: (1) error=%d\n", error
);
171 sdp
->sd_statfs_sync_time
= jiffies
;
174 /* Update quota file */
176 t
= sdp
->sd_quota_sync_time
+
177 gfs2_tune_get(sdp
, gt_quota_quantum
) * HZ
;
179 if (time_after_eq(jiffies
, t
)) {
180 error
= gfs2_quota_sync(sdp
);
183 !test_bit(SDF_SHUTDOWN
, &sdp
->sd_flags
))
184 fs_err(sdp
, "quotad: (2) error=%d\n", error
);
185 sdp
->sd_quota_sync_time
= jiffies
;
188 gfs2_quota_scan(sdp
);
190 t
= gfs2_tune_get(sdp
, gt_quotad_secs
) * HZ
;
191 schedule_timeout_interruptible(t
);