static int scullv_defer_op(int write, struct kiocb *iocb, char __user *buf, size_t count, loff_t pos) { struct async_work *stuff; int result; /* Copy now while we can access the buffer */ if (write) result = scullv_write(iocb->ki_filp, buf, count, &pos); else result = scullv_read(iocb->ki_filp, buf, count, &pos); /* If this is a synchronous IOCB, we return our status now. */ if (is_sync_kiocb(iocb)) return result; /* Otherwise defer the completion for a few milliseconds. */ stuff = kmalloc (sizeof (*stuff), GFP_KERNEL); if (stuff == NULL) return result; /* No memory, just complete now */ stuff->iocb = iocb; stuff->result = result; INIT_DELAYED_WORK(&stuff->work, scullv_do_deferred_op); schedule_delayed_work(&stuff->work, HZ/100); return -EIOCBQUEUED; }
int scullv_write_20 (struct inode *ino, struct file *f, const char *b, int c) { return (int)scullv_write(f, b, c, &f->f_pos); }