summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/ops_address.c51
1 files changed, 25 insertions, 26 deletions
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 48913e569907..ae782d2cbdec 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;
}