Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

udf: Fix iocharset=utf8 mount option

Currently iocharset=utf8 mount option is broken. To use UTF-8 as iocharset,
it is required to use utf8 mount option.

Fix iocharset=utf8 mount option to use be equivalent to the utf8 mount
option.

If UTF-8 as iocharset is used then s_nls_map is set to NULL. So simplify
code around, remove UDF_FLAG_NLS_MAP and UDF_FLAG_UTF8 flags as to
distinguish between UTF-8 and non-UTF-8 it is needed just to check if
s_nls_map set to NULL or not.

Link: https://lore.kernel.org/r/20210808162453.1653-4-pali@kernel.org
Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Jan Kara <jack@suse.cz>

authored by

Pali Rohár and committed by
Jan Kara
b6453334 979a6e28

+21 -35
+19 -31
fs/udf/super.c
··· 343 343 seq_printf(seq, ",lastblock=%u", sbi->s_last_block); 344 344 if (sbi->s_anchor != 0) 345 345 seq_printf(seq, ",anchor=%u", sbi->s_anchor); 346 - if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) 347 - seq_puts(seq, ",utf8"); 348 - if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP) && sbi->s_nls_map) 346 + if (sbi->s_nls_map) 349 347 seq_printf(seq, ",iocharset=%s", sbi->s_nls_map->charset); 348 + else 349 + seq_puts(seq, ",iocharset=utf8"); 350 350 351 351 return 0; 352 352 } ··· 552 552 /* Ignored (never implemented properly) */ 553 553 break; 554 554 case Opt_utf8: 555 - uopt->flags |= (1 << UDF_FLAG_UTF8); 555 + if (!remount) { 556 + unload_nls(uopt->nls_map); 557 + uopt->nls_map = NULL; 558 + } 556 559 break; 557 560 case Opt_iocharset: 558 561 if (!remount) { 559 - if (uopt->nls_map) 560 - unload_nls(uopt->nls_map); 561 - /* 562 - * load_nls() failure is handled later in 563 - * udf_fill_super() after all options are 564 - * parsed. 565 - */ 562 + unload_nls(uopt->nls_map); 563 + uopt->nls_map = NULL; 564 + } 565 + /* When nls_map is not loaded then UTF-8 is used */ 566 + if (!remount && strcmp(args[0].from, "utf8") != 0) { 566 567 uopt->nls_map = load_nls(args[0].from); 567 - uopt->flags |= (1 << UDF_FLAG_NLS_MAP); 568 + if (!uopt->nls_map) { 569 + pr_err("iocharset %s not found\n", 570 + args[0].from); 571 + return 0; 572 + } 568 573 } 569 574 break; 570 575 case Opt_uforget: ··· 2151 2146 if (!udf_parse_options((char *)options, &uopt, false)) 2152 2147 goto parse_options_failure; 2153 2148 2154 - if (uopt.flags & (1 << UDF_FLAG_UTF8) && 2155 - uopt.flags & (1 << UDF_FLAG_NLS_MAP)) { 2156 - udf_err(sb, "utf8 cannot be combined with iocharset\n"); 2157 - goto parse_options_failure; 2158 - } 2159 - if ((uopt.flags & (1 << UDF_FLAG_NLS_MAP)) && !uopt.nls_map) { 2160 - uopt.nls_map = load_nls_default(); 2161 - if (!uopt.nls_map) 2162 - uopt.flags &= ~(1 << UDF_FLAG_NLS_MAP); 2163 - else 2164 - udf_debug("Using default NLS map\n"); 2165 - } 2166 - if (!(uopt.flags & (1 << UDF_FLAG_NLS_MAP))) 2167 - uopt.flags |= (1 << UDF_FLAG_UTF8); 2168 - 2169 2149 fileset.logicalBlockNum = 0xFFFFFFFF; 2170 2150 fileset.partitionReferenceNum = 0xFFFF; 2171 2151 ··· 2305 2315 error_out: 2306 2316 iput(sbi->s_vat_inode); 2307 2317 parse_options_failure: 2308 - if (uopt.nls_map) 2309 - unload_nls(uopt.nls_map); 2318 + unload_nls(uopt.nls_map); 2310 2319 if (lvid_open) 2311 2320 udf_close_lvid(sb); 2312 2321 brelse(sbi->s_lvid_bh); ··· 2355 2366 sbi = UDF_SB(sb); 2356 2367 2357 2368 iput(sbi->s_vat_inode); 2358 - if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) 2359 - unload_nls(sbi->s_nls_map); 2369 + unload_nls(sbi->s_nls_map); 2360 2370 if (!sb_rdonly(sb)) 2361 2371 udf_close_lvid(sb); 2362 2372 brelse(sbi->s_lvid_bh);
-2
fs/udf/udf_sb.h
··· 20 20 #define UDF_FLAG_UNDELETE 6 21 21 #define UDF_FLAG_UNHIDE 7 22 22 #define UDF_FLAG_VARCONV 8 23 - #define UDF_FLAG_NLS_MAP 9 24 - #define UDF_FLAG_UTF8 10 25 23 #define UDF_FLAG_UID_FORGET 11 /* save -1 for uid to disk */ 26 24 #define UDF_FLAG_GID_FORGET 12 27 25 #define UDF_FLAG_UID_SET 13
+2 -2
fs/udf/unicode.c
··· 177 177 return 0; 178 178 } 179 179 180 - if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) 180 + if (UDF_SB(sb)->s_nls_map) 181 181 conv_f = UDF_SB(sb)->s_nls_map->uni2char; 182 182 else 183 183 conv_f = NULL; ··· 285 285 if (ocu_max_len <= 0) 286 286 return 0; 287 287 288 - if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) 288 + if (UDF_SB(sb)->s_nls_map) 289 289 conv_f = UDF_SB(sb)->s_nls_map->char2uni; 290 290 else 291 291 conv_f = NULL;