diff options
author | Chuck Lever <cel@netapp.com> | 2006-03-20 13:44:30 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-20 13:44:30 -0500 |
commit | 99514f8fdda2beef1ca922b7f9d89c1a2c57fec0 (patch) | |
tree | 74a96ad19ed705775d9cd87b79c28aafe0286dee | |
parent | 0cdd80d07fb0f558dfdb30f6e0b9905f5e5475f1 (diff) |
NFS: make iocb available everywhere in direct read path
Pass the iocb argument all the way down to the direct read request
scheduler, and make it available in nfs_direct_read_result.
Test plan:
Compile the kernel with CONFIG_NFS and CONFIG_NFS_DIRECTIO enabled.
Millions of fsx-odirect ops. OraSim.
Signed-off-by: Chuck Lever <cel@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/direct.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 6ecde9602f99..6cbddc51acbc 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -68,6 +68,8 @@ static kmem_cache_t *nfs_direct_cachep; | |||
68 | struct nfs_direct_req { | 68 | struct nfs_direct_req { |
69 | struct kref kref; /* release manager */ | 69 | struct kref kref; /* release manager */ |
70 | struct list_head list; /* nfs_read_data structs */ | 70 | struct list_head list; /* nfs_read_data structs */ |
71 | struct file * filp; /* file descriptor */ | ||
72 | struct kiocb * iocb; /* controlling i/o request */ | ||
71 | wait_queue_head_t wait; /* wait for i/o completion */ | 73 | wait_queue_head_t wait; /* wait for i/o completion */ |
72 | struct inode * inode; /* target file of I/O */ | 74 | struct inode * inode; /* target file of I/O */ |
73 | struct page ** pages; /* pages in our buffer */ | 75 | struct page ** pages; /* pages in our buffer */ |
@@ -240,8 +242,12 @@ static const struct rpc_call_ops nfs_read_direct_ops = { | |||
240 | * For each nfs_read_data struct that was allocated on the list, dispatch | 242 | * For each nfs_read_data struct that was allocated on the list, dispatch |
241 | * an NFS READ operation | 243 | * an NFS READ operation |
242 | */ | 244 | */ |
243 | static void nfs_direct_read_schedule(struct nfs_direct_req *dreq, struct inode *inode, struct nfs_open_context *ctx, unsigned long user_addr, size_t count, loff_t file_offset) | 245 | static void nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t file_offset) |
244 | { | 246 | { |
247 | struct file *file = dreq->filp; | ||
248 | struct inode *inode = file->f_mapping->host; | ||
249 | struct nfs_open_context *ctx = (struct nfs_open_context *) | ||
250 | file->private_data; | ||
245 | struct list_head *list = &dreq->list; | 251 | struct list_head *list = &dreq->list; |
246 | struct page **pages = dreq->pages; | 252 | struct page **pages = dreq->pages; |
247 | size_t rsize = NFS_SERVER(inode)->rsize; | 253 | size_t rsize = NFS_SERVER(inode)->rsize; |
@@ -321,10 +327,11 @@ static ssize_t nfs_direct_read_wait(struct nfs_direct_req *dreq, int intr) | |||
321 | return (ssize_t) result; | 327 | return (ssize_t) result; |
322 | } | 328 | } |
323 | 329 | ||
324 | static ssize_t nfs_direct_read(struct inode *inode, struct nfs_open_context *ctx, unsigned long user_addr, size_t count, loff_t file_offset, struct page **pages, unsigned int nr_pages) | 330 | static ssize_t nfs_direct_read(struct kiocb *iocb, unsigned long user_addr, size_t count, loff_t file_offset, struct page **pages, unsigned int nr_pages) |
325 | { | 331 | { |
326 | ssize_t result; | 332 | ssize_t result; |
327 | sigset_t oldset; | 333 | sigset_t oldset; |
334 | struct inode *inode = iocb->ki_filp->f_mapping->host; | ||
328 | struct rpc_clnt *clnt = NFS_CLIENT(inode); | 335 | struct rpc_clnt *clnt = NFS_CLIENT(inode); |
329 | struct nfs_direct_req *dreq; | 336 | struct nfs_direct_req *dreq; |
330 | 337 | ||
@@ -335,11 +342,11 @@ static ssize_t nfs_direct_read(struct inode *inode, struct nfs_open_context *ctx | |||
335 | dreq->pages = pages; | 342 | dreq->pages = pages; |
336 | dreq->npages = nr_pages; | 343 | dreq->npages = nr_pages; |
337 | dreq->inode = inode; | 344 | dreq->inode = inode; |
345 | dreq->filp = iocb->ki_filp; | ||
338 | 346 | ||
339 | nfs_add_stats(inode, NFSIOS_DIRECTREADBYTES, count); | 347 | nfs_add_stats(inode, NFSIOS_DIRECTREADBYTES, count); |
340 | rpc_clnt_sigmask(clnt, &oldset); | 348 | rpc_clnt_sigmask(clnt, &oldset); |
341 | nfs_direct_read_schedule(dreq, inode, ctx, user_addr, count, | 349 | nfs_direct_read_schedule(dreq, user_addr, count, file_offset); |
342 | file_offset); | ||
343 | result = nfs_direct_read_wait(dreq, clnt->cl_intr); | 350 | result = nfs_direct_read_wait(dreq, clnt->cl_intr); |
344 | rpc_clnt_sigunmask(clnt, &oldset); | 351 | rpc_clnt_sigunmask(clnt, &oldset); |
345 | 352 | ||
@@ -520,10 +527,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, | |||
520 | int page_count; | 527 | int page_count; |
521 | struct page **pages; | 528 | struct page **pages; |
522 | struct file *file = iocb->ki_filp; | 529 | struct file *file = iocb->ki_filp; |
523 | struct nfs_open_context *ctx = | ||
524 | (struct nfs_open_context *) file->private_data; | ||
525 | struct address_space *mapping = file->f_mapping; | 530 | struct address_space *mapping = file->f_mapping; |
526 | struct inode *inode = mapping->host; | ||
527 | 531 | ||
528 | dprintk("nfs: direct read(%s/%s, %lu@%Ld)\n", | 532 | dprintk("nfs: direct read(%s/%s, %lu@%Ld)\n", |
529 | file->f_dentry->d_parent->d_name.name, | 533 | file->f_dentry->d_parent->d_name.name, |
@@ -553,7 +557,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, | |||
553 | goto out; | 557 | goto out; |
554 | } | 558 | } |
555 | 559 | ||
556 | retval = nfs_direct_read(inode, ctx, (unsigned long) buf, count, pos, | 560 | retval = nfs_direct_read(iocb, (unsigned long) buf, count, pos, |
557 | pages, page_count); | 561 | pages, page_count); |
558 | if (retval > 0) | 562 | if (retval > 0) |
559 | iocb->ki_pos = pos + retval; | 563 | iocb->ki_pos = pos + retval; |