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

NFS: create nfs_commit_completion_ops



Factors out the code that needs to change when directio
starts using these code paths.

Signed-off-by: default avatarFred Isaman <iisaman@netapp.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent ea2cf228
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -344,13 +344,12 @@ extern int nfs_initiate_commit(struct rpc_clnt *clnt,
			       int how);
extern void nfs_init_commit(struct nfs_commit_data *data,
			    struct list_head *head,
			    struct pnfs_layout_segment *lseg);
			    struct pnfs_layout_segment *lseg,
			    struct nfs_commit_info *cinfo);
void nfs_retry_commit(struct list_head *page_list,
		      struct pnfs_layout_segment *lseg,
		      struct nfs_commit_info *cinfo);
void nfs_commit_clear_lock(struct nfs_inode *nfsi);
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 *dst,
				 struct nfs_commit_info *cinfo);
void nfs_request_remove_commit_list(struct nfs_page *req,
+4 −8
Original line number Diff line number Diff line
@@ -347,12 +347,8 @@ static void filelayout_commit_count_stats(struct rpc_task *task, void *data)
static void filelayout_commit_release(void *calldata)
{
	struct nfs_commit_data *data = calldata;
	struct nfs_commit_info cinfo;

	nfs_commit_release_pages(data);
	nfs_init_cinfo(&cinfo, data->inode, data->dreq);
	if (atomic_dec_and_test(&cinfo.mds->rpcs_out))
		nfs_commit_clear_lock(NFS_I(data->inode));
	data->completion_ops->completion(data);
	put_lseg(data->lseg);
	nfs_commitdata_release(data);
}
@@ -1108,7 +1104,7 @@ filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
	nreq += alloc_ds_commits(cinfo, &list);

	if (nreq == 0) {
		nfs_commit_clear_lock(NFS_I(inode));
		cinfo->completion_ops->error_cleanup(NFS_I(inode));
		goto out;
	}

@@ -1117,14 +1113,14 @@ filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
	list_for_each_entry_safe(data, tmp, &list, pages) {
		list_del_init(&data->pages);
		if (!data->lseg) {
			nfs_init_commit(data, mds_pages, NULL);
			nfs_init_commit(data, mds_pages, NULL, cinfo);
			nfs_initiate_commit(NFS_CLIENT(inode), data,
					    data->mds_ops, how);
		} else {
			struct pnfs_commit_bucket *buckets;

			buckets = cinfo->ds->buckets;
			nfs_init_commit(data, &buckets[data->ds_commit_index].committing, data->lseg);
			nfs_init_commit(data, &buckets[data->ds_commit_index].committing, data->lseg, cinfo);
			filelayout_initiate_commit(data, how);
		}
	}
+21 −10
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ static void nfs_redirty_request(struct nfs_page *req);
static const struct rpc_call_ops nfs_write_common_ops;
static const struct rpc_call_ops nfs_commit_ops;
static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops;
static const struct nfs_commit_completion_ops nfs_commit_completion_ops;

static struct kmem_cache *nfs_wdata_cachep;
static mempool_t *nfs_wdata_mempool;
@@ -505,6 +506,7 @@ static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo,
	cinfo->lock = &inode->i_lock;
	cinfo->mds = &NFS_I(inode)->commit_info;
	cinfo->ds = pnfs_get_ds_info(inode);
	cinfo->completion_ops = &nfs_commit_completion_ops;
}

void nfs_init_cinfo(struct nfs_commit_info *cinfo,
@@ -1358,13 +1360,12 @@ static int nfs_commit_set_lock(struct nfs_inode *nfsi, int may_wait)
	return (ret < 0) ? ret : 1;
}

void nfs_commit_clear_lock(struct nfs_inode *nfsi)
static void nfs_commit_clear_lock(struct nfs_inode *nfsi)
{
	clear_bit(NFS_INO_COMMIT, &nfsi->flags);
	smp_mb__after_clear_bit();
	wake_up_bit(&nfsi->flags, NFS_INO_COMMIT);
}
EXPORT_SYMBOL_GPL(nfs_commit_clear_lock);

