提交 8b09bee3 编写于 作者: T Trond Myklebust

NFS: Cleanup for nfs_readpages()

Do the coalescing of read requests into block sized requests at start of
I/O as we scan through the pages instead of going through a second pass.
Signed-off-by: NTrond Myklebust <Trond.Myklebust@netapp.com>
上级 bcb71bba
...@@ -342,8 +342,8 @@ static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc) ...@@ -342,8 +342,8 @@ static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc)
* Returns true if the request 'req' was successfully coalesced into the * Returns true if the request 'req' was successfully coalesced into the
* existing list of pages 'desc'. * existing list of pages 'desc'.
*/ */
static int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
struct nfs_page *req) struct nfs_page *req)
{ {
while (!nfs_pageio_do_add_request(desc, req)) { while (!nfs_pageio_do_add_request(desc, req)) {
nfs_pageio_doio(desc); nfs_pageio_doio(desc);
......
...@@ -321,28 +321,6 @@ static int nfs_pagein_one(struct inode *inode, struct list_head *head, size_t co ...@@ -321,28 +321,6 @@ static int nfs_pagein_one(struct inode *inode, struct list_head *head, size_t co
return -ENOMEM; return -ENOMEM;
} }
static int
nfs_pagein_list(struct inode *inode, struct list_head *head, unsigned int rsize)
{
struct nfs_pageio_descriptor desc;
unsigned int pages = 0;
int error = 0;
if (rsize < PAGE_CACHE_SIZE)
nfs_pageio_init(&desc, inode, nfs_pagein_multi, rsize, 0);
else
nfs_pageio_init(&desc, inode, nfs_pagein_one, rsize, 0);
nfs_pageio_add_list(&desc, head);
nfs_pageio_complete(&desc);
pages += (desc.pg_bytes_written + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
nfs_async_read_error(head);
if (error >= 0)
return pages;
return error;
}
/* /*
* This is the callback from RPC telling us whether a reply was * This is the callback from RPC telling us whether a reply was
* received or some error occurred (timeout or socket shutdown). * received or some error occurred (timeout or socket shutdown).
...@@ -532,7 +510,7 @@ int nfs_readpage(struct file *file, struct page *page) ...@@ -532,7 +510,7 @@ int nfs_readpage(struct file *file, struct page *page)
} }
struct nfs_readdesc { struct nfs_readdesc {
struct list_head *head; struct nfs_pageio_descriptor *pgio;
struct nfs_open_context *ctx; struct nfs_open_context *ctx;
}; };
...@@ -556,19 +534,21 @@ readpage_async_filler(void *data, struct page *page) ...@@ -556,19 +534,21 @@ readpage_async_filler(void *data, struct page *page)
} }
if (len < PAGE_CACHE_SIZE) if (len < PAGE_CACHE_SIZE)
memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len); memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len);
nfs_list_add_request(new, desc->head); nfs_pageio_add_request(desc->pgio, new);
return 0; return 0;
} }
int nfs_readpages(struct file *filp, struct address_space *mapping, int nfs_readpages(struct file *filp, struct address_space *mapping,
struct list_head *pages, unsigned nr_pages) struct list_head *pages, unsigned nr_pages)
{ {
LIST_HEAD(head); struct nfs_pageio_descriptor pgio;
struct nfs_readdesc desc = { struct nfs_readdesc desc = {
.head = &head, .pgio = &pgio,
}; };
struct inode *inode = mapping->host; struct inode *inode = mapping->host;
struct nfs_server *server = NFS_SERVER(inode); struct nfs_server *server = NFS_SERVER(inode);
size_t rsize = server->rsize;
unsigned long npages;
int ret = -ESTALE; int ret = -ESTALE;
dprintk("NFS: nfs_readpages (%s/%Ld %d)\n", dprintk("NFS: nfs_readpages (%s/%Ld %d)\n",
...@@ -587,13 +567,16 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, ...@@ -587,13 +567,16 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
} else } else
desc.ctx = get_nfs_open_context((struct nfs_open_context *) desc.ctx = get_nfs_open_context((struct nfs_open_context *)
filp->private_data); filp->private_data);
if (rsize < PAGE_CACHE_SIZE)
nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0);
else
nfs_pageio_init(&pgio, inode, nfs_pagein_one, rsize, 0);
ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc); ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc);
if (!list_empty(&head)) {
int err = nfs_pagein_list(inode, &head, server->rsize); nfs_pageio_complete(&pgio);
if (!ret) npages = (pgio.pg_bytes_written + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
nfs_add_stats(inode, NFSIOS_READPAGES, err); nfs_add_stats(inode, NFSIOS_READPAGES, npages);
ret = err;
}
put_nfs_open_context(desc.ctx); put_nfs_open_context(desc.ctx);
out: out:
return ret; return ret;
......
...@@ -82,6 +82,8 @@ extern void nfs_pageio_init(struct nfs_pageio_descriptor *desc, ...@@ -82,6 +82,8 @@ extern void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
int (*doio)(struct inode *, struct list_head *, size_t, int), int (*doio)(struct inode *, struct list_head *, size_t, int),
size_t bsize, size_t bsize,
int how); int how);
extern int nfs_pageio_add_request(struct nfs_pageio_descriptor *,
struct nfs_page *);
extern void nfs_pageio_add_list(struct nfs_pageio_descriptor *, extern void nfs_pageio_add_list(struct nfs_pageio_descriptor *,
struct list_head *); struct list_head *);
extern void nfs_pageio_complete(struct nfs_pageio_descriptor *desc); extern void nfs_pageio_complete(struct nfs_pageio_descriptor *desc);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册