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) ...@@ -441,6 +441,8 @@ static int cifs_oplock_thread(void * dummyarg)
struct list_head * tmp1; struct list_head * tmp1;
struct oplock_q_entry * oplock_item; struct oplock_q_entry * oplock_item;
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
struct inode * inode;
__u16 netfid;
int rc; int rc;
daemonize("cifsoplockd"); daemonize("cifsoplockd");
...@@ -457,15 +459,16 @@ static int cifs_oplock_thread(void * dummyarg) ...@@ -457,15 +459,16 @@ static int cifs_oplock_thread(void * dummyarg)
qhead); qhead);
if(oplock_item) { if(oplock_item) {
pTcon = oplock_item->tcon; pTcon = oplock_item->tcon;
inode = oplock_item->pinode;
netfid = oplock_item->netfid;
DeleteOplockQEntry(oplock_item); DeleteOplockQEntry(oplock_item);
write_unlock(&GlobalMid_Lock); write_unlock(&GlobalMid_Lock);
rc = filemap_fdatawrite(oplock_item->pinode->i_mapping); rc = filemap_fdatawrite(inode->i_mapping);
if(rc) if(rc)
CIFS_I(oplock_item->pinode)->write_behind_rc CIFS_I(inode)->write_behind_rc
= rc; = rc;
cFYI(1,("Oplock flush inode %p rc %d",oplock_item->pinode,rc)); cFYI(1,("Oplock flush inode %p rc %d",inode,rc));
rc = CIFSSMBLock(0, pTcon, rc = CIFSSMBLock(0, pTcon, netfid,
oplock_item->netfid,
0 /* len */ , 0 /* offset */, 0, 0 /* len */ , 0 /* offset */, 0,
0, LOCKING_ANDX_OPLOCK_RELEASE, 0, LOCKING_ANDX_OPLOCK_RELEASE,
0 /* wait flag */); 0 /* wait flag */);
......
...@@ -481,8 +481,9 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, ...@@ -481,8 +481,9 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
pSMB->hdr.smb_buf_length += pSMB->ByteCount; pSMB->hdr.smb_buf_length += pSMB->ByteCount;
pSMB->ByteCount = cpu_to_le16(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, 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) { if (rc) {
cFYI(1, ("Error in Open = %d", rc)); cFYI(1, ("Error in Open = %d", rc));
} else { } else {
......
...@@ -181,11 +181,26 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -181,11 +181,26 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
direntry->d_op = &cifs_dentry_ops; direntry->d_op = &cifs_dentry_ops;
d_instantiate(direntry, newinode); d_instantiate(direntry, newinode);
} }
if((nd->flags & LOOKUP_OPEN) == FALSE) {
if(newinode) { /* mknod case - do not leave file open */
newinode->i_mode = mode; CIFSSMBClose(xid, pTcon, fileHandle);
pCifsFile = (struct cifsFileInfo *) if(newinode)
kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); 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) { if (pCifsFile) {
memset((char *)pCifsFile, 0, memset((char *)pCifsFile, 0,
...@@ -220,8 +235,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -220,8 +235,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
} }
} }
} }
} }
if (buf) if (buf)
......
...@@ -514,8 +514,8 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to) ...@@ -514,8 +514,8 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
cifsInode = CIFS_I(mapping->host); cifsInode = CIFS_I(mapping->host);
read_lock(&GlobalSMBSeslock); read_lock(&GlobalSMBSeslock);
list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) { list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
open_file = list_entry(tmp,struct cifsFileInfo, flist); open_file = list_entry(tmp,struct cifsFileInfo, flist);
/* We could check if file is open for writing first */ /* We check if file is open for writing first */
if((open_file->pfile) && if((open_file->pfile) &&
((open_file->pfile->f_flags & O_RDWR) || ((open_file->pfile->f_flags & O_RDWR) ||
(open_file->pfile->f_flags & O_WRONLY))) { (open_file->pfile->f_flags & O_WRONLY))) {
...@@ -1098,6 +1098,10 @@ construct_dentry(struct qstr *qstring, struct file *file, ...@@ -1098,6 +1098,10 @@ construct_dentry(struct qstr *qstring, struct file *file,
cFYI(0, (" existing dentry with inode 0x%p", tmp_dentry->d_inode)); cFYI(0, (" existing dentry with inode 0x%p", tmp_dentry->d_inode));
*ptmp_inode = 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 ?? */ /* 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 { } else {
tmp_dentry = d_alloc(file->f_dentry, qstring); tmp_dentry = d_alloc(file->f_dentry, qstring);
*ptmp_inode = new_inode(file->f_dentry->d_sb); *ptmp_inode = new_inode(file->f_dentry->d_sb);
......
...@@ -216,7 +216,8 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -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 */ if (long_op > 1) /* writes past end of file can take looooong time */
timeout = 300 * HZ; timeout = 300 * HZ;
else if (long_op == 1) else if (long_op == 1)
timeout = 60 * HZ; timeout = 45 * HZ; /* should be greater than
servers oplock break timeout (about 43 seconds) */
else else
timeout = 15 * HZ; timeout = 15 * HZ;
/* wait for 15 seconds or until woken up due to response arriving or /* 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, ...@@ -235,6 +236,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
receive_len = receive_len =
be32_to_cpu(midQ->resp_buf->smb_buf_length); be32_to_cpu(midQ->resp_buf->smb_buf_length);
else { else {
cFYI(1,("No response buffer"));
DeleteMidQEntry(midQ); DeleteMidQEntry(midQ);
return -EIO; return -EIO;
} }
...@@ -287,8 +289,10 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -287,8 +289,10 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
4 /* do not count RFC1001 header */ + 4 /* do not count RFC1001 header */ +
(2 * out_buf->WordCount) + 2 /* bcc */ ) (2 * out_buf->WordCount) + 2 /* bcc */ )
BCC(out_buf) = le16_to_cpu(BCC(out_buf)); BCC(out_buf) = le16_to_cpu(BCC(out_buf));
} else } else {
rc = -EIO; rc = -EIO;
cFYI(1,("Bad MID state? "));
}
} }
cifs_no_response_exit: cifs_no_response_exit:
DeleteMidQEntry(midQ); /* BB what if process is killed? 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