cifs: add a warning if we try to to dequeue a deleted mid
authorRonnie Sahlberg <lsahlber@redhat.com>
Thu, 30 Aug 2018 00:12:59 +0000 (10:12 +1000)
committerSteve French <stfrench@microsoft.com>
Tue, 2 Oct 2018 23:12:31 +0000 (18:12 -0500)
cifs_delete_mid() is called once we are finished handling a mid and we
expect no more work done on this mid.

Needed to fix recent commit:
commit 730928c8f4be88e9d6a027a16b1e8fa9c59fc077
("cifs: update smb2_queryfs() to use compounding")

Add a warning if someone tries to dequeue a mid that has already been
flagged to be deleted.
Also change list_del() to list_del_init() so that if we have similar bugs
resurface in the future we will not oops.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/transport.c

index 0c9ab62..9dcaed0 100644 (file)
@@ -1553,6 +1553,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
 
 /* Flags */
 #define   MID_WAIT_CANCELLED    1 /* Cancelled while waiting for response */
+#define   MID_DELETED            2 /* Mid has been dequeued/deleted */
 
 /* Types of response buffer returned from SendReceive2 */
 #define   CIFS_NO_BUFFER        0    /* Response buffer not returned */
index 7aa08db..e9d64c9 100644 (file)
@@ -659,7 +659,15 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed)
                mid->mid_state = MID_RESPONSE_RECEIVED;
        else
                mid->mid_state = MID_RESPONSE_MALFORMED;
-       list_del_init(&mid->qhead);
+       /*
+        * Trying to handle/dequeue a mid after the send_recv()
+        * function has finished processing it is a bug.
+        */
+       if (mid->mid_flags & MID_DELETED)
+               printk_once(KERN_WARNING
+                           "trying to dequeue a deleted mid\n");
+       else
+               list_del_init(&mid->qhead);
        spin_unlock(&GlobalMid_Lock);
 }
 
index 78f96fa..9cc9a12 100644 (file)
@@ -142,7 +142,8 @@ void
 cifs_delete_mid(struct mid_q_entry *mid)
 {
        spin_lock(&GlobalMid_Lock);
-       list_del(&mid->qhead);
+       list_del_init(&mid->qhead);
+       mid->mid_flags |= MID_DELETED;
        spin_unlock(&GlobalMid_Lock);
 
        DeleteMidQEntry(mid);