summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavier Martinez Canillas <martinez.javier@gmail.com>2010-11-28 03:49:26 +0100
committerJavier Martinez Canillas <martinez.javier@gmail.com>2010-11-28 03:49:26 +0100
commitf0c09c6e5adbf9c35c49dc02594fcfaa64a42994 (patch)
tree8cdf6c936e74b13548994dc4ef3e0fd87e2bff7f
parentc66395c972f3588db110f6545ccfe85318df19e8 (diff)
downloadldd3-f0c09c6e5adbf9c35c49dc02594fcfaa64a42994.tar.gz
scullc: main: Change work_struct to delayed_work and change scullc_aio_[read | write] handlers
-rw-r--r--scullc/main.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/scullc/main.c b/scullc/main.c
index abd43ea..0cfe219 100644
--- a/scullc/main.c
+++ b/scullc/main.c
@@ -400,31 +400,40 @@ loff_t scullc_llseek (struct file *filp, loff_t off, int whence)
struct async_work {
struct kiocb *iocb;
int result;
- struct work_struct work;
+ struct delayed_work work;
};
/*
* "Complete" an asynchronous operation.
*/
-static void scullc_do_deferred_op(void *p)
+static void scullc_do_deferred_op(struct work_struct *work)
{
- struct async_work *stuff = (struct async_work *) p;
+ struct async_work *stuff = container_of(work, struct async_work, work.work);
aio_complete(stuff->iocb, stuff->result, 0);
kfree(stuff);
}
-static int scullc_defer_op(int write, struct kiocb *iocb, char __user *buf,
- size_t count, loff_t pos)
+static int scullc_defer_op(int write, struct kiocb *iocb, const struct iovec *iovec,
+ unsigned long nr_segs, loff_t pos)
{
struct async_work *stuff;
- int result;
+ size_t result = 0;
+ size_t len = 0;
+ unsigned long seg = 0;
/* Copy now while we can access the buffer */
- if (write)
- result = scullc_write(iocb->ki_filp, buf, count, &pos);
- else
- result = scullc_read(iocb->ki_filp, buf, count, &pos);
+ for (seg = 0; seg < nr_segs; seg++) {
+ if (write)
+ len = scullc_write(iocb->ki_filp, iovec[seg].iov_base, iovec[seg].iov_len, &pos);
+ else
+ len = scullc_read(iocb->ki_filp, iovec[seg].iov_base, iovec[seg].iov_len, &pos);
+
+ if (result < 0)
+ return result;
+
+ result += len;
+ }
/* If this is a synchronous IOCB, we return our status now. */
if (is_sync_kiocb(iocb))
@@ -436,22 +445,22 @@ static int scullc_defer_op(int write, struct kiocb *iocb, char __user *buf,
return result; /* No memory, just complete now */
stuff->iocb = iocb;
stuff->result = result;
- INIT_WORK(&stuff->work, scullc_do_deferred_op, stuff);
+ INIT_DELAYED_WORK(&stuff->work, scullc_do_deferred_op);
schedule_delayed_work(&stuff->work, HZ/100);
return -EIOCBQUEUED;
}
-static ssize_t scullc_aio_read(struct kiocb *iocb, char __user *buf, size_t count,
- loff_t pos)
+static ssize_t scullc_aio_read(struct kiocb *iocb, const struct iovec *iovec,
+ unsigned long nr_segs, loff_t pos)
{
- return scullc_defer_op(0, iocb, buf, count, pos);
+ return scullc_defer_op(0, iocb, iovec, nr_segs, pos);
}
-static ssize_t scullc_aio_write(struct kiocb *iocb, const char __user *buf,
- size_t count, loff_t pos)
+static ssize_t scullc_aio_write(struct kiocb *iocb, const struct iovec *iovec,
+ unsigned long nr_segs, loff_t pos)
{
- return scullc_defer_op(1, iocb, (char __user *) buf, count, pos);
+ return scullc_defer_op(1, iocb, iovec, nr_segs, pos);
}