From nobody Sat Jan 08 04:29:39 2022 X-Original-To: dev-commits-src-all@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 A6B5C1932520; Sat, 8 Jan 2022 04:29:41 +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 4JW6Yw42vWz3DrG; Sat, 8 Jan 2022 04:29:40 +0000 (UTC) (envelope-from git@FreeBSD.org) 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 0334D1863B; Sat, 8 Jan 2022 04:29:40 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 2084Tdxi022417; Sat, 8 Jan 2022 04:29:39 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 2084Tdku022416; Sat, 8 Jan 2022 04:29:39 GMT (envelope-from git) Date: Sat, 8 Jan 2022 04:29:39 GMT Message-Id: <202201080429.2084Tdku022416@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: aaaa4fb54e5c - main - msdosfs: use mntfs vnode for pm_devvp List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: aaaa4fb54e5c427b7a8d305c3562fe5dde4ec8ec Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1641616181; 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=zSIDVqT9MkK9HGAf6vE2EtMlYU1oN743cUyBHl7oG2Q=; b=NDLW+CPoPeegUGu4ye2q3KS1TjA/qX9LZcb4D5vK+iR4olaJSuMNapfMnWE9z99MWy0Gpa s6Blht29PWtNfBOk9NI88tAgE6xkIJXCu7d44AvL72DPnokzerhHEGxUaot5bTbrUoOczO EH2dRdD5o67tpBiyCsaV2kZOkFOZqI4v0/bO27SIgOge3sVwL1SOtZ2ok6kJEnGq9oQGVl QVwWc6XY6jdX0mzbz3N912db6dLbpGsO/R40RjETdqGJ8aMVNjfjNFt9oxRVmGWv+zyLYQ NoNORLY5J3lbu4VM9Ea6++IiNzkynPy5EIcTLH8/oIfGJaDD0DENRIjvYCTwbg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1641616181; a=rsa-sha256; cv=none; b=Wh+nEPpS9Ji+45H2qiFeMIXNZfFsfvXram3qzj3waFk6QNLJya5zLRnQ0eb+yH4qSNRkkj pXLUaKZ7tTqjwxoPorIwIJZyg4VKC7lN5c1asbiQ7KgUfm8iMyvw9tYbssCUsRT3WJv4Mp jA3huVyqJXsHAasmoZ0az1hL5AH00LlKoAgLRekbQuJsS7EpLMwUedm/L2RAM5oOXMTIkH 5Z+XQi2qId9G/TenxwHvjRl2DteJcn2V6wqw5T9PRX5ZnqEpEacPhkpMiQRxXX+5NK57ZU t8HZdp4Lj3BpCyP6MS29GrzN0hc6oBzUEaDgM4eOXt/CsT59VqQTqsNeYTfcDQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=aaaa4fb54e5c427b7a8d305c3562fe5dde4ec8ec commit aaaa4fb54e5c427b7a8d305c3562fe5dde4ec8ec Author: Konstantin Belousov AuthorDate: 2022-01-06 01:47:31 +0000 Commit: Konstantin Belousov CommitDate: 2022-01-08 04:21:58 +0000 msdosfs: use mntfs vnode for pm_devvp to prevent races with devfs VCHR vnode reclamation, same as it was done for UFS. Reported by: pho Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D33721 --- sys/fs/msdosfs/msdosfs_vfsops.c | 42 ++++++++++++++++++++++++++++++----------- sys/fs/msdosfs/msdosfsmount.h | 1 + 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c index 3c2606ab5a91..15f90c2e0e23 100644 --- a/sys/fs/msdosfs/msdosfs_vfsops.c +++ b/sys/fs/msdosfs/msdosfs_vfsops.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -229,7 +231,7 @@ msdosfs_cmount(struct mntarg *ma, void *data, uint64_t flags) static int msdosfs_mount(struct mount *mp) { - struct vnode *devvp; /* vnode for blk device to mount */ + struct vnode *devvp, *odevvp; /* vnode for blk device to mount */ struct thread *td; /* msdosfs specific mount control block */ struct msdosfsmount *pmp = NULL; @@ -302,17 +304,17 @@ msdosfs_mount(struct mount *mp) * If upgrade to read-write by non-root, then verify * that user has necessary permissions on the device. */ - devvp = pmp->pm_devvp; - vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); - error = VOP_ACCESS(devvp, VREAD | VWRITE, + odevvp = pmp->pm_odevvp; + vn_lock(odevvp, LK_EXCLUSIVE | LK_RETRY); + error = VOP_ACCESS(odevvp, VREAD | VWRITE, td->td_ucred, td); if (error) error = priv_check(td, PRIV_VFS_MOUNT_PERM); if (error) { - VOP_UNLOCK(devvp); + VOP_UNLOCK(odevvp); return (error); } - VOP_UNLOCK(devvp); + VOP_UNLOCK(odevvp); g_topology_lock(); error = g_access(pmp->pm_cp, 0, 1, 0); g_topology_unlock(); @@ -385,7 +387,7 @@ msdosfs_mount(struct mount *mp) #endif } else { vput(devvp); - if (devvp != pmp->pm_devvp) + if (devvp != pmp->pm_odevvp) return (EINVAL); /* XXX needs translation */ } if (error) { @@ -408,11 +410,12 @@ msdosfs_mount(struct mount *mp) } static int -mountmsdosfs(struct vnode *devvp, struct mount *mp) +mountmsdosfs(struct vnode *odevvp, struct mount *mp) { struct msdosfsmount *pmp; struct buf *bp; struct cdev *dev; + struct vnode *devvp; union bootsector *bsp; struct byte_bpb33 *b33; struct byte_bpb50 *b50; @@ -427,10 +430,13 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp) pmp = NULL; ronly = (mp->mnt_flag & MNT_RDONLY) != 0; + devvp = mntfs_allocvp(mp, odevvp); + VOP_UNLOCK(odevvp); + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); dev = devvp->v_rdev; if (atomic_cmpset_acq_ptr((uintptr_t *)&dev->si_mountpt, 0, (uintptr_t)mp) == 0) { - VOP_UNLOCK(devvp); + mntfs_freevp(devvp); return (EBUSY); } g_topology_lock(); @@ -438,11 +444,14 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp) g_topology_unlock(); if (error != 0) { atomic_store_rel_ptr((uintptr_t *)&dev->si_mountpt, 0); - VOP_UNLOCK(devvp); + mntfs_freevp(devvp); return (error); } dev_ref(dev); bo = &devvp->v_bufobj; + BO_LOCK(&odevvp->v_bufobj); + odevvp->v_bufobj.bo_flag |= BO_NOBUFS; + BO_UNLOCK(&odevvp->v_bufobj); VOP_UNLOCK(devvp); if (dev->si_iosize_max != 0) mp->mnt_iosize_max = dev->si_iosize_max; @@ -709,6 +718,7 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp) * fillinusemap() needs pm_devvp. */ pmp->pm_devvp = devvp; + pmp->pm_odevvp = odevvp; pmp->pm_dev = dev; /* @@ -764,7 +774,12 @@ error_exit: free(pmp, M_MSDOSFSMNT); mp->mnt_data = NULL; } + BO_LOCK(&odevvp->v_bufobj); + odevvp->v_bufobj.bo_flag &= ~BO_NOBUFS; + BO_UNLOCK(&odevvp->v_bufobj); atomic_store_rel_ptr((uintptr_t *)&dev->si_mountpt, 0); + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); + mntfs_freevp(devvp); dev_rel(dev); return (error); } @@ -841,11 +856,16 @@ msdosfs_unmount(struct mount *mp, int mntflags) if (susp) vfs_write_resume(mp, VR_START_WRITE); + vn_lock(pmp->pm_devvp, LK_EXCLUSIVE | LK_RETRY); g_topology_lock(); g_vfs_close(pmp->pm_cp); g_topology_unlock(); + BO_LOCK(&pmp->pm_odevvp->v_bufobj); + pmp->pm_odevvp->v_bufobj.bo_flag &= ~BO_NOBUFS; + BO_UNLOCK(&pmp->pm_odevvp->v_bufobj); atomic_store_rel_ptr((uintptr_t *)&pmp->pm_dev->si_mountpt, 0); - vrele(pmp->pm_devvp); + mntfs_freevp(pmp->pm_devvp); + vrele(pmp->pm_odevvp); dev_rel(pmp->pm_dev); free(pmp->pm_inusemap, M_MSDOSFSFAT); lockdestroy(&pmp->pm_fatlock); diff --git a/sys/fs/msdosfs/msdosfsmount.h b/sys/fs/msdosfs/msdosfsmount.h index 6a0ba896dff5..5caa40f2b648 100644 --- a/sys/fs/msdosfs/msdosfsmount.h +++ b/sys/fs/msdosfs/msdosfsmount.h @@ -83,6 +83,7 @@ struct msdosfsmount { mode_t pm_dirmask; /* mask to and with file protection bits for directories */ struct vnode *pm_devvp; /* vnode for character device mounted */ + struct vnode *pm_odevvp;/* real devfs vnode */ struct cdev *pm_dev; /* character device mounted */ struct bpb50 pm_bpb; /* BIOS parameter blk for this fs */ u_long pm_BlkPerSec; /* How many DEV_BSIZE blocks fit inside a physical sector */