switch logger to ->write_iter()
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 23 Aug 2014 16:20:37 +0000 (12:20 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 9 Oct 2014 06:39:09 +0000 (02:39 -0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
drivers/staging/android/logger.c

index 0bf0d24d12d5b8be9f077ba3422a07832ad5e7cb..28b93d39a94eb6b76b72d1db051b2f52b48175e7 100644 (file)
@@ -411,69 +411,18 @@ static void fix_up_readers(struct logger_log *log, size_t len)
 }
 
 /*
- * do_write_log - writes 'len' bytes from 'buf' to 'log'
- *
- * The caller needs to hold log->mutex.
- */
-static void do_write_log(struct logger_log *log, const void *buf, size_t count)
-{
-       size_t len;
-
-       len = min(count, log->size - log->w_off);
-       memcpy(log->buffer + log->w_off, buf, len);
-
-       if (count != len)
-               memcpy(log->buffer, buf + len, count - len);
-
-       log->w_off = logger_offset(log, log->w_off + count);
-
-}
-
-/*
- * do_write_log_user - writes 'len' bytes from the user-space buffer 'buf' to
- * the log 'log'
- *
- * The caller needs to hold log->mutex.
- *
- * Returns 'count' on success, negative error code on failure.
- */
-static ssize_t do_write_log_from_user(struct logger_log *log,
-                                     const void __user *buf, size_t count)
-{
-       size_t len;
-
-       len = min(count, log->size - log->w_off);
-       if (len && copy_from_user(log->buffer + log->w_off, buf, len))
-               return -EFAULT;
-
-       if (count != len)
-               if (copy_from_user(log->buffer, buf + len, count - len))
-                       /*
-                        * Note that by not updating w_off, this abandons the
-                        * portion of the new entry that *was* successfully
-                        * copied, just above.  This is intentional to avoid
-                        * message corruption from missing fragments.
-                        */
-                       return -EFAULT;
-
-       log->w_off = logger_offset(log, log->w_off + count);
-
-       return count;
-}
-
-/*
- * logger_aio_write - our write method, implementing support for write(),
+ * logger_write_iter - our write method, implementing support for write(),
  * writev(), and aio_write(). Writes are our fast path, and we try to optimize
  * them above all else.
  */
-static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
-                        unsigned long nr_segs, loff_t ppos)
+static ssize_t logger_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
        struct logger_log *log = file_get_log(iocb->ki_filp);
-       size_t orig;
        struct logger_entry header;
        struct timespec now;
-       ssize_t ret = 0;
+       size_t len, count;
+
+       count = min_t(size_t, iocb->ki_nbytes, LOGGER_ENTRY_MAX_PAYLOAD);
 
        now = current_kernel_time();
 
@@ -482,7 +431,7 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
        header.sec = now.tv_sec;
        header.nsec = now.tv_nsec;
        header.euid = current_euid();
-       header.len = min_t(size_t, iocb->ki_nbytes, LOGGER_ENTRY_MAX_PAYLOAD);
+       header.len = count;
        header.hdr_size = sizeof(struct logger_entry);
 
        /* null writes succeed, return zero */
@@ -491,8 +440,6 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
 
        mutex_lock(&log->mutex);
 
-       orig = log->w_off;
-
        /*
         * Fix up any readers, pulling them forward to the first readable
         * 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,
         */
        fix_up_readers(log, sizeof(struct logger_entry) + header.len);
 
-       do_write_log(log, &header, sizeof(struct logger_entry));
-
-       while (nr_segs-- > 0) {
-               size_t len;
-               ssize_t nr;
+       len = min(sizeof(header), log->size - log->w_off);
+       memcpy(log->buffer + log->w_off, &header, len);
+       memcpy(log->buffer, (char *)&header + len, sizeof(header) - len);
 
-               /* figure out how much of this vector we can keep */
-               len = min_t(size_t, iov->iov_len, header.len - ret);
+       len = min(count, log->size - log->w_off);
 
-               /* write out this segment's payload */
-               nr = do_write_log_from_user(log, iov->iov_base, len);
-               if (unlikely(nr < 0)) {
-                       log->w_off = orig;
-                       mutex_unlock(&log->mutex);
-                       return nr;
-               }
+       if (copy_from_iter(log->buffer + log->w_off, len, from) != len) {
+               /*
+                * Note that by not updating w_off, this abandons the
+                * portion of the new entry that *was* successfully
+                * copied, just above.  This is intentional to avoid
+                * message corruption from missing fragments.
+                */
+               mutex_unlock(&log->mutex);
+               return -EFAULT;
+       }
 
-               iov++;
-               ret += nr;
+       if (copy_from_iter(log->buffer, count - len, from) != count - len) {
+               mutex_unlock(&log->mutex);
+               return -EFAULT;
        }
 
+       log->w_off = logger_offset(log, log->w_off + count);
        mutex_unlock(&log->mutex);
 
        /* wake up any blocked readers */
        wake_up_interruptible(&log->wq);
 
-       return ret;
+       return len;
 }
 
 static 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)
 static const struct file_operations logger_fops = {
        .owner = THIS_MODULE,
        .read = logger_read,
-       .aio_write = logger_aio_write,
+       .write_iter = logger_write_iter,
        .poll = logger_poll,
        .unlocked_ioctl = logger_ioctl,
        .compat_ioctl = logger_ioctl,