diff options
author | Pavel Shilovsky <piastryyy@gmail.com> | 2011-01-17 12:15:44 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2011-01-19 12:52:29 -0500 |
commit | 12fed00de963433128b5366a21a55808fab2f756 (patch) | |
tree | 2898690f5853027b70eda1bd7f3aeb78fe9af74d /fs/cifs/file.c | |
parent | c56eb8fb6dccb83d9fe62fd4dc00c834de9bc470 (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.c | 21 |
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 | ||