Commit ecfe832e authored by Steve French's avatar Steve French Committed by Steve French

fix cifs distributed caching - send oplock release immediately after flush of...

fix cifs distributed caching - send oplock release immediately after flush of writebehind data on oplock break from server
parent bed8ce47
Version 0.82
------------
Add support for mknod of block or character devices. Fix oplock
code (distributed caching) to properly send response to oplock
break from server.
Version 0.81 Version 0.81
------------ ------------
Finish up CIFS packet digital signing for the default Finish up CIFS packet digital signing for the default
......
...@@ -76,8 +76,9 @@ or Linux: ...@@ -76,8 +76,9 @@ or Linux:
case sensitive = yes case sensitive = yes
delete readonly = yes delete readonly = yes
Some administrators also change the "map archive" and the "create mask" parameters Some administrators also change the "map archive" and the "create mask" parameters
from their defaults. For more information on these see the manual pages from their default values. Creating special devices (mknod) remotely may require
("man smb.conf") on the Samba server system. Note that the cifs vfs, unlike the specifying a mkdev function to Samba. For more information on these see the manual
pages ("man smb.conf") on the Samba server system. Note that the cifs vfs, unlike the
smbfs vfs, does not read the smb.conf on the client system (the few optional settings smbfs vfs, does not read the smb.conf on the client system (the few optional settings
are passed in on mount via -o parameters instead). Note that Samba 2.2.7 or later are passed in on mount via -o parameters instead). Note that Samba 2.2.7 or later
includes a fix that allows the CIFS VFS to delete open files (required for strict includes a fix that allows the CIFS VFS to delete open files (required for strict
......
...@@ -466,7 +466,14 @@ static int cifs_oplock_thread(void * dummyarg) ...@@ -466,7 +466,14 @@ static int cifs_oplock_thread(void * dummyarg)
CIFS_I(pfile->f_dentry->d_inode)->write_behind_rc CIFS_I(pfile->f_dentry->d_inode)->write_behind_rc
= rc; = rc;
cFYI(1,("Oplock flush file %p rc %d",pfile,rc)); cFYI(1,("Oplock flush file %p rc %d",pfile,rc));
/* send oplock break */ if(pfile->private_data) {
rc = CIFSSMBLock(0, pTcon,
((struct cifsFileInfo *) pfile->private_data)->netfid,
0 /* len */ , 0 /* offset */, 0,
0, LOCKING_ANDX_OPLOCK_RELEASE,
0 /* wait flag */);
cFYI(1,("Oplock release rc = %d ",rc));
}
write_lock(&GlobalMid_Lock); write_lock(&GlobalMid_Lock);
} else } else
break; break;
......
...@@ -618,6 +618,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, ...@@ -618,6 +618,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
LOCK_REQ *pSMB = NULL; LOCK_REQ *pSMB = NULL;
LOCK_RSP *pSMBr = NULL; LOCK_RSP *pSMBr = NULL;
int bytes_returned; int bytes_returned;
int timeout = 0;
cFYI(1, ("In CIFSSMBLock")); cFYI(1, ("In CIFSSMBLock"));
...@@ -626,6 +627,9 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, ...@@ -626,6 +627,9 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
if (rc) if (rc)
return rc; return rc;
if(lockType == LOCKING_ANDX_OPLOCK_RELEASE)
timeout = -1; /* no response expected */
pSMB->NumberOfLocks = cpu_to_le32(numLock); pSMB->NumberOfLocks = cpu_to_le32(numLock);
pSMB->NumberOfUnlocks = cpu_to_le32(numUnlock); pSMB->NumberOfUnlocks = cpu_to_le32(numUnlock);
pSMB->LockType = lockType; pSMB->LockType = lockType;
...@@ -640,7 +644,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, ...@@ -640,7 +644,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount); pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
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, timeout);
if (rc) { if (rc) {
cERROR(1, ("Send error in Lock = %d", rc)); cERROR(1, ("Send error in Lock = %d", rc));
......
...@@ -338,13 +338,8 @@ is_valid_oplock_break(struct smb_hdr *buf) ...@@ -338,13 +338,8 @@ is_valid_oplock_break(struct smb_hdr *buf)
netfile = list_entry(tmp1,struct cifsFileInfo,tlist); netfile = list_entry(tmp1,struct cifsFileInfo,tlist);
if(pSMB->Fid == netfile->netfid) { if(pSMB->Fid == netfile->netfid) {
struct cifsInodeInfo *pCifsInode; struct cifsInodeInfo *pCifsInode;
/* BB Add following logic: /* BB Add following logic to mark inode for write through
2) look up inode from tcon->openFileList->file->f_dentry->d_inode inode->i_data.a_ops = &cifs_addr_ops_writethrough; */
3) flush dirty pages and cached byte range locks and mark inode
4) depending on break type change to r/o caching or no caching
cifsinode->clientCanCacheAll = 0
5) inode->i_data.a_ops = &cifs_addr_ops_writethrough;
6) send oplock break response to server */
read_unlock(&GlobalSMBSeslock); read_unlock(&GlobalSMBSeslock);
cFYI(1,("Matching file id, processing oplock break")); cFYI(1,("Matching file id, processing oplock break"));
pCifsInode = pCifsInode =
...@@ -354,7 +349,7 @@ is_valid_oplock_break(struct smb_hdr *buf) ...@@ -354,7 +349,7 @@ is_valid_oplock_break(struct smb_hdr *buf)
pCifsInode->clientCanCacheRead = FALSE; pCifsInode->clientCanCacheRead = FALSE;
pCifsInode->oplockPending = TRUE; pCifsInode->oplockPending = TRUE;
AllocOplockQEntry(netfile->pfile, tcon); AllocOplockQEntry(netfile->pfile, tcon);
cFYI(1,("about to wake up oplock thd")); cFYI(1,("about to wake up oplock thd"));
wake_up_process(oplockThread); wake_up_process(oplockThread);
return TRUE; return TRUE;
} }
......
...@@ -199,13 +199,15 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -199,13 +199,15 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
if (in_buf->smb_buf_length > 12) if (in_buf->smb_buf_length > 12)
in_buf->Flags2 = cpu_to_le16(in_buf->Flags2); in_buf->Flags2 = cpu_to_le16(in_buf->Flags2);
rc = cifs_sign_smb(in_buf, ses, &midQ->sequence_number); rc = cifs_sign_smb(in_buf, ses, &midQ->sequence_number);
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));
if (long_op == -1)
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 */
timeout = 300 * HZ; timeout = 300 * HZ;
else if (long_op == 1) else if (long_op == 1)
...@@ -283,7 +285,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -283,7 +285,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
} else } else
rc = -EIO; rc = -EIO;
} }
cifs_no_response_exit:
DeleteMidQEntry(midQ); /* BB what if process is killed? DeleteMidQEntry(midQ); /* BB what if process is killed?
- BB add background daemon to clean up Mid entries from - BB add background daemon to clean up Mid entries from
killed processes & test killing process with active mid */ killed processes & test killing process with active mid */
......
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