diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-10-05 11:27:47 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-10-05 11:27:47 -0400 |
commit | 087f759a4155dcae08fb82841af2bafd231c7c9b (patch) | |
tree | 8515415dc3914e6c23258ee1634e897789e00c4b | |
parent | befad944e2312c18d855013ce154ca7d2b110ade (diff) | |
parent | 7af929d6d05ba5564139718e30d5bc96bdbc716a (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.h | 1 | ||||
-rw-r--r-- | fs/cifs/connect.c | 13 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 2 | ||||
-rw-r--r-- | fs/cifs/transport.c | 21 |
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 | |||
142 | cifs_delete_mid(struct mid_q_entry *mid) | 142 | cifs_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 | ||
776 | static void | ||
777 | cifs_noop_callback(struct mid_q_entry *mid) | ||
778 | { | ||
779 | } | ||
780 | |||
775 | int | 781 | int |
776 | compound_send_recv(const unsigned int xid, struct cifs_ses *ses, | 782 | compound_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 | } |
910 | out: | 921 | out: |
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); |