void nfs_commitdata_release(struct nfs_commit_data *data)
{
@@ -1414,7 +1415,8 @@ EXPORT_SYMBOL_GPL(nfs_initiate_commit);
 */
void nfs_init_commit(struct nfs_commit_data *data,
		     struct list_head *head,
			    struct pnfs_layout_segment *lseg)
		     struct pnfs_layout_segment *lseg,
		     struct nfs_commit_info *cinfo)
{
	struct nfs_page *first = nfs_list_entry(head->next);
	struct inode *inode = first->wb_context->dentry->d_inode;
@@ -1428,6 +1430,7 @@ void nfs_init_commit(struct nfs_commit_data *data,
	data->cred	  = first->wb_context->cred;
	data->lseg	  = lseg; /* reference transferred */
	data->mds_ops     = &nfs_commit_ops;
	data->completion_ops = cinfo->completion_ops;

	data->args.fh     = NFS_FH(data->inode);
	/* Note: we always request a commit of the entire inode */
@@ -1473,11 +1476,12 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how,
		goto out_bad;

	/* Set up the argument struct */
	nfs_init_commit(data, head, NULL);
	nfs_init_commit(data, head, NULL, cinfo);
	atomic_inc(&cinfo->mds->rpcs_out);
	return nfs_initiate_commit(NFS_CLIENT(inode), data, data->mds_ops, how);
 out_bad:
	nfs_retry_commit(head, NULL, cinfo);
	nfs_commit_clear_lock(NFS_I(inode));
	cinfo->completion_ops->error_cleanup(NFS_I(inode));
	return -ENOMEM;
}

@@ -1495,10 +1499,11 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
	NFS_PROTO(data->inode)->commit_done(task, data);
}

void nfs_commit_release_pages(struct nfs_commit_data *data)
static void nfs_commit_release_pages(struct nfs_commit_data *data)
{
	struct nfs_page	*req;
	int status = data->task.tk_status;
	struct nfs_commit_info cinfo;

	while (!list_empty(&data->pages)) {
		req = nfs_list_entry(data->pages.next);
@@ -1531,15 +1536,16 @@ void nfs_commit_release_pages(struct nfs_commit_data *data)
	next:
		nfs_unlock_request(req);
	}
	nfs_init_cinfo(&cinfo, data->inode, data->dreq);
	if (atomic_dec_and_test(&cinfo.mds->rpcs_out))
		nfs_commit_clear_lock(NFS_I(data->inode));
}
EXPORT_SYMBOL_GPL(nfs_commit_release_pages);

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

	nfs_commit_release_pages(data);
	nfs_commit_clear_lock(NFS_I(data->inode));
	data->completion_ops->completion(data);
	nfs_commitdata_release(calldata);
}

@@ -1549,6 +1555,11 @@ static const struct rpc_call_ops nfs_commit_ops = {
	.rpc_release = nfs_commit_release,
};

static const struct nfs_commit_completion_ops nfs_commit_completion_ops = {
	.completion = nfs_commit_release_pages,
	.error_cleanup = nfs_commit_clear_lock,
};

static int nfs_generic_commit_list(struct inode *inode, struct list_head *head,
				   int how, struct nfs_commit_info *cinfo)
{
+9 −0
Original line number Diff line number Diff line
@@ -1263,10 +1263,18 @@ struct nfs_mds_commit_info {
	struct list_head	list;
};

struct nfs_commit_data;
struct nfs_inode;
struct nfs_commit_completion_ops {
	void (*error_cleanup) (struct nfs_inode *nfsi);
	void (*completion) (struct nfs_commit_data *data);
};

struct nfs_commit_info {
	spinlock_t			*lock;
	struct nfs_mds_commit_info	*mds;
	struct pnfs_ds_commit_info	*ds;
	const struct nfs_commit_completion_ops *completion_ops;
};

struct nfs_commit_data {
@@ -1285,6 +1293,7 @@ struct nfs_commit_data {
	struct nfs_client	*ds_clp;	/* pNFS data server */
	int			ds_commit_index;
	const struct rpc_call_ops *mds_ops;
	const struct nfs_commit_completion_ops *completion_ops;
	int (*commit_done_cb) (struct rpc_task *task, struct nfs_commit_data *data);
};