Commit 7dbb0435 authored by Steve French's avatar Steve French Committed by Steve French

Do not leave files created with mknod open on server. Fix related oops. Fix...

Do not leave files created with mknod open on server. Fix related oops.  Fix timeout on open to be at least server oplock break timeout to avoid timing out successful opens when secondary client hung.
parent 267880af
......@@ -441,6 +441,8 @@ static int cifs_oplock_thread(void * dummyarg)
struct list_head * tmp1;
struct oplock_q_entry * oplock_item;
struct cifsTconInfo *pTcon;
struct inode * inode;
__u16 netfid;
int rc;
daemonize("cifsoplockd");
......@@ -457,15 +459,16 @@ static int cifs_oplock_thread(void * dummyarg)
qhead);
if(oplock_item) {
pTcon = oplock_item->tcon;
inode = oplock_item->pinode;
netfid = oplock_item->netfid;
DeleteOplockQEntry(oplock_item);
write_unlock(&GlobalMid_Lock);
rc = filemap_fdatawrite(oplock_item->pinode->i_mapping);
rc = filemap_fdatawrite(inode->i_mapping);
if(rc)
CIFS_I(oplock_item->pinode)->write_behind_rc
CIFS_I(inode)->write_behind_rc
= rc;
cFYI(1,("Oplock flush inode %p rc %d",oplock_item->pinode,rc));
rc = CIFSSMBLock(0, pTcon,
oplock_item->netfid,
cFYI(1,("Oplock flush inode %p rc %d",inode,rc));
rc = CIFSSMBLock(0, pTcon, netfid,
0 /* len */ , 0 /* offset */, 0,
0, LOCKING_ANDX_OPLOCK_RELEASE,
0 /* wait flag */);
......
......@@ -481,8 +481,9 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
pSMB->hdr.smb_buf_length += pSMB->ByteCount;
pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
/* long_op set to 1 to allow for oplock break timeouts */
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
(struct smb_hdr *) pSMBr, &bytes_returned, 1);
if (rc) {
cFYI(1, ("Error in Open = %d", rc));
} else {
......
......@@ -181,11 +181,26 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
direntry->d_op = &cifs_dentry_ops;
d_instantiate(direntry, newinode);
}
if(newinode) {
newinode->i_mode = mode;
pCifsFile = (struct cifsFileInfo *)
kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
if((nd->flags & LOOKUP_OPEN) == FALSE) {
/* mknod case - do not leave file open */
CIFSSMBClose(xid, pTcon, fileHandle);
if(newinode)
newinode->i_mode = mode;
if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
(__u64)-1,
(__u64)-1,
0 /* dev */,
cifs_sb->local_nls);
else { /* BB implement via Windows security descriptors */
/* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
/* in the meantime could set r/o dos attribute when perms are eg:
mode & 0222 == 0 */
}
} else if(newinode) {
newinode->i_mode = mode;
pCifsFile = (struct cifsFileInfo *)
kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
if (pCifsFile) {
memset((char *)pCifsFile, 0,
......@@ -220,8 +235,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
}
}
}
}
if (buf)
......
......@@ -514,8 +514,8 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
cifsInode = CIFS_I(mapping->host);
read_lock(&GlobalSMBSeslock);
list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
open_file = list_entry(tmp,struct cifsFileInfo, flist);
/* We could check if file is open for writing first */
open_file = list_entry(tmp,struct cifsFileInfo, flist);
/* We check if file is open for writing first */
if((open_file->pfile) &&
((open_file->pfile->f_flags & O_RDWR) ||
(open_file->pfile->f_flags & O_WRONLY))) {
......@@ -1098,6 +1098,10 @@ construct_dentry(struct qstr *qstring, struct file *file,
cFYI(0, (" existing dentry with inode 0x%p", tmp_dentry->d_inode));
*ptmp_inode = tmp_dentry->d_inode;
/* BB overwrite the old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len ?? */
if(*ptmp_inode == NULL) {
*ptmp_inode = new_inode(file->f_dentry->d_sb);
d_instantiate(tmp_dentry, *ptmp_inode);
}
} else {
tmp_dentry = d_alloc(file->f_dentry, qstring);
*ptmp_inode = new_inode(file->f_dentry->d_sb);
......
......@@ -216,7 +216,8 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
if (long_op > 1) /* writes past end of file can take looooong time */
timeout = 300 * HZ;
else if (long_op == 1)
timeout = 60 * HZ;
timeout = 45 * HZ; /* should be greater than
servers oplock break timeout (about 43 seconds) */
else
timeout = 15 * HZ;
/* wait for 15 seconds or until woken up due to response arriving or
......@@ -235,6 +236,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
receive_len =
be32_to_cpu(midQ->resp_buf->smb_buf_length);
else {
cFYI(1,("No response buffer"));
DeleteMidQEntry(midQ);
return -EIO;
}
......@@ -287,8 +289,10 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
4 /* do not count RFC1001 header */ +
(2 * out_buf->WordCount) + 2 /* bcc */ )
BCC(out_buf) = le16_to_cpu(BCC(out_buf));
} else
} else {
rc = -EIO;
cFYI(1,("Bad MID state? "));
}
}
cifs_no_response_exit:
DeleteMidQEntry(midQ); /* BB what if process is killed?
......
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