Commit 4f983096 authored by Steve French's avatar Steve French Committed by Steve French

Avoid smb data corruption under heavy stress

parent cfc71961
Version 0.98 Version 0.98
------------ ------------
Fix hang in commit_write during reconnection of open files under heavy load. Fix hang in commit_write during reconnection of open files under heavy load.
Fix unload_nls oops in a mount failure path. Fix unload_nls oops in a mount failure path. Serialize writes to same socket
which also fixes any possible races when cifs signatures are enabled in SMBs
being sent out of signature sequence number order.
Version 0.97 Version 0.97
------------ ------------
......
...@@ -990,6 +990,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -990,6 +990,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
init_waitqueue_head(&srvTcp->response_q); init_waitqueue_head(&srvTcp->response_q);
INIT_LIST_HEAD(&srvTcp->pending_mid_q); INIT_LIST_HEAD(&srvTcp->pending_mid_q);
srvTcp->tcpStatus = CifsGood; srvTcp->tcpStatus = CifsGood;
init_MUTEX(&srvTcp->tcpSem);
kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp, kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp,
CLONE_FS | CLONE_FILES | CLONE_VM); CLONE_FS | CLONE_FILES | CLONE_VM);
} }
......
...@@ -220,6 +220,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -220,6 +220,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
pCifsFile->pInode = newinode; pCifsFile->pInode = newinode;
pCifsFile->invalidHandle = FALSE; pCifsFile->invalidHandle = FALSE;
pCifsFile->closePend = FALSE; pCifsFile->closePend = FALSE;
init_MUTEX(&pCifsFile->fh_sem);
/* pCifsFile->pfile = file; */ /* put in at open time */ /* pCifsFile->pfile = file; */ /* put in at open time */
write_lock(&GlobalSMBSeslock); write_lock(&GlobalSMBSeslock);
list_add(&pCifsFile->tlist,&pTcon->openFileList); list_add(&pCifsFile->tlist,&pTcon->openFileList);
......
...@@ -142,6 +142,7 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -142,6 +142,7 @@ cifs_open(struct inode *inode, struct file *file)
pCifsFile = (struct cifsFileInfo *) file->private_data; pCifsFile = (struct cifsFileInfo *) file->private_data;
pCifsFile->netfid = netfid; pCifsFile->netfid = netfid;
pCifsFile->pid = current->pid; pCifsFile->pid = current->pid;
init_MUTEX(&pCifsFile->fh_sem);
pCifsFile->pfile = file; /* needed for writepage */ pCifsFile->pfile = file; /* needed for writepage */
pCifsFile->pInode = inode; pCifsFile->pInode = inode;
pCifsFile->invalidHandle = FALSE; pCifsFile->invalidHandle = FALSE;
...@@ -1390,6 +1391,7 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir) ...@@ -1390,6 +1391,7 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
(struct cifsFileInfo *) file->private_data; (struct cifsFileInfo *) file->private_data;
cifsFile->netfid = searchHandle; cifsFile->netfid = searchHandle;
cifsFile->invalidHandle = FALSE; cifsFile->invalidHandle = FALSE;
init_MUTEX(&cifsFile->fh_sem);
} else { } else {
rc = -ENOMEM; rc = -ENOMEM;
break; break;
......
...@@ -192,13 +192,18 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -192,13 +192,18 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
return -EAGAIN; return -EAGAIN;
} /* else ok - we are setting up session */ } /* else ok - we are setting up session */
} }
/* make sure that we sign in the same order that we send on this socket
and avoid races inside tcp sendmsg code that could cause corruption
of smb data */
down(&ses->server->tcpSem);
midQ = AllocMidQEntry(in_buf, ses); midQ = AllocMidQEntry(in_buf, ses);
if (midQ == NULL) { if (midQ == NULL) {
up(&ses->server->tcpSem);
return -EIO; return -EIO;
} }
if (in_buf->smb_buf_length > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE - 4) { if (in_buf->smb_buf_length > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE - 4) {
up(&ses->server->tcpSem);
cERROR(1, cERROR(1,
("Illegal length, greater than maximum frame, %d ", ("Illegal length, greater than maximum frame, %d ",
in_buf->smb_buf_length)); in_buf->smb_buf_length));
...@@ -214,7 +219,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -214,7 +219,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
midQ->midState = MID_REQUEST_SUBMITTED; midQ->midState = MID_REQUEST_SUBMITTED;
rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
(struct sockaddr *) &(ses->server->sockAddr)); (struct sockaddr *) &(ses->server->sockAddr));
up(&ses->server->tcpSem);
if (long_op == -1) if (long_op == -1)
goto cifs_no_response_exit; goto cifs_no_response_exit;
if (long_op > 1) /* writes past end of file can take looooong time */ if (long_op > 1) /* writes past end of file can take looooong time */
......
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