diff options
author | Chuck Lever <cel@netapp.com> | 2006-06-20 12:56:49 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-06-24 13:11:39 -0400 |
commit | 06cf6f2ed0b19629700794727d86ed57b9c0583e (patch) | |
tree | 20630465974dc9391af486d8609aae077701b596 /include/linux/nfs_xdr.h | |
parent | 9c93ab7dff5eb22027ab15010557bb73f9b44c99 (diff) |
NFS: Eliminate nfs_get_user_pages()
Neil Brown observed that the kmalloc() in nfs_get_user_pages() is more
likely to fail if the I/O is large enough to require the allocation of more
than a single page to keep track of all the pinned pages in the user's
buffer.
Instead of tracking one large page array per dreq/iocb, track pages per
nfs_read/write_data, just like the cached I/O path does. An array for
pages is already allocated for us by nfs_readdata_alloc() (and the write
and commit equivalents).
This is also required for adding support for vectored I/O to the NFS direct
I/O path.
The original reason to pin the user buffer and allocate all the NFS data
structures before trying to schedule I/O was to ensure all needed resources
are allocated on the client before starting to send requests. This reduces
the chance that resource exhaustion on the client will cause a short read
or write.
On the other hand, for an application making very large application I/O
requests, this means that it will be nearly impossible for the application
to make forward progress on a resource-limited client.
Thus, moving the buffer pinning functionality into the I/O scheduling
loops should be good for scalability. The next patch will do the same for
NFS data structure allocation.
Signed-off-by: Chuck Lever <cel@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'include/linux/nfs_xdr.h')
-rw-r--r-- | include/linux/nfs_xdr.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 7c7320fa51aa..2d3fb6416d91 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -729,6 +729,7 @@ struct nfs_read_data { | |||
729 | struct list_head pages; /* Coalesced read requests */ | 729 | struct list_head pages; /* Coalesced read requests */ |
730 | struct nfs_page *req; /* multi ops per nfs_page */ | 730 | struct nfs_page *req; /* multi ops per nfs_page */ |
731 | struct page **pagevec; | 731 | struct page **pagevec; |
732 | unsigned int npages; /* active pages in pagevec */ | ||
732 | struct nfs_readargs args; | 733 | struct nfs_readargs args; |
733 | struct nfs_readres res; | 734 | struct nfs_readres res; |
734 | #ifdef CONFIG_NFS_V4 | 735 | #ifdef CONFIG_NFS_V4 |
@@ -747,6 +748,7 @@ struct nfs_write_data { | |||
747 | struct list_head pages; /* Coalesced requests we wish to flush */ | 748 | struct list_head pages; /* Coalesced requests we wish to flush */ |
748 | struct nfs_page *req; /* multi ops per nfs_page */ | 749 | struct nfs_page *req; /* multi ops per nfs_page */ |
749 | struct page **pagevec; | 750 | struct page **pagevec; |
751 | unsigned int npages; /* active pages in pagevec */ | ||
750 | struct nfs_writeargs args; /* argument struct */ | 752 | struct nfs_writeargs args; /* argument struct */ |
751 | struct nfs_writeres res; /* result struct */ | 753 | struct nfs_writeres res; /* result struct */ |
752 | #ifdef CONFIG_NFS_V4 | 754 | #ifdef CONFIG_NFS_V4 |