Print this page
NEX-17289 Minimal SMB 3.0.2 support
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-1643 dtrace provider for smbsrv
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-5844 want SMB2 ioctl FSCTL_SRV_COPYCHUNK
NEX-6124 smb_fsop_read/write should allow file != sr->fid_ofile
NEX-6125 smbtorture invalid response with smb2.ioctl
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-3662 Backport illumos 1501: taskq_create_proc ... TQ_DYNAMIC puts tasks in p0 (take 2)
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Marcel Telka <marcel.telka@nexenta.com>
NEX-3576 RPC error when displaying open files via Windows MMC
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-2188 Browsing top level share produces RPC error 1728
SMB-122 smbd core dumps in smbd_dc_update / smb_log
SMB-117 Win7 fails to open security properties
SMB-11 SMB2 message parse & dispatch
SMB-12 SMB2 Negotiate Protocol
SMB-13 SMB2 Session Setup
SMB-14 SMB2 Logoff
SMB-15 SMB2 Tree Connect
SMB-16 SMB2 Tree Disconnect
SMB-17 SMB2 Create
SMB-18 SMB2 Close
SMB-19 SMB2 Flush
SMB-20 SMB2 Read
SMB-21 SMB2 Write
SMB-22 SMB2 Lock/Unlock
SMB-23 SMB2 Ioctl
SMB-24 SMB2 Cancel
SMB-25 SMB2 Echo
SMB-26 SMB2 Query Dir
SMB-27 SMB2 Change Notify
SMB-28 SMB2 Query Info
SMB-29 SMB2 Set Info
SMB-30 SMB2 Oplocks
SMB-53 SMB2 Create Context options
(SMB2 code review cleanup 1, 2, 3)
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/fs/smbsrv/smb2_read.c
+++ new/usr/src/uts/common/fs/smbsrv/smb2_read.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 - * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
13 + * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
14 14 */
15 15
16 16 /*
17 17 * Dispatch function for SMB2_READ
18 18 */
19 19
20 20 #include <smbsrv/smb2_kproto.h>
21 21 #include <smbsrv/smb_fsops.h>
22 22
23 +extern boolean_t smb_allow_unbuffered;
24 +
23 25 smb_sdrc_t
24 26 smb2_read(smb_request_t *sr)
25 27 {
26 28 smb_ofile_t *of = NULL;
27 29 smb_vdb_t *vdb = NULL;
28 30 struct mbuf *m = NULL;
29 31 uint16_t StructSize;
30 32 uint8_t Padding;
33 + uint8_t Flags;
31 34 uint8_t DataOff;
32 35 uint32_t Length;
33 36 uint64_t Offset;
34 37 smb2fid_t smb2fid;
35 38 uint32_t MinCount;
36 39 uint32_t Channel;
37 40 uint32_t Remaining;
38 41 uint16_t ChanInfoOffset;
39 42 uint16_t ChanInfoLength;
40 43 uint32_t XferCount;
41 44 uint32_t status;
42 45 int rc = 0;
46 + boolean_t unbuffered = B_FALSE;
47 + int ioflag = 0;
43 48
44 49 /*
45 50 * SMB2 Read request
46 51 */
47 52 rc = smb_mbc_decodef(
48 53 &sr->smb_data,
49 - "wb.lqqqlllww",
54 + "wbblqqqlllww",
50 55 &StructSize, /* w */
51 - &Padding, /* b. */
56 + &Padding, /* b */
57 + &Flags, /* b */
52 58 &Length, /* l */
53 59 &Offset, /* q */
54 60 &smb2fid.persistent, /* q */
55 61 &smb2fid.temporal, /* q */
56 62 &MinCount, /* l */
57 63 &Channel, /* l */
58 64 &Remaining, /* l */
59 65 &ChanInfoOffset, /* w */
60 66 &ChanInfoLength); /* w */
61 67 if (rc)
62 68 return (SDRC_ERROR);
63 69 if (StructSize != 49)
64 70 return (SDRC_ERROR);
65 71
72 + /*
73 + * Want FID lookup before the start probe.
74 + */
66 75 status = smb2sr_lookup_fid(sr, &smb2fid);
67 - if (status) {
68 - smb2sr_put_error(sr, status);
69 - return (SDRC_SUCCESS);
70 - }
71 76 of = sr->fid_ofile;
72 77
78 + DTRACE_SMB2_START(op__Read, smb_request_t *, sr); /* arg.rw */
79 +
80 + if (status)
81 + goto errout; /* Bad FID */
82 +
73 83 if (Length > smb2_max_rwsize) {
74 - smb2sr_put_error(sr, NT_STATUS_INVALID_PARAMETER);
75 - return (SDRC_SUCCESS);
84 + status = NT_STATUS_INVALID_PARAMETER;
85 + goto errout;
76 86 }
77 87 if (MinCount > Length)
78 88 MinCount = Length;
79 89
80 90 /* This is automatically free'd. */
81 91 vdb = smb_srm_zalloc(sr, sizeof (*vdb));
82 92 vdb->vdb_tag = 0;
83 93 vdb->vdb_uio.uio_iov = &vdb->vdb_iovec[0];
84 94 vdb->vdb_uio.uio_iovcnt = MAX_IOVEC;
85 95 vdb->vdb_uio.uio_resid = Length;
86 96 vdb->vdb_uio.uio_loffset = (offset_t)Offset;
87 97 vdb->vdb_uio.uio_segflg = UIO_SYSSPACE;
88 98 vdb->vdb_uio.uio_extflg = UIO_COPY_DEFAULT;
89 99
90 100 sr->raw_data.max_bytes = Length;
91 101 m = smb_mbuf_allocate(&vdb->vdb_uio);
92 102
103 + /*
104 + * Unbuffered refers to the MS-FSA Read argument by the same name.
105 + * It indicates that the cache for this range should be flushed to disk,
106 + * and data read directly from disk, bypassing the cache.
107 + * We don't allow that degree of cache management.
108 + * Translate this directly as FRSYNC,
109 + * which should at least flush the cache first.
110 + */
111 +
112 + if (smb_allow_unbuffered &&
113 + (Flags & SMB2_READFLAG_READ_UNBUFFERED) != 0) {
114 + unbuffered = B_TRUE;
115 + ioflag = FRSYNC;
116 + }
117 +
93 118 switch (of->f_tree->t_res_type & STYPE_MASK) {
94 119 case STYPE_DISKTREE:
95 120 if (!smb_node_is_dir(of->f_node)) {
96 121 /* Check for conflicting locks. */
97 122 rc = smb_lock_range_access(sr, of->f_node,
98 123 Offset, Length, B_FALSE);
99 124 if (rc) {
100 125 rc = ERANGE;
101 126 break;
102 127 }
103 128 }
104 - rc = smb_fsop_read(sr, of->f_cr, of->f_node, &vdb->vdb_uio);
129 + rc = smb_fsop_read(sr, of->f_cr, of->f_node, of,
130 + &vdb->vdb_uio, ioflag);
105 131 break;
106 132 case STYPE_IPC:
107 - rc = smb_opipe_read(sr, &vdb->vdb_uio);
133 + if (unbuffered)
134 + rc = EINVAL;
135 + else
136 + rc = smb_opipe_read(sr, &vdb->vdb_uio);
108 137 break;
109 138 default:
110 139 case STYPE_PRINTQ:
111 140 rc = EACCES;
112 141 break;
113 142 }
143 + status = smb_errno2status(rc);
114 144
115 145 /* How much data we moved. */
116 146 XferCount = Length - vdb->vdb_uio.uio_resid;
117 147
118 148 sr->raw_data.max_bytes = XferCount;
119 149 smb_mbuf_trim(m, XferCount);
120 150 MBC_ATTACH_MBUF(&sr->raw_data, m);
121 151
122 152 /*
123 153 * Checking the error return _after_ dealing with
124 154 * the returned data so that if m was allocated,
125 155 * it will be free'd via sr->raw_data cleanup.
126 156 */
127 - if (rc) {
128 - smb2sr_put_errno(sr, rc);
157 +errout:
158 + sr->smb2_status = status;
159 + DTRACE_SMB2_DONE(op__Read, smb_request_t *, sr); /* arg.rw */
160 + if (status) {
161 + smb2sr_put_error(sr, status);
129 162 return (SDRC_SUCCESS);
130 163 }
131 164
132 165 /*
133 166 * SMB2 Read reply
134 167 */
135 168 DataOff = SMB2_HDR_SIZE + 16;
136 169 rc = smb_mbc_encodef(
137 170 &sr->reply,
138 171 "wb.lllC",
139 172 17, /* StructSize */ /* w */
140 173 DataOff, /* b. */
141 174 XferCount, /* l */
142 175 0, /* DataRemaining */ /* l */
143 176 0, /* reserved */ /* l */
144 177 &sr->raw_data); /* C */
145 - if (rc)
178 + if (rc) {
179 + sr->smb2_status = NT_STATUS_INTERNAL_ERROR;
146 180 return (SDRC_ERROR);
181 + }
147 182
148 183 mutex_enter(&of->f_mutex);
149 184 of->f_seek_pos = Offset + XferCount;
150 185 mutex_exit(&of->f_mutex);
151 186
152 187 return (SDRC_SUCCESS);
153 188 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX