Skip to content

Commit

Permalink
[GFS2] Don't hold page lock when starting transaction
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Steven Whitehouse committed Jan 25, 2008
1 parent b8e7cbb commit c41d4f0
Showing 1 changed file with 25 additions and 26 deletions.
51 changes: 25 additions & 26 deletions fs/gfs2/ops_address.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit c41d4f0

Please sign in to comment.