1 /* $OpenBSD: diskmap.c,v 1.3 2011/01/12 23:18:56 thib Exp $ */ 2 3 /* 4 * Copyright (c) 2009, 2010 Joel Sing <jsing@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * Disk mapper. 21 */ 22 23 #include <sys/param.h> 24 #include <sys/types.h> 25 #include <sys/systm.h> 26 #include <sys/device.h> 27 #include <sys/errno.h> 28 #include <sys/buf.h> 29 #include <sys/conf.h> 30 #include <sys/dkio.h> 31 #include <sys/disk.h> 32 #include <sys/disklabel.h> 33 #include <sys/file.h> 34 #include <sys/filedesc.h> 35 #include <sys/malloc.h> 36 #include <sys/namei.h> 37 #include <sys/proc.h> 38 #include <sys/vnode.h> 39 40 int 41 diskmapopen(dev_t dev, int flag, int fmt, struct proc *p) 42 { 43 return 0; 44 } 45 46 int 47 diskmapclose(dev_t dev, int flag, int fmt, struct proc *p) 48 { 49 return 0; 50 } 51 52 int 53 diskmapioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) 54 { 55 struct dk_diskmap *dm; 56 struct nameidata ndp; 57 struct filedesc *fdp; 58 struct file *fp; 59 struct vnode *vp = NULL, *ovp; 60 char *devname; 61 int fd, error = EINVAL; 62 63 if (cmd != DIOCMAP) 64 return EINVAL; 65 66 /* 67 * Map a request for a disk to the correct device. We should be 68 * supplied with either a diskname or a disklabel UID. 69 */ 70 71 dm = (struct dk_diskmap *)addr; 72 fd = dm->fd; 73 devname = malloc(PATH_MAX, M_DEVBUF, M_WAITOK); 74 if (copyinstr(dm->device, devname, PATH_MAX, NULL)) 75 goto invalid; 76 if (disk_map(devname, devname, PATH_MAX, dm->flags) == 0) 77 if (copyoutstr(devname, dm->device, PATH_MAX, NULL)) 78 goto invalid; 79 80 /* Attempt to open actual device. */ 81 fdp = p->p_fd; 82 fdplock(fdp); 83 84 if ((u_int)fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL) { 85 error = EINVAL; 86 goto bad; 87 } 88 89 if (FILE_IS_USABLE(fp) == NULL) { 90 error = EINVAL; 91 goto bad; 92 } 93 94 ndp.ni_segflg = UIO_SYSSPACE; 95 ndp.ni_dirp = devname; 96 ndp.ni_cnd.cn_proc = p; 97 if ((error = vn_open(&ndp, fp->f_flag, 0)) != 0) 98 goto bad; 99 100 vp = ndp.ni_vp; 101 102 /* Close the original vnode. */ 103 ovp = (struct vnode *)fp->f_data; 104 if (fp->f_flag & FWRITE) 105 ovp->v_writecount--; 106 107 if (ovp->v_writecount == 0) { 108 vn_lock(ovp, LK_EXCLUSIVE | LK_RETRY, p); 109 VOP_CLOSE(ovp, fp->f_flag, p->p_ucred, p); 110 vput(ovp); 111 } 112 113 fp->f_type = DTYPE_VNODE; 114 fp->f_ops = &vnops; 115 fp->f_data = (caddr_t)vp; 116 fp->f_offset = 0; 117 fp->f_rxfer = 0; 118 fp->f_wxfer = 0; 119 fp->f_seek = 0; 120 fp->f_rbytes = 0; 121 fp->f_wbytes = 0; 122 123 VOP_UNLOCK(vp, 0, p); 124 125 free(devname, M_DEVBUF); 126 fdpunlock(fdp); 127 128 return 0; 129 130 bad: 131 if (vp) 132 vput(vp); 133 134 fdpunlock(fdp); 135 136 invalid: 137 free(devname, M_DEVBUF); 138 139 return (error); 140 } 141 142 int 143 diskmapread(dev_t dev, struct uio *uio, int flag) 144 { 145 return ENXIO; 146 } 147 148 int 149 diskmapwrite(dev_t dev, struct uio *uio, int flag) 150 { 151 return ENXIO; 152 } 153