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

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
...@@ -344,13 +344,12 @@ extern int nfs_initiate_commit(struct rpc_clnt *clnt, ...@@ -344,13 +344,12 @@ extern int nfs_initiate_commit(struct rpc_clnt *clnt,
int how); int how);
extern void nfs_init_commit(struct nfs_commit_data *data, extern void nfs_init_commit(struct nfs_commit_data *data,
struct list_head *head, 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, void nfs_retry_commit(struct list_head *page_list,
struct pnfs_layout_segment *lseg, struct pnfs_layout_segment *lseg,
struct nfs_commit_info *cinfo); 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_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, void nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst,
struct nfs_commit_info *cinfo); struct nfs_commit_info *cinfo);
void nfs_request_remove_commit_list(struct nfs_page *req, void nfs_request_remove_commit_list(struct nfs_page *req,
......
...@@ -347,12 +347,8 @@ static void filelayout_commit_count_stats(struct rpc_task *task, void *data) ...@@ -347,12 +347,8 @@ static void filelayout_commit_count_stats(struct rpc_task *task, void *data)
static void filelayout_commit_release(void *calldata) static void filelayout_commit_release(void *calldata)
{ {
struct nfs_commit_data *data = calldata; struct nfs_commit_data *data = calldata;
struct nfs_commit_info cinfo;
nfs_commit_release_pages(data); data->completion_ops->completion(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));
put_lseg(data->lseg); put_lseg(data->lseg);
nfs_commitdata_release(data); nfs_commitdata_release(data);
} }
...@@ -1108,7 +1104,7 @@ filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages, ...@@ -1108,7 +1104,7 @@ filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
nreq += alloc_ds_commits(cinfo, &list); nreq += alloc_ds_commits(cinfo, &list);
if (nreq == 0) { if (nreq == 0) {
nfs_commit_clear_lock(NFS_I(inode)); cinfo->completion_ops->error_cleanup(NFS_I(inode));
goto out; goto out;
} }
...@@ -1117,14 +1113,14 @@ filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages, ...@@ -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_for_each_entry_safe(data, tmp, &list, pages) {
list_del_init(&data->pages); list_del_init(&data->pages);
if (!data->lseg) { 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, nfs_initiate_commit(NFS_CLIENT(inode), data,
data->mds_ops, how); data->mds_ops, how);
} else { } else {
struct pnfs_commit_bucket *buckets; struct pnfs_commit_bucket *buckets;
buckets = cinfo->ds->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); filelayout_initiate_commit(data, how);
} }
} }
......
...@@ -46,6 +46,7 @@ static void nfs_redirty_request(struct nfs_page *req); ...@@ -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_write_common_ops;
static const struct rpc_call_ops nfs_commit_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_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 struct kmem_cache *nfs_wdata_cachep;
static mempool_t *nfs_wdata_mempool; static mempool_t *nfs_wdata_mempool;
...@@ -505,6 +506,7 @@ static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo, ...@@ -505,6 +506,7 @@ static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo,
cinfo->lock = &inode->i_lock; cinfo->lock = &inode->i_lock;
cinfo->mds = &NFS_I(inode)->commit_info; cinfo->mds = &NFS_I(inode)->commit_info;
cinfo->ds = pnfs_get_ds_info(inode); cinfo->ds = pnfs_get_ds_info(inode);
cinfo->completion_ops = &nfs_commit_completion_ops;
} }
void nfs_init_cinfo(struct nfs_commit_info *cinfo, 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) ...@@ -1358,13 +1360,12 @@ static int nfs_commit_set_lock(struct nfs_inode *nfsi, int may_wait)
return (ret < 0) ? ret : 1; 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); clear_bit(NFS_INO_COMMIT, &nfsi->flags);
smp_mb__after_clear_bit(); smp_mb__after_clear_bit();
wake_up_bit(&nfsi->flags, NFS_INO_COMMIT); wake_up_bit(&nfsi->flags, NFS_INO_COMMIT);
} }
EXPORT_SYMBOL_GPL(nfs_commit_clear_lock);
void nfs_commitdata_release(struct nfs_commit_data *data) void nfs_commitdata_release(struct nfs_commit_data *data)
{ {
...@@ -1414,7 +1415,8 @@ EXPORT_SYMBOL_GPL(nfs_initiate_commit); ...@@ -1414,7 +1415,8 @@ EXPORT_SYMBOL_GPL(nfs_initiate_commit);
*/ */
void nfs_init_commit(struct nfs_commit_data *data, void nfs_init_commit(struct nfs_commit_data *data,
struct list_head *head, 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 nfs_page *first = nfs_list_entry(head->next);
struct inode *inode = first->wb_context->dentry->d_inode; struct inode *inode = first->wb_context->dentry->d_inode;
...@@ -1428,6 +1430,7 @@ void nfs_init_commit(struct nfs_commit_data *data, ...@@ -1428,6 +1430,7 @@ void nfs_init_commit(struct nfs_commit_data *data,
data->cred = first->wb_context->cred; data->cred = first->wb_context->cred;
data->lseg = lseg; /* reference transferred */ data->lseg = lseg; /* reference transferred */
data->mds_ops = &nfs_commit_ops; data->mds_ops = &nfs_commit_ops;
data->completion_ops = cinfo->completion_ops;
data->args.fh = NFS_FH(data->inode); data->args.fh = NFS_FH(data->inode);
/* Note: we always request a commit of the entire 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, ...@@ -1473,11 +1476,12 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how,
goto out_bad; goto out_bad;
/* Set up the argument struct */ /* 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); return nfs_initiate_commit(NFS_CLIENT(inode), data, data->mds_ops, how);
out_bad: out_bad:
nfs_retry_commit(head, NULL, cinfo); nfs_retry_commit(head, NULL, cinfo);
nfs_commit_clear_lock(NFS_I(inode)); cinfo->completion_ops->error_cleanup(NFS_I(inode));
return -ENOMEM; return -ENOMEM;
} }
...@@ -1495,10 +1499,11 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata) ...@@ -1495,10 +1499,11 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
NFS_PROTO(data->inode)->commit_done(task, data); 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; struct nfs_page *req;
int status = data->task.tk_status; int status = data->task.tk_status;
struct nfs_commit_info cinfo;
while (!list_empty(&data->pages)) { while (!list_empty(&data->pages)) {
req = nfs_list_entry(data->pages.next); req = nfs_list_entry(data->pages.next);
...@@ -1531,15 +1536,16 @@ void nfs_commit_release_pages(struct nfs_commit_data *data) ...@@ -1531,15 +1536,16 @@ void nfs_commit_release_pages(struct nfs_commit_data *data)
next: next:
nfs_unlock_request(req); 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) static void nfs_commit_release(void *calldata)
{ {
struct nfs_commit_data *data = calldata; struct nfs_commit_data *data = calldata;
nfs_commit_release_pages(data); data->completion_ops->completion(data);
nfs_commit_clear_lock(NFS_I(data->inode));
nfs_commitdata_release(calldata); nfs_commitdata_release(calldata);
} }
...@@ -1549,6 +1555,11 @@ static const struct rpc_call_ops nfs_commit_ops = { ...@@ -1549,6 +1555,11 @@ static const struct rpc_call_ops nfs_commit_ops = {
.rpc_release = nfs_commit_release, .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, static int nfs_generic_commit_list(struct inode *inode, struct list_head *head,
int how, struct nfs_commit_info *cinfo) int how, struct nfs_commit_info *cinfo)
{ {
......
...@@ -1263,10 +1263,18 @@ struct nfs_mds_commit_info { ...@@ -1263,10 +1263,18 @@ struct nfs_mds_commit_info {
struct list_head list; 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 { struct nfs_commit_info {
spinlock_t *lock; spinlock_t *lock;
struct nfs_mds_commit_info *mds; struct nfs_mds_commit_info *mds;
struct pnfs_ds_commit_info *ds; struct pnfs_ds_commit_info *ds;
const struct nfs_commit_completion_ops *completion_ops;
}; };
struct nfs_commit_data { struct nfs_commit_data {
...@@ -1285,6 +1293,7 @@ struct nfs_commit_data { ...@@ -1285,6 +1293,7 @@ struct nfs_commit_data {
struct nfs_client *ds_clp; /* pNFS data server */ struct nfs_client *ds_clp; /* pNFS data server */
int ds_commit_index; int ds_commit_index;
const struct rpc_call_ops *mds_ops; 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); int (*commit_done_cb) (struct rpc_task *task, struct nfs_commit_data *data);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment