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