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