diff options
author | jhb <jhb@FreeBSD.org> | 2009-02-11 22:22:26 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2009-02-11 22:22:26 +0000 |
commit | 4a2859b3bea291207bb5f899037462724007ec61 (patch) | |
tree | ea18d4d8d21ad49a6495ab52cb37b81e8d2e1eac /sys/fs/udf | |
parent | 6f82ac1ceb31d819ced6b5f2a93db4518a1805d7 (diff) | |
download | FreeBSD-src-4a2859b3bea291207bb5f899037462724007ec61.zip FreeBSD-src-4a2859b3bea291207bb5f899037462724007ec61.tar.gz |
- Consolidate error handling in the cd9660 and udf mount routines.
- Always read the character device pointer while the associated devfs vnode
is locked. Also, use dev_ref() to obtain a new reference on the vnode for
the mountpoint. This reference is released on unmount. This mirrors the
earlier fix to FFS.
Reviewed by: kib
Diffstat (limited to 'sys/fs/udf')
-rw-r--r-- | sys/fs/udf/udf_vfsops.c | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/sys/fs/udf/udf_vfsops.c b/sys/fs/udf/udf_vfsops.c index 3d3b86d..d731918 100644 --- a/sys/fs/udf/udf_vfsops.c +++ b/sys/fs/udf/udf_vfsops.c @@ -301,8 +301,10 @@ udf_checktag(struct desc_tag *tag, uint16_t id) } static int -udf_mountfs(struct vnode *devvp, struct mount *mp) { +udf_mountfs(struct vnode *devvp, struct mount *mp) +{ struct buf *bp = NULL; + struct cdev *dev; struct anchor_vdp avdp; struct udf_mnt *udfmp = NULL; struct part_desc *pd; @@ -319,6 +321,8 @@ udf_mountfs(struct vnode *devvp, struct mount *mp) { struct g_consumer *cp; struct bufobj *bo; + dev = devvp->v_rdev; + dev_ref(dev); DROP_GIANT(); g_topology_lock(); error = g_vfs_open(devvp, &cp, "udf", 0); @@ -326,7 +330,7 @@ udf_mountfs(struct vnode *devvp, struct mount *mp) { PICKUP_GIANT(); VOP_UNLOCK(devvp, 0); if (error) - return error; + goto bail; bo = &devvp->v_bufobj; @@ -347,7 +351,7 @@ udf_mountfs(struct vnode *devvp, struct mount *mp) { mp->mnt_kern_flag |= MNTK_MPSAFE | MNTK_LOOKUP_SHARED; MNT_IUNLOCK(mp); udfmp->im_mountp = mp; - udfmp->im_dev = devvp->v_rdev; + udfmp->im_dev = dev; udfmp->im_devvp = devvp; udfmp->im_d2l = NULL; udfmp->im_cp = cp; @@ -364,12 +368,8 @@ udf_mountfs(struct vnode *devvp, struct mount *mp) { if (((logical_secsize % cp->provider->sectorsize) != 0) || (logical_secsize < cp->provider->sectorsize)) { - DROP_GIANT(); - g_topology_lock(); - g_vfs_close(cp); - g_topology_unlock(); - PICKUP_GIANT(); - return (EINVAL); + error = EINVAL; + goto bail; } bsize = cp->provider->sectorsize; @@ -492,11 +492,14 @@ bail: free(udfmp, M_UDFMOUNT); if (bp != NULL) brelse(bp); - DROP_GIANT(); - g_topology_lock(); - g_vfs_close(cp); - g_topology_unlock(); - PICKUP_GIANT(); + if (cp != NULL) { + DROP_GIANT(); + g_topology_lock(); + g_vfs_close(cp); + g_topology_unlock(); + PICKUP_GIANT(); + } + dev_rel(dev); return error; }; @@ -529,6 +532,7 @@ udf_unmount(struct mount *mp, int mntflags, struct thread *td) g_topology_unlock(); PICKUP_GIANT(); vrele(udfmp->im_devvp); + dev_rel(udfmp->im_dev); if (udfmp->s_table != NULL) free(udfmp->s_table, M_UDFMOUNT); |