geom_ctl.c (3117e5448429a5c7974888e6c1d1512ae437061d) | geom_ctl.c (d49d7ca5919cd4befb49517b79963db154c5c377) |
---|---|
1/*- 2 * Copyright (c) 2002 Poul-Henning Kamp 3 * Copyright (c) 2002 Networks Associates Technology, Inc. 4 * All rights reserved. 5 * 6 * This software was developed for the FreeBSD Project by Poul-Henning Kamp 7 * and NAI Labs, the Security Research Division of Network Associates, Inc. 8 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the --- 45 unchanged lines hidden (view full) --- 54#include <vm/vm_extern.h> 55 56#include <geom/geom.h> 57#include <geom/geom_int.h> 58#define GEOM_CTL_TABLE 1 59#include <geom/geom_ctl.h> 60#include <geom/geom_ext.h> 61 | 1/*- 2 * Copyright (c) 2002 Poul-Henning Kamp 3 * Copyright (c) 2002 Networks Associates Technology, Inc. 4 * All rights reserved. 5 * 6 * This software was developed for the FreeBSD Project by Poul-Henning Kamp 7 * and NAI Labs, the Security Research Division of Network Associates, Inc. 8 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the --- 45 unchanged lines hidden (view full) --- 54#include <vm/vm_extern.h> 55 56#include <geom/geom.h> 57#include <geom/geom_int.h> 58#define GEOM_CTL_TABLE 1 59#include <geom/geom_ctl.h> 60#include <geom/geom_ext.h> 61 |
62 63static g_access_t g_ctl_access; 64static g_start_t g_ctl_start; 65static void g_ctl_init(void); | |
66static d_ioctl_t g_ctl_ioctl; 67 | 62static d_ioctl_t g_ctl_ioctl; 63 |
68struct g_class g_ctl_class = { 69 "GEOMCTL", 70 NULL, 71 NULL, 72 G_CLASS_INITIALIZER | 64static struct cdevsw g_ctl_cdevsw = { 65 .d_open = nullopen, 66 .d_close = nullclose, 67 .d_ioctl = g_ctl_ioctl, 68 .d_name = "g_ctl", |
73}; 74 | 69}; 70 |
75DECLARE_GEOM_CLASS_INIT(g_ctl_class, g_ctl, g_ctl_init); 76 77/* 78 * We cannot do create our geom.ctl geom/provider in g_ctl_init() because 79 * the event thread has to finish adding our class first and that doesn't 80 * happen until later. We know however, that the events are processed in 81 * FIFO order, so scheduling g_ctl_init2() with g_call_me() is safe. 82 */ 83 84static void 85g_ctl_init2(void *p __unused) 86{ 87 struct g_geom *gp; 88 struct g_provider *pp; 89 90 g_topology_assert(); 91 gp = g_new_geomf(&g_ctl_class, "geom.ctl"); 92 gp->start = g_ctl_start; 93 gp->access = g_ctl_access; 94 pp = g_new_providerf(gp, "%s", gp->name); 95 pp->sectorsize = 512; 96 g_error_provider(pp, 0); 97} 98 99static void | 71void |
100g_ctl_init(void) 101{ | 72g_ctl_init(void) 73{ |
102 mtx_unlock(&Giant); 103 g_add_class(&g_ctl_class); 104 g_call_me(g_ctl_init2, NULL); 105 mtx_lock(&Giant); 106} | |
107 | 74 |
108/* 109 * We allow any kind of access. Access control is handled at the devfs 110 * level. 111 */ 112 113static int 114g_ctl_access(struct g_provider *pp, int r, int w, int e) 115{ 116 int error; 117 118 g_trace(G_T_ACCESS, "g_ctl_access(%s, %d, %d, %d)", 119 pp->name, r, w, e); 120 121 g_topology_assert(); 122 error = 0; 123 return (error); | 75 make_dev(&g_ctl_cdevsw, 0, 76 UID_ROOT, GID_OPERATOR, 0640, PATH_GEOM_CTL); |
124} 125 | 77} 78 |
126static void 127g_ctl_start(struct bio *bp) 128{ 129 struct g_ioctl *gio; 130 int error; 131 132 switch(bp->bio_cmd) { 133 case BIO_DELETE: 134 case BIO_READ: 135 case BIO_WRITE: 136 error = EOPNOTSUPP; 137 break; 138 case BIO_GETATTR: 139 case BIO_SETATTR: 140 if (strcmp(bp->bio_attribute, "GEOM::ioctl") || 141 bp->bio_length != sizeof *gio) { 142 error = EOPNOTSUPP; 143 break; 144 } 145 gio = (struct g_ioctl *)bp->bio_data; 146 gio->func = g_ctl_ioctl; 147 error = EDIRIOCTL; 148 break; 149 default: 150 error = EOPNOTSUPP; 151 break; 152 } 153 g_io_deliver(bp, error); 154 return; 155} 156 157/* 158 * All the stuff above is really just needed to get to the stuff below 159 */ 160 | |
161static int 162g_ctl_ioctl_configgeom(dev_t dev, u_long cmd, caddr_t data, int fflag, struct thread *td) 163{ 164 struct geomconfiggeom *gcp; 165 struct g_configargs ga; 166 int error; 167 168 error = 0; --- 197 unchanged lines hidden (view full) --- 366 req->reqt = &gcrt[i]; 367 break; 368 } 369 if (gcrt[i].request == GEOM_INVALID_REQUEST) 370 return (g_ctl_seterror(req, "Invalid request")); 371 error = geom_ctl_copyin(req); 372 if (error) 373 return (error); | 79static int 80g_ctl_ioctl_configgeom(dev_t dev, u_long cmd, caddr_t data, int fflag, struct thread *td) 81{ 82 struct geomconfiggeom *gcp; 83 struct g_configargs ga; 84 int error; 85 86 error = 0; --- 197 unchanged lines hidden (view full) --- 284 req->reqt = &gcrt[i]; 285 break; 286 } 287 if (gcrt[i].request == GEOM_INVALID_REQUEST) 288 return (g_ctl_seterror(req, "Invalid request")); 289 error = geom_ctl_copyin(req); 290 if (error) 291 return (error); |
292 req->reqt = &gcrt[i]; 293 g_stall_events(); |
|
374 geom_ctl_dump(req); | 294 geom_ctl_dump(req); |
295 g_release_events(); |
|
375 return (0); 376} 377 378static int 379g_ctl_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct thread *td) 380{ 381 int error; 382 | 296 return (0); 297} 298 299static int 300g_ctl_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct thread *td) 301{ 302 int error; 303 |
383 DROP_GIANT(); 384 g_topology_lock(); | |
385 switch(cmd) { 386 case GEOMCONFIGGEOM: | 304 switch(cmd) { 305 case GEOMCONFIGGEOM: |
306 DROP_GIANT(); 307 g_topology_lock(); |
|
387 error = g_ctl_ioctl_configgeom(dev, cmd, data, fflag, td); | 308 error = g_ctl_ioctl_configgeom(dev, cmd, data, fflag, td); |
309 g_topology_unlock(); 310 PICKUP_GIANT(); |
|
388 break; 389 case GEOM_CTL: 390 error = g_ctl_ioctl_ctl(dev, cmd, data, fflag, td); 391 break; 392 default: 393 error = ENOTTY; 394 break; 395 } | 311 break; 312 case GEOM_CTL: 313 error = g_ctl_ioctl_ctl(dev, cmd, data, fflag, td); 314 break; 315 default: 316 error = ENOTTY; 317 break; 318 } |
396 g_topology_unlock(); 397 PICKUP_GIANT(); | |
398 return (error); 399 400} | 319 return (error); 320 321} |