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

Commit 0b7c0153 authored by Fred Isaman's avatar Fred Isaman Committed by Trond Myklebust
Browse files

NFS: add a struct nfs_commit_data to replace nfs_write_data in commits



Commits don't need the vectors of pages, etc. that writes do. Split out
a separate structure for the commit operation.

Signed-off-by: default avatarFred Isaman <iisaman@netapp.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 799ba8d5
Loading
Loading
Loading
Loading
+7 −10
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ struct nfs_direct_req {

	/* commit state */
	struct list_head	rewrite_list;	/* saved nfs_write_data structs */
	struct nfs_write_data *	commit_data;	/* special write_data for commits */
	struct nfs_commit_data *commit_data;	/* special write_data for commits */
	int			flags;
#define NFS_ODIRECT_DO_COMMIT		(1)	/* an unstable reply was received */
#define NFS_ODIRECT_RESCHED_WRITES	(2)	/* write verification failed */
@@ -524,7 +524,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)

static void nfs_direct_commit_result(struct rpc_task *task, void *calldata)
{
	struct nfs_write_data *data = calldata;
	struct nfs_commit_data *data = calldata;

	/* Call the NFS version-specific code */
	NFS_PROTO(data->inode)->commit_done(task, data);
@@ -532,8 +532,8 @@ static void nfs_direct_commit_result(struct rpc_task *task, void *calldata)

static void nfs_direct_commit_release(void *calldata)
{
	struct nfs_write_data *data = calldata;
	struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req;
	struct nfs_commit_data *data = calldata;
	struct nfs_direct_req *dreq = data->dreq;
	int status = data->task.tk_status;

	if (status < 0) {
@@ -551,14 +551,14 @@ static void nfs_direct_commit_release(void *calldata)
}

static const struct rpc_call_ops nfs_commit_direct_ops = {
	.rpc_call_prepare = nfs_write_prepare,
	.rpc_call_prepare = nfs_commit_prepare,
	.rpc_call_done = nfs_direct_commit_result,
	.rpc_release = nfs_direct_commit_release,
};

static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
{
	struct nfs_write_data *data = dreq->commit_data;
	struct nfs_commit_data *data = dreq->commit_data;
	struct rpc_task *task;
	struct rpc_message msg = {
		.rpc_argp = &data->args,
@@ -581,9 +581,6 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
	data->args.fh = NFS_FH(data->inode);
	data->args.offset = 0;
	data->args.count = 0;
	data->args.context = dreq->ctx;
	data->args.lock_context = dreq->l_ctx;
	data->res.count = 0;
	data->res.fattr = &data->fattr;
	data->res.verf = &data->verf;
	nfs_fattr_init(&data->fattr);
@@ -625,7 +622,7 @@ static void nfs_alloc_commit_data(struct nfs_direct_req *dreq)
{
	dreq->commit_data = nfs_commitdata_alloc();
	if (dreq->commit_data != NULL)
		dreq->commit_data->req = (struct nfs_page *) dreq;
		dreq->commit_data->dreq = dreq;
}
#else
static inline void nfs_alloc_commit_data(struct nfs_direct_req *dreq)
+7 −6
Original line number Diff line number Diff line
@@ -314,24 +314,25 @@ extern void nfs_pageio_init_write_mds(struct nfs_pageio_descriptor *pgio,
				  struct inode *inode, int ioflags);
extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio);
extern void nfs_writedata_release(struct nfs_write_data *wdata);
extern void nfs_commit_free(struct nfs_write_data *p);
extern void nfs_commit_free(struct nfs_commit_data *p);
extern int nfs_initiate_write(struct nfs_write_data *data,
			      struct rpc_clnt *clnt,
			      const struct rpc_call_ops *call_ops,
			      int how);
extern void nfs_write_prepare(struct rpc_task *task, void *calldata);
extern int nfs_initiate_commit(struct nfs_write_data *data,
			       struct rpc_clnt *clnt,
extern void nfs_commit_prepare(struct rpc_task *task, void *calldata);
extern int nfs_initiate_commit(struct rpc_clnt *clnt,
			       struct nfs_commit_data *data,
			       const struct rpc_call_ops *call_ops,
			       int how);
extern void nfs_init_commit(struct nfs_write_data *data,
extern void nfs_init_commit(struct nfs_commit_data *data,
			    struct list_head *head,
			    struct pnfs_layout_segment *lseg);
void nfs_retry_commit(struct list_head *page_list,
		      struct pnfs_layout_segment *lseg);
void nfs_commit_clear_lock(struct nfs_inode *nfsi);
void nfs_commitdata_release(void *data);
void nfs_commit_release_pages(struct nfs_write_data *data);
void nfs_commitdata_release(struct nfs_commit_data *data);
void nfs_commit_release_pages(struct nfs_commit_data *data);
void nfs_request_add_commit_list(struct nfs_page *req, struct list_head *head);
void nfs_request_remove_commit_list(struct nfs_page *req);

+8 −2
Original line number Diff line number Diff line
@@ -848,7 +848,12 @@ static void nfs3_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_
	rpc_call_start(task);
}

static int nfs3_commit_done(struct rpc_task *task, struct nfs_write_data *data)
static void nfs3_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data)
{
	rpc_call_start(task);
}

static int nfs3_commit_done(struct rpc_task *task, struct nfs_commit_data *data)
{
	if (nfs3_async_handle_jukebox(task, data->inode))
		return -EAGAIN;
@@ -856,7 +861,7 @@ static int nfs3_commit_done(struct rpc_task *task, struct nfs_write_data *data)
	return 0;
}

static void nfs3_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg)
static void nfs3_proc_commit_setup(struct nfs_commit_data *data, struct rpc_message *msg)
{
	msg->rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT];
}
@@ -907,6 +912,7 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
	.write_rpc_prepare = nfs3_proc_write_rpc_prepare,
	.write_done	= nfs3_write_done,
	.commit_setup	= nfs3_proc_commit_setup,
	.commit_rpc_prepare = nfs3_proc_commit_rpc_prepare,
	.commit_done	= nfs3_commit_done,
	.lock		= nfs3_proc_lock,
	.clear_acl_cache = nfs3_forget_cached_acls,
+3 −3
Original line number Diff line number Diff line
@@ -1287,7 +1287,7 @@ static void nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req,
 *	};
 */
static void encode_commit3args(struct xdr_stream *xdr,
			       const struct nfs_writeargs *args)
			       const struct nfs_commitargs *args)
{
	__be32 *p;

@@ -1300,7 +1300,7 @@ static void encode_commit3args(struct xdr_stream *xdr,

static void nfs3_xdr_enc_commit3args(struct rpc_rqst *req,
				     struct xdr_stream *xdr,
				     const struct nfs_writeargs *args)
				     const struct nfs_commitargs *args)
{
	encode_commit3args(xdr, args);
}
@@ -2319,7 +2319,7 @@ out_status:
 */
static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req,
				   struct xdr_stream *xdr,
				   struct nfs_writeres *result)
				   struct nfs_commitres *result)
{
	enum nfs_stat status;
	int error;
+46 −19
Original line number Diff line number Diff line
@@ -250,7 +250,7 @@ static int filelayout_write_done_cb(struct rpc_task *task,
}

/* Fake up some data that will cause nfs_commit_release to retry the writes. */
static void prepare_to_resend_writes(struct nfs_write_data *data)
static void prepare_to_resend_writes(struct nfs_commit_data *data)
{
	struct nfs_page *first = nfs_list_entry(data->pages.next);

@@ -261,11 +261,11 @@ static void prepare_to_resend_writes(struct nfs_write_data *data)
}

static int filelayout_commit_done_cb(struct rpc_task *task,
				     struct nfs_write_data *data)
				     struct nfs_commit_data *data)
{
	int reset = 0;

