Module Name: src Committed By: hannken Date: Wed Feb 6 09:33:17 UTC 2013
Modified Files: src/sys/dev: fss.c Log Message: Lookup the block device mounted on from the specfs_hash table. This doesn't belong here but makes it possible to pullup. Fixes PR kern/47020 (fss(4) panic) To generate a diff of this commit: cvs rdiff -u -r1.84 -r1.85 src/sys/dev/fss.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/fss.c diff -u src/sys/dev/fss.c:1.84 src/sys/dev/fss.c:1.85 --- src/sys/dev/fss.c:1.84 Wed Feb 6 09:29:46 2013 +++ src/sys/dev/fss.c Wed Feb 6 09:33:16 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: fss.c,v 1.84 2013/02/06 09:29:46 hannken Exp $ */ +/* $NetBSD: fss.c,v 1.85 2013/02/06 09:33:16 hannken Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.84 2013/02/06 09:29:46 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.85 2013/02/06 09:33:16 hannken Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -620,7 +620,7 @@ static int fss_create_files(struct fss_softc *sc, struct fss_set *fss, off_t *bsize, struct lwp *l) { - int error, bits, fsbsize; + int i, error, bits, fsbsize; uint64_t numsec; unsigned int secsize; struct timespec ts; @@ -691,25 +691,31 @@ fss_create_files(struct fss_softc *sc, s vrele(vp); /* - * Get the block device it is mounted on. + * Get the block device it is mounted on and its size. */ - error = namei_simple_kernel(sc->sc_mount->mnt_stat.f_mntfromname, - NSM_FOLLOW_NOEMULROOT, &vp); - if (error != 0) - return error; - - if (vp->v_type != VBLK) { - vrele(vp); + mutex_enter(&device_lock); + for (i = 0; i < SPECHSZ; i++) { + for (vp = specfs_hash[i]; vp; vp = vp->v_specnext) { + if (vp->v_type == VBLK && + vp == vp->v_specnode->sn_dev->sd_bdevvp && + vp->v_specmountpoint == sc->sc_mount) + break; + } + if (vp != NULL) + break; + } + if (vp == NULL) { + mutex_exit(&device_lock); return EINVAL; } - + mutex_enter(vp->v_interlock); + mutex_exit(&device_lock); + error = vget(vp, 0); + if (error) + return error; sc->sc_bdev = vp->v_rdev; - /* - * Get the block device size. - */ - error = getdisksize(vp, &numsec, &secsize); vrele(vp); if (error)