diff options
author | Mateusz Guzik <mjg@FreeBSD.org> | 2020-03-01 21:53:46 +0000 |
---|---|---|
committer | Mateusz Guzik <mjg@FreeBSD.org> | 2020-03-01 21:53:46 +0000 |
commit | 8d03b99b9dafe92896f405c79f846667637c0194 (patch) | |
tree | 7652a4a2fd9f888c114b8b0b375db5a54efd1b9f /sys/compat/linprocfs/linprocfs.c | |
parent | 8243063f9b51391032ce09c18a5adbdc29263d0d (diff) |
fd: move vnodes out of filedesc into a dedicated structure
The new structure is copy-on-write. With the assumption that path lookups are
significantly more frequent than chdirs and chrooting this is a win.
This provides stable root and jail root vnodes without the need to reference
them on lookup, which in turn means less work on globally shared structures.
Note this also happens to fix a bug where jail vnode was never referenced,
meaning subsequent access on lookup could run into use-after-free.
Reviewed by: kib
Differential Revision: https://reviews.freebsd.org/D23884
Notes
Notes:
svn path=/head/; revision=358503
Diffstat (limited to 'sys/compat/linprocfs/linprocfs.c')
-rw-r--r-- | sys/compat/linprocfs/linprocfs.c | 28 |
1 files changed, 8 insertions, 20 deletions
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index caa57f160a2a..c441193a4991 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -1028,23 +1028,16 @@ linprocfs_doprocstatus(PFS_FILL_ARGS) static int linprocfs_doproccwd(PFS_FILL_ARGS) { - struct filedesc *fdp; - struct vnode *vp; + struct pwd *pwd; char *fullpath = "unknown"; char *freepath = NULL; - fdp = p->p_fd; - FILEDESC_SLOCK(fdp); - vp = fdp->fd_cdir; - if (vp != NULL) - VREF(vp); - FILEDESC_SUNLOCK(fdp); - vn_fullpath(td, vp, &fullpath, &freepath); - if (vp != NULL) - vrele(vp); + pwd = pwd_hold(td); + vn_fullpath(td, pwd->pwd_cdir, &fullpath, &freepath); sbuf_printf(sb, "%s", fullpath); if (freepath) free(freepath, M_TEMP); + pwd_drop(pwd); return (0); } @@ -1054,23 +1047,18 @@ linprocfs_doproccwd(PFS_FILL_ARGS) static int linprocfs_doprocroot(PFS_FILL_ARGS) { - struct filedesc *fdp; + struct pwd *pwd; struct vnode *vp; char *fullpath = "unknown"; char *freepath = NULL; - fdp = p->p_fd; - FILEDESC_SLOCK(fdp); - vp = jailed(p->p_ucred) ? fdp->fd_jdir : fdp->fd_rdir; - if (vp != NULL) - VREF(vp); - FILEDESC_SUNLOCK(fdp); + pwd = pwd_hold(td); + vp = jailed(p->p_ucred) ? pwd->pwd_jdir : pwd->pwd_rdir; vn_fullpath(td, vp, &fullpath, &freepath); - if (vp != NULL) - vrele(vp); sbuf_printf(sb, "%s", fullpath); if (freepath) free(freepath, M_TEMP); + pwd_drop(pwd); return (0); } |