Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp578889imm; Mon, 21 May 2018 10:38:46 -0700 (PDT) X-Google-Smtp-Source: AB8JxZquFTPYt2qR32k2q2t/eTjSy/kssQ5fvrua+m8E6XS/Lh7eogRV3h7znFfb7K8VDZBaA+wm X-Received: by 2002:a62:4387:: with SMTP id l7-v6mr20652582pfi.55.1526924326620; Mon, 21 May 2018 10:38:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526924326; cv=none; d=google.com; s=arc-20160816; b=nzvI+TC3X49frN4d5TVRhOZ5FB4vjRPK0iVxAY5P3P0rh8IOA41OyrnAXhxYkfHUGV QAHKrOAPY+H+fphuS7iu0yDyyDEppU8KirDjgF7jS7Jt8Fiz87buUUUOPFGdms4BFVB0 OZYnUbXJRu6zv8EVutCeM8+6tBluQmIOwUgg+xSIamW7CrUzf8h5dAjsbmtACgEoM9Pq OlkFf3qbhREcQhDt07n+UHFUygHLwQFfIh5VxNQjzESUb1FTjXJ/Bc6owmpePRZsyM6I GU/gGzF8JqRzbpOSO1hDIzBJ49eXJUvMooDJDendM/2Y0R8XoFiNayLNK/698KhMxI03 Asrw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=0Jq1D/ZjfecF8oYbhaiP9vlYTELWHwtETc07lu+ZO3o=; b=koLB1ahGDDp0c3sFnqtK4+r+kuIeSnvwkoTLVaq7oW5EVyqVz8MbDg/GknOXz3aWr+ DOnCEJx99EJ8HTGe7Izg20j3C5UjXGf1l8lM6k98sokJwNPYhrV27ieW7/zRfuA8XWrg EF5kkK57Kyns5oM4s6cKx03EST72iYORTKoL0pW4iuIkeZgvmSzFOjqHEdLGSq1/09Na pHWAq9Kqs6neSFfBJF4z+9EOq9EK0Z1Zmg9nnlpN23128XnW4k6IYnejVMFDiYa7X47r k0No07eHITe4E1TSCa3jCpy2tRynqAUfjRCWwcNTbJrTa8zejgNXlID/dRX3aml9ztJ1 QEwQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.co.uk Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b8-v6si15575680pls.261.2018.05.21.10.38.31; Mon, 21 May 2018 10:38:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.co.uk Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753528AbeEURhg (ORCPT + 99 others); Mon, 21 May 2018 13:37:36 -0400 Received: from bhuna.collabora.co.uk ([46.235.227.227]:45344 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753624AbeEURgk (ORCPT ); Mon, 21 May 2018 13:36:40 -0400 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: krisman) with ESMTPSA id 7095C28719F From: Gabriel Krisman Bertazi To: viro@ZenIV.linux.org.uk Cc: jra@google.com, tytso@mit.edu, olaf@sgi.com, darrick.wong@oracle.com, kernel@lists.collabora.co.uk, linux-fsdevel@vger.kernel.org, david@fromorbit.com, jack@suse.cz, linux-kernel@vger.kernel.org, Gabriel Krisman Bertazi Subject: [PATCH v2 06/15] nls: Add support for multiple versions of an encoding Date: Mon, 21 May 2018 14:36:08 -0300 Message-Id: <20180521173617.31625-7-krisman@collabora.co.uk> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180521173617.31625-1-krisman@collabora.co.uk> References: <20180521173617.31625-1-krisman@collabora.co.uk> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org NLS charsets wanting to use this feature can implement the load_create() hook, which creates a nls_table for that specific encoding version. The charset code is responsible for freeing the table memory when the module is removed. Signed-off-by: Gabriel Krisman Bertazi --- fs/nls/nls_core.c | 43 +++++++++++++++++++++++++++++++++++++------ include/linux/nls.h | 4 ++++ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/fs/nls/nls_core.c b/fs/nls/nls_core.c index f4f91f5870ba..989f5ac48a50 100644 --- a/fs/nls/nls_core.c +++ b/fs/nls/nls_core.c @@ -19,10 +19,27 @@ extern struct nls_charset default_charset; static struct nls_charset *charsets = &default_charset; static DEFINE_SPINLOCK(nls_lock); -static struct nls_table *nls_load_table(struct nls_charset *charset) + +static struct nls_table *nls_load_table(struct nls_charset *charset, + const char *version) { - /* For now, return the default table, which is the first one found. */ - return charset->tables; + struct nls_table *tbl; + + if (!charset->load_table) { + /* If there is no table_create, only 1 table is + * supported and it must have been loaded + * statically. + */ + return charset->tables; + } + + tbl = charset->load_table(version); + if (!tbl) { + /* Invalid version */ + return ERR_PTR(-EINVAL); + } + + return tbl; } int __register_nls(struct nls_charset *nls, struct module *owner) @@ -76,21 +93,35 @@ static struct nls_charset *find_nls(char *charset) break; } if (nls && !try_module_get(nls->owner)) - nls = NULL; + nls = ERR_PTR(-EBUSY); spin_unlock(&nls_lock); return nls; } -struct nls_table *load_nls(char *charset) +struct nls_table *load_nls_version(char *charset, char *version) { struct nls_charset *nls_charset; nls_charset = try_then_request_module(find_nls(charset), "nls_%s", charset); if (!nls_charset) + return ERR_PTR(-EINVAL); + + return nls_load_table(nls_charset, version); +} +EXPORT_SYMBOL(load_nls_version); + +struct nls_table *load_nls(char *charset) +{ + struct nls_table *table = load_nls_version(charset, NULL); + + /* Pre-versioned load_nls() didn't return error pointers. Let's + * keep the abi for now to prevent breakage. + */ + if (IS_ERR(table)) return NULL; - return nls_load_table(nls_charset); + return table; } void unload_nls(struct nls_table *nls) diff --git a/include/linux/nls.h b/include/linux/nls.h index cdc95cd9e5d4..3766fbe6efc3 100644 --- a/include/linux/nls.h +++ b/include/linux/nls.h @@ -30,6 +30,8 @@ struct nls_ops { struct nls_table { const struct nls_charset *charset; + unsigned int version; + const struct nls_ops *ops; const unsigned char *charset2lower; const unsigned char *charset2upper; @@ -42,6 +44,7 @@ struct nls_charset { struct module *owner; struct nls_table *tables; struct nls_charset *next; + struct nls_table *(*load_table)(const char *version); }; /* this value hold the maximum octet of charset */ @@ -58,6 +61,7 @@ enum utf16_endian { extern int __register_nls(struct nls_charset *, struct module *); extern int unregister_nls(struct nls_charset *); extern struct nls_table *load_nls(char *); +extern struct nls_table *load_nls_version(char *charset, char *version); extern void unload_nls(struct nls_table *); extern struct nls_table *load_nls_default(void); #define register_nls(nls) __register_nls((nls), THIS_MODULE) -- 2.17.0