aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorSteve French <stfrench@microsoft.com>2019-07-06 15:41:38 -0400
committerSteve French <stfrench@microsoft.com>2019-07-07 23:37:44 -0400
commitff2a09e9196e2f9d5edc60d1a68bc3d3649d035b (patch)
treef87106734c684c680c8dc4d8dc3165fe4dba9383 /fs/cifs
parent96d3cca1241d6e56910b74435301e095705e1ebc (diff)
SMB3: query inode number on open via create context
We can cut the number of roundtrips on open (may also help some rename cases as well) by returning the inode number in the SMB2 open request itself instead of querying it afterwards via a query FILE_INTERNAL_INFO. This should significantly improve the performance of posix open. Add SMB2_CREATE_QUERY_ON_DISK_ID create context request on open calls so that when server supports this we can save a roundtrip for QUERY_INFO on every open. Follow on patch will add the response processing for SMB2_CREATE_QUERY_ON_DISK_ID context and optimize smb2_open_file to avoid the extra network roundtrip on every posix open. This patch adds the context on SMB2/SMB3 open requests. Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/smb2pdu.c48
-rw-r--r--fs/cifs/smb2pdu.h17
2 files changed, 60 insertions, 5 deletions
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 34d5397a1989..f58e4dc3987b 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -2118,6 +2118,48 @@ add_twarp_context(struct kvec *iov, unsigned int *num_iovec, __u64 timewarp)
2118 return 0; 2118 return 0;
2119} 2119}
2120 2120
2121static struct crt_query_id_ctxt *
2122create_query_id_buf(void)
2123{
2124 struct crt_query_id_ctxt *buf;
2125
2126 buf = kzalloc(sizeof(struct crt_query_id_ctxt), GFP_KERNEL);
2127 if (!buf)
2128 return NULL;
2129
2130 buf->ccontext.DataOffset = cpu_to_le16(0);
2131 buf->ccontext.DataLength = cpu_to_le32(0);
2132 buf->ccontext.NameOffset = cpu_to_le16(offsetof
2133 (struct crt_query_id_ctxt, Name));
2134 buf->ccontext.NameLength = cpu_to_le16(4);
2135 /* SMB2_CREATE_QUERY_ON_DISK_ID is "QFid" */
2136 buf->Name[0] = 'Q';
2137 buf->Name[1] = 'F';
2138 buf->Name[2] = 'i';
2139 buf->Name[3] = 'd';
2140 return buf;
2141}
2142
2143/* See MS-SMB2 2.2.13.2.9 */
2144static int
2145add_query_id_context(struct kvec *iov, unsigned int *num_iovec)
2146{
2147 struct smb2_create_req *req = iov[0].iov_base;
2148 unsigned int num = *num_iovec;
2149
2150 iov[num].iov_base = create_query_id_buf();
2151 if (iov[num].iov_base == NULL)
2152 return -ENOMEM;
2153 iov[num].iov_len = sizeof(struct crt_query_id_ctxt);
2154 if (!req->CreateContextsOffset)
2155 req->CreateContextsOffset = cpu_to_le32(
2156 sizeof(struct smb2_create_req) +
2157 iov[num - 1].iov_len);
2158 le32_add_cpu(&req->CreateContextsLength, sizeof(struct crt_query_id_ctxt));
2159 *num_iovec = num + 1;
2160 return 0;
2161}
2162
2121static int 2163static int
2122alloc_path_with_tree_prefix(__le16 **out_path, int *out_size, int *out_len, 2164alloc_path_with_tree_prefix(__le16 **out_path, int *out_size, int *out_len,
2123 const char *treename, const __le16 *path) 2165 const char *treename, const __le16 *path)
@@ -2446,6 +2488,12 @@ SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock,
2446 return rc; 2488 return rc;
2447 } 2489 }
2448 2490
2491 if (n_iov > 2) {
2492 struct create_context *ccontext =
2493 (struct create_context *)iov[n_iov-1].iov_base;
2494 ccontext->Next = cpu_to_le32(iov[n_iov-1].iov_len);
2495 }
2496 add_query_id_context(iov, &n_iov);
2449 2497
2450 rqst->rq_nvec = n_iov; 2498 rqst->rq_nvec = n_iov;
2451 return 0; 2499 return 0;
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index 053ec621e7b9..458bad01ca74 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -662,9 +662,10 @@ struct smb2_tree_disconnect_rsp {
662 * [3] : durable context 662 * [3] : durable context
663 * [4] : posix context 663 * [4] : posix context
664 * [5] : time warp context 664 * [5] : time warp context
665 * [6] : compound padding 665 * [6] : query id context
666 * [7] : compound padding
666 */ 667 */
667#define SMB2_CREATE_IOV_SIZE 7 668#define SMB2_CREATE_IOV_SIZE 8
668 669
669struct smb2_create_req { 670struct smb2_create_req {
670 struct smb2_sync_hdr sync_hdr; 671 struct smb2_sync_hdr sync_hdr;
@@ -688,10 +689,10 @@ struct smb2_create_req {
688 689
689/* 690/*
690 * Maximum size of a SMB2_CREATE response is 64 (smb2 header) + 691 * Maximum size of a SMB2_CREATE response is 64 (smb2 header) +
691 * 88 (fixed part of create response) + 520 (path) + 150 (contexts) + 692 * 88 (fixed part of create response) + 520 (path) + 208 (contexts) +
692 * 2 bytes of padding. 693 * 2 bytes of padding.
693 */ 694 */
694#define MAX_SMB2_CREATE_RESPONSE_SIZE 824 695#define MAX_SMB2_CREATE_RESPONSE_SIZE 880
695 696
696struct smb2_create_rsp { 697struct smb2_create_rsp {
697 struct smb2_sync_hdr sync_hdr; 698 struct smb2_sync_hdr sync_hdr;
@@ -818,7 +819,7 @@ struct durable_reconnect_context_v2 {
818struct on_disk_id { 819struct on_disk_id {
819 __le64 DiskFileId; 820 __le64 DiskFileId;
820 __le64 VolumeId; 821 __le64 VolumeId;
821 __u64 Reserved[4]; 822 __u32 Reserved[4];
822} __packed; 823} __packed;
823 824
824/* See MS-SMB2 2.2.14.2.12 */ 825/* See MS-SMB2 2.2.14.2.12 */
@@ -841,6 +842,12 @@ struct crt_twarp_ctxt {
841 842
842} __packed; 843} __packed;
843 844
845/* See MS-SMB2 2.2.13.2.9 */
846struct crt_query_id_ctxt {
847 struct create_context ccontext;
848 __u8 Name[8];
849} __packed;
850
844#define COPY_CHUNK_RES_KEY_SIZE 24 851#define COPY_CHUNK_RES_KEY_SIZE 24
845struct resume_key_req { 852struct resume_key_req {
846 char ResumeKey[COPY_CHUNK_RES_KEY_SIZE]; 853 char ResumeKey[COPY_CHUNK_RES_KEY_SIZE];