diff options
author | Jeff Layton <jlayton@redhat.com> | 2011-10-19 15:30:07 -0400 |
---|---|---|
committer | Jeff Layton <jlayton@redhat.com> | 2011-10-19 15:30:07 -0400 |
commit | e28bc5b1fdbd6e850488234d6072e6b66fc46146 (patch) | |
tree | 7d5292bb0389b1153fd11f738fe8644cdfb040d1 /fs/cifs/cifsproto.h | |
parent | 2ab2593f4b8953ff951f5531e695e487dfe0b51f (diff) | |
download | linux-3.10-e28bc5b1fdbd6e850488234d6072e6b66fc46146.tar.gz linux-3.10-e28bc5b1fdbd6e850488234d6072e6b66fc46146.tar.bz2 linux-3.10-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/cifsproto.h')
-rw-r--r-- | fs/cifs/cifsproto.h | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 8a7adb31ffe..c25d0636cc4 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -154,6 +154,12 @@ extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *, extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, const char *, int); +extern void dequeue_mid(struct mid_q_entry *mid, bool malformed); +extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf, + unsigned int to_read); +extern int cifs_readv_from_socket(struct TCP_Server_Info *server, + struct kvec *iov_orig, unsigned int nr_segs, + unsigned int to_read); extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, struct cifs_sb_info *cifs_sb); extern int cifs_match_super(struct super_block *, void *); @@ -443,6 +449,24 @@ extern int E_md4hash(const unsigned char *passwd, unsigned char *p16); extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24); +/* asynchronous read support */ +struct cifs_readdata { + struct cifsFileInfo *cfile; + struct address_space *mapping; + __u64 offset; + unsigned int bytes; + pid_t pid; + int result; + struct list_head pages; + struct work_struct work; + unsigned int nr_iov; + struct kvec iov[1]; +}; + +struct cifs_readdata *cifs_readdata_alloc(unsigned int nr_pages); +void cifs_readdata_free(struct cifs_readdata *rdata); +int cifs_async_readv(struct cifs_readdata *rdata); + /* asynchronous write support */ struct cifs_writedata { struct kref refcount; |