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