Received: by 2002:a05:6a10:c604:0:0:0:0 with SMTP id y4csp2041418pxt; Sun, 8 Aug 2021 09:30:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJybKYUPwQhfl7XJ8Su3OO+E/fWqnXdUkThM7fOFzNfZx90kzWPzl5p+re1hBlFaQHqVjXMS X-Received: by 2002:a17:906:4d50:: with SMTP id b16mr19298286ejv.501.1628440207228; Sun, 08 Aug 2021 09:30:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1628440207; cv=none; d=google.com; s=arc-20160816; b=uJlx1UIyfdMsIYZJJjUj1n7uYBs5U7tB3Kj6ry75uB4FfPEBzVeJxBfLf0Hl/98ZKp +JrcG39/IiArV25s7sJYFmEufsvNY7RzpuwTykano+PM3zVkRkNJ1NlWLjbVqYv8mIQ6 EFvVcMFXIx3tUXLS8CD2yznNS4jCliN2hrfVR7AZqbtIQNswtgmZq8/PhQQjKMOydnZV 5W8fimeDpIKMsVp+tXqsFzoEtHissY/joMOyCBWSpx5UHGFWHLqxVms2YukhFPCGuLL8 3xfEa7UEd5k/7cvUGGm4nC0LjPVhg/brwa8umylGFGzQKVTgKS7D4pyfFXkAJ3/356vg b7Mw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=/ovigjHofSNQKm8k02AsmgY2nJfUQ67NJOXObmeXk6w=; b=Ibe+9Cg6ohCMEJOWp+rxOQp0Y7Keh1dX+ETJiXEsL9rjCOoxI9AZGD75PIq8dOtMWY 0fuPZq7TyZ9cUcPn90PeC6XOsJP1TGhYs7l1PaK2pXm11DD1WlHZJJuyvOcLkn8Owmky Bq/2Rv9BFzsA9ByqkuAgnllFkPRHKfh1uw7eOTW0GOJWdcFruRR84PIjsxPfr+ueJKFl uSe6lVm304ab1AgC9Xrhin9n32IHMDksBqP+zkQf2IhD5q3j+R8Qa1b8ge05ug0iycCF 4aHWfXNWzDn+7jQqxBSkd6qpqxNar0p4+au6o3kGQI6NtevFw/moO6TFgGkMf3Oo1kQn 5ORg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="Dvu/AnbA"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id la2si14520451ejc.153.2021.08.08.09.29.42; Sun, 08 Aug 2021 09:30:07 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="Dvu/AnbA"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232598AbhHHQ0T (ORCPT + 99 others); Sun, 8 Aug 2021 12:26:19 -0400 Received: from mail.kernel.org ([198.145.29.99]:47554 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231933AbhHHQZh (ORCPT ); Sun, 8 Aug 2021 12:25:37 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 4E7826103B; Sun, 8 Aug 2021 16:25:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1628439918; bh=Y0Q6rt+tDWZMBi0N4PwxXpAY8aZOyLa7NpaJo/VUL6k=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Dvu/AnbAZPEBaBQPuIZJm8QvDcGhRBm08stqQ3DK71DNbQpFCFI7FwsrM2Eyo9xZZ j2lP4/wkv2OB6oYYR1OJ3+BfxNwQBt0tw4umUTB4NXXrekUqFgDqVx/vWKZVTExkB/ rpUSKnx3NBChV1HNldnKnFY+0YYUPeWwlSJOH+GwQgiRjeFBA+zqDxVZoGjD8O5kh3 HUU5nuvDle+bkxTt2ZJRYOkDcD0KQKr6eY5NF7N6vZdZ0gZOFJvNAhrKLlEmrXMqGD oOKj7wYpSMJZ+dqhTq3aNoePBFFfVjZJRPdM35CrNTCq5nNlKkUx7ZOQXciYfgUbQW Xe9HAz3pDKlcw== Received: by pali.im (Postfix) id 0FB2B13DC; Sun, 8 Aug 2021 18:25:18 +0200 (CEST) From: =?UTF-8?q?Pali=20Roh=C3=A1r?= To: linux-fsdevel@vger.kernel.org, linux-ntfs-dev@lists.sourceforge.net, linux-cifs@vger.kernel.org, jfs-discussion@lists.sourceforge.net, linux-kernel@vger.kernel.org, Alexander Viro , Jan Kara , OGAWA Hirofumi , "Theodore Y . Ts'o" , Luis de Bethencourt , Salah Triki , Andrew Morton , Dave Kleikamp , Anton Altaparmakov , Pavel Machek , =?UTF-8?q?Marek=20Beh=C3=BAn?= , Christoph Hellwig Subject: [RFC PATCH 11/20] hfs: Explicitly set hsb->nls_disk when hsb->nls_io is set Date: Sun, 8 Aug 2021 18:24:44 +0200 Message-Id: <20210808162453.1653-12-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210808162453.1653-1-pali@kernel.org> References: <20210808162453.1653-1-pali@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org It does not make any sense to set hsb->nls_io (NLS iocharset used between VFS and hfs driver) when hsb->nls_disk (NLS codepage used between hfs driver and disk) is not set. Reverse engineering driver code shown what is doing in this special case: When codepage was not defined but iocharset was then hfs driver copied 8bit character from disk directly to 16bit unicode wchar_t type. Which means it did conversion from Latin1 (ISO-8859-1) to Unicode because first 256 Unicode code points matches 8bit ISO-8859-1 codepage table. So when iocharset was specified and codepage not, then codepage used implicit value "iso8859-1". So when hsb->nls_disk is not set and hsb->nls_io is then explicitly set hsb->nls_disk to "iso8859-1". Such setup is obviously incompatible with Mac OS systems as they do not support iso8859-1 encoding for hfs. So print warning into dmesg about this fact. After this change hsb->nls_disk is always set, so remove code paths for case when hsb->nls_disk was not set as they are not needed anymore. Signed-off-by: Pali Rohár --- fs/hfs/super.c | 31 +++++++++++++++++++++++++++++++ fs/hfs/trans.c | 38 ++++++++++++++------------------------ 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 12d9bae39363..86bc46746c7f 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -351,6 +351,37 @@ static int parse_options(char *options, struct hfs_sb_info *hsb) } } + if (hsb->nls_io && !hsb->nls_disk) { + /* + * Previous version of hfs driver did something unexpected: + * When codepage was not defined but iocharset was then + * hfs driver copied 8bit character from disk directly to + * 16bit unicode wchar_t type. Which means it did conversion + * from Latin1 (ISO-8859-1) to Unicode because first 256 + * Unicode code points matches 8bit ISO-8859-1 codepage table. + * So when iocharset was specified and codepage not, then + * codepage used implicit value "iso8859-1". + * + * To not change this previous default behavior as some users + * may depend on it, we load iso8859-1 NLS table explicitly + * to simplify code and make it more reable what happens. + * + * In context of hfs driver it is really strange to use + * ISO-8859-1 codepage table for storing data to disk, but + * nothing forbids it. Just it is highly incompatible with + * Mac OS systems. So via pr_warn() inform user that this + * is not probably what he wants. + */ + pr_warn("iocharset was specified but codepage not, " + "using default codepage=iso8859-1\n"); + pr_warn("this default codepage=iso8859-1 is incompatible with " + "Mac OS systems and may be changed in the future"); + hsb->nls_disk = load_nls("iso8859-1"); + if (!hsb->nls_disk) { + pr_err("unable to load iso8859-1 codepage\n"); + return 0; + } + } if (hsb->nls_disk && !hsb->nls_io) { hsb->nls_io = load_nls_default(); if (!hsb->nls_io) { diff --git a/fs/hfs/trans.c b/fs/hfs/trans.c index 39f5e343bf4d..c75682c61b06 100644 --- a/fs/hfs/trans.c +++ b/fs/hfs/trans.c @@ -48,18 +48,13 @@ int hfs_mac2asc(struct super_block *sb, char *out, const struct hfs_name *in) wchar_t ch; while (srclen > 0) { - if (nls_disk) { - size = nls_disk->char2uni(src, srclen, &ch); - if (size <= 0) { - ch = '?'; - size = 1; - } - src += size; - srclen -= size; - } else { - ch = *src++; - srclen--; + size = nls_disk->char2uni(src, srclen, &ch); + if (size <= 0) { + ch = '?'; + size = 1; } + src += size; + srclen -= size; if (ch == '/') ch = ':'; size = nls_io->uni2char(ch, dst, dstlen); @@ -119,20 +114,15 @@ void hfs_asc2mac(struct super_block *sb, struct hfs_name *out, const struct qstr srclen -= size; if (ch == ':') ch = '/'; - if (nls_disk) { - size = nls_disk->uni2char(ch, dst, dstlen); - if (size < 0) { - if (size == -ENAMETOOLONG) - goto out; - *dst = '?'; - size = 1; - } - dst += size; - dstlen -= size; - } else { - *dst++ = ch > 0xff ? '?' : ch; - dstlen--; + size = nls_disk->uni2char(ch, dst, dstlen); + if (size < 0) { + if (size == -ENAMETOOLONG) + goto out; + *dst = '?'; + size = 1; } + dst += size; + dstlen -= size; } } else { char ch; -- 2.20.1