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

Commit d8007d4d authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFSv4.1: Add an initialisation callback for pNFS



Ensure that we always get a layout before setting up the i/o request.

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 1751c363
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -682,11 +682,13 @@ filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
}

static const struct nfs_pageio_ops filelayout_pg_read_ops = {
	.pg_init = pnfs_generic_pg_init_read,
	.pg_test = filelayout_pg_test,
	.pg_doio = nfs_generic_pg_readpages,
};

static const struct nfs_pageio_ops filelayout_pg_write_ops = {
	.pg_init = pnfs_generic_pg_init_write,
	.pg_test = filelayout_pg_test,
	.pg_doio = nfs_generic_pg_writepages,
};
+2 −0
Original line number Diff line number Diff line
@@ -1008,11 +1008,13 @@ 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,
};

static const struct nfs_pageio_ops objio_pg_write_ops = {
	.pg_init = pnfs_generic_pg_init_write,
	.pg_test = objio_pg_test,
	.pg_doio = nfs_generic_pg_writepages,
};
+2 −0
Original line number Diff line number Diff line
@@ -295,6 +295,8 @@ static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc,
		if (!nfs_can_coalesce_requests(prev, req, desc))
			return 0;
	} else {
		if (desc->pg_ops->pg_init)
			desc->pg_ops->pg_init(desc, req);
		desc->pg_base = req->wb_pgbase;
	}
	nfs_list_remove_request(req);
+31 −26
Original line number Diff line number Diff line
@@ -911,7 +911,7 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo,
 * Layout segment is retreived from the server if not cached.
 * The appropriate layout segment is referenced and returned to the caller.
 */
struct pnfs_layout_segment *
static struct pnfs_layout_segment *
pnfs_update_layout(struct inode *ino,
		   struct nfs_open_context *ctx,
		   loff_t pos,
@@ -1055,6 +1055,34 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
	goto out;
}

void
pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
{
	BUG_ON(pgio->pg_lseg != NULL);

	pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
					   req->wb_context,
					   req_offset(req),
					   req->wb_bytes,
					   IOMODE_READ,
					   GFP_KERNEL);
}
EXPORT_SYMBOL_GPL(pnfs_generic_pg_init_read);

void
pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
{
	BUG_ON(pgio->pg_lseg != NULL);

	pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
					   req->wb_context,
					   req_offset(req),
					   req->wb_bytes,
					   IOMODE_RW,
					   GFP_NOFS);
}
EXPORT_SYMBOL_GPL(pnfs_generic_pg_init_write);

bool
pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *inode)
{
@@ -1083,31 +1111,8 @@ bool
pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
		     struct nfs_page *req)
{
	enum pnfs_iomode access_type;
	gfp_t gfp_flags;

	/* We assume that pg_ioflags == 0 iff we're reading a page */
	if (pgio->pg_ioflags == 0) {
		access_type = IOMODE_READ;
		gfp_flags = GFP_KERNEL;
	} else {
		access_type = IOMODE_RW;
		gfp_flags = GFP_NOFS;
	}

	if (pgio->pg_lseg == NULL) {
		if (pgio->pg_count != prev->wb_bytes)
			return true;
		/* This is first coelesce call for a series of nfs_pages */
		pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
						   prev->wb_context,
						   req_offset(prev),
						   pgio->pg_count,
						   access_type,
						   gfp_flags);
	if (pgio->pg_lseg == NULL)
			return true;
	}
		return nfs_generic_pg_test(pgio, prev, req);

	/*
	 * Test if a nfs_page is fully contained in the pnfs_layout_range.
+2 −12
Original line number Diff line number Diff line
@@ -149,10 +149,6 @@ extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp);
/* pnfs.c */
void get_layout_hdr(struct pnfs_layout_hdr *lo);
void put_lseg(struct pnfs_layout_segment *lseg);
struct pnfs_layout_segment *
pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx,
		   loff_t pos, u64 count, enum pnfs_iomode access_type,
		   gfp_t gfp_flags);

bool pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *);
bool pnfs_pageio_init_write(struct nfs_pageio_descriptor *, struct inode *, int);
@@ -163,6 +159,8 @@ 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 *);
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);
void pnfs_free_lseg_list(struct list_head *tmp_list);
@@ -318,14 +316,6 @@ static inline void put_lseg(struct pnfs_layout_segment *lseg)
{
}

static inline struct pnfs_layout_segment *
pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx,
		   loff_t pos, u64 count, enum pnfs_iomode access_type,
		   gfp_t gfp_flags)
{
	return NULL;
}

static inline enum pnfs_try_status
pnfs_try_to_read_data(struct nfs_read_data *data,
		      const struct rpc_call_ops *call_ops)
Loading