aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-10-05 11:27:47 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-10-05 11:27:47 -0400
commit087f759a4155dcae08fb82841af2bafd231c7c9b (patch)
tree8515415dc3914e6c23258ee1634e897789e00c4b
parentbefad944e2312c18d855013ce154ca7d2b110ade (diff)
parent7af929d6d05ba5564139718e30d5bc96bdbc716a (diff)
Merge tag '4.19-rc6-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6
Steve writes: "SMB3 fixes four small SMB3 fixes: one for stable, the others to address a more recent regression" * tag '4.19-rc6-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6: smb3: fix lease break problem introduced by compounding cifs: only wake the thread for the very last PDU in a compound cifs: add a warning if we try to to dequeue a deleted mid smb2: fix missing files in root share directory listing
-rw-r--r--fs/cifs/cifsglob.h1
-rw-r--r--fs/cifs/connect.c13
-rw-r--r--fs/cifs/smb2ops.c2
-rw-r--r--fs/cifs/transport.c21
4 files changed, 31 insertions, 6 deletions
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,
1553 1553
1554/* Flags */ 1554/* Flags */
1555#define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */ 1555#define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */
1556#define MID_DELETED 2 /* Mid has been dequeued/deleted */
1556 1557
1557/* Types of response buffer returned from SendReceive2 */ 1558/* Types of response buffer returned from SendReceive2 */
1558#define CIFS_NO_BUFFER 0 /* Response buffer not returned */ 1559#define CIFS_NO_BUFFER 0 /* Response buffer not returned */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 7aa08dba4719..52d71b64c0c6 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -659,7 +659,15 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed)
659 mid->mid_state = MID_RESPONSE_RECEIVED; 659 mid->mid_state = MID_RESPONSE_RECEIVED;
660 else 660 else
661 mid->mid_state = MID_RESPONSE_MALFORMED; 661 mid->mid_state = MID_RESPONSE_MALFORMED;
662 list_del_init(&mid->qhead); 662 /*
663 * Trying to handle/dequeue a mid after the send_recv()
664 * function has finished processing it is a bug.
665 */
666 if (mid->mid_flags & MID_DELETED)
667 printk_once(KERN_WARNING
668 "trying to dequeue a deleted mid\n");
669 else
670 list_del_init(&mid->qhead);
663 spin_unlock(&GlobalMid_Lock); 671 spin_unlock(&GlobalMid_Lock);
664} 672}
665 673
@@ -938,8 +946,7 @@ next_pdu:
938 } else { 946 } else {
939 mids[0] = server->ops->find_mid(server, buf); 947 mids[0] = server->ops->find_mid(server, buf);
940 bufs[0] = buf; 948 bufs[0] = buf;
941 if (mids[0]) 949 num_mids = 1;
942 num_mids = 1;
943 950
944 if (!mids[0] || !mids[0]->receive) 951 if (!mids[0] || !mids[0]->receive)
945 length = standard_receive3(server, mids[0]); 952 length = standard_receive3(server, mids[0]);
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index d954ce36b473..89985a0a6819 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -1477,7 +1477,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
1477 } 1477 }
1478 1478
1479 srch_inf->entries_in_buffer = 0; 1479 srch_inf->entries_in_buffer = 0;
1480 srch_inf->index_of_last_entry = 0; 1480 srch_inf->index_of_last_entry = 2;
1481 1481
1482 rc = SMB2_query_directory(xid, tcon, fid->persistent_fid, 1482 rc = SMB2_query_directory(xid, tcon, fid->persistent_fid,
1483 fid->volatile_fid, 0, srch_inf); 1483 fid->volatile_fid, 0, srch_inf);
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 78f96fa3d7d9..b48f43963da6 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -142,7 +142,8 @@ void
142cifs_delete_mid(struct mid_q_entry *mid) 142cifs_delete_mid(struct mid_q_entry *mid)
143{ 143{
144 spin_lock(&GlobalMid_Lock); 144 spin_lock(&GlobalMid_Lock);
145 list_del(&mid->qhead); 145 list_del_init(&mid->qhead);
146 mid->mid_flags |= MID_DELETED;
146 spin_unlock(&GlobalMid_Lock); 147 spin_unlock(&GlobalMid_Lock);
147 148
148 DeleteMidQEntry(mid); 149 DeleteMidQEntry(mid);
@@ -772,6 +773,11 @@ cifs_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
772 return mid; 773 return mid;
773} 774}
774 775
776static void
777cifs_noop_callback(struct mid_q_entry *mid)
778{
779}
780
775int 781int
776compound_send_recv(const unsigned int xid, struct cifs_ses *ses, 782compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
777 const int flags, const int num_rqst, struct smb_rqst *rqst, 783 const int flags, const int num_rqst, struct smb_rqst *rqst,
@@ -826,8 +832,13 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
826 } 832 }
827 833
828 midQ[i]->mid_state = MID_REQUEST_SUBMITTED; 834 midQ[i]->mid_state = MID_REQUEST_SUBMITTED;
835 /*
836 * We don't invoke the callback compounds unless it is the last
837 * request.
838 */
839 if (i < num_rqst - 1)
840 midQ[i]->callback = cifs_noop_callback;
829 } 841 }
830
831 cifs_in_send_inc(ses->server); 842 cifs_in_send_inc(ses->server);
832 rc = smb_send_rqst(ses->server, num_rqst, rqst, flags); 843 rc = smb_send_rqst(ses->server, num_rqst, rqst, flags);
833 cifs_in_send_dec(ses->server); 844 cifs_in_send_dec(ses->server);
@@ -908,6 +919,12 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
908 midQ[i]->resp_buf = NULL; 919 midQ[i]->resp_buf = NULL;
909 } 920 }
910out: 921out:
922 /*
923 * This will dequeue all mids. After this it is important that the
924 * demultiplex_thread will not process any of these mids any futher.
925 * This is prevented above by using a noop callback that will not
926 * wake this thread except for the very last PDU.
927 */
911 for (i = 0; i < num_rqst; i++) 928 for (i = 0; i < num_rqst; i++)
912 cifs_delete_mid(midQ[i]); 929 cifs_delete_mid(midQ[i]);
913 add_credits(ses->server, credits, optype); 930 add_credits(ses->server, credits, optype);