Commit 988aa94c authored by Steve French's avatar Steve French Committed by Steve French

Add support for module init parms for number of small and large cifs network

buffers and for maximum number of simultaneous requests.  Fix directio of 
userbuffers to use copy_to_user.

Signed-off-by: Steve French (sfrench@us.ibm.com)
parent 51e4faad
......@@ -4,7 +4,9 @@ Turn off DNOTIFY (directory change notification support) by default
(unless built with the experimental flag) to fix hang with KDE
file browser. Fix DNOTIFY flag mappings. Fix hang (in wait_event
waiting on an SMB response) in SendReceive when session dies but
reconnects quickly from another task.
reconnects quickly from another task. Add module init parms for
minimum number of large and small network buffers in the buffer pools,
and for the maximum number of simultaneous requests.
Version 1.26
------------
......
......@@ -57,8 +57,20 @@ unsigned int multiuser_mount = 0;
unsigned int extended_security = 0;
unsigned int ntlmv2_support = 0;
unsigned int sign_CIFS_PDUs = 1;
unsigned int CIFSMaximumBufferSize = CIFS_MAX_MSGSIZE;
struct task_struct * oplockThread = NULL;
unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
module_param(CIFSMaxBufSize, int, CIFS_MAX_MSGSIZE);
MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 4096 to 130048");
unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL;
module_param(cifs_min_rcv, int, CIFS_MIN_RCV_POOL);
MODULE_PARM_DESC(cifs_min_rcv,"Network buffers in pool. Default: 4 Range: 1 to 64");
unsigned int cifs_min_small = 30;
module_param(cifs_min_small, int, 30);
MODULE_PARM_DESC(cifs_small_rcv,"Small network buffers in pool. Default: 30 Range: 2 to 256");
unsigned int cifs_max_pending = CIFS_MAX_REQ;
module_param(cifs_max_pending, int, CIFS_MAX_REQ);
MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256");
extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
const char *);
......@@ -434,14 +446,14 @@ cifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size,
cFYI(1,("In read_wrapper size %zd at %lld",read_size,*poffset));
#ifdef CONFIG_CIFS_EXPERIMENTAL /* BB fixme - fix user char * to kernel char * mapping here BB */
#ifdef CONFIG_CIFS_EXPERIMENTAL
/* check whether we can cache writes locally */
if(file->f_dentry->d_sb) {
struct cifs_sb_info *cifs_sb;
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
if(cifs_sb != NULL) {
if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
return cifs_read(file,read_data,
return cifs_user_read(file,read_data,
read_size,poffset);
}
}
......@@ -620,6 +632,13 @@ cifs_destroy_inodecache(void)
static int
cifs_init_request_bufs(void)
{
if(CIFSMaxBufSize < 4096) {
CIFSMaxBufSize = 4096;
cFYI(1,("Buffer size set to minimum of 1 page (4096)"));
} else if (CIFSMaxBufSize > 1024*127) {
CIFSMaxBufSize = 1024 * 127;
cFYI(1,("Buffer size set to maximum"));
}
cifs_req_cachep = kmem_cache_create("cifs_request",
CIFS_MAX_MSGSIZE +
MAX_CIFS_HDR_SIZE, 0,
......@@ -627,7 +646,14 @@ cifs_init_request_bufs(void)
if (cifs_req_cachep == NULL)
return -ENOMEM;
cifs_req_poolp = mempool_create(CIFS_MIN_RCV_POOL,
if(cifs_min_rcv < 1)
cifs_min_rcv = 1;
else if (cifs_min_rcv > 64) {
cifs_min_rcv = 64;
cFYI(1,("cifs_min_rcv set to maximum (64)"));
}
cifs_req_poolp = mempool_create(cifs_min_rcv,
mempool_alloc_slab,
mempool_free_slab,
cifs_req_cachep);
......@@ -652,7 +678,14 @@ cifs_init_request_bufs(void)
return -ENOMEM;
}
cifs_sm_req_poolp = mempool_create(30,
if(cifs_min_small < 2)
cifs_min_small = 2;
else if (cifs_min_small > 256) {
cifs_min_small = 256;
cFYI(1,("cifs_min_small set to maximum (256)"));
}
cifs_sm_req_poolp = mempool_create(cifs_min_small,
mempool_alloc_slab,
mempool_free_slab,
cifs_sm_req_cachep);
......@@ -820,6 +853,14 @@ init_cifs(void)
GlobalSMBSeslock = RW_LOCK_UNLOCKED;
GlobalMid_Lock = SPIN_LOCK_UNLOCKED;
if(cifs_max_pending < 2) {
cifs_max_pending = 2;
cFYI(1,("cifs_max_pending set to min of 2"));
} else if(cifs_max_pending > 256) {
cifs_max_pending = 256;
cFYI(1,("cifs_max_pending set to max of 256"));
}
rc = cifs_init_inodecache();
if (!rc) {
rc = cifs_init_mids();
......
......@@ -63,7 +63,7 @@ extern struct file_operations cifs_file_ops;
extern int cifs_open(struct inode *inode, struct file *file);
extern int cifs_close(struct inode *inode, struct file *file);
extern int cifs_closedir(struct inode *inode, struct file *file);
extern ssize_t cifs_read(struct file *file, char *read_data,
extern ssize_t cifs_user_read(struct file *file, char __user *read_data,
size_t read_size, loff_t * poffset);
extern ssize_t cifs_write(struct file *file, const char *write_data,
size_t write_size, loff_t * poffset);
......
......@@ -428,5 +428,9 @@ GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent
with more secure ntlmssp2 challenge/resp */
GLOBAL_EXTERN unsigned int ntlmv2_support; /* better optional password hash */
GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */
GLOBAL_EXTERN unsigned int linuxExtEnabled; /* enable Linux/Unix CIFS extensions */
GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/
GLOBAL_EXTERN unsigned int CIFSMaxBufSize; /* max size not including hdr */
GLOBAL_EXTERN unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */
GLOBAL_EXTERN unsigned int cifs_min_small; /* min size of small buf pool */
GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/
......@@ -217,7 +217,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
write_unlock(&GlobalSMBSeslock);
if(length > 1) {
mempool_resize(cifs_req_poolp,
length + CIFS_MIN_RCV_POOL,
length + cifs_min_rcv,
GFP_KERNEL);
}
......@@ -489,7 +489,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
write_unlock(&GlobalSMBSeslock);
if(length > 0) {
mempool_resize(cifs_req_poolp,
length + CIFS_MIN_RCV_POOL,
length + cifs_min_rcv,
GFP_KERNEL);
}
......
......@@ -996,6 +996,82 @@ int cifs_flush(struct file *file)
}
ssize_t
cifs_user_read(struct file * file, char __user *read_data, size_t read_size,
loff_t * poffset)
{
int rc = -EACCES;
unsigned int bytes_read = 0;
unsigned int total_read = 0;
unsigned int current_read_size;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
int xid;
struct cifsFileInfo * open_file;
char * smb_read_data;
char * current_offset;
struct smb_com_read_rsp * pSMBr;
xid = GetXid();
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
pTcon = cifs_sb->tcon;
if (file->private_data == NULL) {
FreeXid(xid);
return -EBADF;
}
open_file = (struct cifsFileInfo *)file->private_data;
if((file->f_flags & O_ACCMODE) == O_WRONLY) {
cFYI(1,("attempting read on write only file instance"));
}
for (total_read = 0,current_offset=read_data; read_size > total_read;
total_read += bytes_read,current_offset+=bytes_read) {
current_read_size = min_t(const int,read_size - total_read,cifs_sb->rsize);
rc = -EAGAIN;
smb_read_data = NULL;
while(rc == -EAGAIN) {
if ((open_file->invalidHandle) && (!open_file->closePend)) {
rc = cifs_reopen_file(file->f_dentry->d_inode,
file,TRUE);
if(rc != 0)
break;
}
rc = CIFSSMBRead(xid, pTcon,
open_file->netfid,
current_read_size, *poffset,
&bytes_read, &smb_read_data);
pSMBr = (struct smb_com_read_rsp *)smb_read_data;
copy_to_user(current_offset,smb_read_data + 4 /* RFC1001 hdr */ + le16_to_cpu(pSMBr->DataOffset), bytes_read);
if(smb_read_data) {
cifs_buf_release(smb_read_data);
smb_read_data = NULL;
}
}
if (rc || (bytes_read == 0)) {
if (total_read) {
break;
} else {
FreeXid(xid);
return rc;
}
} else {
#ifdef CONFIG_CIFS_STATS
atomic_inc(&pTcon->num_reads);
spin_lock(&pTcon->stat_lock);
pTcon->bytes_read += total_read;
spin_unlock(&pTcon->stat_lock);
#endif
*poffset += bytes_read;
}
}
FreeXid(xid);
return total_read;
}
ssize_t
cifs_read(struct file * file, char *read_data, size_t read_size,
loff_t * poffset)
......
......@@ -211,11 +211,11 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses,
} else {
spin_lock(&GlobalMid_Lock);
while(1) {
if(atomic_read(&ses->server->inFlight) >= CIFS_MAX_REQ){
if(atomic_read(&ses->server->inFlight) >= cifs_max_pending){
spin_unlock(&GlobalMid_Lock);
wait_event(ses->server->request_q,
atomic_read(&ses->server->inFlight)
< CIFS_MAX_REQ);
< cifs_max_pending);
spin_lock(&GlobalMid_Lock);
} else {
if(ses->server->tcpStatus == CifsExiting) {
......@@ -341,11 +341,11 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
} else {
spin_lock(&GlobalMid_Lock);
while(1) {
if(atomic_read(&ses->server->inFlight) >= CIFS_MAX_REQ){
if(atomic_read(&ses->server->inFlight) >= cifs_max_pending){
spin_unlock(&GlobalMid_Lock);
wait_event(ses->server->request_q,
atomic_read(&ses->server->inFlight)
< CIFS_MAX_REQ);
< cifs_max_pending);
spin_lock(&GlobalMid_Lock);
} else {
if(ses->server->tcpStatus == CifsExiting) {
......
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