aboutsummaryrefslogtreecommitdiff
path: root/sys/ufs/ffs
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2020-07-25 10:38:05 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2020-07-25 10:38:05 +0000
commit9d5a594f0b7f5939834be10a8652837c6933344c (patch)
treeb185307a889913d9b63b071aad474b26869ff5f0 /sys/ufs/ffs
parentc42b77e6941903af76b58f96a1ecb86c6ffac36d (diff)
downloadsrc-9d5a594f0b7f5939834be10a8652837c6933344c.tar.gz
src-9d5a594f0b7f5939834be10a8652837c6933344c.zip
ufs: add support for lockless lookup
ACLs are not supported, meaning their presence will force the use of the old lookup. Reviewed by: kib Tested by: pho (in a patchset) Differential Revision: https://reviews.freebsd.org/D25579
Notes
Notes: svn path=/head/; revision=363520
Diffstat (limited to 'sys/ufs/ffs')
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c22
-rw-r--r--sys/ufs/ffs/ffs_vnops.c8
2 files changed, 24 insertions, 6 deletions
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 696be51ae6a0..8c69212d82e6 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -84,6 +84,7 @@ __FBSDID("$FreeBSD$");
#include <ddb/ddb.h>
static uma_zone_t uma_inode, uma_ufs1, uma_ufs2;
+VFS_SMR_DECLARE;
static int ffs_mountfs(struct vnode *, struct mount *, struct thread *);
static void ffs_oldfscompat_read(struct fs *, struct ufsmount *,
@@ -393,6 +394,7 @@ ffs_mount(struct mount *mp)
uma_ufs2 = uma_zcreate("FFS2 dinode",
sizeof(struct ufs2_dinode), NULL, NULL, NULL, NULL,
UMA_ALIGN_PTR, 0);
+ VFS_SMR_ZONE_SET(uma_inode);
}
vfs_deleteopt(mp->mnt_optnew, "groupquota");
@@ -455,6 +457,7 @@ ffs_mount(struct mount *mp)
}
MNT_ILOCK(mp);
+ mp->mnt_kern_flag &= ~MNTK_FPLOOKUP;
mp->mnt_flag |= mntorflags;
MNT_IUNLOCK(mp);
/*
@@ -795,6 +798,17 @@ ffs_mount(struct mount *mp)
}
}
}
+
+ MNT_ILOCK(mp);
+ /*
+ * This is racy versus lookup, see ufs_fplookup_vexec for details.
+ */
+ if ((mp->mnt_kern_flag & MNTK_FPLOOKUP) != 0)
+ panic("MNTK_FPLOOKUP set on mount %p when it should not be", mp);
+ if ((mp->mnt_flag & (MNT_ACLS | MNT_NFS4ACLS)) == 0)
+ mp->mnt_kern_flag |= MNTK_FPLOOKUP;
+ MNT_IUNLOCK(mp);
+
vfs_mountedfrom(mp, fspec);
return (0);
}
@@ -1968,14 +1982,14 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
ump = VFSTOUFS(mp);
fs = ump->um_fs;
- ip = uma_zalloc(uma_inode, M_WAITOK | M_ZERO);
+ ip = uma_zalloc_smr(uma_inode, M_WAITOK | M_ZERO);
/* Allocate a new vnode/inode. */
error = getnewvnode("ufs", mp, fs->fs_magic == FS_UFS1_MAGIC ?
&ffs_vnodeops1 : &ffs_vnodeops2, &vp);
if (error) {
*vpp = NULL;
- uma_zfree(uma_inode, ip);
+ uma_zfree_smr(uma_inode, ip);
return (error);
}
/*
@@ -2004,7 +2018,7 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
vp->v_vflag |= VV_FORCEINSMQ;
error = insmntque(vp, mp);
if (error != 0) {
- uma_zfree(uma_inode, ip);
+ uma_zfree_smr(uma_inode, ip);
*vpp = NULL;
return (error);
}
@@ -2327,7 +2341,7 @@ ffs_ifree(struct ufsmount *ump, struct inode *ip)
uma_zfree(uma_ufs1, ip->i_din1);
else if (ip->i_din2 != NULL)
uma_zfree(uma_ufs2, ip->i_din2);
- uma_zfree(uma_inode, ip);
+ uma_zfree_smr(uma_inode, ip);
}
static int dobkgrdwrite = 1;
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index 000ded6cbbaa..c363f4bbb094 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -905,8 +905,10 @@ ffs_write(ap)
if ((ip->i_mode & (ISUID | ISGID)) && resid > uio->uio_resid &&
ap->a_cred) {
if (priv_check_cred(ap->a_cred, PRIV_VFS_RETAINSUGID)) {
- ip->i_mode &= ~(ISUID | ISGID);
+ vn_seqc_write_begin(vp);
+ UFS_INODE_SET_MODE(ip, ip->i_mode & ~(ISUID | ISGID));
DIP_SET(ip, i_mode, ip->i_mode);
+ vn_seqc_write_end(vp);
}
}
if (error) {
@@ -1152,8 +1154,10 @@ ffs_extwrite(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *ucred)
*/
if ((ip->i_mode & (ISUID | ISGID)) && resid > uio->uio_resid && ucred) {
if (priv_check_cred(ucred, PRIV_VFS_RETAINSUGID)) {
- ip->i_mode &= ~(ISUID | ISGID);
+ vn_seqc_write_begin(vp);
+ UFS_INODE_SET_MODE(ip, ip->i_mode & ~(ISUID | ISGID));
dp->di_mode = ip->i_mode;
+ vn_seqc_write_end(vp);
}
}
if (error) {