diff mbox series

[2/2] fuse: Increase FUSE_NAME_MAX to PATH_MAX

Message ID 20241212-fuse_name_max-limit-6-13-v1-2-92be52f01eca@ddn.com (mailing list archive)
State New
Headers show
Series fuse: Increase FUSE_NAME_MAX limit | expand

Commit Message

Bernd Schubert Dec. 12, 2024, 9:50 p.m. UTC
Our file system has a translation capability for S3-to-posix.
The current value of 1kiB is enough to cover S3 keys, but
does not allow encoding of escape characters. The limit is
increased by factor 3 to allow worst case encoding with %xx.

Testing large file names was hard with libfuse/example file systems,
so I created a new memfs that does not have a 255 file name length
limitation.
https://github.com/libfuse/libfuse/pull/1077

Signed-off-by: Bernd Schubert <bschubert@ddn.com>
---
 fs/fuse/fuse_i.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Jingbo Xu Dec. 13, 2024, 1:53 a.m. UTC | #1
On 12/13/24 5:50 AM, Bernd Schubert wrote:
> Our file system has a translation capability for S3-to-posix.
> The current value of 1kiB is enough to cover S3 keys, but
> does not allow encoding of escape characters. The limit is
> increased by factor 3 to allow worst case encoding with %xx.
> 
> Testing large file names was hard with libfuse/example file systems,
> so I created a new memfs that does not have a 255 file name length
> limitation.
> https://github.com/libfuse/libfuse/pull/1077
> 
> Signed-off-by: Bernd Schubert <bschubert@ddn.com>
> ---
>  fs/fuse/fuse_i.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
> index 74744c6f286003251564d1235f4d2ca8654d661b..91b4cdd60fd4fe4ca5c3b8f2c9e5999c69d40690 100644
> --- a/fs/fuse/fuse_i.h
> +++ b/fs/fuse/fuse_i.h
> @@ -39,7 +39,7 @@
>  #define FUSE_NOWRITE INT_MIN
>  
>  /** It could be as large as PATH_MAX, but would that have any uses? */
> -#define FUSE_NAME_MAX 1024
> +#define FUSE_NAME_MAX (3 * 1024)


So why not increase it directly to PATH_MAX, as indicated by the comment?
Shachar Sharon Dec. 13, 2024, 9:17 a.m. UTC | #2
The <linux/limits.h> defines NAME_MAX as 255 (_not_ including nul) and
PATH_MAX as 4096 (including nul). It would be nice to keep this
convention also on the FUSE side; that is, define FUSE_NAME_MAX as
1023, or in your case (3 * 1024 - 1). I think this is the also
intention of the code in fuse_notify_inval_entry:

  err = -ENAMETOOLONG
  if (outarg.namelen > FUSE_NAME_MAX)
          goto err;

Otherwise, we should fix this check as well (outarg.namelen >=
FUSE_NAME_MAX). That said, keep in mind that using dir-entry names
larger then NAME_MAX would also cause ENAMETOOLONG by glibc’s
readdir[1]

- Shachar.

[1] https://github.com/bminor/glibc/blob/master/sysdeps/unix/sysv/linux/readdir_r.c#L52-L59


On Thu, Dec 12, 2024 at 11:51 PM Bernd Schubert <bschubert@ddn.com> wrote:
>
> Our file system has a translation capability for S3-to-posix.
> The current value of 1kiB is enough to cover S3 keys, but
> does not allow encoding of escape characters. The limit is
> increased by factor 3 to allow worst case encoding with %xx.
>
> Testing large file names was hard with libfuse/example file systems,
> so I created a new memfs that does not have a 255 file name length
> limitation.
> https://github.com/libfuse/libfuse/pull/1077
>
> Signed-off-by: Bernd Schubert <bschubert@ddn.com>
> ---
>  fs/fuse/fuse_i.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
> index 74744c6f286003251564d1235f4d2ca8654d661b..91b4cdd60fd4fe4ca5c3b8f2c9e5999c69d40690 100644
> --- a/fs/fuse/fuse_i.h
> +++ b/fs/fuse/fuse_i.h
> @@ -39,7 +39,7 @@
>  #define FUSE_NOWRITE INT_MIN
>
>  /** It could be as large as PATH_MAX, but would that have any uses? */
> -#define FUSE_NAME_MAX 1024
> +#define FUSE_NAME_MAX (3 * 1024)
>
>  /** Number of dentries for each connection in the control filesystem */
>  #define FUSE_CTL_NUM_DENTRIES 5
>
> --
> 2.43.0
>
>
Bernd Schubert Dec. 13, 2024, 10:34 a.m. UTC | #3
On 12/13/24 10:17, Shachar Sharon wrote:
> [You don't often get email from synarete@gmail.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> The <linux/limits.h> defines NAME_MAX as 255 (_not_ including nul) and
> PATH_MAX as 4096 (including nul). It would be nice to keep this
> convention also on the FUSE side; that is, define FUSE_NAME_MAX as
> 1023, or in your case (3 * 1024 - 1). I think this is the also
> intention of the code in fuse_notify_inval_entry:
> 
>   err = -ENAMETOOLONG
>   if (outarg.namelen > FUSE_NAME_MAX)
>           goto err;

Thanks for the review, I can change it to (3 * 1024 - 1) or 
(PATH_MAX - 1).

> 
> Otherwise, we should fix this check as well (outarg.namelen >=
> FUSE_NAME_MAX). That said, keep in mind that using dir-entry names
> larger then NAME_MAX would also cause ENAMETOOLONG by glibc’s
> readdir[1]
> 
> - Shachar.
> 
> [1] https://github.com/bminor/glibc/blob/master/sysdeps/unix/sysv/linux/readdir_r.c#L52-L59

Yes, I had seen that glibc uses NAME_MAX, but I had also tested the
patch using the new memfs [1] and the attached script. You can try
it out yourself - listing long file names actually works (on a
Debian 12 system).



Thanks,
Bernd

[1] https://github.com/libfuse/libfuse/blob/master/example/memfs_ll.cc
diff mbox series

Patch

diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 74744c6f286003251564d1235f4d2ca8654d661b..91b4cdd60fd4fe4ca5c3b8f2c9e5999c69d40690 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -39,7 +39,7 @@ 
 #define FUSE_NOWRITE INT_MIN
 
 /** It could be as large as PATH_MAX, but would that have any uses? */
-#define FUSE_NAME_MAX 1024
+#define FUSE_NAME_MAX (3 * 1024)
 
 /** Number of dentries for each connection in the control filesystem */
 #define FUSE_CTL_NUM_DENTRIES 5