[pnfs] [PATCH 05/14] 2.6-latest pnfs client read path layoutget
andros at umich.edu
andros at umich.edu
Mon Nov 12 14:29:17 EST 2007
From: Andy Adamson <andros at umich.edu>
Use the pNFS ds_rsize for read pageio and ask for a layout.
Signed-off by: Andy Adamson<andros at umich.edu>
---
fs/nfs/nfs4proc.c | 1 -
fs/nfs/pnfs.c | 35 +++++++++++++++++++++++++++++++++--
fs/nfs/pnfs.h | 20 +++++++++++++++++++-
fs/nfs/read.c | 7 +++++++
4 files changed, 59 insertions(+), 4 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 79f8e93..7e1eb68 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5252,7 +5252,6 @@ const struct nfs_rpc_ops pnfs_v41_clientops = {
.file_open = nfs_open,
.file_release = nfs_release,
.lock = nfs4_proc_lock,
- .rsize = pnfs_rsize,
.wsize = pnfs_wsize,
.rpages = pnfs_rpages,
.wpages = pnfs_wpages,
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 3f765ad..90b78db 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -439,6 +439,38 @@ pnfs_inject_layout(struct nfs_inode* nfsi,
return io_ops->set_layout(layid, inode, lgr);
}
+void
+pnfs_update_layout_read(struct inode *inode,
+ struct nfs_open_context *ctx,
+ struct list_head *pages,
+ loff_t offset,
+ size_t *rsize)
+{
+ struct nfs_server *nfss = NFS_SERVER(inode);
+ struct page *page;
+ size_t count = 0;
+ int status = 0;
+
+ dprintk("--> %s inode %p ctx %p pages %p offset %lu\n",
+ __func__, inode, ctx, pages, (unsigned long)offset);
+
+ if (!pnfs_enabled_sb(nfss))
+ return;
+
+ /* Calculate the total read-ahead count */
+ list_for_each_entry(page, pages, lru)
+ count += pnfs_page_length(page, inode);
+
+ dprintk("%s count %ld\n", __func__,(long int)count);
+
+ *rsize = pnfs_rsize(inode, count);
+
+ status = virtual_update_layout(inode, ctx, count,
+ offset, IOMODE_RW);
+ dprintk("%s *rsize %Zd virt update returned %d\n",
+ __func__, *rsize, status);
+}
+
/* Check to see if the module is handling which layouts need to be
* retrieved from the server. If they are not, then use retrieve based
* upon the returned data ranges from get_layout.
@@ -1483,12 +1515,11 @@ struct pnfs_client_operations pnfs_ops = {
};
int
-pnfs_rsize(struct inode *inode, unsigned int count, struct nfs_read_data *rdata)
+pnfs_rsize(struct inode *inode, unsigned int count)
{
if (count >= 0 && below_threshold(inode, count, 0))
return NFS_SERVER(inode)->rsize;
- rdata->pnfsflags |= PNFS_USE_DS;
return NFS_SERVER(inode)->ds_rsize;
}
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index edfc732..681443c 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -46,13 +46,31 @@ int pnfs_use_nfsv4_rproto(struct inode *inode, ssize_t count);
unsigned int pnfs_getiosize(struct nfs_server *server);
int pnfs_commit(struct inode* inode, struct list_head *head, int sync, struct nfs_write_data *data);
int pnfs_try_to_commit(struct inode *, struct nfs_write_data *, struct list_head *, int);
-int pnfs_rsize(struct inode *, unsigned int, struct nfs_read_data *);
+int pnfs_rsize(struct inode *, unsigned int);
int pnfs_wsize(struct inode *, unsigned int, struct nfs_write_data *);
int pnfs_rpages(struct inode *);
int pnfs_wpages(struct inode *);
void pnfs_readpage_result_norpc(struct rpc_task *task, void *calldata);
void pnfs_writeback_done_norpc(struct rpc_task *, void *);
void pnfs_commit_done_norpc(struct rpc_task *, void *);
+void pnfs_update_layout_read(struct inode *, struct nfs_open_context *, struct list_head *, loff_t, size_t *);
+
+
+static inline
+unsigned int pnfs_page_length(struct page *page, struct inode *inode)
+{
+ loff_t i_size = i_size_read(inode);
+
+ if (i_size > 0) {
+ pgoff_t end_index = (i_size - 1) >> PAGE_CACHE_SHIFT;
+ if (page->index < end_index)
+ return PAGE_CACHE_SIZE;
+ if (page->index == end_index)
+ return ((i_size - 1) & ~PAGE_CACHE_MASK) + 1;
+ }
+ return 0;
+}
+
#endif /* CONFIG_PNFS */
#endif /* FS_NFS_PNFS_H */
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index dd98eca..7b07865 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -22,6 +22,10 @@
#include <asm/system.h>
#include <linux/module.h>
+#ifdef CONFIG_PNFS
+#include <linux/pnfs_xdr.h>
+#include "pnfs.h"
+#endif /* CONFIG_PNFS */
#include "nfs4_fs.h"
#include "internal.h"
@@ -635,6 +639,9 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
return -EBADF;
} else
desc.ctx = get_nfs_open_context(nfs_file_open_context(filp));
+#ifdef CONFIG_PNFS
+ pnfs_update_layout_read(inode, desc.ctx, pages, filp->f_pos, &rsize);
+#endif /* CONFIG_PNFS */
if (rsize < PAGE_CACHE_SIZE)
nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0);
else
--
1.5.0.2
More information about the pNFS
mailing list