linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] exfat: intorduce skip_stream_check mount opt
@ 2022-06-07  2:49 Yangtao Li
  2022-06-10  1:04 ` Namjae Jeon
  0 siblings, 1 reply; 6+ messages in thread
From: Yangtao Li @ 2022-06-07  2:49 UTC (permalink / raw)
  To: linkinjeon, sj1557.seo; +Cc: linux-fsdevel, linux-kernel, Yangtao Li

There are some files in my USB flash drive that can be recognized by
the Windows computer, but on Linux, only the existence of the file name
can be seen.

When executing ls command to view the file attributes or access, the file
does not exist. Therefore, when the current windows and linux drivers
access a file, there is a difference in the checking of the file metadata,
which leads to this situation.
(There is also a difference between traversing all children of the parent
directory and finding a child in the parent directory on linux.)

So, we introduce a new mount option that skips the check of the file stream
entry in exfat_find_dir_entry().

Signed-off-by: Yangtao Li <frank.li@vivo.com>
---
 fs/exfat/dir.c      | 6 ++++--
 fs/exfat/exfat_fs.h | 3 ++-
 fs/exfat/super.c    | 7 +++++++
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
index cb1c0d8c1714..4ea0077f2955 100644
--- a/fs/exfat/dir.c
+++ b/fs/exfat/dir.c
@@ -1013,6 +1013,7 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
 			}
 
 			if (entry_type == TYPE_STREAM) {
+				struct exfat_mount_options *opts = &sbi->options;
 				u16 name_hash;
 
 				if (step != DIRENT_STEP_STRM) {
@@ -1023,9 +1024,10 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
 				step = DIRENT_STEP_FILE;
 				name_hash = le16_to_cpu(
 						ep->dentry.stream.name_hash);
-				if (p_uniname->name_hash == name_hash &&
+				if ((p_uniname->name_hash == name_hash &&
 				    p_uniname->name_len ==
-						ep->dentry.stream.name_len) {
+						ep->dentry.stream.name_len) ||
+					opts->skip_stream_check == 1) {
 					step = DIRENT_STEP_NAME;
 					order = 1;
 					name_len = 0;
diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h
index 1d6da61157c9..5cd00ac112d9 100644
--- a/fs/exfat/exfat_fs.h
+++ b/fs/exfat/exfat_fs.h
@@ -204,7 +204,8 @@ struct exfat_mount_options {
 	/* on error: continue, panic, remount-ro */
 	enum exfat_error_mode errors;
 	unsigned utf8:1, /* Use of UTF-8 character set */
-		 discard:1; /* Issue discard requests on deletions */
+		 discard:1, /* Issue discard requests on deletions */
+		 skip_stream_check:1; /* Skip stream entry check in exfat_find_dir_entry() */
 	int time_offset; /* Offset of timestamps from UTC (in minutes) */
 };
 
diff --git a/fs/exfat/super.c b/fs/exfat/super.c
index 5539ffc20d16..e9c7df25f2b5 100644
--- a/fs/exfat/super.c
+++ b/fs/exfat/super.c
@@ -173,6 +173,8 @@ static int exfat_show_options(struct seq_file *m, struct dentry *root)
 		seq_puts(m, ",errors=remount-ro");
 	if (opts->discard)
 		seq_puts(m, ",discard");
+	if (opts->skip_stream_check)
+		seq_puts(m, ",skip_stream_check");
 	if (opts->time_offset)
 		seq_printf(m, ",time_offset=%d", opts->time_offset);
 	return 0;
@@ -216,6 +218,7 @@ enum {
 	Opt_charset,
 	Opt_errors,
 	Opt_discard,
+	Opt_skip_stream_check,
 	Opt_time_offset,
 
 	/* Deprecated options */
@@ -242,6 +245,7 @@ static const struct fs_parameter_spec exfat_parameters[] = {
 	fsparam_string("iocharset",		Opt_charset),
 	fsparam_enum("errors",			Opt_errors, exfat_param_enums),
 	fsparam_flag("discard",			Opt_discard),
+	fsparam_flag("skip_stream_check",	Opt_skip_stream_check),
 	fsparam_s32("time_offset",		Opt_time_offset),
 	__fsparam(NULL, "utf8",			Opt_utf8, fs_param_deprecated,
 		  NULL),
@@ -296,6 +300,9 @@ static int exfat_parse_param(struct fs_context *fc, struct fs_parameter *param)
 	case Opt_discard:
 		opts->discard = 1;
 		break;
+	case Opt_skip_stream_check:
+		opts->skip_stream_check = 1;
+		break;
 	case Opt_time_offset:
 		/*
 		 * Make the limit 24 just in case someone invents something
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] exfat: intorduce skip_stream_check mount opt
  2022-06-07  2:49 [PATCH] exfat: intorduce skip_stream_check mount opt Yangtao Li
@ 2022-06-10  1:04 ` Namjae Jeon
  2022-06-10 13:07   ` 答复: " 李扬韬
  0 siblings, 1 reply; 6+ messages in thread
From: Namjae Jeon @ 2022-06-10  1:04 UTC (permalink / raw)
  To: Yangtao Li; +Cc: sj1557.seo, linux-fsdevel, linux-kernel

2022-06-07 11:49 GMT+09:00, Yangtao Li <frank.li@vivo.com>:
> There are some files in my USB flash drive that can be recognized by
> the Windows computer, but on Linux, only the existence of the file name
> can be seen.
>
> When executing ls command to view the file attributes or access, the file
> does not exist. Therefore, when the current windows and linux drivers
> access a file, there is a difference in the checking of the file metadata,
> which leads to this situation.
> (There is also a difference between traversing all children of the parent
> directory and finding a child in the parent directory on linux.)
Still having problem on linux-exfat after recovering it using windows chkdsk?

Thanks.
>
> So, we introduce a new mount option that skips the check of the file stream
> entry in exfat_find_dir_entry().
>
> Signed-off-by: Yangtao Li <frank.li@vivo.com>
> ---
>  fs/exfat/dir.c      | 6 ++++--
>  fs/exfat/exfat_fs.h | 3 ++-
>  fs/exfat/super.c    | 7 +++++++
>  3 files changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
> index cb1c0d8c1714..4ea0077f2955 100644
> --- a/fs/exfat/dir.c
> +++ b/fs/exfat/dir.c
> @@ -1013,6 +1013,7 @@ int exfat_find_dir_entry(struct super_block *sb,
> struct exfat_inode_info *ei,
>  			}
>
>  			if (entry_type == TYPE_STREAM) {
> +				struct exfat_mount_options *opts = &sbi->options;
>  				u16 name_hash;
>
>  				if (step != DIRENT_STEP_STRM) {
> @@ -1023,9 +1024,10 @@ int exfat_find_dir_entry(struct super_block *sb,
> struct exfat_inode_info *ei,
>  				step = DIRENT_STEP_FILE;
>  				name_hash = le16_to_cpu(
>  						ep->dentry.stream.name_hash);
> -				if (p_uniname->name_hash == name_hash &&
> +				if ((p_uniname->name_hash == name_hash &&
>  				    p_uniname->name_len ==
> -						ep->dentry.stream.name_len) {
> +						ep->dentry.stream.name_len) ||
> +					opts->skip_stream_check == 1) {
>  					step = DIRENT_STEP_NAME;
>  					order = 1;
>  					name_len = 0;
> diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h
> index 1d6da61157c9..5cd00ac112d9 100644
> --- a/fs/exfat/exfat_fs.h
> +++ b/fs/exfat/exfat_fs.h
> @@ -204,7 +204,8 @@ struct exfat_mount_options {
>  	/* on error: continue, panic, remount-ro */
>  	enum exfat_error_mode errors;
>  	unsigned utf8:1, /* Use of UTF-8 character set */
> -		 discard:1; /* Issue discard requests on deletions */
> +		 discard:1, /* Issue discard requests on deletions */
> +		 skip_stream_check:1; /* Skip stream entry check in
> exfat_find_dir_entry() */
>  	int time_offset; /* Offset of timestamps from UTC (in minutes) */
>  };
>
> diff --git a/fs/exfat/super.c b/fs/exfat/super.c
> index 5539ffc20d16..e9c7df25f2b5 100644
> --- a/fs/exfat/super.c
> +++ b/fs/exfat/super.c
> @@ -173,6 +173,8 @@ static int exfat_show_options(struct seq_file *m, struct
> dentry *root)
>  		seq_puts(m, ",errors=remount-ro");
>  	if (opts->discard)
>  		seq_puts(m, ",discard");
> +	if (opts->skip_stream_check)
> +		seq_puts(m, ",skip_stream_check");
>  	if (opts->time_offset)
>  		seq_printf(m, ",time_offset=%d", opts->time_offset);
>  	return 0;
> @@ -216,6 +218,7 @@ enum {
>  	Opt_charset,
>  	Opt_errors,
>  	Opt_discard,
> +	Opt_skip_stream_check,
>  	Opt_time_offset,
>
>  	/* Deprecated options */
> @@ -242,6 +245,7 @@ static const struct fs_parameter_spec exfat_parameters[]
> = {
>  	fsparam_string("iocharset",		Opt_charset),
>  	fsparam_enum("errors",			Opt_errors, exfat_param_enums),
>  	fsparam_flag("discard",			Opt_discard),
> +	fsparam_flag("skip_stream_check",	Opt_skip_stream_check),
>  	fsparam_s32("time_offset",		Opt_time_offset),
>  	__fsparam(NULL, "utf8",			Opt_utf8, fs_param_deprecated,
>  		  NULL),
> @@ -296,6 +300,9 @@ static int exfat_parse_param(struct fs_context *fc,
> struct fs_parameter *param)
>  	case Opt_discard:
>  		opts->discard = 1;
>  		break;
> +	case Opt_skip_stream_check:
> +		opts->skip_stream_check = 1;
> +		break;
>  	case Opt_time_offset:
>  		/*
>  		 * Make the limit 24 just in case someone invents something
> --
> 2.35.1
>
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* 答复: [PATCH] exfat: intorduce skip_stream_check mount opt
  2022-06-10  1:04 ` Namjae Jeon