	if (filelayout_async_handle_error(task, data->args.context->state,
	if (filelayout_async_handle_error(task, data->context->state,
					  data->ds_clp, &reset) == -EAGAIN) {
		dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n",
			__func__, data->ds_clp, data->ds_clp->cl_session);
@@ -315,15 +315,42 @@ static void filelayout_write_release(void *data)
	wdata->mds_ops->rpc_release(data);
}

static void filelayout_commit_release(void *data)
static void filelayout_commit_prepare(struct rpc_task *task, void *data)
{
	struct nfs_write_data *wdata = (struct nfs_write_data *)data;
	struct nfs_commit_data *wdata = data;

	nfs_commit_release_pages(wdata);
	if (atomic_dec_and_test(&NFS_I(wdata->inode)->commits_outstanding))
		nfs_commit_clear_lock(NFS_I(wdata->inode));
	put_lseg(wdata->lseg);
	nfs_commitdata_release(wdata);
	if (nfs41_setup_sequence(wdata->ds_clp->cl_session,
				&wdata->args.seq_args, &wdata->res.seq_res,
				task))
		return;

	rpc_call_start(task);
}

static void filelayout_write_commit_done(struct rpc_task *task, void *data)
{
	struct nfs_commit_data *wdata = data;

	/* Note this may cause RPC to be resent */
	wdata->mds_ops->rpc_call_done(task, data);
}

static void filelayout_commit_count_stats(struct rpc_task *task, void *data)
{
	struct nfs_commit_data *cdata = data;

	rpc_count_iostats(task, NFS_SERVER(cdata->inode)->client->cl_metrics);
}

static void filelayout_commit_release(void *calldata)
{
	struct nfs_commit_data *data = calldata;

	nfs_commit_release_pages(data);
	if (atomic_dec_and_test(&NFS_I(data->inode)->commits_outstanding))
		nfs_commit_clear_lock(NFS_I(data->inode));
	put_lseg(data->lseg);
	nfs_commitdata_release(data);
}

static const struct rpc_call_ops filelayout_read_call_ops = {
@@ -341,9 +368,9 @@ static const struct rpc_call_ops filelayout_write_call_ops = {
};

static const struct rpc_call_ops filelayout_commit_call_ops = {
	.rpc_call_prepare = filelayout_write_prepare,
	.rpc_call_done = filelayout_write_call_done,
	.rpc_count_stats = filelayout_write_count_stats,
	.rpc_call_prepare = filelayout_commit_prepare,
	.rpc_call_done = filelayout_write_commit_done,
	.rpc_count_stats = filelayout_commit_count_stats,
	.rpc_release = filelayout_commit_release,
};

@@ -922,7 +949,7 @@ select_ds_fh_from_commit(struct pnfs_layout_segment *lseg, u32 i)
	return flseg->fh_array[i];
}

static int filelayout_initiate_commit(struct nfs_write_data *data, int how)
static int filelayout_initiate_commit(struct nfs_commit_data *data, int how)
{
	struct pnfs_layout_segment *lseg = data->lseg;
	struct nfs4_pnfs_ds *ds;
@@ -941,12 +968,12 @@ static int filelayout_initiate_commit(struct nfs_write_data *data, int how)
		return -EAGAIN;
	}
	dprintk("%s ino %lu, how %d\n", __func__, data->inode->i_ino, how);
	data->write_done_cb = filelayout_commit_done_cb;
	data->commit_done_cb = filelayout_commit_done_cb;
	data->ds_clp = ds->ds_clp;
	fh = select_ds_fh_from_commit(lseg, data->ds_commit_index);
	if (fh)
		data->args.fh = fh;
	return nfs_initiate_commit(data, ds->ds_clp->cl_rpcclient,
	return nfs_initiate_commit(ds->ds_clp->cl_rpcclient, data,
				   &filelayout_commit_call_ops, how);
}

@@ -1008,7 +1035,7 @@ alloc_ds_commits(struct inode *inode, struct list_head *list)
{
	struct nfs4_fl_commit_info *fl_cinfo;
	struct nfs4_fl_commit_bucket *bucket;
	struct nfs_write_data *data;
	struct nfs_commit_data *data;
	int i, j;
	unsigned int nreq = 0;

@@ -1044,7 +1071,7 @@ static int
filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
			   int how)
{
	struct nfs_write_data	*data, *tmp;
	struct nfs_commit_data *data, *tmp;
	LIST_HEAD(list);
	unsigned int nreq = 0;

@@ -1071,7 +1098,7 @@ filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
		list_del_init(&data->pages);
		if (!data->lseg) {
			nfs_init_commit(data, mds_pages, NULL);
			nfs_initiate_commit(data, NFS_CLIENT(inode),
			nfs_initiate_commit(NFS_CLIENT(inode), data,
					    data->mds_ops, how);
		} else {
			struct nfs4_fl_commit_info *fl_cinfo;
Loading