--- y/mm/filemap.c +++ f/mm/filemap.c @@ -3502,10 +3502,12 @@ static struct folio *do_read_cache_folio { struct folio *folio; int err; + bool self_locked; if (!filler) filler = mapping->a_ops->read_folio; repeat: + self_locked = false; folio = filemap_get_folio(mapping, index); if (!folio) { folio = filemap_alloc_folio(gfp, 0); @@ -3519,6 +3521,7 @@ repeat: /* Presumably ENOMEM for xarray node */ return ERR_PTR(err); } + self_locked = folio_test_locked(folio); filler: err = filler(file, folio); @@ -3527,7 +3530,11 @@ filler: return ERR_PTR(err); } - folio_wait_locked(folio); + if (self_locked) + folio_unlock(folio); + else + folio_wait_locked(folio); + if (!folio_test_uptodate(folio)) { folio_put(folio); return ERR_PTR(-EIO); @@ -3563,6 +3570,7 @@ filler: * set again if read page fails. */ folio_clear_error(folio); + self_locked = folio_test_locked(folio); goto filler; out: