From mboxrd@z Thu Jan 1 00:00:00 1970 From: Steven Whitehouse Date: Thu, 10 May 2007 13:38:46 +0100 Subject: [Cluster-devel] [PATCH][TRY 5] GFS2: kernel changes to support new gfs2_grow command In-Reply-To: <4641DCC5.3070906@redhat.com> References: <4641DCC5.3070906@redhat.com> Message-ID: <1178800726.7476.55.camel@quoit> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hi, Now applied to the GFS2 -nmw git tree. Thanks, Steve. On Wed, 2007-05-09 at 09:37 -0500, Robert Peterson wrote: > Hi, > > Sorry about this, but Dave informed me that I still had some __u64's > that I needed to change back to u64's, so this is a respin. > > Regards, > > Bob Peterson > Red Hat Cluster Suite > > Signed-off-By: Bob Peterson > -- > > fs/gfs2/ops_address.c | 29 ++++++++++++++++++++++- > fs/gfs2/ops_address.h | 5 +++- > fs/gfs2/rgrp.c | 60 ++++++++++++++++++++++++++++++++++++++++++++----- > 3 files changed, 86 insertions(+), 8 deletions(-) > > diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c > index 30c1562..846c0ff 100644 > --- a/fs/gfs2/ops_address.c > +++ b/fs/gfs2/ops_address.c > @@ -1,6 +1,6 @@ > /* > * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. > - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. > + * Copyright (C) 2004-2007 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 > @@ -450,6 +450,30 @@ out_uninit: > } > > /** > + * adjust_fs_space - Adjusts the free space available due to gfs2_grow > + * @inode: the rindex inode > + */ > +static void adjust_fs_space(struct inode *inode) > +{ > + struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; > + struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; > + struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; > + u64 fs_total, new_free; > + > + /* Total up the file system space, according to the latest rindex. */ > + fs_total = gfs2_ri_total(sdp); > + > + spin_lock(&sdp->sd_statfs_spin); > + if (fs_total > (m_sc->sc_total + l_sc->sc_total)) > + new_free = fs_total - (m_sc->sc_total + l_sc->sc_total); > + else > + new_free = 0; > + spin_unlock(&sdp->sd_statfs_spin); > + fs_warn(sdp, "File system extended by %llu blocks.\n", new_free); > + gfs2_statfs_change(sdp, new_free, new_free, 0); > +} > + > +/** > * gfs2_commit_write - Commit write to a file > * @file: The file to write to > * @page: The page containing the data > @@ -511,6 +535,9 @@ static int gfs2_commit_write(struct file *file, struct page *page, > di->di_size = cpu_to_be64(inode->i_size); > } > > + if (inode == sdp->sd_rindex) > + adjust_fs_space(inode); > + > brelse(dibh); > gfs2_trans_end(sdp); > if (al->al_requested) { > diff --git a/fs/gfs2/ops_address.h b/fs/gfs2/ops_address.h > index 35aaee4..56c30da 100644 > --- a/fs/gfs2/ops_address.h > +++ b/fs/gfs2/ops_address.h > @@ -1,6 +1,6 @@ > /* > * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. > - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. > + * Copyright (C) 2004-2007 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 > @@ -18,5 +18,8 @@ extern const struct address_space_operations gfs2_file_aops; > extern int gfs2_get_block(struct inode *inode, sector_t lblock, > struct buffer_head *bh_result, int create); > extern int gfs2_releasepage(struct page *page, gfp_t gfp_mask); > +extern u64 gfs2_ri_total(struct gfs2_sbd *sdp); > +extern void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, > + s64 dinodes); > > #endif /* __OPS_ADDRESS_DOT_H__ */ > diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c > index 1727f50..e857f40 100644 > --- a/fs/gfs2/rgrp.c > +++ b/fs/gfs2/rgrp.c > @@ -1,6 +1,6 @@ > /* > * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. > - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. > + * Copyright (C) 2004-2007 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 > @@ -431,6 +431,38 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) > } > > /** > + * gfs2_ri_total - Total up the file system space, according to the rindex. > + * > + */ > +u64 gfs2_ri_total(struct gfs2_sbd *sdp) > +{ > + u64 total_data = 0; > + struct inode *inode = sdp->sd_rindex; > + struct gfs2_inode *ip = GFS2_I(inode); > + struct gfs2_rindex_host ri; > + char buf[sizeof(struct gfs2_rindex)]; > + struct file_ra_state ra_state; > + int error, rgrps; > + > + mutex_lock(&sdp->sd_rindex_mutex); > + file_ra_state_init(&ra_state, inode->i_mapping); > + for (rgrps = 0;; rgrps++) { > + loff_t pos = rgrps * sizeof(struct gfs2_rindex); > + > + if (pos + sizeof(struct gfs2_rindex) >= ip->i_di.di_size) > + break; > + error = gfs2_internal_read(ip, &ra_state, buf, &pos, > + sizeof(struct gfs2_rindex)); > + if (error != sizeof(struct gfs2_rindex)) > + break; > + gfs2_rindex_in(&ri, buf); > + total_data += ri.ri_data; > + } > + mutex_unlock(&sdp->sd_rindex_mutex); > + return total_data; > +} > + > +/** > * gfs2_ri_update - Pull in a new resource index from the disk > * @gl: The glock covering the rindex inode > * > @@ -447,7 +479,12 @@ static int gfs2_ri_update(struct gfs2_inode *ip) > u64 junk = ip->i_di.di_size; > int error; > > - if (do_div(junk, sizeof(struct gfs2_rindex))) { > + /* If someone is holding the rindex file with a glock, they must > + be updating it, in which case we may have partial entries. > + In this case, we ignore the partials. */ > + if (!gfs2_glock_is_held_excl(ip->i_gl) && > + !gfs2_glock_is_held_shrd(ip->i_gl) && > + do_div(junk, sizeof(struct gfs2_rindex))) { > gfs2_consist_inode(ip); > return -EIO; > } > @@ -457,6 +494,9 @@ static int gfs2_ri_update(struct gfs2_inode *ip) > file_ra_state_init(&ra_state, inode->i_mapping); > for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { > loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); > + > + if (pos + sizeof(struct gfs2_rindex) >= ip->i_di.di_size) > + break; > error = gfs2_internal_read(ip, &ra_state, buf, &pos, > sizeof(struct gfs2_rindex)); > if (!error) > @@ -978,18 +1018,25 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line) > { > struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); > struct gfs2_alloc *al = &ip->i_alloc; > - int error; > + int error = 0; > > if (gfs2_assert_warn(sdp, al->al_requested)) > return -EINVAL; > > - error = gfs2_rindex_hold(sdp, &al->al_ri_gh); > + /* We need to hold the rindex unless the inode we're using is > + the rindex itself, in which case it's already held. */ > + if (ip != GFS2_I(sdp->sd_rindex)) > + error = gfs2_rindex_hold(sdp, &al->al_ri_gh); > + else if (!sdp->sd_rgrps) /* We may not have the rindex read in, so: */ > + error = gfs2_ri_update(ip); > + > if (error) > return error; > > error = get_local_rgrp(ip); > if (error) { > - gfs2_glock_dq_uninit(&al->al_ri_gh); > + if (ip != GFS2_I(sdp->sd_rindex)) > + gfs2_glock_dq_uninit(&al->al_ri_gh); > return error; > } > > @@ -1019,7 +1066,8 @@ void gfs2_inplace_release(struct gfs2_inode *ip) > > al->al_rgd = NULL; > gfs2_glock_dq_uninit(&al->al_rgd_gh); > - gfs2_glock_dq_uninit(&al->al_ri_gh); > + if (ip != GFS2_I(sdp->sd_rindex)) > + gfs2_glock_dq_uninit(&al->al_ri_gh); > } > > /** > diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h >