diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2012-05-23 08:14:34 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-07-24 01:32:48 -0400 |
commit | a891f0f895f4a760fdb99636fab05e60597b8224 (patch) | |
tree | 0f911230af82d5b8cbbbbbb423b032ae8f5dc957 | |
parent | 316cf94a910f6f93d43cc574359d163ccae098a3 (diff) |
CIFS: Extend credit mechanism to process request type
Split all requests to echos, oplocks and others - each group uses
its own credit slot. This is indicated by new flags
CIFS_ECHO_OP and CIFS_OBREAK_OP
that are not used now for CIFS. This change is required to support
SMB2 protocol because of different processing of these commands.
Acked-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
-rw-r--r-- | fs/cifs/cifsglob.h | 16 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 4 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 21 | ||||
-rw-r--r-- | fs/cifs/smb1ops.c | 12 | ||||
-rw-r--r-- | fs/cifs/transport.c | 70 |
5 files changed, 74 insertions, 49 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 2aac4e5fb334..844b77c2bc9c 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -171,9 +171,11 @@ struct smb_version_operations { | |||
171 | /* check response: verify signature, map error */ | 171 | /* check response: verify signature, map error */ |
172 | int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *, | 172 | int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *, |
173 | bool); | 173 | bool); |
174 | void (*add_credits)(struct TCP_Server_Info *, const unsigned int); | 174 | void (*add_credits)(struct TCP_Server_Info *, const unsigned int, |
175 | const int); | ||
175 | void (*set_credits)(struct TCP_Server_Info *, const int); | 176 | void (*set_credits)(struct TCP_Server_Info *, const int); |
176 | int * (*get_credits_field)(struct TCP_Server_Info *); | 177 | int * (*get_credits_field)(struct TCP_Server_Info *, const int); |
178 | unsigned int (*get_credits)(struct mid_q_entry *); | ||
177 | __u64 (*get_next_mid)(struct TCP_Server_Info *); | 179 | __u64 (*get_next_mid)(struct TCP_Server_Info *); |
178 | /* data offset from read response message */ | 180 | /* data offset from read response message */ |
179 | unsigned int (*read_data_offset)(char *); | 181 | unsigned int (*read_data_offset)(char *); |
@@ -392,9 +394,10 @@ has_credits(struct TCP_Server_Info *server, int *credits) | |||
392 | } | 394 | } |
393 | 395 | ||
394 | static inline void | 396 | static inline void |
395 | add_credits(struct TCP_Server_Info *server, const unsigned int add) | 397 | add_credits(struct TCP_Server_Info *server, const unsigned int add, |
398 | const int optype) | ||
396 | { | 399 | { |
397 | server->ops->add_credits(server, add); | 400 | server->ops->add_credits(server, add, optype); |
398 | } | 401 | } |
399 | 402 | ||
400 | static inline void | 403 | static inline void |
@@ -957,6 +960,11 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param, | |||
957 | #define CIFS_LARGE_BUF_OP 0x020 /* large request buffer */ | 960 | #define CIFS_LARGE_BUF_OP 0x020 /* large request buffer */ |
958 | #define CIFS_NO_RESP 0x040 /* no response buffer required */ | 961 | #define CIFS_NO_RESP 0x040 /* no response buffer required */ |
959 | 962 | ||
963 | /* Type of request operation */ | ||
964 | #define CIFS_ECHO_OP 0x080 /* echo request */ | ||
965 | #define CIFS_OBREAK_OP 0x0100 /* oplock break request */ | ||
966 | #define CIFS_OP_MASK 0x0180 /* mask request type */ | ||
967 | |||
960 | /* Security Flags: indicate type of session setup needed */ | 968 | /* Security Flags: indicate type of session setup needed */ |
961 | #define CIFSSEC_MAY_SIGN 0x00001 | 969 | #define CIFSSEC_MAY_SIGN 0x00001 |
962 | #define CIFSSEC_MAY_NTLM 0x00002 | 970 | #define CIFSSEC_MAY_NTLM 0x00002 |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 613320c9a780..b37399491fa3 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -71,11 +71,11 @@ extern void DeleteMidQEntry(struct mid_q_entry *midEntry); | |||
71 | extern int cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov, | 71 | extern int cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov, |
72 | unsigned int nvec, mid_receive_t *receive, | 72 | unsigned int nvec, mid_receive_t *receive, |
73 | mid_callback_t *callback, void *cbdata, | 73 | mid_callback_t *callback, void *cbdata, |
74 | bool ignore_pend); | 74 | const int flags); |
75 | extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *, | 75 | extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *, |
76 | struct smb_hdr * /* input */ , | 76 | struct smb_hdr * /* input */ , |
77 | struct smb_hdr * /* out */ , | 77 | struct smb_hdr * /* out */ , |
78 | int * /* bytes returned */ , const int long_op); | 78 | int * /* bytes returned */ , const int); |
79 | extern int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses, | 79 | extern int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses, |
80 | char *in_buf, int flags); | 80 | char *in_buf, int flags); |
81 | extern int cifs_setup_request(struct cifs_ses *, struct kvec *, unsigned int, | 81 | extern int cifs_setup_request(struct cifs_ses *, struct kvec *, unsigned int, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 5659850f780a..92bbd8487ead 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -744,7 +744,7 @@ cifs_echo_callback(struct mid_q_entry *mid) | |||
744 | struct TCP_Server_Info *server = mid->callback_data; | 744 | struct TCP_Server_Info *server = mid->callback_data; |
745 | 745 | ||
746 | DeleteMidQEntry(mid); | 746 | DeleteMidQEntry(mid); |
747 | add_credits(server, 1); | 747 | add_credits(server, 1, CIFS_ECHO_OP); |
748 | } | 748 | } |
749 | 749 | ||
750 | int | 750 | int |
@@ -771,7 +771,7 @@ CIFSSMBEcho(struct TCP_Server_Info *server) | |||
771 | iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4; | 771 | iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4; |
772 | 772 | ||
773 | rc = cifs_call_async(server, &iov, 1, NULL, cifs_echo_callback, | 773 | rc = cifs_call_async(server, &iov, 1, NULL, cifs_echo_callback, |
774 | server, true); | 774 | server, CIFS_ASYNC_OP | CIFS_ECHO_OP); |
775 | if (rc) | 775 | if (rc) |
776 | cFYI(1, "Echo request failed: %d", rc); | 776 | cFYI(1, "Echo request failed: %d", rc); |
777 | 777 | ||
@@ -1589,7 +1589,7 @@ cifs_readv_callback(struct mid_q_entry *mid) | |||
1589 | 1589 | ||
1590 | queue_work(cifsiod_wq, &rdata->work); | 1590 | queue_work(cifsiod_wq, &rdata->work); |
1591 | DeleteMidQEntry(mid); | 1591 | DeleteMidQEntry(mid); |
1592 | add_credits(server, 1); | 1592 | add_credits(server, 1, 0); |
1593 | } | 1593 | } |
1594 | 1594 | ||
1595 | /* cifs_async_readv - send an async write, and set up mid to handle result */ | 1595 | /* cifs_async_readv - send an async write, and set up mid to handle result */ |
@@ -1645,7 +1645,7 @@ cifs_async_readv(struct cifs_readdata *rdata) | |||
1645 | kref_get(&rdata->refcount); | 1645 | kref_get(&rdata->refcount); |
1646 | rc = cifs_call_async(tcon->ses->server, rdata->iov, 1, | 1646 | rc = cifs_call_async(tcon->ses->server, rdata->iov, 1, |
1647 | cifs_readv_receive, cifs_readv_callback, | 1647 | cifs_readv_receive, cifs_readv_callback, |
1648 | rdata, false); | 1648 | rdata, 0); |
1649 | 1649 | ||
1650 | if (rc == 0) | 1650 | if (rc == 0) |
1651 | cifs_stats_inc(&tcon->num_reads); | 1651 | cifs_stats_inc(&tcon->num_reads); |
@@ -2036,7 +2036,7 @@ cifs_writev_callback(struct mid_q_entry *mid) | |||
2036 | 2036 | ||
2037 | queue_work(cifsiod_wq, &wdata->work); | 2037 | queue_work(cifsiod_wq, &wdata->work); |
2038 | DeleteMidQEntry(mid); | 2038 | DeleteMidQEntry(mid); |
2039 | add_credits(tcon->ses->server, 1); | 2039 | add_credits(tcon->ses->server, 1, 0); |
2040 | } | 2040 | } |
2041 | 2041 | ||
2042 | /* cifs_async_writev - send an async write, and set up mid to handle result */ | 2042 | /* cifs_async_writev - send an async write, and set up mid to handle result */ |
@@ -2118,7 +2118,7 @@ cifs_async_writev(struct cifs_writedata *wdata) | |||
2118 | 2118 | ||
2119 | kref_get(&wdata->refcount); | 2119 | kref_get(&wdata->refcount); |
2120 | rc = cifs_call_async(tcon->ses->server, iov, wdata->nr_pages + 1, | 2120 | rc = cifs_call_async(tcon->ses->server, iov, wdata->nr_pages + 1, |
2121 | NULL, cifs_writev_callback, wdata, false); | 2121 | NULL, cifs_writev_callback, wdata, 0); |
2122 | 2122 | ||
2123 | if (rc == 0) | 2123 | if (rc == 0) |
2124 | cifs_stats_inc(&tcon->num_writes); | 2124 | cifs_stats_inc(&tcon->num_writes); |
@@ -2296,7 +2296,7 @@ CIFSSMBLock(const int xid, struct cifs_tcon *tcon, | |||
2296 | LOCK_REQ *pSMB = NULL; | 2296 | LOCK_REQ *pSMB = NULL; |
2297 | /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */ | 2297 | /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */ |
2298 | int bytes_returned; | 2298 | int bytes_returned; |
2299 | int timeout = 0; | 2299 | int flags = 0; |
2300 | __u16 count; | 2300 | __u16 count; |
2301 | 2301 | ||
2302 | cFYI(1, "CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock); | 2302 | cFYI(1, "CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock); |
@@ -2306,10 +2306,11 @@ CIFSSMBLock(const int xid, struct cifs_tcon *tcon, | |||
2306 | return rc; | 2306 | return rc; |
2307 | 2307 | ||
2308 | if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) { | 2308 | if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) { |
2309 | timeout = CIFS_ASYNC_OP; /* no response expected */ | 2309 | /* no response expected */ |
2310 | flags = CIFS_ASYNC_OP | CIFS_OBREAK_OP; | ||
2310 | pSMB->Timeout = 0; | 2311 | pSMB->Timeout = 0; |
2311 | } else if (waitFlag) { | 2312 | } else if (waitFlag) { |
2312 | timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */ | 2313 | flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */ |
2313 | pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */ | 2314 | pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */ |
2314 | } else { | 2315 | } else { |
2315 | pSMB->Timeout = 0; | 2316 | pSMB->Timeout = 0; |
@@ -2342,7 +2343,7 @@ CIFSSMBLock(const int xid, struct cifs_tcon *tcon, | |||
2342 | (struct smb_hdr *) pSMB, &bytes_returned); | 2343 | (struct smb_hdr *) pSMB, &bytes_returned); |
2343 | cifs_small_buf_release(pSMB); | 2344 | cifs_small_buf_release(pSMB); |
2344 | } else { | 2345 | } else { |
2345 | rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, timeout); | 2346 | rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags); |
2346 | /* SMB buffer freed by function above */ | 2347 | /* SMB buffer freed by function above */ |
2347 | } | 2348 | } |
2348 | cifs_stats_inc(&tcon->num_locks); | 2349 | cifs_stats_inc(&tcon->num_locks); |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 28359e789fff..f4f839459e90 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
@@ -101,7 +101,8 @@ cifs_find_mid(struct TCP_Server_Info *server, char *buffer) | |||
101 | } | 101 | } |
102 | 102 | ||
103 | static void | 103 | static void |
104 | cifs_add_credits(struct TCP_Server_Info *server, const unsigned int add) | 104 | cifs_add_credits(struct TCP_Server_Info *server, const unsigned int add, |
105 | const int optype) | ||
105 | { | 106 | { |
106 | spin_lock(&server->req_lock); | 107 | spin_lock(&server->req_lock); |
107 | server->credits += add; | 108 | server->credits += add; |
@@ -120,11 +121,17 @@ cifs_set_credits(struct TCP_Server_Info *server, const int val) | |||
120 | } | 121 | } |
121 | 122 | ||
122 | static int * | 123 | static int * |
123 | cifs_get_credits_field(struct TCP_Server_Info *server) | 124 | cifs_get_credits_field(struct TCP_Server_Info *server, const int optype) |
124 | { | 125 | { |
125 | return &server->credits; | 126 | return &server->credits; |
126 | } | 127 | } |
127 | 128 | ||
129 | static unsigned int | ||
130 | cifs_get_credits(struct mid_q_entry *mid) | ||
131 | { | ||
132 | return 1; | ||
133 | } | ||
134 | |||
128 | /* | 135 | /* |
129 | * Find a free multiplex id (SMB mid). Otherwise there could be | 136 | * Find a free multiplex id (SMB mid). Otherwise there could be |
130 | * mid collisions which might cause problems, demultiplexing the | 137 | * mid collisions which might cause problems, demultiplexing the |
@@ -390,6 +397,7 @@ struct smb_version_operations smb1_operations = { | |||
390 | .add_credits = cifs_add_credits, | 397 | .add_credits = cifs_add_credits, |
391 | .set_credits = cifs_set_credits, | 398 | .set_credits = cifs_set_credits, |
392 | .get_credits_field = cifs_get_credits_field, | 399 | .get_credits_field = cifs_get_credits_field, |
400 | .get_credits = cifs_get_credits, | ||
393 | .get_next_mid = cifs_get_next_mid, | 401 | .get_next_mid = cifs_get_next_mid, |
394 | .read_data_offset = cifs_read_data_offset, | 402 | .read_data_offset = cifs_read_data_offset, |
395 | .read_data_length = cifs_read_data_length, | 403 | .read_data_length = cifs_read_data_length, |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 3e6ffe355384..904702db2526 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -250,13 +250,13 @@ smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer, | |||
250 | } | 250 | } |
251 | 251 | ||
252 | static int | 252 | static int |
253 | wait_for_free_credits(struct TCP_Server_Info *server, const int optype, | 253 | wait_for_free_credits(struct TCP_Server_Info *server, const int timeout, |
254 | int *credits) | 254 | int *credits) |
255 | { | 255 | { |
256 | int rc; | 256 | int rc; |
257 | 257 | ||
258 | spin_lock(&server->req_lock); | 258 | spin_lock(&server->req_lock); |
259 | if (optype == CIFS_ASYNC_OP) { | 259 | if (timeout == CIFS_ASYNC_OP) { |
260 | /* oplock breaks must not be held up */ | 260 | /* oplock breaks must not be held up */ |
261 | server->in_flight++; | 261 | server->in_flight++; |
262 | *credits -= 1; | 262 | *credits -= 1; |
@@ -286,7 +286,7 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int optype, | |||
286 | */ | 286 | */ |
287 | 287 | ||
288 | /* update # of requests on the wire to server */ | 288 | /* update # of requests on the wire to server */ |
289 | if (optype != CIFS_BLOCKING_OP) { | 289 | if (timeout != CIFS_BLOCKING_OP) { |
290 | *credits -= 1; | 290 | *credits -= 1; |
291 | server->in_flight++; | 291 | server->in_flight++; |
292 | } | 292 | } |
@@ -298,10 +298,11 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int optype, | |||
298 | } | 298 | } |
299 | 299 | ||
300 | static int | 300 | static int |
301 | wait_for_free_request(struct TCP_Server_Info *server, const int optype) | 301 | wait_for_free_request(struct TCP_Server_Info *server, const int timeout, |
302 | const int optype) | ||
302 | { | 303 | { |
303 | return wait_for_free_credits(server, optype, | 304 | return wait_for_free_credits(server, timeout, |
304 | server->ops->get_credits_field(server)); | 305 | server->ops->get_credits_field(server, optype)); |
305 | } | 306 | } |
306 | 307 | ||
307 | static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf, | 308 | static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf, |
@@ -378,12 +379,15 @@ cifs_setup_async_request(struct TCP_Server_Info *server, struct kvec *iov, | |||
378 | int | 379 | int |
379 | cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov, | 380 | cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov, |
380 | unsigned int nvec, mid_receive_t *receive, | 381 | unsigned int nvec, mid_receive_t *receive, |
381 | mid_callback_t *callback, void *cbdata, bool ignore_pend) | 382 | mid_callback_t *callback, void *cbdata, const int flags) |
382 | { | 383 | { |
383 | int rc; | 384 | int rc, timeout, optype; |
384 | struct mid_q_entry *mid; | 385 | struct mid_q_entry *mid; |
385 | 386 | ||
386 | rc = wait_for_free_request(server, ignore_pend ? CIFS_ASYNC_OP : 0); | 387 | timeout = flags & CIFS_TIMEOUT_MASK; |
388 | optype = flags & CIFS_OP_MASK; | ||
389 | |||
390 | rc = wait_for_free_request(server, timeout, optype); | ||
387 | if (rc) | 391 | if (rc) |
388 | return rc; | 392 | return rc; |
389 | 393 | ||
@@ -391,7 +395,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov, | |||
391 | rc = cifs_setup_async_request(server, iov, nvec, &mid); | 395 | rc = cifs_setup_async_request(server, iov, nvec, &mid); |
392 | if (rc) { | 396 | if (rc) { |
393 | mutex_unlock(&server->srv_mutex); | 397 | mutex_unlock(&server->srv_mutex); |
394 | add_credits(server, 1); | 398 | add_credits(server, 1, optype); |
395 | wake_up(&server->request_q); | 399 | wake_up(&server->request_q); |
396 | return rc; | 400 | return rc; |
397 | } | 401 | } |
@@ -417,7 +421,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov, | |||
417 | return 0; | 421 | return 0; |
418 | 422 | ||
419 | delete_mid(mid); | 423 | delete_mid(mid); |
420 | add_credits(server, 1); | 424 | add_credits(server, 1, optype); |
421 | wake_up(&server->request_q); | 425 | wake_up(&server->request_q); |
422 | return rc; | 426 | return rc; |
423 | } | 427 | } |
@@ -533,17 +537,19 @@ cifs_setup_request(struct cifs_ses *ses, struct kvec *iov, | |||
533 | 537 | ||
534 | int | 538 | int |
535 | SendReceive2(const unsigned int xid, struct cifs_ses *ses, | 539 | SendReceive2(const unsigned int xid, struct cifs_ses *ses, |
536 | struct kvec *iov, int n_vec, int *pRespBufType /* ret */, | 540 | struct kvec *iov, int n_vec, int *resp_buf_type /* ret */, |
537 | const int flags) | 541 | const int flags) |
538 | { | 542 | { |
539 | int rc = 0; | 543 | int rc = 0; |
540 | int long_op; | 544 | int timeout, optype; |
541 | struct mid_q_entry *midQ; | 545 | struct mid_q_entry *midQ; |
542 | char *buf = iov[0].iov_base; | 546 | char *buf = iov[0].iov_base; |
547 | unsigned int credits = 1; | ||
543 | 548 | ||
544 | long_op = flags & CIFS_TIMEOUT_MASK; | 549 | timeout = flags & CIFS_TIMEOUT_MASK; |
550 | optype = flags & CIFS_OP_MASK; | ||
545 | 551 | ||
546 | *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ | 552 | *resp_buf_type = CIFS_NO_BUFFER; /* no response buf yet */ |
547 | 553 | ||
548 | if ((ses == NULL) || (ses->server == NULL)) { | 554 | if ((ses == NULL) || (ses->server == NULL)) { |
549 | cifs_small_buf_release(buf); | 555 | cifs_small_buf_release(buf); |
@@ -562,7 +568,7 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, | |||
562 | * use ses->maxReq. | 568 | * use ses->maxReq. |
563 | */ | 569 | */ |
564 | 570 | ||
565 | rc = wait_for_free_request(ses->server, long_op); | 571 | rc = wait_for_free_request(ses->server, timeout, optype); |
566 | if (rc) { | 572 | if (rc) { |
567 | cifs_small_buf_release(buf); | 573 | cifs_small_buf_release(buf); |
568 | return rc; | 574 | return rc; |
@@ -581,7 +587,7 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, | |||
581 | mutex_unlock(&ses->server->srv_mutex); | 587 | mutex_unlock(&ses->server->srv_mutex); |
582 | cifs_small_buf_release(buf); | 588 | cifs_small_buf_release(buf); |
583 | /* Update # of requests on wire to server */ | 589 | /* Update # of requests on wire to server */ |
584 | add_credits(ses->server, 1); | 590 | add_credits(ses->server, 1, optype); |
585 | return rc; | 591 | return rc; |
586 | } | 592 | } |
587 | 593 | ||
@@ -598,7 +604,7 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, | |||
598 | goto out; | 604 | goto out; |
599 | } | 605 | } |
600 | 606 | ||
601 | if (long_op == CIFS_ASYNC_OP) { | 607 | if (timeout == CIFS_ASYNC_OP) { |
602 | cifs_small_buf_release(buf); | 608 | cifs_small_buf_release(buf); |
603 | goto out; | 609 | goto out; |
604 | } | 610 | } |
@@ -611,7 +617,7 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, | |||
611 | midQ->callback = DeleteMidQEntry; | 617 | midQ->callback = DeleteMidQEntry; |
612 | spin_unlock(&GlobalMid_Lock); | 618 | spin_unlock(&GlobalMid_Lock); |
613 | cifs_small_buf_release(buf); | 619 | cifs_small_buf_release(buf); |
614 | add_credits(ses->server, 1); | 620 | add_credits(ses->server, 1, optype); |
615 | return rc; | 621 | return rc; |
616 | } | 622 | } |
617 | spin_unlock(&GlobalMid_Lock); | 623 | spin_unlock(&GlobalMid_Lock); |
@@ -621,7 +627,7 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, | |||
621 | 627 | ||
622 | rc = cifs_sync_mid_result(midQ, ses->server); | 628 | rc = cifs_sync_mid_result(midQ, ses->server); |
623 | if (rc != 0) { | 629 | if (rc != 0) { |
624 | add_credits(ses->server, 1); | 630 | add_credits(ses->server, 1, optype); |
625 | return rc; | 631 | return rc; |
626 | } | 632 | } |
627 | 633 | ||
@@ -635,9 +641,11 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, | |||
635 | iov[0].iov_base = buf; | 641 | iov[0].iov_base = buf; |
636 | iov[0].iov_len = get_rfc1002_length(buf) + 4; | 642 | iov[0].iov_len = get_rfc1002_length(buf) + 4; |
637 | if (midQ->large_buf) | 643 | if (midQ->large_buf) |
638 | *pRespBufType = CIFS_LARGE_BUFFER; | 644 | *resp_buf_type = CIFS_LARGE_BUFFER; |
639 | else | 645 | else |
640 | *pRespBufType = CIFS_SMALL_BUFFER; | 646 | *resp_buf_type = CIFS_SMALL_BUFFER; |
647 | |||
648 | credits = ses->server->ops->get_credits(midQ); | ||
641 | 649 | ||
642 | rc = ses->server->ops->check_receive(midQ, ses->server, | 650 | rc = ses->server->ops->check_receive(midQ, ses->server, |
643 | flags & CIFS_LOG_ERROR); | 651 | flags & CIFS_LOG_ERROR); |
@@ -647,7 +655,7 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, | |||
647 | midQ->resp_buf = NULL; | 655 | midQ->resp_buf = NULL; |
648 | out: | 656 | out: |
649 | delete_mid(midQ); | 657 | delete_mid(midQ); |
650 | add_credits(ses->server, 1); | 658 | add_credits(ses->server, credits, optype); |
651 | 659 | ||
652 | return rc; | 660 | return rc; |
653 | } | 661 | } |
@@ -655,7 +663,7 @@ out: | |||
655 | int | 663 | int |
656 | SendReceive(const unsigned int xid, struct cifs_ses *ses, | 664 | SendReceive(const unsigned int xid, struct cifs_ses *ses, |
657 | struct smb_hdr *in_buf, struct smb_hdr *out_buf, | 665 | struct smb_hdr *in_buf, struct smb_hdr *out_buf, |
658 | int *pbytes_returned, const int long_op) | 666 | int *pbytes_returned, const int timeout) |
659 | { | 667 | { |
660 | int rc = 0; | 668 | int rc = 0; |
661 | struct mid_q_entry *midQ; | 669 | struct mid_q_entry *midQ; |
@@ -683,7 +691,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, | |||
683 | return -EIO; | 691 | return -EIO; |
684 | } | 692 | } |
685 | 693 | ||
686 | rc = wait_for_free_request(ses->server, long_op); | 694 | rc = wait_for_free_request(ses->server, timeout, 0); |
687 | if (rc) | 695 | if (rc) |
688 | return rc; | 696 | return rc; |
689 | 697 | ||
@@ -697,7 +705,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, | |||
697 | if (rc) { | 705 | if (rc) { |
698 | mutex_unlock(&ses->server->srv_mutex); | 706 | mutex_unlock(&ses->server->srv_mutex); |
699 | /* Update # of requests on wire to server */ | 707 | /* Update # of requests on wire to server */ |
700 | add_credits(ses->server, 1); | 708 | add_credits(ses->server, 1, 0); |
701 | return rc; | 709 | return rc; |
702 | } | 710 | } |
703 | 711 | ||
@@ -718,7 +726,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, | |||
718 | if (rc < 0) | 726 | if (rc < 0) |
719 | goto out; | 727 | goto out; |
720 | 728 | ||
721 | if (long_op == CIFS_ASYNC_OP) | 729 | if (timeout == CIFS_ASYNC_OP) |
722 | goto out; | 730 | goto out; |
723 | 731 | ||
724 | rc = wait_for_response(ses->server, midQ); | 732 | rc = wait_for_response(ses->server, midQ); |
@@ -729,7 +737,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, | |||
729 | /* no longer considered to be "in-flight" */ | 737 | /* no longer considered to be "in-flight" */ |
730 | midQ->callback = DeleteMidQEntry; | 738 | midQ->callback = DeleteMidQEntry; |
731 | spin_unlock(&GlobalMid_Lock); | 739 | spin_unlock(&GlobalMid_Lock); |
732 | add_credits(ses->server, 1); | 740 | add_credits(ses->server, 1, 0); |
733 | return rc; | 741 | return rc; |
734 | } | 742 | } |
735 | spin_unlock(&GlobalMid_Lock); | 743 | spin_unlock(&GlobalMid_Lock); |
@@ -737,7 +745,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, | |||
737 | 745 | ||
738 | rc = cifs_sync_mid_result(midQ, ses->server); | 746 | rc = cifs_sync_mid_result(midQ, ses->server); |
739 | if (rc != 0) { | 747 | if (rc != 0) { |
740 | add_credits(ses->server, 1); | 748 | add_credits(ses->server, 1, 0); |
741 | return rc; | 749 | return rc; |
742 | } | 750 | } |
743 | 751 | ||
@@ -753,7 +761,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, | |||
753 | rc = cifs_check_receive(midQ, ses->server, 0); | 761 | rc = cifs_check_receive(midQ, ses->server, 0); |
754 | out: | 762 | out: |
755 | delete_mid(midQ); | 763 | delete_mid(midQ); |
756 | add_credits(ses->server, 1); | 764 | add_credits(ses->server, 1, 0); |
757 | 765 | ||
758 | return rc; | 766 | return rc; |
759 | } | 767 | } |
@@ -818,7 +826,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, | |||
818 | return -EIO; | 826 | return -EIO; |
819 | } | 827 | } |
820 | 828 | ||
821 | rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP); | 829 | rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP, 0); |
822 | if (rc) | 830 | if (rc) |
823 | return rc; | 831 | return rc; |
824 | 832 | ||