Generic Linux architectural discussions
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: Jori Koolstra <jkoolstra@xs4all.nl>,
	Alexander Viro	 <viro@zeniv.linux.org.uk>,
	Christian Brauner <brauner@kernel.org>, Jan Kara <jack@suse.cz>,
	Arnd Bergmann <arnd@arndb.de>
Cc: "open list:FILESYSTEMS (VFS and infrastructure)"	
	<linux-fsdevel@vger.kernel.org>,
	open list <linux-kernel@vger.kernel.org>,
	 "open list:GENERIC INCLUDE/ASM HEADER FILES"	
	<linux-arch@vger.kernel.org>
Subject: Re: [PATCH] vfs: missing inode operation should return a consistent error code
Date: Sun, 31 May 2026 10:08:47 -0400	[thread overview]
Message-ID: <c5e32b78aeaa833d18d9b7a566358a6f71d09f23.camel@kernel.org> (raw)
In-Reply-To: <20260531104947.6142-1-jkoolstra@xs4all.nl>

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>

  reply	other threads:[~2026-05-31 14:08 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c5e32b78aeaa833d18d9b7a566358a6f71d09f23.camel@kernel.org \
    --to=jlayton@kernel.org \
    --cc=arnd@arndb.de \
    --cc=brauner@kernel.org \
    --cc=jack@suse.cz \
    --cc=jkoolstra@xs4all.nl \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox