From patchwork Wed Oct 17 18:09:02 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 1607451 Return-Path: X-Original-To: patchwork-cifs-client@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id B375C40135 for ; Wed, 17 Oct 2012 18:09:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757593Ab2JQSJT (ORCPT ); Wed, 17 Oct 2012 14:09:19 -0400 Received: from mail-yh0-f46.google.com ([209.85.213.46]:37068 "EHLO mail-yh0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752080Ab2JQSJR (ORCPT ); Wed, 17 Oct 2012 14:09:17 -0400 Received: by mail-yh0-f46.google.com with SMTP id m54so2178135yhm.19 for ; Wed, 17 Oct 2012 11:09:17 -0700 (PDT) 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=ClijahvxVvB2ms83pwb5FUp0eDAuDzcNlBEdlFeKZjc=; b=LXYuSifVJOXu9AYPqYF9tjPzAhpHhr5f5+eNEVrAAbogEYsOcs24E7jnsRPtX1rzZ8 lHUM5lgq1NeAzb1W+RFQhyksQpkuR156Ymv+aq6kTNVSv3D03Fs3rR69GqOfTYWTiArF FEyXwfdqLLlgLJU+8FtUpABpr7WfTXLKP/j7gQSpUAMnomrm5CejntJlXNuBS5nthvjc PlSTydTOaVoKuJxpDjaPdvg5uHMfp1d6dZYChJmQmn7i/FVNIZJlva6dumtwjPBlbAwH AliqHdRXkz/K0N4ZOoagpiQkdqiepUCr0DjYVEOM0J+BcyuHLavb9T6NN6MAv7o3wO+Z dj3w== Received: by 10.236.83.103 with SMTP id p67mr18315488yhe.78.1350497357586; Wed, 17 Oct 2012 11:09:17 -0700 (PDT) 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 k63sm9397062yhj.20.2012.10.17.11.09.16 (version=SSLv3 cipher=OTHER); Wed, 17 Oct 2012 11:09:16 -0700 (PDT) From: Jeff Layton To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, shirishpargaonkar@gmail.com Subject: [PATCH 6/7] cifs: avoid extra allocation for small cifs.idmap keys Date: Wed, 17 Oct 2012 14:09:02 -0400 Message-Id: <1350497343-7155-7-git-send-email-jlayton@redhat.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1350497343-7155-1-git-send-email-jlayton@redhat.com> References: <1350497343-7155-1-git-send-email-jlayton@redhat.com> X-Gm-Message-State: ALoCoQlVXc9Or0qWQwFJ+BnE56jRtXzAfodirF1+KguJnxggFcrD0XTjXCQpZtbkpVBxSwL8iQhH 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. 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..82d264f 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(unsigned long)) { + 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(unsigned long)) + 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; + fuid = (uid_t)sidkey->payload.value; else - fgid = *(gid_t *)sidkey->payload.value; + fgid = (gid_t)sidkey->payload.value; out_key_put: key_put(sidkey);