mm: variable length argument support
[pandora-kernel.git] / fs / gfs2 / daemon.c
1 /*
2  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3  * Copyright (C) 2004-2006 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 version 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 <linux/lm_interface.h>
19 #include <linux/freezer.h>
20
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"
30
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.
34
35    The kthread functions used to start these daemons block and flush signals. */
36
37 /**
38  * gfs2_scand - Look for cached glocks and inodes to toss from memory
39  * @sdp: Pointer to GFS2 superblock
40  *
41  * One of these daemons runs, finding candidates to add to sd_reclaim_list.
42  * See gfs2_glockd()
43  */
44
45 int gfs2_scand(void *data)
46 {
47         struct gfs2_sbd *sdp = data;
48         unsigned long t;
49
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);
56         }
57
58         return 0;
59 }
60
61 /**
62  * gfs2_glockd - Reclaim unused glock structures
63  * @sdp: Pointer to GFS2 superblock
64  *
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.
67  */
68
69 int gfs2_glockd(void *data)
70 {
71         struct gfs2_sbd *sdp = data;
72
73         while (!kthread_should_stop()) {
74                 while (atomic_read(&sdp->sd_reclaim_count))
75                         gfs2_reclaim_glock(sdp);
76
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();
82         }
83
84         return 0;
85 }
86
87 /**
88  * gfs2_recoverd - Recover dead machine's journals
89  * @sdp: Pointer to GFS2 superblock
90  *
91  */
92
93 int gfs2_recoverd(void *data)
94 {
95         struct gfs2_sbd *sdp = data;
96         unsigned long t;
97
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);
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 = data;
120         struct gfs2_holder ji_gh;
121         unsigned long t;
122         int need_flush;
123
124         while (!kthread_should_stop()) {
125                 /* Advance the log tail */
126
127                 t = sdp->sd_log_flush_time +
128                     gfs2_tune_get(sdp, gt_log_flush_secs) * HZ;
129
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;
137                 }
138
139                 /* Check for latest journal index */
140
141                 t = sdp->sd_jindex_refresh_time +
142                     gfs2_tune_get(sdp, gt_jindex_refresh_secs) * HZ;
143
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;
148                 }
149
150                 t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;
151                 if (freezing(current))
152                         refrigerator();
153                 schedule_timeout_interruptible(t);
154         }
155
156         return 0;
157 }
158
159 /**
160  * gfs2_quotad - Write cached quota changes into the quota file
161  * @sdp: Pointer to GFS2 superblock
162  *
163  */
164
165 int gfs2_quotad(void *data)
166 {
167         struct gfs2_sbd *sdp = data;
168         unsigned long t;
169         int error;
170
171         while (!kthread_should_stop()) {
172                 /* Update the master statfs file */
173
174                 t = sdp->sd_statfs_sync_time +
175                     gfs2_tune_get(sdp, gt_statfs_quantum) * HZ;
176
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;
184                 }
185
186                 /* Update quota file */
187
188                 t = sdp->sd_quota_sync_time +
189                     gfs2_tune_get(sdp, gt_quota_quantum) * HZ;
190
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;
198                 }
199
200                 gfs2_quota_scan(sdp);
201
202                 t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ;
203                 if (freezing(current))
204                         refrigerator();
205                 schedule_timeout_interruptible(t);
206         }
207
208         return 0;
209 }
210