Home | History | Annotate | Line # | Download | only in kern
subr_disk_open.c revision 1.3.2.2
      1  1.3.2.2      yamt /*	$NetBSD: subr_disk_open.c,v 1.3.2.2 2012/05/23 10:08:11 yamt Exp $	*/
      2      1.1     pooka 
      3      1.1     pooka /*-
      4      1.1     pooka  * Copyright (c) 2006 The NetBSD Foundation, Inc.
      5      1.1     pooka  * All rights reserved.
      6      1.1     pooka  *
      7      1.1     pooka  * Redistribution and use in source and binary forms, with or without
      8      1.1     pooka  * modification, are permitted provided that the following conditions
      9      1.1     pooka  * are met:
     10      1.1     pooka  * 1. Redistributions of source code must retain the above copyright
     11      1.1     pooka  *    notice, this list of conditions and the following disclaimer.
     12      1.1     pooka  * 2. Redistributions in binary form must reproduce the above copyright
     13      1.1     pooka  *    notice, this list of conditions and the following disclaimer in the
     14      1.1     pooka  *    documentation and/or other materials provided with the distribution.
     15      1.1     pooka  *
     16      1.1     pooka  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17      1.1     pooka  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18      1.1     pooka  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19      1.1     pooka  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20      1.1     pooka  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21      1.1     pooka  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22      1.1     pooka  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23      1.1     pooka  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24      1.1     pooka  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25      1.1     pooka  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26      1.1     pooka  * POSSIBILITY OF SUCH DAMAGE.
     27      1.1     pooka  */
     28      1.1     pooka 
     29      1.1     pooka #include <sys/cdefs.h>
     30  1.3.2.2      yamt __KERNEL_RCSID(0, "$NetBSD: subr_disk_open.c,v 1.3.2.2 2012/05/23 10:08:11 yamt Exp $");
     31      1.1     pooka 
     32      1.1     pooka #include <sys/param.h>
     33      1.1     pooka #include <sys/conf.h>
     34      1.1     pooka #include <sys/device.h>
     35      1.1     pooka #include <sys/disk.h>
     36      1.1     pooka #include <sys/disklabel.h>
     37      1.1     pooka #include <sys/fcntl.h>
     38      1.1     pooka #include <sys/kauth.h>
     39      1.1     pooka #include <sys/vnode.h>
     40  1.3.2.1      yamt #include <miscfs/specfs/specdev.h>
     41      1.1     pooka 
     42      1.1     pooka struct vnode *
     43      1.1     pooka opendisk(struct device *dv)
     44      1.1     pooka {
     45  1.3.2.2      yamt 	devmajor_t bmajor;
     46  1.3.2.2      yamt 	int unit;
     47      1.1     pooka 	struct vnode *tmpvn;
     48      1.1     pooka 	int error;
     49      1.1     pooka 	dev_t dev;
     50      1.1     pooka 
     51      1.1     pooka 	/*
     52      1.1     pooka 	 * Lookup major number for disk block device.
     53      1.1     pooka 	 */
     54      1.1     pooka 	bmajor = devsw_name2blk(device_xname(dv), NULL, 0);
     55      1.1     pooka 	if (bmajor == -1)
     56      1.1     pooka 		return NULL;
     57      1.1     pooka 
     58  1.3.2.2      yamt 	unit = device_unit(dv);
     59      1.1     pooka 	/*
     60      1.1     pooka 	 * Fake a temporary vnode for the disk, open it, and read
     61      1.1     pooka 	 * and hash the sectors.
     62      1.1     pooka 	 */
     63  1.3.2.2      yamt 	dev = device_is_a(dv, "dk") ? makedev(bmajor, unit) :
     64  1.3.2.2      yamt 	    MAKEDISKDEV(bmajor, unit, RAW_PART);
     65      1.1     pooka 	if (bdevvp(dev, &tmpvn))
     66      1.1     pooka 		panic("%s: can't alloc vnode for %s", __func__,
     67      1.1     pooka 		    device_xname(dv));
     68      1.3  jmcneill 	error = VOP_OPEN(tmpvn, FREAD | FSILENT, NOCRED);
     69      1.1     pooka 	if (error) {
     70      1.1     pooka 		/*
     71      1.1     pooka 		 * Ignore errors caused by missing device, partition,
     72  1.3.2.1      yamt 		 * medium, or busy [presumably because of a wedge covering it]
     73      1.1     pooka 		 */
     74  1.3.2.1      yamt 		switch (error) {
     75  1.3.2.1      yamt 		case ENXIO:
     76  1.3.2.1      yamt 		case ENODEV:
     77  1.3.2.1      yamt 		case EBUSY:
     78  1.3.2.1      yamt 			break;
     79  1.3.2.1      yamt 		default:
     80      1.1     pooka 			printf("%s: can't open dev %s (%d)\n",
     81      1.1     pooka 			    __func__, device_xname(dv), error);
     82  1.3.2.1      yamt 			break;
     83  1.3.2.1      yamt 		}
     84      1.1     pooka 		vput(tmpvn);
     85      1.1     pooka 		return NULL;
     86      1.1     pooka 	}
     87      1.1     pooka 
     88      1.1     pooka 	return tmpvn;
     89      1.1     pooka }
     90      1.2   mlelstv 
     91      1.2   mlelstv int
     92      1.2   mlelstv getdisksize(struct vnode *vp, uint64_t *numsecp, unsigned *secsizep)
     93      1.2   mlelstv {
     94      1.2   mlelstv 	struct partinfo dpart;
     95      1.2   mlelstv 	struct dkwedge_info dkw;
     96      1.2   mlelstv 	struct disk *pdk;
     97      1.2   mlelstv 	int error;
     98      1.2   mlelstv 
     99      1.2   mlelstv 	error = VOP_IOCTL(vp, DIOCGPART, &dpart, FREAD, NOCRED);
    100      1.2   mlelstv 	if (error == 0) {
    101      1.2   mlelstv 		*secsizep = dpart.disklab->d_secsize;
    102      1.2   mlelstv 		*numsecp  = dpart.part->p_size;
    103      1.2   mlelstv 		return 0;
    104      1.2   mlelstv 	}
    105      1.2   mlelstv 
    106      1.2   mlelstv 	error = VOP_IOCTL(vp, DIOCGWEDGEINFO, &dkw, FREAD, NOCRED);
    107      1.2   mlelstv 	if (error == 0) {
    108      1.2   mlelstv 		pdk = disk_find(dkw.dkw_parent);
    109      1.2   mlelstv 		if (pdk != NULL) {
    110      1.2   mlelstv 			*secsizep = DEV_BSIZE << pdk->dk_blkshift;
    111      1.2   mlelstv 			*numsecp  = dkw.dkw_size;
    112      1.2   mlelstv 		} else
    113      1.2   mlelstv 			error = ENODEV;
    114      1.2   mlelstv 	}
    115      1.2   mlelstv 
    116      1.2   mlelstv 	return error;
    117      1.2   mlelstv }
    118  1.3.2.1      yamt 
    119  1.3.2.1      yamt int
    120  1.3.2.1      yamt getdiskinfo(struct vnode *vp, struct dkwedge_info *dkw)
    121  1.3.2.1      yamt {
    122  1.3.2.1      yamt 	struct partinfo dpart;
    123  1.3.2.1      yamt 	int error;
    124  1.3.2.1      yamt 	dev_t dev = vp->v_specnode->sn_rdev;
    125  1.3.2.1      yamt 
    126  1.3.2.1      yamt 	if (VOP_IOCTL(vp, DIOCGWEDGEINFO, dkw, FREAD, NOCRED) == 0)
    127  1.3.2.1      yamt 		return 0;
    128  1.3.2.1      yamt 
    129  1.3.2.1      yamt 	if ((error = VOP_IOCTL(vp, DIOCGPART, &dpart, FREAD, NOCRED)) != 0)
    130  1.3.2.1      yamt 		return error;
    131  1.3.2.1      yamt 
    132  1.3.2.1      yamt 	snprintf(dkw->dkw_devname, sizeof(dkw->dkw_devname), "%s%" PRId32 "%c",
    133  1.3.2.1      yamt 	    devsw_blk2name(major(dev)), DISKUNIT(dev), (char)DISKPART(dev) +
    134  1.3.2.1      yamt 	    'a');
    135  1.3.2.1      yamt 
    136  1.3.2.1      yamt 	dkw->dkw_wname[0] = '\0';
    137  1.3.2.1      yamt 
    138  1.3.2.1      yamt 	strlcpy(dkw->dkw_parent, dkw->dkw_devname, sizeof(dkw->dkw_parent));
    139  1.3.2.1      yamt 
    140  1.3.2.1      yamt 	dkw->dkw_size = dpart.part->p_size;
    141  1.3.2.1      yamt 	dkw->dkw_offset = dpart.part->p_offset;
    142  1.3.2.1      yamt 
    143  1.3.2.1      yamt 	strlcpy(dkw->dkw_ptype, getfstypename(dpart.part->p_fstype),
    144  1.3.2.1      yamt 	    sizeof(dkw->dkw_ptype));
    145  1.3.2.1      yamt 
    146  1.3.2.1      yamt 	return 0;
    147  1.3.2.1      yamt }
    148