aboutsummaryrefslogtreecommitdiff
path: root/sys/ufs
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2020-03-01 21:53:46 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2020-03-01 21:53:46 +0000
commit8d03b99b9dafe92896f405c79f846667637c0194 (patch)
tree7652a4a2fd9f888c114b8b0b375db5a54efd1b9f /sys/ufs
parent8243063f9b51391032ce09c18a5adbdc29263d0d (diff)
downloadsrc-8d03b99b9dafe92896f405c79f846667637c0194.tar.gz
src-8d03b99b9dafe92896f405c79f846667637c0194.zip
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/ufs')
-rw-r--r--sys/ufs/ffs/ffs_alloc.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index ea441404f477..fb270b11d912 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -3190,6 +3190,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS)
struct inode *ip, *dp;
struct mount *mp;
struct fs *fs;
+ struct pwd *pwd;
ufs2_daddr_t blkno;
long blkcnt, blksize;
u_long key;
@@ -3448,11 +3449,11 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS)
/*
* Now we get and lock the child directory containing "..".
*/
- FILEDESC_SLOCK(td->td_proc->p_fd);
- dvp = td->td_proc->p_fd->fd_cdir;
- FILEDESC_SUNLOCK(td->td_proc->p_fd);
+ pwd = pwd_hold(td);
+ dvp = pwd->pwd_cdir;
if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) {
vput(fdvp);
+ pwd_drop(pwd);
break;
}
dp = VTOI(dvp);
@@ -3463,6 +3464,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS)
cache_purge(dvp);
vput(dvp);
vput(fdvp);
+ pwd_drop(pwd);
break;
case FFS_UNLINK:
@@ -3607,7 +3609,7 @@ buffered_write(fp, uio, active_cred, flags, td)
return (EINVAL);
fdp = td->td_proc->p_fd;
FILEDESC_SLOCK(fdp);
- vp = fdp->fd_cdir;
+ vp = fdp->fd_pwd->pwd_cdir;
vref(vp);
FILEDESC_SUNLOCK(fdp);
vn_lock(vp, LK_SHARED | LK_RETRY);