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 20#include "gfs2.h" 21#include "incore.h" 22#include "daemon.h" 23#include "glock.h" 24#include "log.h" 25#include "quota.h" 26#include "recovery.h" 27#include "super.h" 28#include "util.h" 29 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. 33 34 The kthread functions used to start these daemons block and flush signals. */ 35 36/** 37 * gfs2_scand - Look for cached glocks and inodes to toss from memory 38 * @sdp: Pointer to GFS2 superblock 39 * 40 * One of these daemons runs, finding candidates to add to sd_reclaim_list. 41 * See gfs2_glockd() 42 */ 43 44int gfs2_scand(void *data) 45{ 46 struct gfs2_sbd *sdp = data; 47 unsigned long t; 48 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); 53 } 54 55 return 0; 56} 57 58/** 59 * gfs2_glockd - Reclaim unused glock structures 60 * @sdp: Pointer to GFS2 superblock 61 * 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. 64 */ 65 66int gfs2_glockd(void *data) 67{ 68 struct gfs2_sbd *sdp = data; 69 70 while (!kthread_should_stop()) { 71 while (atomic_read(&sdp->sd_reclaim_count)) 72 gfs2_reclaim_glock(sdp); 73 74 wait_event_interruptible(sdp->sd_reclaim_wq, 75 (atomic_read(&sdp->sd_reclaim_count) || 76 kthread_should_stop())); 77 } 78 79 return 0; 80} 81 82/** 83 * gfs2_recoverd - Recover dead machine's journals 84 * @sdp: Pointer to GFS2 superblock 85 * 86 */ 87 88int gfs2_recoverd(void *data) 89{ 90 struct gfs2_sbd *sdp = data; 91 unsigned long t; 92 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); 97 } 98 99 return 0; 100} 101 102/** 103 * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks 104 * @sdp: Pointer to GFS2 superblock 105 * 106 * Also, periodically check to make sure that we're using the most recent 107 * journal index. 108 */ 109 110int gfs2_logd(void *data) 111{ 112 struct gfs2_sbd *sdp = data; 113 struct gfs2_holder ji_gh; 114 unsigned long t; 115 int need_flush; 116 117 while (!kthread_should_stop()) { 118 /* Advance the log tail */ 119 120 t = sdp->sd_log_flush_time + 121 gfs2_tune_get(sdp, gt_log_flush_secs) * HZ; 122 123 gfs2_ail1_empty(sdp, DIO_ALL); 124 gfs2_log_lock(sdp); 125 need_flush = sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks); 126 gfs2_log_unlock(sdp); 127 if (need_flush || time_after_eq(jiffies, t)) { 128 gfs2_log_flush(sdp, NULL); 129 sdp->sd_log_flush_time = jiffies; 130 } 131 132 /* Check for latest journal index */ 133 134 t = sdp->sd_jindex_refresh_time + 135 gfs2_tune_get(sdp, gt_jindex_refresh_secs) * HZ; 136 137 if (time_after_eq(jiffies, t)) { 138 if (!gfs2_jindex_hold(sdp, &ji_gh)) 139 gfs2_glock_dq_uninit(&ji_gh); 140 sdp->sd_jindex_refresh_time = jiffies; 141 } 142 143 t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; 144 schedule_timeout_interruptible(t); 145 } 146 147 return 0; 148} 149 150/** 151 * gfs2_quotad - Write cached quota changes into the quota file 152 * @sdp: Pointer to GFS2 superblock 153 * 154 */ 155 156int gfs2_quotad(void *data) 157{ 158 struct gfs2_sbd *sdp = data; 159 unsigned long t; 160 int error; 161 162 while (!kthread_should_stop()) { 163 /* Update the master statfs file */ 164 165 t = sdp->sd_statfs_sync_time + 166 gfs2_tune_get(sdp, gt_statfs_quantum) * HZ; 167 168 if (time_after_eq(jiffies, t)) { 169 error = gfs2_statfs_sync(sdp); 170 if (error && 171 error != -EROFS && 172 !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) 173 fs_err(sdp, "quotad: (1) error=%d\n", error); 174 sdp->sd_statfs_sync_time = jiffies; 175 } 176 177 /* Update quota file */ 178 179 t = sdp->sd_quota_sync_time + 180 gfs2_tune_get(sdp, gt_quota_quantum) * HZ; 181 182 if (time_after_eq(jiffies, t)) { 183 error = gfs2_quota_sync(sdp); 184 if (error && 185 error != -EROFS && 186 !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) 187 fs_err(sdp, "quotad: (2) error=%d\n", error); 188 sdp->sd_quota_sync_time = jiffies; 189 } 190 191 gfs2_quota_scan(sdp); 192 193 t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ; 194 schedule_timeout_interruptible(t); 195 } 196 197 return 0; 198} 199