20 #define pr_fmt(fmt) "logger: " fmt
22 #include <linux/sched.h>
23 #include <linux/module.h>
27 #include <linux/poll.h>
28 #include <linux/slab.h>
29 #include <linux/time.h>
33 #include <asm/ioctls.h>
84 return n & (log->
size - 1);
167 reader->
r_off = logger_offset(log, reader->
r_off + count);
184 static ssize_t logger_read(
struct file *file,
char __user *buf,
185 size_t count, loff_t *
pos)
229 ret = get_entry_len(log, reader->
r_off);
236 ret = do_read_log_to_user(log, reader, buf, ret);
250 static size_t get_next_entry(
struct logger_log *log,
size_t off,
size_t len)
255 size_t nr = get_entry_len(log, off);
256 off = logger_offset(log, off + nr);
258 }
while (count < len);
277 static inline int is_between(
size_t a,
size_t b,
size_t c)
300 static void fix_up_readers(
struct logger_log *log,
size_t len)
302 size_t old = log->
w_off;
303 size_t new = logger_offset(log, old + len);
306 if (is_between(old,
new, log->
head))
307 log->
head = get_next_entry(log, log->
head, len);
310 if (is_between(old, new, reader->
r_off))
311 reader->
r_off = get_next_entry(log, reader->
r_off, len);
323 len =
min(count, log->size - log->w_off);
324 memcpy(log->buffer + log->w_off, buf, len);
327 memcpy(log->buffer, buf + len, count - len);
329 log->w_off = logger_offset(log, log->w_off + count);
342 const void __user *buf,
size_t count)
360 log->
w_off = logger_offset(log, log->
w_off + count);
371 unsigned long nr_segs, loff_t ppos)
374 size_t orig = log->
w_off;
384 header.nsec = now.tv_nsec;
403 while (nr_segs-- > 0) {
411 nr = do_write_log_from_user(log, iov->
iov_base, len);
430 static struct logger_log *get_log_from_minor(
int minor)
435 if (log->
misc.minor == minor)
454 log = get_log_from_minor(
MINOR(inode->i_rdev));
466 INIT_LIST_HEAD(&reader->
list);
473 file->private_data = reader;
475 file->private_data =
log;
485 static int logger_release(
struct inode *
ignored,
struct file *file)
510 static unsigned int logger_poll(
struct file *file,
poll_table *
wait)
522 poll_wait(file, &log->
wq, wait);
532 static long logger_ioctl(
struct file *file,
unsigned int cmd,
unsigned long arg)
562 ret = get_entry_len(log, reader->
r_off);
572 reader->r_off = log->w_off;
573 log->
head = log->w_off;
586 .aio_write = logger_aio_write,
588 .unlocked_ioctl = logger_ioctl,
589 .compat_ioctl = logger_ioctl,
591 .release = logger_release,
598 static int __init create_log(
char *log_name,
int size)
611 goto out_free_buffer;
617 if (log->
misc.name == NULL) {
622 log->
misc.fops = &logger_fops;
632 INIT_LIST_HEAD(&log->
logs);
638 pr_err(
"failed to register misc device for log '%s'!\n",
643 pr_info(
"created %luK log '%s'\n",
644 (
unsigned long) log->
size >> 10, log->
misc.name);
656 static int __init logger_init(
void)