From nobody Mon Mar 04 18:51:48 2024 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4TpSTx4fkzz5D6CV; Mon, 4 Mar 2024 18:51:49 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4TpSTx0ttMz4bfK; Mon, 4 Mar 2024 18:51:49 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1709578309; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+JQiVziDgGR5VDLOk2ksLQZxO8EIVfTWpqnakA/6s5s=; b=WP3lyToUnQuS8V83Ja2yek5duoyv6F+XzNMSFwAwccZjo9Lj9zcO3VE1oXQ3//5q/E6Cg6 lXGnNZj/w8ZhOv8K4ZCBI4nzkmdDvnziYRwLZcn51Y6yuKhVVm0erlclxH/9fvRGKtLcgf 96xQ8LuKcx4IjA2J/HjFPhgpfEuUjbeeXjd3a+dBpbZwaEXduIRQK8fKRUDbkkpsWo5WP5 1Asd1wWNHaHgDes9TtMpa2RqApbBEYC9wbiCy0CYsxwFck7eXBxrHRUa81PQsFGZAAJRG6 4n6tqne2WSrZR4fs2Jk01z5hPwCetI6eeiXmrsaeYyL7oZ94VfnfhWEsVI1H/Q== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1709578309; a=rsa-sha256; cv=none; b=nDIliSL3wkXbKrNdnB0SU2TVJqD+P3+5ricRtbL9hK0Qp8inRh7s3HXJVel2R2EmeQm3nw ax64LZRYSoe0QU+Z/4AcnPL8RwNkofFlXHeaeIANswrcJP1w+vg8+Ftr6n+6gy7FwFVCoX fuhtgq9zLfEi1Yi+dAurHKXjfs7DQoS7h+U3QDBQL4lSJVMBIQcHCWmsN4tVX9f8FCilJs pZbYISzl6LBsi4s1petEHFBtgnmkxJLWZ5Npy6QZ1VbRY95D7Hm1gmdjLdpQLDr4UJH4DX m4ji/c+H5/JqUxbOKs6V5j0hQKJ2mg7Z5IlTdN3L8RQUf2yhnDAujnCtTM7a8A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1709578309; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+JQiVziDgGR5VDLOk2ksLQZxO8EIVfTWpqnakA/6s5s=; b=tg7KD+8aFh2SIF1TbbUmWU2lWSOgj2iCmyIDLYpXbrsrBxzDprnqHeMZCO2SElN620Z6NE ssdh+P5UrdTkdAQfHFNJmVXuo+TtSk9opmi+QWltLxv6obKWQ3AkN6LLGtHhGUYj/vrvFV 2auzFTPzlFhKqwJcQEvr20z6jJiy5oDHv8zYX6mKV3SqO99LnU3jIDS/fKwYgDIOVYN3Sv 2Hse3dgQE8Y5W0JWkCnDbTzKtHQFeI6caee2cqX0yFurvmcQeVy9GT9e/4kMHtbj2rVC3t 7FP14Eniq45hWuop0LFu8bInxPikenuhOYWT4+YBr+yWUIh56FXNfkWPWTiPLQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4TpSTx0L94zYJ7; Mon, 4 Mar 2024 18:51:49 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 424IpmkU009736; Mon, 4 Mar 2024 18:51:48 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 424IpmRp009733; Mon, 4 Mar 2024 18:51:48 GMT (envelope-from git) Date: Mon, 4 Mar 2024 18:51:48 GMT Message-Id: <202403041851.424IpmRp009733@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: "Jason A. Harmening" Subject: git: 5e806288f0c7 - stable/14 - unionfs: cache upper/lower mount objects List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jah X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 5e806288f0c702e3f35efcf4972a97f0cf7b5676 Auto-Submitted: auto-generated The branch stable/14 has been updated by jah: URL: https://cgit.FreeBSD.org/src/commit/?id=5e806288f0c702e3f35efcf4972a97f0cf7b5676 commit 5e806288f0c702e3f35efcf4972a97f0cf7b5676 Author: Jason A. Harmening AuthorDate: 2023-12-22 20:13:35 +0000 Commit: Jason A. Harmening CommitDate: 2024-03-04 18:31:49 +0000 unionfs: cache upper/lower mount objects Store the upper/lower FS mount objects in unionfs per-mount data and use these instead of the v_mount field of the upper/lower root vnodes. As described in the referenced PR, it is unsafe to access this field on the unionfs unmount path as ZFS rollback may have obliterated the v_mount field of the upper or lower root vnode. Use these stored objects to slightly simplify other code that needs access to the upper/lower mount objects as well. PR: 275870 Reported by: Karlo Miličević Tested by: Karlo Miličević Reviewed by: kib (prior version), olce Differential Revision: https://reviews.freebsd.org/D43815 (cherry picked from commit cc3ec9f7597882d36ee487fd436d1b90bed0ebfd) --- sys/fs/unionfs/union.h | 2 ++ sys/fs/unionfs/union_vfsops.c | 37 ++++++++++++++++++++----------------- sys/fs/unionfs/union_vnops.c | 4 ++-- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/sys/fs/unionfs/union.h b/sys/fs/unionfs/union.h index cbbb00a68c8a..6c7db47ff209 100644 --- a/sys/fs/unionfs/union.h +++ b/sys/fs/unionfs/union.h @@ -53,6 +53,8 @@ typedef enum _unionfs_whitemode { } unionfs_whitemode; struct unionfs_mount { + struct mount *um_lowermp; /* MNT_REFed lower mount object */ + struct mount *um_uppermp; /* MNT_REFed upper mount object */ struct vnode *um_lowervp; /* VREFed once */ struct vnode *um_uppervp; /* VREFed once */ struct vnode *um_rootvp; /* ROOT vnode */ diff --git a/sys/fs/unionfs/union_vfsops.c b/sys/fs/unionfs/union_vfsops.c index c717b048c6ab..4dff07eccaba 100644 --- a/sys/fs/unionfs/union_vfsops.c +++ b/sys/fs/unionfs/union_vfsops.c @@ -73,7 +73,6 @@ static struct vfsops unionfs_vfsops; static int unionfs_domount(struct mount *mp) { - struct mount *lowermp, *uppermp; struct vnode *lowerrootvp; struct vnode *upperrootvp; struct unionfs_mount *ump; @@ -305,18 +304,18 @@ unionfs_domount(struct mount *mp) * reused until that happens. We assume the caller holds a reference * to lowerrootvp as it is the mount's covered vnode. */ - lowermp = vfs_register_upper_from_vp(ump->um_lowervp, mp, + ump->um_lowermp = vfs_register_upper_from_vp(ump->um_lowervp, mp, &ump->um_lower_link); - uppermp = vfs_register_upper_from_vp(ump->um_uppervp, mp, + ump->um_uppermp = vfs_register_upper_from_vp(ump->um_uppervp, mp, &ump->um_upper_link); vrele(upperrootvp); - if (lowermp == NULL || uppermp == NULL) { - if (lowermp != NULL) - vfs_unregister_upper(lowermp, &ump->um_lower_link); - if (uppermp != NULL) - vfs_unregister_upper(uppermp, &ump->um_upper_link); + if (ump->um_lowermp == NULL || ump->um_uppermp == NULL) { + if (ump->um_lowermp != NULL) + vfs_unregister_upper(ump->um_lowermp, &ump->um_lower_link); + if (ump->um_uppermp != NULL) + vfs_unregister_upper(ump->um_uppermp, &ump->um_upper_link); vflush(mp, 1, FORCECLOSE, curthread); free(ump, M_UNIONFSMNT); mp->mnt_data = NULL; @@ -348,8 +347,8 @@ unionfs_domount(struct mount *mp) } MNT_ILOCK(mp); - if ((lowermp->mnt_flag & MNT_LOCAL) != 0 && - (uppermp->mnt_flag & MNT_LOCAL) != 0) + if ((ump->um_lowermp->mnt_flag & MNT_LOCAL) != 0 && + (ump->um_uppermp->mnt_flag & MNT_LOCAL) != 0) mp->mnt_flag |= MNT_LOCAL; mp->mnt_kern_flag |= MNTK_NOMSYNC | MNTK_UNIONFS | (ump->um_uppermp->mnt_kern_flag & MNTK_SHARED_WRITES); @@ -403,8 +402,8 @@ unionfs_unmount(struct mount *mp, int mntflags) vn_lock(mp->mnt_vnodecovered, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE); mp->mnt_vnodecovered->v_vflag &= ~VV_CROSSLOCK; VOP_UNLOCK(mp->mnt_vnodecovered); - vfs_unregister_upper(ump->um_lowervp->v_mount, &ump->um_lower_link); - vfs_unregister_upper(ump->um_uppervp->v_mount, &ump->um_upper_link); + vfs_unregister_upper(ump->um_lowermp, &ump->um_lower_link); + vfs_unregister_upper(ump->um_uppermp, &ump->um_upper_link); free(ump, M_UNIONFSMNT); mp->mnt_data = NULL; @@ -442,7 +441,11 @@ unionfs_quotactl(struct mount *mp, int cmd, uid_t uid, void *arg, bool unbusy; ump = MOUNTTOUNIONFSMOUNT(mp); - uppermp = atomic_load_ptr(&ump->um_uppervp->v_mount); + /* + * Issue a volatile load of um_uppermp here, as the mount may be + * torn down after we call vfs_unbusy(). + */ + uppermp = atomic_load_ptr(&ump->um_uppermp); KASSERT(*mp_busy == true, ("upper mount not busy")); /* * See comment in sys_quotactl() for an explanation of why the @@ -482,7 +485,7 @@ unionfs_statfs(struct mount *mp, struct statfs *sbp) mstat = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK | M_ZERO); - error = VFS_STATFS(ump->um_lowervp->v_mount, mstat); + error = VFS_STATFS(ump->um_lowermp, mstat); if (error) { free(mstat, M_STATFS); return (error); @@ -494,7 +497,7 @@ unionfs_statfs(struct mount *mp, struct statfs *sbp) lbsize = mstat->f_bsize; - error = VFS_STATFS(ump->um_uppervp->v_mount, mstat); + error = VFS_STATFS(ump->um_uppermp, mstat); if (error) { free(mstat, M_STATFS); return (error); @@ -561,10 +564,10 @@ unionfs_extattrctl(struct mount *mp, int cmd, struct vnode *filename_vp, unp = VTOUNIONFS(filename_vp); if (unp->un_uppervp != NULLVP) { - return (VFS_EXTATTRCTL(ump->um_uppervp->v_mount, cmd, + return (VFS_EXTATTRCTL(ump->um_uppermp, cmd, unp->un_uppervp, namespace, attrname)); } else { - return (VFS_EXTATTRCTL(ump->um_lowervp->v_mount, cmd, + return (VFS_EXTATTRCTL(ump->um_lowermp, cmd, unp->un_lowervp, namespace, attrname)); } } diff --git a/sys/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c index ba20bef199e6..31d30ffb8971 100644 --- a/sys/fs/unionfs/union_vnops.c +++ b/sys/fs/unionfs/union_vnops.c @@ -766,7 +766,7 @@ unionfs_access(struct vop_access_args *ap) if (lvp != NULLVP) { if (accmode & VWRITE) { - if (ump->um_uppervp->v_mount->mnt_flag & MNT_RDONLY) { + if ((ump->um_uppermp->mnt_flag & MNT_RDONLY) != 0) { switch (ap->a_vp->v_type) { case VREG: case VDIR: @@ -837,7 +837,7 @@ unionfs_getattr(struct vop_getattr_args *ap) error = VOP_GETATTR(lvp, ap->a_vap, ap->a_cred); - if (error == 0 && !(ump->um_uppervp->v_mount->mnt_flag & MNT_RDONLY)) { + if (error == 0 && (ump->um_uppermp->mnt_flag & MNT_RDONLY) == 0) { /* correct the attr toward shadow file/dir. */ if (ap->a_vp->v_type == VREG || ap->a_vp->v_type == VDIR) { unionfs_create_uppervattr_core(ump, ap->a_vap, &va, td);