Skip to content

Commit ff2a09e

Browse files
committed
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 <[email protected]>
1 parent 96d3cca commit ff2a09e

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

fs/cifs/smb2pdu.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2118,6 +2118,48 @@ add_twarp_context(struct kvec *iov, unsigned int *num_iovec, __u64 timewarp)
21182118
return 0;
21192119
}
21202120

2121+
static struct crt_query_id_ctxt *
2122+
create_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 */
2144+
static int
2145+
add_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+
21212163
static int
21222164
alloc_path_with_tree_prefix(__le16 **out_path, int *out_size, int *out_len,
21232165
const char *treename, const __le16 *path)
@@ -2446,6 +2488,12 @@ SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock,
24462488
return rc;
24472489
}
24482490

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);
24492497

24502498
rqst->rq_nvec = n_iov;
24512499
return 0;

fs/cifs/smb2pdu.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -662,9 +662,10 @@ struct smb2_tree_disconnect_rsp {
662662
* [3] : durable context
663663
* [4] : posix context
664664
* [5] : time warp context
665-
* [6] : compound padding
665+
* [6] : query id context
666+
* [7] : compound padding
666667
*/
667-
#define SMB2_CREATE_IOV_SIZE 7
668+
#define SMB2_CREATE_IOV_SIZE 8
668669

669670
struct smb2_create_req {
670671
struct smb2_sync_hdr sync_hdr;
@@ -688,10 +689,10 @@ struct smb2_create_req {
688689

689690
/*
690691
* 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) +
692693
* 2 bytes of padding.
693694
*/
694-
#define MAX_SMB2_CREATE_RESPONSE_SIZE 824
695+
#define MAX_SMB2_CREATE_RESPONSE_SIZE 880
695696

696697
struct smb2_create_rsp {
697698
struct smb2_sync_hdr sync_hdr;
@@ -818,7 +819,7 @@ struct durable_reconnect_context_v2 {
818819
struct on_disk_id {
819820
__le64 DiskFileId;
820821
__le64 VolumeId;
821-
__u64 Reserved[4];
822+
__u32 Reserved[4];
822823
} __packed;
823824

824825
/* See MS-SMB2 2.2.14.2.12 */
@@ -841,6 +842,12 @@ struct crt_twarp_ctxt {
841842

842843
} __packed;
843844

845+
/* See MS-SMB2 2.2.13.2.9 */
846+
struct crt_query_id_ctxt {
847+
struct create_context ccontext;
848+
__u8 Name[8];
849+
} __packed;
850+
844851
#define COPY_CHUNK_RES_KEY_SIZE 24
845852
struct resume_key_req {
846853
char ResumeKey[COPY_CHUNK_RES_KEY_SIZE];

0 commit comments

Comments
 (0)