[GFS2] Move logging code into log.c (mostly)
This moves the logging code from meta_io.c into log.c and glops.c. As a result the routines can now be static and all the logging code is together in log.c, leaving meta_io.c with just metadata i/o code in it. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
This commit is contained in:
parent
f92a0b6ff4
commit
ddacfaf76d
@ -26,7 +26,58 @@
|
||||
#include "recovery.h"
|
||||
#include "rgrp.h"
|
||||
#include "util.h"
|
||||
#include "trans.h"
|
||||
|
||||
/**
|
||||
* ail_empty_gl - remove all buffers for a given lock from the AIL
|
||||
* @gl: the glock
|
||||
*
|
||||
* None of the buffers should be dirty, locked, or pinned.
|
||||
*/
|
||||
|
||||
static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
|
||||
{
|
||||
struct gfs2_sbd *sdp = gl->gl_sbd;
|
||||
unsigned int blocks;
|
||||
struct list_head *head = &gl->gl_ail_list;
|
||||
struct gfs2_bufdata *bd;
|
||||
struct buffer_head *bh;
|
||||
u64 blkno;
|
||||
int error;
|
||||
|
||||
blocks = atomic_read(&gl->gl_ail_count);
|
||||
if (!blocks)
|
||||
return;
|
||||
|
||||
error = gfs2_trans_begin(sdp, 0, blocks);
|
||||
if (gfs2_assert_withdraw(sdp, !error))
|
||||
return;
|
||||
|
||||
gfs2_log_lock(sdp);
|
||||
while (!list_empty(head)) {
|
||||
bd = list_entry(head->next, struct gfs2_bufdata,
|
||||
bd_ail_gl_list);
|
||||
bh = bd->bd_bh;
|
||||
blkno = bh->b_blocknr;
|
||||
gfs2_assert_withdraw(sdp, !buffer_busy(bh));
|
||||
|
||||
bd->bd_ail = NULL;
|
||||
list_del(&bd->bd_ail_st_list);
|
||||
list_del(&bd->bd_ail_gl_list);
|
||||
atomic_dec(&gl->gl_ail_count);
|
||||
brelse(bh);
|
||||
gfs2_log_unlock(sdp);
|
||||
|
||||
gfs2_trans_add_revoke(sdp, blkno);
|
||||
|
||||
gfs2_log_lock(sdp);
|
||||
}
|
||||
gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count));
|
||||
gfs2_log_unlock(sdp);
|
||||
|
||||
gfs2_trans_end(sdp);
|
||||
gfs2_log_flush(sdp, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gfs2_pte_inval - Sync and invalidate all PTEs associated with a glock
|
||||
|
109
fs/gfs2/log.c
109
fs/gfs2/log.c
@ -58,6 +58,90 @@ unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct,
|
||||
return blks;
|
||||
}
|
||||
|
||||
/**
|
||||
* gfs2_ail1_start_one - Start I/O on a part of the AIL
|
||||
* @sdp: the filesystem
|
||||
* @tr: the part of the AIL
|
||||
*
|
||||
*/
|
||||
|
||||
static void gfs2_ail1_start_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
|
||||
{
|
||||
struct gfs2_bufdata *bd, *s;
|
||||
struct buffer_head *bh;
|
||||
int retry;
|
||||
|
||||
BUG_ON(!spin_is_locked(&sdp->sd_log_lock));
|
||||
|
||||
do {
|
||||
retry = 0;
|
||||
|
||||
list_for_each_entry_safe_reverse(bd, s, &ai->ai_ail1_list,
|
||||
bd_ail_st_list) {
|
||||
bh = bd->bd_bh;
|
||||
|
||||
gfs2_assert(sdp, bd->bd_ail == ai);
|
||||
|
||||
if (!buffer_busy(bh)) {
|
||||
if (!buffer_uptodate(bh)) {
|
||||
gfs2_log_unlock(sdp);
|
||||
gfs2_io_error_bh(sdp, bh);
|
||||
gfs2_log_lock(sdp);
|
||||
}
|
||||
list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!buffer_dirty(bh))
|
||||
continue;
|
||||
|
||||
list_move(&bd->bd_ail_st_list, &ai->ai_ail1_list);
|
||||
|
||||
gfs2_log_unlock(sdp);
|
||||
wait_on_buffer(bh);
|
||||
ll_rw_block(WRITE, 1, &bh);
|
||||
gfs2_log_lock(sdp);
|
||||
|
||||
retry = 1;
|
||||
break;
|
||||
}
|
||||
} while (retry);
|
||||
}
|
||||
|
||||
/**
|
||||
* gfs2_ail1_empty_one - Check whether or not a trans in the AIL has been synced
|
||||
* @sdp: the filesystem
|
||||
* @ai: the AIL entry
|
||||
*
|
||||
*/
|
||||
|
||||
static int gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai, int flags)
|
||||
{
|
||||
struct gfs2_bufdata *bd, *s;
|
||||
struct buffer_head *bh;
|
||||
|
||||
list_for_each_entry_safe_reverse(bd, s, &ai->ai_ail1_list,
|
||||
bd_ail_st_list) {
|
||||
bh = bd->bd_bh;
|
||||
|
||||
gfs2_assert(sdp, bd->bd_ail == ai);
|
||||
|
||||
if (buffer_busy(bh)) {
|
||||
if (flags & DIO_ALL)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (!buffer_uptodate(bh))
|
||||
gfs2_io_error_bh(sdp, bh);
|
||||
|
||||
list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list);
|
||||
}
|
||||
|
||||
return list_empty(&ai->ai_ail1_list);
|
||||
}
|
||||
|
||||
void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags)
|
||||
{
|
||||
struct list_head *head = &sdp->sd_ail1_list;
|
||||
@ -121,6 +205,31 @@ int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gfs2_ail2_empty_one - Check whether or not a trans in the AIL has been synced
|
||||
* @sdp: the filesystem
|
||||
* @ai: the AIL entry
|
||||
*
|
||||
*/
|
||||
|
||||
static void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
|
||||
{
|
||||
struct list_head *head = &ai->ai_ail2_list;
|
||||
struct gfs2_bufdata *bd;
|
||||
|
||||
while (!list_empty(head)) {
|
||||
bd = list_entry(head->prev, struct gfs2_bufdata,
|
||||
bd_ail_st_list);
|
||||
gfs2_assert(sdp, bd->bd_ail == ai);
|
||||
bd->bd_ail = NULL;
|
||||
list_del(&bd->bd_ail_st_list);
|
||||
list_del(&bd->bd_ail_gl_list);
|
||||
atomic_dec(&bd->bd_gl->gl_ail_count);
|
||||
brelse(bd->bd_bh);
|
||||
}
|
||||
}
|
||||
|
||||
static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail)
|
||||
{
|
||||
struct gfs2_ail *ai, *safe;
|
||||
|
@ -34,11 +34,6 @@
|
||||
#include "util.h"
|
||||
#include "ops_address.h"
|
||||
|
||||
#define buffer_busy(bh) \
|
||||
((bh)->b_state & ((1ul << BH_Dirty) | (1ul << BH_Lock) | (1ul << BH_Pinned)))
|
||||
#define buffer_in_io(bh) \
|
||||
((bh)->b_state & ((1ul << BH_Dirty) | (1ul << BH_Lock)))
|
||||
|
||||
static int aspace_get_block(struct inode *inode, sector_t lblock,
|
||||
struct buffer_head *bh_result, int create)
|
||||
{
|
||||
@ -91,165 +86,6 @@ void gfs2_aspace_put(struct inode *aspace)
|
||||
iput(aspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* gfs2_ail1_start_one - Start I/O on a part of the AIL
|
||||
* @sdp: the filesystem
|
||||
* @tr: the part of the AIL
|
||||
*
|
||||
*/
|
||||
|
||||
void gfs2_ail1_start_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
|
||||
{
|
||||
struct gfs2_bufdata *bd, *s;
|
||||
struct buffer_head *bh;
|
||||
int retry;
|
||||
|
||||
BUG_ON(!spin_is_locked(&sdp->sd_log_lock));
|
||||
|
||||
do {
|
||||
retry = 0;
|
||||
|
||||
list_for_each_entry_safe_reverse(bd, s, &ai->ai_ail1_list,
|
||||
bd_ail_st_list) {
|
||||
bh = bd->bd_bh;
|
||||
|
||||
gfs2_assert(sdp, bd->bd_ail == ai);
|
||||
|
||||
if (!buffer_busy(bh)) {
|
||||
if (!buffer_uptodate(bh)) {
|
||||
gfs2_log_unlock(sdp);
|
||||
gfs2_io_error_bh(sdp, bh);
|
||||
gfs2_log_lock(sdp);
|
||||
}
|
||||
list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!buffer_dirty(bh))
|
||||
continue;
|
||||
|
||||
list_move(&bd->bd_ail_st_list, &ai->ai_ail1_list);
|
||||
|
||||
gfs2_log_unlock(sdp);
|
||||
wait_on_buffer(bh);
|
||||
ll_rw_block(WRITE, 1, &bh);
|
||||
gfs2_log_lock(sdp);
|
||||
|
||||
retry = 1;
|
||||
break;
|
||||
}
|
||||
} while (retry);
|
||||
}
|
||||
|
||||
/**
|
||||
* gfs2_ail1_empty_one - Check whether or not a trans in the AIL has been synced
|
||||
* @sdp: the filesystem
|
||||
* @ai: the AIL entry
|
||||
*
|
||||
*/
|
||||
|
||||
int gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai, int flags)
|
||||
{
|
||||
struct gfs2_bufdata *bd, *s;
|
||||
struct buffer_head *bh;
|
||||
|
||||
list_for_each_entry_safe_reverse(bd, s, &ai->ai_ail1_list,
|
||||
bd_ail_st_list) {
|
||||
bh = bd->bd_bh;
|
||||
|
||||
gfs2_assert(sdp, bd->bd_ail == ai);
|
||||
|
||||
if (buffer_busy(bh)) {
|
||||
if (flags & DIO_ALL)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (!buffer_uptodate(bh))
|
||||
gfs2_io_error_bh(sdp, bh);
|
||||
|
||||
list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list);
|
||||
}
|
||||
|
||||
return list_empty(&ai->ai_ail1_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* gfs2_ail2_empty_one - Check whether or not a trans in the AIL has been synced
|
||||
* @sdp: the filesystem
|
||||
* @ai: the AIL entry
|
||||
*
|
||||
*/
|
||||
|
||||
void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
|
||||
{
|
||||
struct list_head *head = &ai->ai_ail2_list;
|
||||
struct gfs2_bufdata *bd;
|
||||
|
||||
while (!list_empty(head)) {
|
||||
bd = list_entry(head->prev, struct gfs2_bufdata,
|
||||
bd_ail_st_list);
|
||||
gfs2_assert(sdp, bd->bd_ail == ai);
|
||||
bd->bd_ail = NULL;
|
||||
list_del(&bd->bd_ail_st_list);
|
||||
list_del(&bd->bd_ail_gl_list);
|
||||
atomic_dec(&bd->bd_gl->gl_ail_count);
|
||||
brelse(bd->bd_bh);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ail_empty_gl - remove all buffers for a given lock from the AIL
|
||||
* @gl: the glock
|
||||
*
|
||||
* None of the buffers should be dirty, locked, or pinned.
|
||||
*/
|
||||
|
||||
void gfs2_ail_empty_gl(struct gfs2_glock *gl)
|
||||
{
|
||||
struct gfs2_sbd *sdp = gl->gl_sbd;
|
||||
unsigned int blocks;
|
||||
struct list_head *head = &gl->gl_ail_list;
|
||||
struct gfs2_bufdata *bd;
|
||||
struct buffer_head *bh;
|
||||
u64 blkno;
|
||||
int error;
|
||||
|
||||
blocks = atomic_read(&gl->gl_ail_count);
|
||||
if (!blocks)
|
||||
return;
|
||||
|
||||
error = gfs2_trans_begin(sdp, 0, blocks);
|
||||
if (gfs2_assert_withdraw(sdp, !error))
|
||||
return;
|
||||
|
||||
gfs2_log_lock(sdp);
|
||||
while (!list_empty(head)) {
|
||||
bd = list_entry(head->next, struct gfs2_bufdata,
|
||||
bd_ail_gl_list);
|
||||
bh = bd->bd_bh;
|
||||
blkno = bh->b_blocknr;
|
||||
gfs2_assert_withdraw(sdp, !buffer_busy(bh));
|
||||
|
||||
bd->bd_ail = NULL;
|
||||
list_del(&bd->bd_ail_st_list);
|
||||
list_del(&bd->bd_ail_gl_list);
|
||||
atomic_dec(&gl->gl_ail_count);
|
||||
brelse(bh);
|
||||
gfs2_log_unlock(sdp);
|
||||
|
||||
gfs2_trans_add_revoke(sdp, blkno);
|
||||
|
||||
gfs2_log_lock(sdp);
|
||||
}
|
||||
gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count));
|
||||
gfs2_log_unlock(sdp);
|
||||
|
||||
gfs2_trans_end(sdp);
|
||||
gfs2_log_flush(sdp, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gfs2_meta_inval - Invalidate all buffers associated with a glock
|
||||
* @gl: the glock
|
||||
|
@ -40,11 +40,6 @@ static inline void gfs2_buffer_copy_tail(struct buffer_head *to_bh,
|
||||
struct inode *gfs2_aspace_get(struct gfs2_sbd *sdp);
|
||||
void gfs2_aspace_put(struct inode *aspace);
|
||||
|
||||
void gfs2_ail1_start_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai);
|
||||
int gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai, int flags);
|
||||
void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai);
|
||||
void gfs2_ail_empty_gl(struct gfs2_glock *gl);
|
||||
|
||||
void gfs2_meta_inval(struct gfs2_glock *gl);
|
||||
void gfs2_meta_sync(struct gfs2_glock *gl);
|
||||
|
||||
@ -74,5 +69,10 @@ static inline int gfs2_meta_inode_buffer(struct gfs2_inode *ip,
|
||||
struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen);
|
||||
void gfs2_meta_syncfs(struct gfs2_sbd *sdp);
|
||||
|
||||
#define buffer_busy(bh) \
|
||||
((bh)->b_state & ((1ul << BH_Dirty) | (1ul << BH_Lock) | (1ul << BH_Pinned)))
|
||||
#define buffer_in_io(bh) \
|
||||
((bh)->b_state & ((1ul << BH_Dirty) | (1ul << BH_Lock)))
|
||||
|
||||
#endif /* __DIO_DOT_H__ */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user