All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] gfs2: Fix mmap + page fault deadlock
@ 2021-05-06 14:26 Andreas Gruenbacher
  2021-05-06 14:45 ` Andreas Gruenbacher
  0 siblings, 1 reply; 2+ messages in thread
From: Andreas Gruenbacher @ 2021-05-06 14:26 UTC (permalink / raw)
  To: fstests; +Cc: Andreas Gruenbacher, Jan Kara, stable

Commit 20f829999c38 has moved the inode glock taking from gfs2_readpage and
gfs2_readahead into gfs2_file_read_iter and gfs2_fault.  In gfs2_fault, we
didn't take into account that page faults can occur while holding the inode
glock, for example,

  gfs2_file_read_iter [grabs inode glock] ->
    generic_file_read_iter ->
      filemap_read ->
        copy_page_to_iter ... ->
          gfs2_fault [tries to grab inode glock again]

  gfs2_file_write_iter ->
    iomap_file_buffered_write ->
      iomap_apply ->
        iomap_ops->iomap_begin [grabs inode glock] ->
        iomap_write_actor ->
          iov_iter_fault_in_readable ... ->
            gfs2_fault [tries to grab inode glock again]

Fix that by checking if we're holding the inode glock already.

Reported-by: Jan Kara <jack@suse.cz>
Fixes: 20f829999c38 ("gfs2: Rework read and page fault locking")
Cc: stable@vger.kernel.org # v5.8+
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/gfs2/file.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index a0b542d84cd9..95b59763b748 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -538,18 +538,22 @@ static vm_fault_t gfs2_fault(struct vm_fault *vmf)
 {
 	struct inode *inode = file_inode(vmf->vma->vm_file);
 	struct gfs2_inode *ip = GFS2_I(inode);
+	bool recursive = gfs2_glock_is_locked_by_me(ip->i_gl);
 	struct gfs2_holder gh;
 	vm_fault_t ret;
 	int err;
 
 	gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
-	err = gfs2_glock_nq(&gh);
-	if (err) {
-		ret = block_page_mkwrite_return(err);
-		goto out_uninit;
+	if (likely(!recursive)) {
+		err = gfs2_glock_nq(&gh);
+		if (err) {
+			ret = block_page_mkwrite_return(err);
+			goto out_uninit;
+		}
 	}
 	ret = filemap_fault(vmf);
-	gfs2_glock_dq(&gh);
+	if (likely(!recursive))
+		gfs2_glock_dq(&gh);
 out_uninit:
 	gfs2_holder_uninit(&gh);
 	return ret;
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] gfs2: Fix mmap + page fault deadlock
  2021-05-06 14:26 [PATCH v2] gfs2: Fix mmap + page fault deadlock Andreas Gruenbacher
@ 2021-05-06 14:45 ` Andreas Gruenbacher
  0 siblings, 0 replies; 2+ messages in thread
From: Andreas Gruenbacher @ 2021-05-06 14:45 UTC (permalink / raw)
  To: fstests; +Cc: Jan Kara, stable

On Thu, May 6, 2021 at 4:27 PM Andreas Gruenbacher <agruenba@redhat.com> wrote:
> Commit 20f829999c38 has moved the inode glock taking from gfs2_readpage and
> gfs2_readahead into gfs2_file_read_iter and gfs2_fault.

Oops, sorry for posting this to the wrong list.

Andreas


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-05-06 14:45 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-06 14:26 [PATCH v2] gfs2: Fix mmap + page fault deadlock Andreas Gruenbacher
2021-05-06 14:45 ` Andreas Gruenbacher

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.