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
------------
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
------------
......
......@@ -990,6 +990,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
init_waitqueue_head(&srvTcp->response_q);
INIT_LIST_HEAD(&srvTcp->pending_mid_q);
srvTcp->tcpStatus = CifsGood;
init_MUTEX(&srvTcp->tcpSem);
kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp,
CLONE_FS | CLONE_FILES | CLONE_VM);
}
......
......@@ -220,6 +220,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
pCifsFile->pInode = newinode;
pCifsFile->invalidHandle = FALSE;
pCifsFile->closePend = FALSE;
init_MUTEX(&pCifsFile->fh_sem);
/* pCifsFile->pfile = file; */ /* put in at open time */
write_lock(&GlobalSMBSeslock);
list_add(&pCifsFile->tlist,&pTcon->openFileList);
......
......@@ -142,6 +142,7 @@ cifs_open(struct inode *inode, struct file *file)
pCifsFile = (struct cifsFileInfo *) file->private_data;
pCifsFile->netfid = netfid;
pCifsFile->pid = current->pid;
init_MUTEX(&pCifsFile->fh_sem);
pCifsFile->pfile = file; /* needed for writepage */
pCifsFile->pInode = inode;
pCifsFile->invalidHandle = FALSE;
......@@ -1390,6 +1391,7 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
(struct cifsFileInfo *) file->private_data;
cifsFile->netfid = searchHandle;
cifsFile->invalidHandle = FALSE;
init_MUTEX(&cifsFile->fh_sem);
} else {
rc = -ENOMEM;
break;
......
......@@ -192,13 +192,18 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
return -EAGAIN;
} /* 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);
if (midQ == NULL) {
up(&ses->server->tcpSem);
return -EIO;
}
if (in_buf->smb_buf_length > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE - 4) {
up(&ses->server->tcpSem);
cERROR(1,
("Illegal length, greater than maximum frame, %d ",
in_buf->smb_buf_length));
......@@ -214,7 +219,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
midQ->midState = MID_REQUEST_SUBMITTED;
rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
(struct sockaddr *) &(ses->server->sockAddr));
up(&ses->server->tcpSem);
if (long_op == -1)
goto cifs_no_response_exit;
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