diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2018-05-31 07:20:55 -0500 |
---|---|---|
committer | Bob Peterson <rpeterso@redhat.com> | 2018-06-04 07:33:17 -0500 |
commit | 7b5747f43f4dd8dce57e686ca4372825bd67c258 (patch) | |
tree | c8c39b17301ea54c80aa5faeed83b3bf501299c2 /fs | |
parent | 07e23d68f6eae20457cbd6d20175492b61b9f844 (diff) |
GFS2: Fix allocation error bug with recursive rgrp glocking
Before this patch function gfs2_write_begin, upon discovering an
error, called gfs2_trim_blocks while the rgrp glock was still held.
That's because gfs2_inplace_release is not called until later.
This patch reorganizes the logic a bit so gfs2_inplace_release
is called to release the lock prior to the call to gfs2_trim_blocks,
thus preventing the glock recursion.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/gfs2/aops.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index f58716567972..66e7172e0134 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -747,18 +747,21 @@ out: put_page(page); gfs2_trans_end(sdp); - if (pos + len > ip->i_inode.i_size) - gfs2_trim_blocks(&ip->i_inode); - goto out_trans_fail; + if (alloc_required) { + gfs2_inplace_release(ip); + if (pos + len > ip->i_inode.i_size) + gfs2_trim_blocks(&ip->i_inode); + } + goto out_qunlock; out_endtrans: gfs2_trans_end(sdp); out_trans_fail: - if (alloc_required) { + if (alloc_required) gfs2_inplace_release(ip); out_qunlock: + if (alloc_required) gfs2_quota_unlock(ip); - } out_unlock: if (&ip->i_inode == sdp->sd_rindex) { gfs2_glock_dq(&m_ip->i_gh); |