]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - fs/gfs2/daemon.c
[GFS2] Tidy up daemon.c
[linux-2.6.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 = 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 = data;
71
72         while (!kthread_should_stop()) {
73                 while (atomic_read(&sdp->sd_reclaim_count))
74                         gfs2_reclaim_glock(sdp);
75
76                 wait_event_interruptible(sdp->sd_reclaim_wq,
77                                          (atomic_read(&sdp->sd_reclaim_count) ||
78                                          kthread_should_stop()));
79         }
80
81         return 0;
82 }
83
84 /**
85  * gfs2_recoverd - Recover dead machine's journals
86  * @sdp: Pointer to GFS2 superblock
87  *
88  */
89
90 int gfs2_recoverd(void *data)
91 {
92         struct gfs2_sbd *sdp = data;
93         unsigned long t;
94
95         while (!kthread_should_stop()) {
96                 gfs2_check_journals(sdp);
97                 t = gfs2_tune_get(sdp,  gt_recoverd_secs) * HZ;
98                 schedule_timeout_interruptible(t);
99         }
100
101         return 0;
102 }
103
104 /**
105  * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks
106  * @sdp: Pointer to GFS2 superblock
107  *
108  * Also, periodically check to make sure that we're using the most recent
109  * journal index.
110  */
111
112 int gfs2_logd(void *data)
113 {
114         struct gfs2_sbd *sdp = data;
115         struct gfs2_holder ji_gh;
116         unsigned long t;
117
118         while (!kthread_should_stop()) {
119                 /* Advance the log tail */
120
121                 t = sdp->sd_log_flush_time +
122                     gfs2_tune_get(sdp, gt_log_flush_secs) * HZ;
123
124                 gfs2_ail1_empty(sdp, DIO_ALL);
125
126                 if (time_after_eq(jiffies, t)) {
127                         gfs2_log_flush(sdp, NULL);
128                         sdp->sd_log_flush_time = jiffies;
129                 }
130
131                 /* Check for latest journal index */
132
133                 t = sdp->sd_jindex_refresh_time +
134                     gfs2_tune_get(sdp, gt_jindex_refresh_secs) * HZ;
135
136                 if (time_after_eq(jiffies, t)) {
137                         if (!gfs2_jindex_hold(sdp, &ji_gh))
138                                 gfs2_glock_dq_uninit(&ji_gh);
139                         sdp->sd_jindex_refresh_time = jiffies;
140                 }
141
142                 t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;
143                 schedule_timeout_interruptible(t);
144         }
145
146         return 0;
147 }
148
149 /**
150  * gfs2_quotad - Write cached quota changes into the quota file
151  * @sdp: Pointer to GFS2 superblock
152  *
153  */
154
155 int gfs2_quotad(void *data)
156 {
157         struct gfs2_sbd *sdp = data;
158         unsigned long t;
159         int error;
160
161         while (!kthread_should_stop()) {
162                 /* Update the master statfs file */
163
164                 t = sdp->sd_statfs_sync_time +
165                     gfs2_tune_get(sdp, gt_statfs_quantum) * HZ;
166
167                 if (time_after_eq(jiffies, t)) {
168                         error = gfs2_statfs_sync(sdp);
169                         if (error &&
170                             error != -EROFS &&
171                             !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
172                                 fs_err(sdp, "quotad: (1) error=%d\n", error);
173                         sdp->sd_statfs_sync_time = jiffies;
174                 }
175
176                 /* Update quota file */
177
178                 t = sdp->sd_quota_sync_time +
179                     gfs2_tune_get(sdp, gt_quota_quantum) * HZ;
180
181                 if (time_after_eq(jiffies, t)) {
182                         error = gfs2_quota_sync(sdp);
183                         if (error &&
184                             error != -EROFS &&
185                             !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
186                                 fs_err(sdp, "quotad: (2) error=%d\n", error);
187                         sdp->sd_quota_sync_time = jiffies;
188                 }
189
190                 gfs2_quota_scan(sdp);
191
192                 t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ;
193                 schedule_timeout_interruptible(t);
194         }
195
196         return 0;
197 }
198
199 /**
200  * gfs2_inoded - Deallocate unlinked inodes
201  * @sdp: Pointer to GFS2 superblock
202  *
203  */
204
205 int gfs2_inoded(void *data)
206 {
207         struct gfs2_sbd *sdp = data;
208         unsigned long t;
209         int error;
210
211         while (!kthread_should_stop()) {
212                 error = gfs2_unlinked_dealloc(sdp);
213                 if (error &&
214                     error != -EROFS &&
215                     !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
216                         fs_err(sdp, "inoded: error = %d\n", error);
217
218                 t = gfs2_tune_get(sdp, gt_inoded_secs) * HZ;
219                 schedule_timeout_interruptible(t);
220         }
221
222         return 0;
223 }
224