xref: /openbsd-src/sys/dev/diskmap.c (revision 6876d15b92c792d3dc529afbd4ff8e773e4c1df5)
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