Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151185022
D27037.id79142.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
36 KB
Referenced Files
None
Subscribers
None
D27037.id79142.diff
View Options
Index: lib/libkvm/kvm_proc.c
===================================================================
--- lib/libkvm/kvm_proc.c
+++ lib/libkvm/kvm_proc.c
@@ -221,6 +221,7 @@
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)) {
Index: lib/libprocstat/libprocstat.c
===================================================================
--- lib/libprocstat/libprocstat.c
+++ lib/libprocstat/libprocstat.c
@@ -460,6 +460,7 @@
{
struct file file;
struct filedesc filed;
+ struct pwddesc pathsd;
struct fdescenttbl *fdt;
struct pwd pwd;
unsigned long pwd_addr;
@@ -484,15 +485,20 @@
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 @@
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);
}
Index: sys/compat/cloudabi/cloudabi_file.c
===================================================================
--- sys/compat/cloudabi/cloudabi_file.c
+++ sys/compat/cloudabi/cloudabi_file.c
@@ -265,7 +265,7 @@
}
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. */
Index: sys/fs/fuse/fuse_internal.c
===================================================================
--- sys/fs/fuse/fuse_internal.c
+++ sys/fs/fuse/fuse_internal.c
@@ -497,7 +497,7 @@
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;
}
Index: sys/fs/fuse/fuse_vnops.c
===================================================================
--- sys/fs/fuse/fuse_vnops.c
+++ sys/fs/fuse/fuse_vnops.c
@@ -668,7 +668,7 @@
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 @@
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));
Index: sys/fs/unionfs/union_subr.c
===================================================================
--- sys/fs/unionfs/union_subr.c
+++ sys/fs/unionfs/union_subr.c
@@ -486,7 +486,7 @@
}
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;
Index: sys/kern/imgact_elf.c
===================================================================
--- sys/kern/imgact_elf.c
+++ sys/kern/imgact_elf.c
@@ -2507,12 +2507,12 @@
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;
}
Index: sys/kern/init_main.c
===================================================================
--- sys/kern/init_main.c
+++ sys/kern/init_main.c
@@ -556,6 +556,7 @@
siginit(&proc0);
/* Create the file descriptor table. */
+ p->p_pd = pdinit(NULL, false);
p->p_fd = fdinit(NULL, false, NULL);
p->p_fdtol = NULL;
Index: sys/kern/kern_descrip.c
===================================================================
--- sys/kern/kern_descrip.c
+++ sys/kern/kern_descrip.c
@@ -102,6 +102,7 @@
static __read_mostly uma_zone_t file_zone;
static __read_mostly uma_zone_t filedesc0_zone;
+static __read_mostly uma_zone_t pwddesc_zone;
__read_mostly uma_zone_t pwd_zone;
VFS_SMR_DECLARE;
@@ -2019,7 +2020,6 @@
/*
* 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.
*/
@@ -2028,7 +2028,6 @@
{
struct filedesc0 *newfdp0;
struct filedesc *newfdp;
- struct pwd *newpwd;
if (prepfiles)
MPASS(lastfile != NULL);
@@ -2042,20 +2041,14 @@
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);
@@ -2073,6 +2066,38 @@
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 = uma_zalloc(pwddesc_zone, 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_SLOCK(pdp);
+ newpwd = pwd_hold_pwddesc(pdp);
+ smr_serialized_store(&newpdp->pd_pwd, newpwd, true);
+ if (!keeplock)
+ PWDDESC_SUNLOCK(pdp);
+ return (newpdp);
+}
+
static struct filedesc *
fdhold(struct proc *p)
{
@@ -2085,6 +2110,18 @@
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)
{
@@ -2098,6 +2135,28 @@
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);
+ uma_zfree(pwddesc_zone, pdp);
+}
+
/*
* Share a filedesc structure.
*/
@@ -2109,6 +2168,16 @@
return (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
*/
@@ -2126,6 +2195,25 @@
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)
{
@@ -2166,11 +2254,26 @@
}
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_SUNLOCK(pdp);
+ return (newpdp);
+}
+
/*
* Copies a filedesc structure, while remapping all file descriptors
* stored inside using a translation table.
@@ -2222,7 +2325,6 @@
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);
@@ -2356,7 +2458,6 @@
{
struct proc *p;
struct filedesc *fdp;
- struct pwd *pwd;
p = td->td_proc;
fdp = p->p_fd;
@@ -2377,21 +2478,29 @@
if (refcount_release(&fdp->fd_refcnt) == 0)
return;
- FILEDESC_XLOCK(fdp);
- pwd = FILEDESC_XLOCKED_LOAD_PWD(fdp);
- pwd_set(fdp, NULL);
- FILEDESC_XUNLOCK(fdp);
-
- pwd_drop(pwd);
-
fdescfree_fds(td, fdp, 1);
}
+void
+pdescfree(struct thread *td)
+{
+ struct proc *p;
+ struct pwddesc *pdp;
+
+ 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);
}
@@ -3438,12 +3547,12 @@
}
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_LOCKED(pdp);
+ pwd = PWDDESC_LOCKED_LOAD_PWD(pdp);
if (pwd != NULL)
refcount_acquire(&pwd->pwd_refcount);
return (pwd);
@@ -3463,22 +3572,22 @@
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_SLOCK(pdp);
+ pwd = pwd_hold_pwddesc(pdp);
MPASS(pwd != NULL);
- FILEDESC_SUNLOCK(fdp);
+ PWDDESC_SUNLOCK(pdp);
return (pwd);
}
@@ -3487,7 +3596,7 @@
{
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);
}
@@ -3527,23 +3636,29 @@
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);
@@ -3553,8 +3668,8 @@
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);
}
@@ -3562,40 +3677,40 @@
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);
@@ -3605,29 +3720,29 @@
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);
}
@@ -3638,7 +3753,7 @@
void
mountcheckdirs(struct vnode *olddp, struct vnode *newdp)
{
- struct filedesc *fdp;
+ struct pwddesc *pdp;
struct pwd *newpwd, *oldpwd;
struct prison *pr;
struct proc *p;
@@ -3651,18 +3766,18 @@
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) {
@@ -3678,10 +3793,10 @@
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);
@@ -3954,6 +4069,7 @@
struct export_fd_buf {
struct filedesc *fdp;
+ struct pwddesc *pdp;
struct sbuf *sb;
ssize_t remainder;
struct kinfo_file kif;
@@ -4001,12 +4117,12 @@
if (efbuf->remainder == 0)
return (0);
- if (efbuf->fdp != NULL)
- FILEDESC_SUNLOCK(efbuf->fdp);
+ if (efbuf->pdp != NULL)
+ PWDDESC_SUNLOCK(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_SLOCK(efbuf->pdp);
return (error);
}
@@ -4021,6 +4137,7 @@
{
struct file *fp;
struct filedesc *fdp;
+ struct pwddesc *pdp;
struct export_fd_buf *efbuf;
struct vnode *cttyvp, *textvp, *tracevp;
struct pwd *pwd;
@@ -4045,9 +4162,11 @@
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;
@@ -4060,11 +4179,12 @@
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_SLOCK(pdp);
+ pwd = pwd_hold_pwddesc(pdp);
if (pwd != NULL) {
/* working directory */
if (pwd->pwd_cdir != NULL) {
@@ -4082,6 +4202,10 @@
export_vnode_to_sb(pwd->pwd_jdir, KF_FD_TYPE_JAIL, FREAD, efbuf);
}
}
+ PWDDESC_SUNLOCK(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)
@@ -4102,10 +4226,11 @@
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);
}
@@ -4176,16 +4301,16 @@
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_SUNLOCK(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_SLOCK(pdp);
return (error);
}
@@ -4198,6 +4323,7 @@
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;
@@ -4208,24 +4334,33 @@
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_SLOCK(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_SUNLOCK(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)
@@ -4240,9 +4375,8 @@
break;
}
FILEDESC_SUNLOCK(fdp);
- if (pwd != NULL)
- pwd_drop(pwd);
fddrop(fdp);
+ pddrop(pdp);
free(kif, M_TEMP);
free(okif, M_TEMP);
return (0);
@@ -4294,7 +4428,7 @@
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;
@@ -4302,18 +4436,18 @@
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_SLOCK(pdp);
+ pwd = PWDDESC_LOCKED_LOAD_PWD(pdp);
cdir = pwd->pwd_cdir;
if (cdir == NULL) {
error = EINVAL;
@@ -4321,8 +4455,8 @@
vrefact(cdir);
error = export_vnode_to_sb(cdir, KF_FD_TYPE_CWD, FREAD, efbuf);
}
- FILEDESC_SUNLOCK(fdp);
- fddrop(fdp);
+ PWDDESC_SUNLOCK(pdp);
+ pddrop(pdp);
free(efbuf, M_TEMP);
return (error);
}
@@ -4502,6 +4636,8 @@
NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
filedesc0_zone = uma_zcreate("filedesc0", sizeof(struct filedesc0),
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
+ pwddesc_zone = uma_zcreate("pwddesc", sizeof(struct pwddesc),
+ NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
pwd_zone = uma_zcreate("PWD", sizeof(struct pwd), NULL, NULL,
NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_SMR);
/*
Index: sys/kern/kern_exec.c
===================================================================
--- sys/kern/kern_exec.c
+++ sys/kern/kern_exec.c
@@ -700,6 +700,7 @@
* cannot be shared after an exec.
*/
fdunshare(td);
+ pdunshare(td);
/* close files on exec */
fdcloseexec(td);
}
Index: sys/kern/kern_exit.c
===================================================================
--- sys/kern/kern_exit.c
+++ sys/kern/kern_exit.c
@@ -366,6 +366,7 @@
* Close open files and release open-file table.
* This may block!
*/
+ pdescfree(td);
fdescfree(td);
/*
Index: sys/kern/kern_fork.c
===================================================================
--- sys/kern/kern_fork.c
+++ sys/kern/kern_fork.c
@@ -332,16 +332,22 @@
*/
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 @@
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 @@
* 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 @@
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;
Index: sys/kern/kern_proc.c
===================================================================
--- sys/kern/kern_proc.c
+++ sys/kern/kern_proc.c
@@ -1143,6 +1143,7 @@
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 @@
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 @@
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 @@
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);
}
Index: sys/kern/kern_thread.c
===================================================================
--- sys/kern/kern_thread.c
+++ sys/kern/kern_thread.c
@@ -86,15 +86,15 @@
"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
#ifdef __i386__
@@ -106,15 +106,15 @@
"struct thread KBI td_frame");
_Static_assert(offsetof(struct thread, td_emuldata) == 0x344,
"struct thread KBI td_emuldata");
-_Static_assert(offsetof(struct proc, p_flag) == 0x68,
+_Static_assert(offsetof(struct proc, p_flag) == 0x6c,
"struct proc KBI p_flag");
-_Static_assert(offsetof(struct proc, p_pid) == 0x74,
+_Static_assert(offsetof(struct proc, p_pid) == 0x78,
"struct proc KBI p_pid");
-_Static_assert(offsetof(struct proc, p_filemon) == 0x268,
+_Static_assert(offsetof(struct proc, p_filemon) == 0x26c,
"struct proc KBI p_filemon");
-_Static_assert(offsetof(struct proc, p_comm) == 0x27c,
+_Static_assert(offsetof(struct proc, p_comm) == 0x280,
"struct proc KBI p_comm");
-_Static_assert(offsetof(struct proc, p_emuldata) == 0x308,
+_Static_assert(offsetof(struct proc, p_emuldata) == 0x30c,
"struct proc KBI p_emuldata");
#endif
Index: sys/kern/uipc_mqueue.c
===================================================================
--- sys/kern/uipc_mqueue.c
+++ sys/kern/uipc_mqueue.c
@@ -2011,7 +2011,7 @@
{
char path[MQFS_NAMELEN + 1];
struct mqfs_node *pn;
- struct filedesc *fdp;
+ struct pwddesc *pdp;
struct file *fp;
struct mqueue *mq;
int fd, error, len, cmode;
@@ -2019,8 +2019,8 @@
AUDIT_ARG_FFLAGS(flags);
AUDIT_ARG_MODE(mode);
- fdp = td->td_proc->p_fd;
- cmode = (((mode & ~fdp->fd_cmask) & ALLPERMS) & ~S_ISTXT);
+ pdp = td->td_proc->p_pd;
+ cmode = (((mode & ~pdp->pd_cmask) & ALLPERMS) & ~S_ISTXT);
mq = NULL;
if ((flags & O_CREAT) != 0 && attr != NULL) {
if (attr->mq_maxmsg <= 0 || attr->mq_maxmsg > maxmsg)
Index: sys/kern/uipc_sem.c
===================================================================
--- sys/kern/uipc_sem.c
+++ sys/kern/uipc_sem.c
@@ -465,7 +465,7 @@
ksem_create(struct thread *td, const char *name, semid_t *semidp, mode_t mode,
unsigned int value, int flags, int compat32)
{
- struct filedesc *fdp;
+ struct pwddesc *pdp;
struct ksem *ks;
struct file *fp;
char *path;
@@ -481,8 +481,8 @@
if (value > SEM_VALUE_MAX)
return (EINVAL);
- fdp = td->td_proc->p_fd;
- mode = (mode & ~fdp->fd_cmask) & ACCESSPERMS;
+ pdp = td->td_proc->p_pd;
+ mode = (mode & ~pdp->pd_cmask) & ACCESSPERMS;
error = falloc(td, &fp, &fd, O_CLOEXEC);
if (error) {
if (name == NULL)
Index: sys/kern/uipc_shm.c
===================================================================
--- sys/kern/uipc_shm.c
+++ sys/kern/uipc_shm.c
@@ -1031,7 +1031,7 @@
kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode,
int shmflags, struct filecaps *fcaps, const char *name __unused)
{
- struct filedesc *fdp;
+ struct pwddesc *pdp;
struct shmfd *shmfd;
struct file *fp;
char *path;
@@ -1081,8 +1081,8 @@
if ((initial_seals & ~F_SEAL_SEAL) != 0)
return (EINVAL);
- fdp = td->td_proc->p_fd;
- cmode = (mode & ~fdp->fd_cmask) & ACCESSPERMS;
+ pdp = td->td_proc->p_pd;
+ cmode = (mode & ~pdp->pd_cmask) & ACCESSPERMS;
/*
* shm_open(2) created shm should always have O_CLOEXEC set, as mandated
Index: sys/kern/uipc_usrreq.c
===================================================================
--- sys/kern/uipc_usrreq.c
+++ sys/kern/uipc_usrreq.c
@@ -660,7 +660,7 @@
}
VATTR_NULL(&vattr);
vattr.va_type = VSOCK;
- vattr.va_mode = (ACCESSPERMS & ~td->td_proc->p_fd->fd_cmask);
+ vattr.va_mode = (ACCESSPERMS & ~td->td_proc->p_pd->pd_cmask);
#ifdef MAC
error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
&vattr);
Index: sys/kern/vfs_syscalls.c
===================================================================
--- sys/kern/vfs_syscalls.c
+++ sys/kern/vfs_syscalls.c
@@ -1100,7 +1100,8 @@
int flags, int mode)
{
struct proc *p = td->td_proc;
- struct filedesc *fdp = p->p_fd;
+ struct filedesc *fdp;
+ struct pwddesc *pdp;
struct file *fp;
struct vnode *vp;
struct nameidata nd;
@@ -1108,6 +1109,8 @@
int cmode, error, indx;
indx = -1;
+ fdp = p->p_fd;
+ pdp = p->p_pd;
AUDIT_ARG_FFLAGS(flags);
AUDIT_ARG_MODE(mode);
@@ -1139,7 +1142,7 @@
*/
/* Set the flags early so the finit in devfs can pick them up. */
fp->f_flag = flags & FMASK;
- cmode = ((mode & ~fdp->fd_cmask) & ALLPERMS) & ~S_ISTXT;
+ cmode = ((mode & ~pdp->pd_cmask) & ALLPERMS) & ~S_ISTXT;
NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, fd,
&rights, td);
td->td_dupfd = -1; /* XXX check for fdopen */
@@ -1341,7 +1344,7 @@
} else {
VATTR_NULL(&vattr);
vattr.va_mode = (mode & ALLPERMS) &
- ~td->td_proc->p_fd->fd_cmask;
+ ~td->td_proc->p_pd->pd_cmask;
vattr.va_rdev = dev;
whiteout = 0;
@@ -1454,7 +1457,7 @@
}
VATTR_NULL(&vattr);
vattr.va_type = VFIFO;
- vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask;
+ vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_pd->pd_cmask;
#ifdef MAC
error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
&vattr);
@@ -1724,7 +1727,7 @@
goto restart;
}
VATTR_NULL(&vattr);
- vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask;
+ vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_pd->pd_cmask;
#ifdef MAC
vattr.va_type = VLNK;
error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
@@ -3787,7 +3790,7 @@
}
VATTR_NULL(&vattr);
vattr.va_type = VDIR;
- vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask;
+ vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_pd->pd_cmask;
#ifdef MAC
error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
&vattr);
@@ -4187,13 +4190,13 @@
int
sys_umask(struct thread *td, struct umask_args *uap)
{
- struct filedesc *fdp;
+ struct pwddesc *pdp;
- fdp = td->td_proc->p_fd;
- FILEDESC_XLOCK(fdp);
- td->td_retval[0] = fdp->fd_cmask;
- fdp->fd_cmask = uap->newmask & ALLPERMS;
- FILEDESC_XUNLOCK(fdp);
+ pdp = td->td_proc->p_pd;
+ PWDDESC_XLOCK(pdp);
+ td->td_retval[0] = pdp->pd_cmask;
+ pdp->pd_cmask = uap->newmask & ALLPERMS;
+ PWDDESC_XUNLOCK(pdp);
return (0);
}
Index: sys/sys/filedesc.h
===================================================================
--- sys/sys/filedesc.h
+++ sys/sys/filedesc.h
@@ -39,6 +39,7 @@
#include <sys/queue.h>
#include <sys/event.h>
#include <sys/lock.h>
+#include <sys/mutex.h>
#include <sys/priority.h>
#include <sys/seqc.h>
#include <sys/sx.h>
@@ -92,12 +93,17 @@
};
typedef SMR_POINTER(struct pwd *) smrpwd_t;
+struct pwddesc {
+ struct mtx pd_lock; /* protects members of this struct */
+ smrpwd_t pd_pwd; /* directories */
+ volatile u_int pd_refcount;
+ u_short pd_cmask; /* mask for file creation */
+};
+
struct filedesc {
struct fdescenttbl *fd_files; /* open files table */
- smrpwd_t fd_pwd; /* directories */
NDSLOTTYPE *fd_map; /* bitmap of free fds */
int fd_freefile; /* approx. next free file */
- u_short fd_cmask; /* mask for file creation */
int fd_refcnt; /* thread reference count */
int fd_holdcnt; /* hold count on structure + mutex */
struct sx fd_sx; /* protects members of this struct */
@@ -134,6 +140,40 @@
#ifdef _KERNEL
+/* Lock a paths descriptor table. */
+#define PWDDESC_LOCK(pdp) (&(pdp)->pd_lock)
+#define PWDDESC_LOCK_INIT(pdp) \
+ mtx_init(PWDDESC_LOCK(pdp), "pwddesc", NULL, MTX_DEF)
+#define PWDDESC_LOCK_DESTROY(pdp) mtx_destroy(PWDDESC_LOCK(pdp))
+#define PWDDESC_XLOCK(pdp) mtx_lock(PWDDESC_LOCK(pdp))
+#define PWDDESC_XUNLOCK(pdp) mtx_unlock(PWDDESC_LOCK(pdp))
+#define PWDDESC_SLOCK(pdp) mtx_lock(PWDDESC_LOCK(pdp))
+#define PWDDESC_SUNLOCK(pdp) mtx_unlock(PWDDESC_LOCK(pdp))
+#define PWDDESC_LOCK_ASSERT(pdp, what) \
+ mtx_assert(PWDDESC_LOCK(pdp), (what))
+#define PWDDESC_ASSERT_LOCKED(pdp) \
+ PWDDESC_LOCK_ASSERT((pdp), MA_OWNED)
+#define PWDDESC_ASSERT_XLOCKED(pdp) \
+ PWDDESC_LOCK_ASSERT((pdp), MA_OWNED)
+#define PWDDESC_ASSERT_UNLOCKED(pdp) \
+ PWDDESC_LOCK_ASSERT((pdp), MA_NOTOWNED)
+
+#define PWDDESC_LOCKED_LOAD_PWD(pdp) ({ \
+ struct pwddesc *_pdp = (pdp); \
+ struct pwd *_pwd; \
+ _pwd = smr_serialized_load(&(_pdp)->pd_pwd, \
+ (PWDDESC_ASSERT_LOCKED(_pdp), true)); \
+ _pwd; \
+})
+
+#define PWDDESC_XLOCKED_LOAD_PWD(pdp) ({ \
+ struct pwddesc *_pdp = (pdp); \
+ struct pwd *_pwd; \
+ _pwd = smr_serialized_load(&(_pdp)->pd_pwd, \
+ (PWDDESC_ASSERT_XLOCKED(_pdp), true)); \
+ _pwd; \
+})
+
/* Lock a file descriptor table. */
#define FILEDESC_LOCK_INIT(fdp) sx_init(&(fdp)->fd_sx, "filedesc structure")
#define FILEDESC_LOCK_DESTROY(fdp) sx_destroy(&(fdp)->fd_sx)
@@ -149,31 +189,15 @@
SX_NOTRECURSED)
#define FILEDESC_UNLOCK_ASSERT(fdp) sx_assert(&(fdp)->fd_sx, SX_UNLOCKED)
-#define FILEDESC_LOCKED_LOAD_PWD(fdp) ({ \
- struct filedesc *_fdp = (fdp); \
- struct pwd *_pwd; \
- _pwd = smr_serialized_load(&(_fdp)->fd_pwd, \
- (FILEDESC_LOCK_ASSERT(_fdp), true)); \
- _pwd; \
-})
-
-#define FILEDESC_XLOCKED_LOAD_PWD(fdp) ({ \
- struct filedesc *_fdp = (fdp); \
- struct pwd *_pwd; \
- _pwd = smr_serialized_load(&(_fdp)->fd_pwd, \
- (FILEDESC_XLOCK_ASSERT(_fdp), true)); \
- _pwd; \
-})
-
#else
/*
* Accessor for libkvm et al.
*/
-#define FILEDESC_KVM_LOAD_PWD(fdp) ({ \
- struct filedesc *_fdp = (fdp); \
+#define PWDDESC_KVM_LOAD_PWD(pdp) ({ \
+ struct pwddesc *_pdp = (pdp); \
struct pwd *_pwd; \
- _pwd = smr_kvm_load(&(_fdp)->fd_pwd); \
+ _pwd = smr_kvm_load(&(_pdp)->pd_pwd); \
_pwd; \
})
@@ -296,21 +320,26 @@
#endif
/* cdir/rdir/jdir manipulation functions. */
+struct pwddesc *pdcopy(struct pwddesc *pdp);
+void pdescfree(struct thread *td);
+struct pwddesc *pdinit(struct pwddesc *pdp, bool keeplock);
+struct pwddesc *pdshare(struct pwddesc *pdp);
+void pdunshare(struct thread *td);
+
void pwd_chdir(struct thread *td, struct vnode *vp);
int pwd_chroot(struct thread *td, struct vnode *vp);
void pwd_ensure_dirs(void);
void pwd_set_rootvnode(void);
-struct pwd *pwd_hold_filedesc(struct filedesc *fdp);
+struct pwd *pwd_hold_pwddesc(struct pwddesc *pdp);
bool pwd_hold_smr(struct pwd *pwd);
struct pwd *pwd_hold(struct thread *td);
void pwd_drop(struct pwd *pwd);
static inline void
-pwd_set(struct filedesc *fdp, struct pwd *newpwd)
+pwd_set(struct pwddesc *pdp, struct pwd *newpwd)
{
-
- smr_serialized_store(&fdp->fd_pwd, newpwd,
- (FILEDESC_XLOCK_ASSERT(fdp), true));
+ smr_serialized_store(&pdp->pd_pwd, newpwd,
+ (PWDDESC_ASSERT_XLOCKED(pdp), true));
}
struct pwd *pwd_get_smr(void);
Index: sys/sys/proc.h
===================================================================
--- sys/sys/proc.h
+++ sys/sys/proc.h
@@ -593,6 +593,7 @@
struct ucred *p_ucred; /* (c) Process owner's identity. */
struct filedesc *p_fd; /* (b) Open files. */
struct filedesc_to_leader *p_fdtol; /* (b) Tracking node */
+ struct pwddesc *p_pd; /* (b) Cwd, chroot, jail, umask */
struct pstats *p_stats; /* (b) Accounting/statistics (CPU). */
struct plimit *p_limit; /* (c) Resource limits. */
struct callout p_limco; /* (c) Limit callout handle */
Index: sys/sys/user.h
===================================================================
--- sys/sys/user.h
+++ sys/sys/user.h
@@ -88,7 +88,7 @@
*/
#define KI_NSPARE_INT 2
#define KI_NSPARE_LONG 12
-#define KI_NSPARE_PTR 6
+#define KI_NSPARE_PTR 5
#ifndef _KERNEL
#ifndef KINFO_PROC_SIZE
@@ -213,6 +213,7 @@
* front of ki_spareptrs, and longs from the end of ki_sparelongs.
* That way the spare room from both arrays will remain contiguous.
*/
+ struct pwddesc *ki_pd; /* pointer to process paths info */
void *ki_spareptrs[KI_NSPARE_PTR]; /* spare room for growth */
long ki_sparelongs[KI_NSPARE_LONG]; /* spare room for growth */
long ki_sflag; /* PS_* flags */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Apr 7, 4:24 PM (2 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31041836
Default Alt Text
D27037.id79142.diff (36 KB)
Attached To
Mode
D27037: Split out cwd/root/jail, cmask state from filedesc table
Attached
Detach File
Event Timeline
Log In to Comment