public inbox for linux-fsdevel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 1/4] openat2: new OPENAT2_REGULAR flag support
  2026-02-06 19:03 [PATCH v4 0/4] openat2: new OPENAT2_REGULAR flag support Dorjoy Chowdhury
@ 2026-02-06 19:03 ` Dorjoy Chowdhury
  0 siblings, 0 replies; 18+ messages in thread
From: Dorjoy Chowdhury @ 2026-02-06 19:03 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-kernel, viro, brauner, jack, jlayton, chuck.lever,
	alex.aring, arnd, adilger, mjguzik, smfrench

This flag indicates the path should be opened if it's a regular file.
This is useful to write secure programs that want to avoid being tricked
into opening device nodes with special semantics while thinking they
operate on regular files. This is a requested feature from uapi-group[1].

A corresponding error code EFTYPE has been introduced. For example, if
openat2 is called on path /dev/null with OPENAT2_REGULAR in the flag param,
it will return -EFTYPE.

When used in combination with O_CREAT, either the regular file is
created, or if the path already exists, it is opened if it's a regular
file. Otherwise, -EFTYPE is returned.

When OPENAT2_REGULAR is combined with O_DIRECTORY, the path will be opened
if the path is either a regular file or a directory.

[1]: https://uapi-group.org/kernel-features/#ability-to-only-open-regular-files

Signed-off-by: Dorjoy Chowdhury <dorjoychy111@gmail.com>
---
 arch/alpha/include/uapi/asm/errno.h        | 2 ++
 arch/alpha/include/uapi/asm/fcntl.h        | 1 +
 arch/mips/include/uapi/asm/errno.h         | 2 ++
 arch/parisc/include/uapi/asm/errno.h       | 2 ++
 arch/parisc/include/uapi/asm/fcntl.h       | 1 +
 arch/sparc/include/uapi/asm/errno.h        | 2 ++
 arch/sparc/include/uapi/asm/fcntl.h        | 1 +
 fs/9p/vfs_inode.c                          | 3 +++
 fs/9p/vfs_inode_dotl.c                     | 3 +++
 fs/ceph/file.c                             | 3 +++
 fs/fuse/dir.c                              | 3 +++
 fs/gfs2/inode.c                            | 3 +++
 fs/namei.c                                 | 9 ++++++++-
 fs/nfs/dir.c                               | 3 +++
 fs/nfs/file.c                              | 3 +++
 fs/open.c                                  | 2 +-
 fs/smb/client/dir.c                        | 3 +++
 fs/vboxsf/dir.c                            | 3 +++
 include/linux/fcntl.h                      | 2 ++
 include/uapi/asm-generic/errno.h           | 2 ++
 include/uapi/asm-generic/fcntl.h           | 4 ++++
 tools/arch/alpha/include/uapi/asm/errno.h  | 2 ++
 tools/arch/mips/include/uapi/asm/errno.h   | 2 ++
 tools/arch/parisc/include/uapi/asm/errno.h | 2 ++
 tools/arch/sparc/include/uapi/asm/errno.h  | 2 ++
 tools/include/uapi/asm-generic/errno.h     | 2 ++
 26 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/arch/alpha/include/uapi/asm/errno.h b/arch/alpha/include/uapi/asm/errno.h
index 6791f6508632..1a99f38813c7 100644
--- a/arch/alpha/include/uapi/asm/errno.h
+++ b/arch/alpha/include/uapi/asm/errno.h
@@ -127,4 +127,6 @@
 
 #define EHWPOISON	139	/* Memory page has hardware error */
 
+#define EFTYPE		140	/* Wrong file type for the intended operation */
+
 #endif
diff --git a/arch/alpha/include/uapi/asm/fcntl.h b/arch/alpha/include/uapi/asm/fcntl.h
index 50bdc8e8a271..fe488bf7c18e 100644
--- a/arch/alpha/include/uapi/asm/fcntl.h
+++ b/arch/alpha/include/uapi/asm/fcntl.h
@@ -34,6 +34,7 @@
 
 #define O_PATH		040000000
 #define __O_TMPFILE	0100000000
+#define OPENAT2_REGULAR	0200000000
 
 #define F_GETLK		7
 #define F_SETLK		8
diff --git a/arch/mips/include/uapi/asm/errno.h b/arch/mips/include/uapi/asm/errno.h
index c01ed91b1ef4..1835a50b69ce 100644
--- a/arch/mips/include/uapi/asm/errno.h
+++ b/arch/mips/include/uapi/asm/errno.h
@@ -126,6 +126,8 @@
 
 #define EHWPOISON	168	/* Memory page has hardware error */
 
+#define EFTYPE		169	/* Wrong file type for the intended operation */
+
 #define EDQUOT		1133	/* Quota exceeded */
 
 
diff --git a/arch/parisc/include/uapi/asm/errno.h b/arch/parisc/include/uapi/asm/errno.h
index 8cbc07c1903e..93194fbb0a80 100644
--- a/arch/parisc/include/uapi/asm/errno.h
+++ b/arch/parisc/include/uapi/asm/errno.h
@@ -124,4 +124,6 @@
 
 #define EHWPOISON	257	/* Memory page has hardware error */
 
+#define EFTYPE		258	/* Wrong file type for the intended operation */
+
 #endif
diff --git a/arch/parisc/include/uapi/asm/fcntl.h b/arch/parisc/include/uapi/asm/fcntl.h
index 03dee816cb13..d46812f2f0f4 100644
--- a/arch/parisc/include/uapi/asm/fcntl.h
+++ b/arch/parisc/include/uapi/asm/fcntl.h
@@ -19,6 +19,7 @@
 
 #define O_PATH		020000000
 #define __O_TMPFILE	040000000
+#define OPENAT2_REGULAR	0100000000
 
 #define F_GETLK64	8
 #define F_SETLK64	9
diff --git a/arch/sparc/include/uapi/asm/errno.h b/arch/sparc/include/uapi/asm/errno.h
index 4a41e7835fd5..71940ec9130b 100644
--- a/arch/sparc/include/uapi/asm/errno.h
+++ b/arch/sparc/include/uapi/asm/errno.h
@@ -117,4 +117,6 @@
 
 #define EHWPOISON	135	/* Memory page has hardware error */
 
+#define EFTYPE		136	/* Wrong file type for the intended operation */
+
 #endif
diff --git a/arch/sparc/include/uapi/asm/fcntl.h b/arch/sparc/include/uapi/asm/fcntl.h
index 67dae75e5274..bb6e9fa94bc9 100644
--- a/arch/sparc/include/uapi/asm/fcntl.h
+++ b/arch/sparc/include/uapi/asm/fcntl.h
@@ -37,6 +37,7 @@
 
 #define O_PATH		0x1000000
 #define __O_TMPFILE	0x2000000
+#define OPENAT2_REGULAR	0x4000000
 
 #define F_GETOWN	5	/*  for sockets. */
 #define F_SETOWN	6	/*  for sockets. */
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 97abe65bf7c1..3d1f91220e17 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -771,6 +771,9 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
 	struct inode *inode;
 	int p9_omode;
 
+	if (flags & OPENAT2_REGULAR)
+		return -EINVAL;
+
 	if (d_in_lookup(dentry)) {
 		struct dentry *res = v9fs_vfs_lookup(dir, dentry, 0);
 		if (res || d_really_is_positive(dentry))
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index 643e759eacb2..2e096eb0be11 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -239,6 +239,9 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
 	struct v9fs_session_info *v9ses;
 	struct posix_acl *pacl = NULL, *dacl = NULL;
 
+	if (flags & OPENAT2_REGULAR)
+		return -EINVAL;
+
 	if (d_in_lookup(dentry)) {
 		struct dentry *res = v9fs_vfs_lookup(dir, dentry, 0);
 		if (res || d_really_is_positive(dentry))
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 31b691b2aea2..d0fa6cd65e0a 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -794,6 +794,9 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
 	if (dentry->d_name.len > NAME_MAX)
 		return -ENAMETOOLONG;
 
+	if (flags & OPENAT2_REGULAR)
+		return -EINVAL;
+
 	err = ceph_wait_on_conflict_unlink(dentry);
 	if (err)
 		return err;
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index f25ee47822ad..cbc6008f6810 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -936,6 +936,9 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
 	if (fuse_is_bad(dir))
 		return -EIO;
 
+	if (flags & OPENAT2_REGULAR)
+		return -EINVAL;
+
 	if (d_in_lookup(entry)) {
 		struct dentry *res = fuse_lookup(dir, entry, 0);
 		if (res || d_really_is_positive(entry))
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index c02ebf0ca625..1efb86b718e1 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -1385,6 +1385,9 @@ static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry,
 {
 	bool excl = !!(flags & O_EXCL);
 
+	if (flags & OPENAT2_REGULAR)
+		return -EINVAL;
+
 	if (d_in_lookup(dentry)) {
 		struct dentry *d = __gfs2_lookup(dir, dentry, file);
 		if (file->f_mode & FMODE_OPENED) {
diff --git a/fs/namei.c b/fs/namei.c
index d7923f2c7b62..a5ce3f91a283 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4614,8 +4614,15 @@ static int do_open(struct nameidata *nd,
 		if (unlikely(error))
 			return error;
 	}
-	if ((nd->flags & LOOKUP_DIRECTORY) && !d_can_lookup(nd->path.dentry))
+
+	if ((open_flag & OPENAT2_REGULAR) && (nd->flags & LOOKUP_DIRECTORY)) {
+		if (!d_is_reg(nd->path.dentry) && !d_can_lookup(nd->path.dentry))
+			return -EFTYPE;
+	} else if ((open_flag & OPENAT2_REGULAR) && !d_is_reg(nd->path.dentry)) {
+		return -EFTYPE;
+	} else if ((nd->flags & LOOKUP_DIRECTORY) && !d_can_lookup(nd->path.dentry)) {
 		return -ENOTDIR;
+	}
 
 	do_truncate = false;
 	acc_mode = op->acc_mode;
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 8f9ea79b7882..ae12bf75ad93 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -2315,6 +2315,9 @@ int nfs_atomic_open_v23(struct inode *dir, struct dentry *dentry,
 	if (dentry->d_name.len > NFS_SERVER(dir)->namelen)
 		return -ENAMETOOLONG;
 
+	if (open_flags & OPENAT2_REGULAR)
+		return -EINVAL;
+
 	if (open_flags & O_CREAT) {
 		error = nfs_do_create(dir, dentry, mode, open_flags);
 		if (!error) {
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 5d08b6409c28..032fc3dbe992 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -52,6 +52,9 @@ int nfs_check_flags(int flags)
 	if ((flags & (O_APPEND | O_DIRECT)) == (O_APPEND | O_DIRECT))
 		return -EINVAL;
 
+	if (flags & OPENAT2_REGULAR)
+		return -EINVAL;
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(nfs_check_flags);
diff --git a/fs/open.c b/fs/open.c
index 74c4c1462b3e..2cef40a3f139 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1211,7 +1211,7 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
 	 * values before calling build_open_flags(), but openat2(2) checks all
 	 * of its arguments.
 	 */
-	if (flags & ~VALID_OPEN_FLAGS)
+	if (flags & ~VALID_OPENAT2_FLAGS)
 		return -EINVAL;
 	if (how->resolve & ~VALID_RESOLVE_FLAGS)
 		return -EINVAL;
diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c
index 747256025e49..fc77c5401574 100644
--- a/fs/smb/client/dir.c
+++ b/fs/smb/client/dir.c
@@ -473,6 +473,9 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
 	if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))
 		return smb_EIO(smb_eio_trace_forced_shutdown);
 
+	if (oflags & OPENAT2_REGULAR)
+		return -EINVAL;
+
 	/*
 	 * Posix open is only called (at lookup time) for file create now. For
 	 * opens (rather than creates), because we do not know if it is a file
diff --git a/fs/vboxsf/dir.c b/fs/vboxsf/dir.c
index 42bedc4ec7af..936ba2962fd0 100644
--- a/fs/vboxsf/dir.c
+++ b/fs/vboxsf/dir.c
@@ -318,6 +318,9 @@ static int vboxsf_dir_atomic_open(struct inode *parent, struct dentry *dentry,
 	u64 handle;
 	int err;
 
+	if (flags & OPENAT2_REGULAR)
+		return -EINVAL;
+
 	if (d_in_lookup(dentry)) {
 		struct dentry *res = vboxsf_dir_lookup(parent, dentry, 0);
 		if (res || d_really_is_positive(dentry))
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index a332e79b3207..a80026718217 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -12,6 +12,8 @@
 	 FASYNC	| O_DIRECT | O_LARGEFILE | O_DIRECTORY | O_NOFOLLOW | \
 	 O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE)
 
+#define VALID_OPENAT2_FLAGS (VALID_OPEN_FLAGS | OPENAT2_REGULAR)
+
 /* List of all valid flags for the how->resolve argument: */
 #define VALID_RESOLVE_FLAGS \
 	(RESOLVE_NO_XDEV | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS | \
diff --git a/include/uapi/asm-generic/errno.h b/include/uapi/asm-generic/errno.h
index 92e7ae493ee3..bd78e69e0a43 100644
--- a/include/uapi/asm-generic/errno.h
+++ b/include/uapi/asm-generic/errno.h
@@ -122,4 +122,6 @@
 
 #define EHWPOISON	133	/* Memory page has hardware error */
 
+#define EFTYPE		134	/* Wrong file type for the intended operation */
+
 #endif
diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index 613475285643..b2c2ddd0edc0 100644
--- a/include/uapi/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h
@@ -88,6 +88,10 @@
 #define __O_TMPFILE	020000000
 #endif
 
+#ifndef OPENAT2_REGULAR
+#define OPENAT2_REGULAR	040000000
+#endif
+
 /* a horrid kludge trying to make sure that this will fail on old kernels */
 #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
 
diff --git a/tools/arch/alpha/include/uapi/asm/errno.h b/tools/arch/alpha/include/uapi/asm/errno.h
index 6791f6508632..1a99f38813c7 100644
--- a/tools/arch/alpha/include/uapi/asm/errno.h
+++ b/tools/arch/alpha/include/uapi/asm/errno.h
@@ -127,4 +127,6 @@
 
 #define EHWPOISON	139	/* Memory page has hardware error */
 
+#define EFTYPE		140	/* Wrong file type for the intended operation */
+
 #endif
diff --git a/tools/arch/mips/include/uapi/asm/errno.h b/tools/arch/mips/include/uapi/asm/errno.h
index c01ed91b1ef4..1835a50b69ce 100644
--- a/tools/arch/mips/include/uapi/asm/errno.h
+++ b/tools/arch/mips/include/uapi/asm/errno.h
@@ -126,6 +126,8 @@
 
 #define EHWPOISON	168	/* Memory page has hardware error */
 
+#define EFTYPE		169	/* Wrong file type for the intended operation */
+
 #define EDQUOT		1133	/* Quota exceeded */
 
 
diff --git a/tools/arch/parisc/include/uapi/asm/errno.h b/tools/arch/parisc/include/uapi/asm/errno.h
index 8cbc07c1903e..93194fbb0a80 100644
--- a/tools/arch/parisc/include/uapi/asm/errno.h
+++ b/tools/arch/parisc/include/uapi/asm/errno.h
@@ -124,4 +124,6 @@
 
 #define EHWPOISON	257	/* Memory page has hardware error */
 
+#define EFTYPE		258	/* Wrong file type for the intended operation */
+
 #endif
diff --git a/tools/arch/sparc/include/uapi/asm/errno.h b/tools/arch/sparc/include/uapi/asm/errno.h
index 4a41e7835fd5..71940ec9130b 100644
--- a/tools/arch/sparc/include/uapi/asm/errno.h
+++ b/tools/arch/sparc/include/uapi/asm/errno.h
@@ -117,4 +117,6 @@
 
 #define EHWPOISON	135	/* Memory page has hardware error */
 
+#define EFTYPE		136	/* Wrong file type for the intended operation */
+
 #endif
diff --git a/tools/include/uapi/asm-generic/errno.h b/tools/include/uapi/asm-generic/errno.h
index 92e7ae493ee3..bd78e69e0a43 100644
--- a/tools/include/uapi/asm-generic/errno.h
+++ b/tools/include/uapi/asm-generic/errno.h
@@ -122,4 +122,6 @@
 
 #define EHWPOISON	133	/* Memory page has hardware error */
 
+#define EFTYPE		134	/* Wrong file type for the intended operation */
+
 #endif
-- 
2.53.0


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

* [PATCH v4 0/4] OPENAT2_REGULAR flag support in openat2
@ 2026-02-21 14:45 Dorjoy Chowdhury
  2026-02-21 14:45 ` [PATCH v4 1/4] openat2: new OPENAT2_REGULAR flag support Dorjoy Chowdhury
                   ` (5 more replies)
  0 siblings, 6 replies; 18+ messages in thread
From: Dorjoy Chowdhury @ 2026-02-21 14:45 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-kernel, ceph-devel, gfs2, linux-nfs, linux-cifs, v9fs,
	linux-kselftest, viro, brauner, jack, jlayton, chuck.lever,
	alex.aring, arnd, adilger, mjguzik, smfrench, richard.henderson,
	mattst88, linmag7, tsbogend, James.Bottomley, deller, davem,
	andreas, idryomov, amarkuze, slava, agruenba, trondmy, anna,
	sfrench, pc, ronniesahlberg, sprasad, tom, bharathsm, shuah,
	miklos, hansg

Hi,

I came upon this "Ability to only open regular files" uapi feature suggestion
from https://uapi-group.org/kernel-features/#ability-to-only-open-regular-files
and thought it would be something I could do as a first patch and get to
know the kernel code a bit better.

I only tested this new flag on my local system (fedora btrfs).

Note that I had submitted a v4 previously (that had -EINVAL for the atomic_open
code paths) but did not do a get_maintainers.pl. It didn't get any review and
please ignore that one anyway. In this version, I have tried to properly update
the filesystems that provide atomic_open (fs/ceph, fs/nfs, fs/smb, fs/gfs2,
fs/fuse, fs/vboxsf, fs/9p) for the new OPENAT2_REGULAR flag. Some of them
(fs/fuse, fs/vboxsf, fs/9p) didn't need any changing. As far as I see, most of
the filesystems do finish_no_open for ~O_CREAT and have file->f_mode |= FMODE_CREATED
for the O_CREAT code path which I assume means they always create new file which
is a regular file. OPENAT2_REGULAR | O_DIRECTORY returns -EINVAL (instead of working
if path is either a directory or regular file) as it was easier to reason about when
making changes in all the filesystems.

Changes in v4:
- changed O_REGULAR to OPENAT2_REGULAR
- OPENAT2_REGULAR does not affect O_PATH
- atomic_open codepaths updated to work properly for OPENAT2_REGULAR
- commit message includes the uapi-group URL
- v3 is at: https://lore.kernel.org/linux-fsdevel/20260127180109.66691-1-dorjoychy111@gmail.com/T/

Changes in v3:
- included motivation about O_REGULAR flag in commit message e.g., programs not wanting to be tricked into opening device nodes
- fixed commit message wrongly referencing ENOTREGULAR instead of ENOTREG
- fixed the O_REGULAR flag in arch/parisc/include/uapi/asm/fcntl.h from 060000000 to 0100000000
- added 2 commits converting arch/{mips,sparc}/include/uapi/asm/fcntl.h O_* macros from hex to octal
- v2 is at: https://lore.kernel.org/linux-fsdevel/20260126154156.55723-1-dorjoychy111@gmail.com/T/

Changes in v2:
- rename ENOTREGULAR to ENOTREG
- define ENOTREG in uapi/asm-generic/errno.h (instead of errno-base.h) and in arch/*/include/uapi/asm/errno.h files
- override O_REGULAR in arch/{alpha,sparc,parisc}/include/uapi/asm/fcntl.h due to clash with include/uapi/asm-generic/fcntl.h
- I have kept the kselftest but now that O_REGULAR and ENOTREG can have different value on different architectures I am not sure if it's right
- v1 is at: https://lore.kernel.org/linux-fsdevel/20260125141518.59493-1-dorjoychy111@gmail.com/T/

Thanks.

Regards,
Dorjoy

Dorjoy Chowdhury (4):
  openat2: new OPENAT2_REGULAR flag support
  kselftest/openat2: test for OPENAT2_REGULAR flag
  sparc/fcntl.h: convert O_* flag macros from hex to octal
  mips/fcntl.h: convert O_* flag macros from hex to octal

 arch/alpha/include/uapi/asm/errno.h           |  2 +
 arch/alpha/include/uapi/asm/fcntl.h           |  1 +
 arch/mips/include/uapi/asm/errno.h            |  2 +
 arch/mips/include/uapi/asm/fcntl.h            | 22 +++++------
 arch/parisc/include/uapi/asm/errno.h          |  2 +
 arch/parisc/include/uapi/asm/fcntl.h          |  1 +
 arch/sparc/include/uapi/asm/errno.h           |  2 +
 arch/sparc/include/uapi/asm/fcntl.h           | 35 +++++++++---------
 fs/ceph/file.c                                |  4 ++
 fs/gfs2/inode.c                               |  2 +
 fs/namei.c                                    |  4 ++
 fs/nfs/dir.c                                  |  4 +-
 fs/open.c                                     |  4 +-
 fs/smb/client/dir.c                           | 11 +++++-
 include/linux/fcntl.h                         |  2 +
 include/uapi/asm-generic/errno.h              |  2 +
 include/uapi/asm-generic/fcntl.h              |  4 ++
 tools/arch/alpha/include/uapi/asm/errno.h     |  2 +
 tools/arch/mips/include/uapi/asm/errno.h      |  2 +
 tools/arch/parisc/include/uapi/asm/errno.h    |  2 +
 tools/arch/sparc/include/uapi/asm/errno.h     |  2 +
 tools/include/uapi/asm-generic/errno.h        |  2 +
 .../testing/selftests/openat2/openat2_test.c  | 37 ++++++++++++++++++-
 23 files changed, 119 insertions(+), 32 deletions(-)

-- 
2.53.0


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

* [PATCH v4 1/4] openat2: new OPENAT2_REGULAR flag support
  2026-02-21 14:45 [PATCH v4 0/4] OPENAT2_REGULAR flag support in openat2 Dorjoy Chowdhury
@ 2026-02-21 14:45 ` Dorjoy Chowdhury
  2026-03-01 12:44   ` Jeff Layton
  2026-02-21 14:45 ` [PATCH v4 2/4] kselftest/openat2: test for OPENAT2_REGULAR flag Dorjoy Chowdhury
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 18+ messages in thread
From: Dorjoy Chowdhury @ 2026-02-21 14:45 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-kernel, ceph-devel, gfs2, linux-nfs, linux-cifs, v9fs,
	linux-kselftest, viro, brauner, jack, jlayton, chuck.lever,
	alex.aring, arnd, adilger, mjguzik, smfrench, richard.henderson,
	mattst88, linmag7, tsbogend, James.Bottomley, deller, davem,
	andreas, idryomov, amarkuze, slava, agruenba, trondmy, anna,
	sfrench, pc, ronniesahlberg, sprasad, tom, bharathsm, shuah,
	miklos, hansg

This flag indicates the path should be opened if it's a regular file.
This is useful to write secure programs that want to avoid being
tricked into opening device nodes with special semantics while thinking
they operate on regular files. This is a requested feature from the
uapi-group[1].

A corresponding error code EFTYPE has been introduced. For example, if
openat2 is called on path /dev/null with OPENAT2_REGULAR in the flag
param, it will return -EFTYPE.

When used in combination with O_CREAT, either the regular file is
created, or if the path already exists, it is opened if it's a regular
file. Otherwise, -EFTYPE is returned.

When OPENAT2_REGULAR is combined with O_DIRECTORY, -EINVAL is returned
as it doesn't make sense to open a path that is both a directory and a
regular file.

[1]: https://uapi-group.org/kernel-features/#ability-to-only-open-regular-files

Signed-off-by: Dorjoy Chowdhury <dorjoychy111@gmail.com>
---
 arch/alpha/include/uapi/asm/errno.h        |  2 ++
 arch/alpha/include/uapi/asm/fcntl.h        |  1 +
 arch/mips/include/uapi/asm/errno.h         |  2 ++
 arch/parisc/include/uapi/asm/errno.h       |  2 ++
 arch/parisc/include/uapi/asm/fcntl.h       |  1 +
 arch/sparc/include/uapi/asm/errno.h        |  2 ++
 arch/sparc/include/uapi/asm/fcntl.h        |  1 +
 fs/ceph/file.c                             |  4 ++++
 fs/gfs2/inode.c                            |  2 ++
 fs/namei.c                                 |  4 ++++
 fs/nfs/dir.c                               |  4 +++-
 fs/open.c                                  |  4 +++-
 fs/smb/client/dir.c                        | 11 ++++++++++-
 include/linux/fcntl.h                      |  2 ++
 include/uapi/asm-generic/errno.h           |  2 ++
 include/uapi/asm-generic/fcntl.h           |  4 ++++
 tools/arch/alpha/include/uapi/asm/errno.h  |  2 ++
 tools/arch/mips/include/uapi/asm/errno.h   |  2 ++
 tools/arch/parisc/include/uapi/asm/errno.h |  2 ++
 tools/arch/sparc/include/uapi/asm/errno.h  |  2 ++
 tools/include/uapi/asm-generic/errno.h     |  2 ++
 21 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/arch/alpha/include/uapi/asm/errno.h b/arch/alpha/include/uapi/asm/errno.h
index 6791f6508632..1a99f38813c7 100644
--- a/arch/alpha/include/uapi/asm/errno.h
+++ b/arch/alpha/include/uapi/asm/errno.h
@@ -127,4 +127,6 @@
 
 #define EHWPOISON	139	/* Memory page has hardware error */
 
+#define EFTYPE		140	/* Wrong file type for the intended operation */
+
 #endif
diff --git a/arch/alpha/include/uapi/asm/fcntl.h b/arch/alpha/include/uapi/asm/fcntl.h
index 50bdc8e8a271..fe488bf7c18e 100644
--- a/arch/alpha/include/uapi/asm/fcntl.h
+++ b/arch/alpha/include/uapi/asm/fcntl.h
@@ -34,6 +34,7 @@
 
 #define O_PATH		040000000
 #define __O_TMPFILE	0100000000
+#define OPENAT2_REGULAR	0200000000
 
 #define F_GETLK		7
 #define F_SETLK		8
diff --git a/arch/mips/include/uapi/asm/errno.h b/arch/mips/include/uapi/asm/errno.h
index c01ed91b1ef4..1835a50b69ce 100644
--- a/arch/mips/include/uapi/asm/errno.h
+++ b/arch/mips/include/uapi/asm/errno.h
@@ -126,6 +126,8 @@
 
 #define EHWPOISON	168	/* Memory page has hardware error */
 
+#define EFTYPE		169	/* Wrong file type for the intended operation */
+
 #define EDQUOT		1133	/* Quota exceeded */
 
 
diff --git a/arch/parisc/include/uapi/asm/errno.h b/arch/parisc/include/uapi/asm/errno.h
index 8cbc07c1903e..93194fbb0a80 100644
--- a/arch/parisc/include/uapi/asm/errno.h
+++ b/arch/parisc/include/uapi/asm/errno.h
@@ -124,4 +124,6 @@
 
 #define EHWPOISON	257	/* Memory page has hardware error */
 
+#define EFTYPE		258	/* Wrong file type for the intended operation */
+
 #endif
diff --git a/arch/parisc/include/uapi/asm/fcntl.h b/arch/parisc/include/uapi/asm/fcntl.h
index 03dee816cb13..d46812f2f0f4 100644
--- a/arch/parisc/include/uapi/asm/fcntl.h
+++ b/arch/parisc/include/uapi/asm/fcntl.h
@@ -19,6 +19,7 @@
 
 #define O_PATH		020000000
 #define __O_TMPFILE	040000000
+#define OPENAT2_REGULAR	0100000000
 
 #define F_GETLK64	8
 #define F_SETLK64	9
diff --git a/arch/sparc/include/uapi/asm/errno.h b/arch/sparc/include/uapi/asm/errno.h
index 4a41e7835fd5..71940ec9130b 100644
--- a/arch/sparc/include/uapi/asm/errno.h
+++ b/arch/sparc/include/uapi/asm/errno.h
@@ -117,4 +117,6 @@
 
 #define EHWPOISON	135	/* Memory page has hardware error */
 
+#define EFTYPE		136	/* Wrong file type for the intended operation */
+
 #endif
diff --git a/arch/sparc/include/uapi/asm/fcntl.h b/arch/sparc/include/uapi/asm/fcntl.h
index 67dae75e5274..bb6e9fa94bc9 100644
--- a/arch/sparc/include/uapi/asm/fcntl.h
+++ b/arch/sparc/include/uapi/asm/fcntl.h
@@ -37,6 +37,7 @@
 
 #define O_PATH		0x1000000
 #define __O_TMPFILE	0x2000000
+#define OPENAT2_REGULAR	0x4000000
 
 #define F_GETOWN	5	/*  for sockets. */
 #define F_SETOWN	6	/*  for sockets. */
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 31b691b2aea2..0a4220f72ada 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -977,6 +977,10 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
 			ceph_init_inode_acls(newino, &as_ctx);
 			file->f_mode |= FMODE_CREATED;
 		}
+		if ((flags & OPENAT2_REGULAR) && !d_is_reg(dentry)) {
+			err = -EFTYPE;
+			goto out_req;
+		}
 		err = finish_open(file, dentry, ceph_open);
 	}
 out_req:
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 8344040ecaf7..0dc3e4240d9e 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -749,6 +749,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
 		if (file) {
 			if (S_ISREG(inode->i_mode))
 				error = finish_open(file, dentry, gfs2_open_common);
+			else if (file->f_flags & OPENAT2_REGULAR)
+				error = -EFTYPE;
 			else
 				error = finish_no_open(file, NULL);
 		}
diff --git a/fs/namei.c b/fs/namei.c
index 5fe6cac48df8..aa5fb2672881 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4651,6 +4651,10 @@ static int do_open(struct nameidata *nd,
 		if (unlikely(error))
 			return error;
 	}
+
+	if ((open_flag & OPENAT2_REGULAR) && !d_is_reg(nd->path.dentry))
+		return -EFTYPE;
+
 	if ((nd->flags & LOOKUP_DIRECTORY) && !d_can_lookup(nd->path.dentry))
 		return -ENOTDIR;
 
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index b3f5c9461204..ef61db67d06e 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -2195,7 +2195,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
 			break;
 		case -EISDIR:
 		case -ENOTDIR:
-			goto no_open;
+			if (!(open_flags & OPENAT2_REGULAR))
+				goto no_open;
+			break;
 		case -ELOOP:
 			if (!(open_flags & O_NOFOLLOW))
 				goto no_open;
diff --git a/fs/open.c b/fs/open.c
index 91f1139591ab..1524f52a1773 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1198,7 +1198,7 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
 	 * values before calling build_open_flags(), but openat2(2) checks all
 	 * of its arguments.
 	 */
-	if (flags & ~VALID_OPEN_FLAGS)
+	if (flags & ~VALID_OPENAT2_FLAGS)
 		return -EINVAL;
 	if (how->resolve & ~VALID_RESOLVE_FLAGS)
 		return -EINVAL;
@@ -1237,6 +1237,8 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
 			return -EINVAL;
 		if (!(acc_mode & MAY_WRITE))
 			return -EINVAL;
+	} else if ((flags & O_DIRECTORY) && (flags & OPENAT2_REGULAR)) {
+		return -EINVAL;
 	}
 	if (flags & O_PATH) {
 		/* O_PATH only permits certain other flags to be set. */
diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c
index cb10088197d2..d12ed0c87599 100644
--- a/fs/smb/client/dir.c
+++ b/fs/smb/client/dir.c
@@ -236,6 +236,11 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
 				 * lookup.
 				 */
 				CIFSSMBClose(xid, tcon, fid->netfid);
+				if (oflags & OPENAT2_REGULAR) {
+					iput(newinode);
+					rc = -EFTYPE;
+					goto out;
+				}
 				goto cifs_create_get_file_info;
 			}
 			/* success, no need to query */
@@ -433,11 +438,15 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
 		goto out_err;
 	}
 
-	if (newinode)
+	if (newinode) {
 		if (S_ISDIR(newinode->i_mode)) {
 			rc = -EISDIR;
 			goto out_err;
+		} else if ((oflags & OPENAT2_REGULAR) && !S_ISREG(newinode->i_mode)) {
+			rc = -EFTYPE;
+			goto out_err;
 		}
+	}
 
 	d_drop(direntry);
 	d_add(direntry, newinode);
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index a332e79b3207..a80026718217 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -12,6 +12,8 @@
 	 FASYNC	| O_DIRECT | O_LARGEFILE | O_DIRECTORY | O_NOFOLLOW | \
 	 O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE)
 
+#define VALID_OPENAT2_FLAGS (VALID_OPEN_FLAGS | OPENAT2_REGULAR)
+
 /* List of all valid flags for the how->resolve argument: */
 #define VALID_RESOLVE_FLAGS \
 	(RESOLVE_NO_XDEV | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS | \
diff --git a/include/uapi/asm-generic/errno.h b/include/uapi/asm-generic/errno.h
index 92e7ae493ee3..bd78e69e0a43 100644
--- a/include/uapi/asm-generic/errno.h
+++ b/include/uapi/asm-generic/errno.h
@@ -122,4 +122,6 @@
 
 #define EHWPOISON	133	/* Memory page has hardware error */
 
+#define EFTYPE		134	/* Wrong file type for the intended operation */
+
 #endif
diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index 613475285643..b2c2ddd0edc0 100644
--- a/include/uapi/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h
@@ -88,6 +88,10 @@
 #define __O_TMPFILE	020000000
 #endif
 
+#ifndef OPENAT2_REGULAR
+#define OPENAT2_REGULAR	040000000
+#endif
+
 /* a horrid kludge trying to make sure that this will fail on old kernels */
 #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
 
diff --git a/tools/arch/alpha/include/uapi/asm/errno.h b/tools/arch/alpha/include/uapi/asm/errno.h
index 6791f6508632..1a99f38813c7 100644
--- a/tools/arch/alpha/include/uapi/asm/errno.h
+++ b/tools/arch/alpha/include/uapi/asm/errno.h
@@ -127,4 +127,6 @@
 
 #define EHWPOISON	139	/* Memory page has hardware error */
 
+#define EFTYPE		140	/* Wrong file type for the intended operation */
+
 #endif
diff --git a/tools/arch/mips/include/uapi/asm/errno.h b/tools/arch/mips/include/uapi/asm/errno.h
index c01ed91b1ef4..1835a50b69ce 100644
--- a/tools/arch/mips/include/uapi/asm/errno.h
+++ b/tools/arch/mips/include/uapi/asm/errno.h
@@ -126,6 +126,8 @@
 
 #define EHWPOISON	168	/* Memory page has hardware error */
 
+#define EFTYPE		169	/* Wrong file type for the intended operation */
+
 #define EDQUOT		1133	/* Quota exceeded */
 
 
diff --git a/tools/arch/parisc/include/uapi/asm/errno.h b/tools/arch/parisc/include/uapi/asm/errno.h
index 8cbc07c1903e..93194fbb0a80 100644
--- a/tools/arch/parisc/include/uapi/asm/errno.h
+++ b/tools/arch/parisc/include/uapi/asm/errno.h
@@ -124,4 +124,6 @@
 
 #define EHWPOISON	257	/* Memory page has hardware error */
 
+#define EFTYPE		258	/* Wrong file type for the intended operation */
+
 #endif
diff --git a/tools/arch/sparc/include/uapi/asm/errno.h b/tools/arch/sparc/include/uapi/asm/errno.h
index 4a41e7835fd5..71940ec9130b 100644
--- a/tools/arch/sparc/include/uapi/asm/errno.h
+++ b/tools/arch/sparc/include/uapi/asm/errno.h
@@ -117,4 +117,6 @@
 
 #define EHWPOISON	135	/* Memory page has hardware error */
 
+#define EFTYPE		136	/* Wrong file type for the intended operation */
+
 #endif
diff --git a/tools/include/uapi/asm-generic/errno.h b/tools/include/uapi/asm-generic/errno.h
index 92e7ae493ee3..bd78e69e0a43 100644
--- a/tools/include/uapi/asm-generic/errno.h
+++ b/tools/include/uapi/asm-generic/errno.h
@@ -122,4 +122,6 @@
 
 #define EHWPOISON	133	/* Memory page has hardware error */
 
+#define EFTYPE		134	/* Wrong file type for the intended operation */
+
 #endif
-- 
2.53.0


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

* [PATCH v4 2/4] kselftest/openat2: test for OPENAT2_REGULAR flag
  2026-02-21 14:45 [PATCH v4 0/4] OPENAT2_REGULAR flag support in openat2 Dorjoy Chowdhury
  2026-02-21 14:45 ` [PATCH v4 1/4] openat2: new OPENAT2_REGULAR flag support Dorjoy Chowdhury
@ 2026-02-21 14:45 ` Dorjoy Chowdhury
  2026-02-21 14:45 ` [PATCH v4 3/4] sparc/fcntl.h: convert O_* flag macros from hex to octal Dorjoy Chowdhury
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 18+ messages in thread
From: Dorjoy Chowdhury @ 2026-02-21 14:45 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-kernel, ceph-devel, gfs2, linux-nfs, linux-cifs, v9fs,
	linux-kselftest, viro, brauner, jack, jlayton, chuck.lever,
	alex.aring, arnd, adilger, mjguzik, smfrench, richard.henderson,
	mattst88, linmag7, tsbogend, James.Bottomley, deller, davem,
	andreas, idryomov, amarkuze, slava, agruenba, trondmy, anna,
	sfrench, pc, ronniesahlberg, sprasad, tom, bharathsm, shuah,
	miklos, hansg

Just a happy path test.

Signed-off-by: Dorjoy Chowdhury <dorjoychy111@gmail.com>
---
 .../testing/selftests/openat2/openat2_test.c  | 37 ++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/openat2/openat2_test.c b/tools/testing/selftests/openat2/openat2_test.c
index 0e161ef9e9e4..e8847f7d416c 100644
--- a/tools/testing/selftests/openat2/openat2_test.c
+++ b/tools/testing/selftests/openat2/openat2_test.c
@@ -320,8 +320,42 @@ void test_openat2_flags(void)
 	}
 }
 
+#ifndef OPENAT2_REGULAR
+#define OPENAT2_REGULAR 040000000
+#endif
+
+#ifndef EFTYPE
+#define EFTYPE 134
+#endif
+
+void test_openat2_regular_flag(void)
+{
+	if (!openat2_supported) {
+		ksft_test_result_skip("Skipping %s as openat2 is not supported\n", __func__);
+		return;
+	}
+
+	struct open_how how = {
+		.flags = OPENAT2_REGULAR | O_RDONLY
+	};
+
+	int fd = sys_openat2(AT_FDCWD, "/dev/null", &how);
+
+	if (fd == -ENOENT) {
+		ksft_test_result_skip("Skipping %s as there is no /dev/null\n", __func__);
+		return;
+	}
+
+	if (fd != -EFTYPE) {
+		ksft_test_result_fail("openat2 should return EFTYPE\n");
+		return;
+	}
+
+	ksft_test_result_pass("%s succeeded\n", __func__);
+}
+
 #define NUM_TESTS (NUM_OPENAT2_STRUCT_VARIATIONS * NUM_OPENAT2_STRUCT_TESTS + \
-		   NUM_OPENAT2_FLAG_TESTS)
+		   NUM_OPENAT2_FLAG_TESTS + 1)
 
 int main(int argc, char **argv)
 {
@@ -330,6 +364,7 @@ int main(int argc, char **argv)
 
 	test_openat2_struct();
 	test_openat2_flags();
+	test_openat2_regular_flag();
 
 	if (ksft_get_fail_cnt() + ksft_get_error_cnt() > 0)
 		ksft_exit_fail();
-- 
2.53.0


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

* [PATCH v4 3/4] sparc/fcntl.h: convert O_* flag macros from hex to octal
  2026-02-21 14:45 [PATCH v4 0/4] OPENAT2_REGULAR flag support in openat2 Dorjoy Chowdhury
  2026-02-21 14:45 ` [PATCH v4 1/4] openat2: new OPENAT2_REGULAR flag support Dorjoy Chowdhury
  2026-02-21 14:45 ` [PATCH v4 2/4] kselftest/openat2: test for OPENAT2_REGULAR flag Dorjoy Chowdhury
@ 2026-02-21 14:45 ` Dorjoy Chowdhury
  2026-02-21 14:45 ` [PATCH v4 4/4] mips/fcntl.h: " Dorjoy Chowdhury
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 18+ messages in thread
From: Dorjoy Chowdhury @ 2026-02-21 14:45 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-kernel, ceph-devel, gfs2, linux-nfs, linux-cifs, v9fs,
	linux-kselftest, viro, brauner, jack, jlayton, chuck.lever,
	alex.aring, arnd, adilger, mjguzik, smfrench, richard.henderson,
	mattst88, linmag7, tsbogend, James.Bottomley, deller, davem,
	andreas, idryomov, amarkuze, slava, agruenba, trondmy, anna,
	sfrench, pc, ronniesahlberg, sprasad, tom, bharathsm, shuah,
	miklos, hansg

Following the convention in include/uapi/asm-generic/fcntl.h and other
architecture specific arch/*/include/uapi/asm/fcntl.h files.

Signed-off-by: Dorjoy Chowdhury <dorjoychy111@gmail.com>
---
 arch/sparc/include/uapi/asm/fcntl.h | 36 ++++++++++++++---------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/arch/sparc/include/uapi/asm/fcntl.h b/arch/sparc/include/uapi/asm/fcntl.h
index bb6e9fa94bc9..33ce58ec57f6 100644
--- a/arch/sparc/include/uapi/asm/fcntl.h
+++ b/arch/sparc/include/uapi/asm/fcntl.h
@@ -2,23 +2,23 @@
 #ifndef _SPARC_FCNTL_H
 #define _SPARC_FCNTL_H
 
-#define O_APPEND	0x0008
-#define FASYNC		0x0040	/* fcntl, for BSD compatibility */
-#define O_CREAT		0x0200	/* not fcntl */
-#define O_TRUNC		0x0400	/* not fcntl */
-#define O_EXCL		0x0800	/* not fcntl */
-#define O_DSYNC		0x2000	/* used to be O_SYNC, see below */
-#define O_NONBLOCK	0x4000
+#define O_APPEND	0000000010
+#define FASYNC		0000000100	/* fcntl, for BSD compatibility */
+#define O_CREAT		0000001000	/* not fcntl */
+#define O_TRUNC		0000002000	/* not fcntl */
+#define O_EXCL		0000004000	/* not fcntl */
+#define O_DSYNC		0000020000	/* used to be O_SYNC, see below */
+#define O_NONBLOCK	0000040000
 #if defined(__sparc__) && defined(__arch64__)
-#define O_NDELAY	0x0004
+#define O_NDELAY	0000000004
 #else
-#define O_NDELAY	(0x0004 | O_NONBLOCK)
+#define O_NDELAY	(0000000004 | O_NONBLOCK)
 #endif
-#define O_NOCTTY	0x8000	/* not fcntl */
-#define O_LARGEFILE	0x40000
-#define O_DIRECT        0x100000 /* direct disk access hint */
-#define O_NOATIME	0x200000
-#define O_CLOEXEC	0x400000
+#define O_NOCTTY	0000100000	/* not fcntl */
+#define O_LARGEFILE	0001000000
+#define O_DIRECT        0004000000 /* direct disk access hint */
+#define O_NOATIME	0010000000
+#define O_CLOEXEC	0020000000
 /*
  * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using
  * the O_SYNC flag.  We continue to use the existing numerical value
@@ -32,12 +32,12 @@
  *
  * Note: __O_SYNC must never be used directly.
  */
-#define __O_SYNC	0x800000
+#define __O_SYNC	0040000000
 #define O_SYNC		(__O_SYNC|O_DSYNC)
 
-#define O_PATH		0x1000000
-#define __O_TMPFILE	0x2000000
-#define OPENAT2_REGULAR	0x4000000
+#define O_PATH		0100000000
+#define __O_TMPFILE	0200000000
+#define OPENAT2_REGULAR	0400000000
 
 #define F_GETOWN	5	/*  for sockets. */
 #define F_SETOWN	6	/*  for sockets. */
-- 
2.53.0


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

* [PATCH v4 4/4] mips/fcntl.h: convert O_* flag macros from hex to octal
  2026-02-21 14:45 [PATCH v4 0/4] OPENAT2_REGULAR flag support in openat2 Dorjoy Chowdhury
                   ` (2 preceding siblings ...)
  2026-02-21 14:45 ` [PATCH v4 3/4] sparc/fcntl.h: convert O_* flag macros from hex to octal Dorjoy Chowdhury
@ 2026-02-21 14:45 ` Dorjoy Chowdhury
  2026-02-21 15:49 ` [PATCH v4 0/4] OPENAT2_REGULAR flag support in openat2 Dorjoy Chowdhury
  2026-03-01 10:16 ` Dorjoy Chowdhury
  5 siblings, 0 replies; 18+ messages in thread
From: Dorjoy Chowdhury @ 2026-02-21 14:45 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-kernel, ceph-devel, gfs2, linux-nfs, linux-cifs, v9fs,
	linux-kselftest, viro, brauner, jack, jlayton, chuck.lever,
	alex.aring, arnd, adilger, mjguzik, smfrench, richard.henderson,
	mattst88, linmag7, tsbogend, James.Bottomley, deller, davem,
	andreas, idryomov, amarkuze, slava, agruenba, trondmy, anna,
	sfrench, pc, ronniesahlberg, sprasad, tom, bharathsm, shuah,
	miklos, hansg

Following the convention in include/uapi/asm-generic/fcntl.h and other
architecture specific arch/*/include/uapi/asm/fcntl.h files.

Signed-off-by: Dorjoy Chowdhury <dorjoychy111@gmail.com>
---
 arch/mips/include/uapi/asm/fcntl.h | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/mips/include/uapi/asm/fcntl.h b/arch/mips/include/uapi/asm/fcntl.h
index 0369a38e3d4f..6aa3f49df17e 100644
--- a/arch/mips/include/uapi/asm/fcntl.h
+++ b/arch/mips/include/uapi/asm/fcntl.h
@@ -11,15 +11,15 @@
 
 #include <asm/sgidefs.h>
 
-#define O_APPEND	0x0008
-#define O_DSYNC		0x0010	/* used to be O_SYNC, see below */
-#define O_NONBLOCK	0x0080
-#define O_CREAT		0x0100	/* not fcntl */
-#define O_TRUNC		0x0200	/* not fcntl */
-#define O_EXCL		0x0400	/* not fcntl */
-#define O_NOCTTY	0x0800	/* not fcntl */
-#define FASYNC		0x1000	/* fcntl, for BSD compatibility */
-#define O_LARGEFILE	0x2000	/* allow large file opens */
+#define O_APPEND	0000010
+#define O_DSYNC		0000020	/* used to be O_SYNC, see below */
+#define O_NONBLOCK	0000200
+#define O_CREAT		0000400	/* not fcntl */
+#define O_TRUNC		0001000	/* not fcntl */
+#define O_EXCL		0002000	/* not fcntl */
+#define O_NOCTTY	0004000	/* not fcntl */
+#define FASYNC		0010000	/* fcntl, for BSD compatibility */
+#define O_LARGEFILE	0020000	/* allow large file opens */
 /*
  * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using
  * the O_SYNC flag.  We continue to use the existing numerical value
@@ -33,9 +33,9 @@
  *
  * Note: __O_SYNC must never be used directly.
  */
-#define __O_SYNC	0x4000
+#define __O_SYNC	0040000
 #define O_SYNC		(__O_SYNC|O_DSYNC)
-#define O_DIRECT	0x8000	/* direct disk access hint */
+#define O_DIRECT	0100000	/* direct disk access hint */
 
 #define F_GETLK		14
 #define F_SETLK		6
-- 
2.53.0


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

* Re: [PATCH v4 0/4] OPENAT2_REGULAR flag support in openat2
  2026-02-21 14:45 [PATCH v4 0/4] OPENAT2_REGULAR flag support in openat2 Dorjoy Chowdhury
                   ` (3 preceding siblings ...)
  2026-02-21 14:45 ` [PATCH v4 4/4] mips/fcntl.h: " Dorjoy Chowdhury
@ 2026-02-21 15:49 ` Dorjoy Chowdhury
  2026-02-21 23:45   ` Askar Safin
  2026-03-01 10:16 ` Dorjoy Chowdhury
  5 siblings, 1 reply; 18+ messages in thread
From: Dorjoy Chowdhury @ 2026-02-21 15:49 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-kernel, ceph-devel, gfs2, linux-nfs, linux-cifs, v9fs,
	linux-kselftest, viro, brauner, jack, jlayton, chuck.lever,
	alex.aring, arnd, adilger, mjguzik, smfrench, richard.henderson,
	mattst88, linmag7, tsbogend, James.Bottomley, deller, davem,
	andreas, idryomov, amarkuze, slava, agruenba, trondmy, anna,
	sfrench, pc, ronniesahlberg, sprasad, tom, bharathsm, shuah,
	miklos, hansg

On Sat, Feb 21, 2026 at 8:59 PM Dorjoy Chowdhury <dorjoychy111@gmail.com> wrote:
>
> Hi,
>
> I came upon this "Ability to only open regular files" uapi feature suggestion
> from https://uapi-group.org/kernel-features/#ability-to-only-open-regular-files
> and thought it would be something I could do as a first patch and get to
> know the kernel code a bit better.
>
> I only tested this new flag on my local system (fedora btrfs).
>
> Note that I had submitted a v4 previously (that had -EINVAL for the atomic_open
> code paths) but did not do a get_maintainers.pl. It didn't get any review and
> please ignore that one anyway. In this version, I have tried to properly update
> the filesystems that provide atomic_open (fs/ceph, fs/nfs, fs/smb, fs/gfs2,
> fs/fuse, fs/vboxsf, fs/9p) for the new OPENAT2_REGULAR flag. Some of them
> (fs/fuse, fs/vboxsf, fs/9p) didn't need any changing. As far as I see, most of
> the filesystems do finish_no_open for ~O_CREAT and have file->f_mode |= FMODE_CREATED
> for the O_CREAT code path which I assume means they always create new file which
> is a regular file. OPENAT2_REGULAR | O_DIRECTORY returns -EINVAL (instead of working
> if path is either a directory or regular file) as it was easier to reason about when
> making changes in all the filesystems.
>
> Changes in v4:
> - changed O_REGULAR to OPENAT2_REGULAR
> - OPENAT2_REGULAR does not affect O_PATH
> - atomic_open codepaths updated to work properly for OPENAT2_REGULAR
> - commit message includes the uapi-group URL
> - v3 is at: https://lore.kernel.org/linux-fsdevel/20260127180109.66691-1-dorjoychy111@gmail.com/T/
>
> Changes in v3:
> - included motivation about O_REGULAR flag in commit message e.g., programs not wanting to be tricked into opening device nodes
> - fixed commit message wrongly referencing ENOTREGULAR instead of ENOTREG
> - fixed the O_REGULAR flag in arch/parisc/include/uapi/asm/fcntl.h from 060000000 to 0100000000
> - added 2 commits converting arch/{mips,sparc}/include/uapi/asm/fcntl.h O_* macros from hex to octal
> - v2 is at: https://lore.kernel.org/linux-fsdevel/20260126154156.55723-1-dorjoychy111@gmail.com/T/
>
> Changes in v2:
> - rename ENOTREGULAR to ENOTREG
> - define ENOTREG in uapi/asm-generic/errno.h (instead of errno-base.h) and in arch/*/include/uapi/asm/errno.h files
> - override O_REGULAR in arch/{alpha,sparc,parisc}/include/uapi/asm/fcntl.h due to clash with include/uapi/asm-generic/fcntl.h
> - I have kept the kselftest but now that O_REGULAR and ENOTREG can have different value on different architectures I am not sure if it's right
> - v1 is at: https://lore.kernel.org/linux-fsdevel/20260125141518.59493-1-dorjoychy111@gmail.com/T/
>
> Thanks.
>
> Regards,
> Dorjoy
>
> Dorjoy Chowdhury (4):
>   openat2: new OPENAT2_REGULAR flag support
>   kselftest/openat2: test for OPENAT2_REGULAR flag
>   sparc/fcntl.h: convert O_* flag macros from hex to octal
>   mips/fcntl.h: convert O_* flag macros from hex to octal
>
>  arch/alpha/include/uapi/asm/errno.h           |  2 +
>  arch/alpha/include/uapi/asm/fcntl.h           |  1 +
>  arch/mips/include/uapi/asm/errno.h            |  2 +
>  arch/mips/include/uapi/asm/fcntl.h            | 22 +++++------
>  arch/parisc/include/uapi/asm/errno.h          |  2 +
>  arch/parisc/include/uapi/asm/fcntl.h          |  1 +
>  arch/sparc/include/uapi/asm/errno.h           |  2 +
>  arch/sparc/include/uapi/asm/fcntl.h           | 35 +++++++++---------
>  fs/ceph/file.c                                |  4 ++
>  fs/gfs2/inode.c                               |  2 +
>  fs/namei.c                                    |  4 ++
>  fs/nfs/dir.c                                  |  4 +-
>  fs/open.c                                     |  4 +-
>  fs/smb/client/dir.c                           | 11 +++++-
>  include/linux/fcntl.h                         |  2 +
>  include/uapi/asm-generic/errno.h              |  2 +
>  include/uapi/asm-generic/fcntl.h              |  4 ++
>  tools/arch/alpha/include/uapi/asm/errno.h     |  2 +
>  tools/arch/mips/include/uapi/asm/errno.h      |  2 +
>  tools/arch/parisc/include/uapi/asm/errno.h    |  2 +
>  tools/arch/sparc/include/uapi/asm/errno.h     |  2 +
>  tools/include/uapi/asm-generic/errno.h        |  2 +
>  .../testing/selftests/openat2/openat2_test.c  | 37 ++++++++++++++++++-
>  23 files changed, 119 insertions(+), 32 deletions(-)
>
> --
> 2.53.0
>

I am not sure if my patch series made it properly to the mailing
lists. https://lore.kernel.org/linux-fsdevel/  is showing a broken
series, only the 2/4, 3/4, 4/4 and I don't see cover-letter or 1/4.
The patch series does have a big cc list (what I got from
get_maintainers.pl excluding commit-signers) and I used git send-email
to send to everyone. It's also showing properly in my gmail inbox. Is
it just the website that's not showing it properly? Should I prune the
cc list and resend? is there any limitations to sending patches to
mailing lists with many cc-s via gmail?

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

* Re: [PATCH v4 0/4] OPENAT2_REGULAR flag support in openat2
  2026-02-21 15:49 ` [PATCH v4 0/4] OPENAT2_REGULAR flag support in openat2 Dorjoy Chowdhury
@ 2026-02-21 23:45   ` Askar Safin
  2026-02-22  7:19     ` Dorjoy Chowdhury
  0 siblings, 1 reply; 18+ messages in thread
From: Askar Safin @ 2026-02-21 23:45 UTC (permalink / raw)
  To: dorjoychy111
  Cc: ceph-devel, gfs2, linux-cifs, linux-fsdevel, linux-kernel,
	linux-kselftest, linux-nfs, v9fs

Dorjoy Chowdhury <dorjoychy111@gmail.com>:
> I am not sure if my patch series made it properly to the mailing
> lists. https://lore.kernel.org/linux-fsdevel/  is showing a broken
> series, only the 2/4, 3/4, 4/4 and I don't see cover-letter or 1/4.
> The patch series does have a big cc list (what I got from
> get_maintainers.pl excluding commit-signers) and I used git send-email
> to send to everyone. It's also showing properly in my gmail inbox. Is
> it just the website that's not showing it properly? Should I prune the
> cc list and resend? is there any limitations to sending patches to
> mailing lists with many cc-s via gmail?

I see all 5 emails on
https://lore.kernel.org/linux-fsdevel/CAFfO_h7TJbB_170eoeobuanDKa2A+64o7-sb5Mpk3ts1oVUHtg@mail.gmail.com/T/#t .

So this was some temporary problem on lore.kernel.org .

Sometimes gmail indeed rejects mails if you try to send too many emails
to too many people. So I suggest adding "--batch-size=1 --relogin-delay=20"
to your send-email invocation. I hope this will make probability of
rejection by gmail less. I usually add these flags.

If you still expirence some problems with gmail, then you may apply
for linux.dev email (go to linux.dev). They are free for Linux contributors.

-- 
Askar Safin

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

* Re: [PATCH v4 0/4] OPENAT2_REGULAR flag support in openat2
  2026-02-21 23:45   ` Askar Safin
@ 2026-02-22  7:19     ` Dorjoy Chowdhury
  0 siblings, 0 replies; 18+ messages in thread
From: Dorjoy Chowdhury @ 2026-02-22  7:19 UTC (permalink / raw)
  To: Askar Safin
  Cc: ceph-devel, gfs2, linux-cifs, linux-fsdevel, linux-kernel,
	linux-kselftest, linux-nfs, v9fs

On Sun, Feb 22, 2026 at 5:46 AM Askar Safin <safinaskar@gmail.com> wrote:
>
> Dorjoy Chowdhury <dorjoychy111@gmail.com>:
> > I am not sure if my patch series made it properly to the mailing
> > lists. https://lore.kernel.org/linux-fsdevel/  is showing a broken
> > series, only the 2/4, 3/4, 4/4 and I don't see cover-letter or 1/4.
> > The patch series does have a big cc list (what I got from
> > get_maintainers.pl excluding commit-signers) and I used git send-email
> > to send to everyone. It's also showing properly in my gmail inbox. Is
> > it just the website that's not showing it properly? Should I prune the
> > cc list and resend? is there any limitations to sending patches to
> > mailing lists with many cc-s via gmail?
>
> I see all 5 emails on
> https://lore.kernel.org/linux-fsdevel/CAFfO_h7TJbB_170eoeobuanDKa2A+64o7-sb5Mpk3ts1oVUHtg@mail.gmail.com/T/#t .
>

Yes, indeed. They showed up after a while.

> So this was some temporary problem on lore.kernel.org .
>
> Sometimes gmail indeed rejects mails if you try to send too many emails
> to too many people. So I suggest adding "--batch-size=1 --relogin-delay=20"
> to your send-email invocation. I hope this will make probability of
> rejection by gmail less. I usually add these flags.
>

Understood. I did not know about these flags.

> If you still expirence some problems with gmail, then you may apply
> for linux.dev email (go to linux.dev). They are free for Linux contributors.
>

Alright.

Thank you!

Regards,
Dorjoy

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

* Re: [PATCH v4 0/4] OPENAT2_REGULAR flag support in openat2
  2026-02-21 14:45 [PATCH v4 0/4] OPENAT2_REGULAR flag support in openat2 Dorjoy Chowdhury
                   ` (4 preceding siblings ...)
  2026-02-21 15:49 ` [PATCH v4 0/4] OPENAT2_REGULAR flag support in openat2 Dorjoy Chowdhury
@ 2026-03-01 10:16 ` Dorjoy Chowdhury
  5 siblings, 0 replies; 18+ messages in thread
From: Dorjoy Chowdhury @ 2026-03-01 10:16 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-kernel, ceph-devel, gfs2, linux-nfs, linux-cifs, v9fs,
	linux-kselftest, viro, brauner, jack, jlayton, chuck.lever,
	alex.aring, arnd, adilger, mjguzik, smfrench, richard.henderson,
	mattst88, linmag7, tsbogend, James.Bottomley, deller, davem,
	andreas, idryomov, amarkuze, slava, agruenba, trondmy, anna,
	sfrench, pc, ronniesahlberg, sprasad, tom, bharathsm, shuah,
	miklos, hansg

Ping...
Requesting for review on this patch series please.

Regards,
Dorjoy

On Sat, Feb 21, 2026 at 8:59 PM Dorjoy Chowdhury <dorjoychy111@gmail.com> wrote:
>
> Hi,
>
> I came upon this "Ability to only open regular files" uapi feature suggestion
> from https://uapi-group.org/kernel-features/#ability-to-only-open-regular-files
> and thought it would be something I could do as a first patch and get to
> know the kernel code a bit better.
>
> I only tested this new flag on my local system (fedora btrfs).
>
> Note that I had submitted a v4 previously (that had -EINVAL for the atomic_open
> code paths) but did not do a get_maintainers.pl. It didn't get any review and
> please ignore that one anyway. In this version, I have tried to properly update
> the filesystems that provide atomic_open (fs/ceph, fs/nfs, fs/smb, fs/gfs2,
> fs/fuse, fs/vboxsf, fs/9p) for the new OPENAT2_REGULAR flag. Some of them
> (fs/fuse, fs/vboxsf, fs/9p) didn't need any changing. As far as I see, most of
> the filesystems do finish_no_open for ~O_CREAT and have file->f_mode |= FMODE_CREATED
> for the O_CREAT code path which I assume means they always create new file which
> is a regular file. OPENAT2_REGULAR | O_DIRECTORY returns -EINVAL (instead of working
> if path is either a directory or regular file) as it was easier to reason about when
> making changes in all the filesystems.
>
> Changes in v4:
> - changed O_REGULAR to OPENAT2_REGULAR
> - OPENAT2_REGULAR does not affect O_PATH
> - atomic_open codepaths updated to work properly for OPENAT2_REGULAR
> - commit message includes the uapi-group URL
> - v3 is at: https://lore.kernel.org/linux-fsdevel/20260127180109.66691-1-dorjoychy111@gmail.com/T/
>
> Changes in v3:
> - included motivation about O_REGULAR flag in commit message e.g., programs not wanting to be tricked into opening device nodes
> - fixed commit message wrongly referencing ENOTREGULAR instead of ENOTREG
> - fixed the O_REGULAR flag in arch/parisc/include/uapi/asm/fcntl.h from 060000000 to 0100000000
> - added 2 commits converting arch/{mips,sparc}/include/uapi/asm/fcntl.h O_* macros from hex to octal
> - v2 is at: https://lore.kernel.org/linux-fsdevel/20260126154156.55723-1-dorjoychy111@gmail.com/T/
>
> Changes in v2:
> - rename ENOTREGULAR to ENOTREG
> - define ENOTREG in uapi/asm-generic/errno.h (instead of errno-base.h) and in arch/*/include/uapi/asm/errno.h files
> - override O_REGULAR in arch/{alpha,sparc,parisc}/include/uapi/asm/fcntl.h due to clash with include/uapi/asm-generic/fcntl.h
> - I have kept the kselftest but now that O_REGULAR and ENOTREG can have different value on different architectures I am not sure if it's right
> - v1 is at: https://lore.kernel.org/linux-fsdevel/20260125141518.59493-1-dorjoychy111@gmail.com/T/
>
> Thanks.
>
> Regards,
> Dorjoy
>
> Dorjoy Chowdhury (4):
>   openat2: new OPENAT2_REGULAR flag support
>   kselftest/openat2: test for OPENAT2_REGULAR flag
>   sparc/fcntl.h: convert O_* flag macros from hex to octal
>   mips/fcntl.h: convert O_* flag macros from hex to octal
>
>  arch/alpha/include/uapi/asm/errno.h           |  2 +
>  arch/alpha/include/uapi/asm/fcntl.h           |  1 +
>  arch/mips/include/uapi/asm/errno.h            |  2 +
>  arch/mips/include/uapi/asm/fcntl.h            | 22 +++++------
>  arch/parisc/include/uapi/asm/errno.h          |  2 +
>  arch/parisc/include/uapi/asm/fcntl.h          |  1 +
>  arch/sparc/include/uapi/asm/errno.h           |  2 +
>  arch/sparc/include/uapi/asm/fcntl.h           | 35 +++++++++---------
>  fs/ceph/file.c                                |  4 ++
>  fs/gfs2/inode.c                               |  2 +
>  fs/namei.c                                    |  4 ++
>  fs/nfs/dir.c                                  |  4 +-
>  fs/open.c                                     |  4 +-
>  fs/smb/client/dir.c                           | 11 +++++-
>  include/linux/fcntl.h                         |  2 +
>  include/uapi/asm-generic/errno.h              |  2 +
>  include/uapi/asm-generic/fcntl.h              |  4 ++
>  tools/arch/alpha/include/uapi/asm/errno.h     |  2 +
>  tools/arch/mips/include/uapi/asm/errno.h      |  2 +
>  tools/arch/parisc/include/uapi/asm/errno.h    |  2 +
>  tools/arch/sparc/include/uapi/asm/errno.h     |  2 +
>  tools/include/uapi/asm-generic/errno.h        |  2 +
>  .../testing/selftests/openat2/openat2_test.c  | 37 ++++++++++++++++++-
>  23 files changed, 119 insertions(+), 32 deletions(-)
>
> --
> 2.53.0
>

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

* Re: [PATCH v4 1/4] openat2: new OPENAT2_REGULAR flag support
  2026-02-21 14:45 ` [PATCH v4 1/4] openat2: new OPENAT2_REGULAR flag support Dorjoy Chowdhury
@ 2026-03-01 12:44   ` Jeff Layton
  2026-03-01 14:16     ` Dorjoy Chowdhury
  0 siblings, 1 reply; 18+ messages in thread
From: Jeff Layton @ 2026-03-01 12:44 UTC (permalink / raw)
  To: Dorjoy Chowdhury, linux-fsdevel
  Cc: linux-kernel, ceph-devel, gfs2, linux-nfs, linux-cifs, v9fs,
	linux-kselftest, viro, brauner, jack, chuck.lever, alex.aring,
	arnd, adilger, mjguzik, smfrench, richard.henderson, mattst88,
	linmag7, tsbogend, James.Bottomley, deller, davem, andreas,
	idryomov, amarkuze, slava, agruenba, trondmy, anna, sfrench, pc,
	ronniesahlberg, sprasad, tom, bharathsm, shuah, miklos, hansg

On Sat, 2026-02-21 at 20:45 +0600, Dorjoy Chowdhury wrote:
> This flag indicates the path should be opened if it's a regular file.
> This is useful to write secure programs that want to avoid being
> tricked into opening device nodes with special semantics while thinking
> they operate on regular files. This is a requested feature from the
> uapi-group[1].
> 
> A corresponding error code EFTYPE has been introduced. For example, if
> openat2 is called on path /dev/null with OPENAT2_REGULAR in the flag
> param, it will return -EFTYPE.
> 
> When used in combination with O_CREAT, either the regular file is
> created, or if the path already exists, it is opened if it's a regular
> file. Otherwise, -EFTYPE is returned.
> 

It would be good to mention that EFTYPE has precedent in BSD/Darwin.
When an error code is already supported in another UNIX-y OS, then it
bolsters the case for adding it here.

Your cover letter mentions that you only tested this on btrfs. At the
very least, you should test NFS and SMB. It should be fairly easy to
set up mounts over loopback for those cases.

There are some places where it doesn't seem like -EFTYPE will be
returned. It looks like it can send back -EISDIR and -ENOTDIR in some
cases as well. With a new API like this, I think we ought to strive for
consistency.

Should this API return -EFTYPE for all cases where it's not S_IFREG? If
not, then what other errors are allowed? Bear in mind that you'll need
to document this in the manpages too.

> When OPENAT2_REGULAR is combined with O_DIRECTORY, -EINVAL is returned
> as it doesn't make sense to open a path that is both a directory and a
> regular file.
> 
> [1]: https://uapi-group.org/kernel-features/#ability-to-only-open-regular-files
> 
> Signed-off-by: Dorjoy Chowdhury <dorjoychy111@gmail.com>
> ---
>  arch/alpha/include/uapi/asm/errno.h        |  2 ++
>  arch/alpha/include/uapi/asm/fcntl.h        |  1 +
>  arch/mips/include/uapi/asm/errno.h         |  2 ++
>  arch/parisc/include/uapi/asm/errno.h       |  2 ++
>  arch/parisc/include/uapi/asm/fcntl.h       |  1 +
>  arch/sparc/include/uapi/asm/errno.h        |  2 ++
>  arch/sparc/include/uapi/asm/fcntl.h        |  1 +
>  fs/ceph/file.c                             |  4 ++++
>  fs/gfs2/inode.c                            |  2 ++
>  fs/namei.c                                 |  4 ++++
>  fs/nfs/dir.c                               |  4 +++-
>  fs/open.c                                  |  4 +++-
>  fs/smb/client/dir.c                        | 11 ++++++++++-
>  include/linux/fcntl.h                      |  2 ++
>  include/uapi/asm-generic/errno.h           |  2 ++
>  include/uapi/asm-generic/fcntl.h           |  4 ++++
>  tools/arch/alpha/include/uapi/asm/errno.h  |  2 ++
>  tools/arch/mips/include/uapi/asm/errno.h   |  2 ++
>  tools/arch/parisc/include/uapi/asm/errno.h |  2 ++
>  tools/arch/sparc/include/uapi/asm/errno.h  |  2 ++
>  tools/include/uapi/asm-generic/errno.h     |  2 ++
>  21 files changed, 55 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/alpha/include/uapi/asm/errno.h b/arch/alpha/include/uapi/asm/errno.h
> index 6791f6508632..1a99f38813c7 100644
> --- a/arch/alpha/include/uapi/asm/errno.h
> +++ b/arch/alpha/include/uapi/asm/errno.h
> @@ -127,4 +127,6 @@
>  
>  #define EHWPOISON	139	/* Memory page has hardware error */
>  
> +#define EFTYPE		140	/* Wrong file type for the intended operation */
> +
>  #endif
> diff --git a/arch/alpha/include/uapi/asm/fcntl.h b/arch/alpha/include/uapi/asm/fcntl.h
> index 50bdc8e8a271..fe488bf7c18e 100644
> --- a/arch/alpha/include/uapi/asm/fcntl.h
> +++ b/arch/alpha/include/uapi/asm/fcntl.h
> @@ -34,6 +34,7 @@
>  
>  #define O_PATH		040000000
>  #define __O_TMPFILE	0100000000
> +#define OPENAT2_REGULAR	0200000000
>  
>  #define F_GETLK		7
>  #define F_SETLK		8
> diff --git a/arch/mips/include/uapi/asm/errno.h b/arch/mips/include/uapi/asm/errno.h
> index c01ed91b1ef4..1835a50b69ce 100644
> --- a/arch/mips/include/uapi/asm/errno.h
> +++ b/arch/mips/include/uapi/asm/errno.h
> @@ -126,6 +126,8 @@
>  
>  #define EHWPOISON	168	/* Memory page has hardware error */
>  
> +#define EFTYPE		169	/* Wrong file type for the intended operation */
> +
>  #define EDQUOT		1133	/* Quota exceeded */
>  
>  
> diff --git a/arch/parisc/include/uapi/asm/errno.h b/arch/parisc/include/uapi/asm/errno.h
> index 8cbc07c1903e..93194fbb0a80 100644
> --- a/arch/parisc/include/uapi/asm/errno.h
> +++ b/arch/parisc/include/uapi/asm/errno.h
> @@ -124,4 +124,6 @@
>  
>  #define EHWPOISON	257	/* Memory page has hardware error */
>  
> +#define EFTYPE		258	/* Wrong file type for the intended operation */
> +
>  #endif
> diff --git a/arch/parisc/include/uapi/asm/fcntl.h b/arch/parisc/include/uapi/asm/fcntl.h
> index 03dee816cb13..d46812f2f0f4 100644
> --- a/arch/parisc/include/uapi/asm/fcntl.h
> +++ b/arch/parisc/include/uapi/asm/fcntl.h
> @@ -19,6 +19,7 @@
>  
>  #define O_PATH		020000000
>  #define __O_TMPFILE	040000000
> +#define OPENAT2_REGULAR	0100000000
>  
>  #define F_GETLK64	8
>  #define F_SETLK64	9
> diff --git a/arch/sparc/include/uapi/asm/errno.h b/arch/sparc/include/uapi/asm/errno.h
> index 4a41e7835fd5..71940ec9130b 100644
> --- a/arch/sparc/include/uapi/asm/errno.h
> +++ b/arch/sparc/include/uapi/asm/errno.h
> @@ -117,4 +117,6 @@
>  
>  #define EHWPOISON	135	/* Memory page has hardware error */
>  
> +#define EFTYPE		136	/* Wrong file type for the intended operation */
> +
>  #endif
> diff --git a/arch/sparc/include/uapi/asm/fcntl.h b/arch/sparc/include/uapi/asm/fcntl.h
> index 67dae75e5274..bb6e9fa94bc9 100644
> --- a/arch/sparc/include/uapi/asm/fcntl.h
> +++ b/arch/sparc/include/uapi/asm/fcntl.h
> @@ -37,6 +37,7 @@
>  
>  #define O_PATH		0x1000000
>  #define __O_TMPFILE	0x2000000
> +#define OPENAT2_REGULAR	0x4000000
>  
>  #define F_GETOWN	5	/*  for sockets. */
>  #define F_SETOWN	6	/*  for sockets. */
> diff --git a/fs/ceph/file.c b/fs/ceph/file.c
> index 31b691b2aea2..0a4220f72ada 100644
> --- a/fs/ceph/file.c
> +++ b/fs/ceph/file.c
> @@ -977,6 +977,10 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
>  			ceph_init_inode_acls(newino, &as_ctx);
>  			file->f_mode |= FMODE_CREATED;
>  		}
> +		if ((flags & OPENAT2_REGULAR) && !d_is_reg(dentry)) {
> +			err = -EFTYPE;
> +			goto out_req;
> +		}
>  		err = finish_open(file, dentry, ceph_open);
>  	}
>  out_req:
> diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
> index 8344040ecaf7..0dc3e4240d9e 100644
> --- a/fs/gfs2/inode.c
> +++ b/fs/gfs2/inode.c
> @@ -749,6 +749,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
>  		if (file) {
>  			if (S_ISREG(inode->i_mode))
>  				error = finish_open(file, dentry, gfs2_open_common);
> +			else if (file->f_flags & OPENAT2_REGULAR)
> +				error = -EFTYPE;
>  			else
>  				error = finish_no_open(file, NULL);
>  		}
> diff --git a/fs/namei.c b/fs/namei.c
> index 5fe6cac48df8..aa5fb2672881 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -4651,6 +4651,10 @@ static int do_open(struct nameidata *nd,
>  		if (unlikely(error))
>  			return error;
>  	}
> +
> +	if ((open_flag & OPENAT2_REGULAR) && !d_is_reg(nd->path.dentry))
> +		return -EFTYPE;
> +
>  	if ((nd->flags & LOOKUP_DIRECTORY) && !d_can_lookup(nd->path.dentry))
>  		return -ENOTDIR;
>  
> diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
> index b3f5c9461204..ef61db67d06e 100644
> --- a/fs/nfs/dir.c
> +++ b/fs/nfs/dir.c
> @@ -2195,7 +2195,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
>  			break;
>  		case -EISDIR:
>  		case -ENOTDIR:
> -			goto no_open;
> +			if (!(open_flags & OPENAT2_REGULAR))
> +				goto no_open;
> +			break;

Shouldn't this also set the error to -EFTYPE?

>  		case -ELOOP:
>  			if (!(open_flags & O_NOFOLLOW))
>  				goto no_open;
> diff --git a/fs/open.c b/fs/open.c
> index 91f1139591ab..1524f52a1773 100644
> --- a/fs/open.c
> +++ b/fs/open.c
> @@ -1198,7 +1198,7 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
>  	 * values before calling build_open_flags(), but openat2(2) checks all
>  	 * of its arguments.
>  	 */
> -	if (flags & ~VALID_OPEN_FLAGS)
> +	if (flags & ~VALID_OPENAT2_FLAGS)
>  		return -EINVAL;
>  	if (how->resolve & ~VALID_RESOLVE_FLAGS)
>  		return -EINVAL;
> @@ -1237,6 +1237,8 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
>  			return -EINVAL;
>  		if (!(acc_mode & MAY_WRITE))
>  			return -EINVAL;
> +	} else if ((flags & O_DIRECTORY) && (flags & OPENAT2_REGULAR)) {
> +		return -EINVAL;
>  	}
>  	if (flags & O_PATH) {
>  		/* O_PATH only permits certain other flags to be set. */
> diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c
> index cb10088197d2..d12ed0c87599 100644
> --- a/fs/smb/client/dir.c
> +++ b/fs/smb/client/dir.c
> @@ -236,6 +236,11 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
>  				 * lookup.
>  				 */
>  				CIFSSMBClose(xid, tcon, fid->netfid);
> +				if (oflags & OPENAT2_REGULAR) {
> +					iput(newinode);
> +					rc = -EFTYPE;
> +					goto out;
> +				}
>  				goto cifs_create_get_file_info;
>  			}
>  			/* success, no need to query */
> @@ -433,11 +438,15 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
>  		goto out_err;
>  	}
>  
> -	if (newinode)
> +	if (newinode) {
>  		if (S_ISDIR(newinode->i_mode)) {
>  			rc = -EISDIR;
>  			goto out_err;

This logic doesn't look quite right. If you do a create and race with a
directory create, then it looks like you'll send back -EISDIR here
instead of -EFTYPE?

> +		} else if ((oflags & OPENAT2_REGULAR) && !S_ISREG(newinode->i_mode)) {
> +			rc = -EFTYPE;
> +			goto out_err;
>  		}
> +	}
>  
>  	d_drop(direntry);
>  	d_add(direntry, newinode);
> diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
> index a332e79b3207..a80026718217 100644
> --- a/include/linux/fcntl.h
> +++ b/include/linux/fcntl.h
> @@ -12,6 +12,8 @@
>  	 FASYNC	| O_DIRECT | O_LARGEFILE | O_DIRECTORY | O_NOFOLLOW | \
>  	 O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE)
>  
> +#define VALID_OPENAT2_FLAGS (VALID_OPEN_FLAGS | OPENAT2_REGULAR)
> +
>  /* List of all valid flags for the how->resolve argument: */
>  #define VALID_RESOLVE_FLAGS \
>  	(RESOLVE_NO_XDEV | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS | \
> diff --git a/include/uapi/asm-generic/errno.h b/include/uapi/asm-generic/errno.h
> index 92e7ae493ee3..bd78e69e0a43 100644
> --- a/include/uapi/asm-generic/errno.h
> +++ b/include/uapi/asm-generic/errno.h
> @@ -122,4 +122,6 @@
>  
>  #define EHWPOISON	133	/* Memory page has hardware error */
>  
> +#define EFTYPE		134	/* Wrong file type for the intended operation */
> +
>  #endif
> diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
> index 613475285643..b2c2ddd0edc0 100644
> --- a/include/uapi/asm-generic/fcntl.h
> +++ b/include/uapi/asm-generic/fcntl.h
> @@ -88,6 +88,10 @@
>  #define __O_TMPFILE	020000000
>  #endif
>  
> +#ifndef OPENAT2_REGULAR
> +#define OPENAT2_REGULAR	040000000
> +#endif
> +
>  /* a horrid kludge trying to make sure that this will fail on old kernels */
>  #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
>  
> diff --git a/tools/arch/alpha/include/uapi/asm/errno.h b/tools/arch/alpha/include/uapi/asm/errno.h
> index 6791f6508632..1a99f38813c7 100644
> --- a/tools/arch/alpha/include/uapi/asm/errno.h
> +++ b/tools/arch/alpha/include/uapi/asm/errno.h
> @@ -127,4 +127,6 @@
>  
>  #define EHWPOISON	139	/* Memory page has hardware error */
>  
> +#define EFTYPE		140	/* Wrong file type for the intended operation */
> +
>  #endif
> diff --git a/tools/arch/mips/include/uapi/asm/errno.h b/tools/arch/mips/include/uapi/asm/errno.h
> index c01ed91b1ef4..1835a50b69ce 100644
> --- a/tools/arch/mips/include/uapi/asm/errno.h
> +++ b/tools/arch/mips/include/uapi/asm/errno.h
> @@ -126,6 +126,8 @@
>  
>  #define EHWPOISON	168	/* Memory page has hardware error */
>  
> +#define EFTYPE		169	/* Wrong file type for the intended operation */
> +
>  #define EDQUOT		1133	/* Quota exceeded */
>  
>  
> diff --git a/tools/arch/parisc/include/uapi/asm/errno.h b/tools/arch/parisc/include/uapi/asm/errno.h
> index 8cbc07c1903e..93194fbb0a80 100644
> --- a/tools/arch/parisc/include/uapi/asm/errno.h
> +++ b/tools/arch/parisc/include/uapi/asm/errno.h
> @@ -124,4 +124,6 @@
>  
>  #define EHWPOISON	257	/* Memory page has hardware error */
>  
> +#define EFTYPE		258	/* Wrong file type for the intended operation */
> +
>  #endif
> diff --git a/tools/arch/sparc/include/uapi/asm/errno.h b/tools/arch/sparc/include/uapi/asm/errno.h
> index 4a41e7835fd5..71940ec9130b 100644
> --- a/tools/arch/sparc/include/uapi/asm/errno.h
> +++ b/tools/arch/sparc/include/uapi/asm/errno.h
> @@ -117,4 +117,6 @@
>  
>  #define EHWPOISON	135	/* Memory page has hardware error */
>  
> +#define EFTYPE		136	/* Wrong file type for the intended operation */
> +
>  #endif
> diff --git a/tools/include/uapi/asm-generic/errno.h b/tools/include/uapi/asm-generic/errno.h
> index 92e7ae493ee3..bd78e69e0a43 100644
> --- a/tools/include/uapi/asm-generic/errno.h
> +++ b/tools/include/uapi/asm-generic/errno.h
> @@ -122,4 +122,6 @@
>  
>  #define EHWPOISON	133	/* Memory page has hardware error */
>  
> +#define EFTYPE		134	/* Wrong file type for the intended operation */
> +
>  #endif

-- 
Jeff Layton <jlayton@kernel.org>

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

* Re: [PATCH v4 1/4] openat2: new OPENAT2_REGULAR flag support
  2026-03-01 12:44   ` Jeff Layton
@ 2026-03-01 14:16     ` Dorjoy Chowdhury
  2026-03-01 14:47       ` Jeff Layton
  0 siblings, 1 reply; 18+ messages in thread
From: Dorjoy Chowdhury @ 2026-03-01 14:16 UTC (permalink / raw)
  To: Jeff Layton
  Cc: linux-fsdevel, linux-kernel, ceph-devel, gfs2, linux-nfs,
	linux-cifs, v9fs, linux-kselftest, viro, brauner, jack,
	chuck.lever, alex.aring, arnd, adilger, mjguzik, smfrench,
	richard.henderson, mattst88, linmag7, tsbogend, James.Bottomley,
	deller, davem, andreas, idryomov, amarkuze, slava, agruenba,
	trondmy, anna, sfrench, pc, ronniesahlberg, sprasad, tom,
	bharathsm, shuah, miklos, hansg

On Sun, Mar 1, 2026 at 6:44 PM Jeff Layton <jlayton@kernel.org> wrote:
>
> On Sat, 2026-02-21 at 20:45 +0600, Dorjoy Chowdhury wrote:
> > This flag indicates the path should be opened if it's a regular file.
> > This is useful to write secure programs that want to avoid being
> > tricked into opening device nodes with special semantics while thinking
> > they operate on regular files. This is a requested feature from the
> > uapi-group[1].
> >
> > A corresponding error code EFTYPE has been introduced. For example, if
> > openat2 is called on path /dev/null with OPENAT2_REGULAR in the flag
> > param, it will return -EFTYPE.
> >
> > When used in combination with O_CREAT, either the regular file is
> > created, or if the path already exists, it is opened if it's a regular
> > file. Otherwise, -EFTYPE is returned.
> >
>
> It would be good to mention that EFTYPE has precedent in BSD/Darwin.
> When an error code is already supported in another UNIX-y OS, then it
> bolsters the case for adding it here.
>

Good suggestion. Yes, I can include this information in the commit
message during the next posting.

> Your cover letter mentions that you only tested this on btrfs. At the
> very least, you should test NFS and SMB. It should be fairly easy to
> set up mounts over loopback for those cases.
>

I used virtme-ng (which I think reuses the host's filesystem) to run
the compiled bzImage and ran the openat2 kselftests there to verify
it's working. Is there a similar way I can test NFS/SMB by adding
kselftests? Or would I need to setup NFS/SMB inside a full VM distro
with a modified kernel to test this? I would appreciate any suggestion
on this.

> There are some places where it doesn't seem like -EFTYPE will be
> returned. It looks like it can send back -EISDIR and -ENOTDIR in some
> cases as well. With a new API like this, I think we ought to strive for
> consistency.
>

Good point. There was a comment in a previous posting of this patch
series "The most useful behavior would indicate what was found (e.g.,
a pipe)."
(ref: https://lore.kernel.org/linux-fsdevel/vhq3osjqs3nn764wrp2lxp66b4dxpb3n5x3dijhe2yr53qfgy3@tfswbjskc3y6/
)
So I thought maybe it would be useful to return -EISDIR where it was
already doing that. But it is a good point about consistency that we
won't be doing this for other different types so I guess it's better
to return -EFTYPE for all the cases anyway as you mention. Any
thoughts?


> Should this API return -EFTYPE for all cases where it's not S_IFREG? If
> not, then what other errors are allowed? Bear in mind that you'll need
> to document this in the manpages too.
>

Are the manpages in the kernel git repository or in a separate
repository? Do I make separate patch series for that? Sorry I don't
know about this in detail.

> > When OPENAT2_REGULAR is combined with O_DIRECTORY, -EINVAL is returned
> > as it doesn't make sense to open a path that is both a directory and a
> > regular file.
> >
> > [1]: https://uapi-group.org/kernel-features/#ability-to-only-open-regular-files
> >
> > Signed-off-by: Dorjoy Chowdhury <dorjoychy111@gmail.com>
> > ---
> >  arch/alpha/include/uapi/asm/errno.h        |  2 ++
> >  arch/alpha/include/uapi/asm/fcntl.h        |  1 +
> >  arch/mips/include/uapi/asm/errno.h         |  2 ++
> >  arch/parisc/include/uapi/asm/errno.h       |  2 ++
> >  arch/parisc/include/uapi/asm/fcntl.h       |  1 +
> >  arch/sparc/include/uapi/asm/errno.h        |  2 ++
> >  arch/sparc/include/uapi/asm/fcntl.h        |  1 +
> >  fs/ceph/file.c                             |  4 ++++
> >  fs/gfs2/inode.c                            |  2 ++
> >  fs/namei.c                                 |  4 ++++
> >  fs/nfs/dir.c                               |  4 +++-
> >  fs/open.c                                  |  4 +++-
> >  fs/smb/client/dir.c                        | 11 ++++++++++-
> >  include/linux/fcntl.h                      |  2 ++
> >  include/uapi/asm-generic/errno.h           |  2 ++
> >  include/uapi/asm-generic/fcntl.h           |  4 ++++
> >  tools/arch/alpha/include/uapi/asm/errno.h  |  2 ++
> >  tools/arch/mips/include/uapi/asm/errno.h   |  2 ++
> >  tools/arch/parisc/include/uapi/asm/errno.h |  2 ++
> >  tools/arch/sparc/include/uapi/asm/errno.h  |  2 ++
> >  tools/include/uapi/asm-generic/errno.h     |  2 ++
> >  21 files changed, 55 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/alpha/include/uapi/asm/errno.h b/arch/alpha/include/uapi/asm/errno.h
> > index 6791f6508632..1a99f38813c7 100644
> > --- a/arch/alpha/include/uapi/asm/errno.h
> > +++ b/arch/alpha/include/uapi/asm/errno.h
> > @@ -127,4 +127,6 @@
> >
> >  #define EHWPOISON    139     /* Memory page has hardware error */
> >
> > +#define EFTYPE               140     /* Wrong file type for the intended operation */
> > +
> >  #endif
> > diff --git a/arch/alpha/include/uapi/asm/fcntl.h b/arch/alpha/include/uapi/asm/fcntl.h
> > index 50bdc8e8a271..fe488bf7c18e 100644
> > --- a/arch/alpha/include/uapi/asm/fcntl.h
> > +++ b/arch/alpha/include/uapi/asm/fcntl.h
> > @@ -34,6 +34,7 @@
> >
> >  #define O_PATH               040000000
> >  #define __O_TMPFILE  0100000000
> > +#define OPENAT2_REGULAR      0200000000
> >
> >  #define F_GETLK              7
> >  #define F_SETLK              8
> > diff --git a/arch/mips/include/uapi/asm/errno.h b/arch/mips/include/uapi/asm/errno.h
> > index c01ed91b1ef4..1835a50b69ce 100644
> > --- a/arch/mips/include/uapi/asm/errno.h
> > +++ b/arch/mips/include/uapi/asm/errno.h
> > @@ -126,6 +126,8 @@
> >
> >  #define EHWPOISON    168     /* Memory page has hardware error */
> >
> > +#define EFTYPE               169     /* Wrong file type for the intended operation */
> > +
> >  #define EDQUOT               1133    /* Quota exceeded */
> >
> >
> > diff --git a/arch/parisc/include/uapi/asm/errno.h b/arch/parisc/include/uapi/asm/errno.h
> > index 8cbc07c1903e..93194fbb0a80 100644
> > --- a/arch/parisc/include/uapi/asm/errno.h
> > +++ b/arch/parisc/include/uapi/asm/errno.h
> > @@ -124,4 +124,6 @@
> >
> >  #define EHWPOISON    257     /* Memory page has hardware error */
> >
> > +#define EFTYPE               258     /* Wrong file type for the intended operation */
> > +
> >  #endif
> > diff --git a/arch/parisc/include/uapi/asm/fcntl.h b/arch/parisc/include/uapi/asm/fcntl.h
> > index 03dee816cb13..d46812f2f0f4 100644
> > --- a/arch/parisc/include/uapi/asm/fcntl.h
> > +++ b/arch/parisc/include/uapi/asm/fcntl.h
> > @@ -19,6 +19,7 @@
> >
> >  #define O_PATH               020000000
> >  #define __O_TMPFILE  040000000
> > +#define OPENAT2_REGULAR      0100000000
> >
> >  #define F_GETLK64    8
> >  #define F_SETLK64    9
> > diff --git a/arch/sparc/include/uapi/asm/errno.h b/arch/sparc/include/uapi/asm/errno.h
> > index 4a41e7835fd5..71940ec9130b 100644
> > --- a/arch/sparc/include/uapi/asm/errno.h
> > +++ b/arch/sparc/include/uapi/asm/errno.h
> > @@ -117,4 +117,6 @@
> >
> >  #define EHWPOISON    135     /* Memory page has hardware error */
> >
> > +#define EFTYPE               136     /* Wrong file type for the intended operation */
> > +
> >  #endif
> > diff --git a/arch/sparc/include/uapi/asm/fcntl.h b/arch/sparc/include/uapi/asm/fcntl.h
> > index 67dae75e5274..bb6e9fa94bc9 100644
> > --- a/arch/sparc/include/uapi/asm/fcntl.h
> > +++ b/arch/sparc/include/uapi/asm/fcntl.h
> > @@ -37,6 +37,7 @@
> >
> >  #define O_PATH               0x1000000
> >  #define __O_TMPFILE  0x2000000
> > +#define OPENAT2_REGULAR      0x4000000
> >
> >  #define F_GETOWN     5       /*  for sockets. */
> >  #define F_SETOWN     6       /*  for sockets. */
> > diff --git a/fs/ceph/file.c b/fs/ceph/file.c
> > index 31b691b2aea2..0a4220f72ada 100644
> > --- a/fs/ceph/file.c
> > +++ b/fs/ceph/file.c
> > @@ -977,6 +977,10 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
> >                       ceph_init_inode_acls(newino, &as_ctx);
> >                       file->f_mode |= FMODE_CREATED;
> >               }
> > +             if ((flags & OPENAT2_REGULAR) && !d_is_reg(dentry)) {
> > +                     err = -EFTYPE;
> > +                     goto out_req;
> > +             }
> >               err = finish_open(file, dentry, ceph_open);
> >       }
> >  out_req:
> > diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
> > index 8344040ecaf7..0dc3e4240d9e 100644
> > --- a/fs/gfs2/inode.c
> > +++ b/fs/gfs2/inode.c
> > @@ -749,6 +749,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
> >               if (file) {
> >                       if (S_ISREG(inode->i_mode))
> >                               error = finish_open(file, dentry, gfs2_open_common);
> > +                     else if (file->f_flags & OPENAT2_REGULAR)
> > +                             error = -EFTYPE;
> >                       else
> >                               error = finish_no_open(file, NULL);
> >               }
> > diff --git a/fs/namei.c b/fs/namei.c
> > index 5fe6cac48df8..aa5fb2672881 100644
> > --- a/fs/namei.c
> > +++ b/fs/namei.c
> > @@ -4651,6 +4651,10 @@ static int do_open(struct nameidata *nd,
> >               if (unlikely(error))
> >                       return error;
> >       }
> > +
> > +     if ((open_flag & OPENAT2_REGULAR) && !d_is_reg(nd->path.dentry))
> > +             return -EFTYPE;
> > +
> >       if ((nd->flags & LOOKUP_DIRECTORY) && !d_can_lookup(nd->path.dentry))
> >               return -ENOTDIR;
> >
> > diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
> > index b3f5c9461204..ef61db67d06e 100644
> > --- a/fs/nfs/dir.c
> > +++ b/fs/nfs/dir.c
> > @@ -2195,7 +2195,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
> >                       break;
> >               case -EISDIR:
> >               case -ENOTDIR:
> > -                     goto no_open;
> > +                     if (!(open_flags & OPENAT2_REGULAR))
> > +                             goto no_open;
> > +                     break;
>
> Shouldn't this also set the error to -EFTYPE?
>
> >               case -ELOOP:
> >                       if (!(open_flags & O_NOFOLLOW))
> >                               goto no_open;
> > diff --git a/fs/open.c b/fs/open.c
> > index 91f1139591ab..1524f52a1773 100644
> > --- a/fs/open.c
> > +++ b/fs/open.c
> > @@ -1198,7 +1198,7 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
> >        * values before calling build_open_flags(), but openat2(2) checks all
> >        * of its arguments.
> >        */
> > -     if (flags & ~VALID_OPEN_FLAGS)
> > +     if (flags & ~VALID_OPENAT2_FLAGS)
> >               return -EINVAL;
> >       if (how->resolve & ~VALID_RESOLVE_FLAGS)
> >               return -EINVAL;
> > @@ -1237,6 +1237,8 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
> >                       return -EINVAL;
> >               if (!(acc_mode & MAY_WRITE))
> >                       return -EINVAL;
> > +     } else if ((flags & O_DIRECTORY) && (flags & OPENAT2_REGULAR)) {
> > +             return -EINVAL;
> >       }
> >       if (flags & O_PATH) {
> >               /* O_PATH only permits certain other flags to be set. */
> > diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c
> > index cb10088197d2..d12ed0c87599 100644
> > --- a/fs/smb/client/dir.c
> > +++ b/fs/smb/client/dir.c
> > @@ -236,6 +236,11 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
> >                                * lookup.
> >                                */
> >                               CIFSSMBClose(xid, tcon, fid->netfid);
> > +                             if (oflags & OPENAT2_REGULAR) {
> > +                                     iput(newinode);
> > +                                     rc = -EFTYPE;
> > +                                     goto out;
> > +                             }
> >                               goto cifs_create_get_file_info;
> >                       }
> >                       /* success, no need to query */
> > @@ -433,11 +438,15 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
> >               goto out_err;
> >       }
> >
> > -     if (newinode)
> > +     if (newinode) {
> >               if (S_ISDIR(newinode->i_mode)) {
> >                       rc = -EISDIR;
> >                       goto out_err;
>
> This logic doesn't look quite right. If you do a create and race with a
> directory create, then it looks like you'll send back -EISDIR here
> instead of -EFTYPE?
>

Yes, I thought it would be useful for the caller to know what type of
file it actually is so I had kept this the same. Let me know if it is
preferable to return -EFTYPE always.

Thanks for reviewing!

Regards,
Dorjoy

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

* Re: [PATCH v4 1/4] openat2: new OPENAT2_REGULAR flag support
  2026-03-01 14:16     ` Dorjoy Chowdhury
@ 2026-03-01 14:47       ` Jeff Layton
  2026-03-01 15:01         ` Dorjoy Chowdhury
  0 siblings, 1 reply; 18+ messages in thread
From: Jeff Layton @ 2026-03-01 14:47 UTC (permalink / raw)
  To: Dorjoy Chowdhury
  Cc: linux-fsdevel, linux-kernel, ceph-devel, gfs2, linux-nfs,
	linux-cifs, v9fs, linux-kselftest, viro, brauner, jack,
	chuck.lever, alex.aring, arnd, adilger, mjguzik, smfrench,
	richard.henderson, mattst88, linmag7, tsbogend, James.Bottomley,
	deller, davem, andreas, idryomov, amarkuze, slava, agruenba,
	trondmy, anna, sfrench, pc, ronniesahlberg, sprasad, tom,
	bharathsm, shuah, miklos, hansg

On Sun, 2026-03-01 at 20:16 +0600, Dorjoy Chowdhury wrote:
> On Sun, Mar 1, 2026 at 6:44 PM Jeff Layton <jlayton@kernel.org> wrote:
> > 
> > On Sat, 2026-02-21 at 20:45 +0600, Dorjoy Chowdhury wrote:
> > > This flag indicates the path should be opened if it's a regular file.
> > > This is useful to write secure programs that want to avoid being
> > > tricked into opening device nodes with special semantics while thinking
> > > they operate on regular files. This is a requested feature from the
> > > uapi-group[1].
> > > 
> > > A corresponding error code EFTYPE has been introduced. For example, if
> > > openat2 is called on path /dev/null with OPENAT2_REGULAR in the flag
> > > param, it will return -EFTYPE.
> > > 
> > > When used in combination with O_CREAT, either the regular file is
> > > created, or if the path already exists, it is opened if it's a regular
> > > file. Otherwise, -EFTYPE is returned.
> > > 
> > 
> > It would be good to mention that EFTYPE has precedent in BSD/Darwin.
> > When an error code is already supported in another UNIX-y OS, then it
> > bolsters the case for adding it here.
> > 
> 
> Good suggestion. Yes, I can include this information in the commit
> message during the next posting.
> 
> > Your cover letter mentions that you only tested this on btrfs. At the
> > very least, you should test NFS and SMB. It should be fairly easy to
> > set up mounts over loopback for those cases.
> > 
> 
> I used virtme-ng (which I think reuses the host's filesystem) to run
> the compiled bzImage and ran the openat2 kselftests there to verify
> it's working. Is there a similar way I can test NFS/SMB by adding
> kselftests? Or would I need to setup NFS/SMB inside a full VM distro
> with a modified kernel to test this? I would appreciate any suggestion
> on this.
> 

I imagine virtme would need some configuration to set up for nfs or
cifs, but maybe it's possible. I mostly use kdevops for this sort of
testing.

> > There are some places where it doesn't seem like -EFTYPE will be
> > returned. It looks like it can send back -EISDIR and -ENOTDIR in some
> > cases as well. With a new API like this, I think we ought to strive for
> > consistency.
> > 
> 
> Good point. There was a comment in a previous posting of this patch
> series "The most useful behavior would indicate what was found (e.g.,
> a pipe)."
> (ref: https://lore.kernel.org/linux-fsdevel/vhq3osjqs3nn764wrp2lxp66b4dxpb3n5x3dijhe2yr53qfgy3@tfswbjskc3y6/
> )
> So I thought maybe it would be useful to return -EISDIR where it was
> already doing that. But it is a good point about consistency that we
> won't be doing this for other different types so I guess it's better
> to return -EFTYPE for all the cases anyway as you mention. Any
> thoughts?
> 

There is a case to be made for either. The big question is whether you
can consistently return the same error codes in the same situations.

For instance, you can return -EISDIR on NFS when the target is a
directory, but can you do the same on btrfs or ceph? If not, then we
have a situation where we have to deal with the possibility of two
different error codes.

In general, I think returning EFTYPE for everything is simplest and
therefore best. Sure, EISDIR tells you a bit more about the target, but
that info is probably not that helpful if you were expecting it to be a
regular file.

> 
> > Should this API return -EFTYPE for all cases where it's not S_IFREG? If
> > not, then what other errors are allowed? Bear in mind that you'll need
> > to document this in the manpages too.
> > 
> 
> Are the manpages in the kernel git repository or in a separate
> repository? Do I make separate patch series for that? Sorry I don't
> know about this in detail.
> 

Separate repo and mailing list: https://www.kernel.org/doc/man-pages/

...come to think of it, you should also cc the linux-api mailing list
when you send the next version:

    https://www.kernel.org/doc/man-pages/linux-api-ml.html

This one is fairly straightforward, but once a new API is in a released
kernel, it's hard to change things, so we'll want to make sure we get
this right.

I should also ask you about testcases here. You should add some tests
to fstests for O_REGULAR if you haven't already:

    https://www.kernel.org/doc/man-pages/linux-api-ml.html

> > > When OPENAT2_REGULAR is combined with O_DIRECTORY, -EINVAL is returned
> > > as it doesn't make sense to open a path that is both a directory and a
> > > regular file.
> > > 
> > > [1]: https://uapi-group.org/kernel-features/#ability-to-only-open-regular-files
> > > 
> > > Signed-off-by: Dorjoy Chowdhury <dorjoychy111@gmail.com>
> > > ---
> > >  arch/alpha/include/uapi/asm/errno.h        |  2 ++
> > >  arch/alpha/include/uapi/asm/fcntl.h        |  1 +
> > >  arch/mips/include/uapi/asm/errno.h         |  2 ++
> > >  arch/parisc/include/uapi/asm/errno.h       |  2 ++
> > >  arch/parisc/include/uapi/asm/fcntl.h       |  1 +
> > >  arch/sparc/include/uapi/asm/errno.h        |  2 ++
> > >  arch/sparc/include/uapi/asm/fcntl.h        |  1 +
> > >  fs/ceph/file.c                             |  4 ++++
> > >  fs/gfs2/inode.c                            |  2 ++
> > >  fs/namei.c                                 |  4 ++++
> > >  fs/nfs/dir.c                               |  4 +++-
> > >  fs/open.c                                  |  4 +++-
> > >  fs/smb/client/dir.c                        | 11 ++++++++++-
> > >  include/linux/fcntl.h                      |  2 ++
> > >  include/uapi/asm-generic/errno.h           |  2 ++
> > >  include/uapi/asm-generic/fcntl.h           |  4 ++++
> > >  tools/arch/alpha/include/uapi/asm/errno.h  |  2 ++
> > >  tools/arch/mips/include/uapi/asm/errno.h   |  2 ++
> > >  tools/arch/parisc/include/uapi/asm/errno.h |  2 ++
> > >  tools/arch/sparc/include/uapi/asm/errno.h  |  2 ++
> > >  tools/include/uapi/asm-generic/errno.h     |  2 ++
> > >  21 files changed, 55 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/arch/alpha/include/uapi/asm/errno.h b/arch/alpha/include/uapi/asm/errno.h
> > > index 6791f6508632..1a99f38813c7 100644
> > > --- a/arch/alpha/include/uapi/asm/errno.h
> > > +++ b/arch/alpha/include/uapi/asm/errno.h
> > > @@ -127,4 +127,6 @@
> > > 
> > >  #define EHWPOISON    139     /* Memory page has hardware error */
> > > 
> > > +#define EFTYPE               140     /* Wrong file type for the intended operation */
> > > +
> > >  #endif
> > > diff --git a/arch/alpha/include/uapi/asm/fcntl.h b/arch/alpha/include/uapi/asm/fcntl.h
> > > index 50bdc8e8a271..fe488bf7c18e 100644
> > > --- a/arch/alpha/include/uapi/asm/fcntl.h
> > > +++ b/arch/alpha/include/uapi/asm/fcntl.h
> > > @@ -34,6 +34,7 @@
> > > 
> > >  #define O_PATH               040000000
> > >  #define __O_TMPFILE  0100000000
> > > +#define OPENAT2_REGULAR      0200000000
> > > 
> > >  #define F_GETLK              7
> > >  #define F_SETLK              8
> > > diff --git a/arch/mips/include/uapi/asm/errno.h b/arch/mips/include/uapi/asm/errno.h
> > > index c01ed91b1ef4..1835a50b69ce 100644
> > > --- a/arch/mips/include/uapi/asm/errno.h
> > > +++ b/arch/mips/include/uapi/asm/errno.h
> > > @@ -126,6 +126,8 @@
> > > 
> > >  #define EHWPOISON    168     /* Memory page has hardware error */
> > > 
> > > +#define EFTYPE               169     /* Wrong file type for the intended operation */
> > > +
> > >  #define EDQUOT               1133    /* Quota exceeded */
> > > 
> > > 
> > > diff --git a/arch/parisc/include/uapi/asm/errno.h b/arch/parisc/include/uapi/asm/errno.h
> > > index 8cbc07c1903e..93194fbb0a80 100644
> > > --- a/arch/parisc/include/uapi/asm/errno.h
> > > +++ b/arch/parisc/include/uapi/asm/errno.h
> > > @@ -124,4 +124,6 @@
> > > 
> > >  #define EHWPOISON    257     /* Memory page has hardware error */
> > > 
> > > +#define EFTYPE               258     /* Wrong file type for the intended operation */
> > > +
> > >  #endif
> > > diff --git a/arch/parisc/include/uapi/asm/fcntl.h b/arch/parisc/include/uapi/asm/fcntl.h
> > > index 03dee816cb13..d46812f2f0f4 100644
> > > --- a/arch/parisc/include/uapi/asm/fcntl.h
> > > +++ b/arch/parisc/include/uapi/asm/fcntl.h
> > > @@ -19,6 +19,7 @@
> > > 
> > >  #define O_PATH               020000000
> > >  #define __O_TMPFILE  040000000
> > > +#define OPENAT2_REGULAR      0100000000
> > > 
> > >  #define F_GETLK64    8
> > >  #define F_SETLK64    9
> > > diff --git a/arch/sparc/include/uapi/asm/errno.h b/arch/sparc/include/uapi/asm/errno.h
> > > index 4a41e7835fd5..71940ec9130b 100644
> > > --- a/arch/sparc/include/uapi/asm/errno.h
> > > +++ b/arch/sparc/include/uapi/asm/errno.h
> > > @@ -117,4 +117,6 @@
> > > 
> > >  #define EHWPOISON    135     /* Memory page has hardware error */
> > > 
> > > +#define EFTYPE               136     /* Wrong file type for the intended operation */
> > > +
> > >  #endif
> > > diff --git a/arch/sparc/include/uapi/asm/fcntl.h b/arch/sparc/include/uapi/asm/fcntl.h
> > > index 67dae75e5274..bb6e9fa94bc9 100644
> > > --- a/arch/sparc/include/uapi/asm/fcntl.h
> > > +++ b/arch/sparc/include/uapi/asm/fcntl.h
> > > @@ -37,6 +37,7 @@
> > > 
> > >  #define O_PATH               0x1000000
> > >  #define __O_TMPFILE  0x2000000
> > > +#define OPENAT2_REGULAR      0x4000000
> > > 
> > >  #define F_GETOWN     5       /*  for sockets. */
> > >  #define F_SETOWN     6       /*  for sockets. */
> > > diff --git a/fs/ceph/file.c b/fs/ceph/file.c
> > > index 31b691b2aea2..0a4220f72ada 100644
> > > --- a/fs/ceph/file.c
> > > +++ b/fs/ceph/file.c
> > > @@ -977,6 +977,10 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
> > >                       ceph_init_inode_acls(newino, &as_ctx);
> > >                       file->f_mode |= FMODE_CREATED;
> > >               }
> > > +             if ((flags & OPENAT2_REGULAR) && !d_is_reg(dentry)) {
> > > +                     err = -EFTYPE;
> > > +                     goto out_req;
> > > +             }
> > >               err = finish_open(file, dentry, ceph_open);
> > >       }
> > >  out_req:
> > > diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
> > > index 8344040ecaf7..0dc3e4240d9e 100644
> > > --- a/fs/gfs2/inode.c
> > > +++ b/fs/gfs2/inode.c
> > > @@ -749,6 +749,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
> > >               if (file) {
> > >                       if (S_ISREG(inode->i_mode))
> > >                               error = finish_open(file, dentry, gfs2_open_common);
> > > +                     else if (file->f_flags & OPENAT2_REGULAR)
> > > +                             error = -EFTYPE;
> > >                       else
> > >                               error = finish_no_open(file, NULL);
> > >               }
> > > diff --git a/fs/namei.c b/fs/namei.c
> > > index 5fe6cac48df8..aa5fb2672881 100644
> > > --- a/fs/namei.c
> > > +++ b/fs/namei.c
> > > @@ -4651,6 +4651,10 @@ static int do_open(struct nameidata *nd,
> > >               if (unlikely(error))
> > >                       return error;
> > >       }
> > > +
> > > +     if ((open_flag & OPENAT2_REGULAR) && !d_is_reg(nd->path.dentry))
> > > +             return -EFTYPE;
> > > +
> > >       if ((nd->flags & LOOKUP_DIRECTORY) && !d_can_lookup(nd->path.dentry))
> > >               return -ENOTDIR;
> > > 
> > > diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
> > > index b3f5c9461204..ef61db67d06e 100644
> > > --- a/fs/nfs/dir.c
> > > +++ b/fs/nfs/dir.c
> > > @@ -2195,7 +2195,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
> > >                       break;
> > >               case -EISDIR:
> > >               case -ENOTDIR:
> > > -                     goto no_open;
> > > +                     if (!(open_flags & OPENAT2_REGULAR))
> > > +                             goto no_open;
> > > +                     break;
> > 
> > Shouldn't this also set the error to -EFTYPE?
> > 
> > >               case -ELOOP:
> > >                       if (!(open_flags & O_NOFOLLOW))
> > >                               goto no_open;
> > > diff --git a/fs/open.c b/fs/open.c
> > > index 91f1139591ab..1524f52a1773 100644
> > > --- a/fs/open.c
> > > +++ b/fs/open.c
> > > @@ -1198,7 +1198,7 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
> > >        * values before calling build_open_flags(), but openat2(2) checks all
> > >        * of its arguments.
> > >        */
> > > -     if (flags & ~VALID_OPEN_FLAGS)
> > > +     if (flags & ~VALID_OPENAT2_FLAGS)
> > >               return -EINVAL;
> > >       if (how->resolve & ~VALID_RESOLVE_FLAGS)
> > >               return -EINVAL;
> > > @@ -1237,6 +1237,8 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
> > >                       return -EINVAL;
> > >               if (!(acc_mode & MAY_WRITE))
> > >                       return -EINVAL;
> > > +     } else if ((flags & O_DIRECTORY) && (flags & OPENAT2_REGULAR)) {
> > > +             return -EINVAL;
> > >       }
> > >       if (flags & O_PATH) {
> > >               /* O_PATH only permits certain other flags to be set. */
> > > diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c
> > > index cb10088197d2..d12ed0c87599 100644
> > > --- a/fs/smb/client/dir.c
> > > +++ b/fs/smb/client/dir.c
> > > @@ -236,6 +236,11 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
> > >                                * lookup.
> > >                                */
> > >                               CIFSSMBClose(xid, tcon, fid->netfid);
> > > +                             if (oflags & OPENAT2_REGULAR) {
> > > +                                     iput(newinode);
> > > +                                     rc = -EFTYPE;
> > > +                                     goto out;
> > > +                             }
> > >                               goto cifs_create_get_file_info;
> > >                       }
> > >                       /* success, no need to query */
> > > @@ -433,11 +438,15 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
> > >               goto out_err;
> > >       }
> > > 
> > > -     if (newinode)
> > > +     if (newinode) {
> > >               if (S_ISDIR(newinode->i_mode)) {
> > >                       rc = -EISDIR;
> > >                       goto out_err;
> > 
> > This logic doesn't look quite right. If you do a create and race with a
> > directory create, then it looks like you'll send back -EISDIR here
> > instead of -EFTYPE?
> > 
> 
> Yes, I thought it would be useful for the caller to know what type of
> file it actually is so I had kept this the same. Let me know if it is
> preferable to return -EFTYPE always.
> 
> Thanks for reviewing!
> 
> Regards,
> Dorjoy

-- 
Jeff Layton <jlayton@kernel.org>

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

* Re: [PATCH v4 1/4] openat2: new OPENAT2_REGULAR flag support
  2026-03-01 14:47       ` Jeff Layton
@ 2026-03-01 15:01         ` Dorjoy Chowdhury
  2026-03-01 15:10           ` Jeff Layton
  0 siblings, 1 reply; 18+ messages in thread
From: Dorjoy Chowdhury @ 2026-03-01 15:01 UTC (permalink / raw)
  To: Jeff Layton
  Cc: linux-fsdevel, linux-kernel, ceph-devel, gfs2, linux-nfs,
	linux-cifs, v9fs, linux-kselftest, viro, brauner, jack,
	chuck.lever, alex.aring, arnd, adilger, mjguzik, smfrench,
	richard.henderson, mattst88, linmag7, tsbogend, James.Bottomley,
	deller, davem, andreas, idryomov, amarkuze, slava, agruenba,
	trondmy, anna, sfrench, pc, ronniesahlberg, sprasad, tom,
	bharathsm, shuah, miklos, hansg

On Sun, Mar 1, 2026 at 8:47 PM Jeff Layton <jlayton@kernel.org> wrote:
>
> On Sun, 2026-03-01 at 20:16 +0600, Dorjoy Chowdhury wrote:
> > On Sun, Mar 1, 2026 at 6:44 PM Jeff Layton <jlayton@kernel.org> wrote:
> > >
> > > On Sat, 2026-02-21 at 20:45 +0600, Dorjoy Chowdhury wrote:
> > > > This flag indicates the path should be opened if it's a regular file.
> > > > This is useful to write secure programs that want to avoid being
> > > > tricked into opening device nodes with special semantics while thinking
> > > > they operate on regular files. This is a requested feature from the
> > > > uapi-group[1].
> > > >
> > > > A corresponding error code EFTYPE has been introduced. For example, if
> > > > openat2 is called on path /dev/null with OPENAT2_REGULAR in the flag
> > > > param, it will return -EFTYPE.
> > > >
> > > > When used in combination with O_CREAT, either the regular file is
> > > > created, or if the path already exists, it is opened if it's a regular
> > > > file. Otherwise, -EFTYPE is returned.
> > > >
> > >
> > > It would be good to mention that EFTYPE has precedent in BSD/Darwin.
> > > When an error code is already supported in another UNIX-y OS, then it
> > > bolsters the case for adding it here.
> > >
> >
> > Good suggestion. Yes, I can include this information in the commit
> > message during the next posting.
> >
> > > Your cover letter mentions that you only tested this on btrfs. At the
> > > very least, you should test NFS and SMB. It should be fairly easy to
> > > set up mounts over loopback for those cases.
> > >
> >
> > I used virtme-ng (which I think reuses the host's filesystem) to run
> > the compiled bzImage and ran the openat2 kselftests there to verify
> > it's working. Is there a similar way I can test NFS/SMB by adding
> > kselftests? Or would I need to setup NFS/SMB inside a full VM distro
> > with a modified kernel to test this? I would appreciate any suggestion
> > on this.
> >
>
> I imagine virtme would need some configuration to set up for nfs or
> cifs, but maybe it's possible. I mostly use kdevops for this sort of
> testing.
>

Got it. I will try to figure this out and do some testing for NFS/SMB. Thanks.

> > > There are some places where it doesn't seem like -EFTYPE will be
> > > returned. It looks like it can send back -EISDIR and -ENOTDIR in some
> > > cases as well. With a new API like this, I think we ought to strive for
> > > consistency.
> > >
> >
> > Good point. There was a comment in a previous posting of this patch
> > series "The most useful behavior would indicate what was found (e.g.,
> > a pipe)."
> > (ref: https://lore.kernel.org/linux-fsdevel/vhq3osjqs3nn764wrp2lxp66b4dxpb3n5x3dijhe2yr53qfgy3@tfswbjskc3y6/
> > )
> > So I thought maybe it would be useful to return -EISDIR where it was
> > already doing that. But it is a good point about consistency that we
> > won't be doing this for other different types so I guess it's better
> > to return -EFTYPE for all the cases anyway as you mention. Any
> > thoughts?
> >
>
> There is a case to be made for either. The big question is whether you
> can consistently return the same error codes in the same situations.
>
> For instance, you can return -EISDIR on NFS when the target is a
> directory, but can you do the same on btrfs or ceph? If not, then we
> have a situation where we have to deal with the possibility of two
> different error codes.
>
> In general, I think returning EFTYPE for everything is simplest and
> therefore best. Sure, EISDIR tells you a bit more about the target, but
> that info is probably not that helpful if you were expecting it to be a
> regular file.
>

Good point. I agree. I will fix this and return -EFTYPE for everything
in the next posting.

> >
> > > Should this API return -EFTYPE for all cases where it's not S_IFREG? If
> > > not, then what other errors are allowed? Bear in mind that you'll need
> > > to document this in the manpages too.
> > >
> >
> > Are the manpages in the kernel git repository or in a separate
> > repository? Do I make separate patch series for that? Sorry I don't
> > know about this in detail.
> >
>
> Separate repo and mailing list: https://www.kernel.org/doc/man-pages/
>
> ...come to think of it, you should also cc the linux-api mailing list
> when you send the next version:
>
>     https://www.kernel.org/doc/man-pages/linux-api-ml.html
>
> This one is fairly straightforward, but once a new API is in a released
> kernel, it's hard to change things, so we'll want to make sure we get
> this right.
>

I did not know about this. I will cc linux-api mailing list from the
next posting.

> I should also ask you about testcases here. You should add some tests
> to fstests for O_REGULAR if you haven't already:
>
>     https://www.kernel.org/doc/man-pages/linux-api-ml.html
>

I only added a kselftest for the new flag in
tools/testing/selftests/openat2/openat2_test.c in my second commit in
this patch series. Where are the fstests that I should add tests? I
think you added the wrong URL above, probably a typo.

Regards,
Dorjoy

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

* Re: [PATCH v4 1/4] openat2: new OPENAT2_REGULAR flag support
  2026-03-01 15:01         ` Dorjoy Chowdhury
@ 2026-03-01 15:10           ` Jeff Layton
  2026-03-01 15:15             ` Dorjoy Chowdhury
  0 siblings, 1 reply; 18+ messages in thread
From: Jeff Layton @ 2026-03-01 15:10 UTC (permalink / raw)
  To: Dorjoy Chowdhury
  Cc: linux-fsdevel, linux-kernel, ceph-devel, gfs2, linux-nfs,
	linux-cifs, v9fs, linux-kselftest, viro, brauner, jack,
	chuck.lever, alex.aring, arnd, adilger, mjguzik, smfrench,
	richard.henderson, mattst88, linmag7, tsbogend, James.Bottomley,
	deller, davem, andreas, idryomov, amarkuze, slava, agruenba,
	trondmy, anna, sfrench, pc, ronniesahlberg, sprasad, tom,
	bharathsm, shuah, miklos, hansg

On Sun, 2026-03-01 at 21:01 +0600, Dorjoy Chowdhury wrote:
> On Sun, Mar 1, 2026 at 8:47 PM Jeff Layton <jlayton@kernel.org> wrote:
> > 
> > On Sun, 2026-03-01 at 20:16 +0600, Dorjoy Chowdhury wrote:
> > > On Sun, Mar 1, 2026 at 6:44 PM Jeff Layton <jlayton@kernel.org> wrote:
> > > > 
> > > > On Sat, 2026-02-21 at 20:45 +0600, Dorjoy Chowdhury wrote:
> > > > > This flag indicates the path should be opened if it's a regular file.
> > > > > This is useful to write secure programs that want to avoid being
> > > > > tricked into opening device nodes with special semantics while thinking
> > > > > they operate on regular files. This is a requested feature from the
> > > > > uapi-group[1].
> > > > > 
> > > > > A corresponding error code EFTYPE has been introduced. For example, if
> > > > > openat2 is called on path /dev/null with OPENAT2_REGULAR in the flag
> > > > > param, it will return -EFTYPE.
> > > > > 
> > > > > When used in combination with O_CREAT, either the regular file is
> > > > > created, or if the path already exists, it is opened if it's a regular
> > > > > file. Otherwise, -EFTYPE is returned.
> > > > > 
> > > > 
> > > > It would be good to mention that EFTYPE has precedent in BSD/Darwin.
> > > > When an error code is already supported in another UNIX-y OS, then it
> > > > bolsters the case for adding it here.
> > > > 
> > > 
> > > Good suggestion. Yes, I can include this information in the commit
> > > message during the next posting.
> > > 
> > > > Your cover letter mentions that you only tested this on btrfs. At the
> > > > very least, you should test NFS and SMB. It should be fairly easy to
> > > > set up mounts over loopback for those cases.
> > > > 
> > > 
> > > I used virtme-ng (which I think reuses the host's filesystem) to run
> > > the compiled bzImage and ran the openat2 kselftests there to verify
> > > it's working. Is there a similar way I can test NFS/SMB by adding
> > > kselftests? Or would I need to setup NFS/SMB inside a full VM distro
> > > with a modified kernel to test this? I would appreciate any suggestion
> > > on this.
> > > 
> > 
> > I imagine virtme would need some configuration to set up for nfs or
> > cifs, but maybe it's possible. I mostly use kdevops for this sort of
> > testing.
> > 
> 
> Got it. I will try to figure this out and do some testing for NFS/SMB. Thanks.
> 
> > > > There are some places where it doesn't seem like -EFTYPE will be
> > > > returned. It looks like it can send back -EISDIR and -ENOTDIR in some
> > > > cases as well. With a new API like this, I think we ought to strive for
> > > > consistency.
> > > > 
> > > 
> > > Good point. There was a comment in a previous posting of this patch
> > > series "The most useful behavior would indicate what was found (e.g.,
> > > a pipe)."
> > > (ref: https://lore.kernel.org/linux-fsdevel/vhq3osjqs3nn764wrp2lxp66b4dxpb3n5x3dijhe2yr53qfgy3@tfswbjskc3y6/
> > > )
> > > So I thought maybe it would be useful to return -EISDIR where it was
> > > already doing that. But it is a good point about consistency that we
> > > won't be doing this for other different types so I guess it's better
> > > to return -EFTYPE for all the cases anyway as you mention. Any
> > > thoughts?
> > > 
> > 
> > There is a case to be made for either. The big question is whether you
> > can consistently return the same error codes in the same situations.
> > 
> > For instance, you can return -EISDIR on NFS when the target is a
> > directory, but can you do the same on btrfs or ceph? If not, then we
> > have a situation where we have to deal with the possibility of two
> > different error codes.
> > 
> > In general, I think returning EFTYPE for everything is simplest and
> > therefore best. Sure, EISDIR tells you a bit more about the target, but
> > that info is probably not that helpful if you were expecting it to be a
> > regular file.
> > 
> 
> Good point. I agree. I will fix this and return -EFTYPE for everything
> in the next posting.
> 
> > > 
> > > > Should this API return -EFTYPE for all cases where it's not S_IFREG? If
> > > > not, then what other errors are allowed? Bear in mind that you'll need
> > > > to document this in the manpages too.
> > > > 
> > > 
> > > Are the manpages in the kernel git repository or in a separate
> > > repository? Do I make separate patch series for that? Sorry I don't
> > > know about this in detail.
> > > 
> > 
> > Separate repo and mailing list: https://www.kernel.org/doc/man-pages/
> > 
> > ...come to think of it, you should also cc the linux-api mailing list
> > when you send the next version:
> > 
> >     https://www.kernel.org/doc/man-pages/linux-api-ml.html
> > 
> > This one is fairly straightforward, but once a new API is in a released
> > kernel, it's hard to change things, so we'll want to make sure we get
> > this right.
> > 
> 
> I did not know about this. I will cc linux-api mailing list from the
> next posting.
> 
> > I should also ask you about testcases here. You should add some tests
> > to fstests for O_REGULAR if you haven't already:
> > 
> >     https://www.kernel.org/doc/man-pages/linux-api-ml.html
> > 
> 
> I only added a kselftest for the new flag in
> tools/testing/selftests/openat2/openat2_test.c in my second commit in
> this patch series. Where are the fstests that I should add tests? I
> think you added the wrong URL above, probably a typo.
> 
> 

I did indeed, sorry. They're here:

https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git

-- 
Jeff Layton <jlayton@kernel.org>

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

* Re: [PATCH v4 1/4] openat2: new OPENAT2_REGULAR flag support
  2026-03-01 15:10           ` Jeff Layton
@ 2026-03-01 15:15             ` Dorjoy Chowdhury
  2026-03-01 15:17               ` Jeff Layton
  0 siblings, 1 reply; 18+ messages in thread
From: Dorjoy Chowdhury @ 2026-03-01 15:15 UTC (permalink / raw)
  To: Jeff Layton
  Cc: linux-fsdevel, linux-kernel, ceph-devel, gfs2, linux-nfs,
	linux-cifs, v9fs, linux-kselftest, viro, brauner, jack,
	chuck.lever, alex.aring, arnd, adilger, mjguzik, smfrench,
	richard.henderson, mattst88, linmag7, tsbogend, James.Bottomley,
	deller, davem, andreas, idryomov, amarkuze, slava, agruenba,
	trondmy, anna, sfrench, pc, ronniesahlberg, sprasad, tom,
	bharathsm, shuah, miklos, hansg

On Sun, Mar 1, 2026 at 9:10 PM Jeff Layton <jlayton@kernel.org> wrote:
>
> On Sun, 2026-03-01 at 21:01 +0600, Dorjoy Chowdhury wrote:
> > On Sun, Mar 1, 2026 at 8:47 PM Jeff Layton <jlayton@kernel.org> wrote:
> > >
> > > On Sun, 2026-03-01 at 20:16 +0600, Dorjoy Chowdhury wrote:
> > > > On Sun, Mar 1, 2026 at 6:44 PM Jeff Layton <jlayton@kernel.org> wrote:
> > > > >
> > > > > On Sat, 2026-02-21 at 20:45 +0600, Dorjoy Chowdhury wrote:
> > > > > > This flag indicates the path should be opened if it's a regular file.
> > > > > > This is useful to write secure programs that want to avoid being
> > > > > > tricked into opening device nodes with special semantics while thinking
> > > > > > they operate on regular files. This is a requested feature from the
> > > > > > uapi-group[1].
> > > > > >
> > > > > > A corresponding error code EFTYPE has been introduced. For example, if
> > > > > > openat2 is called on path /dev/null with OPENAT2_REGULAR in the flag
> > > > > > param, it will return -EFTYPE.
> > > > > >
> > > > > > When used in combination with O_CREAT, either the regular file is
> > > > > > created, or if the path already exists, it is opened if it's a regular
> > > > > > file. Otherwise, -EFTYPE is returned.
> > > > > >
> > > > >
> > > > > It would be good to mention that EFTYPE has precedent in BSD/Darwin.
> > > > > When an error code is already supported in another UNIX-y OS, then it
> > > > > bolsters the case for adding it here.
> > > > >
> > > >
> > > > Good suggestion. Yes, I can include this information in the commit
> > > > message during the next posting.
> > > >
> > > > > Your cover letter mentions that you only tested this on btrfs. At the
> > > > > very least, you should test NFS and SMB. It should be fairly easy to
> > > > > set up mounts over loopback for those cases.
> > > > >
> > > >
> > > > I used virtme-ng (which I think reuses the host's filesystem) to run
> > > > the compiled bzImage and ran the openat2 kselftests there to verify
> > > > it's working. Is there a similar way I can test NFS/SMB by adding
> > > > kselftests? Or would I need to setup NFS/SMB inside a full VM distro
> > > > with a modified kernel to test this? I would appreciate any suggestion
> > > > on this.
> > > >
> > >
> > > I imagine virtme would need some configuration to set up for nfs or
> > > cifs, but maybe it's possible. I mostly use kdevops for this sort of
> > > testing.
> > >
> >
> > Got it. I will try to figure this out and do some testing for NFS/SMB. Thanks.
> >
> > > > > There are some places where it doesn't seem like -EFTYPE will be
> > > > > returned. It looks like it can send back -EISDIR and -ENOTDIR in some
> > > > > cases as well. With a new API like this, I think we ought to strive for
> > > > > consistency.
> > > > >
> > > >
> > > > Good point. There was a comment in a previous posting of this patch
> > > > series "The most useful behavior would indicate what was found (e.g.,
> > > > a pipe)."
> > > > (ref: https://lore.kernel.org/linux-fsdevel/vhq3osjqs3nn764wrp2lxp66b4dxpb3n5x3dijhe2yr53qfgy3@tfswbjskc3y6/
> > > > )
> > > > So I thought maybe it would be useful to return -EISDIR where it was
> > > > already doing that. But it is a good point about consistency that we
> > > > won't be doing this for other different types so I guess it's better
> > > > to return -EFTYPE for all the cases anyway as you mention. Any
> > > > thoughts?
> > > >
> > >
> > > There is a case to be made for either. The big question is whether you
> > > can consistently return the same error codes in the same situations.
> > >
> > > For instance, you can return -EISDIR on NFS when the target is a
> > > directory, but can you do the same on btrfs or ceph? If not, then we
> > > have a situation where we have to deal with the possibility of two
> > > different error codes.
> > >
> > > In general, I think returning EFTYPE for everything is simplest and
> > > therefore best. Sure, EISDIR tells you a bit more about the target, but
> > > that info is probably not that helpful if you were expecting it to be a
> > > regular file.
> > >
> >
> > Good point. I agree. I will fix this and return -EFTYPE for everything
> > in the next posting.
> >
> > > >
> > > > > Should this API return -EFTYPE for all cases where it's not S_IFREG? If
> > > > > not, then what other errors are allowed? Bear in mind that you'll need
> > > > > to document this in the manpages too.
> > > > >
> > > >
> > > > Are the manpages in the kernel git repository or in a separate
> > > > repository? Do I make separate patch series for that? Sorry I don't
> > > > know about this in detail.
> > > >
> > >
> > > Separate repo and mailing list: https://www.kernel.org/doc/man-pages/
> > >
> > > ...come to think of it, you should also cc the linux-api mailing list
> > > when you send the next version:
> > >
> > >     https://www.kernel.org/doc/man-pages/linux-api-ml.html
> > >
> > > This one is fairly straightforward, but once a new API is in a released
> > > kernel, it's hard to change things, so we'll want to make sure we get
> > > this right.
> > >
> >
> > I did not know about this. I will cc linux-api mailing list from the
> > next posting.
> >
> > > I should also ask you about testcases here. You should add some tests
> > > to fstests for O_REGULAR if you haven't already:
> > >
> > >     https://www.kernel.org/doc/man-pages/linux-api-ml.html
> > >
> >
> > I only added a kselftest for the new flag in
> > tools/testing/selftests/openat2/openat2_test.c in my second commit in
> > this patch series. Where are the fstests that I should add tests? I
> > think you added the wrong URL above, probably a typo.
> >
> >
>
> I did indeed, sorry. They're here:
>
> https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git
>

Thanks! This is a separate git repository, so I guess for both
manpages and fstests I need to submit separate patch series for
O_REGULAR. Do I need to wait first for this patch series to be merged?
How does it work?

Regards,
Dorjoy

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

* Re: [PATCH v4 1/4] openat2: new OPENAT2_REGULAR flag support
  2026-03-01 15:15             ` Dorjoy Chowdhury
@ 2026-03-01 15:17               ` Jeff Layton
  2026-03-01 15:19                 ` Dorjoy Chowdhury
  0 siblings, 1 reply; 18+ messages in thread
From: Jeff Layton @ 2026-03-01 15:17 UTC (permalink / raw)
  To: Dorjoy Chowdhury
  Cc: linux-fsdevel, linux-kernel, ceph-devel, gfs2, linux-nfs,
	linux-cifs, v9fs, linux-kselftest, viro, brauner, jack,
	chuck.lever, alex.aring, arnd, adilger, mjguzik, smfrench,
	richard.henderson, mattst88, linmag7, tsbogend, James.Bottomley,
	deller, davem, andreas, idryomov, amarkuze, slava, agruenba,
	trondmy, anna, sfrench, pc, ronniesahlberg, sprasad, tom,
	bharathsm, shuah, miklos, hansg

On Sun, 2026-03-01 at 21:15 +0600, Dorjoy Chowdhury wrote:
> > > 
> > > I only added a kselftest for the new flag in
> > > tools/testing/selftests/openat2/openat2_test.c in my second commit in
> > > this patch series. Where are the fstests that I should add tests? I
> > > think you added the wrong URL above, probably a typo.
> > > 
> > > 
> > 
> > I did indeed, sorry. They're here:
> > 
> > https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git
> > 
> 
> Thanks! This is a separate git repository, so I guess for both
> manpages and fstests I need to submit separate patch series for
> O_REGULAR. Do I need to wait first for this patch series to be merged?
> How does it work?
> 
> 

No, you can submit them in parallel, but they probably won't get merged
until the kernel patches go in.

-- 
Jeff Layton <jlayton@kernel.org>

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

* Re: [PATCH v4 1/4] openat2: new OPENAT2_REGULAR flag support
  2026-03-01 15:17               ` Jeff Layton
@ 2026-03-01 15:19                 ` Dorjoy Chowdhury
  0 siblings, 0 replies; 18+ messages in thread
From: Dorjoy Chowdhury @ 2026-03-01 15:19 UTC (permalink / raw)
  To: Jeff Layton
  Cc: linux-fsdevel, linux-kernel, ceph-devel, gfs2, linux-nfs,
	linux-cifs, v9fs, linux-kselftest, viro, brauner, jack,
	chuck.lever, alex.aring, arnd, adilger, mjguzik, smfrench,
	richard.henderson, mattst88, linmag7, tsbogend, James.Bottomley,
	deller, davem, andreas, idryomov, amarkuze, slava, agruenba,
	trondmy, anna, sfrench, pc, ronniesahlberg, sprasad, tom,
	bharathsm, shuah, miklos, hansg

On Sun, Mar 1, 2026 at 9:17 PM Jeff Layton <jlayton@kernel.org> wrote:
>
> On Sun, 2026-03-01 at 21:15 +0600, Dorjoy Chowdhury wrote:
> > > >
> > > > I only added a kselftest for the new flag in
> > > > tools/testing/selftests/openat2/openat2_test.c in my second commit in
> > > > this patch series. Where are the fstests that I should add tests? I
> > > > think you added the wrong URL above, probably a typo.
> > > >
> > > >
> > >
> > > I did indeed, sorry. They're here:
> > >
> > > https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git
> > >
> >
> > Thanks! This is a separate git repository, so I guess for both
> > manpages and fstests I need to submit separate patch series for
> > O_REGULAR. Do I need to wait first for this patch series to be merged?
> > How does it work?
> >
> >
>
> No, you can submit them in parallel, but they probably won't get merged
> until the kernel patches go in.
>

Alright. I can look into submitting patches in parallel. Thanks for
all the info!

Regards,
Dorjoy

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

end of thread, other threads:[~2026-03-01 15:20 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-21 14:45 [PATCH v4 0/4] OPENAT2_REGULAR flag support in openat2 Dorjoy Chowdhury
2026-02-21 14:45 ` [PATCH v4 1/4] openat2: new OPENAT2_REGULAR flag support Dorjoy Chowdhury
2026-03-01 12:44   ` Jeff Layton
2026-03-01 14:16     ` Dorjoy Chowdhury
2026-03-01 14:47       ` Jeff Layton
2026-03-01 15:01         ` Dorjoy Chowdhury
2026-03-01 15:10           ` Jeff Layton
2026-03-01 15:15             ` Dorjoy Chowdhury
2026-03-01 15:17               ` Jeff Layton
2026-03-01 15:19                 ` Dorjoy Chowdhury
2026-02-21 14:45 ` [PATCH v4 2/4] kselftest/openat2: test for OPENAT2_REGULAR flag Dorjoy Chowdhury
2026-02-21 14:45 ` [PATCH v4 3/4] sparc/fcntl.h: convert O_* flag macros from hex to octal Dorjoy Chowdhury
2026-02-21 14:45 ` [PATCH v4 4/4] mips/fcntl.h: " Dorjoy Chowdhury
2026-02-21 15:49 ` [PATCH v4 0/4] OPENAT2_REGULAR flag support in openat2 Dorjoy Chowdhury
2026-02-21 23:45   ` Askar Safin
2026-02-22  7:19     ` Dorjoy Chowdhury
2026-03-01 10:16 ` Dorjoy Chowdhury
  -- strict thread matches above, loose matches on Subject: below --
2026-02-06 19:03 [PATCH v4 0/4] openat2: new OPENAT2_REGULAR flag support Dorjoy Chowdhury
2026-02-06 19:03 ` [PATCH v4 1/4] " Dorjoy Chowdhury

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox