From: Steve French <smfrench@gmail.com>
To: CIFS <linux-cifs@vger.kernel.org>,
samba-technical <samba-technical@lists.samba.org>
Subject: [SMB3][PATCH] Speed up open by skipping query FILE_INTERNAL_INFORMATION
Date: Thu, 18 Jul 2019 02:43:17 -0500 [thread overview]
Message-ID: <CAH2r5mtn5SyUao9Y3f-_ubqgSV8t3RSj2fzAR9bE5ZQQ5dFcRQ@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 162 bytes --]
Now that we have the qfid context returned on open we can cut 1/3 of
the traffic on open by not sending the query FILE_INTERNAL_INFORMATION
--
Thanks,
Steve
[-- Attachment #2: 0001-smb3-optimize-open-to-not-send-query-file-internal-i.patch --]
[-- Type: text/x-patch, Size: 6184 bytes --]
From e3f8b1c5dbf19a0e6ef38d09b423f68b00078a9c Mon Sep 17 00:00:00 2001
From: Steve French <stfrench@microsoft.com>
Date: Thu, 18 Jul 2019 02:39:05 -0500
Subject: [PATCH] smb3: optimize open to not send query file internal info
We can cut one third of the traffic on open by not querying the
inode number explicitly via SMB3 query_info since it is now
returned on open in the qfid context.
Speeds up open significantly.
Signed-off-by: Steve French <stfrench@microsoft.com>
---
fs/cifs/smb2file.c | 18 ++++++++++++------
fs/cifs/smb2ops.c | 5 +++--
fs/cifs/smb2pdu.c | 42 +++++++++++++++++++++++++++++++-----------
fs/cifs/smb2pdu.h | 2 ++
fs/cifs/smb2proto.h | 5 +++--
5 files changed, 51 insertions(+), 21 deletions(-)
diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
index 54bffb2a1786..e6a1fc72018f 100644
--- a/fs/cifs/smb2file.c
+++ b/fs/cifs/smb2file.c
@@ -88,14 +88,20 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
}
if (buf) {
- /* open response does not have IndexNumber field - get it */
- rc = SMB2_get_srv_num(xid, oparms->tcon, fid->persistent_fid,
+ /* if open response does not have IndexNumber field - get it */
+ if (smb2_data->IndexNumber == 0) {
+ rc = SMB2_get_srv_num(xid, oparms->tcon,
+ fid->persistent_fid,
fid->volatile_fid,
&smb2_data->IndexNumber);
- if (rc) {
- /* let get_inode_info disable server inode numbers */
- smb2_data->IndexNumber = 0;
- rc = 0;
+ if (rc) {
+ /*
+ * let get_inode_info disable server inode
+ * numbers
+ */
+ smb2_data->IndexNumber = 0;
+ rc = 0;
+ }
}
move_smb2_info_to_cifs(buf, smb2_data);
}
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 0cdc4e47ca87..e73486e9b94d 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -711,11 +711,12 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid)
tcon->crfid.is_valid = true;
kref_init(&tcon->crfid.refcount);
+ /* BB TBD check to see if oplock level check can be removed below */
if (o_rsp->OplockLevel == SMB2_OPLOCK_LEVEL_LEASE) {
kref_get(&tcon->crfid.refcount);
- oplock = smb2_parse_lease_state(server, o_rsp,
+ oplock = smb2_parse_contexts(server, o_rsp,
&oparms.fid->epoch,
- oparms.fid->lease_key);
+ oparms.fid->lease_key, NULL);
} else
goto oshr_exit;
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index b352f453a6d2..a55708b75468 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -1873,26 +1873,46 @@ create_reconnect_durable_buf(struct cifs_fid *fid)
return buf;
}
+static void
+parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *buf)
+{
+ struct on_disk_id *pdisk_id = (struct on_disk_id *)cc;
+
+ cifs_dbg(FYI, "parse query id context 0x%llx 0x%llx\n",
+ pdisk_id->DiskFileId, pdisk_id->VolumeId);
+ buf->IndexNumber = pdisk_id->DiskFileId;
+}
+
__u8
-smb2_parse_lease_state(struct TCP_Server_Info *server,
+smb2_parse_contexts(struct TCP_Server_Info *server,
struct smb2_create_rsp *rsp,
- unsigned int *epoch, char *lease_key)
+ unsigned int *epoch, char *lease_key,
+ struct smb2_file_all_info *buf)
{
char *data_offset;
struct create_context *cc;
unsigned int next;
unsigned int remaining;
char *name;
+ __u8 oplock = 0;
data_offset = (char *)rsp + le32_to_cpu(rsp->CreateContextsOffset);
remaining = le32_to_cpu(rsp->CreateContextsLength);
cc = (struct create_context *)data_offset;
+
+ /* Initialize inode number to 0 in case no valid data in qfid context */
+ if (buf)
+ buf->IndexNumber = 0;
+
while (remaining >= sizeof(struct create_context)) {
name = le16_to_cpu(cc->NameOffset) + (char *)cc;
if (le16_to_cpu(cc->NameLength) == 4 &&
- strncmp(name, "RqLs", 4) == 0)
- return server->ops->parse_lease_buf(cc, epoch,
- lease_key);
+ strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4) == 0)
+ oplock = server->ops->parse_lease_buf(cc, epoch,
+ lease_key);
+ else if (buf && (le16_to_cpu(cc->NameLength) == 4) &&
+ strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4) == 0)
+ parse_query_id_ctxt(cc, buf);
next = le32_to_cpu(cc->Next);
if (!next)
@@ -1901,7 +1921,7 @@ smb2_parse_lease_state(struct TCP_Server_Info *server,
cc = (struct create_context *)((char *)cc + next);
}
- return 0;
+ return oplock;
}
static int
@@ -2588,11 +2608,11 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
buf->DeletePending = 0;
}
- if (rsp->OplockLevel == SMB2_OPLOCK_LEVEL_LEASE)
- *oplock = smb2_parse_lease_state(server, rsp,
- &oparms->fid->epoch,
- oparms->fid->lease_key);
- else
+
+ *oplock = smb2_parse_contexts(server, rsp, &oparms->fid->epoch,
+ oparms->fid->lease_key,
+ buf);
+ if (*oplock == 0) /* no lease open context found */
*oplock = rsp->OplockLevel;
creat_exit:
SMB2_open_free(&rqst);
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index 7e2e782f8edd..7c916adc2fbc 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -819,6 +819,8 @@ struct durable_reconnect_context_v2 {
/* See MS-SMB2 2.2.14.2.9 */
struct on_disk_id {
+ struct create_context ccontext;
+ __u8 Name[8];
__le64 DiskFileId;
__le64 VolumeId;
__u32 Reserved[4];
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
index e4ca98cf3af3..b6b1a1bed466 100644
--- a/fs/cifs/smb2proto.h
+++ b/fs/cifs/smb2proto.h
@@ -232,9 +232,10 @@ extern int smb3_validate_negotiate(const unsigned int, struct cifs_tcon *);
extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *,
enum securityEnum);
-extern __u8 smb2_parse_lease_state(struct TCP_Server_Info *server,
+extern __u8 smb2_parse_contexts(struct TCP_Server_Info *server,
struct smb2_create_rsp *rsp,
- unsigned int *epoch, char *lease_key);
+ unsigned int *epoch, char *lease_key,
+ struct smb2_file_all_info *buf);
extern int smb3_encryption_required(const struct cifs_tcon *tcon);
extern int smb2_validate_iov(unsigned int offset, unsigned int buffer_length,
struct kvec *iov, unsigned int min_buf_size);
--
2.20.1
next reply other threads:[~2019-07-18 7:43 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-18 7:43 Steve French [this message]
2019-07-18 17:37 ` [SMB3][PATCH] Speed up open by skipping query FILE_INTERNAL_INFORMATION Pavel Shilovsky
2019-07-18 18:46 ` Steve French
2019-07-18 19:16 ` Pavel Shilovsky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAH2r5mtn5SyUao9Y3f-_ubqgSV8t3RSj2fzAR9bE5ZQQ5dFcRQ@mail.gmail.com \
--to=smfrench@gmail.com \
--cc=linux-cifs@vger.kernel.org \
--cc=samba-technical@lists.samba.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).