]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - fs/gfs2/daemon.c
[GFS2] Macros removal in gfs2.h
[linux-2.6-omap-h63xx.git] / fs / gfs2 / daemon.c
1 /*
2  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3  * Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
4  *
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>
17 #include <linux/gfs2_ondisk.h>
18 #include <asm/semaphore.h>
19
20 #include "gfs2.h"
21 #include "lm_interface.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 "unlinked.h"
30 #include "util.h"
31
32 /* This uses schedule_timeout() instead of msleep() because it's good for
33    the daemons to wake up more often than the timeout when unmounting so
34    the user's unmount doesn't sit there forever.
35    
36    The kthread functions used to start these daemons block and flush signals. */
37
38 /**
39  * gfs2_scand - Look for cached glocks and inodes to toss from memory
40  * @sdp: Pointer to GFS2 superblock
41  *
42  * One of these daemons runs, finding candidates to add to sd_reclaim_list.
43  * See gfs2_glockd()
44  */
45
46 int gfs2_scand(void *data)
47 {
48         struct gfs2_sbd *sdp = (struct gfs2_sbd *)data;
49         unsigned long t;
50
51         while (!kthread_should_stop()) {
52                 gfs2_scand_internal(sdp);
53                 t = gfs2_tune_get(sdp, gt_scand_secs) * HZ;
54                 schedule_timeout_interruptible(t);
55         }
56
57         return 0;
58 }
59
60 /**
61  * gfs2_glockd - Reclaim unused glock structures
62  * @sdp: Pointer to GFS2 superblock
63  *
64  * One or more of these daemons run, reclaiming glocks on sd_reclaim_list.
65  * Number of daemons can be set by user, with num_glockd mount option.
66  */
67
68 int gfs2_glockd(void *data)
69 {
70         struct gfs2_sbd *sdp = (struct gfs2_sbd *)data;
71         DECLARE_WAITQUEUE(wait_chan, current);
72
73         while (!kthread_should_stop()) {
74                 while (atomic_read(&sdp->sd_reclaim_count))
75                         gfs2_reclaim_glock(sdp);
76
77                 set_current_state(TASK_INTERRUPTIBLE);
78                 add_wait_queue(&sdp->sd_reclaim_wq, &wait_chan);
79                 if (!atomic_read(&sdp->sd_reclaim_count) &&
80                     !kthread_should_stop())
81                         schedule();
82                 remove_wait_queue(&sdp->sd_reclaim_wq, &wait_chan);
83                 set_current_state(TASK_RUNNING);
84         }
85
86         return 0;
87 }
88
89 /**
90  * gfs2_recoverd - Recover dead machine's journals
91  * @sdp: Pointer to GFS2 superblock
92  *
93  */
94
95 int gfs2_recoverd(void *data)
96 {
97         struct gfs2_sbd *sdp = (struct gfs2_sbd *)data;
98         unsigned long t;
99
100         while (!kthread_should_stop()) {
101                 gfs2_check_journals(sdp);
102                 t = gfs2_tune_get(sdp,  gt_recoverd_secs) * HZ;
103                 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
117 int gfs2_logd(void *data)
118 {
119         struct gfs2_sbd *sdp = (struct gfs2_sbd *)data;
120         struct gfs2_holder ji_gh;
121         unsigned long t;
122
123         while (!kthread_should_stop()) {
124                 /* Advance the log tail */
125
126                 t = sdp->sd_log_flush_time +
127                     gfs2_tune_get(sdp, gt_log_flush_secs) * HZ;
128
129                 gfs2_ail1_empty(sdp, DIO_ALL);
130
131                 if (time_after_eq(jiffies, t)) {
132                         gfs2_log_flush(sdp);
133                         sdp->sd_log_flush_time = jiffies;
134                 }
135
136                 /* Check for latest journal index */
137
138                 t = sdp->sd_jindex_refresh_time +
139                     gfs2_tune_get(sdp, gt_jindex_refresh_secs) * HZ;
140
141                 if (time_after_eq(jiffies, t)) {
142                         if (!gfs2_jindex_hold(sdp, &ji_gh))
143                                 gfs2_glock_dq_uninit(&ji_gh);
144                         sdp->sd_jindex_refresh_time = jiffies;
145                 }
146
147                 t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;
148                 schedule_timeout_interruptible(t);
149         }
150
151         return 0;
152 }
153
154 /**
155  * gfs2_quotad - Write cached quota changes into the quota file
156  * @sdp: Pointer to GFS2 superblock
157  *
158  */
159
160 int gfs2_quotad(void *data)
161 {
162         struct gfs2_sbd *sdp = (struct gfs2_sbd *)data;
163         unsigned long t;
164         int error;
165
166         while (!kthread_should_stop()) {
167                 /* Update the master statfs file */
168
169                 t = sdp->sd_statfs_sync_time +
170                     gfs2_tune_get(sdp, gt_statfs_quantum) * HZ;
171
172                 if (time_after_eq(jiffies, t)) {
173                         error = gfs2_statfs_sync(sdp);
174                         if (error &&
175                             error != -EROFS &&
176                             !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
177                                 fs_err(sdp, "quotad: (1) error=%d\n", error);
178                         sdp->sd_statfs_sync_time = jiffies;
179                 }
180
181                 /* Update quota file */
182
183                 t = sdp->sd_quota_sync_time +
184                     gfs2_tune_get(sdp, gt_quota_quantum) * HZ;
185
186                 if (time_after_eq(jiffies, t)) {
187                         error = gfs2_quota_sync(sdp);
188                         if (error &&
189                             error != -EROFS &&
190                             !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
191                                 fs_err(sdp, "quotad: (2) error=%d\n", error);
192                         sdp->sd_quota_sync_time = jiffies;
193                 }
194
195                 gfs2_quota_scan(sdp);
196
197                 t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ;
198                 schedule_timeout_interruptible(t);
199         }
200
201         return 0;
202 }
203
204 /**
205  * gfs2_inoded - Deallocate unlinked inodes
206  * @sdp: Pointer to GFS2 superblock
207  *
208  */
209
210 int gfs2_inoded(void *data)
211 {
212         struct gfs2_sbd *sdp = (struct gfs2_sbd *)data;
213         unsigned long t;
214         int error;
215
216         while (!kthread_should_stop()) {
217                 error = gfs2_unlinked_dealloc(sdp);
218                 if (error &&
219                     error != -EROFS &&
220                     !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
221                         fs_err(sdp, "inoded: error = %d\n", error);
222
223                 t = gfs2_tune_get(sdp, gt_inoded_secs) * HZ;
224                 schedule_timeout_interruptible(t);
225         }
226
227         return 0;
228 }
229