Merge tag 'netfs-prep-20220318' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 31 Mar 2022 22:49:36 +0000 (15:49 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 31 Mar 2022 22:49:36 +0000 (15:49 -0700)
Pull netfs updates from David Howells:
 "Netfs prep for write helpers.

  Having had a go at implementing write helpers and content encryption
  support in netfslib, it seems that the netfs_read_{,sub}request
  structs and the equivalent write request structs were almost the same
  and so should be merged, thereby requiring only one set of
  alloc/get/put functions and a common set of tracepoints.

  Merging the structs also has the advantage that if a bounce buffer is
  added to the request struct, a read operation can be performed to fill
  the bounce buffer, the contents of the buffer can be modified and then
  a write operation can be performed on it to send the data wherever it
  needs to go using the same request structure all the way through. The
  I/O handlers would then transparently perform any required crypto.
  This should make it easier to perform RMW cycles if needed.

  The potentially common functions and structs, however, by their names
  all proclaim themselves to be associated with the read side of things.

  The bulk of these changes alter this in the following ways:

   - Rename struct netfs_read_{,sub}request to netfs_io_{,sub}request.

   - Rename some enums, members and flags to make them more appropriate.

   - Adjust some comments to match.

   - Drop "read"/"rreq" from the names of common functions. For
     instance, netfs_get_read_request() becomes netfs_get_request().

   - The ->init_rreq() and ->issue_op() methods become ->init_request()
     and ->issue_read(). I've kept the latter as a read-specific
     function and in another branch added an ->issue_write() method.

  The driver source is then reorganised into a number of files:

        fs/netfs/buffered_read.c        Create read reqs to the pagecache
        fs/netfs/io.c                   Dispatchers for read and write reqs
        fs/netfs/main.c                 Some general miscellaneous bits
        fs/netfs/objects.c              Alloc, get and put functions
        fs/netfs/stats.c                Optional procfs statistics.

  and future development can be fitted into this scheme, e.g.:

        fs/netfs/buffered_write.c       Modify the pagecache
        fs/netfs/buffered_flush.c       Writeback from the pagecache
        fs/netfs/direct_read.c          DIO read support
        fs/netfs/direct_write.c         DIO write support
        fs/netfs/unbuffered_write.c     Write modifications directly back

  Beyond the above changes, there are also some changes that affect how
  things work:

   - Make fscache_end_operation() generally available.

   - In the netfs tracing header, generate enums from the symbol ->
     string mapping tables rather than manually coding them.

   - Add a struct for filesystems that uses netfslib to put into their
     inode wrapper structs to hold extra state that netfslib is
     interested in, such as the fscache cookie. This allows netfslib
     functions to be set in filesystem operation tables and jumped to
     directly without having to have a filesystem wrapper.

   - Add a member to the struct added above to track the remote inode
     length as that may differ if local modifications are buffered. We
     may need to supply an appropriate EOF pointer when storing data (in
     AFS for example).

   - Pass extra information to netfs_alloc_request() so that the
     ->init_request() hook can access it and retain information to
     indicate the origin of the operation.

   - Make the ->init_request() hook return an error, thereby allowing a
     filesystem that isn't allowed to cache an inode (ceph or cifs, for
     example) to skip readahead.

   - Switch to using refcount_t for subrequests and add tracepoints to
     log refcount changes for the request and subrequest structs.

   - Add a function to consolidate dispatching a read request. Similar
     code is used in three places and another couple are likely to be
     added in the future"

Link: https://lore.kernel.org/all/2639515.1648483225@warthog.procyon.org.uk/
* tag 'netfs-prep-20220318' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
  afs: Maintain netfs_i_context::remote_i_size
  netfs: Keep track of the actual remote file size
  netfs: Split some core bits out into their own file
  netfs: Split fs/netfs/read_helper.c
  netfs: Rename read_helper.c to io.c
  netfs: Prepare to split read_helper.c
  netfs: Add a function to consolidate beginning a read
  netfs: Add a netfs inode context
  ceph: Make ceph_init_request() check caps on readahead
  netfs: Change ->init_request() to return an error code
  netfs: Refactor arguments for netfs_alloc_read_request
  netfs: Adjust the netfs_failure tracepoint to indicate non-subreq lines
  netfs: Trace refcounting on the netfs_io_subrequest struct
  netfs: Trace refcounting on the netfs_io_request struct
  netfs: Adjust the netfs_rreq tracepoint slightly
  netfs: Split netfs_io_* object handling out
  netfs: Finish off rename of netfs_read_request to netfs_io_request
  netfs: Rename netfs_read_*request to netfs_io_*request
  netfs: Generate enums from trace symbol mapping lists
  fscache: export fscache_end_operation()

14 files changed:
1  2 
fs/9p/vfs_addr.c
fs/9p/vfs_inode.c
fs/afs/file.c
fs/afs/internal.h
fs/afs/super.c
fs/afs/write.c
fs/cachefiles/io.c
fs/ceph/addr.c
fs/ceph/cache.h
fs/ceph/inode.c
fs/ceph/super.h
fs/nfs/fscache.c
include/linux/fscache.h
include/trace/events/cachefiles.h

