diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2012-09-18 19:20:29 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-09-24 22:46:27 -0400 |
commit | 09a4707e7638247302c6d798061aed117141fb74 (patch) | |
tree | d31b23d8b91941b30425d6a4d8235d9e91d7afef /fs/cifs | |
parent | fc9c59662e0cd37577556d0de865268baeb9b293 (diff) |
CIFS: Add SMB2 support for cifs_iovec_read
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/cifsglob.h | 25 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 20 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 2 | ||||
-rw-r--r-- | fs/cifs/file.c | 4 | ||||
-rw-r--r-- | fs/cifs/smb2glob.h | 6 | ||||
-rw-r--r-- | fs/cifs/smb2misc.c | 3 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 19 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 137 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.h | 28 | ||||
-rw-r--r-- | fs/cifs/smb2proto.h | 1 |
10 files changed, 225 insertions, 20 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index fcf81c05635f..93dd582bb8d1 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -857,12 +857,37 @@ struct cifsFileInfo { | |||
857 | 857 | ||
858 | struct cifs_io_parms { | 858 | struct cifs_io_parms { |
859 | __u16 netfid; | 859 | __u16 netfid; |
860 | #ifdef CONFIG_CIFS_SMB2 | ||
861 | __u64 persistent_fid; /* persist file id for smb2 */ | ||
862 | __u64 volatile_fid; /* volatile file id for smb2 */ | ||
863 | #endif | ||
860 | __u32 pid; | 864 | __u32 pid; |
861 | __u64 offset; | 865 | __u64 offset; |
862 | unsigned int length; | 866 | unsigned int length; |
863 | struct cifs_tcon *tcon; | 867 | struct cifs_tcon *tcon; |
864 | }; | 868 | }; |
865 | 869 | ||
870 | struct cifs_readdata; | ||
871 | |||
872 | /* asynchronous read support */ | ||
873 | struct cifs_readdata { | ||
874 | struct kref refcount; | ||
875 | struct list_head list; | ||
876 | struct completion done; | ||
877 | struct cifsFileInfo *cfile; | ||
878 | struct address_space *mapping; | ||
879 | __u64 offset; | ||
880 | unsigned int bytes; | ||
881 | pid_t pid; | ||
882 | int result; | ||
883 | struct list_head pages; | ||
884 | struct work_struct work; | ||
885 | int (*marshal_iov) (struct cifs_readdata *rdata, | ||
886 | unsigned int remaining); | ||
887 | unsigned int nr_iov; | ||
888 | struct kvec iov[1]; | ||
889 | }; | ||
890 | |||
866 | /* | 891 | /* |
867 | * Take a reference on the file private data. Must be called with | 892 | * Take a reference on the file private data. Must be called with |
868 | * cifs_file_list_lock held. | 893 | * cifs_file_list_lock held. |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 2c6ad78a16cc..6656eb5dbf70 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -464,27 +464,9 @@ extern int E_md4hash(const unsigned char *passwd, unsigned char *p16, | |||
464 | extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, | 464 | extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, |
465 | unsigned char *p24); | 465 | unsigned char *p24); |
466 | 466 | ||
467 | /* asynchronous read support */ | ||
468 | struct cifs_readdata { | ||
469 | struct kref refcount; | ||
470 | struct list_head list; | ||
471 | struct completion done; | ||
472 | struct cifsFileInfo *cfile; | ||
473 | struct address_space *mapping; | ||
474 | __u64 offset; | ||
475 | unsigned int bytes; | ||
476 | pid_t pid; | ||
477 | int result; | ||
478 | struct list_head pages; | ||
479 | struct work_struct work; | ||
480 | int (*marshal_iov) (struct cifs_readdata *rdata, | ||
481 | unsigned int remaining); | ||
482 | unsigned int nr_iov; | ||
483 | struct kvec iov[1]; | ||
484 | }; | ||
485 | |||
486 | void cifs_readdata_release(struct kref *refcount); | 467 | void cifs_readdata_release(struct kref *refcount); |
487 | int cifs_async_readv(struct cifs_readdata *rdata); | 468 | int cifs_async_readv(struct cifs_readdata *rdata); |
469 | int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid); | ||
488 | 470 | ||
489 | /* asynchronous write support */ | 471 | /* asynchronous write support */ |
490 | struct cifs_writedata { | 472 | struct cifs_writedata { |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 4c48b9c60b26..8a07f218266f 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -1440,7 +1440,7 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) | |||
1440 | return 0; | 1440 | return 0; |
1441 | } | 1441 | } |
1442 | 1442 | ||
1443 | static int | 1443 | int |
1444 | cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) | 1444 | cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) |
1445 | { | 1445 | { |
1446 | int length, len; | 1446 | int length, len; |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ec7c2e6bcbdf..29ac8ee46039 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -2732,6 +2732,10 @@ restart_loop: | |||
2732 | cifs_stats_bytes_read(tcon, total_read); | 2732 | cifs_stats_bytes_read(tcon, total_read); |
2733 | *poffset += total_read; | 2733 | *poffset += total_read; |
2734 | 2734 | ||
2735 | /* mask nodata case */ | ||
2736 | if (rc == -ENODATA) | ||
2737 | rc = 0; | ||
2738 | |||
2735 | return total_read ? total_read : rc; | 2739 | return total_read ? total_read : rc; |
2736 | } | 2740 | } |
2737 | 2741 | ||
diff --git a/fs/cifs/smb2glob.h b/fs/cifs/smb2glob.h index 33c1d89090c0..11505d73ff32 100644 --- a/fs/cifs/smb2glob.h +++ b/fs/cifs/smb2glob.h | |||
@@ -41,4 +41,10 @@ | |||
41 | #define SMB2_OP_RENAME 6 | 41 | #define SMB2_OP_RENAME 6 |
42 | #define SMB2_OP_DELETE 7 | 42 | #define SMB2_OP_DELETE 7 |
43 | 43 | ||
44 | /* Used when constructing chained read requests. */ | ||
45 | #define CHAINED_REQUEST 1 | ||
46 | #define START_OF_CHAIN 2 | ||
47 | #define END_OF_CHAIN 4 | ||
48 | #define RELATED_REQUEST 8 | ||
49 | |||
44 | #endif /* _SMB2_GLOB_H */ | 50 | #endif /* _SMB2_GLOB_H */ |
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index e4d3b9964167..9275883c8530 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c | |||
@@ -244,6 +244,9 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr) | |||
244 | ((struct smb2_query_info_rsp *)hdr)->OutputBufferLength); | 244 | ((struct smb2_query_info_rsp *)hdr)->OutputBufferLength); |
245 | break; | 245 | break; |
246 | case SMB2_READ: | 246 | case SMB2_READ: |
247 | *off = ((struct smb2_read_rsp *)hdr)->DataOffset; | ||
248 | *len = le32_to_cpu(((struct smb2_read_rsp *)hdr)->DataLength); | ||
249 | break; | ||
247 | case SMB2_QUERY_DIRECTORY: | 250 | case SMB2_QUERY_DIRECTORY: |
248 | case SMB2_IOCTL: | 251 | case SMB2_IOCTL: |
249 | case SMB2_CHANGE_NOTIFY: | 252 | case SMB2_CHANGE_NOTIFY: |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 20afb756e97a..d9ca357d9809 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -379,6 +379,20 @@ smb2_flush_file(const unsigned int xid, struct cifs_tcon *tcon, | |||
379 | return SMB2_flush(xid, tcon, fid->persistent_fid, fid->volatile_fid); | 379 | return SMB2_flush(xid, tcon, fid->persistent_fid, fid->volatile_fid); |
380 | } | 380 | } |
381 | 381 | ||
382 | static unsigned int | ||
383 | smb2_read_data_offset(char *buf) | ||
384 | { | ||
385 | struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf; | ||
386 | return rsp->DataOffset; | ||
387 | } | ||
388 | |||
389 | static unsigned int | ||
390 | smb2_read_data_length(char *buf) | ||
391 | { | ||
392 | struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf; | ||
393 | return le32_to_cpu(rsp->DataLength); | ||
394 | } | ||
395 | |||
382 | struct smb_version_operations smb21_operations = { | 396 | struct smb_version_operations smb21_operations = { |
383 | .setup_request = smb2_setup_request, | 397 | .setup_request = smb2_setup_request, |
384 | .setup_async_request = smb2_setup_async_request, | 398 | .setup_async_request = smb2_setup_async_request, |
@@ -388,6 +402,9 @@ struct smb_version_operations smb21_operations = { | |||
388 | .get_credits_field = smb2_get_credits_field, | 402 | .get_credits_field = smb2_get_credits_field, |
389 | .get_credits = smb2_get_credits, | 403 | .get_credits = smb2_get_credits, |
390 | .get_next_mid = smb2_get_next_mid, | 404 | .get_next_mid = smb2_get_next_mid, |
405 | .read_data_offset = smb2_read_data_offset, | ||
406 | .read_data_length = smb2_read_data_length, | ||
407 | .map_error = map_smb2_to_linux_error, | ||
391 | .find_mid = smb2_find_mid, | 408 | .find_mid = smb2_find_mid, |
392 | .check_message = smb2_check_message, | 409 | .check_message = smb2_check_message, |
393 | .dump_detail = smb2_dump_detail, | 410 | .dump_detail = smb2_dump_detail, |
@@ -416,12 +433,14 @@ struct smb_version_operations smb21_operations = { | |||
416 | .set_fid = smb2_set_fid, | 433 | .set_fid = smb2_set_fid, |
417 | .close = smb2_close_file, | 434 | .close = smb2_close_file, |
418 | .flush = smb2_flush_file, | 435 | .flush = smb2_flush_file, |
436 | .async_readv = smb2_async_readv, | ||
419 | }; | 437 | }; |
420 | 438 | ||
421 | struct smb_version_values smb21_values = { | 439 | struct smb_version_values smb21_values = { |
422 | .version_string = SMB21_VERSION_STRING, | 440 | .version_string = SMB21_VERSION_STRING, |
423 | .header_size = sizeof(struct smb2_hdr), | 441 | .header_size = sizeof(struct smb2_hdr), |
424 | .max_header_size = MAX_SMB2_HDR_SIZE, | 442 | .max_header_size = MAX_SMB2_HDR_SIZE, |
443 | .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, | ||
425 | .lock_cmd = SMB2_LOCK, | 444 | .lock_cmd = SMB2_LOCK, |
426 | .cap_unix = 0, | 445 | .cap_unix = 0, |
427 | .cap_nt_find = SMB2_NT_FIND, | 446 | .cap_nt_find = SMB2_NT_FIND, |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index ff374063f4e2..e18671852d41 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/fs.h> | 31 | #include <linux/fs.h> |
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/vfs.h> | 33 | #include <linux/vfs.h> |
34 | #include <linux/task_io_accounting_ops.h> | ||
34 | #include <linux/uaccess.h> | 35 | #include <linux/uaccess.h> |
35 | #include <linux/xattr.h> | 36 | #include <linux/xattr.h> |
36 | #include "smb2pdu.h" | 37 | #include "smb2pdu.h" |
@@ -42,6 +43,7 @@ | |||
42 | #include "cifs_debug.h" | 43 | #include "cifs_debug.h" |
43 | #include "ntlmssp.h" | 44 | #include "ntlmssp.h" |
44 | #include "smb2status.h" | 45 | #include "smb2status.h" |
46 | #include "smb2glob.h" | ||
45 | 47 | ||
46 | /* | 48 | /* |
47 | * The following table defines the expected "StructureSize" of SMB2 requests | 49 | * The following table defines the expected "StructureSize" of SMB2 requests |
@@ -1190,3 +1192,138 @@ SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, | |||
1190 | free_rsp_buf(resp_buftype, iov[0].iov_base); | 1192 | free_rsp_buf(resp_buftype, iov[0].iov_base); |
1191 | return rc; | 1193 | return rc; |
1192 | } | 1194 | } |
1195 | |||
1196 | /* | ||
1197 | * To form a chain of read requests, any read requests after the first should | ||
1198 | * have the end_of_chain boolean set to true. | ||
1199 | */ | ||
1200 | static int | ||
1201 | smb2_new_read_req(struct kvec *iov, struct cifs_io_parms *io_parms, | ||
1202 | unsigned int remaining_bytes, int request_type) | ||
1203 | { | ||
1204 | int rc = -EACCES; | ||
1205 | struct smb2_read_req *req = NULL; | ||
1206 | |||
1207 | rc = small_smb2_init(SMB2_READ, io_parms->tcon, (void **) &req); | ||
1208 | if (rc) | ||
1209 | return rc; | ||
1210 | if (io_parms->tcon->ses->server == NULL) | ||
1211 | return -ECONNABORTED; | ||
1212 | |||
1213 | req->hdr.ProcessId = cpu_to_le32(io_parms->pid); | ||
1214 | |||
1215 | req->PersistentFileId = io_parms->persistent_fid; | ||
1216 | req->VolatileFileId = io_parms->volatile_fid; | ||
1217 | req->ReadChannelInfoOffset = 0; /* reserved */ | ||
1218 | req->ReadChannelInfoLength = 0; /* reserved */ | ||
1219 | req->Channel = 0; /* reserved */ | ||
1220 | req->MinimumCount = 0; | ||
1221 | req->Length = cpu_to_le32(io_parms->length); | ||
1222 | req->Offset = cpu_to_le64(io_parms->offset); | ||
1223 | |||
1224 | if (request_type & CHAINED_REQUEST) { | ||
1225 | if (!(request_type & END_OF_CHAIN)) { | ||
1226 | /* 4 for rfc1002 length field */ | ||
1227 | req->hdr.NextCommand = | ||
1228 | cpu_to_le32(get_rfc1002_length(req) + 4); | ||
1229 | } else /* END_OF_CHAIN */ | ||
1230 | req->hdr.NextCommand = 0; | ||
1231 | if (request_type & RELATED_REQUEST) { | ||
1232 | req->hdr.Flags |= SMB2_FLAGS_RELATED_OPERATIONS; | ||
1233 | /* | ||
1234 | * Related requests use info from previous read request | ||
1235 | * in chain. | ||
1236 | */ | ||
1237 | req->hdr.SessionId = 0xFFFFFFFF; | ||
1238 | req->hdr.TreeId = 0xFFFFFFFF; | ||
1239 | req->PersistentFileId = 0xFFFFFFFF; | ||
1240 | req->VolatileFileId = 0xFFFFFFFF; | ||
1241 | } | ||
1242 | } | ||
1243 | if (remaining_bytes > io_parms->length) | ||
1244 | req->RemainingBytes = cpu_to_le32(remaining_bytes); | ||
1245 | else | ||
1246 | req->RemainingBytes = 0; | ||
1247 | |||
1248 | iov[0].iov_base = (char *)req; | ||
1249 | /* 4 for rfc1002 length field */ | ||
1250 | iov[0].iov_len = get_rfc1002_length(req) + 4; | ||
1251 | return rc; | ||
1252 | } | ||
1253 | |||
1254 | static void | ||
1255 | smb2_readv_callback(struct mid_q_entry *mid) | ||
1256 | { | ||
1257 | struct cifs_readdata *rdata = mid->callback_data; | ||
1258 | struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink); | ||
1259 | struct TCP_Server_Info *server = tcon->ses->server; | ||
1260 | struct smb2_hdr *buf = (struct smb2_hdr *)rdata->iov[0].iov_base; | ||
1261 | unsigned int credits_received = 1; | ||
1262 | |||
1263 | cFYI(1, "%s: mid=%llu state=%d result=%d bytes=%u", __func__, | ||
1264 | mid->mid, mid->mid_state, rdata->result, rdata->bytes); | ||
1265 | |||
1266 | switch (mid->mid_state) { | ||
1267 | case MID_RESPONSE_RECEIVED: | ||
1268 | credits_received = le16_to_cpu(buf->CreditRequest); | ||
1269 | /* result already set, check signature */ | ||
1270 | /* if (server->sec_mode & | ||
1271 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | ||
1272 | if (smb2_verify_signature(mid->resp_buf, server)) | ||
1273 | cERROR(1, "Unexpected SMB signature"); */ | ||
1274 | /* FIXME: should this be counted toward the initiating task? */ | ||
1275 | task_io_account_read(rdata->bytes); | ||
1276 | cifs_stats_bytes_read(tcon, rdata->bytes); | ||
1277 | break; | ||
1278 | case MID_REQUEST_SUBMITTED: | ||
1279 | case MID_RETRY_NEEDED: | ||
1280 | rdata->result = -EAGAIN; | ||
1281 | break; | ||
1282 | default: | ||
1283 | if (rdata->result != -ENODATA) | ||
1284 | rdata->result = -EIO; | ||
1285 | } | ||
1286 | |||
1287 | if (rdata->result) | ||
1288 | cifs_stats_fail_inc(tcon, SMB2_READ_HE); | ||
1289 | |||
1290 | queue_work(cifsiod_wq, &rdata->work); | ||
1291 | DeleteMidQEntry(mid); | ||
1292 | add_credits(server, credits_received, 0); | ||
1293 | } | ||
1294 | |||
1295 | /* smb2_async_readv - send an async write, and set up mid to handle result */ | ||
1296 | int | ||
1297 | smb2_async_readv(struct cifs_readdata *rdata) | ||
1298 | { | ||
1299 | int rc; | ||
1300 | struct smb2_hdr *buf; | ||
1301 | struct cifs_io_parms io_parms; | ||
1302 | |||
1303 | cFYI(1, "%s: offset=%llu bytes=%u", __func__, | ||
1304 | rdata->offset, rdata->bytes); | ||
1305 | |||
1306 | io_parms.tcon = tlink_tcon(rdata->cfile->tlink); | ||
1307 | io_parms.offset = rdata->offset; | ||
1308 | io_parms.length = rdata->bytes; | ||
1309 | io_parms.persistent_fid = rdata->cfile->fid.persistent_fid; | ||
1310 | io_parms.volatile_fid = rdata->cfile->fid.volatile_fid; | ||
1311 | io_parms.pid = rdata->pid; | ||
1312 | rc = smb2_new_read_req(&rdata->iov[0], &io_parms, 0, 0); | ||
1313 | if (rc) | ||
1314 | return rc; | ||
1315 | |||
1316 | buf = (struct smb2_hdr *)rdata->iov[0].iov_base; | ||
1317 | /* 4 for rfc1002 length field */ | ||
1318 | rdata->iov[0].iov_len = get_rfc1002_length(rdata->iov[0].iov_base) + 4; | ||
1319 | |||
1320 | kref_get(&rdata->refcount); | ||
1321 | rc = cifs_call_async(io_parms.tcon->ses->server, rdata->iov, 1, | ||
1322 | cifs_readv_receive, smb2_readv_callback, | ||
1323 | rdata, 0); | ||
1324 | if (rc) | ||
1325 | kref_put(&rdata->refcount, cifs_readdata_release); | ||
1326 | |||
1327 | cifs_small_buf_release(buf); | ||
1328 | return rc; | ||
1329 | } | ||
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index f5bf63f66971..4abb58106809 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
@@ -468,6 +468,34 @@ struct smb2_flush_rsp { | |||
468 | __le16 Reserved; | 468 | __le16 Reserved; |
469 | } __packed; | 469 | } __packed; |
470 | 470 | ||
471 | struct smb2_read_req { | ||
472 | struct smb2_hdr hdr; | ||
473 | __le16 StructureSize; /* Must be 49 */ | ||
474 | __u8 Padding; /* offset from start of SMB2 header to place read */ | ||
475 | __u8 Reserved; | ||
476 | __le32 Length; | ||
477 | __le64 Offset; | ||
478 | __u64 PersistentFileId; /* opaque endianness */ | ||
479 | __u64 VolatileFileId; /* opaque endianness */ | ||
480 | __le32 MinimumCount; | ||
481 | __le32 Channel; /* Reserved MBZ */ | ||
482 | __le32 RemainingBytes; | ||
483 | __le16 ReadChannelInfoOffset; /* Reserved MBZ */ | ||
484 | __le16 ReadChannelInfoLength; /* Reserved MBZ */ | ||
485 | __u8 Buffer[1]; | ||
486 | } __packed; | ||
487 | |||
488 | struct smb2_read_rsp { | ||
489 | struct smb2_hdr hdr; | ||
490 | __le16 StructureSize; /* Must be 17 */ | ||
491 | __u8 DataOffset; | ||
492 | __u8 Reserved; | ||
493 | __le32 DataLength; | ||
494 | __le32 DataRemaining; | ||
495 | __u32 Reserved2; | ||
496 | __u8 Buffer[1]; | ||
497 | } __packed; | ||
498 | |||
471 | struct smb2_echo_req { | 499 | struct smb2_echo_req { |
472 | struct smb2_hdr hdr; | 500 | struct smb2_hdr hdr; |
473 | __le16 StructureSize; /* Must be 4 */ | 501 | __le16 StructureSize; /* Must be 4 */ |
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 51e6cd185c79..f442e4699974 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h | |||
@@ -97,6 +97,7 @@ extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, | |||
97 | extern int SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon, | 97 | extern int SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon, |
98 | u64 persistent_fid, u64 volatile_fid, | 98 | u64 persistent_fid, u64 volatile_fid, |
99 | __le64 *uniqueid); | 99 | __le64 *uniqueid); |
100 | extern int smb2_async_readv(struct cifs_readdata *rdata); | ||
100 | extern int SMB2_echo(struct TCP_Server_Info *server); | 101 | extern int SMB2_echo(struct TCP_Server_Info *server); |
101 | 102 | ||
102 | #endif /* _SMB2PROTO_H */ | 103 | #endif /* _SMB2PROTO_H */ |