aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
authorPavel Shilovsky <piastryyy@gmail.com>2011-01-17 12:15:44 -0500
committerSteve French <sfrench@us.ibm.com>2011-01-19 12:52:29 -0500
commit12fed00de963433128b5366a21a55808fab2f756 (patch)
tree2898690f5853027b70eda1bd7f3aeb78fe9af74d /fs/cifs/file.c
parentc56eb8fb6dccb83d9fe62fd4dc00c834de9bc470 (diff)
CIFS: Fix oplock break handling (try #2)
When we get oplock break notification we should set the appropriate value of OplockLevel field in oplock break acknowledge according to the oplock level held by the client in this time. As we only can have level II oplock or no oplock in the case of oplock break, we should be aware only about clientCanCacheRead field in cifsInodeInfo structure. Also fix bug connected with wrong interpretation of OplockLevel field during oplock break notification processing. Signed-off-by: Pavel Shilovsky <piastryyy@gmail.com> Cc: <stable@kernel.org> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index d843631c028d..af371910f543 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -726,12 +726,12 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
726 726
727 /* BB we could chain these into one lock request BB */ 727 /* BB we could chain these into one lock request BB */
728 rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start, 728 rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start,
729 0, 1, lockType, 0 /* wait flag */ ); 729 0, 1, lockType, 0 /* wait flag */, 0);
730 if (rc == 0) { 730 if (rc == 0) {
731 rc = CIFSSMBLock(xid, tcon, netfid, length, 731 rc = CIFSSMBLock(xid, tcon, netfid, length,
732 pfLock->fl_start, 1 /* numUnlock */ , 732 pfLock->fl_start, 1 /* numUnlock */ ,
733 0 /* numLock */ , lockType, 733 0 /* numLock */ , lockType,
734 0 /* wait flag */ ); 734 0 /* wait flag */, 0);
735 pfLock->fl_type = F_UNLCK; 735 pfLock->fl_type = F_UNLCK;
736 if (rc != 0) 736 if (rc != 0)
737 cERROR(1, "Error unlocking previously locked " 737 cERROR(1, "Error unlocking previously locked "
@@ -748,13 +748,13 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
748 rc = CIFSSMBLock(xid, tcon, netfid, length, 748 rc = CIFSSMBLock(xid, tcon, netfid, length,
749 pfLock->fl_start, 0, 1, 749 pfLock->fl_start, 0, 1,
750 lockType | LOCKING_ANDX_SHARED_LOCK, 750 lockType | LOCKING_ANDX_SHARED_LOCK,
751 0 /* wait flag */); 751 0 /* wait flag */, 0);
752 if (rc == 0) { 752 if (rc == 0) {
753 rc = CIFSSMBLock(xid, tcon, netfid, 753 rc = CIFSSMBLock(xid, tcon, netfid,
754 length, pfLock->fl_start, 1, 0, 754 length, pfLock->fl_start, 1, 0,
755 lockType | 755 lockType |
756 LOCKING_ANDX_SHARED_LOCK, 756 LOCKING_ANDX_SHARED_LOCK,
757 0 /* wait flag */); 757 0 /* wait flag */, 0);
758 pfLock->fl_type = F_RDLCK; 758 pfLock->fl_type = F_RDLCK;
759 if (rc != 0) 759 if (rc != 0)
760 cERROR(1, "Error unlocking " 760 cERROR(1, "Error unlocking "
@@ -797,8 +797,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
797 797
798 if (numLock) { 798 if (numLock) {
799 rc = CIFSSMBLock(xid, tcon, netfid, length, 799 rc = CIFSSMBLock(xid, tcon, netfid, length,
800 pfLock->fl_start, 800 pfLock->fl_start, 0, numLock, lockType,
801 0, numLock, lockType, wait_flag); 801 wait_flag, 0);
802 802
803 if (rc == 0) { 803 if (rc == 0) {
804 /* For Windows locks we must store them. */ 804 /* For Windows locks we must store them. */
@@ -818,9 +818,9 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
818 (pfLock->fl_start + length) >= 818 (pfLock->fl_start + length) >=
819 (li->offset + li->length)) { 819 (li->offset + li->length)) {
820 stored_rc = CIFSSMBLock(xid, tcon, 820 stored_rc = CIFSSMBLock(xid, tcon,
821 netfid, 821 netfid, li->length,
822 li->length, li->offset, 822 li->offset, 1, 0,
823 1, 0, li->type, false); 823 li->type, false, 0);
824 if (stored_rc) 824 if (stored_rc)
825 rc = stored_rc; 825 rc = stored_rc;
826 else { 826 else {
@@ -2192,7 +2192,8 @@ void cifs_oplock_break(struct work_struct *work)
2192 */ 2192 */
2193 if (!cfile->oplock_break_cancelled) { 2193 if (!cfile->oplock_break_cancelled) {
2194 rc = CIFSSMBLock(0, tlink_tcon(cfile->tlink), cfile->netfid, 0, 2194 rc = CIFSSMBLock(0, tlink_tcon(cfile->tlink), cfile->netfid, 0,
2195 0, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, false); 2195 0, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, false,
2196 cinode->clientCanCacheRead ? 1 : 0);
2196 cFYI(1, "Oplock release rc = %d", rc); 2197 cFYI(1, "Oplock release rc = %d", rc);
2197 } 2198 }
2198 2199