Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 493292dd authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFS: Move the pnfs read code into pnfs.c



...and ensure that we recoalese to take into account differences in
block sizes when falling back to read through the MDS.

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent d9156f9f
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -291,14 +291,18 @@ extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *,
extern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh);
#endif

struct nfs_pageio_descriptor;
/* read.c */
extern int nfs_initiate_read(struct nfs_read_data *data, struct rpc_clnt *clnt,
			     const struct rpc_call_ops *call_ops);
extern void nfs_read_prepare(struct rpc_task *task, void *calldata);
extern int nfs_generic_pagein(struct nfs_pageio_descriptor *desc,
		struct list_head *head);

struct nfs_pageio_descriptor;
extern void nfs_pageio_init_read_mds(struct nfs_pageio_descriptor *pgio,
		struct inode *inode);
extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio);
extern void nfs_readdata_release(struct nfs_read_data *rdata);

/* write.c */
extern void nfs_pageio_init_write_mds(struct nfs_pageio_descriptor *pgio,
+1 −1
Original line number Diff line number Diff line
@@ -735,7 +735,7 @@ filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
static const struct nfs_pageio_ops filelayout_pg_read_ops = {
	.pg_init = filelayout_pg_init_read,
	.pg_test = filelayout_pg_test,
	.pg_doio = nfs_generic_pg_readpages,
	.pg_doio = pnfs_generic_pg_readpages,
};

static const struct nfs_pageio_ops filelayout_pg_write_ops = {
+1 −1
Original line number Diff line number Diff line
@@ -1007,7 +1007,7 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio,
static const struct nfs_pageio_ops objio_pg_read_ops = {
	.pg_init = pnfs_generic_pg_init_read,
	.pg_test = objio_pg_test,
	.pg_doio = nfs_generic_pg_readpages,
	.pg_doio = pnfs_generic_pg_readpages,
};

static const struct nfs_pageio_ops objio_pg_write_ops = {
+55 −2
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
 */

#include <linux/nfs_fs.h>
#include <linux/nfs_page.h>
#include "internal.h"
#include "pnfs.h"
#include "iostat.h"
@@ -1216,18 +1217,32 @@ pnfs_ld_read_done(struct nfs_read_data *data)
}
EXPORT_SYMBOL_GPL(pnfs_ld_read_done);

static void
pnfs_read_through_mds(struct nfs_pageio_descriptor *desc,
		struct nfs_read_data *data)
{
	list_splice_tail_init(&data->pages, &desc->pg_list);
	if (data->req && list_empty(&data->req->wb_list))
		nfs_list_add_request(data->req, &desc->pg_list);
	nfs_pageio_reset_read_mds(desc);
	desc->pg_recoalesce = 1;
	nfs_readdata_release(data);
}

/*
 * Call the appropriate parallel I/O subsystem read function.
 */
enum pnfs_try_status
static enum pnfs_try_status
pnfs_try_to_read_data(struct nfs_read_data *rdata,
		       const struct rpc_call_ops *call_ops)
		       const struct rpc_call_ops *call_ops,
		       struct pnfs_layout_segment *lseg)
{
	struct inode *inode = rdata->inode;
	struct nfs_server *nfss = NFS_SERVER(inode);
	enum pnfs_try_status trypnfs;

	rdata->mds_ops = call_ops;
	rdata->lseg = get_lseg(lseg);

	dprintk("%s: Reading ino:%lu %u@%llu\n",
		__func__, inode->i_ino, rdata->args.count, rdata->args.offset);
@@ -1243,6 +1258,44 @@ pnfs_try_to_read_data(struct nfs_read_data *rdata,
	return trypnfs;
}

static void
pnfs_do_multiple_reads(struct nfs_pageio_descriptor *desc, struct list_head *head)
{
	struct nfs_read_data *data;
	const struct rpc_call_ops *call_ops = desc->pg_rpc_callops;
	struct pnfs_layout_segment *lseg = desc->pg_lseg;

	desc->pg_lseg = NULL;
	while (!list_empty(head)) {
		enum pnfs_try_status trypnfs;

		data = list_entry(head->next, struct nfs_read_data, list);
		list_del_init(&data->list);

		trypnfs = pnfs_try_to_read_data(data, call_ops, lseg);
		if (trypnfs == PNFS_NOT_ATTEMPTED)
			pnfs_read_through_mds(desc, data);
	}
	put_lseg(lseg);
}

int
pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
{
	LIST_HEAD(head);
	int ret;

	ret = nfs_generic_pagein(desc, &head);
	if (ret != 0) {
		put_lseg(desc->pg_lseg);
		desc->pg_lseg = NULL;
		return ret;
	}
	pnfs_do_multiple_reads(desc, &head);
	return 0;
}
EXPORT_SYMBOL_GPL(pnfs_generic_pg_readpages);

/*
 * Currently there is only one (whole file) write lseg.
 */
+1 −9
Original line number Diff line number Diff line
@@ -157,9 +157,8 @@ void set_pnfs_layoutdriver(struct nfs_server *, u32 id);
void unset_pnfs_layoutdriver(struct nfs_server *);
enum pnfs_try_status pnfs_try_to_write_data(struct nfs_write_data *,
					     const struct rpc_call_ops *, int);
enum pnfs_try_status pnfs_try_to_read_data(struct nfs_read_data *,
					    const struct rpc_call_ops *);
void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *, struct nfs_page *);
int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc);
void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *, struct nfs_page *);
bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req);
int pnfs_layout_process(struct nfs4_layoutget *lgp);
@@ -329,13 +328,6 @@ static inline void put_lseg(struct pnfs_layout_segment *lseg)
{
}

static inline enum pnfs_try_status
pnfs_try_to_read_data(struct nfs_read_data *data,
		      const struct rpc_call_ops *call_ops)
{
	return PNFS_NOT_ATTEMPTED;
}

static inline enum pnfs_try_status
pnfs_try_to_write_data(struct nfs_write_data *data,
		       const struct rpc_call_ops *call_ops, int how)
Loading