[SMB3] Speed up open by skipping query FILE_INTERNAL_INFORMATION
diff mbox series

Message ID CAH2r5mtn5SyUao9Y3f-_ubqgSV8t3RSj2fzAR9bE5ZQQ5dFcRQ@mail.gmail.com
State New
Headers show
Series
  • [SMB3] Speed up open by skipping query FILE_INTERNAL_INFORMATION
Related show

Commit Message

Steve French July 18, 2019, 7:43 a.m. UTC
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

Comments

Pavel Shilovsky July 18, 2019, 5:37 p.m. UTC | #1
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) {

What's about a server returning 0 for the IndexNumber?

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

oplock being 0 here probably means that the lease state which is
granted is NONE. You still need to keep if (rsp->OplockLevel ==
SMB2_OPLOCK_LEVEL_LEASE) gate.

 /* See MS-SMB2 2.2.14.2.9 */
 struct on_disk_id {

Please prefix the structure name with "create_".

Best regards,
Pavel Shilovskiy

чт, 18 июл. 2019 г. в 00:43, Steve French via samba-technical
<samba-technical@lists.samba.org>:
>
> 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
Steve French July 18, 2019, 6:46 p.m. UTC | #2
Also fyi - did some experiments today.  Perf across the open vfs entry
point averaged about 20% better with the patch

On Thu, Jul 18, 2019 at 12:37 PM Pavel Shilovsky
<pavel.shilovsky@gmail.com> wrote:
>
> 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) {
>
> What's about a server returning 0 for the IndexNumber?
>
> - 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;
>
> oplock being 0 here probably means that the lease state which is
> granted is NONE. You still need to keep if (rsp->OplockLevel ==
> SMB2_OPLOCK_LEVEL_LEASE) gate.
>
>  /* See MS-SMB2 2.2.14.2.9 */
>  struct on_disk_id {
>
> Please prefix the structure name with "create_".
>
> Best regards,
> Pavel Shilovskiy
>
> чт, 18 июл. 2019 г. в 00:43, Steve French via samba-technical
> <samba-technical@lists.samba.org>:
> >
> > 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
Pavel Shilovsky July 18, 2019, 7:16 p.m. UTC | #3
This is good improvement at almost no cost! We should definitely get
this functionality in!

Best regards,
Pavel Shilovskiy

чт, 18 июл. 2019 г. в 11:46, Steve French <smfrench@gmail.com>:
>
> Also fyi - did some experiments today.  Perf across the open vfs entry
> point averaged about 20% better with the patch
>
> On Thu, Jul 18, 2019 at 12:37 PM Pavel Shilovsky
> <pavel.shilovsky@gmail.com> wrote:
> >
> > 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) {
> >
> > What's about a server returning 0 for the IndexNumber?
> >
> > - 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;
> >
> > oplock being 0 here probably means that the lease state which is
> > granted is NONE. You still need to keep if (rsp->OplockLevel ==
> > SMB2_OPLOCK_LEVEL_LEASE) gate.
> >
> >  /* See MS-SMB2 2.2.14.2.9 */
> >  struct on_disk_id {
> >
> > Please prefix the structure name with "create_".
> >
> > Best regards,
> > Pavel Shilovskiy
> >
> > чт, 18 июл. 2019 г. в 00:43, Steve French via samba-technical
> > <samba-technical@lists.samba.org>:
> > >
> > > 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
>
>
>
> --
> Thanks,
>
> Steve

Patch
diff mbox series

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