FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Cluster Development

 
 
LinkBack Thread Tools
 
Old 11-21-2011, 10:14 AM
Steven Whitehouse
 
Default GFS2: move gfs2_blkrsv_get calls to function gfs2_inplace_reserve

Hi,

It looks like if you were to merge this patch and the one that precedes
it, then the resulting patch would be both smaller and easier to follow,

Steve.

On Fri, 2011-11-18 at 15:17 -0500, Bob Peterson wrote:
> Hi,
>
> Here is the simplification patch I wrote about earlier.
>
> Regards,
>
> Bob Peterson
> Red Hat File Systems
>
> Signed-off-by: Bob Peterson <rpeterso@redhat.com>
> --
> GFS2: move gfs2_blkrsv_get calls to function gfs2_inplace_reserve
>
> This patch moves all the block reservation structure allocations to
> function gfs2_inplace_reserve to simplify the code. It also moves
> the frees to function gfs2_inplace_release.
>
> diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
> index d201342..501e5cb 100644
> --- a/fs/gfs2/aops.c
> +++ b/fs/gfs2/aops.c
> @@ -616,7 +616,6 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
> int alloc_required;
> int error = 0;
> struct gfs2_qadata *qa = NULL;
> - struct gfs2_blkreserv *rs = NULL;
> pgoff_t index = pos >> PAGE_CACHE_SHIFT;
> unsigned from = pos & (PAGE_CACHE_SIZE - 1);
> struct page *page;
> @@ -650,16 +649,9 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
> if (error)
> goto out_alloc_put;
>
> - rs = gfs2_blkrsv_get(ip);
> - if (!rs) {
> - error = -ENOMEM;
> - goto out_qunlock;
> - }
> -
> - rs->rs_requested = data_blocks + ind_blocks;
> - error = gfs2_inplace_reserve(ip);
> + error = gfs2_inplace_reserve(ip, data_blocks + ind_blocks);
> if (error)
> - goto out_blkrsv_put;
> + goto out_qunlock;
> }
>
> rblocks = RES_DINODE + ind_blocks;
> @@ -715,8 +707,6 @@ out_endtrans:
> out_trans_fail:
> if (alloc_required) {
> gfs2_inplace_release(ip);
> -out_blkrsv_put:
> - gfs2_blkrsv_put(ip);
> out_qunlock:
> gfs2_quota_unlock(ip);
> out_alloc_put:
> @@ -858,7 +848,6 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
> struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
> struct buffer_head *dibh;
> struct gfs2_qadata *qa = ip->i_qadata;
> - struct gfs2_blkreserv *rs = ip->i_res;
> unsigned int from = pos & (PAGE_CACHE_SIZE - 1);
> unsigned int to = from + len;
> int ret;
> @@ -890,10 +879,8 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
> brelse(dibh);
> failed:
> gfs2_trans_end(sdp);
> - if (rs) {
> + if (ip->i_res)
> gfs2_inplace_release(ip);
> - gfs2_blkrsv_put(ip);
> - }
> if (qa) {
> gfs2_quota_unlock(ip);
> gfs2_qadata_put(ip);
> diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
> index dd6f3d1..14a7040 100644
> --- a/fs/gfs2/bmap.c
> +++ b/fs/gfs2/bmap.c
> @@ -1164,7 +1164,6 @@ static int do_grow(struct inode *inode, u64 size)
> struct gfs2_sbd *sdp = GFS2_SB(inode);
> struct buffer_head *dibh;
> struct gfs2_qadata *qa = NULL;
> - struct gfs2_blkreserv *rs = NULL;
> int error;
>
> if (gfs2_is_stuffed(ip) &&
> @@ -1177,15 +1176,9 @@ static int do_grow(struct inode *inode, u64 size)
> if (error)
> goto do_grow_alloc_put;
>
> - rs = gfs2_blkrsv_get(ip);
> - if (!rs) {
> - error = -ENOMEM;
> - goto do_grow_qunlock;
> - }
> - rs->rs_requested = 1;
> - error = gfs2_inplace_reserve(ip);
> + error = gfs2_inplace_reserve(ip, 1);
> if (error)
> - goto do_grow_rsput;
> + goto do_grow_qunlock;
> }
>
> error = gfs2_trans_begin(sdp, RES_DINODE + RES_STATFS + RES_RG_BIT, 0);
> @@ -1213,8 +1206,6 @@ do_end_trans:
> do_grow_release:
> if (qa) {
> gfs2_inplace_release(ip);
> -do_grow_rsput:
> - gfs2_blkrsv_put(ip);
> do_grow_qunlock:
> gfs2_quota_unlock(ip);
> do_grow_alloc_put:
> diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
> index a0ea143..5ad2681 100644
> --- a/fs/gfs2/file.c
> +++ b/fs/gfs2/file.c
> @@ -366,7 +366,6 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
> unsigned int data_blocks, ind_blocks, rblocks;
> struct gfs2_holder gh;
> struct gfs2_qadata *qa;
> - struct gfs2_blkreserv *rs;
> loff_t size;
> int ret;
>
> @@ -402,13 +401,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
> if (ret)
> goto out_alloc_put;
> gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks);
> - rs = gfs2_blkrsv_get(ip);
> - if (!rs) {
> - ret = -ENOMEM;
> - goto out_quota_unlock;
> - }
> - rs->rs_requested = data_blocks + ind_blocks;
> - ret = gfs2_inplace_reserve(ip);
> + ret = gfs2_inplace_reserve(ip, data_blocks + ind_blocks);
> if (ret)
> goto out_rsrv_put;
>
> @@ -452,8 +445,6 @@ out_trans_end:
> out_trans_fail:
> gfs2_inplace_release(ip);
> out_rsrv_put:
> - gfs2_blkrsv_put(ip);
> -out_quota_unlock:
> gfs2_quota_unlock(ip);
> out_alloc_put:
> gfs2_qadata_put(ip);
> @@ -759,7 +750,6 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
> unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
> loff_t bytes, max_bytes;
> struct gfs2_qadata *qa;
> - struct gfs2_blkreserv *rs;
> int error;
> loff_t bsize_mask = ~((loff_t)sdp->sd_sb.sb_bsize - 1);
> loff_t next = (offset + len - 1) >> sdp->sd_sb.sb_bsize_shift;
> @@ -801,16 +791,10 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
> if (error)
> goto out_alloc_put;
>
> - rs = gfs2_blkrsv_get(ip);
> - if (!rs) {
> - error = -ENOMEM;
> - goto out_qunlock;
> - }
> retry:
> gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks);
>
> - rs->rs_requested = data_blocks + ind_blocks;
> - error = gfs2_inplace_reserve(ip);
> + error = gfs2_inplace_reserve(ip, data_blocks + ind_blocks);
> if (error) {
> if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) {
> bytes >>= 1;
> @@ -819,12 +803,11 @@ retry:
> bytes = sdp->sd_sb.sb_bsize;
> goto retry;
> }
> - goto out_rsrv_put;
> + goto out_qunlock;
> }
> max_bytes = bytes;
> calc_max_reserv(ip, (len > max_chunk_size)? max_chunk_size: len,
> &max_bytes, &data_blocks, &ind_blocks);
> - rs->rs_requested = data_blocks + ind_blocks;
>
> rblocks = RES_DINODE + ind_blocks + RES_STATFS + RES_QUOTA +
> RES_RG_HDR + gfs2_rg_blocks(ip);
> @@ -852,8 +835,6 @@ retry:
>
> out_trans_fail:
> gfs2_inplace_release(ip);
> -out_rsrv_put:
> - gfs2_blkrsv_put(ip);
> out_qunlock:
> gfs2_quota_unlock(ip);
> out_alloc_put:
> diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
> index 81435fa..02df0b8 100644
> --- a/fs/gfs2/inode.c
> +++ b/fs/gfs2/inode.c
> @@ -394,11 +394,8 @@ static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation)
> error = gfs2_rindex_update(sdp);
> if (error)
> fs_warn(sdp, "rindex update returns %d
", error);
> - if (gfs2_blkrsv_get(dip) == NULL)
> - return -ENOMEM;
>
> - dip->i_res->rs_requested = RES_DINODE;
> - error = gfs2_inplace_reserve(dip);
> + error = gfs2_inplace_reserve(dip, RES_DINODE);
> if (error)
> goto out;
>
> @@ -413,7 +410,6 @@ static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation)
> out_ipreserv:
> gfs2_inplace_release(dip);
> out:
> - gfs2_blkrsv_put(dip);
> return error;
> }
>
> @@ -560,7 +556,6 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
> {
> struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
> struct gfs2_qadata *qa;
> - struct gfs2_blkreserv *rs = NULL;
> int alloc_required;
> struct buffer_head *dibh;
> int error;
> @@ -581,16 +576,9 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
> if (error)
> goto fail_quota_locks;
>
> - rs = gfs2_blkrsv_get(dip);
> - if (!rs) {
> - error = -ENOMEM;
> - goto fail_quota_locks;
> - }
> - rs->rs_requested = sdp->sd_max_dirres;
> -
> - error = gfs2_inplace_reserve(dip);
> + error = gfs2_inplace_reserve(dip, sdp->sd_max_dirres);
> if (error)
> - goto fail_rsrv_put;
> + goto fail_quota_locks;
>
> error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
> dip->i_rgd->rd_length +
> @@ -625,10 +613,6 @@ fail_end_trans:
> fail_ipreserv:
> gfs2_inplace_release(dip);
>
> -fail_rsrv_put:
> - if (alloc_required)
> - gfs2_blkrsv_put(dip);
> -
> fail_quota_locks:
> gfs2_quota_unlock(dip);
>
> @@ -744,10 +728,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
> gfs2_trans_end(sdp);
> /* Check if we reserved space in the rgrp. Function link_dinode may
> not, depending on whether alloc is required. */
> - if (dip->i_res) {
> + if (dip->i_res)
> gfs2_inplace_release(dip);
> - gfs2_blkrsv_put(dip);
> - }
> gfs2_quota_unlock(dip);
> gfs2_qadata_put(dip);
> mark_inode_dirty(inode);
> @@ -895,7 +877,6 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
>
> if (alloc_required) {
> struct gfs2_qadata *qa = gfs2_qadata_get(dip);
> - struct gfs2_blkreserv *rs = NULL;
>
> if (!qa) {
> error = -ENOMEM;
> @@ -906,16 +887,9 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
> if (error)
> goto out_alloc;
>
> - rs = gfs2_blkrsv_get(dip);
> - if (!rs) {
> - error = -ENOMEM;
> - goto out_gunlock_q;
> - }
> - rs->rs_requested = sdp->sd_max_dirres;
> -
> - error = gfs2_inplace_reserve(dip);
> + error = gfs2_inplace_reserve(dip, sdp->sd_max_dirres);
> if (error)
> - goto out_rsrv_put;
> + goto out_qunlock;
>
> error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
> gfs2_rg_blocks(dip) +
> @@ -951,10 +925,7 @@ out_end_trans:
> out_ipres:
> if (alloc_required)
> gfs2_inplace_release(dip);
> -out_rsrv_put:
> - if (alloc_required)
> - gfs2_blkrsv_put(dip);
> -out_gunlock_q:
> +out_qunlock:
> if (alloc_required)
> gfs2_quota_unlock(dip);
> out_alloc:
> @@ -1383,7 +1354,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
>
> if (alloc_required) {
> struct gfs2_qadata *qa = gfs2_qadata_get(ndip);
> - struct gfs2_blkreserv *rs;
> +
> if (!qa) {
> error = -ENOMEM;
> goto out_gunlock;
> @@ -1393,16 +1364,9 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
> if (error)
> goto out_alloc;
>
> - rs = gfs2_blkrsv_get(ndip);
> - if (!rs) {
> - error = -ENOMEM;
> - goto out_gunlock_q;
> - }
> - rs->rs_requested = sdp->sd_max_dirres;
> -
> - error = gfs2_inplace_reserve(ndip);
> + error = gfs2_inplace_reserve(ndip, sdp->sd_max_dirres);
> if (error)
> - goto out_rsrv_put;
> + goto out_qunlock;
>
> error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
> gfs2_rg_blocks(ndip) +
> @@ -1456,10 +1420,7 @@ out_end_trans:
> out_ipreserv:
> if (alloc_required)
> gfs2_inplace_release(ndip);
> -out_rsrv_put:
> - if (alloc_required)
> - gfs2_blkrsv_put(ndip);
> -out_gunlock_q:
> +out_qunlock:
> if (alloc_required)
> gfs2_quota_unlock(ndip);
> out_alloc:
> diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
> index d538f4d..98a01db 100644
> --- a/fs/gfs2/quota.c
> +++ b/fs/gfs2/quota.c
> @@ -762,7 +762,6 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
> struct gfs2_quota_data *qd;
> loff_t offset;
> unsigned int nalloc = 0, blocks;
> - struct gfs2_blkreserv *rs = NULL;
> int error;
>
> gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota),
> @@ -792,26 +791,19 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
> nalloc++;
> }
>
> - rs = gfs2_blkrsv_get(ip);
> - if (!rs) {
> - error = -ENOMEM;
> - goto out_gunlock;
> - }
> /*
> * 1 blk for unstuffing inode if stuffed. We add this extra
> * block to the reservation unconditionally. If the inode
> * doesn't need unstuffing, the block will be released to the
> * rgrp since it won't be allocated during the transaction
> */
> - rs->rs_requested = 1;
> /* +3 in the end for unstuffing block, inode size update block
> * and another block in case quota straddles page boundary and
> * two blocks need to be updated instead of 1 */
> blocks = num_qd * data_blocks + RES_DINODE + num_qd + 3;
>
> - if (nalloc)
> - rs->rs_requested += nalloc * (data_blocks + ind_blocks);
> - error = gfs2_inplace_reserve(ip);
> + error = gfs2_inplace_reserve(ip, 1 +
> + (nalloc * (data_blocks + ind_blocks)));
> if (error)
> goto out_alloc;
>
> @@ -840,8 +832,6 @@ out_end_trans:
> out_ipres:
> gfs2_inplace_release(ip);
> out_alloc:
> - gfs2_blkrsv_put(ip);
> -out_gunlock:
> gfs2_glock_dq_uninit(&i_gh);
> out:
> while (qx--)
> @@ -1529,7 +1519,6 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id,
> unsigned int data_blocks, ind_blocks;
> unsigned int blocks = 0;
> int alloc_required;
> - struct gfs2_blkreserv *rs;
> loff_t offset;
> int error;
>
> @@ -1594,15 +1583,12 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id,
> if (gfs2_is_stuffed(ip))
> alloc_required = 1;
> if (alloc_required) {
> - rs = gfs2_blkrsv_get(ip);
> - if (rs == NULL)
> - goto out_i;
> gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota),
> &data_blocks, &ind_blocks);
> - blocks = rs->rs_requested = 1 + data_blocks + ind_blocks;
> - error = gfs2_inplace_reserve(ip);
> + blocks = 1 + data_blocks + ind_blocks;
> + error = gfs2_inplace_reserve(ip, blocks);
> if (error)
> - goto out_alloc;
> + goto out_i;
> blocks += gfs2_rg_blocks(ip);
> }
>
> @@ -1617,11 +1603,8 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id,
>
> gfs2_trans_end(sdp);
> out_release:
> - if (alloc_required) {
> + if (alloc_required)
> gfs2_inplace_release(ip);
> -out_alloc:
> - gfs2_blkrsv_put(ip);
> - }
> out_i:
> gfs2_glock_dq_uninit(&i_gh);
> out_q:
> diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
> index a51f3cd..72bea39 100644
> --- a/fs/gfs2/rgrp.c
> +++ b/fs/gfs2/rgrp.c
> @@ -885,7 +885,7 @@ struct gfs2_qadata *gfs2_qadata_get(struct gfs2_inode *ip)
> * Returns: the struct gfs2_qadata
> */
>
> -struct gfs2_blkreserv *gfs2_blkrsv_get(struct gfs2_inode *ip)
> +static struct gfs2_blkreserv *gfs2_blkrsv_get(struct gfs2_inode *ip)
> {
> BUG_ON(ip->i_res != NULL);
> ip->i_res = kzalloc(sizeof(struct gfs2_blkreserv), GFP_NOFS);
> @@ -1039,6 +1039,13 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
> return -ENOSPC;
> }
>
> +static void gfs2_blkrsv_put(struct gfs2_inode *ip)
> +{
> + BUG_ON(ip->i_res == NULL);
> + kfree(ip->i_res);
> + ip->i_res = NULL;
> +}
> +
> /**
> * gfs2_inplace_reserve - Reserve space in the filesystem
> * @ip: the inode to reserve space for
> @@ -1046,16 +1053,23 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
> * Returns: errno
> */
>
> -int gfs2_inplace_reserve(struct gfs2_inode *ip)
> +int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
> {
> struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
> - struct gfs2_blkreserv *rs = ip->i_res;
> + struct gfs2_blkreserv *rs;
> int error = 0;
> u64 last_unlinked = NO_BLOCK;
> int tries = 0;
>
> - if (gfs2_assert_warn(sdp, rs->rs_requested))
> - return -EINVAL;
> + rs = gfs2_blkrsv_get(ip);
> + if (!rs)
> + return -ENOMEM;
> +
> + rs->rs_requested = requested;
> + if (gfs2_assert_warn(sdp, requested)) {
> + error = -EINVAL;
> + goto out;
> + }
>
> do {
> error = get_local_rgrp(ip, &last_unlinked);
> @@ -1072,6 +1086,9 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip)
> gfs2_log_flush(sdp, NULL);
> } while (tries++ < 3);
>
> +out:
> + if (error)
> + gfs2_blkrsv_put(ip);
> return error;
> }
>
> @@ -1086,6 +1103,7 @@ void gfs2_inplace_release(struct gfs2_inode *ip)
> {
> struct gfs2_blkreserv *rs = ip->i_res;
>
> + gfs2_blkrsv_put(ip);
> if (rs->rs_rgd_gh.gh_gl)
> gfs2_glock_dq_uninit(&rs->rs_rgd_gh);
> }
> diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
> index 57002a7..7ad2099 100644
> --- a/fs/gfs2/rgrp.h
> +++ b/fs/gfs2/rgrp.h
> @@ -38,15 +38,7 @@ static inline void gfs2_qadata_put(struct gfs2_inode *ip)
> ip->i_qadata = NULL;
> }
>
> -extern struct gfs2_blkreserv *gfs2_blkrsv_get(struct gfs2_inode *ip);
> -static inline void gfs2_blkrsv_put(struct gfs2_inode *ip)
> -{
> - BUG_ON(ip->i_res == NULL);
> - kfree(ip->i_res);
> - ip->i_res = NULL;
> -}
> -
> -extern int gfs2_inplace_reserve(struct gfs2_inode *ip);
> +extern int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested);
> extern void gfs2_inplace_release(struct gfs2_inode *ip);
>
> extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n,
> diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
> index b3642df..4d017b4 100644
> --- a/fs/gfs2/xattr.c
> +++ b/fs/gfs2/xattr.c
> @@ -710,7 +710,6 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
> ea_skeleton_call_t skeleton_call, void *private)
> {
> struct gfs2_qadata *qa;
> - struct gfs2_blkreserv *rs;
> struct buffer_head *dibh;
> int error;
>
> @@ -722,16 +721,9 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
> if (error)
> goto out;
>
> - rs = gfs2_blkrsv_get(ip);
> - if (!rs) {
> - error = -ENOMEM;
> - goto out_gunlock_q;
> - }
> - rs->rs_requested = blks;
> -
> - error = gfs2_inplace_reserve(ip);
> + error = gfs2_inplace_reserve(ip, blks);
> if (error)
> - goto out_rsrv_put;
> + goto out_qunlock;
>
> error = gfs2_trans_begin(GFS2_SB(&ip->i_inode),
> blks + gfs2_rg_blocks(ip) +
> @@ -755,9 +747,7 @@ out_end_trans:
> gfs2_trans_end(GFS2_SB(&ip->i_inode));
> out_ipres:
> gfs2_inplace_release(ip);
> -out_rsrv_put:
> - gfs2_blkrsv_put(ip);
> -out_gunlock_q:
> +out_qunlock:
> gfs2_quota_unlock(ip);
> out:
> gfs2_qadata_put(ip);
>
 
Old 11-22-2011, 11:53 AM
Steven Whitehouse
 
Default GFS2: move gfs2_blkrsv_get calls to function gfs2_inplace_reserve

Hi,

On Mon, 2011-11-21 at 13:36 -0500, Bob Peterson wrote:
> ----- Original Message -----
> | Hi,
> |
> | It looks like if you were to merge this patch and the one that
> | precedes
> | it, then the resulting patch would be both smaller and easier to
> | follow,
> |
> | Steve.
>
> Hi,
>
> You're right, it is smaller, and it is easier to follow.
> Here is the combined patch:
>
> Regards,
>
> Bob Peterson
> Red Hat File Systems
>
> Signed-off-by: Bob Peterson <rpeterso@redhat.com>
> --
> GFS2: decouple quota allocations from block allocations
>
> This patch separates the code pertaining to allocations into two
> parts: quota-related information and block reservations.
> This added complexity allows for code simplification in a
> follow-on patch. I could have done the simplification with this
> patch but I wanted to preserve the original logic as much as
> possible so that patch isn't too big and complex.
>

I've added this to the tree, however I'm also going to check in the
following patch, which fixes up a few items from the last few updates,

Steve.

>From 6a8099ed5677ac1bb2c74b74a31fecb8282f56c2 Mon Sep 17 00:00:00 2001
From: Steven Whitehouse <swhiteho@redhat.com>
Date: Tue, 22 Nov 2011 12:18:51 +0000
Subject: [PATCH] GFS2: Fix multi-block allocation

Clean up gfs2_alloc_blocks so that it takes the full extent length
rather than just the number of non-inode blocks as an argument. That
will only make a difference in the inode allocation case for now.

Also, this fixes the extent length handling around gfs2_alloc_extent() so
that multi block allocations will work again.

The rd_last_alloc block is set to the final block in the allocated
extent (as per the update to i_goal, but referenced to a different
start point).

This also removes the dinode argument to rgblk_search() which is no
longer used.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>

diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index ab8c429..e0ada04 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -389,7 +389,7 @@ static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation)
{
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
int error;
- int dblocks = 0;
+ int dblocks = 1;

error = gfs2_rindex_update(sdp);
if (error)
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index f6e05d6..2223462 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -65,7 +65,7 @@ static const char valid_change[16] = {
};

static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
- unsigned char old_state, bool dinode,
+ unsigned char old_state,
struct gfs2_bitmap **rbi);

/**
@@ -939,7 +939,7 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip

while (goal < rgd->rd_data) {
down_write(&sdp->sd_log_flush_lock);
- block = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, 0, &bi);
+ block = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, &bi);
up_write(&sdp->sd_log_flush_lock);
if (block == BFITNOENT)
break;
@@ -1147,14 +1147,14 @@ static unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block)
}

/**
- * rgblk_search - find a block in @old_state
+ * rgblk_search - find a block in @state
* @rgd: the resource group descriptor
* @goal: the goal block within the RG (start here to search for avail block)
- * @old_state: GFS2_BLKST_XXX the before-allocation state to find
+ * @state: GFS2_BLKST_XXX the before-allocation state to find
* @dinode: TRUE if the first block we allocate is for a dinode
* @rbi: address of the pointer to the bitmap containing the block found
*
- * Walk rgrp's bitmap to find bits that represent a block in @old_state.
+ * Walk rgrp's bitmap to find bits that represent a block in @state.
*
* This function never fails, because we wouldn't call it unless we
* know (from reservation results, etc.) that a block is available.
@@ -1166,7 +1166,7 @@ static unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block)
*/

static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
- unsigned char old_state, bool dinode,
+ unsigned char state,
struct gfs2_bitmap **rbi)
{
struct gfs2_bitmap *bi = NULL;
@@ -1198,21 +1198,21 @@ do_search:
bi = rgd->rd_bits + buf;

if (test_bit(GBF_FULL, &bi->bi_flags) &&
- (old_state == GFS2_BLKST_FREE))
+ (state == GFS2_BLKST_FREE))
goto skip;

