diff options
author | Dmitry Chagin <dchagin@FreeBSD.org> | 2023-04-28 08:54:58 +0000 |
---|---|---|
committer | Dmitry Chagin <dchagin@FreeBSD.org> | 2023-06-29 08:15:29 +0000 |
commit | c43f5eb2f4c7cbfde1873c9d0ece23e719ae312e (patch) | |
tree | 8f0e41155c2fdeab992669d6d20794571e7ffafe /sys/compat/linux/linux_util.c | |
parent | 78c8b272ae7d856e493d5dd302e0e51e926e2606 (diff) |
linux(4): Move translate_vnhook_major_minor() into the Linux common module
(cherry picked from commit 6072eea0c375fc3ab0cf5bb494c75d1beac7b8ba)
Diffstat (limited to 'sys/compat/linux/linux_util.c')
-rw-r--r-- | sys/compat/linux/linux_util.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/sys/compat/linux/linux_util.c b/sys/compat/linux/linux_util.c index 2a21fdc10bd7..5995ac5e18af 100644 --- a/sys/compat/linux/linux_util.c +++ b/sys/compat/linux/linux_util.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include <sys/malloc.h> #include <sys/namei.h> #include <sys/proc.h> +#include <sys/stat.h> #include <sys/syscallsubr.h> #include <sys/vnode.h> @@ -225,6 +226,31 @@ linux_vn_get_major_minor(const struct vnode *vp, int *major, int *minor) return (error); } +void +translate_vnhook_major_minor(struct vnode *vp, struct stat *sb) +{ + int major, minor; + + if (vn_isdisk(vp)) { + sb->st_mode &= ~S_IFMT; + sb->st_mode |= S_IFBLK; + } + + /* + * Return the same st_dev for every devfs instance. The reason + * for this is to work around an idiosyncrasy of glibc getttynam() + * implementation: it checks whether st_dev returned for fd 0 + * is the same as st_dev returned for the target of /proc/self/fd/0 + * symlink, and with linux chroots having their own devfs instance, + * the check will fail if you chroot into it. + */ + if (rootdevmp != NULL && vp->v_mount->mnt_vfc == rootdevmp->mnt_vfc) + sb->st_dev = rootdevmp->mnt_stat.f_fsid.val[0]; + + if (linux_vn_get_major_minor(vp, &major, &minor) == 0) + sb->st_rdev = (major << 8 | minor); +} + char * linux_get_char_devices(void) { |