aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsglob.h23
-rw-r--r--fs/cifs/cifsproto.h5
-rw-r--r--fs/cifs/cifssmb.c5
-rw-r--r--fs/cifs/connect.c6
-rw-r--r--fs/cifs/transport.c5
5 files changed, 34 insertions, 10 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index a73dd1d5e7ef..d153d0b89d39 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -656,8 +656,24 @@ static inline void cifs_stats_bytes_read(struct cifs_tcon *tcon,
656struct mid_q_entry; 656struct mid_q_entry;
657 657
658/* 658/*
659 * This is the prototype for the mid callback function. When creating one, 659 * This is the prototype for the mid receive function. This function is for
660 * take special care to avoid deadlocks. Things to bear in mind: 660 * receiving the rest of the SMB frame, starting with the WordCount (which is
661 * just after the MID in struct smb_hdr). Note:
662 *
663 * - This will be called by cifsd, with no locks held.
664 * - The mid will still be on the pending_mid_q.
665 * - mid->resp_buf will point to the current buffer.
666 *
667 * Returns zero on a successful receive, or an error. The receive state in
668 * the TCP_Server_Info will also be updated.
669 */
670typedef int (mid_receive_t)(struct TCP_Server_Info *server,
671 struct mid_q_entry *mid);
672
673/*
674 * This is the prototype for the mid callback function. This is called once the
675 * mid has been received off of the socket. When creating one, take special
676 * care to avoid deadlocks. Things to bear in mind:
661 * 677 *
662 * - it will be called by cifsd, with no locks held 678 * - it will be called by cifsd, with no locks held
663 * - the mid will be removed from any lists 679 * - the mid will be removed from any lists
@@ -675,9 +691,10 @@ struct mid_q_entry {
675 unsigned long when_sent; /* time when smb send finished */ 691 unsigned long when_sent; /* time when smb send finished */
676 unsigned long when_received; /* when demux complete (taken off wire) */ 692 unsigned long when_received; /* when demux complete (taken off wire) */
677#endif 693#endif
694 mid_receive_t *receive; /* call receive callback */
678 mid_callback_t *callback; /* call completion callback */ 695 mid_callback_t *callback; /* call completion callback */
679 void *callback_data; /* general purpose pointer for callback */ 696 void *callback_data; /* general purpose pointer for callback */
680 struct smb_hdr *resp_buf; /* response buffer */ 697 struct smb_hdr *resp_buf; /* pointer to received SMB header */
681 int midState; /* wish this were enum but can not pass to wait_event */ 698 int midState; /* wish this were enum but can not pass to wait_event */
682 __u8 command; /* smb command code */ 699 __u8 command; /* smb command code */
683 bool largeBuf:1; /* if valid response, is pointer to large buf */ 700 bool largeBuf:1; /* if valid response, is pointer to large buf */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index a1fa9cec05d6..8a7adb31ffed 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -69,8 +69,9 @@ extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer,
69 struct TCP_Server_Info *server); 69 struct TCP_Server_Info *server);
70extern void DeleteMidQEntry(struct mid_q_entry *midEntry); 70extern void DeleteMidQEntry(struct mid_q_entry *midEntry);
71extern int cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov, 71extern int cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
72 unsigned int nvec, mid_callback_t *callback, 72 unsigned int nvec, mid_receive_t *receive,
73 void *cbdata, bool ignore_pend); 73 mid_callback_t *callback, void *cbdata,
74 bool ignore_pend);
74extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *, 75extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *,
75 struct smb_hdr * /* input */ , 76 struct smb_hdr * /* input */ ,
76 struct smb_hdr * /* out */ , 77 struct smb_hdr * /* out */ ,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index c824c106b2b7..0613df4d8e74 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -737,7 +737,8 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
737 iov.iov_base = smb; 737 iov.iov_base = smb;
738 iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4; 738 iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
739 739
740 rc = cifs_call_async(server, &iov, 1, cifs_echo_callback, server, true); 740 rc = cifs_call_async(server, &iov, 1, NULL, cifs_echo_callback,
741 server, true);
741 if (rc) 742 if (rc)
742 cFYI(1, "Echo request failed: %d", rc); 743 cFYI(1, "Echo request failed: %d", rc);
743 744
@@ -1834,7 +1835,7 @@ cifs_async_writev(struct cifs_writedata *wdata)
1834 1835
1835 kref_get(&wdata->refcount); 1836 kref_get(&wdata->refcount);
1836 rc = cifs_call_async(tcon->ses->server, iov, wdata->nr_pages + 1, 1837 rc = cifs_call_async(tcon->ses->server, iov, wdata->nr_pages + 1,
1837 cifs_writev_callback, wdata, false); 1838 NULL, cifs_writev_callback, wdata, false);
1838 1839
1839 if (rc == 0) 1840 if (rc == 0)
1840 cifs_stats_inc(&tcon->num_writes); 1841 cifs_stats_inc(&tcon->num_writes);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index f05dedda37c6..eeee2f5d13ce 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -824,7 +824,11 @@ cifs_demultiplex_thread(void *p)
824 824
825 mid_entry = find_mid(server, smb_buffer); 825 mid_entry = find_mid(server, smb_buffer);
826 826
827 length = standard_receive3(server, mid_entry); 827 if (!mid_entry || !mid_entry->receive)
828 length = standard_receive3(server, mid_entry);
829 else
830 length = mid_entry->receive(server, mid_entry);
831
828 if (length < 0) 832 if (length < 0)
829 continue; 833 continue;
830 834
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 33a3fbf3a3a5..e7398d0cd054 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -339,8 +339,8 @@ wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
339 */ 339 */
340int 340int
341cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov, 341cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
342 unsigned int nvec, mid_callback_t *callback, void *cbdata, 342 unsigned int nvec, mid_receive_t *receive,
343 bool ignore_pend) 343 mid_callback_t *callback, void *cbdata, bool ignore_pend)
344{ 344{
345 int rc; 345 int rc;
346 struct mid_q_entry *mid; 346 struct mid_q_entry *mid;
@@ -374,6 +374,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
374 goto out_err; 374 goto out_err;
375 } 375 }
376 376
377 mid->receive = receive;
377 mid->callback = callback; 378 mid->callback = callback;
378 mid->callback_data = cbdata; 379 mid->callback_data = cbdata;
379 mid->midState = MID_REQUEST_SUBMITTED; 380 mid->midState = MID_REQUEST_SUBMITTED;