Merge tag '6.10-rc-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 26 May 2024 05:33:10 +0000 (22:33 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 26 May 2024 05:33:10 +0000 (22:33 -0700)
Pull smb client fixes from Steve French:

 - two important netfs integration fixes - including for a data
   corruption and also fixes for multiple xfstests

 - reenable swap support over SMB3

* tag '6.10-rc-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: Fix missing set of remote_i_size
  cifs: Fix smb3_insert_range() to move the zero_point
  cifs: update internal version number
  smb3: reenable swapfiles over SMB3 mounts

fs/netfs/direct_write.c
fs/smb/client/cifsfs.c
fs/smb/client/cifsfs.h
fs/smb/client/file.c
fs/smb/client/smb2ops.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 ec5b639f421a27e46c894ff977237eb4c994942f..a665aac9be9f4bcef7c017a01577c45809dcefed 100644 (file)
@@ -1226,7 +1226,7 @@ static loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
        struct cifsFileInfo *smb_file_src = src_file->private_data;
        struct cifsFileInfo *smb_file_target = dst_file->private_data;
        struct cifs_tcon *target_tcon, *src_tcon;
-       unsigned long long destend, fstart, fend, new_size;
+       unsigned long long destend, fstart, fend, old_size, new_size;
        unsigned int xid;
        int rc;
 
@@ -1293,6 +1293,7 @@ static loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
                goto unlock;
        if (fend > target_cifsi->netfs.zero_point)
                target_cifsi->netfs.zero_point = fend + 1;
+       old_size = target_cifsi->netfs.remote_i_size;
 
        /* Discard all the folios that overlap the destination region. */
        cifs_dbg(FYI, "about to discard pages %llx-%llx\n", fstart, fend);
@@ -1305,9 +1306,8 @@ static loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
        if (target_tcon->ses->server->ops->duplicate_extents) {
                rc = target_tcon->ses->server->ops->duplicate_extents(xid,
                        smb_file_src, smb_file_target, off, len, destoff);
-               if (rc == 0 && new_size > i_size_read(target_inode)) {
+               if (rc == 0 && new_size > old_size) {
                        truncate_setsize(target_inode, new_size);
-                       netfs_resize_file(&target_cifsi->netfs, new_size, true);
                        fscache_resize_cookie(cifs_inode_cookie(target_inode),
                                              new_size);
                }
index 87310f05d39765fa8fb692a0b13061febb8edd87..62d5fee3e5ebbdefc0de78a5bd20f5d6d0dd51f9 100644 (file)
@@ -147,6 +147,6 @@ extern const struct export_operations cifs_export_ops;
 #endif /* CONFIG_CIFS_NFSD_EXPORT */
 
 /* when changing internal version - update following two lines at same time */
-#define SMB3_PRODUCT_BUILD 48
-#define CIFS_VERSION   "2.48"
+#define SMB3_PRODUCT_BUILD 49
+#define CIFS_VERSION   "2.49"
 #endif                         /* _CIFSFS_H */
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 ef18cd30f66c5a875f60f2d5fccda38c643c37b2..4ce6c3121a7ef17866be79561fa4589360967a17 100644 (file)
@@ -2028,6 +2028,7 @@ smb2_duplicate_extents(const unsigned int xid,
                 * size will be queried on next revalidate, but it is important
                 * to make sure that file's cached size is updated immediately
                 */
+               netfs_resize_file(netfs_inode(inode), dest_off + len, true);
                cifs_setsize(inode, dest_off + len);
        }
        rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid,
@@ -3636,6 +3637,7 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
        rc = smb2_copychunk_range(xid, cfile, cfile, off, count, off + len);
        if (rc < 0)
                goto out_2;
+       cifsi->netfs.zero_point = new_eof;
 
        rc = smb3_zero_data(file, tcon, off, len, xid);
        if (rc < 0)
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 */