Example #1
0
static int scullc_defer_op(int write, struct kiocb *iocb, const struct iovec * iov, unsigned long count, loff_t pos)
{
	struct async_work *stuff;
	int result = 0;

	/* Copy now while we can access the buffer */
	if (write)
	{
		result = scullc_write(iocb->ki_filp, iov->iov_base, iov->iov_len, &pos);
	} else
	{
	result = scullc_read(iocb->ki_filp, iov->iov_base, iov->iov_len, &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->dwork, scullc_do_deferred_op);
	schedule_delayed_work(&stuff->dwork, HZ/100);
	return -EIOCBQUEUED;
}
Example #2
0
static int scullc_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 = scullc_write(iocb->ki_filp, buf, count, &pos);
	else
		result = scullc_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_WORK(&stuff->work, scullc_do_deferred_op, stuff);
	schedule_delayed_work(&stuff->work, HZ/100);
	return -EIOCBQUEUED;
}
Example #3
0
static ssize_t
ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
		unsigned long nr_segs, loff_t pos)
{
	struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
	int unaligned_aio = 0;
	int ret;

	trace_ext4_file_write(iocb->ki_filp->f_path.dentry, iocb->ki_left);
	/*
	 * If we have encountered a bitmap-format file, the size limit
	 * is smaller than s_maxbytes, which is for extent-mapped files.
	 */

	if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
		struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
		size_t length = iov_length(iov, nr_segs);

		if ((pos > sbi->s_bitmap_maxbytes ||
		    (pos == sbi->s_bitmap_maxbytes && length > 0)))
			return -EFBIG;

		if (pos + length > sbi->s_bitmap_maxbytes) {
			nr_segs = iov_shorten((struct iovec *)iov, nr_segs,
					      sbi->s_bitmap_maxbytes - pos);
		}
	} else if (unlikely((iocb->ki_filp->f_flags & O_DIRECT) &&
		   !is_sync_kiocb(iocb))) {
		unaligned_aio = ext4_unaligned_aio(inode, iov, nr_segs, pos);
	}

	/* Unaligned direct AIO must be serialized; see comment above */
	if (unaligned_aio) {
		static unsigned long unaligned_warn_time;

		/* Warn about this once per day */
		if (printk_timed_ratelimit(&unaligned_warn_time, 60*60*24*HZ))
			ext4_msg(inode->i_sb, KERN_WARNING,
				 "Unaligned AIO/DIO on inode %ld by %s; "
				 "performance will be poor.",
				 inode->i_ino, current->comm);
		mutex_lock(ext4_aio_mutex(inode));
		ext4_aiodio_wait(inode);
	}

	ret = generic_file_aio_write(iocb, iov, nr_segs, pos);

	if (unaligned_aio)
		mutex_unlock(ext4_aio_mutex(inode));

	trace_file_write_done(iocb->ki_filp);
	return ret;
}
Example #4
0
static ssize_t
ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
                unsigned long nr_segs, loff_t pos)
{
    struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
    int unaligned_aio = 0;
    int ret;

    trace_ext4_file_write(iocb->ki_filp->f_path.dentry, iocb->ki_left);

    if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
        struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
        size_t length = iov_length(iov, nr_segs);

        if ((pos > sbi->s_bitmap_maxbytes ||
                (pos == sbi->s_bitmap_maxbytes && length > 0)))
            return -EFBIG;

        if (pos + length > sbi->s_bitmap_maxbytes) {
            nr_segs = iov_shorten((struct iovec *)iov, nr_segs,
                                  sbi->s_bitmap_maxbytes - pos);
        }
    } else if (unlikely((iocb->ki_filp->f_flags & O_DIRECT) &&
                        !is_sync_kiocb(iocb))) {
        unaligned_aio = ext4_unaligned_aio(inode, iov, nr_segs, pos);
    }


    if (unaligned_aio) {
        static unsigned long unaligned_warn_time;


        if (printk_timed_ratelimit(&unaligned_warn_time, 60*60*24*HZ))
            ext4_msg(inode->i_sb, KERN_WARNING,
                     "Unaligned AIO/DIO on inode %ld by %s; "
                     "performance will be poor.",
                     inode->i_ino, current->comm);
        mutex_lock(ext4_aio_mutex(inode));
        ext4_aiodio_wait(inode);
    }

    ret = generic_file_aio_write(iocb, iov, nr_segs, pos);

    if (unaligned_aio)
        mutex_unlock(ext4_aio_mutex(inode));

    return ret;
}