gfs2: Split up gfs2_meta_sync into inode and rgrp versions
Before this patch, function gfs2_meta_sync called filemap_fdatawrite to write the address space for the metadata being synced. That's great for inodes, but resource groups all point to the same superblock-address space, sdp->sd_aspace. Each rgrp has its own range of blocks on which it should operate. That meant every time an rgrp's metadata was synced, it would write all of them instead of just the range. This patch eliminates function gfs2_meta_sync and tailors specific metasync functions for inodes and rgrps. Signed-off-by: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
This commit is contained in:
parent
c4af59bd44
commit
4a55752ae2
|
@ -164,6 +164,31 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
|
|||
GFS2_LFC_AIL_FLUSH);
|
||||
}
|
||||
|
||||
/**
|
||||
* gfs2_rgrp_metasync - sync out the metadata of a resource group
|
||||
* @gl: the glock protecting the resource group
|
||||
*
|
||||
*/
|
||||
|
||||
static int gfs2_rgrp_metasync(struct gfs2_glock *gl)
|
||||
{
|
||||
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
|
||||
struct address_space *metamapping = &sdp->sd_aspace;
|
||||
struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl);
|
||||
const unsigned bsize = sdp->sd_sb.sb_bsize;
|
||||
loff_t start = (rgd->rd_addr * bsize) & PAGE_MASK;
|
||||
loff_t end = PAGE_ALIGN((rgd->rd_addr + rgd->rd_length) * bsize) - 1;
|
||||
int error;
|
||||
|
||||
filemap_fdatawrite_range(metamapping, start, end);
|
||||
error = filemap_fdatawait_range(metamapping, start, end);
|
||||
WARN_ON_ONCE(error && !gfs2_withdrawn(sdp));
|
||||
mapping_set_error(metamapping, error);
|
||||
if (error)
|
||||
gfs2_io_error(sdp);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* rgrp_go_sync - sync out the metadata for this glock
|
||||
* @gl: the glock
|
||||
|
@ -176,11 +201,7 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
|
|||
static int rgrp_go_sync(struct gfs2_glock *gl)
|
||||
{
|
||||
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
|
||||
struct address_space *mapping = &sdp->sd_aspace;
|
||||
struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl);
|
||||
const unsigned bsize = sdp->sd_sb.sb_bsize;
|
||||
loff_t start = (rgd->rd_addr * bsize) & PAGE_MASK;
|
||||
loff_t end = PAGE_ALIGN((rgd->rd_addr + rgd->rd_length) * bsize) - 1;
|
||||
int error;
|
||||
|
||||
if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
|
||||
|
@ -189,10 +210,7 @@ static int rgrp_go_sync(struct gfs2_glock *gl)
|
|||
|
||||
gfs2_log_flush(sdp, gl, GFS2_LOG_HEAD_FLUSH_NORMAL |
|
||||
GFS2_LFC_RGRP_GO_SYNC);
|
||||
filemap_fdatawrite_range(mapping, start, end);
|
||||
error = filemap_fdatawait_range(mapping, start, end);
|
||||
WARN_ON_ONCE(error && !gfs2_withdrawn(sdp));
|
||||
mapping_set_error(mapping, error);
|
||||
error = gfs2_rgrp_metasync(gl);
|
||||
if (!error)
|
||||
error = gfs2_ail_empty_gl(gl);
|
||||
gfs2_free_clones(rgd);
|
||||
|
@ -266,7 +284,24 @@ static void gfs2_clear_glop_pending(struct gfs2_inode *ip)
|
|||
}
|
||||
|
||||
/**
|
||||
* inode_go_sync - Sync the dirty data and/or metadata for an inode glock
|
||||
* gfs2_inode_metasync - sync out the metadata of an inode
|
||||
* @gl: the glock protecting the inode
|
||||
*
|
||||
*/
|
||||
int gfs2_inode_metasync(struct gfs2_glock *gl)
|
||||
{
|
||||
struct address_space *metamapping = gfs2_glock2aspace(gl);
|
||||
int error;
|
||||
|
||||
filemap_fdatawrite(metamapping);
|
||||
error = filemap_fdatawait(metamapping);
|
||||
if (error)
|
||||
gfs2_io_error(gl->gl_name.ln_sbd);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* inode_go_sync - Sync the dirty metadata of an inode
|
||||
* @gl: the glock protecting the inode
|
||||
*
|
||||
*/
|
||||
|
@ -297,8 +332,7 @@ static int inode_go_sync(struct gfs2_glock *gl)
|
|||
error = filemap_fdatawait(mapping);
|
||||
mapping_set_error(mapping, error);
|
||||
}
|
||||
ret = filemap_fdatawait(metamapping);
|
||||
mapping_set_error(metamapping, ret);
|
||||
ret = gfs2_inode_metasync(gl);
|
||||
if (!error)
|
||||
error = ret;
|
||||
gfs2_ail_empty_gl(gl);
|
||||
|
|
|
@ -22,6 +22,7 @@ extern const struct gfs2_glock_operations gfs2_quota_glops;
|
|||
extern const struct gfs2_glock_operations gfs2_journal_glops;
|
||||
extern const struct gfs2_glock_operations *gfs2_glops_list[];
|
||||
|
||||
extern int gfs2_inode_metasync(struct gfs2_glock *gl);
|
||||
extern void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync);
|
||||
|
||||
#endif /* __GLOPS_DOT_H__ */
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "incore.h"
|
||||
#include "inode.h"
|
||||
#include "glock.h"
|
||||
#include "glops.h"
|
||||
#include "log.h"
|
||||
#include "lops.h"
|
||||
#include "meta_io.h"
|
||||
|
@ -817,41 +818,19 @@ static int buf_lo_scan_elements(struct gfs2_jdesc *jd, u32 start,
|
|||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* gfs2_meta_sync - Sync all buffers associated with a glock
|
||||
* @gl: The glock
|
||||
*
|
||||
*/
|
||||
|
||||
void gfs2_meta_sync(struct gfs2_glock *gl)
|
||||
{
|
||||
struct address_space *mapping = gfs2_glock2aspace(gl);
|
||||
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
|
||||
int error;
|
||||
|
||||
if (mapping == NULL)
|
||||
mapping = &sdp->sd_aspace;
|
||||
|
||||
filemap_fdatawrite(mapping);
|
||||
error = filemap_fdatawait(mapping);
|
||||
|
||||
if (error)
|
||||
gfs2_io_error(gl->gl_name.ln_sbd);
|
||||
}
|
||||
|
||||
static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
|
||||
{
|
||||
struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
|
||||
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
|
||||
|
||||
if (error) {
|
||||
gfs2_meta_sync(ip->i_gl);
|
||||
gfs2_inode_metasync(ip->i_gl);
|
||||
return;
|
||||
}
|
||||
if (pass != 1)
|
||||
return;
|
||||
|
||||
gfs2_meta_sync(ip->i_gl);
|
||||
gfs2_inode_metasync(ip->i_gl);
|
||||
|
||||
fs_info(sdp, "jid=%u: Replayed %u of %u blocks\n",
|
||||
jd->jd_jid, jd->jd_replayed_blocks, jd->jd_found_blocks);
|
||||
|
@ -1060,14 +1039,14 @@ static void databuf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
|
|||
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
|
||||
|
||||
if (error) {
|
||||
gfs2_meta_sync(ip->i_gl);
|
||||
gfs2_inode_metasync(ip->i_gl);
|
||||
return;
|
||||
}
|
||||
if (pass != 1)
|
||||
return;
|
||||
|
||||
/* data sync? */
|
||||
gfs2_meta_sync(ip->i_gl);
|
||||
gfs2_inode_metasync(ip->i_gl);
|
||||
|
||||
fs_info(sdp, "jid=%u: Replayed %u of %u data blocks\n",
|
||||
jd->jd_jid, jd->jd_replayed_blocks, jd->jd_found_blocks);
|
||||
|
|
|
@ -27,8 +27,6 @@ extern void gfs2_log_submit_bio(struct bio **biop, int opf);
|
|||
extern void gfs2_pin(struct gfs2_sbd *sdp, struct buffer_head *bh);
|
||||
extern int gfs2_find_jhead(struct gfs2_jdesc *jd,
|
||||
struct gfs2_log_header_host *head, bool keep_cache);
|
||||
extern void gfs2_meta_sync(struct gfs2_glock *gl);
|
||||
|
||||
static inline unsigned int buf_limit(struct gfs2_sbd *sdp)
|
||||
{
|
||||
unsigned int limit;
|
||||
|
|
|
@ -349,7 +349,7 @@ static int update_statfs_inode(struct gfs2_jdesc *jd,
|
|||
|
||||
mark_buffer_dirty(bh);
|
||||
brelse(bh);
|
||||
gfs2_meta_sync(ip->i_gl);
|
||||
gfs2_inode_metasync(ip->i_gl);
|
||||
|
||||
out:
|
||||
return error;
|
||||
|
|
Loading…
Reference in New Issue