nfsd4: reshuffle lease-setting code to allow reuse
[safe/jmp/linux-2.6] / fs / splice.c
index 73766d2..3920866 100644 (file)
@@ -502,8 +502,10 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
                len = left;
 
        ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
-       if (ret > 0)
+       if (ret > 0) {
                *ppos += ret;
+               file_accessed(in);
+       }
 
        return ret;
 }
@@ -646,9 +648,11 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
        ret = buf->ops->confirm(pipe, buf);
        if (!ret) {
                more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len;
-
-               ret = file->f_op->sendpage(file, buf->page, buf->offset,
-                                          sd->len, &pos, more);
+               if (file->f_op && file->f_op->sendpage)
+                       ret = file->f_op->sendpage(file, buf->page, buf->offset,
+                                                  sd->len, &pos, more);
+               else
+                       ret = -EINVAL;
        }
 
        return ret;
@@ -963,8 +967,10 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
 
                mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
                ret = file_remove_suid(out);
-               if (!ret)
+               if (!ret) {
+                       file_update_time(out);
                        ret = splice_from_pipe_feed(pipe, &sd, pipe_to_file);
+               }
                mutex_unlock(&inode->i_mutex);
        } while (ret > 0);
        splice_from_pipe_end(pipe, &sd);
@@ -976,25 +982,15 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
 
        if (ret > 0) {
                unsigned long nr_pages;
+               int err;
 
-               *ppos += ret;
                nr_pages = (ret + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 
-               /*
-                * If file or inode is SYNC and we actually wrote some data,
-                * sync it.
-                */
-               if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
-                       int err;
-
-                       mutex_lock(&inode->i_mutex);
-                       err = generic_osync_inode(inode, mapping,
-                                                 OSYNC_METADATA|OSYNC_DATA);
-                       mutex_unlock(&inode->i_mutex);
-
-                       if (err)
-                               ret = err;
-               }
+               err = generic_write_sync(out, *ppos, ret);
+               if (err)
+                       ret = err;
+               else
+                       *ppos += ret;
                balance_dirty_pages_ratelimited_nr(mapping, nr_pages);
        }
 
@@ -1074,8 +1070,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
        if (unlikely(ret < 0))
                return ret;
 
-       splice_write = out->f_op->splice_write;
-       if (!splice_write)
+       if (out->f_op && out->f_op->splice_write)
+               splice_write = out->f_op->splice_write;
+       else
                splice_write = default_file_splice_write;
 
        return splice_write(pipe, out, ppos, len, flags);
@@ -1099,8 +1096,9 @@ static long do_splice_to(struct file *in, loff_t *ppos,
        if (unlikely(ret < 0))
                return ret;
 
-       splice_read = in->f_op->splice_read;
-       if (!splice_read)
+       if (in->f_op && in->f_op->splice_read)
+               splice_read = in->f_op->splice_read;
+       else
                splice_read = default_file_splice_read;
 
        return splice_read(in, ppos, pipe, len, flags);
@@ -1322,7 +1320,8 @@ static long do_splice(struct file *in, loff_t __user *off_in,
                if (off_in)
                        return -ESPIPE;
                if (off_out) {
-                       if (out->f_op->llseek == no_llseek)
+                       if (!out->f_op || !out->f_op->llseek ||
+                           out->f_op->llseek == no_llseek)
                                return -EINVAL;
                        if (copy_from_user(&offset, off_out, sizeof(loff_t)))
                                return -EFAULT;
@@ -1342,7 +1341,8 @@ static long do_splice(struct file *in, loff_t __user *off_in,
                if (off_out)
                        return -ESPIPE;
                if (off_in) {
-                       if (in->f_op->llseek == no_llseek)
+                       if (!in->f_op || !in->f_op->llseek ||
+                           in->f_op->llseek == no_llseek)
                                return -EINVAL;
                        if (copy_from_user(&offset, off_in, sizeof(loff_t)))
                                return -EFAULT;