From patchwork Fri Jan 14 17:52:41 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovsky X-Patchwork-Id: 479761 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p0EHxvm7018683 for ; Fri, 14 Jan 2011 18:00:09 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752414Ab1ANRx1 (ORCPT ); Fri, 14 Jan 2011 12:53:27 -0500 Received: from mail-ew0-f46.google.com ([209.85.215.46]:35549 "EHLO mail-ew0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752312Ab1ANRx0 (ORCPT ); Fri, 14 Jan 2011 12:53:26 -0500 Received: by ewy5 with SMTP id 5so1609762ewy.19 for ; Fri, 14 Jan 2011 09:53:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:date:message-id:x-mailer; bh=8zp2+KJilJlo0RvzqRJ3Pqm7f4ixK5Z/l4oRgGuls5Y=; b=xXxsSdNpfjTOhEOKvbjndRGPDgaJAViJk3cqzfKOLrU8sbbdrqkbazPHSG/tcWes7p mi3cWoqkcsXlfTXPJSvwaVQKwWdTWlPOpNS9KCqieh8JiYpfrePKzF2BEi3qJkR/ifSg VZJ+/FasDpaliENmK6/CYfqhDNue1tNg4rZdM= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; b=EOuLytarhqfH4VOVRGEn28EFwfrmbl6fRO1JSD80OgLEMPB3rO2m0w8hccTXAHpnYt /lATpPoUng1Z/JlA3g2XiDLuZ+cEF/nmidPbT14JdqaZvnN8vIvQsb3zsxoq4KyWu60Y epbV8vfvzLr0CIGxb9Yp67yaIs2zhvIFTxRYQ= Received: by 10.213.23.12 with SMTP id p12mr1001733ebb.50.1295027605127; Fri, 14 Jan 2011 09:53:25 -0800 (PST) Received: from localhost.localdomain ([79.126.73.123]) by mx.google.com with ESMTPS id t5sm1123454eeh.14.2011.01.14.09.53.22 (version=TLSv1/SSLv3 cipher=RC4-MD5); Fri, 14 Jan 2011 09:53:24 -0800 (PST) From: Pavel Shilovsky To: linux-cifs@vger.kernel.org Cc: Subject: [PATCH] CIFS: Fix oplock break handling Date: Fri, 14 Jan 2011 20:52:41 +0300 Message-Id: <1295027561-24077-1-git-send-email-piastryyy@gmail.com> X-Mailer: git-send-email 1.7.1 Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 14 Jan 2011 18:00:10 +0000 (UTC) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index e6d1481..95d5dbb 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -347,7 +347,7 @@ extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, const __u16 netfid, const __u64 len, const __u64 offset, const __u32 numUnlock, const __u32 numLock, const __u8 lockType, - const bool waitFlag); + const bool waitFlag, const __u8 oplock_level); extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, const __u16 smb_file_id, const int get_flag, const __u64 len, struct file_lock *, diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 2f6795e..3652cc6 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -1663,7 +1663,8 @@ int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, const __u16 smb_file_id, const __u64 len, const __u64 offset, const __u32 numUnlock, - const __u32 numLock, const __u8 lockType, const bool waitFlag) + const __u32 numLock, const __u8 lockType, + const bool waitFlag, const __u8 oplock_level) { int rc = 0; LOCK_REQ *pSMB = NULL; @@ -1691,6 +1692,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, pSMB->NumberOfLocks = cpu_to_le16(numLock); pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock); pSMB->LockType = lockType; + pSMB->OplockLevel = oplock_level; pSMB->AndXCommand = 0xFF; /* none */ pSMB->Fid = smb_file_id; /* netfid stays le */ diff --git a/fs/cifs/file.c b/fs/cifs/file.c index d843631..7e83cdb 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) /* BB we could chain these into one lock request BB */ rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start, - 0, 1, lockType, 0 /* wait flag */ ); + 0, 1, lockType, 0 /* wait flag */, 0); if (rc == 0) { rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start, 1 /* numUnlock */ , 0 /* numLock */ , lockType, - 0 /* wait flag */ ); + 0 /* wait flag */, 0); pfLock->fl_type = F_UNLCK; if (rc != 0) cERROR(1, "Error unlocking previously locked " @@ -748,13 +748,13 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start, 0, 1, lockType | LOCKING_ANDX_SHARED_LOCK, - 0 /* wait flag */); + 0 /* wait flag */, 0); if (rc == 0) { rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start, 1, 0, lockType | LOCKING_ANDX_SHARED_LOCK, - 0 /* wait flag */); + 0 /* wait flag */, 0); pfLock->fl_type = F_RDLCK; if (rc != 0) cERROR(1, "Error unlocking " @@ -797,8 +797,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) if (numLock) { rc = CIFSSMBLock(xid, tcon, netfid, length, - pfLock->fl_start, - 0, numLock, lockType, wait_flag); + pfLock->fl_start, 0, numLock, lockType, + wait_flag, 0); if (rc == 0) { /* For Windows locks we must store them. */ @@ -818,9 +818,9 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) (pfLock->fl_start + length) >= (li->offset + li->length)) { stored_rc = CIFSSMBLock(xid, tcon, - netfid, - li->length, li->offset, - 1, 0, li->type, false); + netfid, li->length, + li->offset, 1, 0, + li->type, false, 0); if (stored_rc) rc = stored_rc; else { @@ -2192,7 +2192,8 @@ void cifs_oplock_break(struct work_struct *work) */ if (!cfile->oplock_break_cancelled) { rc = CIFSSMBLock(0, tlink_tcon(cfile->tlink), cfile->netfid, 0, - 0, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, false); + 0, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, false, + cinode->clientCanCacheRead); cFYI(1, "Oplock release rc = %d", rc); } diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 43f1028..09bfcf0 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -571,7 +571,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) pCifsInode = CIFS_I(netfile->dentry->d_inode); cifs_set_oplock_level(pCifsInode, - pSMB->OplockLevel); + pSMB->OplockLevel ? OPLOCK_READ : 0); /* * cifs_oplock_break_put() can't be called * from here. Get reference after queueing