fdescfs: add a mount option rdlnk

which changes /dev/fd/N files types to symbolic link with the behavior
of symbolic links.

PR:	272127
Reported by:	Peter Eriksson <pen@lysator.liu.se>
Reviewed by:	dchagin
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D40969
This commit is contained in:
Konstantin Belousov 2023-07-11 08:03:49 +03:00
parent 9c3bfe2ad0
commit 3905309dfe
3 changed files with 13 additions and 5 deletions

View File

@ -43,6 +43,7 @@
#define FMNT_UNMOUNTF 0x01
#define FMNT_LINRDLNKF 0x02
#define FMNT_NODUP 0x04
#define FMNT_RDLNKF 0x08
struct fdescmount {
struct vnode *f_root; /* Root node */

View File

@ -100,6 +100,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, "rdlnk", NULL, NULL) == 0)
fmp->flags |= FMNT_RDLNKF;
if (vfs_getopt(mp->mnt_optnew, "nodup", NULL, NULL) == 0)
fmp->flags |= FMNT_NODUP;
error = fdesc_allocvp(Froot, -1, FD_ROOT, mp, &rvp);

View File

@ -190,8 +190,12 @@ fdesc_allocvp(fdntype ftype, unsigned fd_fd, int ix, struct mount *mp,
fd->fd_type = ftype;
fd->fd_fd = fd_fd;
fd->fd_ix = ix;
if (ftype == Fdesc && fmp->flags & FMNT_LINRDLNKF)
vp->v_vflag |= VV_READLINK;
if (ftype == Fdesc) {
if ((fmp->flags & FMNT_RDLNKF) != 0)
vp->v_type = VLNK;
else if ((fmp->flags & FMNT_LINRDLNKF) != 0)
vp->v_vflag |= VV_READLINK;
}
error = insmntque1(vp, mp);
if (error != 0) {
vgone(vp);
@ -457,7 +461,8 @@ fdesc_getattr(struct vop_getattr_args *ap)
break;
case Fdesc:
vap->va_type = (vp->v_vflag & VV_READLINK) == 0 ? VCHR : VLNK;
vap->va_type = (VFSTOFDESC(vp->v_mount)->flags &
(FMNT_RDLNKF | FMNT_LINRDLNKF)) == 0 ? VCHR : VLNK;
vap->va_nlink = 1;
vap->va_size = 0;
vap->va_rdev = makedev(0, vap->va_fileid);
@ -575,8 +580,8 @@ fdesc_readdir(struct vop_readdir_args *ap)
break;
dp->d_namlen = sprintf(dp->d_name, "%d", fcnt);
dp->d_reclen = UIO_MX;
dp->d_type = (fmp->flags & FMNT_LINRDLNKF) == 0 ?
DT_CHR : DT_LNK;
dp->d_type = (fmp->flags & (FMNT_RDLNKF |
FMNT_LINRDLNKF)) == 0 ? DT_CHR : DT_LNK;
dp->d_fileno = i + FD_DESC;
dirent_terminate(dp);
break;