Re: [PATCH 5/5] cifs: cancel oplock release callbacks during reconnect
Shirish Pargaonkar <[email protected]>
| Newsgroups | gmane.linux.file-systems.cifs |
|---|---|
| Message-ID | <[email protected]> |
On Fri, Aug 28, 2009 at 2:26 PM, Jeff Layton<[email protected]> wrote: > On Fri, 28 Aug 2009 14:14:43 -0500 > Shirish Pargaonkar <[email protected]> wrote: > >> On Tue, Aug 18, 2009 at 1:07 PM, Jeff Layton<[email protected]> wrote: >> > 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 <[email protected]> >> > --- >> > 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); >> > -- >> > 1.6.0.6 >> > >> > _______________________________________________ >> > linux-cifs-client mailing list >> > [email protected] >> > https://lists.samba.org/mailman/listinfo/linux-cifs-client >> > >> >> >> Acked-by: Shirish Pargaonkar <[email protected]> >> >> with a question, does what you say about pTcon->needs_reconnect apply >> to oplock->cancel also? > > I don't think so. oplock->cancel doesn't get cleared on a reconnect. > > ...or did I misunderstand the question? > > Thanks, > -- > Jeff Layton <[email protected]> > Jeff, I was thinking, if oplock->cancel is false but before call is sent out, reconnect happens and it is not necessary to send the call (oplock->cancel is true) and yet it could get sent, similar to what can happen in case of tcon->need_reconnect?