From 12982f31a233250c7a62b17fb4bd13594cb78777 Mon Sep 17 00:00:00 2001 From: "Bjoern B. Brandenburg" Date: Sat, 23 Jul 2011 23:38:57 -0400 Subject: ftdev: let bufffer-specific code handle writes from userspace This allows us to splice in information into logs from events that were recorded in userspace. --- include/litmus/ftdev.h | 5 ++++- litmus/ftdev.c | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/include/litmus/ftdev.h b/include/litmus/ftdev.h index 348387e9adf9..0b959874dd70 100644 --- a/include/litmus/ftdev.h +++ b/include/litmus/ftdev.h @@ -16,7 +16,8 @@ typedef int (*ftdev_can_open_t)(struct ftdev* dev, unsigned int buf_no); /* return 0 on success, otherwise -$REASON */ typedef int (*ftdev_alloc_t)(struct ftdev* dev, unsigned int buf_no); typedef void (*ftdev_free_t)(struct ftdev* dev, unsigned int buf_no); - +/* Let devices handle writes from userspace. No synchronization provided. */ +typedef ssize_t (*ftdev_write_t)(struct ft_buffer* buf, size_t len, const char __user *from); struct ftdev_event; @@ -27,6 +28,7 @@ struct ftdev_minor { /* FIXME: filter for authorized events */ struct ftdev_event* events; struct device* device; + struct ftdev* ftdev; }; struct ftdev { @@ -39,6 +41,7 @@ struct ftdev { ftdev_alloc_t alloc; ftdev_free_t free; ftdev_can_open_t can_open; + ftdev_write_t write; }; struct ft_buffer* alloc_ft_buffer(unsigned int count, size_t size); diff --git a/litmus/ftdev.c b/litmus/ftdev.c index 216dc0b4cb94..06fcf4cf77dc 100644 --- a/litmus/ftdev.c +++ b/litmus/ftdev.c @@ -114,6 +114,7 @@ static int ftdev_open(struct inode *in, struct file *filp) goto out; ftdm = ftdev->minor + buf_idx; + ftdm->ftdev = ftdev; filp->private_data = ftdm; if (mutex_lock_interruptible(&ftdm->lock)) { @@ -284,11 +285,25 @@ out: return err; } +static ssize_t ftdev_write(struct file *filp, const char __user *from, + size_t len, loff_t *f_pos) +{ + struct ftdev_minor* ftdm = filp->private_data; + ssize_t err = -EINVAL; + struct ftdev* ftdev = ftdm->ftdev; + + /* dispatch write to buffer-specific code, if available */ + if (ftdev->write) + err = ftdev->write(ftdm->buf, len, from); + + return err; +} struct file_operations ftdev_fops = { .owner = THIS_MODULE, .open = ftdev_open, .release = ftdev_release, + .write = ftdev_write, .read = ftdev_read, .unlocked_ioctl = ftdev_ioctl, }; @@ -308,6 +323,7 @@ int ftdev_init( struct ftdev* ftdev, struct module* owner, ftdev->alloc = NULL; ftdev->free = NULL; ftdev->can_open = NULL; + ftdev->write = NULL; ftdev->minor = kcalloc(ftdev->minor_cnt, sizeof(*ftdev->minor), GFP_KERNEL); -- cgit v1.2.2