summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/fs/msdosfs/msdosfs_vfsops.c30
1 files changed, 13 insertions, 17 deletions
diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
index d4b6a02..63d60dd 100644
--- a/sys/fs/msdosfs/msdosfs_vfsops.c
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c
@@ -292,11 +292,9 @@ msdosfs_mount(struct mount *mp)
}
/* Downgrade the device from rw to ro. */
- DROP_GIANT();
g_topology_lock();
error = g_access(pmp->pm_cp, 0, -1, 0);
g_topology_unlock();
- PICKUP_GIANT();
if (error) {
(void)markvoldirty(pmp, 1);
return (error);
@@ -328,11 +326,9 @@ msdosfs_mount(struct mount *mp)
return (error);
}
VOP_UNLOCK(devvp, 0);
- DROP_GIANT();
g_topology_lock();
error = g_access(pmp->pm_cp, 0, 1, 0);
g_topology_unlock();
- PICKUP_GIANT();
if (error)
return (error);
@@ -401,8 +397,6 @@ msdosfs_mount(struct mount *mp)
return error;
}
- if (devvp->v_type == VCHR && devvp->v_rdev != NULL)
- devvp->v_rdev->si_mountpt = mp;
vfs_mountedfrom(mp, from);
#ifdef MSDOSFS_DEBUG
printf("msdosfs_mount(): mp %p, pmp %p, inusemap %p\n", mp, pmp, pmp->pm_inusemap);
@@ -431,15 +425,21 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp)
ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
dev = devvp->v_rdev;
- dev_ref(dev);
- DROP_GIANT();
+ if (atomic_cmpset_acq_ptr((uintptr_t *)&dev->si_mountpt, 0,
+ (uintptr_t)mp) == 0) {
+ VOP_UNLOCK(devvp, 0);
+ return (EBUSY);
+ }
g_topology_lock();
error = g_vfs_open(devvp, &cp, "msdosfs", ronly ? 0 : 1);
g_topology_unlock();
- PICKUP_GIANT();
+ if (error != 0) {
+ atomic_store_rel_ptr((uintptr_t *)&dev->si_mountpt, 0);
+ VOP_UNLOCK(devvp, 0);
+ return (error);
+ }
+ dev_ref(dev);
VOP_UNLOCK(devvp, 0);
- if (error)
- goto error_exit;
bo = &devvp->v_bufobj;
@@ -770,11 +770,9 @@ error_exit:
if (bp)
brelse(bp);
if (cp != NULL) {
- DROP_GIANT();
g_topology_lock();
g_vfs_close(cp);
g_topology_unlock();
- PICKUP_GIANT();
}
if (pmp) {
lockdestroy(&pmp->pm_fatlock);
@@ -783,6 +781,7 @@ error_exit:
free(pmp, M_MSDOSFSMNT);
mp->mnt_data = NULL;
}
+ atomic_store_rel_ptr((uintptr_t *)&dev->si_mountpt, 0);
dev_rel(dev);
return (error);
}
@@ -846,13 +845,10 @@ msdosfs_unmount(struct mount *mp, int mntflags)
BO_UNLOCK(bo);
}
#endif
- DROP_GIANT();
- if (pmp->pm_devvp->v_type == VCHR && pmp->pm_devvp->v_rdev != NULL)
- pmp->pm_devvp->v_rdev->si_mountpt = NULL;
g_topology_lock();
g_vfs_close(pmp->pm_cp);
g_topology_unlock();
- PICKUP_GIANT();
+ atomic_store_rel_ptr((uintptr_t *)&pmp->pm_dev->si_mountpt, 0);
vrele(pmp->pm_devvp);
dev_rel(pmp->pm_dev);
free(pmp->pm_inusemap, M_MSDOSFSFAT);
OpenPOWER on IntegriCloud