aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-08-23 12:20:37 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-10-09 02:39:09 -0400
commitcd678fce428018dee0c9345ed63ebf9920d9902f (patch)
tree502f5ce646c454f76a57244118111580ecee032b /drivers/staging
parent512b2268156a4e15ebf897f9a883bdee153a54b7 (diff)
switch logger to ->write_iter()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/android/logger.c103
1 files changed, 26 insertions, 77 deletions
diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c
index 0bf0d24d12d5..28b93d39a94e 100644
--- a/drivers/staging/android/logger.c
+++ b/drivers/staging/android/logger.c
@@ -411,69 +411,18 @@ static void fix_up_readers(struct logger_log *log, size_t len)
411} 411}
412 412
413/* 413/*
414 * do_write_log - writes 'len' bytes from 'buf' to 'log' 414 * logger_write_iter - our write method, implementing support for write(),
415 *
416 * The caller needs to hold log->mutex.
417 */
418static void do_write_log(struct logger_log *log, const void *buf, size_t count)
419{
420 size_t len;
421
422 len = min(count, log->size - log->w_off);
423 memcpy(log->buffer + log->w_off, buf, len);
424
425 if (count != len)
426 memcpy(log->buffer, buf + len, count - len);
427
428 log->w_off = logger_offset(log, log->w_off + count);
429
430}
431
432/*
433 * do_write_log_user - writes 'len' bytes from the user-space buffer 'buf' to
434 * the log 'log'
435 *
436 * The caller needs to hold log->mutex.
437 *
438 * Returns 'count' on success, negative error code on failure.
439 */
440static ssize_t do_write_log_from_user(struct logger_log *log,
441 const void __user *buf, size_t count)
442{
443 size_t len;
444
445 len = min(count, log->size - log->w_off);
446 if (len && copy_from_user(log->buffer + log->w_off, buf, len))
447 return -EFAULT;
448
449 if (count != len)
450 if (copy_from_user(log->buffer, buf + len, count - len))
451 /*
452 * Note that by not updating w_off, this abandons the
453 * portion of the new entry that *was* successfully
454 * copied, just above. This is intentional to avoid
455 * message corruption from missing fragments.
456 */
457 return -EFAULT;
458
459 log->w_off = logger_offset(log, log->w_off + count);
460
461 return count;
462}
463
464/*
465 * logger_aio_write - our write method, implementing support for write(),
466 * writev(), and aio_write(). Writes are our fast path, and we try to optimize 415 * writev(), and aio_write(). Writes are our fast path, and we try to optimize
467 * them above all else. 416 * them above all else.
468 */ 417 */
469static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, 418static ssize_t logger_write_iter(struct kiocb *iocb, struct iov_iter *from)
470 unsigned long nr_segs, loff_t ppos)
471{ 419{
472 struct logger_log *log = file_get_log(iocb->ki_filp); 420 struct logger_log *log = file_get_log(iocb->ki_filp);
473 size_t orig;
474 struct logger_entry header; 421 struct logger_entry header;
475 struct timespec now; 422 struct timespec now;
476 ssize_t ret = 0; 423 size_t len, count;
424
425 count = min_t(size_t, iocb->ki_nbytes, LOGGER_ENTRY_MAX_PAYLOAD);
477 426
478 now = current_kernel_time(); 427 now = current_kernel_time();
479 428
@@ -482,7 +431,7 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
482 header.sec = now.tv_sec; 431 header.sec = now.tv_sec;
483 header.nsec = now.tv_nsec; 432 header.nsec = now.tv_nsec;
484 header.euid = current_euid(); 433 header.euid = current_euid();
485 header.len = min_t(size_t, iocb->ki_nbytes, LOGGER_ENTRY_MAX_PAYLOAD); 434 header.len = count;
486 header.hdr_size = sizeof(struct logger_entry); 435 header.hdr_size = sizeof(struct logger_entry);
487 436
488 /* null writes succeed, return zero */ 437 /* null writes succeed, return zero */
@@ -491,8 +440,6 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
491 440
492 mutex_lock(&log->mutex); 441 mutex_lock(&log->mutex);
493 442
494 orig = log->w_off;
495
496 /* 443 /*
497 * Fix up any readers, pulling them forward to the first readable 444 * Fix up any readers, pulling them forward to the first readable
498 * entry after (what will be) the new write offset. We do this now 445 * entry after (what will be) the new write offset. We do this now
@@ -501,33 +448,35 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
501 */ 448 */
502 fix_up_readers(log, sizeof(struct logger_entry) + header.len); 449 fix_up_readers(log, sizeof(struct logger_entry) + header.len);
503 450
504 do_write_log(log, &header, sizeof(struct logger_entry)); 451 len = min(sizeof(header), log->size - log->w_off);
505 452 memcpy(log->buffer + log->w_off, &header, len);
506 while (nr_segs-- > 0) { 453 memcpy(log->buffer, (char *)&header + len, sizeof(header) - len);
507 size_t len;
508 ssize_t nr;
509 454
510 /* figure out how much of this vector we can keep */ 455 len = min(count, log->size - log->w_off);
511 len = min_t(size_t, iov->iov_len, header.len - ret);
512 456
513 /* write out this segment's payload */ 457 if (copy_from_iter(log->buffer + log->w_off, len, from) != len) {
514 nr = do_write_log_from_user(log, iov->iov_base, len); 458 /*
515 if (unlikely(nr < 0)) { 459 * Note that by not updating w_off, this abandons the
516 log->w_off = orig; 460 * portion of the new entry that *was* successfully
517 mutex_unlock(&log->mutex); 461 * copied, just above. This is intentional to avoid
518 return nr; 462 * message corruption from missing fragments.
519 } 463 */
464 mutex_unlock(&log->mutex);
465 return -EFAULT;
466 }
520 467
521 iov++; 468 if (copy_from_iter(log->buffer, count - len, from) != count - len) {
522 ret += nr; 469 mutex_unlock(&log->mutex);
470 return -EFAULT;
523 } 471 }
524 472
473 log->w_off = logger_offset(log, log->w_off + count);
525 mutex_unlock(&log->mutex); 474 mutex_unlock(&log->mutex);
526 475
527 /* wake up any blocked readers */ 476 /* wake up any blocked readers */
528 wake_up_interruptible(&log->wq); 477 wake_up_interruptible(&log->wq);
529 478
530 return ret; 479 return len;
531} 480}
532 481
533static struct logger_log *get_log_from_minor(int minor) 482static struct logger_log *get_log_from_minor(int minor)
@@ -736,7 +685,7 @@ static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
736static const struct file_operations logger_fops = { 685static const struct file_operations logger_fops = {
737 .owner = THIS_MODULE, 686 .owner = THIS_MODULE,
738 .read = logger_read, 687 .read = logger_read,
739 .aio_write = logger_aio_write, 688 .write_iter = logger_write_iter,
740 .poll = logger_poll, 689 .poll = logger_poll,
741 .unlocked_ioctl = logger_ioctl, 690 .unlocked_ioctl = logger_ioctl,
742 .compat_ioctl = logger_ioctl, 691 .compat_ioctl = logger_ioctl,