* [PATCH] vfs: missing inode operation should return a consistent error code
@ 2026-05-31 10:49 Jori Koolstra
2026-05-31 14:08 ` Jeff Layton
0 siblings, 1 reply; 8+ messages in thread
From: Jori Koolstra @ 2026-05-31 10:49 UTC (permalink / raw)
To: Alexander Viro, Christian Brauner, Jan Kara, Arnd Bergmann
Cc: Jori Koolstra, open list:FILESYSTEMS (VFS and infrastructure),
open list, open list:GENERIC INCLUDE/ASM HEADER FILES
Currently several different error codes are used in the VFS for
situations where the underlying filesystem does not support the
requested inode operation (such as mkdir, tmpfile, create, etc.)
Examples: create returns EACCES, mkdir EPERM, tmpfile EOPNOTSUPP,
fileattr_get ENOIOCTLCMD.
We should provide a sensible unified error code for these situations.
EOPNOTSUPP is already used for this both in the kernel (when lacking
tmpfile support) and in userland (e.g. glibc).[1] Restricting EOPNOTSUPP
to socket operations as POSIX suggests is not the current reality and
this was recently changed in the man page as well.[2]
vfs_fileattr_get|set return ENOIOCTLCMD, but this cannot be changed
since EOPNOTSUPP is already used to by underlying filesystems to indicate
that a flag is not supported. The change to EOPNOTSUPP was reverted by
4dd5b5ac089b ("Revert "fs: make vfs_fileattr_[get|set] return
-EOPNOTSUPP"")
[1]: https://lore.kernel.org/all/20260528-abnimmt-befreien-perspektive-a7930659fb40@brauner/
[2]: https://lore.kernel.org/linux-fsdevel/ahd3SmZZqnzP0-O2@devuan/T/#t
Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl>
---
fs/namei.c | 18 +++++++++---------
include/uapi/asm-generic/errno.h | 2 +-
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index c7fac83c9a85..813419c340ad 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4192,7 +4192,7 @@ int vfs_create(struct mnt_idmap *idmap, struct dentry *dentry, umode_t mode,
return error;
if (!dir->i_op->create)
- return -EACCES; /* shouldn't it be ENOSYS? */
+ return -EOPNOTSUPP;
mode = vfs_prepare_mode(idmap, dir, mode, S_IALLUGO, S_IFREG);
error = security_inode_create(dir, dentry, mode);
@@ -4504,7 +4504,7 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file,
file->f_mode |= FMODE_CREATED;
audit_inode_child(dir_inode, dentry, AUDIT_TYPE_CHILD_CREATE);
if (!dir_inode->i_op->create) {
- error = -EACCES;
+ error = -EOPNOTSUPP;
goto out_dput;
}
@@ -5102,7 +5102,7 @@ int vfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
return -EPERM;
if (!dir->i_op->mknod)
- return -EPERM;
+ return -EOPNOTSUPP;
mode = vfs_prepare_mode(idmap, dir, mode, mode, mode);
error = devcgroup_inode_mknod(mode, dev);
@@ -5241,7 +5241,7 @@ struct dentry *vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
if (error)
goto err;
- error = -EPERM;
+ error = -EOPNOTSUPP;
if (!dir->i_op->mkdir)
goto err;
@@ -5345,7 +5345,7 @@ int vfs_rmdir(struct mnt_idmap *idmap, struct inode *dir,
return error;
if (!dir->i_op->rmdir)
- return -EPERM;
+ return -EOPNOTSUPP;
dget(dentry);
inode_lock(dentry->d_inode);
@@ -5479,7 +5479,7 @@ int vfs_unlink(struct mnt_idmap *idmap, struct inode *dir,
return error;
if (!dir->i_op->unlink)
- return -EPERM;
+ return -EOPNOTSUPP;
inode_lock(target);
if (IS_SWAPFILE(target))
@@ -5630,7 +5630,7 @@ int vfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
return error;
if (!dir->i_op->symlink)
- return -EPERM;
+ return -EOPNOTSUPP;
error = security_inode_symlink(dir, dentry, oldname);
if (error)
@@ -5752,7 +5752,7 @@ int vfs_link(struct dentry *old_dentry, struct mnt_idmap *idmap,
if (HAS_UNMAPPED_ID(idmap, inode))
return -EPERM;
if (!dir->i_op->link)
- return -EPERM;
+ return -EOPNOTSUPP;
if (S_ISDIR(inode->i_mode))
return -EPERM;
@@ -5961,7 +5961,7 @@ int vfs_rename(struct renamedata *rd)
return error;
if (!old_dir->i_op->rename)
- return -EPERM;
+ return -EOPNOTSUPP;
/*
* If we are going to change the parent - check write permissions,
diff --git a/include/uapi/asm-generic/errno.h b/include/uapi/asm-generic/errno.h
index 92e7ae493ee3..7b5b71ae1b12 100644
--- a/include/uapi/asm-generic/errno.h
+++ b/include/uapi/asm-generic/errno.h
@@ -76,7 +76,7 @@
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
-#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
+#define EOPNOTSUPP 95 /* Operation not supported */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
base-commit: 670b77dfebe7257adc0defbc48a4c43cfdf6c8f6
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH] vfs: missing inode operation should return a consistent error code
2026-05-31 10:49 [PATCH] vfs: missing inode operation should return a consistent error code Jori Koolstra
@ 2026-05-31 14:08 ` Jeff Layton
2026-06-01 15:58 ` Jan Kara
0 siblings, 1 reply; 8+ messages in thread
From: Jeff Layton @ 2026-05-31 14:08 UTC (permalink / raw)
To: Jori Koolstra, Alexander Viro, Christian Brauner, Jan Kara,
Arnd Bergmann
Cc: open list:FILESYSTEMS (VFS and infrastructure), open list,
open list:GENERIC INCLUDE/ASM HEADER FILES
On Sun, 2026-05-31 at 12:49 +0200, Jori Koolstra wrote:
> Currently several different error codes are used in the VFS for
> situations where the underlying filesystem does not support the
> requested inode operation (such as mkdir, tmpfile, create, etc.)
> Examples: create returns EACCES, mkdir EPERM, tmpfile EOPNOTSUPP,
> fileattr_get ENOIOCTLCMD.
>
> We should provide a sensible unified error code for these situations.
> EOPNOTSUPP is already used for this both in the kernel (when lacking
> tmpfile support) and in userland (e.g. glibc).[1] Restricting EOPNOTSUPP
> to socket operations as POSIX suggests is not the current reality and
> this was recently changed in the man page as well.[2]
>
> vfs_fileattr_get|set return ENOIOCTLCMD, but this cannot be changed
> since EOPNOTSUPP is already used to by underlying filesystems to indicate
> that a flag is not supported. The change to EOPNOTSUPP was reverted by
> 4dd5b5ac089b ("Revert "fs: make vfs_fileattr_[get|set] return
> -EOPNOTSUPP"")
>
> [1]: https://lore.kernel.org/all/20260528-abnimmt-befreien-perspektive-a7930659fb40@brauner/
> [2]: https://lore.kernel.org/linux-fsdevel/ahd3SmZZqnzP0-O2@devuan/T/#t
>
> Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl>
> ---
> fs/namei.c | 18 +++++++++---------
> include/uapi/asm-generic/errno.h | 2 +-
> 2 files changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/fs/namei.c b/fs/namei.c
> index c7fac83c9a85..813419c340ad 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -4192,7 +4192,7 @@ int vfs_create(struct mnt_idmap *idmap, struct dentry *dentry, umode_t mode,
> return error;
>
> if (!dir->i_op->create)
> - return -EACCES; /* shouldn't it be ENOSYS? */
> + return -EOPNOTSUPP;
>
> mode = vfs_prepare_mode(idmap, dir, mode, S_IALLUGO, S_IFREG);
> error = security_inode_create(dir, dentry, mode);
> @@ -4504,7 +4504,7 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file,
> file->f_mode |= FMODE_CREATED;
> audit_inode_child(dir_inode, dentry, AUDIT_TYPE_CHILD_CREATE);
> if (!dir_inode->i_op->create) {
> - error = -EACCES;
> + error = -EOPNOTSUPP;
> goto out_dput;
> }
>
> @@ -5102,7 +5102,7 @@ int vfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
> return -EPERM;
>
> if (!dir->i_op->mknod)
> - return -EPERM;
> + return -EOPNOTSUPP;
>
> mode = vfs_prepare_mode(idmap, dir, mode, mode, mode);
> error = devcgroup_inode_mknod(mode, dev);
> @@ -5241,7 +5241,7 @@ struct dentry *vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
> if (error)
> goto err;
>
> - error = -EPERM;
> + error = -EOPNOTSUPP;
> if (!dir->i_op->mkdir)
> goto err;
>
> @@ -5345,7 +5345,7 @@ int vfs_rmdir(struct mnt_idmap *idmap, struct inode *dir,
> return error;
>
> if (!dir->i_op->rmdir)
> - return -EPERM;
> + return -EOPNOTSUPP;
>
> dget(dentry);
> inode_lock(dentry->d_inode);
> @@ -5479,7 +5479,7 @@ int vfs_unlink(struct mnt_idmap *idmap, struct inode *dir,
> return error;
>
> if (!dir->i_op->unlink)
> - return -EPERM;
> + return -EOPNOTSUPP;
>
> inode_lock(target);
> if (IS_SWAPFILE(target))
> @@ -5630,7 +5630,7 @@ int vfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
> return error;
>
> if (!dir->i_op->symlink)
> - return -EPERM;
> + return -EOPNOTSUPP;
>
> error = security_inode_symlink(dir, dentry, oldname);
> if (error)
> @@ -5752,7 +5752,7 @@ int vfs_link(struct dentry *old_dentry, struct mnt_idmap *idmap,
> if (HAS_UNMAPPED_ID(idmap, inode))
> return -EPERM;
> if (!dir->i_op->link)
> - return -EPERM;
> + return -EOPNOTSUPP;
> if (S_ISDIR(inode->i_mode))
> return -EPERM;
>
> @@ -5961,7 +5961,7 @@ int vfs_rename(struct renamedata *rd)
> return error;
>
> if (!old_dir->i_op->rename)
> - return -EPERM;
> + return -EOPNOTSUPP;
>
> /*
> * If we are going to change the parent - check write permissions,
> diff --git a/include/uapi/asm-generic/errno.h b/include/uapi/asm-generic/errno.h
> index 92e7ae493ee3..7b5b71ae1b12 100644
> --- a/include/uapi/asm-generic/errno.h
> +++ b/include/uapi/asm-generic/errno.h
> @@ -76,7 +76,7 @@
> #define ENOPROTOOPT 92 /* Protocol not available */
> #define EPROTONOSUPPORT 93 /* Protocol not supported */
> #define ESOCKTNOSUPPORT 94 /* Socket type not supported */
> -#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
> +#define EOPNOTSUPP 95 /* Operation not supported */
> #define EPFNOSUPPORT 96 /* Protocol family not supported */
> #define EAFNOSUPPORT 97 /* Address family not supported by protocol */
> #define EADDRINUSE 98 /* Address already in use */
>
> base-commit: 670b77dfebe7257adc0defbc48a4c43cfdf6c8f6
This seems ill-advised. The problem is that most of this behavior has
been well established for years, and not all userland software (and
even some internal callers like nfsd), will react well when you go
changing behavior like this.
As a case in point, the POSIX spec doesn't list EOPNOTSUPP as a valid
error return for open():
https://pubs.opengroup.org/onlinepubs/9690949399/functions/open.html
The manpage for open() says only:
EOPNOTSUPP
The filesystem containing pathname does not support O_TMPFILE.
What is the poor userland developer to make of this when open() starts
returning EOPNOTSUPP without O_TMPFILE being specified?
--
Jeff Layton <jlayton@kernel.org>
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] vfs: missing inode operation should return a consistent error code
2026-05-31 14:08 ` Jeff Layton
@ 2026-06-01 15:58 ` Jan Kara
2026-06-01 16:27 ` Jori Koolstra
0 siblings, 1 reply; 8+ messages in thread
From: Jan Kara @ 2026-06-01 15:58 UTC (permalink / raw)
To: Jeff Layton
Cc: Jori Koolstra, Alexander Viro, Christian Brauner, Jan Kara,
Arnd Bergmann, open list:FILESYSTEMS (VFS and infrastructure),
open list, open list:GENERIC INCLUDE/ASM HEADER FILES
On Sun 31-05-26 10:08:47, Jeff Layton wrote:
> On Sun, 2026-05-31 at 12:49 +0200, Jori Koolstra wrote:
> > Currently several different error codes are used in the VFS for
> > situations where the underlying filesystem does not support the
> > requested inode operation (such as mkdir, tmpfile, create, etc.)
> > Examples: create returns EACCES, mkdir EPERM, tmpfile EOPNOTSUPP,
> > fileattr_get ENOIOCTLCMD.
> >
> > We should provide a sensible unified error code for these situations.
> > EOPNOTSUPP is already used for this both in the kernel (when lacking
> > tmpfile support) and in userland (e.g. glibc).[1] Restricting EOPNOTSUPP
> > to socket operations as POSIX suggests is not the current reality and
> > this was recently changed in the man page as well.[2]
> >
> > vfs_fileattr_get|set return ENOIOCTLCMD, but this cannot be changed
> > since EOPNOTSUPP is already used to by underlying filesystems to indicate
> > that a flag is not supported. The change to EOPNOTSUPP was reverted by
> > 4dd5b5ac089b ("Revert "fs: make vfs_fileattr_[get|set] return
> > -EOPNOTSUPP"")
> >
> > [1]: https://lore.kernel.org/all/20260528-abnimmt-befreien-perspektive-a7930659fb40@brauner/
> > [2]: https://lore.kernel.org/linux-fsdevel/ahd3SmZZqnzP0-O2@devuan/T/#t
> >
> > Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl>
> > ---
> > fs/namei.c | 18 +++++++++---------
> > include/uapi/asm-generic/errno.h | 2 +-
> > 2 files changed, 10 insertions(+), 10 deletions(-)
> >
> > diff --git a/fs/namei.c b/fs/namei.c
> > index c7fac83c9a85..813419c340ad 100644
> > --- a/fs/namei.c
> > +++ b/fs/namei.c
> > @@ -4192,7 +4192,7 @@ int vfs_create(struct mnt_idmap *idmap, struct dentry *dentry, umode_t mode,
> > return error;
> >
> > if (!dir->i_op->create)
> > - return -EACCES; /* shouldn't it be ENOSYS? */
> > + return -EOPNOTSUPP;
> >
> > mode = vfs_prepare_mode(idmap, dir, mode, S_IALLUGO, S_IFREG);
> > error = security_inode_create(dir, dentry, mode);
> > @@ -4504,7 +4504,7 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file,
> > file->f_mode |= FMODE_CREATED;
> > audit_inode_child(dir_inode, dentry, AUDIT_TYPE_CHILD_CREATE);
> > if (!dir_inode->i_op->create) {
> > - error = -EACCES;
> > + error = -EOPNOTSUPP;
> > goto out_dput;
> > }
> >
> > @@ -5102,7 +5102,7 @@ int vfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
> > return -EPERM;
> >
> > if (!dir->i_op->mknod)
> > - return -EPERM;
> > + return -EOPNOTSUPP;
> >
> > mode = vfs_prepare_mode(idmap, dir, mode, mode, mode);
> > error = devcgroup_inode_mknod(mode, dev);
> > @@ -5241,7 +5241,7 @@ struct dentry *vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
> > if (error)
> > goto err;
> >
> > - error = -EPERM;
> > + error = -EOPNOTSUPP;
> > if (!dir->i_op->mkdir)
> > goto err;
> >
> > @@ -5345,7 +5345,7 @@ int vfs_rmdir(struct mnt_idmap *idmap, struct inode *dir,
> > return error;
> >
> > if (!dir->i_op->rmdir)
> > - return -EPERM;
> > + return -EOPNOTSUPP;
> >
> > dget(dentry);
> > inode_lock(dentry->d_inode);
> > @@ -5479,7 +5479,7 @@ int vfs_unlink(struct mnt_idmap *idmap, struct inode *dir,
> > return error;
> >
> > if (!dir->i_op->unlink)
> > - return -EPERM;
> > + return -EOPNOTSUPP;
> >
> > inode_lock(target);
> > if (IS_SWAPFILE(target))
> > @@ -5630,7 +5630,7 @@ int vfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
> > return error;
> >
> > if (!dir->i_op->symlink)
> > - return -EPERM;
> > + return -EOPNOTSUPP;
> >
> > error = security_inode_symlink(dir, dentry, oldname);
> > if (error)
> > @@ -5752,7 +5752,7 @@ int vfs_link(struct dentry *old_dentry, struct mnt_idmap *idmap,
> > if (HAS_UNMAPPED_ID(idmap, inode))
> > return -EPERM;
> > if (!dir->i_op->link)
> > - return -EPERM;
> > + return -EOPNOTSUPP;
> > if (S_ISDIR(inode->i_mode))
> > return -EPERM;
> >
> > @@ -5961,7 +5961,7 @@ int vfs_rename(struct renamedata *rd)
> > return error;
> >
> > if (!old_dir->i_op->rename)
> > - return -EPERM;
> > + return -EOPNOTSUPP;
> >
> > /*
> > * If we are going to change the parent - check write permissions,
> > diff --git a/include/uapi/asm-generic/errno.h b/include/uapi/asm-generic/errno.h
> > index 92e7ae493ee3..7b5b71ae1b12 100644
> > --- a/include/uapi/asm-generic/errno.h
> > +++ b/include/uapi/asm-generic/errno.h
> > @@ -76,7 +76,7 @@
> > #define ENOPROTOOPT 92 /* Protocol not available */
> > #define EPROTONOSUPPORT 93 /* Protocol not supported */
> > #define ESOCKTNOSUPPORT 94 /* Socket type not supported */
> > -#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
> > +#define EOPNOTSUPP 95 /* Operation not supported */
> > #define EPFNOSUPPORT 96 /* Protocol family not supported */
> > #define EAFNOSUPPORT 97 /* Address family not supported by protocol */
> > #define EADDRINUSE 98 /* Address already in use */
> >
> > base-commit: 670b77dfebe7257adc0defbc48a4c43cfdf6c8f6
>
> This seems ill-advised. The problem is that most of this behavior has
> been well established for years, and not all userland software (and
> even some internal callers like nfsd), will react well when you go
> changing behavior like this.
>
> As a case in point, the POSIX spec doesn't list EOPNOTSUPP as a valid
> error return for open():
>
> https://pubs.opengroup.org/onlinepubs/9690949399/functions/open.html
>
> The manpage for open() says only:
>
> EOPNOTSUPP
> The filesystem containing pathname does not support O_TMPFILE.
>
> What is the poor userland developer to make of this when open() starts
> returning EOPNOTSUPP without O_TMPFILE being specified?
So I wouldn't care as much about POSIX, we largely ignore it anyway in the
kernel. But I tend to agree that changing the error code we returned for
several decades just for the sake of "cleanliness" isn't IMHO a good enough
reason to risk breaking userspace or causing confusion.
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] vfs: missing inode operation should return a consistent error code
2026-06-01 15:58 ` Jan Kara
@ 2026-06-01 16:27 ` Jori Koolstra
2026-06-01 16:50 ` Jan Kara
0 siblings, 1 reply; 8+ messages in thread
From: Jori Koolstra @ 2026-06-01 16:27 UTC (permalink / raw)
To: Jan Kara, Jeff Layton
Cc: Alexander Viro, Christian Brauner, Arnd Bergmann,
open list:FILESYSTEMS (VFS and infrastructure), open list,
open list:GENERIC INCLUDE/ASM HEADER FILES
> Op 01-06-2026 17:58 CEST schreef Jan Kara <jack@suse.cz>:
>
>
> On Sun 31-05-26 10:08:47, Jeff Layton wrote:
> >
> > This seems ill-advised. The problem is that most of this behavior has
> > been well established for years, and not all userland software (and
> > even some internal callers like nfsd), will react well when you go
> > changing behavior like this.
> >
> > As a case in point, the POSIX spec doesn't list EOPNOTSUPP as a valid
> > error return for open():
> >
> > https://pubs.opengroup.org/onlinepubs/9690949399/functions/open.html
> >
> > The manpage for open() says only:
> >
> > EOPNOTSUPP
> > The filesystem containing pathname does not support O_TMPFILE.
> >
> > What is the poor userland developer to make of this when open() starts
> > returning EOPNOTSUPP without O_TMPFILE being specified?
>
> So I wouldn't care as much about POSIX, we largely ignore it anyway in the
> kernel. But I tend to agree that changing the error code we returned for
> several decades just for the sake of "cleanliness" isn't IMHO a good enough
> reason to risk breaking userspace or causing confusion.
>
> Honza
> --
> Jan Kara <jack@suse.com>
> SUSE Labs, CR
For what its worth, the EACCES return value for not having a create() call on
the fs is also not specified in the open() man page. For mkdir, EPERM IS specified.
But in general, can we never add new error codes to any syscall? Are there user
programs that do neatly check for each specified error code in the man page, but
that do not implement a fallback at all? I mean, I am not unsympathetic to the
arguments that you and Jeff make, but such a user program would be odd.
Best,
Jori.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] vfs: missing inode operation should return a consistent error code
2026-06-01 16:27 ` Jori Koolstra
@ 2026-06-01 16:50 ` Jan Kara
2026-06-11 20:31 ` Jori Koolstra
2026-06-17 14:44 ` Pedro Falcato
0 siblings, 2 replies; 8+ messages in thread
From: Jan Kara @ 2026-06-01 16:50 UTC (permalink / raw)
To: Jori Koolstra
Cc: Jan Kara, Jeff Layton, Alexander Viro, Christian Brauner,
Arnd Bergmann, open list:FILESYSTEMS (VFS and infrastructure),
open list, open list:GENERIC INCLUDE/ASM HEADER FILES
On Mon 01-06-26 18:27:53, Jori Koolstra wrote:
>
> > Op 01-06-2026 17:58 CEST schreef Jan Kara <jack@suse.cz>:
> >
> >
> > On Sun 31-05-26 10:08:47, Jeff Layton wrote:
> > >
> > > This seems ill-advised. The problem is that most of this behavior has
> > > been well established for years, and not all userland software (and
> > > even some internal callers like nfsd), will react well when you go
> > > changing behavior like this.
> > >
> > > As a case in point, the POSIX spec doesn't list EOPNOTSUPP as a valid
> > > error return for open():
> > >
> > > https://pubs.opengroup.org/onlinepubs/9690949399/functions/open.html
> > >
> > > The manpage for open() says only:
> > >
> > > EOPNOTSUPP
> > > The filesystem containing pathname does not support O_TMPFILE.
> > >
> > > What is the poor userland developer to make of this when open() starts
> > > returning EOPNOTSUPP without O_TMPFILE being specified?
> >
> > So I wouldn't care as much about POSIX, we largely ignore it anyway in the
> > kernel. But I tend to agree that changing the error code we returned for
> > several decades just for the sake of "cleanliness" isn't IMHO a good enough
> > reason to risk breaking userspace or causing confusion.
> >
> > Honza
> > --
> > Jan Kara <jack@suse.com>
> > SUSE Labs, CR
>
> For what its worth, the EACCES return value for not having a create()
> call on the fs is also not specified in the open() man page. For mkdir,
> EPERM IS specified.
Yep, as I said we don't really follow POSIX closely. And it goes way
further than just error code :)
> But in general, can we never add new error codes to any syscall? Are
> there user programs that do neatly check for each specified error code in
> the man page, but that do not implement a fallback at all? I mean, I am
> not unsympathetic to the arguments that you and Jeff make, but such a
> user program would be odd.
We certainly can (and sometimes do) modify the returned errors. It is
always just a balancing act between the benefit of the change and chances
somebody will get broken by it. In this case I don't quite see the
benefit, not that I'd be too worried about the a regression but there's
always the chance...
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] vfs: missing inode operation should return a consistent error code
2026-06-01 16:50 ` Jan Kara
@ 2026-06-11 20:31 ` Jori Koolstra
2026-06-17 13:24 ` Christian Brauner
2026-06-17 14:44 ` Pedro Falcato
1 sibling, 1 reply; 8+ messages in thread
From: Jori Koolstra @ 2026-06-11 20:31 UTC (permalink / raw)
To: Jan Kara, Christian Brauner
Cc: Jeff Layton, Alexander Viro, Arnd Bergmann,
open list:FILESYSTEMS (VFS and infrastructure), open list,
open list:GENERIC INCLUDE/ASM HEADER FILES
@Christian, since you suggested equalizing the error codes for missing
inode ops, what is your opinion?
> Op 01-06-2026 18:50 CEST schreef Jan Kara <jack@suse.cz>:
>
> We certainly can (and sometimes do) modify the returned errors. It is
> always just a balancing act between the benefit of the change and chances
> somebody will get broken by it. In this case I don't quite see the
> benefit, not that I'd be too worried about the a regression but there's
> always the chance...
>
> Honza
No, I get that, and maybe you are right. I feel in this case it would be
really odd if this breaks anyone's application. It would mean you are
rigorously testing for receiving specific error codes, without handling
a general error case. That just seems odd, especially since some of these
error codes are not even listed as a possibility for missing ops (like EACCES).
I would say we change this and revert if anyone complains. I believe that was
also Christian's view in another thread, but I may be mistaken.
But regardless, it's just a nice to have, and I can definitely live without.
It is just a clean-up I came across while working on O_CREAT|O_DIRECTORY.
Best,
Jori.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] vfs: missing inode operation should return a consistent error code
2026-06-11 20:31 ` Jori Koolstra
@ 2026-06-17 13:24 ` Christian Brauner
0 siblings, 0 replies; 8+ messages in thread
From: Christian Brauner @ 2026-06-17 13:24 UTC (permalink / raw)
To: Jori Koolstra
Cc: Jan Kara, Jeff Layton, Alexander Viro, Arnd Bergmann,
open list:FILESYSTEMS (VFS and infrastructure), open list,
open list:GENERIC INCLUDE/ASM HEADER FILES
On Thu, Jun 11, 2026 at 10:31:12PM +0200, Jori Koolstra wrote:
> @Christian, since you suggested equalizing the error codes for missing
> inode ops, what is your opinion?
>
> > Op 01-06-2026 18:50 CEST schreef Jan Kara <jack@suse.cz>:
> >
> > We certainly can (and sometimes do) modify the returned errors. It is
> > always just a balancing act between the benefit of the change and chances
> > somebody will get broken by it. In this case I don't quite see the
> > benefit, not that I'd be too worried about the a regression but there's
> > always the chance...
> >
> > Honza
>
> No, I get that, and maybe you are right. I feel in this case it would be
> really odd if this breaks anyone's application. It would mean you are
> rigorously testing for receiving specific error codes, without handling
> a general error case. That just seems odd, especially since some of these
> error codes are not even listed as a possibility for missing ops (like EACCES).
> I would say we change this and revert if anyone complains. I believe that was
> also Christian's view in another thread, but I may be mistaken.
It's a general stance, yes. I think trying to make the things we
maintain more consistent is worth risking someone reporting a
regression.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] vfs: missing inode operation should return a consistent error code
2026-06-01 16:50 ` Jan Kara
2026-06-11 20:31 ` Jori Koolstra
@ 2026-06-17 14:44 ` Pedro Falcato
1 sibling, 0 replies; 8+ messages in thread
From: Pedro Falcato @ 2026-06-17 14:44 UTC (permalink / raw)
To: Jan Kara
Cc: Jori Koolstra, Jeff Layton, Alexander Viro, Christian Brauner,
Arnd Bergmann, open list:FILESYSTEMS (VFS and infrastructure),
open list, open list:GENERIC INCLUDE/ASM HEADER FILES
On Mon, Jun 01, 2026 at 06:50:10PM +0200, Jan Kara wrote:
> On Mon 01-06-26 18:27:53, Jori Koolstra wrote:
> >
> > > Op 01-06-2026 17:58 CEST schreef Jan Kara <jack@suse.cz>:
> > >
> > >
> > > On Sun 31-05-26 10:08:47, Jeff Layton wrote:
> > > >
> > > > This seems ill-advised. The problem is that most of this behavior has
> > > > been well established for years, and not all userland software (and
> > > > even some internal callers like nfsd), will react well when you go
> > > > changing behavior like this.
> > > >
> > > > As a case in point, the POSIX spec doesn't list EOPNOTSUPP as a valid
> > > > error return for open():
> > > >
> > > > https://pubs.opengroup.org/onlinepubs/9690949399/functions/open.html
> > > >
> > > > The manpage for open() says only:
> > > >
> > > > EOPNOTSUPP
> > > > The filesystem containing pathname does not support O_TMPFILE.
> > > >
> > > > What is the poor userland developer to make of this when open() starts
> > > > returning EOPNOTSUPP without O_TMPFILE being specified?
> > >
> > > So I wouldn't care as much about POSIX, we largely ignore it anyway in the
> > > kernel. But I tend to agree that changing the error code we returned for
> > > several decades just for the sake of "cleanliness" isn't IMHO a good enough
> > > reason to risk breaking userspace or causing confusion.
> > >
> > > Honza
> > > --
> > > Jan Kara <jack@suse.com>
> > > SUSE Labs, CR
> >
> > For what its worth, the EACCES return value for not having a create()
> > call on the fs is also not specified in the open() man page. For mkdir,
> > EPERM IS specified.
>
> Yep, as I said we don't really follow POSIX closely. And it goes way
> further than just error code :)
Not trying to excessively necro here (just seen this thread), but I'll
have to interject here: POSIX very much lets you return whatever error codes
you want. Quoting directly from POSIX.1-2024 (System Interfaces, 2.3 Error Numbers)
> Implementations may support additional errors not included in this list,
> may generate errors included in this list under circumstances other than
> those described here, or may contain extensions or limitations that prevent
> some errors from occurring.
and also:
> Implementations may generate error numbers listed here under circumstances
> other than those described [...]
> Implementations shall not generate a different error number from one
> required by this volume of POSIX.1-2024 for an error condition described
> in this volume of POSIX.1-2024, but may generate additional errors unless
> explicitly disallowed for a particular function.
which pretty much give you the freedom to do whatever you want (and that's how
I've seen other people language-lawyer this as well).
So, yes, while it is true that the kernel sometimes treats POSIX as merely a
suggestion, in this case we're strictly adhering :)
>
> > But in general, can we never add new error codes to any syscall? Are
> > there user programs that do neatly check for each specified error code in
> > the man page, but that do not implement a fallback at all? I mean, I am
> > not unsympathetic to the arguments that you and Jeff make, but such a
> > user program would be odd.
>
> We certainly can (and sometimes do) modify the returned errors. It is
> always just a balancing act between the benefit of the change and chances
> somebody will get broken by it. In this case I don't quite see the
> benefit, not that I'd be too worried about the a regression but there's
> always the chance...
>
FWIW my opinion here would be that changing the error number doesn't _really_
matter. Filesystems with missing ops are generally already outliers in "sane
filesystems semantics ", and it's unlikely that someone is doing something like
if (unlink(path) < 0 && errno == EPERM) {
printf("path is bad since you can't unlink it!!!\n");
}
particularly as most of these error numbers are actually impossible to
distinguish (I don't have permissions on the filesystem, or does the
filesystem not implement this op?).
--
Pedro
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-06-17 14:45 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-31 10:49 [PATCH] vfs: missing inode operation should return a consistent error code Jori Koolstra
2026-05-31 14:08 ` Jeff Layton
2026-06-01 15:58 ` Jan Kara
2026-06-01 16:27 ` Jori Koolstra
2026-06-01 16:50 ` Jan Kara
2026-06-11 20:31 ` Jori Koolstra
2026-06-17 13:24 ` Christian Brauner
2026-06-17 14:44 ` Pedro Falcato
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox