123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- /*
- * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License version 2.
- */
- #include <linux/sched.h>
- #include <linux/slab.h>
- #include <linux/spinlock.h>
- #include <linux/completion.h>
- #include <linux/buffer_head.h>
- #include <linux/kthread.h>
- #include <linux/delay.h>
- #include <linux/gfs2_ondisk.h>
- #include <linux/lm_interface.h>
- #include <linux/freezer.h>
- #include "gfs2.h"
- #include "incore.h"
- #include "daemon.h"
- #include "glock.h"
- #include "log.h"
- #include "quota.h"
- #include "recovery.h"
- #include "super.h"
- #include "util.h"
- /* This uses schedule_timeout() instead of msleep() because it's good for
- the daemons to wake up more often than the timeout when unmounting so
- the user's unmount doesn't sit there forever.
- The kthread functions used to start these daemons block and flush signals. */
- /**
- * gfs2_glockd - Reclaim unused glock structures
- * @sdp: Pointer to GFS2 superblock
- *
- * One or more of these daemons run, reclaiming glocks on sd_reclaim_list.
- * Number of daemons can be set by user, with num_glockd mount option.
- */
- int gfs2_glockd(void *data)
- {
- struct gfs2_sbd *sdp = data;
- while (!kthread_should_stop()) {
- while (atomic_read(&sdp->sd_reclaim_count))
- gfs2_reclaim_glock(sdp);
- wait_event_interruptible(sdp->sd_reclaim_wq,
- (atomic_read(&sdp->sd_reclaim_count) ||
- kthread_should_stop()));
- if (freezing(current))
- refrigerator();
- }
- return 0;
- }
- /**
- * gfs2_recoverd - Recover dead machine's journals
- * @sdp: Pointer to GFS2 superblock
- *
- */
- int gfs2_recoverd(void *data)
- {
- struct gfs2_sbd *sdp = data;
- unsigned long t;
- while (!kthread_should_stop()) {
- gfs2_check_journals(sdp);
- t = gfs2_tune_get(sdp, gt_recoverd_secs) * HZ;
- if (freezing(current))
- refrigerator();
- schedule_timeout_interruptible(t);
- }
- return 0;
- }
- /**
- * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks
- * @sdp: Pointer to GFS2 superblock
- *
- * Also, periodically check to make sure that we're using the most recent
- * journal index.
- */
- int gfs2_logd(void *data)
- {
- struct gfs2_sbd *sdp = data;
- struct gfs2_holder ji_gh;
- unsigned long t;
- int need_flush;
- while (!kthread_should_stop()) {
- /* Advance the log tail */
- t = sdp->sd_log_flush_time +
- gfs2_tune_get(sdp, gt_log_flush_secs) * HZ;
- gfs2_ail1_empty(sdp, DIO_ALL);
- gfs2_log_lock(sdp);
- need_flush = sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks);
- gfs2_log_unlock(sdp);
- if (need_flush || time_after_eq(jiffies, t)) {
- gfs2_log_flush(sdp, NULL);
- sdp->sd_log_flush_time = jiffies;
- }
- /* Check for latest journal index */
- t = sdp->sd_jindex_refresh_time +
- gfs2_tune_get(sdp, gt_jindex_refresh_secs) * HZ;
- if (time_after_eq(jiffies, t)) {
- if (!gfs2_jindex_hold(sdp, &ji_gh))
- gfs2_glock_dq_uninit(&ji_gh);
- sdp->sd_jindex_refresh_time = jiffies;
- }
- t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;
- if (freezing(current))
- refrigerator();
- schedule_timeout_interruptible(t);
- }
- return 0;
- }
- /**
- * gfs2_quotad - Write cached quota changes into the quota file
- * @sdp: Pointer to GFS2 superblock
- *
- */
- int gfs2_quotad(void *data)
- {
- struct gfs2_sbd *sdp = data;
- unsigned long t;
- int error;
- while (!kthread_should_stop()) {
- /* Update the master statfs file */
- t = sdp->sd_statfs_sync_time +
- gfs2_tune_get(sdp, gt_statfs_quantum) * HZ;
- if (time_after_eq(jiffies, t)) {
- error = gfs2_statfs_sync(sdp);
- if (error &&
- error != -EROFS &&
- !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
- fs_err(sdp, "quotad: (1) error=%d\n", error);
- sdp->sd_statfs_sync_time = jiffies;
- }
- /* Update quota file */
- t = sdp->sd_quota_sync_time +
- gfs2_tune_get(sdp, gt_quota_quantum) * HZ;
- if (time_after_eq(jiffies, t)) {
- error = gfs2_quota_sync(sdp);
- if (error &&
- error != -EROFS &&
- !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
- fs_err(sdp, "quotad: (2) error=%d\n", error);
- sdp->sd_quota_sync_time = jiffies;
- }
- gfs2_quota_scan(sdp);
- t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ;
- if (freezing(current))
- refrigerator();
- schedule_timeout_interruptible(t);
- }
- return 0;
- }
|