Index: sys/kern/vfs_subr.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/kern/vfs_subr.c,v diff -u -p -u -p -r1.325 vfs_subr.c --- sys/kern/vfs_subr.c 31 Oct 2024 10:06:51 -0000 1.325 +++ sys/kern/vfs_subr.c 20 Dec 2024 12:40:50 -0000 @@ -181,6 +181,7 @@ vfs_mount_alloc(struct vnode *vp, struct struct mount *mp; mp = malloc(sizeof(*mp), M_MOUNT, M_WAITOK|M_ZERO); + refcnt_init(&mp->mnt_refs); rw_init_flags(&mp->mnt_lock, "vfslock", RWL_IS_VNODE); (void)vfs_busy(mp, VB_READ|VB_NOWAIT); @@ -196,14 +197,29 @@ vfs_mount_alloc(struct vnode *vp, struct return (mp); } +struct mount * +vfs_mount_take(struct mount *mp) +{ + refcnt_take(&mp->mnt_refs); + return (mp); +} + +static void +vfs_mount_rele(struct mount *mp) +{ + if (refcnt_rele(&mp->mnt_refs)) + free(mp, M_MOUNT, sizeof(*mp)); +} + /* * Release a mount point. */ void vfs_mount_free(struct mount *mp) { + SET(mp->mnt_flag, MNT_FREE); atomic_dec_int(&mp->mnt_vfc->vfc_refcount); - free(mp, M_MOUNT, sizeof(*mp)); + vfs_mount_rele(mp); } /* @@ -216,27 +232,27 @@ vfs_mount_free(struct mount *mp) int vfs_busy(struct mount *mp, int flags) { - int rwflags = 0; + int rwflags = ISSET(flags, VB_WRITE) ? RW_WRITE : RW_READ; + int error = 0; - if (flags & VB_WRITE) - rwflags |= RW_WRITE; - else - rwflags |= RW_READ; - - if (flags & VB_WAIT) - rwflags |= RW_SLEEPFAIL; - else + if (!ISSET(flags, VB_WAIT)) rwflags |= RW_NOSLEEP; #ifdef WITNESS - if (flags & VB_DUPOK) + if (ISSET(flags, VB_DUPOK) rwflags |= RW_DUPOK; #endif - if (rw_enter(&mp->mnt_lock, rwflags)) - return (EBUSY); + vfs_mount_take(mp); + if (rw_enter(&mp->mnt_lock, rwflags) != 0) + error = EBUSY; + else if (ISSET(mp->mnt_flag, MNT_FREE)) { + rw_exit(&mp->mnt_lock); + error = EBUSY; + } + vfs_mount_rele(mp); - return (0); + return (error); } /* Index: sys/sys/mount.h =================================================================== RCS file: /mount/openbsd/cvs/src/sys/sys/mount.h,v diff -u -p -u -p -r1.152 mount.h --- sys/sys/mount.h 5 Nov 2024 17:28:32 -0000 1.152 +++ sys/sys/mount.h 20 Dec 2024 12:40:50 -0000 @@ -340,6 +340,7 @@ struct mount { struct vnode *mnt_syncer; /* syncer vnode */ TAILQ_HEAD(, vnode) mnt_vnodelist; /* list of vnodes this mount */ struct rwlock mnt_lock; /* mount structure lock */ + struct refcnt mnt_refs; int mnt_flag; /* flags */ struct statfs mnt_stat; /* cache of filesystem stats */ void *mnt_data; /* private data */ @@ -388,8 +389,8 @@ struct mount { "\20\001RDONLY\002SYNCHRONOUS\003NOEXEC\004NOSUID\005NODEV\006NOPERM" \ "\007ASYNC\010EXRDONLY\011EXPORTED\012DEFEXPORTED\013EXPORTANON" \ "\014WXALLOWED\015LOCAL\016QUOTA\017ROOTFS\020NOATIME\021UPDATE" \ - "\022DELEXPORT\023RELOAD\024FORCE\025STALLED\026SWAPPABLE\032WANTRDWR" \ - "\033SOFTDEP\034DOOMED" + "\022DELEXPORT\023RELOAD\024FORCE\025STALLED\026SWAPPABLE\031FREE" \ + "\032WANTRDWR\033SOFTDEP\034DOOMED" /* * filesystem control flags. @@ -400,6 +401,7 @@ struct mount { #define MNT_FORCE 0x00080000 /* force unmount or readonly change */ #define MNT_STALLED 0x00100000 /* filesystem stalled */ #define MNT_SWAPPABLE 0x00200000 /* filesystem can be used for swap */ +#define MNT_FREE 0x01000000 /* filesystem is unmounted */ #define MNT_WANTRDWR 0x02000000 /* want upgrade to read/write */ #define MNT_SOFTDEP 0x04000000 /* soft dependencies being done - now ignored */ #define MNT_DOOMED 0x08000000 /* device behind filesystem is gone */