Hi David, Below change needs to be applied on top of your branch. lxsmbadmin@netfsvm:~/latest_14mar/linux-fs$ git diff diff --git a/fs/cifs/file.c b/fs/cifs/file.c index af7483c246ac..447934ff80b8 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2969,6 +2969,12 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from, cur_len = min_t(const size_t, len, wsize); + if (!cur_len) { + rc = -EAGAIN; + add_credits_and_wake_if(server, credits, 0); + break; + } + wdata = cifs_writedata_alloc(cifs_uncached_writev_complete); if (!wdata) { rc = -ENOMEM; lxsmbadmin@netfsvm:~/xfstests-dev$ sudo ./check generic/013 SECTION -- smb3 FSTYP -- cifs PLATFORM -- Linux/x86_64 netfsvm 5.17.0-rc6+ #1 SMP PREEMPT Mon Mar 14 09:05:47 UTC 2022 MKFS_OPTIONS -- //127.0.0.1/sambashare_scratch MOUNT_OPTIONS -- -ousername=,password=,noperm,vers=3.0,actimeo=0 //127.0.0.1/sambashare_scratch /mnt/xfstests_scratch generic/013 149s Ran: generic/013 Passed all 1 tests SECTION -- smb3 ========================= Ran: generic/013 Passed all 1 tests Regards, Rohith On Fri, Mar 11, 2022 at 1:56 PM David Howells <dhowells@xxxxxxxxxx> wrote: > > > David Howells <dhowells@xxxxxxxxxx> wrote: > > > The other issue is that if I run splice to an empty file, it works; running > > another splice to the same file will result in the server giving > > STATUS_ACCESS_DENIED when cifs_write_begin() tries to read from the file: > > > > 7 0.009485249 192.168.6.2 → 192.168.6.1 SMB2 183 Read Request Len:65536 Off:0 File: x > > 8 0.009674245 192.168.6.1 → 192.168.6.2 SMB2 143 Read Response, Error: STATUS_ACCESS_DENIED > > > > Actually - that might be because the file is only 65536 bytes long because the > > first splice finished short. > > Actually, it's because I opened the output file O_WRONLY. If I open it > O_RDWR, it works. The test program is attached below. > > David > --- > #define _GNU_SOURCE > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > #include <unistd.h> > #include <fcntl.h> > > int main(int argc, char *argv[]) > { > off64_t opos; > size_t len; > int in, out; > > if (argc != 4) { > printf("Format: %s size in out\n", argv[0]); > exit(2); > } > > len = atol(argv[1]); > > if (strcmp(argv[2], "-") != 0) { > in = open(argv[2], O_RDONLY); > if (in < 0) { > perror(argv[2]); > return 1; > } > } else { > in = 0; > } > > if (strcmp(argv[3], "-") != 0) { > out = open(argv[3], O_WRONLY); // Change to O_RDWR > if (out < 0) { > perror(argv[3]); > return 1; > } > } else { > out = 1; > } > > opos = 3; > if (splice(in, NULL, out, &opos, len, 0) < 0) { > perror("splice"); > return 1; > } > > if (close(in) < 0) { > perror("close/in"); > return 1; > } > > if (close(out) < 0) { > perror("close/out"); > return 1; > } > > return 0; > } >