summaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorJeff Layton2011-10-19 21:30:07 +0200
committerJeff Layton2011-10-19 21:30:07 +0200
commite28bc5b1fdbd6e850488234d6072e6b66fc46146 (patch)
tree7d5292bb0389b1153fd11f738fe8644cdfb040d1 /fs/cifs/connect.c
parentcifs: fix protocol definition for READ_RSP (diff)
downloadkernel-qcow2-linux-e28bc5b1fdbd6e850488234d6072e6b66fc46146.tar.gz
kernel-qcow2-linux-e28bc5b1fdbd6e850488234d6072e6b66fc46146.tar.xz
kernel-qcow2-linux-e28bc5b1fdbd6e850488234d6072e6b66fc46146.zip
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 eeee2f5d13ce..3d518b9e8c18 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)
return new_iov;
}
-static int
-readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig,
- unsigned int nr_segs, unsigned int to_read)
+int
+cifs_readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig,
+ unsigned int nr_segs, unsigned int to_read)
{
int length = 0;
int total_read;
@@ -479,16 +479,16 @@ readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig,
return total_read;
}
-static int
-read_from_socket(struct TCP_Server_Info *server, char *buf,
- unsigned int to_read)
+int
+cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
+ unsigned int to_read)
{
struct kvec iov;
iov.iov_base = buf;
iov.iov_len = to_read;
- return readv_from_socket(server, &iov, 1, to_read);
+ return cifs_readv_from_socket(server, &iov, 1, to_read);
}
static bool
@@ -553,8 +553,8 @@ find_mid(struct TCP_Server_Info *server, struct smb_hdr *buf)
return NULL;
}
-static void
-dequeue_mid(struct mid_q_entry *mid, int malformed)
+void
+dequeue_mid(struct mid_q_entry *mid, bool malformed)
{
#ifdef CONFIG_CIFS_STATS2
mid->when_received = jiffies;
@@ -730,7 +730,7 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
}
/* now read the rest */
- length = read_from_socket(server,
+ length = cifs_read_from_socket(server,
buf + sizeof(struct smb_hdr) - 1,
pdu_length - sizeof(struct smb_hdr) + 1 + 4);
if (length < 0)
@@ -791,7 +791,7 @@ cifs_demultiplex_thread(void *p)
buf = server->smallbuf;
pdu_length = 4; /* enough to get RFC1001 header */
- length = read_from_socket(server, buf, pdu_length);
+ length = cifs_read_from_socket(server, buf, pdu_length);
if (length < 0)
continue;
server->total_read = length;
@@ -816,8 +816,8 @@ cifs_demultiplex_thread(void *p)
}
/* read down to the MID */
- length = read_from_socket(server, buf + 4,
- sizeof(struct smb_hdr) - 1 - 4);
+ length = cifs_read_from_socket(server, buf + 4,
+ sizeof(struct smb_hdr) - 1 - 4);
if (length < 0)
continue;
server->total_read += length;