diff options
-rw-r--r-- | drivers/staging/android/logger.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index 28b93d39a94e..a673ffa34aa3 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c | |||
@@ -420,7 +420,7 @@ static ssize_t logger_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
420 | struct logger_log *log = file_get_log(iocb->ki_filp); | 420 | struct logger_log *log = file_get_log(iocb->ki_filp); |
421 | struct logger_entry header; | 421 | struct logger_entry header; |
422 | struct timespec now; | 422 | struct timespec now; |
423 | size_t len, count; | 423 | size_t len, count, w_off; |
424 | 424 | ||
425 | count = min_t(size_t, iocb->ki_nbytes, LOGGER_ENTRY_MAX_PAYLOAD); | 425 | count = min_t(size_t, iocb->ki_nbytes, LOGGER_ENTRY_MAX_PAYLOAD); |
426 | 426 | ||
@@ -452,11 +452,14 @@ static ssize_t logger_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
452 | memcpy(log->buffer + log->w_off, &header, len); | 452 | memcpy(log->buffer + log->w_off, &header, len); |
453 | memcpy(log->buffer, (char *)&header + len, sizeof(header) - len); | 453 | memcpy(log->buffer, (char *)&header + len, sizeof(header) - len); |
454 | 454 | ||
455 | len = min(count, log->size - log->w_off); | 455 | /* Work with a copy until we are ready to commit the whole entry */ |
456 | w_off = logger_offset(log, log->w_off + sizeof(struct logger_entry)); | ||
456 | 457 | ||
457 | if (copy_from_iter(log->buffer + log->w_off, len, from) != len) { | 458 | len = min(count, log->size - w_off); |
459 | |||
460 | if (copy_from_iter(log->buffer + w_off, len, from) != len) { | ||
458 | /* | 461 | /* |
459 | * Note that by not updating w_off, this abandons the | 462 | * Note that by not updating log->w_off, this abandons the |
460 | * portion of the new entry that *was* successfully | 463 | * portion of the new entry that *was* successfully |
461 | * copied, just above. This is intentional to avoid | 464 | * copied, just above. This is intentional to avoid |
462 | * message corruption from missing fragments. | 465 | * message corruption from missing fragments. |
@@ -470,7 +473,7 @@ static ssize_t logger_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
470 | return -EFAULT; | 473 | return -EFAULT; |
471 | } | 474 | } |
472 | 475 | ||
473 | log->w_off = logger_offset(log, log->w_off + count); | 476 | log->w_off = logger_offset(log, w_off + count); |
474 | mutex_unlock(&log->mutex); | 477 | mutex_unlock(&log->mutex); |
475 | 478 | ||
476 | /* wake up any blocked readers */ | 479 | /* wake up any blocked readers */ |