From: "J. Bruce Fields" <bfields@redhat.com>
To: linux-nfs@vger.kernel.org
Cc: Trond Myklebust <trondmy@gmail.com>,
"J. Bruce Fields" <bfields@redhat.com>
Subject: [PATCH 8/8] nfsd4: replace defer_free by svcxdr_tmpalloc
Date: Wed, 25 Jun 2014 21:48:08 -0400 [thread overview]
Message-ID: <1403747288-21590-8-git-send-email-bfields@redhat.com> (raw)
In-Reply-To: <1403747288-21590-1-git-send-email-bfields@redhat.com>
From: "J. Bruce Fields" <bfields@redhat.com>
Avoid an extra allocation for the tmpbuf struct itself, and stop
ignoring some allocation failures.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
---
fs/nfsd/nfs4xdr.c | 46 +++++++++++++++++-----------------------------
fs/nfsd/xdr4.h | 13 +++++++++----
2 files changed, 26 insertions(+), 33 deletions(-)
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index be4f19c..46115f2 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -181,25 +181,24 @@ static int zero_clientid(clientid_t *clid)
}
/**
- * defer_free - mark an allocation as deferred freed
+ * svcxdr_tmpalloc - allocate memory to be freed after compound processing
* @argp: NFSv4 compound argument structure
* @p: pointer to be freed (with kfree())
*
* Marks @p to be freed when processing the compound operation
* described in @argp finishes.
*/
-static int
-defer_free(struct nfsd4_compoundargs *argp, void *p)
+static void *
+svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, u32 len)
{
- struct tmpbuf *tb;
+ struct svcxdr_tmpbuf *tb;
- tb = kmalloc(sizeof(*tb), GFP_KERNEL);
+ tb = kmalloc(sizeof(*tb) + len, GFP_KERNEL);
if (!tb)
- return -ENOMEM;
- tb->buf = p;
+ return NULL;
tb->next = argp->to_free;
argp->to_free = tb;
- return 0;
+ return tb->buf;
}
/*
@@ -212,13 +211,12 @@ defer_free(struct nfsd4_compoundargs *argp, void *p)
static char *
svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len)
{
- char *p = kmalloc(len + 1, GFP_KERNEL);
+ char *p = svcxdr_tmpalloc(argp, len + 1);
if (!p)
return NULL;
memcpy(p, buf, len);
p[len] = '\0';
- defer_free(argp, p);
return p;
}
@@ -234,19 +232,13 @@ svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len)
*/
static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
{
- if (p == argp->tmp) {
- p = kmemdup(argp->tmp, nbytes, GFP_KERNEL);
- if (!p)
- return NULL;
- } else {
- BUG_ON(p != argp->tmpp);
- argp->tmpp = NULL;
- }
- if (defer_free(argp, p)) {
- kfree(p);
+ void *ret;
+
+ ret = svcxdr_tmpalloc(argp, nbytes);
+ if (!ret)
return NULL;
- } else
- return (char *)p;
+ memcpy(ret, p, nbytes);
+ return ret;
}
static __be32
@@ -309,12 +301,10 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
if (nace > NFS4_ACL_MAX)
return nfserr_fbig;
- *acl = kmalloc(nfs4_acl_size(nace), GFP_KERNEL);
+ *acl = svcxdr_tmpalloc(argp, nfs4_acl_bytes(nace));
if (*acl == NULL)
return nfserr_jukebox;
- defer_free(argp, *acl);
-
(*acl)->naces = nace;
for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) {
READ_BUF(16); len += 16;
@@ -1487,13 +1477,12 @@ nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_sta
INIT_LIST_HEAD(&test_stateid->ts_stateid_list);
for (i = 0; i < test_stateid->ts_num_ids; i++) {
- stateid = kmalloc(sizeof(struct nfsd4_test_stateid_id), GFP_KERNEL);
+ stateid = svcxdr_tmpalloc(argp, sizeof(*stateid));
if (!stateid) {
status = nfserrno(-ENOMEM);
goto out;
}
- defer_free(argp, stateid);
INIT_LIST_HEAD(&stateid->ts_id_list);
list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list);
@@ -3977,9 +3966,8 @@ int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp)
kfree(args->tmpp);
args->tmpp = NULL;
while (args->to_free) {
- struct tmpbuf *tb = args->to_free;
+ struct svcxdr_tmpbuf *tb = args->to_free;
args->to_free = tb->next;
- kfree(tb->buf);
kfree(tb);
}
return 1;
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 4379cc8..efce901 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -478,6 +478,14 @@ struct nfsd4_op {
bool nfsd4_cache_this_op(struct nfsd4_op *);
+/*
+ * Memory needed just for the duration of processing one compound:
+ */
+struct svcxdr_tmpbuf {
+ struct svcxdr_tmpbuf *next;
+ char buf[];
+};
+
struct nfsd4_compoundargs {
/* scratch variables for XDR decode */
__be32 * p;
@@ -486,10 +494,7 @@ struct nfsd4_compoundargs {
int pagelen;
__be32 tmp[8];
__be32 * tmpp;
- struct tmpbuf {
- struct tmpbuf *next;
- void *buf;
- } *to_free;
+ struct svcxdr_tmpbuf *to_free;
struct svc_rqst *rqstp;
--
1.7.9.5
prev parent reply other threads:[~2014-06-26 1:48 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20140624204418.GG2343@pad.redhat.com>
2014-06-26 1:48 ` [PATCH 1/8] nfsd: fix rare symlink decoding bug J. Bruce Fields
2014-06-26 1:48 ` [PATCH 2/8] nfsd: make NFSv2 null terminate symlink data J. Bruce Fields
2014-06-26 1:48 ` [PATCH 3/8] nfsd: let nfsd_symlink assume null-terminated data J. Bruce Fields
2014-06-26 1:48 ` [PATCH 4/8] nfsd4: rename cr_linkname->cr_data J. Bruce Fields
2014-06-26 1:48 ` [PATCH 5/8] nfsd4: remove unused defer_free argument J. Bruce Fields
2014-06-26 1:48 ` [PATCH 6/8] nfsd4: define svcxdr_dupstr to share some common code J. Bruce Fields
2014-06-26 1:48 ` [PATCH 7/8] nfsd4: remove nfs4_acl_new J. Bruce Fields
2014-06-26 1:48 ` J. Bruce Fields [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1403747288-21590-8-git-send-email-bfields@redhat.com \
--to=bfields@redhat.com \
--cc=linux-nfs@vger.kernel.org \
--cc=trondmy@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox