Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/vfs_mount.c
| Show First 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | mount_init(void *mem, int size, int flags) | ||||
| mp->mnt_ref_pcpu = uma_zalloc_pcpu(pcpu_zone_int, | mp->mnt_ref_pcpu = uma_zalloc_pcpu(pcpu_zone_int, | ||||
| M_WAITOK | M_ZERO); | M_WAITOK | M_ZERO); | ||||
| mp->mnt_lockref_pcpu = uma_zalloc_pcpu(pcpu_zone_int, | mp->mnt_lockref_pcpu = uma_zalloc_pcpu(pcpu_zone_int, | ||||
| M_WAITOK | M_ZERO); | M_WAITOK | M_ZERO); | ||||
| mp->mnt_writeopcount_pcpu = uma_zalloc_pcpu(pcpu_zone_int, | mp->mnt_writeopcount_pcpu = uma_zalloc_pcpu(pcpu_zone_int, | ||||
| M_WAITOK | M_ZERO); | M_WAITOK | M_ZERO); | ||||
| mp->mnt_ref = 0; | mp->mnt_ref = 0; | ||||
| mp->mnt_vfs_ops = 1; | mp->mnt_vfs_ops = 1; | ||||
| mp->mnt_rootvnode = NULL; | |||||
| return (0); | return (0); | ||||
| } | } | ||||
| static void | static void | ||||
| mount_fini(void *mem, int size) | mount_fini(void *mem, int size) | ||||
| { | { | ||||
| struct mount *mp; | struct mount *mp; | ||||
| ▲ Show 20 Lines • Show All 432 Lines • ▼ Show 20 Lines | vfs_mount_destroy(struct mount *mp) | ||||
| if (mp->mnt_lockref != 0) | if (mp->mnt_lockref != 0) | ||||
| panic("vfs_mount_destroy: nonzero lock refcount"); | panic("vfs_mount_destroy: nonzero lock refcount"); | ||||
| MNT_IUNLOCK(mp); | MNT_IUNLOCK(mp); | ||||
| if (mp->mnt_vfs_ops != 1) | if (mp->mnt_vfs_ops != 1) | ||||
| panic("%s: vfs_ops should be 1 but %d found\n", __func__, | panic("%s: vfs_ops should be 1 but %d found\n", __func__, | ||||
| mp->mnt_vfs_ops); | mp->mnt_vfs_ops); | ||||
| if (mp->mnt_rootvnode != NULL) | |||||
| panic("%s: mount point still has a root vnode %p\n", __func__, | |||||
| mp->mnt_rootvnode); | |||||
| if (mp->mnt_vnodecovered != NULL) | if (mp->mnt_vnodecovered != NULL) | ||||
| vrele(mp->mnt_vnodecovered); | vrele(mp->mnt_vnodecovered); | ||||
| #ifdef MAC | #ifdef MAC | ||||
| mac_mount_destroy(mp); | mac_mount_destroy(mp); | ||||
| #endif | #endif | ||||
| if (mp->mnt_opt != NULL) | if (mp->mnt_opt != NULL) | ||||
| vfs_freeopts(mp->mnt_opt); | vfs_freeopts(mp->mnt_opt); | ||||
| crfree(mp->mnt_cred); | crfree(mp->mnt_cred); | ||||
| ▲ Show 20 Lines • Show All 436 Lines • ▼ Show 20 Lines | |||||
| vfs_domount_update( | vfs_domount_update( | ||||
| struct thread *td, /* Calling thread. */ | struct thread *td, /* Calling thread. */ | ||||
| struct vnode *vp, /* Mount point vnode. */ | struct vnode *vp, /* Mount point vnode. */ | ||||
| uint64_t fsflags, /* Flags common to all filesystems. */ | uint64_t fsflags, /* Flags common to all filesystems. */ | ||||
| struct vfsoptlist **optlist /* Options local to the filesystem. */ | struct vfsoptlist **optlist /* Options local to the filesystem. */ | ||||
| ) | ) | ||||
| { | { | ||||
| struct export_args export; | struct export_args export; | ||||
| struct vnode *rootvp; | |||||
| void *bufp; | void *bufp; | ||||
| struct mount *mp; | struct mount *mp; | ||||
| int error, export_error, len; | int error, export_error, len; | ||||
| uint64_t flag; | uint64_t flag; | ||||
| ASSERT_VOP_ELOCKED(vp, __func__); | ASSERT_VOP_ELOCKED(vp, __func__); | ||||
| KASSERT((fsflags & MNT_UPDATE) != 0, ("MNT_UPDATE should be here")); | KASSERT((fsflags & MNT_UPDATE) != 0, ("MNT_UPDATE should be here")); | ||||
| mp = vp->v_mount; | mp = vp->v_mount; | ||||
| ▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0) { | ||||
| error = EBUSY; | error = EBUSY; | ||||
| goto end; | goto end; | ||||
| } | } | ||||
| mp->mnt_flag &= ~MNT_UPDATEMASK; | mp->mnt_flag &= ~MNT_UPDATEMASK; | ||||
| mp->mnt_flag |= fsflags & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE | | mp->mnt_flag |= fsflags & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE | | ||||
| MNT_SNAPSHOT | MNT_ROOTFS | MNT_UPDATEMASK | MNT_RDONLY); | MNT_SNAPSHOT | MNT_ROOTFS | MNT_UPDATEMASK | MNT_RDONLY); | ||||
| if ((mp->mnt_flag & MNT_ASYNC) == 0) | if ((mp->mnt_flag & MNT_ASYNC) == 0) | ||||
| mp->mnt_kern_flag &= ~MNTK_ASYNC; | mp->mnt_kern_flag &= ~MNTK_ASYNC; | ||||
| rootvp = vfs_cache_root_clear(mp); | |||||
| MNT_IUNLOCK(mp); | MNT_IUNLOCK(mp); | ||||
| if (rootvp != NULL) | |||||
| vrele(rootvp); | |||||
| mp->mnt_optnew = *optlist; | mp->mnt_optnew = *optlist; | ||||
| vfs_mergeopts(mp->mnt_optnew, mp->mnt_opt); | vfs_mergeopts(mp->mnt_optnew, mp->mnt_opt); | ||||
| /* | /* | ||||
| * Mount the filesystem. | * Mount the filesystem. | ||||
| * XXX The final recipients of VFS_MOUNT just overwrite the ndp they | * XXX The final recipients of VFS_MOUNT just overwrite the ndp they | ||||
| * get. No freeing of cn_pnbuf. | * get. No freeing of cn_pnbuf. | ||||
| */ | */ | ||||
| ▲ Show 20 Lines • Show All 466 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /* | /* | ||||
| * Do the actual filesystem unmount. | * Do the actual filesystem unmount. | ||||
| */ | */ | ||||
| int | int | ||||
| dounmount(struct mount *mp, int flags, struct thread *td) | dounmount(struct mount *mp, int flags, struct thread *td) | ||||
| { | { | ||||
| struct vnode *coveredvp; | struct vnode *coveredvp, *rootvp; | ||||
| int error; | int error; | ||||
| uint64_t async_flag; | uint64_t async_flag; | ||||
| int mnt_gen_r; | int mnt_gen_r; | ||||
| if ((coveredvp = mp->mnt_vnodecovered) != NULL) { | if ((coveredvp = mp->mnt_vnodecovered) != NULL) { | ||||
| mnt_gen_r = mp->mnt_gen; | mnt_gen_r = mp->mnt_gen; | ||||
| VI_LOCK(coveredvp); | VI_LOCK(coveredvp); | ||||
| vholdl(coveredvp); | vholdl(coveredvp); | ||||
| Show All 31 Lines | dounmount(struct mount *mp, int flags, struct thread *td) | ||||
| MNT_ILOCK(mp); | MNT_ILOCK(mp); | ||||
| if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0 || | if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0 || | ||||
| (mp->mnt_flag & MNT_UPDATE) != 0 || | (mp->mnt_flag & MNT_UPDATE) != 0 || | ||||
| !TAILQ_EMPTY(&mp->mnt_uppers)) { | !TAILQ_EMPTY(&mp->mnt_uppers)) { | ||||
| dounmount_cleanup(mp, coveredvp, 0); | dounmount_cleanup(mp, coveredvp, 0); | ||||
| return (EBUSY); | return (EBUSY); | ||||
| } | } | ||||
| mp->mnt_kern_flag |= MNTK_UNMOUNT; | mp->mnt_kern_flag |= MNTK_UNMOUNT; | ||||
| rootvp = vfs_cache_root_clear(mp); | |||||
| if (flags & MNT_NONBUSY) { | if (flags & MNT_NONBUSY) { | ||||
| MNT_IUNLOCK(mp); | MNT_IUNLOCK(mp); | ||||
| error = vfs_check_usecounts(mp); | error = vfs_check_usecounts(mp); | ||||
| MNT_ILOCK(mp); | MNT_ILOCK(mp); | ||||
| if (error != 0) { | if (error != 0) { | ||||
| dounmount_cleanup(mp, coveredvp, MNTK_UNMOUNT); | dounmount_cleanup(mp, coveredvp, MNTK_UNMOUNT); | ||||
| if (rootvp != NULL) | |||||
| vrele(rootvp); | |||||
| return (error); | return (error); | ||||
| } | } | ||||
| } | } | ||||
| /* Allow filesystems to detect that a forced unmount is in progress. */ | /* Allow filesystems to detect that a forced unmount is in progress. */ | ||||
| if (flags & MNT_FORCE) { | if (flags & MNT_FORCE) { | ||||
| mp->mnt_kern_flag |= MNTK_UNMOUNTF; | mp->mnt_kern_flag |= MNTK_UNMOUNTF; | ||||
| MNT_IUNLOCK(mp); | MNT_IUNLOCK(mp); | ||||
| /* | /* | ||||
| Show All 11 Lines | dounmount(struct mount *mp, int flags, struct thread *td) | ||||
| } | } | ||||
| MNT_IUNLOCK(mp); | MNT_IUNLOCK(mp); | ||||
| KASSERT(mp->mnt_lockref == 0, | KASSERT(mp->mnt_lockref == 0, | ||||
| ("%s: invalid lock refcount in the drain path @ %s:%d", | ("%s: invalid lock refcount in the drain path @ %s:%d", | ||||
| __func__, __FILE__, __LINE__)); | __func__, __FILE__, __LINE__)); | ||||
| KASSERT(error == 0, | KASSERT(error == 0, | ||||
| ("%s: invalid return value for msleep in the drain path @ %s:%d", | ("%s: invalid return value for msleep in the drain path @ %s:%d", | ||||
| __func__, __FILE__, __LINE__)); | __func__, __FILE__, __LINE__)); | ||||
| if (rootvp != NULL) | |||||
| vrele(rootvp); | |||||
| if (mp->mnt_flag & MNT_EXPUBLIC) | if (mp->mnt_flag & MNT_EXPUBLIC) | ||||
| vfs_setpublicfs(NULL, NULL, NULL); | vfs_setpublicfs(NULL, NULL, NULL); | ||||
| /* | /* | ||||
| * From now, we can claim that the use reference on the | * From now, we can claim that the use reference on the | ||||
| * coveredvp is ours, and the ref can be released only by | * coveredvp is ours, and the ref can be released only by | ||||
| * successfull unmount by us, or left for later unmount | * successfull unmount by us, or left for later unmount | ||||
| ▲ Show 20 Lines • Show All 638 Lines • Show Last 20 Lines | |||||