|
@@ -60,14 +60,28 @@ static mempool_t *nfs_wdata_mempool;
|
|
|
static struct kmem_cache *nfs_cdata_cachep;
|
|
|
static mempool_t *nfs_commit_mempool;
|
|
|
|
|
|
-struct nfs_commit_data *nfs_commitdata_alloc(void)
|
|
|
+struct nfs_commit_data *nfs_commitdata_alloc(bool never_fail)
|
|
|
{
|
|
|
- struct nfs_commit_data *p = mempool_alloc(nfs_commit_mempool, GFP_NOIO);
|
|
|
+ struct nfs_commit_data *p;
|
|
|
|
|
|
- if (p) {
|
|
|
- memset(p, 0, sizeof(*p));
|
|
|
- INIT_LIST_HEAD(&p->pages);
|
|
|
+ if (never_fail)
|
|
|
+ p = mempool_alloc(nfs_commit_mempool, GFP_NOIO);
|
|
|
+ else {
|
|
|
+ /* It is OK to do some reclaim, not no safe to wait
|
|
|
+ * for anything to be returned to the pool.
|
|
|
+ * mempool_alloc() cannot handle that particular combination,
|
|
|
+ * so we need two separate attempts.
|
|
|
+ */
|
|
|
+ p = mempool_alloc(nfs_commit_mempool, GFP_NOWAIT);
|
|
|
+ if (!p)
|
|
|
+ p = kmem_cache_alloc(nfs_cdata_cachep, GFP_NOIO |
|
|
|
+ __GFP_NOWARN | __GFP_NORETRY);
|
|
|
+ if (!p)
|
|
|
+ return NULL;
|
|
|
}
|
|
|
+
|
|
|
+ memset(p, 0, sizeof(*p));
|
|
|
+ INIT_LIST_HEAD(&p->pages);
|
|
|
return p;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(nfs_commitdata_alloc);
|
|
@@ -82,8 +96,7 @@ static struct nfs_pgio_header *nfs_writehdr_alloc(void)
|
|
|
{
|
|
|
struct nfs_pgio_header *p = mempool_alloc(nfs_wdata_mempool, GFP_NOIO);
|
|
|
|
|
|
- if (p)
|
|
|
- memset(p, 0, sizeof(*p));
|
|
|
+ memset(p, 0, sizeof(*p));
|
|
|
return p;
|
|
|
}
|
|
|
|
|
@@ -1705,19 +1718,13 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how,
|
|
|
if (list_empty(head))
|
|
|
return 0;
|
|
|
|
|
|
- data = nfs_commitdata_alloc();
|
|
|
-
|
|
|
- if (!data)
|
|
|
- goto out_bad;
|
|
|
+ data = nfs_commitdata_alloc(true);
|
|
|
|
|
|
/* Set up the argument struct */
|
|
|
nfs_init_commit(data, head, NULL, cinfo);
|
|
|
atomic_inc(&cinfo->mds->rpcs_out);
|
|
|
return nfs_initiate_commit(NFS_CLIENT(inode), data, NFS_PROTO(inode),
|
|
|
data->mds_ops, how, 0);
|
|
|
- out_bad:
|
|
|
- nfs_retry_commit(head, NULL, cinfo, 0);
|
|
|
- return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
int nfs_commit_file(struct file *file, struct nfs_write_verifier *verf)
|