From patchwork Tue Nov 6 21:14:19 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 1706811 Return-Path: X-Original-To: patchwork-cifs-client@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 90493DFE75 for ; Tue, 6 Nov 2012 21:14:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752510Ab2KFVO1 (ORCPT ); Tue, 6 Nov 2012 16:14:27 -0500 Received: from mail-ye0-f174.google.com ([209.85.213.174]:50936 "EHLO mail-ye0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751468Ab2KFVO0 (ORCPT ); Tue, 6 Nov 2012 16:14:26 -0500 Received: by mail-ye0-f174.google.com with SMTP id m12so200101yen.19 for ; Tue, 06 Nov 2012 13:14:26 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=/VooHEWejw6zGlAxmXkmAZCqJs9edvGYc2lKsOLZ9yE=; b=EzuhcoCHhmHbRJ048VJ8evbt0xOpbI4uZGg8A20ZDrFvIXjMmVII1j+FNJUU4r9GiR yvLfg8USyBx4XAqmXti8A/WgvYkd08Doco5LHXGiVTtB96NX5ptM5xhAn3Ni/UdDkGUm QSvKxN7hnHYfaC4/1SgHujNDPqpEFSkvA3hREgwejJndWPZUQgDZ3mYZRPRgxW2bN8Ex 4ZyE9VNUesZJP2oEm3g5gtrJ0mLMfzLxdyZbi7S5Eg9WpmMegD7KlhxN2qb7voAnp4BY o/pfy2Qpsc6QuDPxCfK+WTRXI4LcV4pXYNsjAB4p0fRfcH2Bx5CtYjOLltxnREVi5nPP 8E5A== Received: by 10.236.181.225 with SMTP id l61mr2495567yhm.47.1352236465883; Tue, 06 Nov 2012 13:14:25 -0800 (PST) Received: from salusa.poochiereds.net (cpe-107-015-110-129.nc.res.rr.com. [107.15.110.129]) by mx.google.com with ESMTPS id g6sm19890908ani.5.2012.11.06.13.14.24 (version=SSLv3 cipher=OTHER); Tue, 06 Nov 2012 13:14:24 -0800 (PST) From: Jeff Layton To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org Subject: [PATCH v3 6/9] cifs: avoid extra allocation for small cifs.idmap keys Date: Tue, 6 Nov 2012 16:14:19 -0500 Message-Id: <1352236459-18787-1-git-send-email-jlayton@redhat.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1350649250-5343-7-git-send-email-jlayton@redhat.com> References: <1350649250-5343-7-git-send-email-jlayton@redhat.com> X-Gm-Message-State: ALoCoQkObfmVdKgrlcc3wfx+lSLxp47E20nFSoJq0ml5PHJGm4M4+ep1SXbhsiR6JAudw0G5edG+ Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org The cifs.idmap keytype always allocates memory to hold the payload from userspace. In the common case where we're translating a SID to a UID or GID, we're allocating memory to hold something that's less than or equal to the size of a pointer. When the payload is the same size as a pointer or smaller, just store it in the payload.value union member instead. That saves us an extra allocation on the sid_to_id upcall. Note that we have to take extra care to check the datalen when we go to dereference the .data pointer in the union, but the callers now check that as a matter of course anyway. Reviewed-by: Shirish Pargaonkar Signed-off-by: Jeff Layton --- fs/cifs/cifsacl.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index f4508ee..751d34b 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -49,6 +49,20 @@ cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep) { char *payload; + /* + * If the payload is less than or equal to the size of a pointer, then + * an allocation here is wasteful. Just copy the data directly to the + * payload.value union member instead. + * + * With this however, you must check the datalen before trying to + * dereference payload.data! + */ + if (prep->datalen <= sizeof(void *)) { + key->payload.value = 0; + memcpy(&key->payload.value, prep->data, prep->datalen); + key->datalen = prep->datalen; + return 0; + } payload = kmalloc(prep->datalen, GFP_KERNEL); if (!payload) return -ENOMEM; @@ -62,7 +76,8 @@ cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep) static inline void cifs_idmap_key_destroy(struct key *key) { - kfree(key->payload.data); + if (key->datalen > sizeof(void *)) + kfree(key->payload.data); } static struct key_type cifs_idmap_key_type = { @@ -245,7 +260,7 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, * probably a safe assumption but might be better to check based on * sidtype. */ - if (sidkey->datalen < sizeof(uid_t)) { + if (sidkey->datalen != sizeof(uid_t)) { rc = -EIO; cFYI(1, "%s: Downcall contained malformed key " "(datalen=%hu)", __func__, sidkey->datalen); @@ -253,9 +268,9 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, } if (sidtype == SIDOWNER) - fuid = *(uid_t *)sidkey->payload.value; + memcpy(&fuid, &sidkey->payload.value, sizeof(uid_t)); else - fgid = *(gid_t *)sidkey->payload.value; + memcpy(&fgid, &sidkey->payload.value, sizeof(gid_t)); out_key_put: key_put(sidkey);