svn commit: r367777 - in head: lib/libkvm lib/libprocstat sys/compat/cloudabi sys/fs/fuse sys/fs/unionfs sys/kern sys/sys
Conrad Meyer
cem at FreeBSD.org
Tue Nov 17 21:14:17 UTC 2020
Author: cem
Date: Tue Nov 17 21:14:13 2020
New Revision: 367777
URL: https://svnweb.freebsd.org/changeset/base/367777
Log:
Split out cwd/root/jail, cmask state from filedesc table
No functional change intended.
Tracking these structures separately for each proc enables future work to
correctly emulate clone(2) in linux(4).
__FreeBSD_version is bumped (to 1300130) for consumption by, e.g., lsof.
Reviewed by: kib
Discussed with: markj, mjg
Differential Revision: https://reviews.freebsd.org/D27037
Modified:
head/lib/libkvm/kvm_proc.c
head/lib/libprocstat/libprocstat.c
head/sys/compat/cloudabi/cloudabi_file.c
head/sys/fs/fuse/fuse_internal.c
head/sys/fs/fuse/fuse_vnops.c
head/sys/fs/unionfs/union_subr.c
head/sys/kern/imgact_elf.c
head/sys/kern/init_main.c
head/sys/kern/kern_descrip.c
head/sys/kern/kern_exec.c
head/sys/kern/kern_exit.c
head/sys/kern/kern_fork.c
head/sys/kern/kern_proc.c
head/sys/kern/kern_thread.c
head/sys/kern/uipc_mqueue.c
head/sys/kern/uipc_sem.c
head/sys/kern/uipc_shm.c
head/sys/kern/uipc_usrreq.c
head/sys/kern/vfs_syscalls.c
head/sys/sys/filedesc.h
head/sys/sys/param.h
head/sys/sys/proc.h
head/sys/sys/user.h
Modified: head/lib/libkvm/kvm_proc.c
==============================================================================
--- head/lib/libkvm/kvm_proc.c Tue Nov 17 20:01:21 2020 (r367776)
+++ head/lib/libkvm/kvm_proc.c Tue Nov 17 21:14:13 2020 (r367777)
@@ -221,6 +221,7 @@ kvm_proclist(kvm_t *kd, int what, int arg, struct proc
kp->ki_tracep = proc.p_tracevp;
kp->ki_textvp = proc.p_textvp;
kp->ki_fd = proc.p_fd;
+ kp->ki_pd = proc.p_pd;
kp->ki_vmspace = proc.p_vmspace;
if (proc.p_sigacts != NULL) {
if (KREAD(kd, (u_long)proc.p_sigacts, &sigacts)) {
Modified: head/lib/libprocstat/libprocstat.c
==============================================================================
--- head/lib/libprocstat/libprocstat.c Tue Nov 17 20:01:21 2020 (r367776)
+++ head/lib/libprocstat/libprocstat.c Tue Nov 17 21:14:13 2020 (r367777)
@@ -460,6 +460,7 @@ procstat_getfiles_kvm(struct procstat *procstat, struc
{
struct file file;
struct filedesc filed;
+ struct pwddesc pathsd;
struct fdescenttbl *fdt;
struct pwd pwd;
unsigned long pwd_addr;
@@ -484,15 +485,20 @@ procstat_getfiles_kvm(struct procstat *procstat, struc
kd = procstat->kd;
if (kd == NULL)
return (NULL);
- if (kp->ki_fd == NULL)
+ if (kp->ki_fd == NULL || kp->ki_pd == NULL)
return (NULL);
if (!kvm_read_all(kd, (unsigned long)kp->ki_fd, &filed,
sizeof(filed))) {
warnx("can't read filedesc at %p", (void *)kp->ki_fd);
return (NULL);
}
+ if (!kvm_read_all(kd, (unsigned long)kp->ki_pd, &pathsd,
+ sizeof(pathsd))) {
+ warnx("can't read pwddesc at %p", (void *)kp->ki_pd);
+ return (NULL);
+ }
haspwd = false;
- pwd_addr = (unsigned long)(FILEDESC_KVM_LOAD_PWD(&filed));
+ pwd_addr = (unsigned long)(PWDDESC_KVM_LOAD_PWD(&pathsd));
if (pwd_addr != 0) {
if (!kvm_read_all(kd, pwd_addr, &pwd, sizeof(pwd))) {
warnx("can't read fd_pwd at %p", (void *)pwd_addr);
@@ -2086,18 +2092,18 @@ procstat_freegroups(struct procstat *procstat __unused
static int
procstat_getumask_kvm(kvm_t *kd, struct kinfo_proc *kp, unsigned short *maskp)
{
- struct filedesc fd;
+ struct pwddesc pd;
assert(kd != NULL);
assert(kp != NULL);
- if (kp->ki_fd == NULL)
+ if (kp->ki_pd == NULL)
return (-1);
- if (!kvm_read_all(kd, (unsigned long)kp->ki_fd, &fd, sizeof(fd))) {
- warnx("can't read filedesc at %p for pid %d", kp->ki_fd,
+ if (!kvm_read_all(kd, (unsigned long)kp->ki_pd, &pd, sizeof(pd))) {
+ warnx("can't read pwddesc at %p for pid %d", kp->ki_pd,
kp->ki_pid);
return (-1);
}
- *maskp = fd.fd_cmask;
+ *maskp = pd.pd_cmask;
return (0);
}
Modified: head/sys/compat/cloudabi/cloudabi_file.c
==============================================================================
--- head/sys/compat/cloudabi/cloudabi_file.c Tue Nov 17 20:01:21 2020 (r367776)
+++ head/sys/compat/cloudabi/cloudabi_file.c Tue Nov 17 21:14:13 2020 (r367777)
@@ -265,7 +265,7 @@ cloudabi_sys_file_open(struct thread *td,
}
NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path, uap->dirfd.fd,
&rights, td);
- error = vn_open(&nd, &fflags, 0777 & ~td->td_proc->p_fd->fd_cmask, fp);
+ error = vn_open(&nd, &fflags, 0777 & ~td->td_proc->p_pd->pd_cmask, fp);
cloudabi_freestr(path);
if (error != 0) {
/* Custom operations provided. */
Modified: head/sys/fs/fuse/fuse_internal.c
==============================================================================
--- head/sys/fs/fuse/fuse_internal.c Tue Nov 17 20:01:21 2020 (r367776)
+++ head/sys/fs/fuse/fuse_internal.c Tue Nov 17 21:14:13 2020 (r367777)
@@ -497,7 +497,7 @@ fuse_internal_mknod(struct vnode *dvp, struct vnode **
fmni.rdev = vap->va_rdev;
if (fuse_libabi_geq(data, 7, 12)) {
insize = sizeof(fmni);
- fmni.umask = curthread->td_proc->p_fd->fd_cmask;
+ fmni.umask = curthread->td_proc->p_pd->pd_cmask;
} else {
insize = FUSE_COMPAT_MKNOD_IN_SIZE;
}
Modified: head/sys/fs/fuse/fuse_vnops.c
==============================================================================
--- head/sys/fs/fuse/fuse_vnops.c Tue Nov 17 20:01:21 2020 (r367776)
+++ head/sys/fs/fuse/fuse_vnops.c Tue Nov 17 21:14:13 2020 (r367777)
@@ -668,7 +668,7 @@ fuse_vnop_create(struct vop_create_args *ap)
fci->flags = O_CREAT | flags;
if (fuse_libabi_geq(data, 7, 12)) {
insize = sizeof(*fci);
- fci->umask = td->td_proc->p_fd->fd_cmask;
+ fci->umask = td->td_proc->p_pd->pd_cmask;
} else {
insize = sizeof(struct fuse_open_in);
}
@@ -1269,7 +1269,7 @@ fuse_vnop_mkdir(struct vop_mkdir_args *ap)
return ENXIO;
}
fmdi.mode = MAKEIMODE(vap->va_type, vap->va_mode);
- fmdi.umask = curthread->td_proc->p_fd->fd_cmask;
+ fmdi.umask = curthread->td_proc->p_pd->pd_cmask;
return (fuse_internal_newentry(dvp, vpp, cnp, FUSE_MKDIR, &fmdi,
sizeof(fmdi), VDIR));
Modified: head/sys/fs/unionfs/union_subr.c
==============================================================================
--- head/sys/fs/unionfs/union_subr.c Tue Nov 17 20:01:21 2020 (r367776)
+++ head/sys/fs/unionfs/union_subr.c Tue Nov 17 21:14:13 2020 (r367777)
@@ -486,7 +486,7 @@ unionfs_create_uppervattr_core(struct unionfs_mount *u
}
break;
default: /* UNIONFS_TRADITIONAL */
- uva->va_mode = 0777 & ~td->td_proc->p_fd->fd_cmask;
+ uva->va_mode = 0777 & ~td->td_proc->p_pd->pd_cmask;
uva->va_uid = ump->um_uid;
uva->va_gid = ump->um_gid;
break;
Modified: head/sys/kern/imgact_elf.c
==============================================================================
--- head/sys/kern/imgact_elf.c Tue Nov 17 20:01:21 2020 (r367776)
+++ head/sys/kern/imgact_elf.c Tue Nov 17 21:14:13 2020 (r367777)
@@ -2507,12 +2507,12 @@ note_procstat_umask(void *arg, struct sbuf *sb, size_t
int structsize;
p = (struct proc *)arg;
- size = sizeof(structsize) + sizeof(p->p_fd->fd_cmask);
+ size = sizeof(structsize) + sizeof(p->p_pd->pd_cmask);
if (sb != NULL) {
KASSERT(*sizep == size, ("invalid size"));
- structsize = sizeof(p->p_fd->fd_cmask);
+ structsize = sizeof(p->p_pd->pd_cmask);
sbuf_bcat(sb, &structsize, sizeof(structsize));
- sbuf_bcat(sb, &p->p_fd->fd_cmask, sizeof(p->p_fd->fd_cmask));
+ sbuf_bcat(sb, &p->p_pd->pd_cmask, sizeof(p->p_pd->pd_cmask));
}
*sizep = size;
}
Modified: head/sys/kern/init_main.c
==============================================================================
--- head/sys/kern/init_main.c Tue Nov 17 20:01:21 2020 (r367776)
+++ head/sys/kern/init_main.c Tue Nov 17 21:14:13 2020 (r367777)
@@ -555,6 +555,7 @@ proc0_init(void *dummy __unused)
siginit(&proc0);
/* Create the file descriptor table. */
+ p->p_pd = pdinit(NULL, false);
p->p_fd = fdinit(NULL, false, NULL);
p->p_fdtol = NULL;
Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c Tue Nov 17 20:01:21 2020 (r367776)
+++ head/sys/kern/kern_descrip.c Tue Nov 17 21:14:13 2020 (r367777)
@@ -93,6 +93,7 @@ __FBSDID("$FreeBSD$");
static MALLOC_DEFINE(M_FILEDESC, "filedesc", "Open file descriptor table");
static MALLOC_DEFINE(M_PWD, "pwd", "Descriptor table vnodes");
+static MALLOC_DEFINE(M_PWDDESC, "pwddesc", "Pwd descriptors");
static MALLOC_DEFINE(M_FILEDESC_TO_LEADER, "filedesc_to_leader",
"file desc to leader structures");
static MALLOC_DEFINE(M_SIGIO, "sigio", "sigio structures");
@@ -2029,7 +2030,6 @@ finstall(struct thread *td, struct file *fp, int *fd,
/*
* Build a new filedesc structure from another.
- * Copy the current, root, and jail root vnode references.
*
* If fdp is not NULL, return with it shared locked.
*/
@@ -2038,7 +2038,6 @@ fdinit(struct filedesc *fdp, bool prepfiles, int *last
{
struct filedesc0 *newfdp0;
struct filedesc *newfdp;
- struct pwd *newpwd;
if (prepfiles)
MPASS(lastfile != NULL);
@@ -2052,20 +2051,14 @@ fdinit(struct filedesc *fdp, bool prepfiles, int *last
FILEDESC_LOCK_INIT(newfdp);
refcount_init(&newfdp->fd_refcnt, 1);
refcount_init(&newfdp->fd_holdcnt, 1);
- newfdp->fd_cmask = CMASK;
newfdp->fd_map = newfdp0->fd_dmap;
newfdp->fd_files = (struct fdescenttbl *)&newfdp0->fd_dfiles;
newfdp->fd_files->fdt_nfiles = NDFILE;
- if (fdp == NULL) {
- newpwd = pwd_alloc();
- smr_serialized_store(&newfdp->fd_pwd, newpwd, true);
+ if (fdp == NULL)
return (newfdp);
- }
FILEDESC_SLOCK(fdp);
- newpwd = pwd_hold_filedesc(fdp);
- smr_serialized_store(&newfdp->fd_pwd, newpwd, true);
if (!prepfiles) {
FILEDESC_SUNLOCK(fdp);
return (newfdp);
@@ -2083,6 +2076,38 @@ fdinit(struct filedesc *fdp, bool prepfiles, int *last
return (newfdp);
}
+/*
+ * Build a pwddesc structure from another.
+ * Copy the current, root, and jail root vnode references.
+ *
+ * If pdp is not NULL, return with it shared locked.
+ */
+struct pwddesc *
+pdinit(struct pwddesc *pdp, bool keeplock)
+{
+ struct pwddesc *newpdp;
+ struct pwd *newpwd;
+
+ newpdp = malloc(sizeof(*newpdp), M_PWDDESC, M_WAITOK | M_ZERO);
+
+ PWDDESC_LOCK_INIT(newpdp);
+ refcount_init(&newpdp->pd_refcount, 1);
+ newpdp->pd_cmask = CMASK;
+
+ if (pdp == NULL) {
+ newpwd = pwd_alloc();
+ smr_serialized_store(&newpdp->pd_pwd, newpwd, true);
+ return (newpdp);
+ }
+
+ PWDDESC_XLOCK(pdp);
+ newpwd = pwd_hold_pwddesc(pdp);
+ smr_serialized_store(&newpdp->pd_pwd, newpwd, true);
+ if (!keeplock)
+ PWDDESC_XUNLOCK(pdp);
+ return (newpdp);
+}
+
static struct filedesc *
fdhold(struct proc *p)
{
@@ -2095,6 +2120,18 @@ fdhold(struct proc *p)
return (fdp);
}
+static struct pwddesc *
+pdhold(struct proc *p)
+{
+ struct pwddesc *pdp;
+
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ pdp = p->p_pd;
+ if (pdp != NULL)
+ refcount_acquire(&pdp->pd_refcount);
+ return (pdp);
+}
+
static void
fddrop(struct filedesc *fdp)
{
@@ -2108,6 +2145,28 @@ fddrop(struct filedesc *fdp)
uma_zfree(filedesc0_zone, fdp);
}
+static void
+pddrop(struct pwddesc *pdp)
+{
+ struct pwd *pwd;
+
+ if (refcount_release_if_not_last(&pdp->pd_refcount))
+ return;
+
+ PWDDESC_XLOCK(pdp);
+ if (refcount_release(&pdp->pd_refcount) == 0) {
+ PWDDESC_XUNLOCK(pdp);
+ return;
+ }
+ pwd = PWDDESC_XLOCKED_LOAD_PWD(pdp);
+ pwd_set(pdp, NULL);
+ PWDDESC_XUNLOCK(pdp);
+ pwd_drop(pwd);
+
+ PWDDESC_LOCK_DESTROY(pdp);
+ free(pdp, M_PWDDESC);
+}
+
/*
* Share a filedesc structure.
*/
@@ -2120,6 +2179,16 @@ fdshare(struct filedesc *fdp)
}
/*
+ * Share a pwddesc structure.
+ */
+struct pwddesc *
+pdshare(struct pwddesc *pdp)
+{
+ refcount_acquire(&pdp->pd_refcount);
+ return (pdp);
+}
+
+/*
* Unshare a filedesc structure, if necessary by making a copy
*/
void
@@ -2136,7 +2205,26 @@ fdunshare(struct thread *td)
p->p_fd = tmp;
}
+/*
+ * Unshare a pwddesc structure.
+ */
void
+pdunshare(struct thread *td)
+{
+ struct pwddesc *pdp;
+ struct proc *p;
+
+ p = td->td_proc;
+ /* Not shared. */
+ if (p->p_pd->pd_refcount == 1)
+ return;
+
+ pdp = pdcopy(p->p_pd);
+ pdescfree(td);
+ p->p_pd = pdp;
+}
+
+void
fdinstall_remapped(struct thread *td, struct filedesc *fdp)
{
@@ -2176,12 +2264,27 @@ fdcopy(struct filedesc *fdp)
}
if (newfdp->fd_freefile == -1)
newfdp->fd_freefile = i;
- newfdp->fd_cmask = fdp->fd_cmask;
FILEDESC_SUNLOCK(fdp);
return (newfdp);
}
/*
+ * Copy a pwddesc structure.
+ */
+struct pwddesc *
+pdcopy(struct pwddesc *pdp)
+{
+ struct pwddesc *newpdp;
+
+ MPASS(pdp != NULL);
+
+ newpdp = pdinit(pdp, true);
+ newpdp->pd_cmask = pdp->pd_cmask;
+ PWDDESC_XUNLOCK(pdp);
+ return (newpdp);
+}
+
+/*
* Copies a filedesc structure, while remapping all file descriptors
* stored inside using a translation table.
*
@@ -2232,7 +2335,6 @@ fdcopy_remapped(struct filedesc *fdp, const int *fds,
filecaps_copy(&ofde->fde_caps, &nfde->fde_caps, true);
fdused_init(newfdp, i);
}
- newfdp->fd_cmask = fdp->fd_cmask;
FILEDESC_SUNLOCK(fdp);
*ret = newfdp;
return (0);
@@ -2366,7 +2468,6 @@ fdescfree(struct thread *td)
{
struct proc *p;
struct filedesc *fdp;
- struct pwd *pwd;
p = td->td_proc;
fdp = p->p_fd;
@@ -2387,21 +2488,29 @@ fdescfree(struct thread *td)
if (refcount_release(&fdp->fd_refcnt) == 0)
return;
- FILEDESC_XLOCK(fdp);
- pwd = FILEDESC_XLOCKED_LOAD_PWD(fdp);
- pwd_set(fdp, NULL);
- FILEDESC_XUNLOCK(fdp);
+ fdescfree_fds(td, fdp, 1);
+}
- pwd_drop(pwd);
+void
+pdescfree(struct thread *td)
+{
+ struct proc *p;
+ struct pwddesc *pdp;
- fdescfree_fds(td, fdp, 1);
+ p = td->td_proc;
+ pdp = p->p_pd;
+ MPASS(pdp != NULL);
+
+ PROC_LOCK(p);
+ p->p_pd = NULL;
+ PROC_UNLOCK(p);
+
+ pddrop(pdp);
}
void
fdescfree_remapped(struct filedesc *fdp)
{
-
- pwd_drop(smr_serialized_load(&fdp->fd_pwd, true));
fdescfree_fds(curthread, fdp, 0);
}
@@ -3452,12 +3561,12 @@ pwd_fill(struct pwd *oldpwd, struct pwd *newpwd)
}
struct pwd *
-pwd_hold_filedesc(struct filedesc *fdp)
+pwd_hold_pwddesc(struct pwddesc *pdp)
{
struct pwd *pwd;
- FILEDESC_LOCK_ASSERT(fdp);
- pwd = FILEDESC_LOCKED_LOAD_PWD(fdp);
+ PWDDESC_ASSERT_XLOCKED(pdp);
+ pwd = PWDDESC_XLOCKED_LOAD_PWD(pdp);
if (pwd != NULL)
refcount_acquire(&pwd->pwd_refcount);
return (pwd);
@@ -3477,22 +3586,22 @@ pwd_hold_smr(struct pwd *pwd)
struct pwd *
pwd_hold(struct thread *td)
{
- struct filedesc *fdp;
+ struct pwddesc *pdp;
struct pwd *pwd;
- fdp = td->td_proc->p_fd;
+ pdp = td->td_proc->p_pd;
vfs_smr_enter();
- pwd = vfs_smr_entered_load(&fdp->fd_pwd);
+ pwd = vfs_smr_entered_load(&pdp->pd_pwd);
if (pwd_hold_smr(pwd)) {
vfs_smr_exit();
return (pwd);
}
vfs_smr_exit();
- FILEDESC_SLOCK(fdp);
- pwd = pwd_hold_filedesc(fdp);
+ PWDDESC_XLOCK(pdp);
+ pwd = pwd_hold_pwddesc(pdp);
MPASS(pwd != NULL);
- FILEDESC_SUNLOCK(fdp);
+ PWDDESC_XUNLOCK(pdp);
return (pwd);
}
@@ -3501,7 +3610,7 @@ pwd_get_smr(void)
{
struct pwd *pwd;
- pwd = vfs_smr_entered_load(&curproc->p_fd->fd_pwd);
+ pwd = vfs_smr_entered_load(&curproc->p_pd->pd_pwd);
MPASS(pwd != NULL);
return (pwd);
}
@@ -3541,23 +3650,29 @@ pwd_drop(struct pwd *pwd)
int
pwd_chroot(struct thread *td, struct vnode *vp)
{
+ struct pwddesc *pdp;
struct filedesc *fdp;
struct pwd *newpwd, *oldpwd;
int error;
fdp = td->td_proc->p_fd;
+ pdp = td->td_proc->p_pd;
newpwd = pwd_alloc();
- FILEDESC_XLOCK(fdp);
- oldpwd = FILEDESC_XLOCKED_LOAD_PWD(fdp);
+ FILEDESC_SLOCK(fdp);
+ PWDDESC_XLOCK(pdp);
+ oldpwd = PWDDESC_XLOCKED_LOAD_PWD(pdp);
if (chroot_allow_open_directories == 0 ||
(chroot_allow_open_directories == 1 &&
oldpwd->pwd_rdir != rootvnode)) {
error = chroot_refuse_vdir_fds(fdp);
+ FILEDESC_SUNLOCK(fdp);
if (error != 0) {
- FILEDESC_XUNLOCK(fdp);
+ PWDDESC_XUNLOCK(pdp);
pwd_drop(newpwd);
return (error);
}
+ } else {
+ FILEDESC_SUNLOCK(fdp);
}
vrefact(vp);
@@ -3567,8 +3682,8 @@ pwd_chroot(struct thread *td, struct vnode *vp)
newpwd->pwd_jdir = vp;
}
pwd_fill(oldpwd, newpwd);
- pwd_set(fdp, newpwd);
- FILEDESC_XUNLOCK(fdp);
+ pwd_set(pdp, newpwd);
+ PWDDESC_XUNLOCK(pdp);
pwd_drop(oldpwd);
return (0);
}
@@ -3576,40 +3691,40 @@ pwd_chroot(struct thread *td, struct vnode *vp)
void
pwd_chdir(struct thread *td, struct vnode *vp)
{
- struct filedesc *fdp;
+ struct pwddesc *pdp;
struct pwd *newpwd, *oldpwd;
VNPASS(vp->v_usecount > 0, vp);
newpwd = pwd_alloc();
- fdp = td->td_proc->p_fd;
- FILEDESC_XLOCK(fdp);
- oldpwd = FILEDESC_XLOCKED_LOAD_PWD(fdp);
+ pdp = td->td_proc->p_pd;
+ PWDDESC_XLOCK(pdp);
+ oldpwd = PWDDESC_XLOCKED_LOAD_PWD(pdp);
newpwd->pwd_cdir = vp;
pwd_fill(oldpwd, newpwd);
- pwd_set(fdp, newpwd);
- FILEDESC_XUNLOCK(fdp);
+ pwd_set(pdp, newpwd);
+ PWDDESC_XUNLOCK(pdp);
pwd_drop(oldpwd);
}
void
pwd_ensure_dirs(void)
{
- struct filedesc *fdp;
+ struct pwddesc *pdp;
struct pwd *oldpwd, *newpwd;
- fdp = curproc->p_fd;
- FILEDESC_XLOCK(fdp);
- oldpwd = FILEDESC_XLOCKED_LOAD_PWD(fdp);
+ pdp = curproc->p_pd;
+ PWDDESC_XLOCK(pdp);
+ oldpwd = PWDDESC_XLOCKED_LOAD_PWD(pdp);
if (oldpwd->pwd_cdir != NULL && oldpwd->pwd_rdir != NULL) {
- FILEDESC_XUNLOCK(fdp);
+ PWDDESC_XUNLOCK(pdp);
return;
}
- FILEDESC_XUNLOCK(fdp);
+ PWDDESC_XUNLOCK(pdp);
newpwd = pwd_alloc();
- FILEDESC_XLOCK(fdp);
- oldpwd = FILEDESC_XLOCKED_LOAD_PWD(fdp);
+ PWDDESC_XLOCK(pdp);
+ oldpwd = PWDDESC_XLOCKED_LOAD_PWD(pdp);
pwd_fill(oldpwd, newpwd);
if (newpwd->pwd_cdir == NULL) {
vrefact(rootvnode);
@@ -3619,29 +3734,29 @@ pwd_ensure_dirs(void)
vrefact(rootvnode);
newpwd->pwd_rdir = rootvnode;
}
- pwd_set(fdp, newpwd);
- FILEDESC_XUNLOCK(fdp);
+ pwd_set(pdp, newpwd);
+ PWDDESC_XUNLOCK(pdp);
pwd_drop(oldpwd);
}
void
pwd_set_rootvnode(void)
{
- struct filedesc *fdp;
+ struct pwddesc *pdp;
struct pwd *oldpwd, *newpwd;
- fdp = curproc->p_fd;
+ pdp = curproc->p_pd;
newpwd = pwd_alloc();
- FILEDESC_XLOCK(fdp);
- oldpwd = FILEDESC_XLOCKED_LOAD_PWD(fdp);
+ PWDDESC_XLOCK(pdp);
+ oldpwd = PWDDESC_XLOCKED_LOAD_PWD(pdp);
vrefact(rootvnode);
newpwd->pwd_cdir = rootvnode;
vrefact(rootvnode);
newpwd->pwd_rdir = rootvnode;
pwd_fill(oldpwd, newpwd);
- pwd_set(fdp, newpwd);
- FILEDESC_XUNLOCK(fdp);
+ pwd_set(pdp, newpwd);
+ PWDDESC_XUNLOCK(pdp);
pwd_drop(oldpwd);
}
@@ -3652,7 +3767,7 @@ pwd_set_rootvnode(void)
void
mountcheckdirs(struct vnode *olddp, struct vnode *newdp)
{
- struct filedesc *fdp;
+ struct pwddesc *pdp;
struct pwd *newpwd, *oldpwd;
struct prison *pr;
struct proc *p;
@@ -3665,18 +3780,18 @@ mountcheckdirs(struct vnode *olddp, struct vnode *newd
sx_slock(&allproc_lock);
FOREACH_PROC_IN_SYSTEM(p) {
PROC_LOCK(p);
- fdp = fdhold(p);
+ pdp = pdhold(p);
PROC_UNLOCK(p);
- if (fdp == NULL)
+ if (pdp == NULL)
continue;
- FILEDESC_XLOCK(fdp);
- oldpwd = FILEDESC_XLOCKED_LOAD_PWD(fdp);
+ PWDDESC_XLOCK(pdp);
+ oldpwd = PWDDESC_XLOCKED_LOAD_PWD(pdp);
if (oldpwd == NULL ||
(oldpwd->pwd_cdir != olddp &&
oldpwd->pwd_rdir != olddp &&
oldpwd->pwd_jdir != olddp)) {
- FILEDESC_XUNLOCK(fdp);
- fddrop(fdp);
+ PWDDESC_XUNLOCK(pdp);
+ pddrop(pdp);
continue;
}
if (oldpwd->pwd_cdir == olddp) {
@@ -3692,10 +3807,10 @@ mountcheckdirs(struct vnode *olddp, struct vnode *newd
newpwd->pwd_jdir = newdp;
}
pwd_fill(oldpwd, newpwd);
- pwd_set(fdp, newpwd);
- FILEDESC_XUNLOCK(fdp);
+ pwd_set(pdp, newpwd);
+ PWDDESC_XUNLOCK(pdp);
pwd_drop(oldpwd);
- fddrop(fdp);
+ pddrop(pdp);
newpwd = pwd_alloc();
}
sx_sunlock(&allproc_lock);
@@ -3968,6 +4083,7 @@ export_vnode_to_kinfo(struct vnode *vp, int fd, int ff
struct export_fd_buf {
struct filedesc *fdp;
+ struct pwddesc *pdp;
struct sbuf *sb;
ssize_t remainder;
struct kinfo_file kif;
@@ -4015,12 +4131,12 @@ export_vnode_to_sb(struct vnode *vp, int fd, int fflag
if (efbuf->remainder == 0)
return (0);
- if (efbuf->fdp != NULL)
- FILEDESC_SUNLOCK(efbuf->fdp);
+ if (efbuf->pdp != NULL)
+ PWDDESC_XUNLOCK(efbuf->pdp);
export_vnode_to_kinfo(vp, fd, fflags, &efbuf->kif, efbuf->flags);
error = export_kinfo_to_sb(efbuf);
- if (efbuf->fdp != NULL)
- FILEDESC_SLOCK(efbuf->fdp);
+ if (efbuf->pdp != NULL)
+ PWDDESC_XLOCK(efbuf->pdp);
return (error);
}
@@ -4035,6 +4151,7 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *s
{
struct file *fp;
struct filedesc *fdp;
+ struct pwddesc *pdp;
struct export_fd_buf *efbuf;
struct vnode *cttyvp, *textvp, *tracevp;
struct pwd *pwd;
@@ -4059,9 +4176,11 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *s
vrefact(cttyvp);
}
fdp = fdhold(p);
+ pdp = pdhold(p);
PROC_UNLOCK(p);
efbuf = malloc(sizeof(*efbuf), M_TEMP, M_WAITOK);
efbuf->fdp = NULL;
+ efbuf->pdp = NULL;
efbuf->sb = sb;
efbuf->remainder = maxlen;
efbuf->flags = flags;
@@ -4074,11 +4193,12 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *s
export_vnode_to_sb(cttyvp, KF_FD_TYPE_CTTY, FREAD | FWRITE,
efbuf);
error = 0;
- if (fdp == NULL)
+ if (pdp == NULL || fdp == NULL)
goto fail;
efbuf->fdp = fdp;
- FILEDESC_SLOCK(fdp);
- pwd = pwd_hold_filedesc(fdp);
+ efbuf->pdp = pdp;
+ PWDDESC_XLOCK(pdp);
+ pwd = pwd_hold_pwddesc(pdp);
if (pwd != NULL) {
/* working directory */
if (pwd->pwd_cdir != NULL) {
@@ -4096,6 +4216,10 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *s
export_vnode_to_sb(pwd->pwd_jdir, KF_FD_TYPE_JAIL, FREAD, efbuf);
}
}
+ PWDDESC_XUNLOCK(pdp);
+ if (pwd != NULL)
+ pwd_drop(pwd);
+ FILEDESC_SLOCK(fdp);
lastfile = fdlastfile(fdp);
for (i = 0; fdp->fd_refcnt > 0 && i <= lastfile; i++) {
if ((fp = fdp->fd_ofiles[i].fde_file) == NULL)
@@ -4116,10 +4240,11 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *s
break;
}
FILEDESC_SUNLOCK(fdp);
- if (pwd != NULL)
- pwd_drop(pwd);
- fddrop(fdp);
fail:
+ if (fdp != NULL)
+ fddrop(fdp);
+ if (pdp != NULL)
+ pddrop(pdp);
free(efbuf, M_TEMP);
return (error);
}
@@ -4190,16 +4315,16 @@ kinfo_to_okinfo(struct kinfo_file *kif, struct kinfo_o
static int
export_vnode_for_osysctl(struct vnode *vp, int type, struct kinfo_file *kif,
- struct kinfo_ofile *okif, struct filedesc *fdp, struct sysctl_req *req)
+ struct kinfo_ofile *okif, struct pwddesc *pdp, struct sysctl_req *req)
{
int error;
vrefact(vp);
- FILEDESC_SUNLOCK(fdp);
+ PWDDESC_XUNLOCK(pdp);
export_vnode_to_kinfo(vp, type, 0, kif, KERN_FILEDESC_PACK_KINFO);
kinfo_to_okinfo(kif, okif);
error = SYSCTL_OUT(req, okif, sizeof(*okif));
- FILEDESC_SLOCK(fdp);
+ PWDDESC_XLOCK(pdp);
return (error);
}
@@ -4212,6 +4337,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS)
struct kinfo_ofile *okif;
struct kinfo_file *kif;
struct filedesc *fdp;
+ struct pwddesc *pdp;
struct pwd *pwd;
int error, i, lastfile, *name;
struct file *fp;
@@ -4222,24 +4348,33 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS)
if (error != 0)
return (error);
fdp = fdhold(p);
+ if (fdp != NULL)
+ pdp = pdhold(p);
PROC_UNLOCK(p);
- if (fdp == NULL)
+ if (fdp == NULL || pdp == NULL) {
+ if (fdp != NULL)
+ fddrop(fdp);
return (ENOENT);
+ }
kif = malloc(sizeof(*kif), M_TEMP, M_WAITOK);
okif = malloc(sizeof(*okif), M_TEMP, M_WAITOK);
- FILEDESC_SLOCK(fdp);
- pwd = pwd_hold_filedesc(fdp);
+ PWDDESC_XLOCK(pdp);
+ pwd = pwd_hold_pwddesc(pdp);
if (pwd != NULL) {
if (pwd->pwd_cdir != NULL)
export_vnode_for_osysctl(pwd->pwd_cdir, KF_FD_TYPE_CWD, kif,
- okif, fdp, req);
+ okif, pdp, req);
if (pwd->pwd_rdir != NULL)
export_vnode_for_osysctl(pwd->pwd_rdir, KF_FD_TYPE_ROOT, kif,
- okif, fdp, req);
+ okif, pdp, req);
if (pwd->pwd_jdir != NULL)
export_vnode_for_osysctl(pwd->pwd_jdir, KF_FD_TYPE_JAIL, kif,
- okif, fdp, req);
+ okif, pdp, req);
}
+ PWDDESC_XUNLOCK(pdp);
+ if (pwd != NULL)
+ pwd_drop(pwd);
+ FILEDESC_SLOCK(fdp);
lastfile = fdlastfile(fdp);
for (i = 0; fdp->fd_refcnt > 0 && i <= lastfile; i++) {
if ((fp = fdp->fd_ofiles[i].fde_file) == NULL)
@@ -4254,9 +4389,8 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS)
break;
}
FILEDESC_SUNLOCK(fdp);
- if (pwd != NULL)
- pwd_drop(pwd);
fddrop(fdp);
+ pddrop(pdp);
free(kif, M_TEMP);
free(okif, M_TEMP);
return (0);
@@ -4308,7 +4442,7 @@ static SYSCTL_NODE(_kern_proc, KERN_PROC_FILEDESC, fil
int
kern_proc_cwd_out(struct proc *p, struct sbuf *sb, ssize_t maxlen)
{
- struct filedesc *fdp;
+ struct pwddesc *pdp;
struct pwd *pwd;
struct export_fd_buf *efbuf;
struct vnode *cdir;
@@ -4316,18 +4450,18 @@ kern_proc_cwd_out(struct proc *p, struct sbuf *sb, ss
PROC_LOCK_ASSERT(p, MA_OWNED);
- fdp = fdhold(p);
+ pdp = pdhold(p);
PROC_UNLOCK(p);
- if (fdp == NULL)
+ if (pdp == NULL)
return (EINVAL);
efbuf = malloc(sizeof(*efbuf), M_TEMP, M_WAITOK);
- efbuf->fdp = fdp;
+ efbuf->pdp = pdp;
efbuf->sb = sb;
efbuf->remainder = maxlen;
- FILEDESC_SLOCK(fdp);
- pwd = FILEDESC_LOCKED_LOAD_PWD(fdp);
+ PWDDESC_XLOCK(pdp);
+ pwd = PWDDESC_XLOCKED_LOAD_PWD(pdp);
cdir = pwd->pwd_cdir;
if (cdir == NULL) {
error = EINVAL;
@@ -4335,8 +4469,8 @@ kern_proc_cwd_out(struct proc *p, struct sbuf *sb, ss
vrefact(cdir);
error = export_vnode_to_sb(cdir, KF_FD_TYPE_CWD, FREAD, efbuf);
}
- FILEDESC_SUNLOCK(fdp);
- fddrop(fdp);
+ PWDDESC_XUNLOCK(pdp);
+ pddrop(pdp);
free(efbuf, M_TEMP);
return (error);
}
Modified: head/sys/kern/kern_exec.c
==============================================================================
--- head/sys/kern/kern_exec.c Tue Nov 17 20:01:21 2020 (r367776)
+++ head/sys/kern/kern_exec.c Tue Nov 17 21:14:13 2020 (r367777)
@@ -700,6 +700,7 @@ interpret:
* cannot be shared after an exec.
*/
fdunshare(td);
+ pdunshare(td);
/* close files on exec */
fdcloseexec(td);
}
Modified: head/sys/kern/kern_exit.c
==============================================================================
--- head/sys/kern/kern_exit.c Tue Nov 17 20:01:21 2020 (r367776)
+++ head/sys/kern/kern_exit.c Tue Nov 17 21:14:13 2020 (r367777)
@@ -367,6 +367,7 @@ exit1(struct thread *td, int rval, int signo)
* Close open files and release open-file table.
* This may block!
*/
+ pdescfree(td);
fdescfree(td);
/*
Modified: head/sys/kern/kern_fork.c
==============================================================================
--- head/sys/kern/kern_fork.c Tue Nov 17 20:01:21 2020 (r367776)
+++ head/sys/kern/kern_fork.c Tue Nov 17 21:14:13 2020 (r367777)
@@ -332,16 +332,22 @@ fork_norfproc(struct thread *td, int flags)
*/
if (flags & RFCFDG) {
struct filedesc *fdtmp;
+ struct pwddesc *pdtmp;
+ pdtmp = pdinit(td->td_proc->p_pd, false);
fdtmp = fdinit(td->td_proc->p_fd, false, NULL);
+ pdescfree(td);
fdescfree(td);
p1->p_fd = fdtmp;
+ p1->p_pd = pdtmp;
}
/*
* Unshare file descriptors (from parent).
*/
- if (flags & RFFDG)
+ if (flags & RFFDG) {
fdunshare(td);
+ pdunshare(td);
+ }
fail:
if (((p1->p_flag & (P_HADTHREADS|P_SYSTEM)) == P_HADTHREADS) &&
@@ -360,6 +366,7 @@ do_fork(struct thread *td, struct fork_req *fr, struct
struct proc *p1, *pptr;
struct filedesc *fd;
struct filedesc_to_leader *fdtol;
+ struct pwddesc *pd;
struct sigacts *newsigacts;
p1 = td->td_proc;
@@ -403,12 +410,15 @@ do_fork(struct thread *td, struct fork_req *fr, struct
* Copy filedesc.
*/
if (fr->fr_flags & RFCFDG) {
+ pd = pdinit(p1->p_pd, false);
fd = fdinit(p1->p_fd, false, NULL);
fdtol = NULL;
} else if (fr->fr_flags & RFFDG) {
+ pd = pdcopy(p1->p_pd);
fd = fdcopy(p1->p_fd);
fdtol = NULL;
} else {
+ pd = pdshare(p1->p_pd);
fd = fdshare(p1->p_fd);
if (p1->p_fdtol == NULL)
p1->p_fdtol = filedesc_to_leader_alloc(NULL, NULL,
@@ -498,6 +508,7 @@ do_fork(struct thread *td, struct fork_req *fr, struct
p2->p_textvp = p1->p_textvp;
p2->p_fd = fd;
p2->p_fdtol = fdtol;
+ p2->p_pd = pd;
if (p1->p_flag2 & P2_INHERIT_PROTECTED) {
p2->p_flag |= P_PROTECTED;
Modified: head/sys/kern/kern_proc.c
==============================================================================
--- head/sys/kern/kern_proc.c Tue Nov 17 20:01:21 2020 (r367776)
+++ head/sys/kern/kern_proc.c Tue Nov 17 21:14:13 2020 (r367777)
@@ -1144,6 +1144,7 @@ fill_kinfo_proc_only(struct proc *p, struct kinfo_proc
kp->ki_traceflag = p->p_traceflag;
#endif
kp->ki_fd = p->p_fd;
+ kp->ki_pd = p->p_pd;
kp->ki_vmspace = p->p_vmspace;
kp->ki_flag = p->p_flag;
kp->ki_flag2 = p->p_flag2;
@@ -2967,7 +2968,7 @@ sysctl_kern_proc_umask(SYSCTL_HANDLER_ARGS)
u_int namelen = arg2;
struct proc *p;
int error;
- u_short fd_cmask;
+ u_short cmask;
pid_t pid;
if (namelen != 1)
@@ -2976,7 +2977,7 @@ sysctl_kern_proc_umask(SYSCTL_HANDLER_ARGS)
pid = (pid_t)name[0];
p = curproc;
if (pid == p->p_pid || pid == 0) {
- fd_cmask = p->p_fd->fd_cmask;
+ cmask = p->p_pd->pd_cmask;
goto out;
}
@@ -2984,10 +2985,10 @@ sysctl_kern_proc_umask(SYSCTL_HANDLER_ARGS)
if (error != 0)
return (error);
- fd_cmask = p->p_fd->fd_cmask;
+ cmask = p->p_pd->pd_cmask;
PRELE(p);
out:
- error = SYSCTL_OUT(req, &fd_cmask, sizeof(fd_cmask));
+ error = SYSCTL_OUT(req, &cmask, sizeof(cmask));
return (error);
}
Modified: head/sys/kern/kern_thread.c
==============================================================================
--- head/sys/kern/kern_thread.c Tue Nov 17 20:01:21 2020 (r367776)
+++ head/sys/kern/kern_thread.c Tue Nov 17 21:14:13 2020 (r367777)
@@ -88,15 +88,15 @@ _Static_assert(offsetof(struct thread, td_frame) == 0x
"struct thread KBI td_frame");
_Static_assert(offsetof(struct thread, td_emuldata) == 0x6b0,
"struct thread KBI td_emuldata");
-_Static_assert(offsetof(struct proc, p_flag) == 0xb0,
+_Static_assert(offsetof(struct proc, p_flag) == 0xb8,
"struct proc KBI p_flag");
-_Static_assert(offsetof(struct proc, p_pid) == 0xbc,
+_Static_assert(offsetof(struct proc, p_pid) == 0xc4,
"struct proc KBI p_pid");
-_Static_assert(offsetof(struct proc, p_filemon) == 0x3b8,
+_Static_assert(offsetof(struct proc, p_filemon) == 0x3c0,
"struct proc KBI p_filemon");
-_Static_assert(offsetof(struct proc, p_comm) == 0x3d0,
+_Static_assert(offsetof(struct proc, p_comm) == 0x3d8,
"struct proc KBI p_comm");
-_Static_assert(offsetof(struct proc, p_emuldata) == 0x4b0,
+_Static_assert(offsetof(struct proc, p_emuldata) == 0x4b8,
"struct proc KBI p_emuldata");
#endif
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list