aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2011-10-19 15:30:07 -0400
committerJeff Layton <jlayton@redhat.com>2011-10-19 15:30:07 -0400
commite28bc5b1fdbd6e850488234d6072e6b66fc46146 (patch)
tree7d5292bb0389b1153fd11f738fe8644cdfb040d1 /fs/cifs/connect.c
parent2ab2593f4b8953ff951f5531e695e487dfe0b51f (diff)
cifs: add cifs_async_readv
...which will allow cifs to do an asynchronous read call to the server. The caller will allocate and set up cifs_readdata for each READ_AND_X call that should be issued on the wire. The pages passed in are added to the pagecache, but not placed on the LRU list yet (as we need the page->lru to keep the pages on the list in the readdata). When cifsd identifies the mid, it will see that there is a special receive handler for the call, and use that to receive the rest of the frame. cifs_readv_receive will then marshal up a kvec array with kmapped pages from the pagecache, which eliminates one copy of the data. Once the data is received, the pages are added to the LRU list, set uptodate, and unlocked. Reviewed-and-Tested-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c26
1 files changed, 13 insertions, 13 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index eeee2f5d13c..3d518b9e8c1 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -422,9 +422,9 @@ get_server_iovec(struct TCP_Server_Info *server, unsigned int nr_segs)
422 return new_iov; 422 return new_iov;
423} 423}
424 424
425static int 425int
426readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig, 426cifs_readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig,
427 unsigned int nr_segs, unsigned int to_read) 427 unsigned int nr_segs, unsigned int to_read)
428{ 428{
429 int length = 0; 429 int length = 0;
430 int total_read; 430 int total_read;
@@ -479,16 +479,16 @@ readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig,
479 return total_read; 479 return total_read;
480} 480}
481 481
482static int 482int
483read_from_socket(struct TCP_Server_Info *server, char *buf, 483cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
484 unsigned int to_read) 484 unsigned int to_read)
485{ 485{
486 struct kvec iov; 486 struct kvec iov;
487 487
488 iov.iov_base = buf; 488 iov.iov_base = buf;
489 iov.iov_len = to_read; 489 iov.iov_len = to_read;
490 490
491 return readv_from_socket(server, &iov, 1, to_read); 491 return cifs_readv_from_socket(server, &iov, 1, to_read);
492} 492}
493 493
494static bool 494static bool
@@ -553,8 +553,8 @@ find_mid(struct TCP_Server_Info *server, struct smb_hdr *buf)
553 return NULL; 553 return NULL;
554} 554}
555 555
556static void 556void
557dequeue_mid(struct mid_q_entry *mid, int malformed) 557dequeue_mid(struct mid_q_entry *mid, bool malformed)
558{ 558{
559#ifdef CONFIG_CIFS_STATS2 559#ifdef CONFIG_CIFS_STATS2
560 mid->when_received = jiffies; 560 mid->when_received = jiffies;
@@ -730,7 +730,7 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
730 } 730 }
731 731
732 /* now read the rest */ 732 /* now read the rest */
733 length = read_from_socket(server, 733 length = cifs_read_from_socket(server,
734 buf + sizeof(struct smb_hdr) - 1, 734 buf + sizeof(struct smb_hdr) - 1,
735 pdu_length - sizeof(struct smb_hdr) + 1 + 4); 735 pdu_length - sizeof(struct smb_hdr) + 1 + 4);
736 if (length < 0) 736 if (length < 0)
@@ -791,7 +791,7 @@ cifs_demultiplex_thread(void *p)
791 buf = server->smallbuf; 791 buf = server->smallbuf;
792 pdu_length = 4; /* enough to get RFC1001 header */ 792 pdu_length = 4; /* enough to get RFC1001 header */
793 793
794 length = read_from_socket(server, buf, pdu_length); 794 length = cifs_read_from_socket(server, buf, pdu_length);
795 if (length < 0) 795 if (length < 0)
796 continue; 796 continue;
797 server->total_read = length; 797 server->total_read = length;
@@ -816,8 +816,8 @@ cifs_demultiplex_thread(void *p)
816 } 816 }
817 817
818 /* read down to the MID */ 818 /* read down to the MID */
819 length = read_from_socket(server, buf + 4, 819 length = cifs_read_from_socket(server, buf + 4,
820 sizeof(struct smb_hdr) - 1 - 4); 820 sizeof(struct smb_hdr) - 1 - 4);
821 if (length < 0) 821 if (length < 0)
822 continue; 822 continue;
823 server->total_read += length; 823 server->total_read += length;