Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
[safe/jmp/linux-2.6] / fs / read_write.c
index 9d1e76b..9c04852 100644 (file)
@@ -97,6 +97,23 @@ loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
 }
 EXPORT_SYMBOL(generic_file_llseek);
 
+/**
+ * noop_llseek - No Operation Performed llseek implementation
+ * @file:      file structure to seek on
+ * @offset:    file offset to seek to
+ * @origin:    type of seek
+ *
+ * This is an implementation of ->llseek useable for the rare special case when
+ * userspace expects the seek to succeed but the (device) file is actually not
+ * able to perform the seek. In this case you use noop_llseek() instead of
+ * falling back to the default implementation of ->llseek.
+ */
+loff_t noop_llseek(struct file *file, loff_t offset, int origin)
+{
+       return file->f_pos;
+}
+EXPORT_SYMBOL(noop_llseek);
+
 loff_t no_llseek(struct file *file, loff_t offset, int origin)
 {
        return -ESPIPE;
@@ -258,6 +275,7 @@ ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *pp
        init_sync_kiocb(&kiocb, filp);
        kiocb.ki_pos = *ppos;
        kiocb.ki_left = len;
+       kiocb.ki_nbytes = len;
 
        for (;;) {
                ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
@@ -313,6 +331,7 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof
        init_sync_kiocb(&kiocb, filp);
        kiocb.ki_pos = *ppos;
        kiocb.ki_left = len;
+       kiocb.ki_nbytes = len;
 
        for (;;) {
                ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
@@ -805,12 +824,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
                goto out;
        if (!(in_file->f_mode & FMODE_READ))
                goto fput_in;
-       retval = -EINVAL;
-       in_inode = in_file->f_path.dentry->d_inode;
-       if (!in_inode)
-               goto fput_in;
-       if (!in_file->f_op || !in_file->f_op->splice_read)
-               goto fput_in;
        retval = -ESPIPE;
        if (!ppos)
                ppos = &in_file->f_pos;
@@ -832,8 +845,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
        if (!(out_file->f_mode & FMODE_WRITE))
                goto fput_out;
        retval = -EINVAL;
-       if (!out_file->f_op || !out_file->f_op->sendpage)
-               goto fput_out;
+       in_inode = in_file->f_path.dentry->d_inode;
        out_inode = out_file->f_path.dentry->d_inode;
        retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
        if (retval < 0)
@@ -844,9 +856,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
                max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
 
        pos = *ppos;
-       retval = -EINVAL;
-       if (unlikely(pos < 0))
-               goto fput_out;
        if (unlikely(pos + count > max)) {
                retval = -EOVERFLOW;
                if (pos >= max)