|
@@ -459,7 +459,6 @@ struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *ops)
|
|
|
if (hdr) {
|
|
|
INIT_LIST_HEAD(&hdr->pages);
|
|
|
spin_lock_init(&hdr->lock);
|
|
|
- atomic_set(&hdr->refcnt, 0);
|
|
|
hdr->rw_ops = ops;
|
|
|
}
|
|
|
return hdr;
|
|
@@ -477,31 +476,18 @@ void nfs_pgio_header_free(struct nfs_pgio_header *hdr)
|
|
|
EXPORT_SYMBOL_GPL(nfs_pgio_header_free);
|
|
|
|
|
|
/**
|
|
|
- * nfs_pgio_data_alloc - Allocate pageio data
|
|
|
- * @hdr: The header making a request
|
|
|
- * @pagecount: Number of pages to create
|
|
|
- */
|
|
|
-static bool nfs_pgio_data_init(struct nfs_pgio_header *hdr,
|
|
|
- unsigned int pagecount)
|
|
|
-{
|
|
|
- if (nfs_pgarray_set(&hdr->page_array, pagecount)) {
|
|
|
- atomic_inc(&hdr->refcnt);
|
|
|
- return true;
|
|
|
- }
|
|
|
- return false;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * nfs_pgio_data_destroy - Properly release pageio data
|
|
|
- * @hdr: The header with data to destroy
|
|
|
+ * nfs_pgio_data_destroy - make @hdr suitable for reuse
|
|
|
+ *
|
|
|
+ * Frees memory and releases refs from nfs_generic_pgio, so that it may
|
|
|
+ * be called again.
|
|
|
+ *
|
|
|
+ * @hdr: A header that has had nfs_generic_pgio called
|
|
|
*/
|
|
|
void nfs_pgio_data_destroy(struct nfs_pgio_header *hdr)
|
|
|
{
|
|
|
put_nfs_open_context(hdr->args.context);
|
|
|
if (hdr->page_array.pagevec != hdr->page_array.page_array)
|
|
|
kfree(hdr->page_array.pagevec);
|
|
|
- if (atomic_dec_and_test(&hdr->refcnt))
|
|
|
- hdr->completion_ops->completion(hdr);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(nfs_pgio_data_destroy);
|
|
|
|
|
@@ -620,6 +606,7 @@ static int nfs_pgio_error(struct nfs_pageio_descriptor *desc,
|
|
|
{
|
|
|
set_bit(NFS_IOHDR_REDO, &hdr->flags);
|
|
|
nfs_pgio_data_destroy(hdr);
|
|
|
+ hdr->completion_ops->completion(hdr);
|
|
|
desc->pg_completion_ops->error_cleanup(&desc->pg_list);
|
|
|
return -ENOMEM;
|
|
|
}
|
|
@@ -634,6 +621,7 @@ static void nfs_pgio_release(void *calldata)
|
|
|
if (hdr->rw_ops->rw_release)
|
|
|
hdr->rw_ops->rw_release(hdr);
|
|
|
nfs_pgio_data_destroy(hdr);
|
|
|
+ hdr->completion_ops->completion(hdr);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -707,9 +695,10 @@ int nfs_generic_pgio(struct nfs_pageio_descriptor *desc,
|
|
|
struct page **pages;
|
|
|
struct list_head *head = &desc->pg_list;
|
|
|
struct nfs_commit_info cinfo;
|
|
|
+ unsigned int pagecount;
|
|
|
|
|
|
- if (!nfs_pgio_data_init(hdr, nfs_page_array_len(desc->pg_base,
|
|
|
- desc->pg_count)))
|
|
|
+ pagecount = nfs_page_array_len(desc->pg_base, desc->pg_count);
|
|
|
+ if (!nfs_pgarray_set(&hdr->page_array, pagecount))
|
|
|
return nfs_pgio_error(desc, hdr);
|
|
|
|
|
|
nfs_init_cinfo(&cinfo, desc->pg_inode, desc->pg_dreq);
|
|
@@ -743,14 +732,11 @@ static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc)
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
nfs_pgheader_init(desc, hdr, nfs_pgio_header_free);
|
|
|
- atomic_inc(&hdr->refcnt);
|
|
|
ret = nfs_generic_pgio(desc, hdr);
|
|
|
if (ret == 0)
|
|
|
ret = nfs_initiate_pgio(NFS_CLIENT(hdr->inode),
|
|
|
hdr, desc->pg_rpc_callops,
|
|
|
desc->pg_ioflags, 0);
|
|
|
- if (atomic_dec_and_test(&hdr->refcnt))
|
|
|
- hdr->completion_ops->completion(hdr);
|
|
|
return ret;
|
|
|
}
|
|
|
|