git: 043f20498526 - stable/13 - fdescfs: add an option to return underlying file vnode on lookup
Konstantin Belousov
kib at FreeBSD.org
Fri Jun 11 00:48:02 UTC 2021
The branch stable/13 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=043f204985261d6daae69538c4609b3e143ee444
commit 043f204985261d6daae69538c4609b3e143ee444
Author: Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2021-05-05 22:53:20 +0000
Commit: Konstantin Belousov <kib at 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 at 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 at 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);
}
More information about the dev-commits-src-all
mailing list