From patchwork Tue Aug 18 18:07:02 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 42401 Received: from lists.samba.org (fn.samba.org [216.83.154.106]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n7II7LNb005729 for ; Tue, 18 Aug 2009 18:07:21 GMT Received: from fn.samba.org (localhost [127.0.0.1]) by lists.samba.org (Postfix) with ESMTP id D121046576; Tue, 18 Aug 2009 12:00:46 -0600 (MDT) X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on fn.samba.org X-Spam-Level: X-Spam-Status: No, score=-3.3 required=3.8 tests=AWL, BAYES_00, NO_MORE_FUNN, SPF_PASS autolearn=no version=3.2.5 X-Original-To: linux-cifs-client@lists.samba.org Delivered-To: linux-cifs-client@lists.samba.org Received: from cdptpa-omtalb.mail.rr.com (cdptpa-omtalb.mail.rr.com [75.180.132.123]) by lists.samba.org (Postfix) with ESMTP id C4244ACFC9 for ; Tue, 18 Aug 2009 12:00:31 -0600 (MDT) Received: from mail.poochiereds.net ([71.70.153.3]) by cdptpa-omta02.mail.rr.com with ESMTP id <20090818180705010.SGEA8845@cdptpa-omta02.mail.rr.com>; Tue, 18 Aug 2009 18:07:05 +0000 Received: by mail.poochiereds.net (Postfix, from userid 4447) id 226EE5814F; Tue, 18 Aug 2009 14:07:03 -0400 (EDT) From: Jeff Layton To: smfrench@gmail.com Date: Tue, 18 Aug 2009 14:07:02 -0400 Message-Id: <1250618822-6131-6-git-send-email-jlayton@redhat.com> X-Mailer: git-send-email 1.6.0.6 In-Reply-To: <1250618822-6131-1-git-send-email-jlayton@redhat.com> References: <1250618822-6131-1-git-send-email-jlayton@redhat.com> Cc: linux-cifs-client@lists.samba.org Subject: [linux-cifs-client] [PATCH 5/5] cifs: cancel oplock release callbacks during reconnect X-BeenThere: linux-cifs-client@lists.samba.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: The Linux CIFS VFS client List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-cifs-client-bounces@lists.samba.org Errors-To: linux-cifs-client-bounces@lists.samba.org cifs_oplock_thread has a check for pTcon->needs_reconnect and will skip the CIFSSMBLock call if it's set. Problem: what if the tcon has this set and then gets reconnected before the call goes out on the wire? The oplock release isn't needed and could be a bad thing at that point if the filehandle was reclaimed. Cancel oplock release calls during a reconnect event. Signed-off-by: Jeff Layton Acked-by: Shirish Pargaonkar --- fs/cifs/cifsfs.c | 2 +- fs/cifs/cifsglob.h | 1 + fs/cifs/connect.c | 9 +++++++++ fs/cifs/misc.c | 1 + 4 files changed, 12 insertions(+), 1 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 647c5bc..92e06c1 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -1024,7 +1024,7 @@ static int cifs_oplock_thread(void *dummyarg) * to server still is disconnected since oplock * already released by the server in that case */ - if (!tcon->need_reconnect) { + if (!oplock->cancel) { rc = CIFSSMBLock(0, tcon, oplock->netfid, 0 /* len */ , 0 /* offset */, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 363dbcf..676c107 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -448,6 +448,7 @@ struct oplock_q_entry { struct inode *pinode; struct cifsTconInfo *tcon; __u16 netfid; + bool cancel; }; /* for pending dnotify requests */ diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index f49304d..b7b67e9 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -121,6 +121,7 @@ cifs_reconnect(struct TCP_Server_Info *server) struct cifsSesInfo *ses; struct cifsTconInfo *tcon; struct mid_q_entry *mid_entry; + struct oplock_q_entry *oplock; spin_lock(&GlobalMid_Lock); if (server->tcpStatus == CifsExiting) { @@ -137,6 +138,7 @@ cifs_reconnect(struct TCP_Server_Info *server) /* before reconnecting the tcp session, mark the smb session (uid) and the tid bad so they are not used until reconnected */ + spin_lock(&cifs_oplock_lock); read_lock(&cifs_tcp_ses_lock); list_for_each(tmp, &server->smb_ses_list) { ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list); @@ -145,9 +147,16 @@ cifs_reconnect(struct TCP_Server_Info *server) list_for_each(tmp2, &ses->tcon_list) { tcon = list_entry(tmp2, struct cifsTconInfo, tcon_list); tcon->need_reconnect = true; + list_for_each_entry(oplock, &cifs_oplock_list, qhead) { + if (oplock->tcon == tcon) + oplock->cancel = true; + } } + } read_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_oplock_lock); + /* do not want to be sending data on a socket we are freeing */ mutex_lock(&server->srv_mutex); if (server->ssocket) { diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 3bf3a52..4a2d297 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -612,6 +612,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv, oplock->tcon = tcon; oplock->pinode = inode; oplock->netfid = netfile->netfid; + oplock->cancel = false; spin_lock(&cifs_oplock_lock); list_add_tail(&oplock->qhead, &cifs_oplock_list);