diff mbox series

[1/2] cifs: add a warning if we try to to dequeue a deleted mid

Message ID 20180829022141.3216-2-lsahlber@redhat.com (mailing list archive)
State New, archived
Headers show
Series extra debugging/logging for mid deletion | expand

Commit Message

Ronnie Sahlberg Aug. 29, 2018, 2:21 a.m. UTC
cifs_delete_mid() is called once we are finished handling a mid and we
expect no more work done on this mid.

Add a warning if someone tries to dequeue a mid that has already been
flagged to be deleted.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/cifsglob.h  |  1 +
 fs/cifs/connect.c   | 10 +++++++++-
 fs/cifs/transport.c |  1 +
 3 files changed, 11 insertions(+), 1 deletion(-)

Comments

Steve French Aug. 29, 2018, 9:24 p.m. UTC | #1
tentatively merged into cifs-2.6.git for-next

Let me know if you see any patches of yours that need to be fixed up
(or any missing patches)
On Tue, Aug 28, 2018 at 9:21 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
>
> cifs_delete_mid() is called once we are finished handling a mid and we
> expect no more work done on this mid.
>
> Add a warning if someone tries to dequeue a mid that has already been
> flagged to be deleted.
>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
>  fs/cifs/cifsglob.h  |  1 +
>  fs/cifs/connect.c   | 10 +++++++++-
>  fs/cifs/transport.c |  1 +
>  3 files changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> index 0c9ab62c3df4..9dcaed031843 100644
> --- a/fs/cifs/cifsglob.h
> +++ b/fs/cifs/cifsglob.h
> @@ -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 */
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index c832a8a1970a..c67ff7d2b201 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -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);
>  }
>
> diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
> index 78f96fa3d7d9..9e3a1e87ae1c 100644
> --- a/fs/cifs/transport.c
> +++ b/fs/cifs/transport.c
> @@ -143,6 +143,7 @@ cifs_delete_mid(struct mid_q_entry *mid)
>  {
>         spin_lock(&GlobalMid_Lock);
>         list_del(&mid->qhead);
> +       mid->mid_flags |= MID_DELETED;
>         spin_unlock(&GlobalMid_Lock);
>
>         DeleteMidQEntry(mid);
> --
> 2.13.3
>
Pavel Shilovsky Aug. 29, 2018, 10:35 p.m. UTC | #2
--
Best regards,
Pavel Shilovsky

вт, 28 авг. 2018 г. в 19:22, Ronnie Sahlberg <lsahlber@redhat.com>:
>
> cifs_delete_mid() is called once we are finished handling a mid and we
> expect no more work done on this mid.
>
> Add a warning if someone tries to dequeue a mid that has already been
> flagged to be deleted.
>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
>  fs/cifs/cifsglob.h  |  1 +
>  fs/cifs/connect.c   | 10 +++++++++-
>  fs/cifs/transport.c |  1 +
>  3 files changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> index 0c9ab62c3df4..9dcaed031843 100644
> --- a/fs/cifs/cifsglob.h
> +++ b/fs/cifs/cifsglob.h
> @@ -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 */
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index c832a8a1970a..c67ff7d2b201 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -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);
>  }
>
> diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
> index 78f96fa3d7d9..9e3a1e87ae1c 100644
> --- a/fs/cifs/transport.c
> +++ b/fs/cifs/transport.c
> @@ -143,6 +143,7 @@ cifs_delete_mid(struct mid_q_entry *mid)
>  {
>         spin_lock(&GlobalMid_Lock);
>         list_del(&mid->qhead);

Shouldn't we replace list_del to list_del_init to avoid a possibility
of corruption here? A kernel warning you added above will let us know
about the problem anyway.

> +       mid->mid_flags |= MID_DELETED;
>         spin_unlock(&GlobalMid_Lock);
>
>         DeleteMidQEntry(mid);
> --
> 2.13.3
>
diff mbox series

Patch

diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 0c9ab62c3df4..9dcaed031843 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -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 */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index c832a8a1970a..c67ff7d2b201 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -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);
 }
 
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 78f96fa3d7d9..9e3a1e87ae1c 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -143,6 +143,7 @@  cifs_delete_mid(struct mid_q_entry *mid)
 {
 	spin_lock(&GlobalMid_Lock);
 	list_del(&mid->qhead);
+	mid->mid_flags |= MID_DELETED;
 	spin_unlock(&GlobalMid_Lock);
 
 	DeleteMidQEntry(mid);