Commit ea3aa74e authored by Steve French's avatar Steve French Committed by Steve French

[CIFS] Increase size of small SMB pool (and decrease number) and

do not zero the beginning of the header twice.

Signed-off-by: Steve French (sfrench@us.ibm.com)
parent 55350724
......@@ -202,13 +202,11 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
bufAllocCount.counter);
length += item_length;
buf += item_length;
#ifdef CONFIG_CIFS_EXPERIMENTAL
item_length =
sprintf(buf,"SMB Small Req/Resp Buffer: %d\n",
smBufAllocCount.counter);
length += item_length;
buf += item_length;
#endif /* CIFS_EXPERIMENTAL */
item_length =
sprintf(buf,"Operations (MIDs): %d\n",
midCount.counter);
......
......@@ -207,10 +207,8 @@ static kmem_cache_t *cifs_inode_cachep;
static kmem_cache_t *cifs_req_cachep;
static kmem_cache_t *cifs_mid_cachep;
kmem_cache_t *cifs_oplock_cachep;
#ifdef CONFIG_CIFS_EXPERIMENTAL
static kmem_cache_t *cifs_sm_req_cachep;
mempool_t *cifs_sm_req_poolp;
#endif /* CIFS_EXPERIMENTAL */
mempool_t *cifs_req_poolp;
mempool_t *cifs_mid_poolp;
......@@ -634,23 +632,23 @@ cifs_init_request_bufs(void)
kmem_cache_destroy(cifs_req_cachep);
return -ENOMEM;
}
#ifdef CONFIG_CIFS_EXPERIMENTAL
/* 120 bytes is enough for most SMB responses and handle
based requests (but not write response, nor is it
sufficient for path based requests). 112 bytes is 75 more than
sizeof(struct smb_hdr) but still (with slab hdr) just smaller than
128 byte cutoff which should make it easy to alloc off the slab
compared to 17K (5page) alloc of large cifs buffers and not
so large as to force a single page alloc for each slab entry */
/* 256 (MAX_CIFS_HDR_SIZE bytes is enough for most SMB responses and
almost all handle based requests (but not write response, nor is it
sufficient for path based requests). A smaller size would have
been more efficient (compacting multiple slab items on one 4k page)
for the case in which debug was on, but this larger size allows
more SMBs to use small buffer alloc and is still much more
efficient to alloc 1 per page off the slab compared to 17K (5page)
alloc of large cifs buffers even when page debugging is on */
cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq",
112, 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
MAX_CIFS_HDR_SIZE, 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
if (cifs_sm_req_cachep == NULL) {
mempool_destroy(cifs_req_poolp);
kmem_cache_destroy(cifs_req_cachep);
return -ENOMEM;
}
cifs_sm_req_poolp = mempool_create(64,
cifs_sm_req_poolp = mempool_create(30,
mempool_alloc_slab,
mempool_free_slab,
cifs_sm_req_cachep);
......@@ -661,7 +659,6 @@ cifs_init_request_bufs(void)
kmem_cache_destroy(cifs_sm_req_cachep);
return -ENOMEM;
}
#endif /* CIFS_EXPERIMENTAL */
return 0;
}
......@@ -673,12 +670,10 @@ cifs_destroy_request_bufs(void)
if (kmem_cache_destroy(cifs_req_cachep))
printk(KERN_WARNING
"cifs_destroy_request_cache: error not all structures were freed\n");
#ifdef CONFIG_CIFS_EXPERIMENTAL
mempool_destroy(cifs_sm_req_poolp);
if (kmem_cache_destroy(cifs_sm_req_cachep))
printk(KERN_WARNING
"cifs_destroy_request_cache: cifs_small_rq free error\n");
#endif /* CIFS_EXPERIMENTAL */
}
static int
......
......@@ -413,9 +413,7 @@ GLOBAL_EXTERN atomic_t tconInfoReconnectCount;
/* Various Debug counters to remove someday (BB) */
GLOBAL_EXTERN atomic_t bufAllocCount;
#ifdef CONFIG_CIFS_EXPERIMENTAL
GLOBAL_EXTERN atomic_t smBufAllocCount;
#endif /* CIFS_EXPERIMENTAL */
GLOBAL_EXTERN atomic_t midCount;
/* Misc globals */
......
......@@ -32,10 +32,8 @@ struct statfs;
extern struct smb_hdr *cifs_buf_get(void);
extern void cifs_buf_release(void *);
#ifdef CONFIG_CIFS_EXPERIMENTAL
extern struct smb_hdr *cifs_small_buf_get(void);
extern void cifs_small_buf_release(void *);
#endif /* CIFS_EXPERIMENTAL */
extern int smb_send(struct socket *, struct smb_hdr *,
unsigned int /* length */ , struct sockaddr *);
extern unsigned int _GetXid(void);
......
......@@ -78,7 +78,6 @@ static void mark_open_files_invalid(struct cifsTconInfo * pTcon)
/* BB Add call to invalidate_inodes(sb) for all superblocks mounted to this tcon */
}
#ifdef CONFIG_CIFS_EXPERIMENTAL
static int
small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
void **request_buf /* returned */)
......@@ -169,7 +168,6 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
#endif /* CONFIG_CIFS_STATS */
return rc;
}
#endif /* CIFS_EXPERIMENTAL */
static int
smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
......@@ -414,7 +412,7 @@ int
CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
{
struct smb_hdr *smb_buffer;
struct smb_hdr *smb_buffer_response;
struct smb_hdr *smb_buffer_response; /* BB removeme BB */
int rc = 0;
int length;
......@@ -448,20 +446,20 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
up(&tcon->tconSem);
return -EIO;
}
rc = smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
(void **) &smb_buffer, (void **) &smb_buffer_response);
rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, (void **)&smb_buffer);
if (rc) {
up(&tcon->tconSem);
return rc;
}
} else {
smb_buffer_response = smb_buffer; /* BB removeme BB */
}
rc = SendReceive(xid, tcon->ses, smb_buffer, smb_buffer_response,
&length, 0);
if (rc)
cFYI(1, (" Tree disconnect failed %d", rc));
if (smb_buffer)
cifs_buf_release(smb_buffer);
cifs_small_buf_release(smb_buffer);
up(&tcon->tconSem);
/* No need to return error on this operation if tid invalidated and
......@@ -491,9 +489,8 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
up(&ses->sesSem);
return -EBUSY;
}
rc = smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL /* no tcon anymore */,
(void **) &pSMB, (void **) &smb_buffer_response);
rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */
if(ses->server) {
if(ses->server->secMode &
......@@ -521,7 +518,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
}
}
if (pSMB)
cifs_buf_release(pSMB);
cifs_small_buf_release(pSMB);
up(&ses->sesSem);
/* if session dead then we do not need to do ulogoff,
......@@ -915,6 +912,66 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
return rc;
}
#ifdef CONFIG_CIFS_EXPERIMENTAL
int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
const int netfid, const unsigned int count,
const __u64 offset, unsigned int *nbytes, const char __user *buf,
const int long_op)
{
int rc = -EACCES;
WRITE_REQ *pSMB = NULL;
WRITE_RSP *pSMBr = NULL;
/*int bytes_returned;*/
unsigned bytes_sent;
__u16 byte_count;
rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB);
pSMBr = (WRITE_RSP *)pSMB; /* BB removeme BB */
if (rc)
return rc;
/* tcon and ses pointer are checked in smb_init */
if (tcon->ses->server == NULL)
return -ECONNABORTED;
pSMB->AndXCommand = 0xFF; /* none */
pSMB->Fid = netfid;
pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
pSMB->Reserved = 0xFFFFFFFF;
pSMB->WriteMode = 0;
pSMB->Remaining = 0;
bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & ~0xFF;
if (bytes_sent > count)
bytes_sent = count;
pSMB->DataLengthHigh = 0;
pSMB->DataOffset =
cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
byte_count = bytes_sent + 1 /* pad */ ;
pSMB->DataLengthLow = cpu_to_le16(bytes_sent);
pSMB->DataLengthHigh = 0;
pSMB->hdr.smb_buf_length += byte_count;
pSMB->ByteCount = cpu_to_le16(byte_count);
/* rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, buf, buflen, &bytes_returned, long_op); */ /* BB fixme BB */
if (rc) {
cFYI(1, ("Send error in write2 (large write) = %d", rc));
*nbytes = 0;
} else
*nbytes = le16_to_cpu(pSMBr->Count);
if (pSMB)
cifs_small_buf_release(pSMB);
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
return rc;
}
#endif /* CIFS_EXPERIMENTAL */
int
CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
const __u16 smb_file_id, const __u64 len,
......@@ -989,13 +1046,8 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
cFYI(1, ("In CIFSSMBClose"));
/* do not retry on dead session on close */
#ifdef CONFIG_CIFS_EXPERIMENTAL
rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
#else
rc = smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB,
(void **) &pSMBr);
#endif /* CIFS_EXPERIMENTAL */
if(rc == -EAGAIN)
return 0;
if (rc)
......@@ -1013,13 +1065,8 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
}
}
#ifdef CONFIG_CIFS_EXPERIMENTAL
if (pSMB)
cifs_small_buf_release(pSMB);
#else
if (pSMB)
cifs_buf_release(pSMB);
#endif /* CIFS_EXPERIMENTAL */
/* Since session is dead, file will be closed on server already */
if(rc == -EAGAIN)
......@@ -2712,12 +2759,12 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
{
int rc = 0;
FINDCLOSE_REQ *pSMB = NULL;
CLOSE_RSP *pSMBr = NULL;
CLOSE_RSP *pSMBr = NULL; /* BB removeme BB */
int bytes_returned;
cFYI(1, ("In CIFSSMBFindClose"));
rc = smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **) &pSMB,
(void **) &pSMBr);
rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
/* no sense returning error if session restarted
file handle has been closed */
if(rc == -EAGAIN)
......@@ -2733,7 +2780,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
cERROR(1, ("Send error in FindClose = %d", rc));
}
if (pSMB)
cifs_buf_release(pSMB);
cifs_small_buf_release(pSMB);
/* Since session is dead, search handle closed on server already */
if (rc == -EAGAIN)
......
......@@ -29,9 +29,7 @@
#include "smberr.h"
#include "nterr.h"
#ifdef CONFIG_CIFS_EXPERIMENTAL
extern mempool_t *cifs_sm_req_poolp;
#endif /* CIFS_EXPERIMENTAL */
extern mempool_t *cifs_req_poolp;
extern struct task_struct * oplockThread;
......@@ -163,10 +161,9 @@ cifs_buf_get(void)
(struct smb_hdr *) mempool_alloc(cifs_req_poolp, SLAB_KERNEL | SLAB_NOFS);
/* clear the first few header bytes */
/* clear through bcc + 1, making an even 0x40 bytes */
/* for most paths, more is cleared in header_assemble */
if (ret_buf) {
memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);
memset(ret_buf, 0, sizeof(struct smb_hdr) + 3);
atomic_inc(&bufAllocCount);
}
......@@ -187,7 +184,6 @@ cifs_buf_release(void *buf_to_free)
return;
}
#ifdef CONFIG_CIFS_EXPERIMENTAL
struct smb_hdr *
cifs_small_buf_get(void)
{
......@@ -199,14 +195,11 @@ cifs_small_buf_get(void)
defaults to this and can not be bigger */
ret_buf =
(struct smb_hdr *) mempool_alloc(cifs_sm_req_poolp, SLAB_KERNEL | SLAB_NOFS);
/* clear the first few header bytes */
/* clear through bcc + 1, making an even 0x40 bytes */
if (ret_buf) {
memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);
/* No need to clear memory here, cleared in header assemble */
/* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/
atomic_inc(&smBufAllocCount);
}
return ret_buf;
}
......@@ -223,22 +216,17 @@ cifs_small_buf_release(void *buf_to_free)
atomic_dec(&smBufAllocCount);
return;
}
#endif /* CIFS_EXPERIMENTAL */
void
header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
const struct cifsTconInfo *treeCon, int word_count
/* length of fixed section (word count) in two byte units */
)
/* length of fixed section (word count) in two byte units */)
{
int i;
struct list_head* temp_item;
struct cifsSesInfo * ses;
char *temp = (char *) buffer;
for (i = 0; i < MAX_CIFS_HDR_SIZE; i++) {
temp[i] = 0; /* BB is this needed ?? */
}
memset(temp,0,MAX_CIFS_HDR_SIZE);
buffer->smb_buf_length =
(2 * word_count) + sizeof (struct smb_hdr) -
......
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