Line data Source code
1 : /* $OpenBSD: diskmap.c,v 1.24 2018/08/20 14:59:02 visa 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/systm.h>
25 : #include <sys/device.h>
26 : #include <sys/errno.h>
27 : #include <sys/conf.h>
28 : #include <sys/dkio.h>
29 : #include <sys/disk.h>
30 : #include <sys/disklabel.h>
31 : #include <sys/fcntl.h>
32 : #include <sys/file.h>
33 : #include <sys/filedesc.h>
34 : #include <sys/lock.h>
35 : #include <sys/malloc.h>
36 : #include <sys/namei.h>
37 : #include <sys/proc.h>
38 : #include <sys/vnode.h>
39 : #include <sys/pledge.h>
40 : #include <sys/namei.h>
41 :
42 : int
43 0 : diskmapopen(dev_t dev, int flag, int fmt, struct proc *p)
44 : {
45 0 : return 0;
46 : }
47 :
48 : int
49 0 : diskmapclose(dev_t dev, int flag, int fmt, struct proc *p)
50 : {
51 0 : return 0;
52 : }
53 :
54 : int
55 0 : diskmapioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
56 : {
57 : struct dk_diskmap *dm;
58 0 : struct nameidata ndp;
59 0 : struct filedesc *fdp = p->p_fd;
60 0 : struct file *fp0 = NULL, *fp = NULL;
61 : struct vnode *vp = NULL;
62 : char *devname, flags;
63 : int fd, error = EINVAL;
64 :
65 0 : if (cmd != DIOCMAP)
66 0 : return EINVAL;
67 :
68 : /*
69 : * Map a request for a disk to the correct device. We should be
70 : * supplied with either a diskname or a disklabel UID.
71 : */
72 :
73 0 : dm = (struct dk_diskmap *)addr;
74 0 : fd = dm->fd;
75 0 : devname = malloc(PATH_MAX, M_DEVBUF, M_WAITOK);
76 0 : if (copyinstr(dm->device, devname, PATH_MAX, NULL))
77 : goto invalid;
78 0 : if (disk_map(devname, devname, PATH_MAX, dm->flags) == 0)
79 0 : if (copyoutstr(devname, dm->device, PATH_MAX, NULL))
80 : goto invalid;
81 :
82 : /* Attempt to open actual device. */
83 0 : if ((error = getvnode(p, fd, &fp0)) != 0)
84 : goto invalid;
85 :
86 0 : NDINIT(&ndp, 0, 0, UIO_SYSSPACE, devname, p);
87 0 : ndp.ni_pledge = PLEDGE_RPATH;
88 0 : ndp.ni_unveil = UNVEIL_READ;
89 0 : if ((error = vn_open(&ndp, fp0->f_flag, 0)) != 0)
90 : goto invalid;
91 :
92 0 : vp = ndp.ni_vp;
93 0 : VOP_UNLOCK(vp);
94 :
95 0 : fdplock(fdp);
96 : /*
97 : * Stop here if the 'struct file *' has been replaced,
98 : * for example by another thread calling dup2(2), while
99 : * this thread was sleeping in vn_open().
100 : *
101 : * Note that this would not happen for correct usages of
102 : * "/dev/diskmap".
103 : */
104 0 : if (fdp->fd_ofiles[fd] != fp0) {
105 : error = EAGAIN;
106 0 : goto bad;
107 : }
108 :
109 0 : fp = fnew(p);
110 0 : if (fp == NULL) {
111 : error = ENFILE;
112 0 : goto bad;
113 : }
114 :
115 : /* Zap old file. */
116 0 : mtx_enter(&fdp->fd_fplock);
117 0 : KASSERT(fdp->fd_ofiles[fd] == fp0);
118 0 : flags = fdp->fd_ofileflags[fd];
119 0 : fdp->fd_ofiles[fd] = NULL;
120 0 : fdp->fd_ofileflags[fd] = 0;
121 0 : mtx_leave(&fdp->fd_fplock);
122 :
123 : /* Insert new file. */
124 0 : fp->f_flag = fp0->f_flag;
125 0 : fp->f_type = DTYPE_VNODE;
126 0 : fp->f_ops = &vnops;
127 0 : fp->f_data = (caddr_t)vp;
128 0 : fdinsert(fdp, fd, flags, fp);
129 0 : fdpunlock(fdp);
130 :
131 0 : closef(fp0, p);
132 0 : free(devname, M_DEVBUF, PATH_MAX);
133 :
134 0 : return 0;
135 :
136 : bad:
137 0 : fdpunlock(fdp);
138 :
139 0 : if (vp)
140 0 : vrele(vp);
141 : invalid:
142 0 : if (fp0)
143 0 : FRELE(fp0, p);
144 :
145 0 : free(devname, M_DEVBUF, PATH_MAX);
146 :
147 0 : return (error);
148 0 : }
149 :
150 : int
151 0 : diskmapread(dev_t dev, struct uio *uio, int flag)
152 : {
153 0 : return ENXIO;
154 : }
155 :
156 : int
157 0 : diskmapwrite(dev_t dev, struct uio *uio, int flag)
158 : {
159 0 : return ENXIO;
160 : }
|