OSDN Git Service

gfs2: Rework read and page fault locking
authorAndreas Gruenbacher <agruenba@redhat.com>
Wed, 1 Jul 2020 17:25:19 +0000 (19:25 +0200)
committerAndreas Gruenbacher <agruenba@redhat.com>
Tue, 7 Jul 2020 21:40:12 +0000 (23:40 +0200)
commit20f829999c38b18e3d17f9e40dea3a28f721fac4
treee73ba3b4f61e25ed01fed1eb700205c442ddaeec
parent41da51bce36f44eefc1e3d0f47d18841cbd065ba
gfs2: Rework read and page fault locking

So far, gfs2 has taken the inode glocks inside the ->readpage and
->readahead address space operations.  Since commit d4388340ae0b ("fs:
convert mpage_readpages to mpage_readahead"), gfs2_readahead is passed
the pages to read ahead locked.  With that, the current holder of the
inode glock may be trying to lock one of those pages while
gfs2_readahead is trying to take the inode glock, resulting in a
deadlock.

Fix that by moving the lock taking to the higher-level ->read_iter file
and ->fault vm operations.  This also gets rid of an ugly lock inversion
workaround in gfs2_readpage.

The cache consistency model of filesystems like gfs2 is such that if
data is found in the page cache, the data is up to date and can be used
without taking any filesystem locks.  If a page is not cached,
filesystem locks must be taken before populating the page cache.

To avoid taking the inode glock when the data is already cached,
gfs2_file_read_iter first tries to read the data with the IOCB_NOIO flag
set.  If that fails, the inode glock is taken and the operation is
retried with the IOCB_NOIO flag cleared.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
fs/gfs2/aops.c
fs/gfs2/file.c