• David Howells's avatar
    netfs: Fix handling of USE_PGPRIV2 and WRITE_TO_CACHE flags · 7b589a9b
    David Howells authored
    The NETFS_RREQ_USE_PGPRIV2 and NETFS_RREQ_WRITE_TO_CACHE flags aren't used
    correctly.  The problem is that we try to set them up in the request
    initialisation, but we the cache may be in the process of setting up still,
    and so the state may not be correct.  Further, we secondarily sample the
    cache state and make contradictory decisions later.
    
    The issue arises because we set up the cache resources, which allows the
    cache's ->prepare_read() to switch on NETFS_SREQ_COPY_TO_CACHE - which
    triggers cache writing even if we didn't set the flags when allocating.
    
    Fix this in the following way:
    
     (1) Drop NETFS_ICTX_USE_PGPRIV2 and instead set NETFS_RREQ_USE_PGPRIV2 in
         ->init_request() rather than trying to juggle that in
         netfs_alloc_request().
    
     (2) Repurpose NETFS_RREQ_USE_PGPRIV2 to merely indicate that if caching is
         to be done, then PG_private_2 is to be used rather than only setting
         it if we decide to cache and then having netfs_rreq_unlock_folios()
         set the non-PG_private_2 writeback-to-cache if it wasn't set.
    
     (3) Split netfs_rreq_unlock_folios() into two functions, one of which
         contains the deprecated code for using PG_private_2 to avoid
         accidentally doing the writeback path - and always use it if
         USE_PGPRIV2 is set.
    
     (4) As NETFS_ICTX_USE_PGPRIV2 is removed, make netfs_write_begin() always
         wait for PG_private_2.  This function is deprecated and only used by
         ceph anyway, and so label it so.
    
     (5) Drop the NETFS_RREQ_WRITE_TO_CACHE flag and use
         fscache_operation_valid() on the cache_resources instead.  This has
         the advantage of picking up the result of netfs_begin_cache_read() and
         fscache_begin_write_operation() - which are called after the object is
         initialised and will wait for the cache to come to a usable state.
    
    Just reverting ae678317[1] isn't a sufficient fix, so this need to be
    applied on top of that.  Without this as well, things like:
    
     rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: {
    
    and:
    
     WARNING: CPU: 13 PID: 3621 at fs/ceph/caps.c:3386
    
    may happen, along with some UAFs due to PG_private_2 not getting used to
    wait on writeback completion.
    
    Fixes: 2ff1e975 ("netfs: Replace PG_fscache by setting folio->private and marking dirty")
    Reported-by: default avatarMax Kellermann <max.kellermann@ionos.com>
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    cc: Ilya Dryomov <idryomov@gmail.com>
    cc: Xiubo Li <xiubli@redhat.com>
    cc: Hristo Venev <hristo@venev.name>
    cc: Jeff Layton <jlayton@kernel.org>
    cc: Matthew Wilcox <willy@infradead.org>
    cc: ceph-devel@vger.kernel.org
    cc: netfs@lists.linux.dev
    cc: linux-fsdevel@vger.kernel.org
    cc: linux-mm@kvack.org
    Link: https://lore.kernel.org/r/3575457.1722355300@warthog.procyon.org.uk/ [1]
    Link: https://lore.kernel.org/r/1173209.1723152682@warthog.procyon.org.ukSigned-off-by: default avatarChristian Brauner <brauner@kernel.org>
    7b589a9b
inode.c 87.2 KB