@ 2022-06-10 13:07   ` 李扬韬
  2022-06-16  0:46     ` Namjae Jeon
  0 siblings, 1 reply; 6+ messages in thread
From: 李扬韬 @ 2022-06-10 13:07 UTC (permalink / raw)
  To: Namjae Jeon; +Cc: sj1557.seo, linux-fsdevel, linux-kernel

HI Namjae,

> Still having problem on linux-exfat after recovering it using windows chkdsk?

After repairing with the chkdsk tool on the windows platform, the current file can be accessed normally on linux.
However, it can be accessed normally on the Windows platform itself, and no tools are required to repair it.
Imagine that if some users do not have a Windows environment and do not understand repair tools, they
cannot access these files on Linux.

Why not just skip the stream entry like Windows does and allow access without fixing it?

Thx,
Yangtao

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: 答复: [PATCH] exfat: intorduce skip_stream_check mount opt
  2022-06-10 13:07   ` 答复: " 李扬韬
@ 2022-06-16  0:46     ` Namjae Jeon
  2022-06-21 14:39       ` 答复: " 李扬韬
  2022-06-22 12:15       ` 李扬韬
  0 siblings, 2 replies; 6+ messages in thread
From: Namjae Jeon @ 2022-06-16  0:46 UTC (permalink / raw)
  To: 李扬韬; +Cc: sj1557.seo, linux-fsdevel, linux-kernel

