Commit cd678fce authored by Al Viro's avatar Al Viro

switch logger to ->write_iter()

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 512b2268
...@@ -411,69 +411,18 @@ static void fix_up_readers(struct logger_log *log, size_t len) ...@@ -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' * logger_write_iter - our write method, implementing support for write(),
*
* 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(),
* writev(), and aio_write(). Writes are our fast path, and we try to optimize * writev(), and aio_write(). Writes are our fast path, and we try to optimize
* them above all else. * them above all else.
*/ */
static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, static ssize_t logger_write_iter(struct kiocb *iocb, struct iov_iter *from)
unsigned long nr_segs, loff_t ppos)
{ {
struct logger_log *log = file_get_log(iocb->ki_filp); struct logger_log *log = file_get_log(iocb->ki_filp);
size_t orig;
struct logger_entry header; struct logger_entry header;
struct timespec now; 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(); now = current_kernel_time();
...@@ -482,7 +431,7 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -482,7 +431,7 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
header.sec = now.tv_sec; header.sec = now.tv_sec;
header.nsec = now.tv_nsec; header.nsec = now.tv_nsec;
header.euid = current_euid(); 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); header.hdr_size = sizeof(struct logger_entry);
/* null writes succeed, return zero */ /* null writes succeed, return zero */
...@@ -491,8 +440,6 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -491,8 +440,6 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
mutex_lock(&log->mutex); mutex_lock(&log->mutex);
orig = log->w_off;
/* /*
* Fix up any readers, pulling them forward to the first readable * Fix up any readers, pulling them forward to the first readable
* entry after (what will be) the new write offset. We do this now * 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,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); fix_up_readers(log, sizeof(struct logger_entry) + header.len);
do_write_log(log, &header, sizeof(struct logger_entry)); 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);
while (nr_segs-- > 0) { len = min(count, log->size - log->w_off);
size_t len;
ssize_t nr;
/* figure out how much of this vector we can keep */
len = min_t(size_t, iov->iov_len, header.len - ret);
/* write out this segment's payload */ if (copy_from_iter(log->buffer + log->w_off, len, from) != len) {
nr = do_write_log_from_user(log, iov->iov_base, len); /*
if (unlikely(nr < 0)) { * Note that by not updating w_off, this abandons the
log->w_off = orig; * 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); mutex_unlock(&log->mutex);
return nr; return -EFAULT;
} }
iov++; if (copy_from_iter(log->buffer, count - len, from) != count - len) {
ret += nr; mutex_unlock(&log->mutex);
return -EFAULT;
} }
log->w_off = logger_offset(log, log->w_off + count);
mutex_unlock(&log->mutex); mutex_unlock(&log->mutex);
/* wake up any blocked readers */ /* wake up any blocked readers */
wake_up_interruptible(&log->wq); wake_up_interruptible(&log->wq);
return ret; return len;
} }
static struct logger_log *get_log_from_minor(int minor) 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) ...@@ -736,7 +685,7 @@ static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
static const struct file_operations logger_fops = { static const struct file_operations logger_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.read = logger_read, .read = logger_read,
.aio_write = logger_aio_write, .write_iter = logger_write_iter,
.poll = logger_poll, .poll = logger_poll,
.unlocked_ioctl = logger_ioctl, .unlocked_ioctl = logger_ioctl,
.compat_ioctl = logger_ioctl, .compat_ioctl = logger_ioctl,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment