Commit 89a5bfa3 authored by Steve French's avatar Steve French

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.

This is better in multiple ways, and
speeds up file open about 10% (more if network is slow).
Reviewed-by: default avatarPavel Shilovsky <pshilov@microsoft.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent bf3c90ee
...@@ -88,15 +88,21 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, ...@@ -88,15 +88,21 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
} }
if (buf) { if (buf) {
/* open response does not have IndexNumber field - get it */ /* if open response does not have IndexNumber field - get it */
rc = SMB2_get_srv_num(xid, oparms->tcon, fid->persistent_fid, if (smb2_data->IndexNumber == 0) {
rc = SMB2_get_srv_num(xid, oparms->tcon,
fid->persistent_fid,
fid->volatile_fid, fid->volatile_fid,
&smb2_data->IndexNumber); &smb2_data->IndexNumber);
if (rc) { if (rc) {
/* let get_inode_info disable server inode numbers */ /*
* let get_inode_info disable server inode
* numbers
*/
smb2_data->IndexNumber = 0; smb2_data->IndexNumber = 0;
rc = 0; rc = 0;
} }
}
move_smb2_info_to_cifs(buf, smb2_data); move_smb2_info_to_cifs(buf, smb2_data);
} }
......
...@@ -754,11 +754,12 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid) ...@@ -754,11 +754,12 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid)
tcon->crfid.is_valid = true; tcon->crfid.is_valid = true;
kref_init(&tcon->crfid.refcount); 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) { if (o_rsp->OplockLevel == SMB2_OPLOCK_LEVEL_LEASE) {
kref_get(&tcon->crfid.refcount); kref_get(&tcon->crfid.refcount);
oplock = smb2_parse_lease_state(server, o_rsp, smb2_parse_contexts(server, o_rsp,
&oparms.fid->epoch, &oparms.fid->epoch,
oparms.fid->lease_key); oparms.fid->lease_key, &oplock, NULL);
} else } else
goto oshr_exit; goto oshr_exit;
......
...@@ -1873,10 +1873,21 @@ create_reconnect_durable_buf(struct cifs_fid *fid) ...@@ -1873,10 +1873,21 @@ create_reconnect_durable_buf(struct cifs_fid *fid)
return buf; return buf;
} }
__u8 static void
smb2_parse_lease_state(struct TCP_Server_Info *server, parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *buf)
{
struct create_on_disk_id *pdisk_id = (struct create_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;
}
void
smb2_parse_contexts(struct TCP_Server_Info *server,
struct smb2_create_rsp *rsp, struct smb2_create_rsp *rsp,
unsigned int *epoch, char *lease_key) unsigned int *epoch, char *lease_key, __u8 *oplock,
struct smb2_file_all_info *buf)
{ {
char *data_offset; char *data_offset;
struct create_context *cc; struct create_context *cc;
...@@ -1884,15 +1895,24 @@ smb2_parse_lease_state(struct TCP_Server_Info *server, ...@@ -1884,15 +1895,24 @@ smb2_parse_lease_state(struct TCP_Server_Info *server,
unsigned int remaining; unsigned int remaining;
char *name; char *name;
*oplock = 0;
data_offset = (char *)rsp + le32_to_cpu(rsp->CreateContextsOffset); data_offset = (char *)rsp + le32_to_cpu(rsp->CreateContextsOffset);
remaining = le32_to_cpu(rsp->CreateContextsLength); remaining = le32_to_cpu(rsp->CreateContextsLength);
cc = (struct create_context *)data_offset; 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)) { while (remaining >= sizeof(struct create_context)) {
name = le16_to_cpu(cc->NameOffset) + (char *)cc; name = le16_to_cpu(cc->NameOffset) + (char *)cc;
if (le16_to_cpu(cc->NameLength) == 4 && if (le16_to_cpu(cc->NameLength) == 4 &&
strncmp(name, "RqLs", 4) == 0) strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4) == 0)
return server->ops->parse_lease_buf(cc, epoch, *oplock = server->ops->parse_lease_buf(cc, epoch,
lease_key); 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); next = le32_to_cpu(cc->Next);
if (!next) if (!next)
...@@ -1901,7 +1921,10 @@ smb2_parse_lease_state(struct TCP_Server_Info *server, ...@@ -1901,7 +1921,10 @@ smb2_parse_lease_state(struct TCP_Server_Info *server,
cc = (struct create_context *)((char *)cc + next); cc = (struct create_context *)((char *)cc + next);
} }
return 0; if (rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE)
*oplock = rsp->OplockLevel;
return;
} }
static int static int
...@@ -2588,12 +2611,9 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, ...@@ -2588,12 +2611,9 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
buf->DeletePending = 0; buf->DeletePending = 0;
} }
if (rsp->OplockLevel == SMB2_OPLOCK_LEVEL_LEASE)
*oplock = smb2_parse_lease_state(server, rsp, smb2_parse_contexts(server, rsp, &oparms->fid->epoch,
&oparms->fid->epoch, oparms->fid->lease_key, oplock, buf);
oparms->fid->lease_key);
else
*oplock = rsp->OplockLevel;
creat_exit: creat_exit:
SMB2_open_free(&rqst); SMB2_open_free(&rqst);
free_rsp_buf(resp_buftype, rsp); free_rsp_buf(resp_buftype, rsp);
......
...@@ -818,7 +818,9 @@ struct durable_reconnect_context_v2 { ...@@ -818,7 +818,9 @@ struct durable_reconnect_context_v2 {
} __packed; } __packed;
/* See MS-SMB2 2.2.14.2.9 */ /* See MS-SMB2 2.2.14.2.9 */
struct on_disk_id { struct create_on_disk_id {
struct create_context ccontext;
__u8 Name[8];
__le64 DiskFileId; __le64 DiskFileId;
__le64 VolumeId; __le64 VolumeId;
__u32 Reserved[4]; __u32 Reserved[4];
......
...@@ -228,9 +228,10 @@ extern int smb3_validate_negotiate(const unsigned int, struct cifs_tcon *); ...@@ -228,9 +228,10 @@ extern int smb3_validate_negotiate(const unsigned int, struct cifs_tcon *);
extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *, extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *,
enum securityEnum); enum securityEnum);
extern __u8 smb2_parse_lease_state(struct TCP_Server_Info *server, extern void smb2_parse_contexts(struct TCP_Server_Info *server,
struct smb2_create_rsp *rsp, struct smb2_create_rsp *rsp,
unsigned int *epoch, char *lease_key); unsigned int *epoch, char *lease_key,
__u8 *oplock, struct smb2_file_all_info *buf);
extern int smb3_encryption_required(const struct cifs_tcon *tcon); extern int smb3_encryption_required(const struct cifs_tcon *tcon);
extern int smb2_validate_iov(unsigned int offset, unsigned int buffer_length, extern int smb2_validate_iov(unsigned int offset, unsigned int buffer_length,
struct kvec *iov, unsigned int min_buf_size); struct kvec *iov, unsigned int min_buf_size);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment