lkml.org 
[lkml]   [2008]   [Jan]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 10/58] [GFS2] Don't hold page lock when starting transaction
    Date
    From: Steven Whitehouse <swhiteho@redhat.com>

    This is an addendum to the new AOPs work which moves the point
    at which we take the page lock so that we don't get it until
    the last possible moment. This resolves a conflict between
    starting transactions and the page lock.

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

    diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
    index 48913e5..ae782d2 100644
    --- a/fs/gfs2/ops_address.c
    +++ b/fs/gfs2/ops_address.c
    @@ -657,18 +657,10 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
    if (unlikely(error))
    goto out_uninit;

    - error = -ENOMEM;
    - page = __grab_cache_page(mapping, index);
    - *pagep = page;
    - if (!page)
    - goto out_unlock;
    -
    gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks);
    -
    error = gfs2_write_alloc_required(ip, pos, len, &alloc_required);
    if (error)
    - goto out_putpage;
    -
    + goto out_unlock;

    ip->i_alloc.al_requested = 0;
    if (alloc_required) {
    @@ -699,40 +691,47 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
    if (error)
    goto out_trans_fail;

    + error = -ENOMEM;
    + page = __grab_cache_page(mapping, index);
    + *pagep = page;
    + if (unlikely(!page))
    + goto out_endtrans;
    +
    if (gfs2_is_stuffed(ip)) {
    + error = 0;
    if (pos + len > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) {
    error = gfs2_unstuff_dinode(ip, page);
    if (error == 0)
    goto prepare_write;
    - } else if (!PageUptodate(page))
    + } else if (!PageUptodate(page)) {
    error = stuffed_readpage(ip, page);
    + }
    goto out;
    }

    prepare_write:
    error = block_prepare_write(page, from, to, gfs2_get_block);
    -
    out:
    - if (error) {
    - gfs2_trans_end(sdp);
    + if (error == 0)
    + return 0;
    +
    + page_cache_release(page);
    + if (pos + len > ip->i_inode.i_size)
    + vmtruncate(&ip->i_inode, ip->i_inode.i_size);
    +out_endtrans:
    + gfs2_trans_end(sdp);
    out_trans_fail:
    - if (alloc_required) {
    - gfs2_inplace_release(ip);
    + if (alloc_required) {
    + gfs2_inplace_release(ip);
    out_qunlock:
    - gfs2_quota_unlock(ip);
    + gfs2_quota_unlock(ip);
    out_alloc_put:
    - gfs2_alloc_put(ip);
    - }
    -out_putpage:
    - page_cache_release(page);
    - if (pos + len > ip->i_inode.i_size)
    - vmtruncate(&ip->i_inode, ip->i_inode.i_size);
    + gfs2_alloc_put(ip);
    + }
    out_unlock:
    - gfs2_glock_dq_m(1, &ip->i_gh);
    + gfs2_glock_dq(&ip->i_gh);
    out_uninit:
    - gfs2_holder_uninit(&ip->i_gh);
    - }
    -
    + gfs2_holder_uninit(&ip->i_gh);
    return error;
    }

    --
    1.5.1.2


    \
     
     \ /
      Last update: 2008-01-21 11:09    [W:4.038 / U:0.284 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site