/* The GFS2_BLKST_UNLINKED state doesn't apply to the clone
bitmaps, so we must search the originals for that. */
buffer = bi->bi_bh->b_data + bi->bi_offset;
WARN_ON(!buffer_uptodate(bi->bi_bh));
- if (old_state != GFS2_BLKST_UNLINKED && bi->bi_clone)
+ if (state != GFS2_BLKST_UNLINKED && bi->bi_clone)
buffer = bi->bi_clone + bi->bi_offset;

- blk = gfs2_bitfit(buffer, bi->bi_len, goal, old_state);
+ blk = gfs2_bitfit(buffer, bi->bi_len, goal, state);
if (blk != BFITNOENT)
break;

- if ((goal == 0) && (old_state == GFS2_BLKST_FREE))
+ if ((goal == 0) && (state == GFS2_BLKST_FREE))
set_bit(GBF_FULL, &bi->bi_flags);

/* Try next bitmap block (wrap back to rgrp header if at end) */
@@ -1247,12 +1247,12 @@ static u64 gfs2_alloc_extent(struct gfs2_rgrpd *rgd, struct gfs2_bitmap *bi,
u32 goal;
const u8 *buffer = NULL;

+ *n = 0;
buffer = bi->bi_bh->b_data + bi->bi_offset;
gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1);
gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset,
bi, blk, dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED);
- if (!dinode)
- (*n)++;
+ (*n)++;
goal = blk;
while (*n < elen) {
goal++;
@@ -1266,7 +1266,7 @@ static u64 gfs2_alloc_extent(struct gfs2_rgrpd *rgd, struct gfs2_bitmap *bi,
(*n)++;
}
blk = gfs2_bi2rgd_blk(bi, blk);
- rgd->rd_last_alloc = blk;
+ rgd->rd_last_alloc = blk + *n - 1;
return rgd->rd_data0 + blk;
}

@@ -1358,20 +1358,21 @@ static void gfs2_rgrp_error(struct gfs2_rgrpd *rgd)
* gfs2_alloc_blocks - Allocate one or more blocks of data and/or a dinode
* @ip: the inode to allocate the block for
* @bn: Used to return the starting block number
- * @ndata: requested number of data blocks/extent length (value/result)
+ * @ndata: requested number of blocks/extent length (value/result)
* @dinode: 1 if we're allocating a dinode block, else 0
* @generation: the generation number of the inode
*
* Returns: 0 or error
*/

-int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *ndata,
+int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
bool dinode, u64 *generation)
{
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head *dibh;
struct gfs2_rgrpd *rgd;
- u32 goal, extlen, blk; /* block, within the rgrp scope */
+ unsigned int ndata;
+ u32 goal, blk; /* block, within the rgrp scope */
u64 block; /* block, within the file system scope */
int error;
struct gfs2_bitmap *bi;
@@ -1389,17 +1390,19 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *ndata,
else
goal = rgd->rd_last_alloc;

- blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, dinode, &bi);
+ blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, &bi);

- *ndata = 0;
/* Since all blocks are reserved in advance, this shouldn't happen */
if (blk == BFITNOENT)
goto rgrp_error;

- block = gfs2_alloc_extent(rgd, bi, blk, dinode, ndata);
+ block = gfs2_alloc_extent(rgd, bi, blk, dinode, nblocks);
+ ndata = *nblocks;
+ if (dinode)
+ ndata--;

