Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c41d4f09 authored by Steven Whitehouse's avatar Steven Whitehouse
Browse files

[GFS2] Don't hold page lock when starting transaction



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: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent b8e7cbb6
Loading
Loading
Loading
Loading
+25 −26
Original line number Diff line number Diff line
@@ -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,21 +691,34 @@ 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) {
	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) {
@@ -723,16 +728,10 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
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);
out_unlock:
		gfs2_glock_dq_m(1, &ip->i_gh);
	gfs2_glock_dq(&ip->i_gh);
out_uninit:
	gfs2_holder_uninit(&ip->i_gh);
	}

	return error;
}