2022-06-10 22:07 GMT+09:00, 李扬韬 <frank.li@vivo.com>:
> HI Namjae,
>
>> Still having problem on linux-exfat after recovering it using windows
>> chkdsk?
>
> After repairing with the chkdsk tool on the windows platform, the current
> file can be accessed normally on linux.
> However, it can be accessed normally on the Windows platform itself, and no
> tools are required to repair it.
> Imagine that if some users do not have a Windows environment and do not
> understand repair tools, they
> cannot access these files on Linux.
>
> Why not just skip the stream entry like Windows does and allow access
> without fixing it?
If the name hash is not checked, file lookup performance will degrade.
Probably you don't want the overall performance degrade for a few
corrupted files. I suggest fixing it by fsck in exfatprogs before
mounting. We are preparing repair function release in fsck to do that
in next month.

Thanks!
>
> Thx,
> Yangtao
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* 答复: 答复: [PATCH] exfat: intorduce skip_stream_check mount opt
  2022-06-16  0:46     ` Namjae Jeon
@ 2022-06-21 14:39       ` 李扬韬
  2022-06-22 12:15       ` 李扬韬
  1 sibling, 0 replies; 6+ messages in thread
From: 李扬韬 @ 2022-06-21 14:39 UTC (permalink / raw)
  To: Namjae Jeon; +Cc: sj1557.seo, linux-fsdevel, linux-kernel

>I suggest fixing it by fsck in exfatprogs before mounting. We are preparing repair function release in fsck to do that in next month.

Is there any progress in the implementation of this part of the code?
And can you provide a demo? When is it expected that the code will be able to be merged.

MBR,
Yangtao

^ permalink raw reply	[flat|nested] 6+ messages in thread

* 答复: 答复: [PATCH] exfat: intorduce skip_stream_check mount opt
  2022-06-16  0:46     ` Namjae Jeon
  2022-06-21 14:39       ` 答复: " 李扬韬
@ 2022-06-22 12:15       ` 李扬韬
  1 sibling, 0 replies; 6+ messages in thread
From: 李扬韬 @ 2022-06-22 12:15 UTC (permalink / raw)
  To: Namjae Jeon; +Cc: sj1557.seo, linux-fsdevel, linux-kernel

> Probably you don't want the overall performance degrade for a few corrupted files. Thanks!

Why is the performance degraded, can you describe the reasons and scenarios more clearly.
Is there any actual test data, maybe we can actually test the impact?

Thx,
Yangtao

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-06-22 12:15 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-07  2:49 [PATCH] exfat: intorduce skip_stream_check mount opt Yangtao Li
2022-06-10  1:04 ` Namjae Jeon
2022-06-10 13:07   ` 答复: " 李扬韬
2022-06-16  0:46     ` Namjae Jeon
2022-06-21 14:39       ` 答复: " 李扬韬
2022-06-22 12:15       ` 李扬韬

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).