index 76956c9d2af9e98cec72240244fcdf651d2db6a3,ed06f3c34e98e84c2ac1901be71b581e29b33d2f..5011281883432dc9111ef498a6d5abc55f14a1e3
@@@ -370,9 -353,9 +336,9 @@@ static bool v9fs_dirty_folio(struct add
  #endif
  
  const struct address_space_operations v9fs_addr_operations = {
-       .readpage = v9fs_vfs_readpage,
-       .readahead = v9fs_vfs_readahead,
+       .readpage = netfs_readpage,
+       .readahead = netfs_readahead,
 -      .set_page_dirty = v9fs_set_page_dirty,
 +      .dirty_folio = v9fs_dirty_folio,
        .writepage = v9fs_vfs_writepage,
        .write_begin = v9fs_write_begin,
        .write_end = v9fs_write_end,
index 84c3cf7dffa5eb58063705745a8dab6074b66e57,a7dc6781a6228a2eef4f17239262ef82128916b5..55367ecb9442e0129fe2e9b89778b063d48fc9fa
@@@ -228,12 -228,9 +228,9 @@@ struct inode *v9fs_alloc_inode(struct s
  {
        struct v9fs_inode *v9inode;
  
 -      v9inode = kmem_cache_alloc(v9fs_inode_cache, GFP_KERNEL);
 +      v9inode = alloc_inode_sb(sb, v9fs_inode_cache, GFP_KERNEL);
        if (!v9inode)
                return NULL;
- #ifdef CONFIG_9P_FSCACHE
-       v9inode->fscache = NULL;
- #endif
        v9inode->writeback_fid = NULL;
        v9inode->cache_validity = 0;
        mutex_init(&v9inode->v_mutex);
diff --cc fs/afs/file.c
index 0f9fdb284a2022423fe323d902aff6c0f71be615,2b68b207024818cc140b4e6b1833d98e90c5bfde..26292a110a8f9abf03471a402fdf567a4a6bfcc0
  #include "internal.h"
  
  static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);
- static int afs_readpage(struct file *file, struct page *page);
  static int afs_symlink_readpage(struct file *file, struct page *page);
 -static void afs_invalidatepage(struct page *page, unsigned int offset,
 -                             unsigned int length);
 +static void afs_invalidate_folio(struct folio *folio, size_t offset,
 +                             size_t length);
  static int afs_releasepage(struct page *page, gfp_t gfp_flags);
  
- static void afs_readahead(struct readahead_control *ractl);
  static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter);
  static void afs_vm_open(struct vm_area_struct *area);
  static void afs_vm_close(struct vm_area_struct *area);
@@@ -52,12 -50,12 +50,12 @@@ const struct inode_operations afs_file_
  };
  
  const struct address_space_operations afs_file_aops = {
-       .readpage       = afs_readpage,
-       .readahead      = afs_readahead,
+       .readpage       = netfs_readpage,
+       .readahead      = netfs_readahead,
 -      .set_page_dirty = afs_set_page_dirty,
 -      .launder_page   = afs_launder_page,
 +      .dirty_folio    = afs_dirty_folio,
 +      .launder_folio  = afs_launder_folio,
        .releasepage    = afs_releasepage,
 -      .invalidatepage = afs_invalidatepage,
 +      .invalidate_folio = afs_invalidate_folio,
        .write_begin    = afs_write_begin,
        .write_end      = afs_write_end,
        .writepage      = afs_writepage,
Simple merge
diff --cc fs/afs/super.c
Simple merge
diff --cc fs/afs/write.c
Simple merge
Simple merge
diff --cc fs/ceph/addr.c
Simple merge
diff --cc fs/ceph/cache.h
index b90f3016994d1d4012d73ee05f818646efede6bc,c20e43cade94621145a94941d4ffd662cfcb889e..7255b790a4c1c579827223d4b5493f204a24e053
@@@ -54,15 -49,15 +49,15 @@@ static inline void ceph_fscache_unpin_w
        fscache_unpin_writeback(wbc, ceph_fscache_cookie(ceph_inode(inode)));
  }
  
 -static inline int ceph_fscache_set_page_dirty(struct page *page)
 +static inline int ceph_fscache_dirty_folio(struct address_space *mapping,
 +              struct folio *folio)
  {
 -      struct inode *inode = page->mapping->host;
 -      struct ceph_inode_info *ci = ceph_inode(inode);
 +      struct ceph_inode_info *ci = ceph_inode(mapping->host);
  
 -      return fscache_set_page_dirty(page, ceph_fscache_cookie(ci));
 +      return fscache_dirty_folio(mapping, folio, ceph_fscache_cookie(ci));
  }
  
- static inline int ceph_begin_cache_operation(struct netfs_read_request *rreq)
+ static inline int ceph_begin_cache_operation(struct netfs_io_request *rreq)
  {
        struct fscache_cookie *cookie = ceph_fscache_cookie(ceph_inode(rreq->inode));
  
diff --cc fs/ceph/inode.c
Simple merge
diff --cc fs/ceph/super.h
Simple merge
Simple merge
Simple merge
Simple merge