Only publish configured devices.

Implemented write(). Not sure it works as it KDLs here on shutdown :^)


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21004 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol
2007-05-03 20:38:09 +00:00
parent 65c84f154b
commit ff517f433e
@@ -404,6 +404,13 @@ status_t nbd_post_request(struct nbd_device *dev, struct nbd_request_entry *req)
if (err < 0) if (err < 0)
return err; return err;
if (req->type == NBD_CMD_WRITE)
err = ksend(dev->sock, req->buffer, req->len, 0);
if (err < 0)
return err;
else
req->len = err;
err = nbd_queue_request(dev, req); err = nbd_queue_request(dev, req);
return err; return err;
} }
@@ -546,7 +553,7 @@ status_t nbd_control(cookie_t *cookie, uint32 op, void *data, size_t len) {
geom->head_count = 1; geom->head_count = 1;
geom->device_type = B_DISK; geom->device_type = B_DISK;
geom->removable = false; geom->removable = false;
geom->read_only = false; // XXX geom->read_only = cookie->dev->readonly;
geom->write_once = false; geom->write_once = false;
return B_OK; return B_OK;
} }
@@ -617,10 +624,11 @@ status_t nbd_read(cookie_t *cookie, off_t position, void *data, size_t *numbytes
if (semerr == B_OK) { if (semerr == B_OK) {
*numbytes = req->len; *numbytes = req->len;
memcpy(data, req->buffer, req->len); memcpy(data, req->buffer, req->len);
nbd_free_request(dev, req); err = B_OK;
if (*numbytes == 0 && req->reply.error) if (*numbytes == 0 && req->reply.error)
return B_ERROR; err = EIO;
return B_OK; nbd_free_request(dev, req);
return err;
} }
*numbytes = 0; *numbytes = 0;
@@ -637,15 +645,79 @@ err0:
} }
status_t nbd_write(cookie_t *cookie, off_t position, const void *data, size_t *numbytes) { status_t nbd_write(cookie_t *cookie, off_t position, const void *data, size_t *numbytes) {
PRINT((DP ">%s(%d, %Ld, , )\n", __FUNCTION__, WHICH(cookie->dev), position)); struct nbd_device *dev = cookie->dev;
(void)cookie; (void)position; (void)data; (void)numbytes; struct nbd_request_entry *req;
status_t err, semerr;
PRINT((DP ">%s(%d, %Ld, %ld, )\n", __FUNCTION__, WHICH(cookie->dev), position, *numbytes));
if (position < 0)
return EINVAL;
if (!data)
return EINVAL;
err = B_NOT_ALLOWED;
if (dev->readonly)
goto err0;
err = nbd_alloc_request(dev, &req, NBD_CMD_WRITE, position, *numbytes, data);
if (err)
goto err0;
//LOCK
err = benaphore_lock(&dev->ben);
if (err)
goto err1;
/* sending request+data must be atomic */
err = nbd_post_request(dev, req);
//UNLOCK
benaphore_unlock(&dev->ben);
if (err)
goto err2;
semerr = acquire_sem(req->sem);
//LOCK
err = benaphore_lock(&dev->ben);
if(err)
goto err3;
/* bad scenarii */
if (!req->replied)
req->discard = true;
else if (semerr)
nbd_free_request(dev, req);
//UNLOCK
benaphore_unlock(&dev->ben);
if (semerr == B_OK) {
*numbytes = req->len;
err = B_OK;
if (*numbytes == 0 && req->reply.error)
err = EIO;
nbd_free_request(dev, req);
return err;
}
*numbytes = 0; *numbytes = 0;
return EIO; return semerr;
err3:
err2:
err1:
nbd_free_request(dev, req);
err0:
*numbytes = 0;
return err;
} }
device_hooks nbd_hooks={ device_hooks nbd_hooks={
(device_open_hook)nbd_open, (device_open_hook)nbd_open,
nbd_close, (device_close_hook)nbd_close,
(device_free_hook)nbd_free, (device_free_hook)nbd_free,
(device_control_hook)nbd_control, (device_control_hook)nbd_control,
(device_read_hook)nbd_read, (device_read_hook)nbd_read,
@@ -659,7 +731,7 @@ device_hooks nbd_hooks={
#pragma mark ==== driver hooks ==== #pragma mark ==== driver hooks ====
static const char *nbd_name[MAX_NBDS+1] = { static char *nbd_name[MAX_NBDS+1] = {
NULL NULL
}; };
@@ -677,6 +749,7 @@ init_driver (void)
int i, j; int i, j;
// XXX: load settings // XXX: load settings
void *handle; void *handle;
char **names = nbd_name;
PRINT((DP ">%s()\n", __FUNCTION__)); PRINT((DP ">%s()\n", __FUNCTION__));
handle = load_driver_settings(DRV); handle = load_driver_settings(DRV);
@@ -704,16 +777,12 @@ init_driver (void)
#ifdef MOUNT_KLUDGE #ifdef MOUNT_KLUDGE
nbd_devices[i].kludge = -1; nbd_devices[i].kludge = -1;
#endif #endif
nbd_name[i] = malloc(DEVICE_NAME_MAX);
if (nbd_name[i] == NULL)
break;
sprintf(nbd_name[i], DEVICE_FMT, i);
}
nbd_name[i] = NULL; nbd_name[i] = NULL;
}
for (i = 0; i < MAX_NBDS; i++) { for (i = 0; i < MAX_NBDS; i++) {
driver_settings *settings = get_driver_settings(handle); const driver_settings *settings = get_driver_settings(handle);
driver_parameter *p; driver_parameter *p = NULL;
char keyname[10]; char keyname[10];
char *v; char *v;
sprintf(keyname, "%d", i); sprintf(keyname, "%d", i);
@@ -732,11 +801,16 @@ init_driver (void)
nbd_devices[i].server.sin_family = AF_INET; nbd_devices[i].server.sin_family = AF_INET;
kinet_aton(p->parameters[j].values[0], &nbd_devices[i].server.sin_addr); kinet_aton(p->parameters[j].values[0], &nbd_devices[i].server.sin_addr);
nbd_devices[i].server.sin_port = htons(atoi(p->parameters[j].values[1])); nbd_devices[i].server.sin_port = htons(atoi(p->parameters[j].values[1]));
dprintf(DP " configured [%d]\n", i);
*(names) = malloc(DEVICE_NAME_MAX);
if (*(names) == NULL)
return ENOMEM;
sprintf(*(names++), DEVICE_FMT, i);
nbd_devices[i].valid = true; nbd_devices[i].valid = true;
} }
} }
} }
*names = NULL;
unload_driver_settings(handle); unload_driver_settings(handle);
return B_OK; return B_OK;
@@ -762,7 +836,7 @@ const char**
publish_devices() publish_devices()
{ {
PRINT((DP ">%s()\n", __FUNCTION__)); PRINT((DP ">%s()\n", __FUNCTION__));
return nbd_name; return (const char **)nbd_name;
} }
device_hooks* device_hooks*
@@ -778,7 +852,9 @@ nbd_find_device(const char* name)
int i; int i;
PRINT((DP ">%s(%s)\n", __FUNCTION__, name)); PRINT((DP ">%s(%s)\n", __FUNCTION__, name));
for (i = 0; i < MAX_NBDS; i++) { for (i = 0; i < MAX_NBDS; i++) {
if (!strcmp(nbd_name[i], name)) char buf[DEVICE_NAME_MAX];
sprintf(buf, DEVICE_FMT, i);
if (!strcmp(buf, name))
return &nbd_devices[i]; return &nbd_devices[i];
} }
return NULL; return NULL;