[CIFS] Readpages and readir performance improvements - eliminate extra
memcpy. Part 1 Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
parent
bf82067917
commit
84afc29b18
|
@ -1,6 +1,7 @@
|
||||||
Version 1.40
|
Version 1.40
|
||||||
------------
|
------------
|
||||||
Use fsuid (fsgid) more consistently instead of uid (gid).
|
Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance
|
||||||
|
of readpages by eliminating one extra memcpy.
|
||||||
|
|
||||||
Version 1.39
|
Version 1.39
|
||||||
------------
|
------------
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* fs/cifs/cifsencrypt.c
|
* fs/cifs/cifsencrypt.c
|
||||||
*
|
*
|
||||||
* Copyright (C) International Business Machines Corp., 2003
|
* Copyright (C) International Business Machines Corp., 2005
|
||||||
* Author(s): Steve French (sfrench@us.ibm.com)
|
* Author(s): Steve French (sfrench@us.ibm.com)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
@ -82,6 +82,59 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cifs_calc_signature2(const struct kvec * iov, int n_vec,
|
||||||
|
const char * key, char * signature)
|
||||||
|
{
|
||||||
|
struct MD5Context context;
|
||||||
|
|
||||||
|
if((iov == NULL) || (signature == NULL))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
MD5Init(&context);
|
||||||
|
MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16);
|
||||||
|
|
||||||
|
/* MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); */ /* BB FIXME BB */
|
||||||
|
|
||||||
|
MD5Final(signature,&context);
|
||||||
|
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
/* return 0; */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int cifs_sign_smb2(struct kvec * iov, int n_vec, struct TCP_Server_Info *server,
|
||||||
|
__u32 * pexpected_response_sequence_number)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
char smb_signature[20];
|
||||||
|
struct smb_hdr * cifs_pdu = iov[0].iov_base;
|
||||||
|
|
||||||
|
if((cifs_pdu == NULL) || (server == NULL))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
spin_lock(&GlobalMid_Lock);
|
||||||
|
cifs_pdu->Signature.Sequence.SequenceNumber =
|
||||||
|
cpu_to_le32(server->sequence_number);
|
||||||
|
cifs_pdu->Signature.Sequence.Reserved = 0;
|
||||||
|
|
||||||
|
*pexpected_response_sequence_number = server->sequence_number++;
|
||||||
|
server->sequence_number++;
|
||||||
|
spin_unlock(&GlobalMid_Lock);
|
||||||
|
|
||||||
|
rc = cifs_calc_signature2(iov, n_vec, server->mac_signing_key,
|
||||||
|
smb_signature);
|
||||||
|
if(rc)
|
||||||
|
memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
|
||||||
|
else
|
||||||
|
memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key,
|
int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key,
|
||||||
__u32 expected_sequence_number)
|
__u32 expected_sequence_number)
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,7 +48,7 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
|
||||||
struct smb_hdr * /* out */ ,
|
struct smb_hdr * /* out */ ,
|
||||||
int * /* bytes returned */ , const int long_op);
|
int * /* bytes returned */ , const int long_op);
|
||||||
extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
|
extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
|
||||||
struct kvec *, int /* nvec */,
|
struct kvec *, int /* nvec to send */,
|
||||||
int * /* bytes returned */ , const int long_op);
|
int * /* bytes returned */ , const int long_op);
|
||||||
extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid);
|
extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid);
|
||||||
extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
|
extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
|
||||||
|
@ -237,12 +237,10 @@ extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
|
||||||
const __u64 lseek, unsigned int *nbytes,
|
const __u64 lseek, unsigned int *nbytes,
|
||||||
const char *buf, const char __user *ubuf,
|
const char *buf, const char __user *ubuf,
|
||||||
const int long_op);
|
const int long_op);
|
||||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
|
||||||
extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
|
extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
|
||||||
const int netfid, const unsigned int count,
|
const int netfid, const unsigned int count,
|
||||||
const __u64 offset, unsigned int *nbytes,
|
const __u64 offset, unsigned int *nbytes,
|
||||||
struct kvec *iov, const int nvec, const int long_op);
|
struct kvec *iov, const int nvec, const int long_op);
|
||||||
#endif /* CONFIG_CIFS_EXPERIMENTAL */
|
|
||||||
extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
|
extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
|
||||||
const unsigned char *searchName, __u64 * inode_number,
|
const unsigned char *searchName, __u64 * inode_number,
|
||||||
const struct nls_table *nls_codepage,
|
const struct nls_table *nls_codepage,
|
||||||
|
@ -269,6 +267,8 @@ extern void tconInfoFree(struct cifsTconInfo *);
|
||||||
extern int cifs_reconnect(struct TCP_Server_Info *server);
|
extern int cifs_reconnect(struct TCP_Server_Info *server);
|
||||||
|
|
||||||
extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *);
|
extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *);
|
||||||
|
extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
|
||||||
|
__u32 *);
|
||||||
extern int cifs_verify_signature(struct smb_hdr *, const char * mac_key,
|
extern int cifs_verify_signature(struct smb_hdr *, const char * mac_key,
|
||||||
__u32 expected_sequence_number);
|
__u32 expected_sequence_number);
|
||||||
extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass);
|
extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass);
|
||||||
|
|
|
@ -1155,7 +1155,6 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
|
||||||
int
|
int
|
||||||
CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
|
CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
|
||||||
const int netfid, const unsigned int count,
|
const int netfid, const unsigned int count,
|
||||||
|
@ -1234,8 +1233,6 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* CIFS_EXPERIMENTAL */
|
|
||||||
|
|
||||||
int
|
int
|
||||||
CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
|
CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
|
||||||
const __u16 smb_file_id, const __u64 len,
|
const __u16 smb_file_id, const __u64 len,
|
||||||
|
|
|
@ -870,7 +870,6 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
|
||||||
/* BB FIXME We can not sign across two buffers yet */
|
/* BB FIXME We can not sign across two buffers yet */
|
||||||
if((experimEnabled) && ((pTcon->ses->server->secMode &
|
if((experimEnabled) && ((pTcon->ses->server->secMode &
|
||||||
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0)) {
|
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0)) {
|
||||||
|
@ -889,7 +888,6 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
|
||||||
iov, 1, long_op);
|
iov, 1, long_op);
|
||||||
} else
|
} else
|
||||||
/* BB FIXME fixup indentation of line below */
|
/* BB FIXME fixup indentation of line below */
|
||||||
#endif
|
|
||||||
rc = CIFSSMBWrite(xid, pTcon,
|
rc = CIFSSMBWrite(xid, pTcon,
|
||||||
open_file->netfid,
|
open_file->netfid,
|
||||||
min_t(const int, cifs_sb->wsize,
|
min_t(const int, cifs_sb->wsize,
|
||||||
|
@ -1026,7 +1024,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
|
||||||
static int cifs_writepages(struct address_space *mapping,
|
static int cifs_writepages(struct address_space *mapping,
|
||||||
struct writeback_control *wbc)
|
struct writeback_control *wbc)
|
||||||
{
|
{
|
||||||
|
@ -1229,7 +1226,6 @@ retry:
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static int cifs_writepage(struct page* page, struct writeback_control *wbc)
|
static int cifs_writepage(struct page* page, struct writeback_control *wbc)
|
||||||
{
|
{
|
||||||
|
@ -1875,9 +1871,7 @@ struct address_space_operations cifs_addr_ops = {
|
||||||
.readpage = cifs_readpage,
|
.readpage = cifs_readpage,
|
||||||
.readpages = cifs_readpages,
|
.readpages = cifs_readpages,
|
||||||
.writepage = cifs_writepage,
|
.writepage = cifs_writepage,
|
||||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
|
||||||
.writepages = cifs_writepages,
|
.writepages = cifs_writepages,
|
||||||
#endif
|
|
||||||
.prepare_write = cifs_prepare_write,
|
.prepare_write = cifs_prepare_write,
|
||||||
.commit_write = cifs_commit_write,
|
.commit_write = cifs_commit_write,
|
||||||
.set_page_dirty = __set_page_dirty_nobuffers,
|
.set_page_dirty = __set_page_dirty_nobuffers,
|
||||||
|
|
|
@ -206,7 +206,6 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
|
||||||
static int
|
static int
|
||||||
smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
|
smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
|
||||||
struct sockaddr *sin)
|
struct sockaddr *sin)
|
||||||
|
@ -392,8 +391,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BB FIXME */
|
rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
|
||||||
/* rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); */
|
|
||||||
|
|
||||||
midQ->midState = MID_REQUEST_SUBMITTED;
|
midQ->midState = MID_REQUEST_SUBMITTED;
|
||||||
#ifdef CONFIG_CIFS_STATS2
|
#ifdef CONFIG_CIFS_STATS2
|
||||||
|
@ -492,11 +490,17 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
|
||||||
|
|
||||||
if (midQ->resp_buf &&
|
if (midQ->resp_buf &&
|
||||||
(midQ->midState == MID_RESPONSE_RECEIVED)) {
|
(midQ->midState == MID_RESPONSE_RECEIVED)) {
|
||||||
|
|
||||||
in_buf->smb_buf_length = receive_len;
|
in_buf->smb_buf_length = receive_len;
|
||||||
/* BB verify that length would not overrun small buf */
|
if(receive_len > 500) {
|
||||||
|
/* use multiple buffers on way out */
|
||||||
|
} else {
|
||||||
memcpy((char *)in_buf + 4,
|
memcpy((char *)in_buf + 4,
|
||||||
(char *)midQ->resp_buf + 4,
|
(char *)midQ->resp_buf + 4,
|
||||||
receive_len);
|
receive_len);
|
||||||
|
iov[0].iov_len = receive_len + 4;
|
||||||
|
iov[1].iov_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
dump_smb(in_buf, 80);
|
dump_smb(in_buf, 80);
|
||||||
/* convert the length into a more usable form */
|
/* convert the length into a more usable form */
|
||||||
|
@ -549,7 +553,6 @@ out_unlock2:
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#endif /* CIFS_EXPERIMENTAL */
|
|
||||||
|
|
||||||
int
|
int
|
||||||
SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
|
SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
|
||||||
|
|
Loading…
Reference in New Issue