aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/udf
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2009-02-11 22:22:26 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2009-02-11 22:22:26 +0000
commit0b2ab5ec8e17f25f101d4f04016043be787f3def (patch)
treeea18d4d8d21ad49a6495ab52cb37b81e8d2e1eac /sys/fs/udf
parentee445a69c5ef5834941792facf42ff0ef1e5e7b0 (diff)
downloadsrc-0b2ab5ec8e17f25f101d4f04016043be787f3def.tar.gz
src-0b2ab5ec8e17f25f101d4f04016043be787f3def.zip
- 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
Notes
Notes: svn path=/head/; revision=188502
Diffstat (limited to 'sys/fs/udf')
-rw-r--r--sys/fs/udf/udf_vfsops.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/sys/fs/udf/udf_vfsops.c b/sys/fs/udf/udf_vfsops.c
index 3d3b86d91195..d73191845b71 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);