- From eea848a0bc2e8b9d5ba7de6465b3a09ba6ea67b0 Mon Sep 17 00:00:00 2001
- From: Cedric Blancher <cedric.blancher@gmail.com>
- Date: Mon, 7 Apr 2025 15:17:59 +0200
- Subject: [PATCH 1/8] sys: Allow nfs_mount with rsize=/wsize= up to 16MB
- Allow nfs_mount with rsize=/wsize= up to 16MB.
- Default is still 1MB.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_driver.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index 496387c..7b3045d 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -295,8 +295,8 @@ nfs41_updowncall_list upcall, downcall;
- #define SERVER_NAME_BUFFER_SIZE 1024
- #define MOUNT_CONFIG_RW_SIZE_MIN 1024
- -#define MOUNT_CONFIG_RW_SIZE_DEFAULT 1048576
- -#define MOUNT_CONFIG_RW_SIZE_MAX 1048576
- +#define MOUNT_CONFIG_RW_SIZE_DEFAULT (1*1024*1024)
- +#define MOUNT_CONFIG_RW_SIZE_MAX (16*1024*1024)
- #define MAX_SEC_FLAVOR_LEN 12
- #define UPCALL_TIMEOUT_DEFAULT 50 /* in seconds */
- --
- 2.45.1
- From 0d6917fed806e21c39db66c85c78a7f6e6ca0a57 Mon Sep 17 00:00:00 2001
- From: Cedric Blancher <cedric.blancher@gmail.com>
- Date: Mon, 7 Apr 2025 15:25:03 +0200
- Subject: [PATCH 2/8] sys: Increase minimum rsize=/wsize= limit to 8192
- Increase minimum rsize=/wsize= limit to 8192, to make sure it
- can fit a full 4096byte long path.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_driver.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index 7b3045d..d086d2e 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -294,7 +294,7 @@ nfs41_updowncall_list upcall, downcall;
- #define SERVER_NAME_BUFFER_SIZE 1024
- -#define MOUNT_CONFIG_RW_SIZE_MIN 1024
- +#define MOUNT_CONFIG_RW_SIZE_MIN 8192
- #define MOUNT_CONFIG_RW_SIZE_DEFAULT (1*1024*1024)
- #define MOUNT_CONFIG_RW_SIZE_MAX (16*1024*1024)
- #define MAX_SEC_FLAVOR_LEN 12
- --
- 2.45.1
- From 70111ace6a8fbe3d6f55b3bdde3046dada3ae10b Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 7 Apr 2025 17:10:41 +0200
- Subject: [PATCH 3/8] daemon: Crash in |decode_read_plus_res_ok()| when
- |NFS4_CONTENT_HOLE| hole size exceeds supplied buffer size
- Crash in |decode_read_plus_res_ok()| when |NFS4_CONTENT_HOLE| hole size
- exceeds supplied buffer size.
- Stack trace looks like this:
- ---- snip ----
- nfsd!decode_read_plus_res_ok(struct __rpc_xdr * xdr = 0x000001f5`f9e47f30, struct __nfs42_read_plus_res_ok * res = 0x0000006c`1f1fa3a8)+0x555 [msnfs41_uidmapping\ms-nfs41-client\daemon\nfs42_xdr.c @ 233]
- nfsd!decode_op_read_plus(struct __rpc_xdr * xdr = 0x000001f5`f9e47f30, struct __nfs_resop4 * resop = 0x0000006c`1f1fa310)+0x6d [msnfs41_uidmapping\ms-nfs41-client\daemon\nfs42_xdr.c @ 263]
- nfsd!nfs_decode_compound(struct __rpc_xdr * xdr = 0x000001f5`f9e47f30, char ** pres = 0x0000006c`1f1f9e98)+0x242 [msnfs41_uidmapping\ms-nfs41-client\daemon\nfs41_xdr.c @ 3778]
- libtirpc!authunix_unwrap(struct __auth * auth = 0x000001f5`f9834740, struct __rpc_xdr * xdrs = 0x000001f5`f9e47f30, <function> * func = 0x00007ff6`ef3066bd, char * args = 0x0000006c`1f1f9e98 "", unsigned int seq = 0xffffffff)+0x29 [msnfs41_uidmapping\ms-nfs41-client\libtirpc\src\auth_unix.c @ 392]
- libtirpc!clnt_vc_call(struct __rpc_client * cl = 0x000001f5`f9e20950, unsigned int proc = 1, <function> * xdr_args = 0x00007ff6`ef30686b, void * args_ptr = 0x0000006c`1f1f9a80, <function> * xdr_results = 0x00007ff6`ef3066bd, void * results_ptr = 0x0000006c`1f1f9e98, struct timeval timeout = struct timeval)+0x8e3 [msnfs41_uidmapping\ms-nfs41-client\libtirpc\src\clnt_vc.c @ 738]
- nfsd!nfs41_send_compound(struct __nfs41_rpc_clnt * rpc = 0x000001f5`f9e47720, char * inbuf = 0x0000006c`1f1f9a80 ".", char * outbuf = 0x0000006c`1f1f9e98 "")+0xb1 [msnfs41_uidmapping\ms-nfs41-client\daemon\nfs41_rpc.c @ 366]
- nfsd!compound_encode_send_decode(struct __nfs41_session * session = 0x000001f5`f986bee0, struct __nfs41_compound * compound = 0x0000006c`1f1f9a80, int try_recovery = 0n1)+0xdb [msnfs41_uidmapping\ms-nfs41-client\daemon\nfs41_compound.c @ 173]
- nfsd!nfs42_read_plus(struct __nfs41_session * session = 0x000001f5`f986bee0, struct __nfs41_path_fh * file = 0x000001f5`f9e39140, struct __stateid_arg * stateid = 0x0000006c`1f1fa628, unsigned int64 offset = 0xd000, unsigned int count = 0x4000, unsigned char * data_out = 0x000001f5`fd300000 "", unsigned int * data_len_out = 0x0000006c`1f1fa59c, int * eof_out = 0x0000006c`1f1fa57c)+0x16d [msnfs41_uidmapping\ms-nfs41-client\daemon\nfs42_ops.c @ 235]
- nfsd!read_from_mds(struct __nfs41_upcall * upcall = 0x0000006c`1f1fe7a0, struct __stateid_arg * stateid = 0x0000006c`1f1fa628)+0x165 [msnfs41_uidmapping\ms-nfs41-client\daemon\readwrite.c @ 82]
- nfsd!handle_read(void * daemon_context = 0x00007ff6`ef392010, struct __nfs41_upcall * upcall = 0x0000006c`1f1fe7a0)+0xd2 [msnfs41_uidmapping\ms-nfs41-client\daemon\readwrite.c @ 183]
- nfsd!upcall_handle(void * daemon_context = 0x00007ff6`ef392010, struct __nfs41_upcall * upcall = 0x0000006c`1f1fe7a0)+0x77 [msnfs41_uidmapping\ms-nfs41-client\daemon\upcall.c @ 227]
- nfsd!nfsd_worker_thread_main(void * args = 0x00007ff6`ef392010)+0x248 [msnfs41_uidmapping\ms-nfs41-client\daemon\nfs41_daemon.c @ 207]
- nfsd!nfsd_thread_main(void * args = 0x00007ff6`ef392010)+0x1f [msnfs41_uidmapping\ms-nfs41-client\daemon\nfs41_daemon.c @ 245]
- ucrtbased!invoke_thread_procedure(<function> * procedure = 0x00007ff6`ef3379b0, void * context = 0x00007ff6`ef392010)+0x2c [d:\th\minkernel\crts\ucrt\src\appcrt\startup\thread.cpp @ 92]
- ucrtbased!thread_start<unsigned int (void * parameter = 0x000001f5`f985b090)+0x93 [d:\th\minkernel\crts\ucrt\src\appcrt\startup\thread.cpp @ 115]
- KERNEL32!BaseThreadInitThunk+0x14
- ntdll!RtlUserThreadStart+0x21
- ---- snip ----
- The returned |NFS4_CONTENT_HOLE| hole size in this case is much
- bigger than the destination buffer (the NFSv4.2 RFC specifies that
- OP_READ_PLUS must return the full size of the hole, and not clamp
- it to the buffer size - the NFS client has to do that), causing the
- |memset(buffer, 0, hole_size)| to write beyond the buffers end.
- Fix is do clamp the |hole_length| that the |memset()| fits into the
- destination buffer.
- Seen with
- msnfs41client_cygwin_64bit32bit_binaries_20250331_22h33m_gitbf8d343
- with a Linux 5.10.0-22-amd64 nfsd woth commercial software (sparse
- file *.exe).
- Issue can be replicated with tests/sparsefiles/testsparsefile1.ksh
- Reported-by: Sebastian Feld <sebastian.n.feld@gmail.com>
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/nfs42_xdr.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
- diff --git a/daemon/nfs42_xdr.c b/daemon/nfs42_xdr.c
- index c3367be..ad82d20 100644
- --- a/daemon/nfs42_xdr.c
- +++ b/daemon/nfs42_xdr.c
- @@ -226,10 +226,13 @@ static bool_t decode_read_plus_res_ok(
- */
- if (((hole_buff - res->data) + hole_length) >
- res->data_len) {
- - hole_length = res->data_len;
- + hole_length = res->data_len -
- + (hole_buff - res->data);
- }
- EASSERT(hole_length < UINT_MAX);
- + EASSERT(((hole_buff - res->data) + hole_length) <=
- + res->data_len);
- (void)memset(hole_buff, 0, (size_t)hole_length);
- read_data_len = __max(read_data_len,
- --
- 2.45.1
- From 429a2b9b18258922f120a2b49e24e8f2af51e3a5 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 7 Apr 2025 17:42:47 +0200
- Subject: [PATCH 4/8] daemon: |decode_read_plus_res_ok()| should not print
- "'NFS4_CONTENT_HOLE' content" debug messages by default
- |decode_read_plus_res_ok()| should not print "'NFS4_CONTENT_HOLE'
- content" debug messages by default.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/nfs42_xdr.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
- diff --git a/daemon/nfs42_xdr.c b/daemon/nfs42_xdr.c
- index ad82d20..316d03d 100644
- --- a/daemon/nfs42_xdr.c
- +++ b/daemon/nfs42_xdr.c
- @@ -175,6 +175,9 @@ static bool_t decode_read_plus_res_ok(
- switch(co) {
- case NFS4_CONTENT_DATA:
- + DPRINTF(2,
- + ("i=%d, 'NFS4_CONTENT_DATA' content\n", (int)i));
- +
- if (!xdr_u_hyper(xdr, &contents[i].u.data.offset)) {
- DPRINTF(0,
- ("i=%d, decoding 'offset' failed\n", (int)i));
- @@ -207,7 +210,7 @@ static bool_t decode_read_plus_res_ok(
- unsigned char *hole_buff;
- uint64_t hole_length;
- - DPRINTF(0,
- + DPRINTF(2,
- ("i=%d, 'NFS4_CONTENT_HOLE' content\n", (int)i));
- if (!xdr_u_hyper(xdr, &contents[i].u.hole.offset))
- return FALSE;
- --
- 2.45.1
- From 5d024f96ace8c3209a68468d3eab063c4d09c6c6 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 7 Apr 2025 17:45:12 +0200
- Subject: [PATCH 5/8] daemon: Fix compiler warning in
- |decode_read_plus_res_ok()|
- Fix compiler warning in |decode_read_plus_res_ok()|.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/nfs42_xdr.c | 4 ++++
- 1 file changed, 4 insertions(+)
- diff --git a/daemon/nfs42_xdr.c b/daemon/nfs42_xdr.c
- index 316d03d..12d133b 100644
- --- a/daemon/nfs42_xdr.c
- +++ b/daemon/nfs42_xdr.c
- @@ -175,6 +175,7 @@ static bool_t decode_read_plus_res_ok(
- switch(co) {
- case NFS4_CONTENT_DATA:
- + {
- DPRINTF(2,
- ("i=%d, 'NFS4_CONTENT_DATA' content\n", (int)i));
- @@ -205,8 +206,10 @@ static bool_t decode_read_plus_res_ok(
- read_data_len = __max(read_data_len,
- ((size_t)(contents[i].u.data.data - res->data) +
- contents[i].u.data.data_len));
- + }
- break;
- case NFS4_CONTENT_HOLE:
- + {
- unsigned char *hole_buff;
- uint64_t hole_length;
- @@ -240,6 +243,7 @@ static bool_t decode_read_plus_res_ok(
- read_data_len = __max(read_data_len,
- ((hole_buff - res->data) + hole_length));
- + }
- break;
- default:
- eprintf("decode_read_plus_res_ok: unknown co=%d\n",
- --
- 2.45.1
- From 4e4dae97efe9ef3878cc0d6f5433c601e2dcce0e Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 7 Apr 2025 18:23:42 +0200
- Subject: [PATCH 6/8] sys: RFE: Increase default rsize=/wsize= value to 4MB
- RFE: Increase default rsize=/wsize= value to 4MB
- Reported-by: Cedric Blancher <cedric.blancher@gmail.com>
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_driver.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index d086d2e..c671625 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -295,7 +295,7 @@ nfs41_updowncall_list upcall, downcall;
- #define SERVER_NAME_BUFFER_SIZE 1024
- #define MOUNT_CONFIG_RW_SIZE_MIN 8192
- -#define MOUNT_CONFIG_RW_SIZE_DEFAULT (1*1024*1024)
- +#define MOUNT_CONFIG_RW_SIZE_DEFAULT (4*1024*1024)
- #define MOUNT_CONFIG_RW_SIZE_MAX (16*1024*1024)
- #define MAX_SEC_FLAVOR_LEN 12
- #define UPCALL_TIMEOUT_DEFAULT 50 /* in seconds */
- --
- 2.45.1
- From 8df76fc31bc7815ce0bc6bb4425454f631f15e72 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 7 Apr 2025 19:18:18 +0200
- Subject: [PATCH 7/8] tests: testsparseexe1.ksh should test *.exe checksums
- before/after cp
- testsparseexe1.ksh should test *.exe checksums before/after cp,
- the checksums should be identical since only sequences of 0x00-bytes
- are turned into holes, and holes read as 0x00 bytes.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- tests/sparsefiles/testsparseexe1.ksh | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
- diff --git a/tests/sparsefiles/testsparseexe1.ksh b/tests/sparsefiles/testsparseexe1.ksh
- index 9eebed5..87f4eab 100644
- --- a/tests/sparsefiles/testsparseexe1.ksh
- +++ b/tests/sparsefiles/testsparseexe1.ksh
- @@ -114,6 +114,8 @@ function test_sparseexe1
- integer res.sparseexe_sparse_blocks=$(stat --printf '%b\n' 'sparseexe_sparse.exe')
- integer res.sparseexe_orig_filesize=$(stat --printf '%s\n' 'sparseexe_orig.exe')
- integer res.sparseexe_sparse_filesize=$(stat --printf '%s\n' 'sparseexe_sparse.exe')
- + typeset res.sparseexe_orig_md5hash=$(md5sum --total 'sparseexe_orig.exe')
- + typeset res.sparseexe_sparse_md5hash=$(md5sum --total '%s\n' 'sparseexe_sparse.exe')
- compound res.testrun=(
- typeset stderr=''
- @@ -164,6 +166,16 @@ function test_sparseexe1
- (( res.errors++ ))
- fi
- + if [[ "${res.sparseexe_orig_md5hash}" == "${res.sparseexe_sparse_md5hash}" ]] ; then
- + printf 'test file MD5 hash sum: OK, both hash sums are identical (%q)\n' \
- + "${res.sparseexe_sparse_md5hash}"
- + else
- + printf '# ERROR: MD5 hash sums are NOT identical (%q != %q)\n' \
- + "${res.sparseexe_orig_md5hash}" \
- + "${res.sparseexe_sparse_md5hash}"
- + (( res.errors++ ))
- + fi
- +
- if (( res.errors == 0 )) ; then
- printf '#### %s: All tests OK\n' "$0"
- exit 0
- @@ -180,6 +192,7 @@ function test_sparseexe1
- #
- builtin cat
- builtin rm
- +builtin md5sum || exit 1 # need AST md5sum for option --total
- test_sparseexe1
- --
- 2.45.1
- From d8da6e8dbdb3bc58a7da4ddaa759a98b579683b4 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 7 Apr 2025 19:28:55 +0200
- Subject: [PATCH 8/8] tests: testsparseexe1.ksh minor cleanup
- testsparseexe1.ksh minor cleanup
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- tests/sparsefiles/testsparseexe1.ksh | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
- diff --git a/tests/sparsefiles/testsparseexe1.ksh b/tests/sparsefiles/testsparseexe1.ksh
- index 87f4eab..b2c2a42 100644
- --- a/tests/sparsefiles/testsparseexe1.ksh
- +++ b/tests/sparsefiles/testsparseexe1.ksh
- @@ -98,12 +98,12 @@ function test_sparseexe1
- # /usr/bin/cp.exe has sparse file support (which depends on
- # SEEK_HOLE+SEEK_DATA.
- #
- - if which -a 'fallocate.exe' 2>'/dev/null' ; then
- - print $'# copy *.exe via cp --sparse=always, turn all sections with long sequences of \'\\0\'-bytes into "holes" ...'
- + if which -a 'fallocate.exe' 1>'/dev/null' ; then
- + print $'# copy *.exe via cp --sparse=always, turn all sections with long sequences of 0x00-bytes into "holes" ...'
- # explicitly use /usr/bin/cp and not the AST cp builtin
- /usr/bin/cp --sparse=always 'sparseexe_orig.exe' 'sparseexe_sparse.exe'
- else
- - print $'# copy *.exe via dd conv=sparse, turn all sections with long sequences of \'\\0\'-bytes into "holes" ...'
- + print $'# copy *.exe via dd conv=sparse, turn all sections with long sequences of 0x00-bytes into "holes" ...'
- # explicitly use /usr/bin/cp and not the AST cp builtin
- dd if='sparseexe_orig.exe' of='sparseexe_sparse.exe' conv=sparse
- chmod a+x 'sparseexe_sparse.exe'
- @@ -115,7 +115,7 @@ function test_sparseexe1
- integer res.sparseexe_orig_filesize=$(stat --printf '%s\n' 'sparseexe_orig.exe')
- integer res.sparseexe_sparse_filesize=$(stat --printf '%s\n' 'sparseexe_sparse.exe')
- typeset res.sparseexe_orig_md5hash=$(md5sum --total 'sparseexe_orig.exe')
- - typeset res.sparseexe_sparse_md5hash=$(md5sum --total '%s\n' 'sparseexe_sparse.exe')
- + typeset res.sparseexe_sparse_md5hash=$(md5sum --total 'sparseexe_sparse.exe')
- compound res.testrun=(
- typeset stderr=''
- --
- 2.45.1
msnfs41client: Patches for sparse support, READ_PLUS hole crash, increase r/w buffer size, tests+misc, 2025-04-07
Posted by Anonymous on Mon 7th Apr 2025 21:18
raw | new post
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.