With the glock holder auto-demotion in do_promote fixed, we can re-enable this feature.
This reverts commit e1fa9ea85ce89207d2ac0316da35a4a7736801f9. Signed-off-by: Andreas Gruenbacher <agrue...@redhat.com> --- fs/gfs2/file.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 2cceb193dcd8..fee69467f11e 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -832,6 +832,7 @@ static ssize_t gfs2_file_direct_read(struct kiocb *iocb, struct iov_iter *to, ret = gfs2_glock_nq(gh); if (ret) goto out_uninit; +retry_under_glock: pagefault_disable(); to->nofault = true; ret = iomap_dio_rw(iocb, to, &gfs2_iomap_ops, NULL, @@ -845,10 +846,14 @@ static ssize_t gfs2_file_direct_read(struct kiocb *iocb, struct iov_iter *to, read = ret; if (should_fault_in_pages(to, iocb, &prev_count, &window_size)) { - gfs2_glock_dq(gh); + gfs2_holder_allow_demote(gh); window_size -= fault_in_iov_iter_writeable(to, window_size); - if (window_size) + gfs2_holder_disallow_demote(gh); + if (window_size) { + if (gfs2_holder_queued(gh)) + goto retry_under_glock; goto retry; + } } out_unlock: if (gfs2_holder_queued(gh)) @@ -897,6 +902,7 @@ static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from, /* Silently fall back to buffered I/O when writing beyond EOF */ if (iocb->ki_pos + iov_iter_count(from) > i_size_read(&ip->i_inode)) goto out_unlock; +retry_under_glock: from->nofault = true; ret = iomap_dio_rw(iocb, from, &gfs2_iomap_ops, NULL, @@ -913,10 +919,14 @@ static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from, written = ret; if (should_fault_in_pages(from, iocb, &prev_count, &window_size)) { - gfs2_glock_dq(gh); + gfs2_holder_allow_demote(gh); window_size -= fault_in_iov_iter_readable(from, window_size); - if (window_size) + gfs2_holder_disallow_demote(gh); + if (window_size) { + if (gfs2_holder_queued(gh)) + goto retry_under_glock; goto retry; + } } out_unlock: if (gfs2_holder_queued(gh)) @@ -968,6 +978,7 @@ static ssize_t gfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *to) ret = gfs2_glock_nq(&gh); if (ret) goto out_uninit; +retry_under_glock: pagefault_disable(); ret = generic_file_read_iter(iocb, to); pagefault_enable(); @@ -977,10 +988,14 @@ static ssize_t gfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *to) read += ret; if (should_fault_in_pages(to, iocb, &prev_count, &window_size)) { - gfs2_glock_dq(&gh); + gfs2_holder_allow_demote(&gh); window_size -= fault_in_iov_iter_writeable(to, window_size); - if (window_size) + gfs2_holder_disallow_demote(&gh); + if (window_size) { + if (gfs2_holder_queued(&gh)) + goto retry_under_glock; goto retry; + } } out_unlock: if (gfs2_holder_queued(&gh)) @@ -1019,17 +1034,22 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb, gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, gh); retry: + ret = gfs2_glock_nq(gh); + if (ret) + goto out_uninit; if (should_fault_in_pages(from, iocb, &prev_count, &window_size)) { +retry_under_glock: + gfs2_holder_allow_demote(gh); window_size -= fault_in_iov_iter_readable(from, window_size); + gfs2_holder_disallow_demote(gh); if (!window_size) { ret = -EFAULT; - goto out_uninit; + goto out_unlock; } + if (!gfs2_holder_queued(gh)) + goto retry; from->count = min(from->count, window_size); } - ret = gfs2_glock_nq(gh); - if (ret) - goto out_uninit; if (inode == sdp->sd_rindex) { struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); @@ -1057,10 +1077,8 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb, goto out_unlock; from->count = orig_count - written; - if (should_fault_in_pages(from, iocb, &prev_count, &window_size)) { - gfs2_glock_dq(gh); - goto retry; - } + if (should_fault_in_pages(from, iocb, &prev_count, &window_size)) + goto retry_under_glock; out_unlock: if (gfs2_holder_queued(gh)) gfs2_glock_dq(gh); -- 2.35.1