kern/180979: [netsmb][patch]: Fix large files handling
Maxim Samsonov
xors at mailup.net
Wed Jul 31 19:00:00 UTC 2013
>Number: 180979
>Category: kern
>Synopsis: [netsmb][patch]: Fix large files handling
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Jul 31 19:00:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator: Maxim Samsonov
>Release: 9.2-BETA2
>Organization:
>Environment:
FreeBSD fern.localbroom.net 9.2-BETA2 FreeBSD 9.2-BETA2 #0: Wed Jul 31 13:50:29 MSK 2013 xors at fern.localbroom.net:/usr/obj/usr/src/sys/FERN amd64
>Description:
NETSMB should honour SMB_CAP_LARGE_FILES capability as well as SMB_CAP_LARGE_READX and SMB_CAP_LARGE_WRITEX capabilities in order to read/write large files (over 4G) correctly.
So 64-bit file offsets are supported if SMB_CAP_LARGE_FILES capability is detected.
This fix was inspired from the following NetBSD patch:
http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/netsmb/smb_smb.c?rev=1.31&content-type=text/x-cvsweb-markup&only_with_tag=MAIN
..
Fix detection of SMB capabilities according to the CIFS spec:
1.) SMB_CAP_LARGE_FILES advertises support for 64-bit file offsets.
2.) SMB_CAP_LARGE_READX and SMB_CAP_LARGE_WRITEX advertise support for
large reads and writes (larger than 64KB).
The code previously only used SMB_CAP_LARGE_READX and SMB_CAP_LARGE_WRITEX
which is not correct and doesn't work for the Apple Time Capsule which
only supports SMB_CAP_LARGE_FILES.
..
>How-To-Repeat:
>Fix:
Patch attached with submission follows:
diff --git a/sys/netsmb/smb_smb.c b/sys/netsmb/smb_smb.c
--- a/sys/netsmb/smb_smb.c
+++ b/sys/netsmb/smb_smb.c
@@ -771,7 +771,12 @@
u_int8_t wc;
int error, rlen, blksz;
- if (SSTOVC(ssp)->vc_sopt.sv_caps & SMB_CAP_LARGE_READX)
+ if (uio->uio_offset > UINT32_MAX
+ && !(SSTOVC(ssp)->vc_sopt.sv_caps & SMB_CAP_LARGE_FILES)) {
+ return (EFBIG);
+ }
+
+ if (SSTOVC(ssp)->vc_sopt.sv_caps & (SMB_CAP_LARGE_READX | SMB_CAP_LARGE_FILES))
return (smb_smb_readx(ssp, fid, len, rresid, uio, scred));
error = smb_rq_alloc(SSTOCP(ssp), SMB_COM_READ, scred, &rqp);
@@ -850,7 +855,12 @@
u_int8_t wc;
int error, blksz;
- if (*len && SSTOVC(ssp)->vc_sopt.sv_caps & SMB_CAP_LARGE_WRITEX)
+ if (uio->uio_offset > UINT32_MAX
+ && !(SSTOVC(ssp)->vc_sopt.sv_caps & SMB_CAP_LARGE_FILES)) {
+ return (EFBIG);
+ }
+
+ if (*len && SSTOVC(ssp)->vc_sopt.sv_caps & (SMB_CAP_LARGE_WRITEX | SMB_CAP_LARGE_FILES))
return (smb_smb_writex(ssp, fid, len, rresid, uio, scred));
blksz = SSTOVC(ssp)->vc_txmax - SMB_HDRLEN - 16;
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list