NFS: create nfs_commit_completion_ops
Factors out the code that needs to change when directio starts using these code paths. Signed-off-by: Fred Isaman <iisaman@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
ea2cf2282b
commit
f453a54a01
4 changed files with 36 additions and 21 deletions
|
@ -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)
|
||||||
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,
|
||||||
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,
|
||||||
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);
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
@ -1413,8 +1414,9 @@ EXPORT_SYMBOL_GPL(nfs_initiate_commit);
|
||||||
* Set up the argument/result storage required for the RPC call.
|
* Set up the argument/result storage required for the RPC call.
|
||||||
*/
|
*/
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
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 = {
|
||||||
.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 {
|
||||||
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 {
|
||||||
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue