LOG: fix bugs in userland write handler

- report correct number of bytes written;
- correctly return partial writes on failure;
- do not overwrite result if there is a pending read.

Change-Id: I92aeeaee1eccb47c2aa2b6666a2f560c3cb17f42
This commit is contained in:
David van Moolenbroek 2015-07-24 20:54:27 +00:00
parent 0184c63535
commit 818c405ae1

View file

@ -126,7 +126,7 @@ subwrite(struct logdevice *log, size_t size, endpoint_t endpt,
cp_grant_id_t grant, char *localbuf) cp_grant_id_t grant, char *localbuf)
{ {
size_t count, offset; size_t count, offset;
int overflow, r; int overflow, r, result;
devminor_t minor; devminor_t minor;
char *buf; char *buf;
message m; message m;
@ -134,6 +134,7 @@ subwrite(struct logdevice *log, size_t size, endpoint_t endpt,
/* With a sufficiently large input size, we might wrap around the ring buffer /* With a sufficiently large input size, we might wrap around the ring buffer
* multiple times. * multiple times.
*/ */
result = 0;
for (offset = 0; offset < size; offset += count) { for (offset = 0; offset < size; offset += count) {
count = size - offset; count = size - offset;
@ -147,8 +148,11 @@ subwrite(struct logdevice *log, size_t size, endpoint_t endpt,
} }
else { else {
if((r=sys_safecopyfrom(endpt, grant, offset, if((r=sys_safecopyfrom(endpt, grant, offset,
(vir_bytes)buf, count)) != OK) (vir_bytes)buf, count)) != OK) {
break; /* do process partial write upon error */ /* return any partial success upon error */
result = (offset > 0) ? (int)offset : r;
break;
}
} }
LOGINC(log->log_write, count); LOGINC(log->log_write, count);
@ -160,7 +164,7 @@ subwrite(struct logdevice *log, size_t size, endpoint_t endpt,
LOGINC(log->log_read, overflow); LOGINC(log->log_read, overflow);
} }
r = offset; /* this will be the return value upon success */ result += (int)count;
} }
if (log->log_size > 0 && log->log_source != NONE) { if (log->log_size > 0 && log->log_source != NONE) {
@ -185,7 +189,7 @@ subwrite(struct logdevice *log, size_t size, endpoint_t endpt,
log->log_selected &= ~CDEV_OP_RD; log->log_selected &= ~CDEV_OP_RD;
} }
return r; return result;
} }
/*===========================================================================* /*===========================================================================*