aboutsummaryrefslogtreecommitdiffstats
path: root/fs/splice.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 12:10:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 12:10:19 -0400
commit790eac5640abf7a57fa3a644386df330e18c11b0 (patch)
tree08de20bde44f59e51b91ff473a71047c2957e8c9 /fs/splice.c
parent0b0585c3e192967cb2ef0ac0816eb8a8c8d99840 (diff)
parent48bde8d3620f5f3c6ae9ff599eb404055ae51664 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull second set of VFS changes from Al Viro: "Assorted f_pos race fixes, making do_splice_direct() safe to call with i_mutex on parent, O_TMPFILE support, Jeff's locks.c series, ->d_hash/->d_compare calling conventions changes from Linus, misc stuff all over the place." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (63 commits) Document ->tmpfile() ext4: ->tmpfile() support vfs: export lseek_execute() to modules lseek_execute() doesn't need an inode passed to it block_dev: switch to fixed_size_llseek() cpqphp_sysfs: switch to fixed_size_llseek() tile-srom: switch to fixed_size_llseek() proc_powerpc: switch to fixed_size_llseek() ubi/cdev: switch to fixed_size_llseek() pci/proc: switch to fixed_size_llseek() isapnp: switch to fixed_size_llseek() lpfc: switch to fixed_size_llseek() locks: give the blocked_hash its own spinlock locks: add a new "lm_owner_key" lock operation locks: turn the blocked_list into a hashtable locks: convert fl_link to a hlist_node locks: avoid taking global lock if possible when waking up blocked waiters locks: protect most of the file_lock handling with i_lock locks: encapsulate the fl_link list handling locks: make "added" in __posix_lock_file a bool ...
Diffstat (limited to 'fs/splice.c')
-rw-r--r--fs/splice.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/fs/splice.c b/fs/splice.c
index d37431dd60a1..3b7ee656f3aa 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1098,27 +1098,13 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
1098{ 1098{
1099 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, 1099 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
1100 loff_t *, size_t, unsigned int); 1100 loff_t *, size_t, unsigned int);
1101 int ret;
1102
1103 if (unlikely(!(out->f_mode & FMODE_WRITE)))
1104 return -EBADF;
1105
1106 if (unlikely(out->f_flags & O_APPEND))
1107 return -EINVAL;
1108
1109 ret = rw_verify_area(WRITE, out, ppos, len);
1110 if (unlikely(ret < 0))
1111 return ret;
1112 1101
1113 if (out->f_op && out->f_op->splice_write) 1102 if (out->f_op && out->f_op->splice_write)
1114 splice_write = out->f_op->splice_write; 1103 splice_write = out->f_op->splice_write;
1115 else 1104 else
1116 splice_write = default_file_splice_write; 1105 splice_write = default_file_splice_write;
1117 1106
1118 file_start_write(out); 1107 return splice_write(pipe, out, ppos, len, flags);
1119 ret = splice_write(pipe, out, ppos, len, flags);
1120 file_end_write(out);
1121 return ret;
1122} 1108}
1123 1109
1124/* 1110/*
@@ -1307,6 +1293,16 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
1307 }; 1293 };
1308 long ret; 1294 long ret;
1309 1295
1296 if (unlikely(!(out->f_mode & FMODE_WRITE)))
1297 return -EBADF;
1298
1299 if (unlikely(out->f_flags & O_APPEND))
1300 return -EINVAL;
1301
1302 ret = rw_verify_area(WRITE, out, opos, len);
1303 if (unlikely(ret < 0))
1304 return ret;
1305
1310 ret = splice_direct_to_actor(in, &sd, direct_splice_actor); 1306 ret = splice_direct_to_actor(in, &sd, direct_splice_actor);
1311 if (ret > 0) 1307 if (ret > 0)
1312 *ppos = sd.pos; 1308 *ppos = sd.pos;
@@ -1362,7 +1358,19 @@ static long do_splice(struct file *in, loff_t __user *off_in,
1362 offset = out->f_pos; 1358 offset = out->f_pos;
1363 } 1359 }
1364 1360
1361 if (unlikely(!(out->f_mode & FMODE_WRITE)))
1362 return -EBADF;
1363
1364 if (unlikely(out->f_flags & O_APPEND))
1365 return -EINVAL;
1366
1367 ret = rw_verify_area(WRITE, out, &offset, len);
1368 if (unlikely(ret < 0))
1369 return ret;
1370
1371 file_start_write(out);
1365 ret = do_splice_from(ipipe, out, &offset, len, flags); 1372 ret = do_splice_from(ipipe, out, &offset, len, flags);
1373 file_end_write(out);
1366 1374
1367 if (!off_out) 1375 if (!off_out)
1368 out->f_pos = offset; 1376 out->f_pos = offset;