diff options
Diffstat (limited to 'fs/splice.c')
-rw-r--r-- | fs/splice.c | 176 |
1 files changed, 111 insertions, 65 deletions
diff --git a/fs/splice.c b/fs/splice.c index 9313b6124a2e..8f1dfaecc8f0 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -193,8 +193,8 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe, | |||
193 | break; | 193 | break; |
194 | } | 194 | } |
195 | 195 | ||
196 | if (pipe->nrbufs < PIPE_BUFFERS) { | 196 | if (pipe->nrbufs < pipe->buffers) { |
197 | int newbuf = (pipe->curbuf + pipe->nrbufs) & (PIPE_BUFFERS - 1); | 197 | int newbuf = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1); |
198 | struct pipe_buffer *buf = pipe->bufs + newbuf; | 198 | struct pipe_buffer *buf = pipe->bufs + newbuf; |
199 | 199 | ||
200 | buf->page = spd->pages[page_nr]; | 200 | buf->page = spd->pages[page_nr]; |
@@ -214,7 +214,7 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe, | |||
214 | 214 | ||
215 | if (!--spd->nr_pages) | 215 | if (!--spd->nr_pages) |
216 | break; | 216 | break; |
217 | if (pipe->nrbufs < PIPE_BUFFERS) | 217 | if (pipe->nrbufs < pipe->buffers) |
218 | continue; | 218 | continue; |
219 | 219 | ||
220 | break; | 220 | break; |
@@ -265,6 +265,36 @@ static void spd_release_page(struct splice_pipe_desc *spd, unsigned int i) | |||
265 | page_cache_release(spd->pages[i]); | 265 | page_cache_release(spd->pages[i]); |
266 | } | 266 | } |
267 | 267 | ||
268 | /* | ||
269 | * Check if we need to grow the arrays holding pages and partial page | ||
270 | * descriptions. | ||
271 | */ | ||
272 | int splice_grow_spd(struct pipe_inode_info *pipe, struct splice_pipe_desc *spd) | ||
273 | { | ||
274 | if (pipe->buffers <= PIPE_DEF_BUFFERS) | ||
275 | return 0; | ||
276 | |||
277 | spd->pages = kmalloc(pipe->buffers * sizeof(struct page *), GFP_KERNEL); | ||
278 | spd->partial = kmalloc(pipe->buffers * sizeof(struct partial_page), GFP_KERNEL); | ||
279 | |||
280 | if (spd->pages && spd->partial) | ||
281 | return 0; | ||
282 | |||
283 | kfree(spd->pages); | ||
284 | kfree(spd->partial); | ||
285 | return -ENOMEM; | ||
286 | } | ||
287 | |||
288 | void splice_shrink_spd(struct pipe_inode_info *pipe, | ||
289 | struct splice_pipe_desc *spd) | ||
290 | { | ||
291 | if (pipe->buffers <= PIPE_DEF_BUFFERS) | ||
292 | return; | ||
293 | |||
294 | kfree(spd->pages); | ||
295 | kfree(spd->partial); | ||
296 | } | ||
297 | |||
268 | static int | 298 | static int |
269 | __generic_file_splice_read(struct file *in, loff_t *ppos, | 299 | __generic_file_splice_read(struct file *in, loff_t *ppos, |
270 | struct pipe_inode_info *pipe, size_t len, | 300 | struct pipe_inode_info *pipe, size_t len, |
@@ -272,8 +302,8 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
272 | { | 302 | { |
273 | struct address_space *mapping = in->f_mapping; | 303 | struct address_space *mapping = in->f_mapping; |
274 | unsigned int loff, nr_pages, req_pages; | 304 | unsigned int loff, nr_pages, req_pages; |
275 | struct page *pages[PIPE_BUFFERS]; | 305 | struct page *pages[PIPE_DEF_BUFFERS]; |
276 | struct partial_page partial[PIPE_BUFFERS]; | 306 | struct partial_page partial[PIPE_DEF_BUFFERS]; |
277 | struct page *page; | 307 | struct page *page; |
278 | pgoff_t index, end_index; | 308 | pgoff_t index, end_index; |
279 | loff_t isize; | 309 | loff_t isize; |
@@ -286,15 +316,18 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
286 | .spd_release = spd_release_page, | 316 | .spd_release = spd_release_page, |
287 | }; | 317 | }; |
288 | 318 | ||
319 | if (splice_grow_spd(pipe, &spd)) | ||
320 | return -ENOMEM; | ||
321 | |||
289 | index = *ppos >> PAGE_CACHE_SHIFT; | 322 | index = *ppos >> PAGE_CACHE_SHIFT; |
290 | loff = *ppos & ~PAGE_CACHE_MASK; | 323 | loff = *ppos & ~PAGE_CACHE_MASK; |
291 | req_pages = (len + loff + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 324 | req_pages = (len + loff + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
292 | nr_pages = min(req_pages, (unsigned)PIPE_BUFFERS); | 325 | nr_pages = min(req_pages, pipe->buffers); |
293 | 326 | ||
294 | /* | 327 | /* |
295 | * Lookup the (hopefully) full range of pages we need. | 328 | * Lookup the (hopefully) full range of pages we need. |
296 | */ | 329 | */ |
297 | spd.nr_pages = find_get_pages_contig(mapping, index, nr_pages, pages); | 330 | spd.nr_pages = find_get_pages_contig(mapping, index, nr_pages, spd.pages); |
298 | index += spd.nr_pages; | 331 | index += spd.nr_pages; |
299 | 332 | ||
300 | /* | 333 | /* |
@@ -321,7 +354,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
321 | break; | 354 | break; |
322 | 355 | ||
323 | error = add_to_page_cache_lru(page, mapping, index, | 356 | error = add_to_page_cache_lru(page, mapping, index, |
324 | mapping_gfp_mask(mapping)); | 357 | GFP_KERNEL); |
325 | if (unlikely(error)) { | 358 | if (unlikely(error)) { |
326 | page_cache_release(page); | 359 | page_cache_release(page); |
327 | if (error == -EEXIST) | 360 | if (error == -EEXIST) |
@@ -335,7 +368,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
335 | unlock_page(page); | 368 | unlock_page(page); |
336 | } | 369 | } |
337 | 370 | ||
338 | pages[spd.nr_pages++] = page; | 371 | spd.pages[spd.nr_pages++] = page; |
339 | index++; | 372 | index++; |
340 | } | 373 | } |
341 | 374 | ||
@@ -356,7 +389,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
356 | * this_len is the max we'll use from this page | 389 | * this_len is the max we'll use from this page |
357 | */ | 390 | */ |
358 | this_len = min_t(unsigned long, len, PAGE_CACHE_SIZE - loff); | 391 | this_len = min_t(unsigned long, len, PAGE_CACHE_SIZE - loff); |
359 | page = pages[page_nr]; | 392 | page = spd.pages[page_nr]; |
360 | 393 | ||
361 | if (PageReadahead(page)) | 394 | if (PageReadahead(page)) |
362 | page_cache_async_readahead(mapping, &in->f_ra, in, | 395 | page_cache_async_readahead(mapping, &in->f_ra, in, |
@@ -366,17 +399,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
366 | * If the page isn't uptodate, we may need to start io on it | 399 | * If the page isn't uptodate, we may need to start io on it |
367 | */ | 400 | */ |
368 | if (!PageUptodate(page)) { | 401 | if (!PageUptodate(page)) { |
369 | /* | 402 | lock_page(page); |
370 | * If in nonblock mode then dont block on waiting | ||
371 | * for an in-flight io page | ||
372 | */ | ||
373 | if (flags & SPLICE_F_NONBLOCK) { | ||
374 | if (!trylock_page(page)) { | ||
375 | error = -EAGAIN; | ||
376 | break; | ||
377 | } | ||
378 | } else | ||
379 | lock_page(page); | ||
380 | 403 | ||
381 | /* | 404 | /* |
382 | * Page was truncated, or invalidated by the | 405 | * Page was truncated, or invalidated by the |
@@ -393,8 +416,8 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
393 | error = -ENOMEM; | 416 | error = -ENOMEM; |
394 | break; | 417 | break; |
395 | } | 418 | } |
396 | page_cache_release(pages[page_nr]); | 419 | page_cache_release(spd.pages[page_nr]); |
397 | pages[page_nr] = page; | 420 | spd.pages[page_nr] = page; |
398 | } | 421 | } |
399 | /* | 422 | /* |
400 | * page was already under io and is now done, great | 423 | * page was already under io and is now done, great |
@@ -451,8 +474,8 @@ fill_it: | |||
451 | len = this_len; | 474 | len = this_len; |
452 | } | 475 | } |
453 | 476 | ||
454 | partial[page_nr].offset = loff; | 477 | spd.partial[page_nr].offset = loff; |
455 | partial[page_nr].len = this_len; | 478 | spd.partial[page_nr].len = this_len; |
456 | len -= this_len; | 479 | len -= this_len; |
457 | loff = 0; | 480 | loff = 0; |
458 | spd.nr_pages++; | 481 | spd.nr_pages++; |
@@ -464,12 +487,13 @@ fill_it: | |||
464 | * we got, 'nr_pages' is how many pages are in the map. | 487 | * we got, 'nr_pages' is how many pages are in the map. |
465 | */ | 488 | */ |
466 | while (page_nr < nr_pages) | 489 | while (page_nr < nr_pages) |
467 | page_cache_release(pages[page_nr++]); | 490 | page_cache_release(spd.pages[page_nr++]); |
468 | in->f_ra.prev_pos = (loff_t)index << PAGE_CACHE_SHIFT; | 491 | in->f_ra.prev_pos = (loff_t)index << PAGE_CACHE_SHIFT; |
469 | 492 | ||
470 | if (spd.nr_pages) | 493 | if (spd.nr_pages) |
471 | return splice_to_pipe(pipe, &spd); | 494 | error = splice_to_pipe(pipe, &spd); |
472 | 495 | ||
496 | splice_shrink_spd(pipe, &spd); | ||
473 | return error; | 497 | return error; |
474 | } | 498 | } |
475 | 499 | ||
@@ -560,10 +584,9 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, | |||
560 | unsigned int nr_pages; | 584 | unsigned int nr_pages; |
561 | unsigned int nr_freed; | 585 | unsigned int nr_freed; |
562 | size_t offset; | 586 | size_t offset; |
563 | struct page *pages[PIPE_BUFFERS]; | 587 | struct page *pages[PIPE_DEF_BUFFERS]; |
564 | struct partial_page partial[PIPE_BUFFERS]; | 588 | struct partial_page partial[PIPE_DEF_BUFFERS]; |
565 | struct iovec vec[PIPE_BUFFERS]; | 589 | struct iovec *vec, __vec[PIPE_DEF_BUFFERS]; |
566 | pgoff_t index; | ||
567 | ssize_t res; | 590 | ssize_t res; |
568 | size_t this_len; | 591 | size_t this_len; |
569 | int error; | 592 | int error; |
@@ -576,11 +599,21 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, | |||
576 | .spd_release = spd_release_page, | 599 | .spd_release = spd_release_page, |
577 | }; | 600 | }; |
578 | 601 | ||
579 | index = *ppos >> PAGE_CACHE_SHIFT; | 602 | if (splice_grow_spd(pipe, &spd)) |
603 | return -ENOMEM; | ||
604 | |||
605 | res = -ENOMEM; | ||
606 | vec = __vec; | ||
607 | if (pipe->buffers > PIPE_DEF_BUFFERS) { | ||
608 | vec = kmalloc(pipe->buffers * sizeof(struct iovec), GFP_KERNEL); | ||
609 | if (!vec) | ||
610 | goto shrink_ret; | ||
611 | } | ||
612 | |||
580 | offset = *ppos & ~PAGE_CACHE_MASK; | 613 | offset = *ppos & ~PAGE_CACHE_MASK; |
581 | nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 614 | nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
582 | 615 | ||
583 | for (i = 0; i < nr_pages && i < PIPE_BUFFERS && len; i++) { | 616 | for (i = 0; i < nr_pages && i < pipe->buffers && len; i++) { |
584 | struct page *page; | 617 | struct page *page; |
585 | 618 | ||
586 | page = alloc_page(GFP_USER); | 619 | page = alloc_page(GFP_USER); |
@@ -591,7 +624,7 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, | |||
591 | this_len = min_t(size_t, len, PAGE_CACHE_SIZE - offset); | 624 | this_len = min_t(size_t, len, PAGE_CACHE_SIZE - offset); |
592 | vec[i].iov_base = (void __user *) page_address(page); | 625 | vec[i].iov_base = (void __user *) page_address(page); |
593 | vec[i].iov_len = this_len; | 626 | vec[i].iov_len = this_len; |
594 | pages[i] = page; | 627 | spd.pages[i] = page; |
595 | spd.nr_pages++; | 628 | spd.nr_pages++; |
596 | len -= this_len; | 629 | len -= this_len; |
597 | offset = 0; | 630 | offset = 0; |
@@ -610,11 +643,11 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, | |||
610 | nr_freed = 0; | 643 | nr_freed = 0; |
611 | for (i = 0; i < spd.nr_pages; i++) { | 644 | for (i = 0; i < spd.nr_pages; i++) { |
612 | this_len = min_t(size_t, vec[i].iov_len, res); | 645 | this_len = min_t(size_t, vec[i].iov_len, res); |
613 | partial[i].offset = 0; | 646 | spd.partial[i].offset = 0; |
614 | partial[i].len = this_len; | 647 | spd.partial[i].len = this_len; |
615 | if (!this_len) { | 648 | if (!this_len) { |
616 | __free_page(pages[i]); | 649 | __free_page(spd.pages[i]); |
617 | pages[i] = NULL; | 650 | spd.pages[i] = NULL; |
618 | nr_freed++; | 651 | nr_freed++; |
619 | } | 652 | } |
620 | res -= this_len; | 653 | res -= this_len; |
@@ -625,13 +658,18 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, | |||
625 | if (res > 0) | 658 | if (res > 0) |
626 | *ppos += res; | 659 | *ppos += res; |
627 | 660 | ||
661 | shrink_ret: | ||
662 | if (vec != __vec) | ||
663 | kfree(vec); | ||
664 | splice_shrink_spd(pipe, &spd); | ||
628 | return res; | 665 | return res; |
629 | 666 | ||
630 | err: | 667 | err: |
631 | for (i = 0; i < spd.nr_pages; i++) | 668 | for (i = 0; i < spd.nr_pages; i++) |
632 | __free_page(pages[i]); | 669 | __free_page(spd.pages[i]); |
633 | 670 | ||
634 | return error; | 671 | res = error; |
672 | goto shrink_ret; | ||
635 | } | 673 | } |
636 | EXPORT_SYMBOL(default_file_splice_read); | 674 | EXPORT_SYMBOL(default_file_splice_read); |
637 | 675 | ||
@@ -784,7 +822,7 @@ int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_desc *sd, | |||
784 | if (!buf->len) { | 822 | if (!buf->len) { |
785 | buf->ops = NULL; | 823 | buf->ops = NULL; |
786 | ops->release(pipe, buf); | 824 | ops->release(pipe, buf); |
787 | pipe->curbuf = (pipe->curbuf + 1) & (PIPE_BUFFERS - 1); | 825 | pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1); |
788 | pipe->nrbufs--; | 826 | pipe->nrbufs--; |
789 | if (pipe->inode) | 827 | if (pipe->inode) |
790 | sd->need_wakeup = true; | 828 | sd->need_wakeup = true; |
@@ -1211,7 +1249,7 @@ out_release: | |||
1211 | * If we did an incomplete transfer we must release | 1249 | * If we did an incomplete transfer we must release |
1212 | * the pipe buffers in question: | 1250 | * the pipe buffers in question: |
1213 | */ | 1251 | */ |
1214 | for (i = 0; i < PIPE_BUFFERS; i++) { | 1252 | for (i = 0; i < pipe->buffers; i++) { |
1215 | struct pipe_buffer *buf = pipe->bufs + i; | 1253 | struct pipe_buffer *buf = pipe->bufs + i; |
1216 | 1254 | ||
1217 | if (buf->ops) { | 1255 | if (buf->ops) { |
@@ -1232,7 +1270,8 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, | |||
1232 | { | 1270 | { |
1233 | struct file *file = sd->u.file; | 1271 | struct file *file = sd->u.file; |
1234 | 1272 | ||
1235 | return do_splice_from(pipe, file, &sd->pos, sd->total_len, sd->flags); | 1273 | return do_splice_from(pipe, file, &file->f_pos, sd->total_len, |
1274 | sd->flags); | ||
1236 | } | 1275 | } |
1237 | 1276 | ||
1238 | /** | 1277 | /** |
@@ -1321,8 +1360,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1321 | if (off_in) | 1360 | if (off_in) |
1322 | return -ESPIPE; | 1361 | return -ESPIPE; |
1323 | if (off_out) { | 1362 | if (off_out) { |
1324 | if (!out->f_op || !out->f_op->llseek || | 1363 | if (!(out->f_mode & FMODE_PWRITE)) |
1325 | out->f_op->llseek == no_llseek) | ||
1326 | return -EINVAL; | 1364 | return -EINVAL; |
1327 | if (copy_from_user(&offset, off_out, sizeof(loff_t))) | 1365 | if (copy_from_user(&offset, off_out, sizeof(loff_t))) |
1328 | return -EFAULT; | 1366 | return -EFAULT; |
@@ -1342,8 +1380,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1342 | if (off_out) | 1380 | if (off_out) |
1343 | return -ESPIPE; | 1381 | return -ESPIPE; |
1344 | if (off_in) { | 1382 | if (off_in) { |
1345 | if (!in->f_op || !in->f_op->llseek || | 1383 | if (!(in->f_mode & FMODE_PREAD)) |
1346 | in->f_op->llseek == no_llseek) | ||
1347 | return -EINVAL; | 1384 | return -EINVAL; |
1348 | if (copy_from_user(&offset, off_in, sizeof(loff_t))) | 1385 | if (copy_from_user(&offset, off_in, sizeof(loff_t))) |
1349 | return -EFAULT; | 1386 | return -EFAULT; |
@@ -1371,7 +1408,8 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1371 | */ | 1408 | */ |
1372 | static int get_iovec_page_array(const struct iovec __user *iov, | 1409 | static int get_iovec_page_array(const struct iovec __user *iov, |
1373 | unsigned int nr_vecs, struct page **pages, | 1410 | unsigned int nr_vecs, struct page **pages, |
1374 | struct partial_page *partial, int aligned) | 1411 | struct partial_page *partial, int aligned, |
1412 | unsigned int pipe_buffers) | ||
1375 | { | 1413 | { |
1376 | int buffers = 0, error = 0; | 1414 | int buffers = 0, error = 0; |
1377 | 1415 | ||
@@ -1414,8 +1452,8 @@ static int get_iovec_page_array(const struct iovec __user *iov, | |||
1414 | break; | 1452 | break; |
1415 | 1453 | ||
1416 | npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT; | 1454 | npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT; |
1417 | if (npages > PIPE_BUFFERS - buffers) | 1455 | if (npages > pipe_buffers - buffers) |
1418 | npages = PIPE_BUFFERS - buffers; | 1456 | npages = pipe_buffers - buffers; |
1419 | 1457 | ||
1420 | error = get_user_pages_fast((unsigned long)base, npages, | 1458 | error = get_user_pages_fast((unsigned long)base, npages, |
1421 | 0, &pages[buffers]); | 1459 | 0, &pages[buffers]); |
@@ -1450,7 +1488,7 @@ static int get_iovec_page_array(const struct iovec __user *iov, | |||
1450 | * or if we mapped the max number of pages that we have | 1488 | * or if we mapped the max number of pages that we have |
1451 | * room for. | 1489 | * room for. |
1452 | */ | 1490 | */ |
1453 | if (error < npages || buffers == PIPE_BUFFERS) | 1491 | if (error < npages || buffers == pipe_buffers) |
1454 | break; | 1492 | break; |
1455 | 1493 | ||
1456 | nr_vecs--; | 1494 | nr_vecs--; |
@@ -1593,8 +1631,8 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov, | |||
1593 | unsigned long nr_segs, unsigned int flags) | 1631 | unsigned long nr_segs, unsigned int flags) |
1594 | { | 1632 | { |
1595 | struct pipe_inode_info *pipe; | 1633 | struct pipe_inode_info *pipe; |
1596 | struct page *pages[PIPE_BUFFERS]; | 1634 | struct page *pages[PIPE_DEF_BUFFERS]; |
1597 | struct partial_page partial[PIPE_BUFFERS]; | 1635 | struct partial_page partial[PIPE_DEF_BUFFERS]; |
1598 | struct splice_pipe_desc spd = { | 1636 | struct splice_pipe_desc spd = { |
1599 | .pages = pages, | 1637 | .pages = pages, |
1600 | .partial = partial, | 1638 | .partial = partial, |
@@ -1602,17 +1640,25 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov, | |||
1602 | .ops = &user_page_pipe_buf_ops, | 1640 | .ops = &user_page_pipe_buf_ops, |
1603 | .spd_release = spd_release_page, | 1641 | .spd_release = spd_release_page, |
1604 | }; | 1642 | }; |
1643 | long ret; | ||
1605 | 1644 | ||
1606 | pipe = pipe_info(file->f_path.dentry->d_inode); | 1645 | pipe = pipe_info(file->f_path.dentry->d_inode); |
1607 | if (!pipe) | 1646 | if (!pipe) |
1608 | return -EBADF; | 1647 | return -EBADF; |
1609 | 1648 | ||
1610 | spd.nr_pages = get_iovec_page_array(iov, nr_segs, pages, partial, | 1649 | if (splice_grow_spd(pipe, &spd)) |
1611 | flags & SPLICE_F_GIFT); | 1650 | return -ENOMEM; |
1651 | |||
1652 | spd.nr_pages = get_iovec_page_array(iov, nr_segs, spd.pages, | ||
1653 | spd.partial, flags & SPLICE_F_GIFT, | ||
1654 | pipe->buffers); | ||
1612 | if (spd.nr_pages <= 0) | 1655 | if (spd.nr_pages <= 0) |
1613 | return spd.nr_pages; | 1656 | ret = spd.nr_pages; |
1657 | else | ||
1658 | ret = splice_to_pipe(pipe, &spd); | ||
1614 | 1659 | ||
1615 | return splice_to_pipe(pipe, &spd); | 1660 | splice_shrink_spd(pipe, &spd); |
1661 | return ret; | ||
1616 | } | 1662 | } |
1617 | 1663 | ||
1618 | /* | 1664 | /* |
@@ -1738,13 +1784,13 @@ static int opipe_prep(struct pipe_inode_info *pipe, unsigned int flags) | |||
1738 | * Check ->nrbufs without the inode lock first. This function | 1784 | * Check ->nrbufs without the inode lock first. This function |
1739 | * is speculative anyways, so missing one is ok. | 1785 | * is speculative anyways, so missing one is ok. |
1740 | */ | 1786 | */ |
1741 | if (pipe->nrbufs < PIPE_BUFFERS) | 1787 | if (pipe->nrbufs < pipe->buffers) |
1742 | return 0; | 1788 | return 0; |
1743 | 1789 | ||
1744 | ret = 0; | 1790 | ret = 0; |
1745 | pipe_lock(pipe); | 1791 | pipe_lock(pipe); |
1746 | 1792 | ||
1747 | while (pipe->nrbufs >= PIPE_BUFFERS) { | 1793 | while (pipe->nrbufs >= pipe->buffers) { |
1748 | if (!pipe->readers) { | 1794 | if (!pipe->readers) { |
1749 | send_sig(SIGPIPE, current, 0); | 1795 | send_sig(SIGPIPE, current, 0); |
1750 | ret = -EPIPE; | 1796 | ret = -EPIPE; |
@@ -1810,7 +1856,7 @@ retry: | |||
1810 | * Cannot make any progress, because either the input | 1856 | * Cannot make any progress, because either the input |
1811 | * pipe is empty or the output pipe is full. | 1857 | * pipe is empty or the output pipe is full. |
1812 | */ | 1858 | */ |
1813 | if (!ipipe->nrbufs || opipe->nrbufs >= PIPE_BUFFERS) { | 1859 | if (!ipipe->nrbufs || opipe->nrbufs >= opipe->buffers) { |
1814 | /* Already processed some buffers, break */ | 1860 | /* Already processed some buffers, break */ |
1815 | if (ret) | 1861 | if (ret) |
1816 | break; | 1862 | break; |
@@ -1831,7 +1877,7 @@ retry: | |||
1831 | } | 1877 | } |
1832 | 1878 | ||
1833 | ibuf = ipipe->bufs + ipipe->curbuf; | 1879 | ibuf = ipipe->bufs + ipipe->curbuf; |
1834 | nbuf = (opipe->curbuf + opipe->nrbufs) % PIPE_BUFFERS; | 1880 | nbuf = (opipe->curbuf + opipe->nrbufs) & (opipe->buffers - 1); |
1835 | obuf = opipe->bufs + nbuf; | 1881 | obuf = opipe->bufs + nbuf; |
1836 | 1882 | ||
1837 | if (len >= ibuf->len) { | 1883 | if (len >= ibuf->len) { |
@@ -1841,7 +1887,7 @@ retry: | |||
1841 | *obuf = *ibuf; | 1887 | *obuf = *ibuf; |
1842 | ibuf->ops = NULL; | 1888 | ibuf->ops = NULL; |
1843 | opipe->nrbufs++; | 1889 | opipe->nrbufs++; |
1844 | ipipe->curbuf = (ipipe->curbuf + 1) % PIPE_BUFFERS; | 1890 | ipipe->curbuf = (ipipe->curbuf + 1) & (ipipe->buffers - 1); |
1845 | ipipe->nrbufs--; | 1891 | ipipe->nrbufs--; |
1846 | input_wakeup = true; | 1892 | input_wakeup = true; |
1847 | } else { | 1893 | } else { |
@@ -1914,11 +1960,11 @@ static int link_pipe(struct pipe_inode_info *ipipe, | |||
1914 | * If we have iterated all input buffers or ran out of | 1960 | * If we have iterated all input buffers or ran out of |
1915 | * output room, break. | 1961 | * output room, break. |
1916 | */ | 1962 | */ |
1917 | if (i >= ipipe->nrbufs || opipe->nrbufs >= PIPE_BUFFERS) | 1963 | if (i >= ipipe->nrbufs || opipe->nrbufs >= opipe->buffers) |
1918 | break; | 1964 | break; |
1919 | 1965 | ||
1920 | ibuf = ipipe->bufs + ((ipipe->curbuf + i) & (PIPE_BUFFERS - 1)); | 1966 | ibuf = ipipe->bufs + ((ipipe->curbuf + i) & (ipipe->buffers-1)); |
1921 | nbuf = (opipe->curbuf + opipe->nrbufs) & (PIPE_BUFFERS - 1); | 1967 | nbuf = (opipe->curbuf + opipe->nrbufs) & (opipe->buffers - 1); |
1922 | 1968 | ||
1923 | /* | 1969 | /* |
1924 | * Get a reference to this pipe buffer, | 1970 | * Get a reference to this pipe buffer, |