Commit ddc8cf8f authored by Jeff Layton's avatar Jeff Layton Committed by Steve French

cifs: move locked sections out of DeleteMidQEntry and AllocMidQEntry

In later patches, we're going to need to have finer-grained control
over the addition and removal of these structs from the pending_mid_q
and we'll need to be able to call the destructor while holding the
spinlock. Move the locked sections out of both routines and into
the callers. Fix up current callers of DeleteMidQEntry to call a new
routine that dequeues the entry and then destroys it.
Reviewed-by: default avatarSuresh Jayaraman <sjayaraman@suse.de>
Reviewed-by: default avatarPavel Shilovsky <piastryyy@gmail.com>
Signed-off-by: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent 8097531a
...@@ -63,9 +63,6 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server) ...@@ -63,9 +63,6 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
atomic_inc(&midCount); atomic_inc(&midCount);
temp->midState = MID_REQUEST_ALLOCATED; temp->midState = MID_REQUEST_ALLOCATED;
spin_lock(&GlobalMid_Lock);
list_add_tail(&temp->qhead, &server->pending_mid_q);
spin_unlock(&GlobalMid_Lock);
return temp; return temp;
} }
...@@ -75,10 +72,7 @@ DeleteMidQEntry(struct mid_q_entry *midEntry) ...@@ -75,10 +72,7 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
#ifdef CONFIG_CIFS_STATS2 #ifdef CONFIG_CIFS_STATS2
unsigned long now; unsigned long now;
#endif #endif
spin_lock(&GlobalMid_Lock);
midEntry->midState = MID_FREE; midEntry->midState = MID_FREE;
list_del(&midEntry->qhead);
spin_unlock(&GlobalMid_Lock);
atomic_dec(&midCount); atomic_dec(&midCount);
if (midEntry->largeBuf) if (midEntry->largeBuf)
cifs_buf_release(midEntry->resp_buf); cifs_buf_release(midEntry->resp_buf);
...@@ -103,6 +97,16 @@ DeleteMidQEntry(struct mid_q_entry *midEntry) ...@@ -103,6 +97,16 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
mempool_free(midEntry, cifs_mid_poolp); mempool_free(midEntry, cifs_mid_poolp);
} }
static void
delete_mid(struct mid_q_entry *mid)
{
spin_lock(&GlobalMid_Lock);
list_del(&mid->qhead);
spin_unlock(&GlobalMid_Lock);
DeleteMidQEntry(mid);
}
static int static int
smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec) smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
{ {
...@@ -308,6 +312,9 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf, ...@@ -308,6 +312,9 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
*ppmidQ = AllocMidQEntry(in_buf, ses->server); *ppmidQ = AllocMidQEntry(in_buf, ses->server);
if (*ppmidQ == NULL) if (*ppmidQ == NULL)
return -ENOMEM; return -ENOMEM;
spin_lock(&GlobalMid_Lock);
list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q);
spin_unlock(&GlobalMid_Lock);
return 0; return 0;
} }
...@@ -508,7 +515,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -508,7 +515,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
} }
} }
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
DeleteMidQEntry(midQ); delete_mid(midQ);
/* Update # of requests on wire to server */ /* Update # of requests on wire to server */
atomic_dec(&ses->server->inFlight); atomic_dec(&ses->server->inFlight);
wake_up(&ses->server->request_q); wake_up(&ses->server->request_q);
...@@ -564,14 +571,14 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -564,14 +571,14 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
if ((flags & CIFS_NO_RESP) == 0) if ((flags & CIFS_NO_RESP) == 0)
midQ->resp_buf = NULL; /* mark it so buf will midQ->resp_buf = NULL; /* mark it so buf will
not be freed by not be freed by
DeleteMidQEntry */ delete_mid */
} else { } else {
rc = -EIO; rc = -EIO;
cFYI(1, "Bad MID state?"); cFYI(1, "Bad MID state?");
} }
out: out:
DeleteMidQEntry(midQ); delete_mid(midQ);
atomic_dec(&ses->server->inFlight); atomic_dec(&ses->server->inFlight);
wake_up(&ses->server->request_q); wake_up(&ses->server->request_q);
...@@ -699,7 +706,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -699,7 +706,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
} }
} }
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
DeleteMidQEntry(midQ); delete_mid(midQ);
/* Update # of requests on wire to server */ /* Update # of requests on wire to server */
atomic_dec(&ses->server->inFlight); atomic_dec(&ses->server->inFlight);
wake_up(&ses->server->request_q); wake_up(&ses->server->request_q);
...@@ -755,7 +762,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -755,7 +762,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
} }
out: out:
DeleteMidQEntry(midQ); delete_mid(midQ);
atomic_dec(&ses->server->inFlight); atomic_dec(&ses->server->inFlight);
wake_up(&ses->server->request_q); wake_up(&ses->server->request_q);
...@@ -863,7 +870,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, ...@@ -863,7 +870,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
if (rc) { if (rc) {
DeleteMidQEntry(midQ); delete_mid(midQ);
mutex_unlock(&ses->server->srv_mutex); mutex_unlock(&ses->server->srv_mutex);
return rc; return rc;
} }
...@@ -880,7 +887,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, ...@@ -880,7 +887,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
mutex_unlock(&ses->server->srv_mutex); mutex_unlock(&ses->server->srv_mutex);
if (rc < 0) { if (rc < 0) {
DeleteMidQEntry(midQ); delete_mid(midQ);
return rc; return rc;
} }
...@@ -902,7 +909,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, ...@@ -902,7 +909,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
rc = send_nt_cancel(tcon, in_buf, midQ); rc = send_nt_cancel(tcon, in_buf, midQ);
if (rc) { if (rc) {
DeleteMidQEntry(midQ); delete_mid(midQ);
return rc; return rc;
} }
} else { } else {
...@@ -914,7 +921,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, ...@@ -914,7 +921,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
/* If we get -ENOLCK back the lock may have /* If we get -ENOLCK back the lock may have
already been removed. Don't exit in this case. */ already been removed. Don't exit in this case. */
if (rc && rc != -ENOLCK) { if (rc && rc != -ENOLCK) {
DeleteMidQEntry(midQ); delete_mid(midQ);
return rc; return rc;
} }
} }
...@@ -951,7 +958,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, ...@@ -951,7 +958,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
} }
} }
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
DeleteMidQEntry(midQ); delete_mid(midQ);
return rc; return rc;
} }
...@@ -1001,7 +1008,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, ...@@ -1001,7 +1008,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
out: out:
DeleteMidQEntry(midQ); delete_mid(midQ);
if (rstart && rc == -EACCES) if (rstart && rc == -EACCES)
return -ERESTARTSYS; return -ERESTARTSYS;
return rc; return rc;
......
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