Why don&#39;t we have a reference to this inode already?   We can&#39;t have an oplock break unless the file is open, if the file is open then we have a reference to the inode ...<br><br><div class="gmail_quote">On Tue, Aug 18, 2009 at 1:07 PM, Jeff Layton <span dir="ltr">&lt;<a href="mailto:jlayton@redhat.com">jlayton@redhat.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">When an oplock break comes in, cifs needs to do things like write out<br>
dirty data for it. It doesn&#39;t hold a reference to that inode in this<br>
case however. Get an active reference to the inode when an oplock break<br>
comes in. If we don&#39;t get a reference, we still need to create an oplock<br>
queue entry so that the oplock release call gets done, but we&#39;ll want to<br>
skip writeback in that case.<br>
<br>
Signed-off-by: Jeff Layton &lt;<a href="mailto:jlayton@redhat.com">jlayton@redhat.com</a>&gt;<br>
---<br>
 fs/cifs/cifsfs.c |   26 ++++++++++----------------<br>
 fs/cifs/misc.c   |    4 +++-<br>
 2 files changed, 13 insertions(+), 17 deletions(-)<br>
<br>
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c<br>
index 2fcc722..647c5bc 100644<br>
--- a/fs/cifs/cifsfs.c<br>
+++ b/fs/cifs/cifsfs.c<br>
@@ -993,13 +993,8 @@ static int cifs_oplock_thread(void *dummyarg)<br>
                        cFYI(1, (&quot;found oplock item to write out&quot;));<br>
                        tcon = oplock-&gt;tcon;<br>
                        inode = oplock-&gt;pinode;<br>
-                       /* can not grab inode sem here since it would<br>
-                               deadlock when oplock received on delete<br>
-                               since vfs_unlink holds the i_mutex across<br>
-                               the call */<br>
-                       /* mutex_lock(&amp;inode-&gt;i_mutex);*/<br>
-                       cifsi = CIFS_I(inode);<br>
-                       if (S_ISREG(inode-&gt;i_mode)) {<br>
+                       if (inode &amp;&amp; S_ISREG(inode-&gt;i_mode)) {<br>
+                               cifsi = CIFS_I(inode);<br>
 #ifdef CONFIG_CIFS_EXPERIMENTAL<br>
                                if (cifsi-&gt;clientCanCacheAll == 0)<br>
                                        break_lease(inode, FMODE_READ);<br>
@@ -1010,17 +1005,16 @@ static int cifs_oplock_thread(void *dummyarg)<br>
                                if (cifsi-&gt;clientCanCacheRead == 0) {<br>
                                        waitrc = filemap_fdatawait(<br>
                                                              inode-&gt;i_mapping);<br>
+                                       if (rc == 0)<br>
+                                               rc = waitrc;<br>
                                        invalidate_remote_inode(inode);<br>
                                }<br>
-                               if (rc == 0)<br>
-                                       rc = waitrc;<br>
-                       } else<br>
-                               rc = 0;<br>
-                       /* mutex_unlock(&amp;inode-&gt;i_mutex);*/<br>
-                       if (rc)<br>
-                               cifsi-&gt;write_behind_rc = rc;<br>
-                       cFYI(1, (&quot;Oplock flush inode %p rc %d&quot;,<br>
-                               inode, rc));<br>
+                               if (rc)<br>
+                                       cifsi-&gt;write_behind_rc = rc;<br>
+                               cFYI(1, (&quot;Oplock flush inode %p rc %d&quot;,<br>
+                                        inode, rc));<br>
+                       }<br>
+                       iput(inode);<br>
<br>
                        /*<br>
                         * releasing stale oplock after recent reconnect<br>
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c<br>
index 7221af9..3bf3a52 100644<br>
--- a/fs/cifs/misc.c<br>
+++ b/fs/cifs/misc.c<br>
@@ -502,6 +502,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv,<br>
        struct cifsInodeInfo *pCifsInode;<br>
        struct cifsFileInfo *netfile;<br>
        struct oplock_q_entry *oplock;<br>
+       struct inode *inode;<br>
<br>
        cFYI(1, (&quot;Checking for oplock break or dnotify response&quot;));<br>
        if ((pSMB-&gt;hdr.Command == SMB_COM_NT_TRANSACT) &amp;&amp;<br>
@@ -600,6 +601,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv,<br>
                                pCifsInode-&gt;clientCanCacheAll = false;<br>
                                if (pSMB-&gt;OplockLevel == 0)<br>
                                        pCifsInode-&gt;clientCanCacheRead = false;<br>
+                               inode = igrab(netfile-&gt;pInode);<br>
<br>
                                if (!oplock) {<br>
                                        cERROR(1, (&quot;Unable to allocate &quot;<br>
@@ -608,7 +610,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv,<br>
                                }<br>
<br>
                                oplock-&gt;tcon = tcon;<br>
-                               oplock-&gt;pinode = netfile-&gt;pInode;<br>
+                               oplock-&gt;pinode = inode;<br>
                                oplock-&gt;netfid = netfile-&gt;netfid;<br>
                                spin_lock(&amp;cifs_oplock_lock);<br>
                                list_add_tail(&amp;oplock-&gt;qhead,<br>
<font color="#888888">--<br>
1.6.0.6<br>
<br>
</font></blockquote></div><br><br clear="all"><br>-- <br>Thanks,<br><br>Steve<br>