aboutsummaryrefslogtreecommitdiffstats
path: root/fs/splice.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/splice.c')
-rw-r--r--fs/splice.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/fs/splice.c b/fs/splice.c
index cb211360273a..e7d7080de2f9 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -176,6 +176,7 @@ static const struct pipe_buf_operations user_page_pipe_buf_ops = {
176static ssize_t splice_to_pipe(struct pipe_inode_info *pipe, 176static ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
177 struct splice_pipe_desc *spd) 177 struct splice_pipe_desc *spd)
178{ 178{
179 unsigned int spd_pages = spd->nr_pages;
179 int ret, do_wakeup, page_nr; 180 int ret, do_wakeup, page_nr;
180 181
181 ret = 0; 182 ret = 0;
@@ -244,17 +245,18 @@ static ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
244 pipe->waiting_writers--; 245 pipe->waiting_writers--;
245 } 246 }
246 247
247 if (pipe->inode) 248 if (pipe->inode) {
248 mutex_unlock(&pipe->inode->i_mutex); 249 mutex_unlock(&pipe->inode->i_mutex);
249 250
250 if (do_wakeup) { 251 if (do_wakeup) {
251 smp_mb(); 252 smp_mb();
252 if (waitqueue_active(&pipe->wait)) 253 if (waitqueue_active(&pipe->wait))
253 wake_up_interruptible(&pipe->wait); 254 wake_up_interruptible(&pipe->wait);
254 kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); 255 kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
256 }
255 } 257 }
256 258
257 while (page_nr < spd->nr_pages) 259 while (page_nr < spd_pages)
258 page_cache_release(spd->pages[page_nr++]); 260 page_cache_release(spd->pages[page_nr++]);
259 261
260 return ret; 262 return ret;
@@ -811,7 +813,10 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
811 813
812 ret = __splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); 814 ret = __splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
813 if (ret > 0) { 815 if (ret > 0) {
816 unsigned long nr_pages;
817
814 *ppos += ret; 818 *ppos += ret;
819 nr_pages = (ret + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
815 820
816 /* 821 /*
817 * If file or inode is SYNC and we actually wrote some data, 822 * If file or inode is SYNC and we actually wrote some data,
@@ -824,7 +829,7 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
824 if (err) 829 if (err)
825 ret = err; 830 ret = err;
826 } 831 }
827 balance_dirty_pages_ratelimited(mapping); 832 balance_dirty_pages_ratelimited_nr(mapping, nr_pages);
828 } 833 }
829 834
830 return ret; 835 return ret;
@@ -863,7 +868,10 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
863 868
864 ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); 869 ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
865 if (ret > 0) { 870 if (ret > 0) {
871 unsigned long nr_pages;
872
866 *ppos += ret; 873 *ppos += ret;
874 nr_pages = (ret + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
867 875
868 /* 876 /*
869 * If file or inode is SYNC and we actually wrote some data, 877 * If file or inode is SYNC and we actually wrote some data,
@@ -878,7 +886,7 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
878 if (err) 886 if (err)
879 ret = err; 887 ret = err;
880 } 888 }
881 balance_dirty_pages_ratelimited(mapping); 889 balance_dirty_pages_ratelimited_nr(mapping, nr_pages);
882 } 890 }
883 891
884 return ret; 892 return ret;