Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 11 Jun 2021 00:48:01 GMT
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 043f20498526 - stable/13 - fdescfs: add an option to return underlying file vnode on lookup
Message-ID:  <202106110048.15B0m1w9047989@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=043f204985261d6daae69538c4609b3e143ee444

commit 043f204985261d6daae69538c4609b3e143ee444
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-05-05 22:53:20 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-06-11 00:33:48 +0000

    fdescfs: add an option to return underlying file vnode on lookup
    
    (cherry picked from commit f9b1e711f0d8c27f2d29e7a8e6276947d37a6a22)
---
 share/man/man5/fdescfs.5      | 94 +++++++++++++++++++++++++++++++++++++------
 sys/fs/fdescfs/fdesc.h        |  1 +
 sys/fs/fdescfs/fdesc_vfsops.c |  2 +
 sys/fs/fdescfs/fdesc_vnops.c  | 12 +++++-
 4 files changed, 95 insertions(+), 14 deletions(-)

diff --git a/share/man/man5/fdescfs.5 b/share/man/man5/fdescfs.5
index 3f16104c0ac8..f2abda2bb4c2 100644
--- a/share/man/man5/fdescfs.5
+++ b/share/man/man5/fdescfs.5
@@ -1,3 +1,5 @@
+.\" Copyright (c) 2021 The FreeBSD Foundation, Inc.
+.\"
 .\" Copyright (c) 1996
 .\"	Mike Pritchard <mpp@FreeBSD.org>.  All rights reserved.
 .\"
@@ -8,6 +10,10 @@
 .\" This code is derived from software donated to Berkeley by
 .\" Jan-Simon Pendry.
 .\"
+.\" Parts of this documentation was written by
+.\" Konstantin Belousov <kib@FreeBSD.org> under sponsorship
+.\" from the FreeBSD Foundation.
+.\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
 .\" are met:
@@ -34,7 +40,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd August 1, 2017
+.Dd May 17, 2021
 .Dt FDESCFS 5
 .Os
 .Sh NAME
@@ -62,7 +68,40 @@ through
 .Pa /dev/fd/#
 refer to file descriptors which can be accessed through the file
 system.
-If the file descriptor is open and the mode the file is being opened
+.Pp
+The following mount options can be used when mounting
+.Nm
+filesystem:
+.Bl -tag -width linrdlnk
+.It Cm nodup
+For file descriptors referencing vnodes, instead of the
+.Xr dup 2
+semantic described above, implement re-opening of the referenced vnode.
+See below for more details.
+.It Cm linrdlnk
+Report the type of the
+.Nm
+vnode as
+.Dv VLNK
+instead of
+.Fx
+traditional
+.Dv VCHR .
+For
+.Xr linux 4
+ABI compatibility mount
+.Nm
+volume with the
+.Cm linrdlnk
+option.
+.El
+.Pp
+For
+.Nm
+mounted without the
+.Cm nodup
+mount option,
+if the file descriptor is open and the mode the file is being opened
 with is a subset of the mode of the existing descriptor, the call:
 .Bd -literal -offset indent
 fd = open("/dev/fd/0", mode);
@@ -74,7 +113,6 @@ fd = fcntl(0, F_DUPFD, 0);
 .Ed
 .Pp
 are equivalent.
-.Pp
 Flags to the
 .Xr open 2
 call other than
@@ -84,6 +122,38 @@ and
 .Dv O_RDWR
 are ignored.
 .Pp
+For
+.Nm
+mounted with the
+.Cm nodup
+option, and file descriptor referencing a vnode, the call:
+.Bd -literal -offset indent
+fd = open("/dev/fd/0", mode);
+.Ed
+.Pp
+reopens the referenced vnode with the specified
+.Fa mode .
+In other words, the
+.Fn open
+call above is equivalent to
+.Bd -literal -offset indent
+fd = openat(0, "", O_EMPTY_PATH, mode);
+.Ed
+.Pp
+In particular, if the file descriptor was opened with the
+.Dv O_PATH
+flag, then either
+.Dv O_EMPTY_PATH
+or
+.Fn open
+over
+.Nm
+mount with
+.Cm nodup
+option allows one to convert it to a regularly opened file,
+assuming that the current permissions allow the requested
+.Fa mode .
+.Pp
 .Em "Note:"
 .Pa /dev/fd/0 ,
 .Pa /dev/fd/1
@@ -92,14 +162,6 @@ and
 files are created by default when devfs alone is mounted.
 .Nm
 creates entries for all file descriptors opened by the process.
-.Pp
-For
-.Xr linux 4
-ABI compatibility mount
-.Nm
-volume with
-.Cm linrdlnk
-option.
 .Sh FILES
 .Bl -tag -width /dev/stderr -compact
 .It Pa /dev/fd/#
@@ -110,13 +172,19 @@ To mount a
 volume located on
 .Pa /dev/fd :
 .Pp
-.Dl "mount -t fdescfs null /dev/fd"
+.Dl "mount -t fdescfs none /dev/fd"
 .Pp
 For
 .Xr linux 4
 ABI compatibility:
 .Pp
-.Dl "mount -t fdescfs -o linrdlnk null /compat/linux/dev/fd"
+.Dl "mount -t fdescfs -o linrdlnk none /compat/linux/dev/fd"
+.Pp
+For substitute of
+.Dv O_EMPTY_PATH
+flag use:
+.Pp
+.Dl "mount -t fdescfs -o nodup none /dev/fdpath"
 .Sh SEE ALSO
 .Xr devfs 5 ,
 .Xr mount 8
diff --git a/sys/fs/fdescfs/fdesc.h b/sys/fs/fdescfs/fdesc.h
index b578b7309130..94682f42cdb3 100644
--- a/sys/fs/fdescfs/fdesc.h
+++ b/sys/fs/fdescfs/fdesc.h
@@ -42,6 +42,7 @@
 /* Private mount flags for fdescfs. */
 #define FMNT_UNMOUNTF	0x01
 #define FMNT_LINRDLNKF	0x02
+#define	FMNT_NODUP	0x04
 
 struct fdescmount {
 	struct vnode	*f_root;	/* Root node */
diff --git a/sys/fs/fdescfs/fdesc_vfsops.c b/sys/fs/fdescfs/fdesc_vfsops.c
index 64f8d28bdcfd..9d8fdda47cbf 100644
--- a/sys/fs/fdescfs/fdesc_vfsops.c
+++ b/sys/fs/fdescfs/fdesc_vfsops.c
@@ -101,6 +101,8 @@ fdesc_mount(struct mount *mp)
 	fmp->flags = 0;
 	if (vfs_getopt(mp->mnt_optnew, "linrdlnk", NULL, NULL) == 0)
 		fmp->flags |= FMNT_LINRDLNKF;
+	if (vfs_getopt(mp->mnt_optnew, "nodup", NULL, NULL) == 0)
+		fmp->flags |= FMNT_NODUP;
 	error = fdesc_allocvp(Froot, -1, FD_ROOT, mp, &rvp);
 	if (error) {
 		free(fmp, M_FDESCMNT);
diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c
index 1271b50e6e94..c5a7b86f1de5 100644
--- a/sys/fs/fdescfs/fdesc_vnops.c
+++ b/sys/fs/fdescfs/fdesc_vnops.c
@@ -264,10 +264,20 @@ fdesc_get_ino_alloc(struct mount *mp, void *arg, int lkflags,
     struct vnode **rvp)
 {
 	struct fdesc_get_ino_args *a;
+	struct fdescmount *fdm;
+	struct vnode *vp;
 	int error;
 
 	a = arg;
-	error = fdesc_allocvp(a->ftype, a->fd_fd, a->ix, mp, rvp);
+	fdm = VFSTOFDESC(mp);
+	if ((fdm->flags & FMNT_NODUP) != 0 && a->fp->f_type == DTYPE_VNODE) {
+		vp = a->fp->f_vnode;
+		vget(vp, lkflags | LK_RETRY);
+		*rvp = vp;
+		error = 0;
+	} else {
+		error = fdesc_allocvp(a->ftype, a->fd_fd, a->ix, mp, rvp);
+	}
 	fdrop(a->fp, a->td);
 	return (error);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202106110048.15B0m1w9047989>