5e687eac1b
This patch contains various tweaks to how log flushes and active item writeback work. gfs2_logd is now managed by a waitqueue, and gfs2_log_reseve now waits for gfs2_logd to do the log flushing. Multiple functions were rewritten to remove the need to call gfs2_log_lock(). Instead of using one test to see if gfs2_logd had work to do, there are now seperate tests to check if there are two many buffers in the incore log or if there are two many items on the active items list. This patch is a port of a patch Steve Whitehouse wrote about a year ago, with some minor changes. Since gfs2_ail1_start always submits all the active items, it no longer needs to keep track of the first ai submitted, so this has been removed. In gfs2_log_reserve(), the order of the calls to prepare_to_wait_exclusive() and wake_up() when firing off the logd thread has been switched. If it called wake_up first there was a small window for a race, where logd could run and return before gfs2_log_reserve was ready to get woken up. If gfs2_logd ran, but did not free up enough blocks, gfs2_log_reserve() would be left waiting for gfs2_logd to eventualy run because it timed out. Finally, gt_logd_secs, which controls how long to wait before gfs2_logd times out, and flushes the log, can now be set on mount with ar_commit. Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
75 lines
1.9 KiB
C
75 lines
1.9 KiB
C
/*
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef __LOG_DOT_H__
|
|
#define __LOG_DOT_H__
|
|
|
|
#include <linux/list.h>
|
|
#include <linux/spinlock.h>
|
|
#include "incore.h"
|
|
|
|
/**
|
|
* gfs2_log_lock - acquire the right to mess with the log manager
|
|
* @sdp: the filesystem
|
|
*
|
|
*/
|
|
|
|
static inline void gfs2_log_lock(struct gfs2_sbd *sdp)
|
|
__acquires(&sdp->sd_log_lock)
|
|
{
|
|
spin_lock(&sdp->sd_log_lock);
|
|
}
|
|
|
|
/**
|
|
* gfs2_log_unlock - release the right to mess with the log manager
|
|
* @sdp: the filesystem
|
|
*
|
|
*/
|
|
|
|
static inline void gfs2_log_unlock(struct gfs2_sbd *sdp)
|
|
__releases(&sdp->sd_log_lock)
|
|
{
|
|
spin_unlock(&sdp->sd_log_lock);
|
|
}
|
|
|
|
static inline void gfs2_log_pointers_init(struct gfs2_sbd *sdp,
|
|
unsigned int value)
|
|
{
|
|
if (++value == sdp->sd_jdesc->jd_blocks) {
|
|
value = 0;
|
|
}
|
|
sdp->sd_log_head = sdp->sd_log_tail = value;
|
|
}
|
|
|
|
unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct,
|
|
unsigned int ssize);
|
|
|
|
int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks);
|
|
void gfs2_log_incr_head(struct gfs2_sbd *sdp);
|
|
|
|
struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp);
|
|
struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp,
|
|
struct buffer_head *real);
|
|
void __gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl);
|
|
|
|
static inline void gfs2_log_flush(struct gfs2_sbd *sbd, struct gfs2_glock *gl)
|
|
{
|
|
if (!gl || test_bit(GLF_LFLUSH, &gl->gl_flags))
|
|
__gfs2_log_flush(sbd, gl);
|
|
}
|
|
|
|
void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans);
|
|
void gfs2_remove_from_ail(struct gfs2_bufdata *bd);
|
|
|
|
void gfs2_log_shutdown(struct gfs2_sbd *sdp);
|
|
void gfs2_meta_syncfs(struct gfs2_sbd *sdp);
|
|
int gfs2_logd(void *data);
|
|
|
|
#endif /* __LOG_DOT_H__ */
|