smb3: reenable swapfiles over SMB3 mounts
authorSteve French <stfrench@microsoft.com>
Wed, 15 May 2024 23:06:03 +0000 (18:06 -0500)
committerSteve French <stfrench@microsoft.com>
Tue, 21 May 2024 16:14:55 +0000 (11:14 -0500)
With the changes to folios/netfs it is now easier to reenable
swapfile support over SMB3 which fixes various xfstests

Reviewed-by: David Howells <dhowells@redhat.com>
Suggested-by: David Howells <dhowells@redhat.com>
Fixes: e1209d3a7a67 ("mm: introduce ->swap_rw and use it for reads from SWP_FS_OPS swap-space")
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/netfs/direct_write.c
fs/smb/client/file.c
include/linux/netfs.h

index 608ba6416919a8f95fd06645980964ba40bd4308..f516460e994e2ad142c0fd26ccb2528c7f1dae64 100644 (file)
@@ -27,7 +27,7 @@ static void netfs_cleanup_dio_write(struct netfs_io_request *wreq)
  * Perform an unbuffered write where we may have to do an RMW operation on an
  * encrypted file.  This can also be used for direct I/O writes.
  */
-static ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *iter,
+ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *iter,
                                                  struct netfs_group *netfs_group)
 {
        struct netfs_io_request *wreq;
@@ -117,6 +117,7 @@ out:
        netfs_put_request(wreq, false, netfs_rreq_trace_put_return);
        return ret;
 }
+EXPORT_SYMBOL(netfs_unbuffered_write_iter_locked);
 
 /**
  * netfs_unbuffered_write_iter - Unbuffered write to a file
index 9d38294a7e68002e348ee57a8a005c02d83c0955..9d5c2440abfc8fa61b09274a271ca11670bce36d 100644 (file)
@@ -3189,6 +3189,28 @@ static void cifs_swap_deactivate(struct file *file)
        /* do we need to unpin (or unlock) the file */
 }
 
+/**
+ * cifs_swap_rw - SMB3 address space operation for swap I/O
+ * @iocb: target I/O control block
+ * @iter: I/O buffer
+ *
+ * Perform IO to the swap-file.  This is much like direct IO.
+ */
+static int cifs_swap_rw(struct kiocb *iocb, struct iov_iter *iter)
+{
+       ssize_t ret;
+
+       WARN_ON_ONCE(iov_iter_count(iter) != PAGE_SIZE);
+
+       if (iov_iter_rw(iter) == READ)
+               ret = netfs_unbuffered_read_iter_locked(iocb, iter);
+       else
+               ret = netfs_unbuffered_write_iter_locked(iocb, iter, NULL);
+       if (ret < 0)
+               return ret;
+       return 0;
+}
+
 const struct address_space_operations cifs_addr_ops = {
        .read_folio     = netfs_read_folio,
        .readahead      = netfs_readahead,
@@ -3204,6 +3226,7 @@ const struct address_space_operations cifs_addr_ops = {
         */
        .swap_activate  = cifs_swap_activate,
        .swap_deactivate = cifs_swap_deactivate,
+       .swap_rw = cifs_swap_rw,
 };
 
 /*
index ca56a4428043d58392954fbfbedd43178cde7a74..d2d291a9cdadba94743daf38cb7ad56bad99ebf3 100644 (file)
@@ -400,6 +400,8 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
 ssize_t netfs_buffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *from,
                                         struct netfs_group *netfs_group);
 ssize_t netfs_unbuffered_write_iter(struct kiocb *iocb, struct iov_iter *from);
+ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *iter,
+                                          struct netfs_group *netfs_group);
 ssize_t netfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from);
 
 /* Address operations API */