if (!dinode) {
- ip->i_goal = block + *ndata - 1;
+ ip->i_goal = block + ndata - 1;
error = gfs2_meta_inode_buffer(ip, &dibh);
if (error == 0) {
struct gfs2_dinode *di =
@@ -1410,13 +1413,10 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *ndata,
brelse(dibh);
}
}
- extlen = *ndata;
- if (dinode)
- extlen++;
- if (rgd->rd_free < extlen)
+ if (rgd->rd_free < *nblocks)
goto rgrp_error;

- rgd->rd_free -= extlen;
+ rgd->rd_free -= *nblocks;
if (dinode) {
rgd->rd_dinodes++;
*generation = rgd->rd_igeneration++;
@@ -1427,15 +1427,20 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *ndata,
gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1);
gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data);

- gfs2_statfs_change(sdp, 0, -(s64)extlen, dinode ? 1 : 0);
+ gfs2_statfs_change(sdp, 0, -(s64)*nblocks, dinode ? 1 : 0);
if (dinode)
gfs2_trans_add_unrevoke(sdp, block, 1);
- if (*ndata)
- gfs2_quota_change(ip, *ndata, ip->i_inode.i_uid,
+
+ /*
+ * This needs reviewing to see why we cannot do the quota change
+ * at this point in the dinode case.
+ */
+ if (ndata)
+ gfs2_quota_change(ip, ndata, ip->i_inode.i_uid,
ip->i_inode.i_gid);

- rgd->rd_free_clone -= extlen;
- trace_gfs2_block_alloc(ip, block, extlen,
+ rgd->rd_free_clone -= *nblocks;
+ trace_gfs2_block_alloc(ip, block, *nblocks,
dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED);
*bn = block;
return 0;
--
1.7.4
 

Thread Tools




All times are GMT. The time now is 10:55 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org