diff options
| -rw-r--r-- | fs/cifs/cifsglob.h | 3 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 3 | ||||
| -rw-r--r-- | fs/cifs/smb2ops.c | 8 | ||||
| -rw-r--r-- | fs/cifs/smb2pdu.c | 49 | ||||
| -rw-r--r-- | fs/cifs/smb2pdu.h | 12 | ||||
| -rw-r--r-- | fs/cifs/smb2proto.h | 1 |
6 files changed, 73 insertions, 3 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 0c53a8339253..ae9a1e900c15 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -73,6 +73,9 @@ | |||
| 73 | /* (max path length + 1 for null) * 2 for unicode */ | 73 | /* (max path length + 1 for null) * 2 for unicode */ |
| 74 | #define MAX_NAME 514 | 74 | #define MAX_NAME 514 |
| 75 | 75 | ||
| 76 | /* SMB echo "timeout" -- FIXME: tunable? */ | ||
| 77 | #define SMB_ECHO_INTERVAL (60 * HZ) | ||
| 78 | |||
| 76 | #include "cifspdu.h" | 79 | #include "cifspdu.h" |
| 77 | 80 | ||
| 78 | #ifndef XATTR_DOS_ATTRIB | 81 | #ifndef XATTR_DOS_ATTRIB |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index a83ed766aa94..5ab173fd6339 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -56,9 +56,6 @@ | |||
| 56 | #define CIFS_PORT 445 | 56 | #define CIFS_PORT 445 |
| 57 | #define RFC1001_PORT 139 | 57 | #define RFC1001_PORT 139 |
| 58 | 58 | ||
| 59 | /* SMB echo "timeout" -- FIXME: tunable? */ | ||
| 60 | #define SMB_ECHO_INTERVAL (60 * HZ) | ||
| 61 | |||
| 62 | extern mempool_t *cifs_req_poolp; | 59 | extern mempool_t *cifs_req_poolp; |
| 63 | 60 | ||
| 64 | /* FIXME: should these be tunable? */ | 61 | /* FIXME: should these be tunable? */ |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 8672e49d1c4c..483bd0ba2ecb 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
| @@ -207,6 +207,12 @@ smb2_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, | |||
| 207 | return NULL; | 207 | return NULL; |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | static bool | ||
| 211 | smb2_can_echo(struct TCP_Server_Info *server) | ||
| 212 | { | ||
| 213 | return server->echoes; | ||
| 214 | } | ||
| 215 | |||
| 210 | struct smb_version_operations smb21_operations = { | 216 | struct smb_version_operations smb21_operations = { |
| 211 | .setup_request = smb2_setup_request, | 217 | .setup_request = smb2_setup_request, |
| 212 | .setup_async_request = smb2_setup_async_request, | 218 | .setup_async_request = smb2_setup_async_request, |
| @@ -226,6 +232,8 @@ struct smb_version_operations smb21_operations = { | |||
| 226 | .tree_connect = SMB2_tcon, | 232 | .tree_connect = SMB2_tcon, |
| 227 | .tree_disconnect = SMB2_tdis, | 233 | .tree_disconnect = SMB2_tdis, |
| 228 | .is_path_accessible = smb2_is_path_accessible, | 234 | .is_path_accessible = smb2_is_path_accessible, |
| 235 | .can_echo = smb2_can_echo, | ||
| 236 | .echo = SMB2_echo, | ||
| 229 | .query_path_info = smb2_query_path_info, | 237 | .query_path_info = smb2_query_path_info, |
| 230 | .get_srv_inum = smb2_get_srv_inum, | 238 | .get_srv_inum = smb2_get_srv_inum, |
| 231 | .build_path_to_root = smb2_build_path_to_root, | 239 | .build_path_to_root = smb2_build_path_to_root, |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 7ef5324786a6..373b6945161f 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
| @@ -1074,3 +1074,52 @@ qinf_exit: | |||
| 1074 | free_rsp_buf(resp_buftype, rsp); | 1074 | free_rsp_buf(resp_buftype, rsp); |
| 1075 | return rc; | 1075 | return rc; |
| 1076 | } | 1076 | } |
| 1077 | |||
| 1078 | /* | ||
| 1079 | * This is a no-op for now. We're not really interested in the reply, but | ||
| 1080 | * rather in the fact that the server sent one and that server->lstrp | ||
| 1081 | * gets updated. | ||
| 1082 | * | ||
| 1083 | * FIXME: maybe we should consider checking that the reply matches request? | ||
| 1084 | */ | ||
| 1085 | static void | ||
| 1086 | smb2_echo_callback(struct mid_q_entry *mid) | ||
| 1087 | { | ||
| 1088 | struct TCP_Server_Info *server = mid->callback_data; | ||
| 1089 | struct smb2_echo_rsp *smb2 = (struct smb2_echo_rsp *)mid->resp_buf; | ||
| 1090 | unsigned int credits_received = 1; | ||
| 1091 | |||
| 1092 | if (mid->mid_state == MID_RESPONSE_RECEIVED) | ||
| 1093 | credits_received = le16_to_cpu(smb2->hdr.CreditRequest); | ||
| 1094 | |||
| 1095 | DeleteMidQEntry(mid); | ||
| 1096 | add_credits(server, credits_received, CIFS_ECHO_OP); | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | int | ||
| 1100 | SMB2_echo(struct TCP_Server_Info *server) | ||
| 1101 | { | ||
| 1102 | struct smb2_echo_req *req; | ||
| 1103 | int rc = 0; | ||
| 1104 | struct kvec iov; | ||
| 1105 | |||
| 1106 | cFYI(1, "In echo request"); | ||
| 1107 | |||
| 1108 | rc = small_smb2_init(SMB2_ECHO, NULL, (void **)&req); | ||
| 1109 | if (rc) | ||
| 1110 | return rc; | ||
| 1111 | |||
| 1112 | req->hdr.CreditRequest = cpu_to_le16(1); | ||
| 1113 | |||
| 1114 | iov.iov_base = (char *)req; | ||
| 1115 | /* 4 for rfc1002 length field */ | ||
| 1116 | iov.iov_len = get_rfc1002_length(req) + 4; | ||
| 1117 | |||
| 1118 | rc = cifs_call_async(server, &iov, 1, NULL, smb2_echo_callback, server, | ||
| 1119 | CIFS_ECHO_OP); | ||
| 1120 | if (rc) | ||
| 1121 | cFYI(1, "Echo request failed: %d", rc); | ||
| 1122 | |||
| 1123 | cifs_small_buf_release(req); | ||
| 1124 | return rc; | ||
| 1125 | } | ||
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index 9151e9040b02..59aae608d366 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
| @@ -448,6 +448,18 @@ struct smb2_close_rsp { | |||
| 448 | __le32 Attributes; | 448 | __le32 Attributes; |
| 449 | } __packed; | 449 | } __packed; |
| 450 | 450 | ||
| 451 | struct smb2_echo_req { | ||
| 452 | struct smb2_hdr hdr; | ||
| 453 | __le16 StructureSize; /* Must be 4 */ | ||
| 454 | __u16 Reserved; | ||
| 455 | } __packed; | ||
| 456 | |||
| 457 | struct smb2_echo_rsp { | ||
| 458 | struct smb2_hdr hdr; | ||
| 459 | __le16 StructureSize; /* Must be 4 */ | ||
| 460 | __u16 Reserved; | ||
| 461 | } __packed; | ||
| 462 | |||
| 451 | /* Possible InfoType values */ | 463 | /* Possible InfoType values */ |
| 452 | #define SMB2_O_INFO_FILE 0x01 | 464 | #define SMB2_O_INFO_FILE 0x01 |
| 453 | #define SMB2_O_INFO_FILESYSTEM 0x02 | 465 | #define SMB2_O_INFO_FILESYSTEM 0x02 |
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 1a17955c35c9..902bbe2b5ad3 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h | |||
| @@ -73,5 +73,6 @@ extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, | |||
| 73 | extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, | 73 | extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, |
| 74 | u64 persistent_file_id, u64 volatile_file_id, | 74 | u64 persistent_file_id, u64 volatile_file_id, |
| 75 | struct smb2_file_all_info *data); | 75 | struct smb2_file_all_info *data); |
| 76 | extern int SMB2_echo(struct TCP_Server_Info *server); | ||
| 76 | 77 | ||
| 77 | #endif /* _SMB2PROTO_H */ | 78 | #endif /* _SMB2PROTO_H */ |
