Commit 087f759a authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

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
parents befad944 7af929d6
...@@ -1553,6 +1553,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param, ...@@ -1553,6 +1553,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
/* Flags */ /* Flags */
#define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */ #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 */ /* Types of response buffer returned from SendReceive2 */
#define CIFS_NO_BUFFER 0 /* Response buffer not returned */ #define CIFS_NO_BUFFER 0 /* Response buffer not returned */
......
...@@ -659,7 +659,15 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed) ...@@ -659,7 +659,15 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed)
mid->mid_state = MID_RESPONSE_RECEIVED; mid->mid_state = MID_RESPONSE_RECEIVED;
else else
mid->mid_state = MID_RESPONSE_MALFORMED; 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); spin_unlock(&GlobalMid_Lock);
} }
...@@ -938,8 +946,7 @@ cifs_demultiplex_thread(void *p) ...@@ -938,8 +946,7 @@ cifs_demultiplex_thread(void *p)
} else { } else {
mids[0] = server->ops->find_mid(server, buf); mids[0] = server->ops->find_mid(server, buf);
bufs[0] = buf; bufs[0] = buf;
if (mids[0]) num_mids = 1;
num_mids = 1;
if (!mids[0] || !mids[0]->receive) if (!mids[0] || !mids[0]->receive)
length = standard_receive3(server, mids[0]); length = standard_receive3(server, mids[0]);
......
...@@ -1477,7 +1477,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -1477,7 +1477,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
} }
srch_inf->entries_in_buffer = 0; srch_inf->entries_in_buffer = 0;
srch_inf->index_of_last_entry = 0; srch_inf->index_of_last_entry = 2;
rc = SMB2_query_directory(xid, tcon, fid->persistent_fid, rc = SMB2_query_directory(xid, tcon, fid->persistent_fid,
fid->volatile_fid, 0, srch_inf); fid->volatile_fid, 0, srch_inf);
......
...@@ -142,7 +142,8 @@ void ...@@ -142,7 +142,8 @@ void
cifs_delete_mid(struct mid_q_entry *mid) cifs_delete_mid(struct mid_q_entry *mid)
{ {
spin_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
list_del(&mid->qhead); list_del_init(&mid->qhead);
mid->mid_flags |= MID_DELETED;
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
DeleteMidQEntry(mid); DeleteMidQEntry(mid);
...@@ -772,6 +773,11 @@ cifs_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst) ...@@ -772,6 +773,11 @@ cifs_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
return mid; return mid;
} }
static void
cifs_noop_callback(struct mid_q_entry *mid)
{
}
int int
compound_send_recv(const unsigned int xid, struct cifs_ses *ses, compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
const int flags, const int num_rqst, struct smb_rqst *rqst, 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,8 +832,13 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
} }
midQ[i]->mid_state = MID_REQUEST_SUBMITTED; midQ[i]->mid_state = MID_REQUEST_SUBMITTED;
/*
* We don't invoke the callback compounds unless it is the last
* request.
*/
if (i < num_rqst - 1)
midQ[i]->callback = cifs_noop_callback;
} }
cifs_in_send_inc(ses->server); cifs_in_send_inc(ses->server);
rc = smb_send_rqst(ses->server, num_rqst, rqst, flags); rc = smb_send_rqst(ses->server, num_rqst, rqst, flags);
cifs_in_send_dec(ses->server); cifs_in_send_dec(ses->server);
...@@ -908,6 +919,12 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, ...@@ -908,6 +919,12 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
midQ[i]->resp_buf = NULL; midQ[i]->resp_buf = NULL;
} }
out: out:
/*
* This will dequeue all mids. After this it is important that the
* demultiplex_thread will not process any of these mids any futher.
* This is prevented above by using a noop callback that will not
* wake this thread except for the very last PDU.
*/
for (i = 0; i < num_rqst; i++) for (i = 0; i < num_rqst; i++)
cifs_delete_mid(midQ[i]); cifs_delete_mid(midQ[i]);
add_credits(ses->server, credits, optype); add_credits(ses->server, credits, optype);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment