diff options
Diffstat (limited to 'fs/splice.c')
| -rw-r--r-- | fs/splice.c | 306 |
1 files changed, 178 insertions, 128 deletions
diff --git a/fs/splice.c b/fs/splice.c index 447ebc0a37f3..a285fd746dc0 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
| @@ -51,7 +51,7 @@ struct splice_pipe_desc { | |||
| 51 | * addition of remove_mapping(). If success is returned, the caller may | 51 | * addition of remove_mapping(). If success is returned, the caller may |
| 52 | * attempt to reuse this page for another destination. | 52 | * attempt to reuse this page for another destination. |
| 53 | */ | 53 | */ |
| 54 | static int page_cache_pipe_buf_steal(struct pipe_inode_info *info, | 54 | static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe, |
| 55 | struct pipe_buffer *buf) | 55 | struct pipe_buffer *buf) |
| 56 | { | 56 | { |
| 57 | struct page *page = buf->page; | 57 | struct page *page = buf->page; |
| @@ -78,21 +78,19 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *info, | |||
| 78 | return 1; | 78 | return 1; |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | buf->flags |= PIPE_BUF_FLAG_STOLEN | PIPE_BUF_FLAG_LRU; | 81 | buf->flags |= PIPE_BUF_FLAG_LRU; |
| 82 | return 0; | 82 | return 0; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | static void page_cache_pipe_buf_release(struct pipe_inode_info *info, | 85 | static void page_cache_pipe_buf_release(struct pipe_inode_info *pipe, |
| 86 | struct pipe_buffer *buf) | 86 | struct pipe_buffer *buf) |
| 87 | { | 87 | { |
| 88 | page_cache_release(buf->page); | 88 | page_cache_release(buf->page); |
| 89 | buf->page = NULL; | 89 | buf->flags &= ~PIPE_BUF_FLAG_LRU; |
| 90 | buf->flags &= ~(PIPE_BUF_FLAG_STOLEN | PIPE_BUF_FLAG_LRU); | ||
| 91 | } | 90 | } |
| 92 | 91 | ||
| 93 | static void *page_cache_pipe_buf_map(struct file *file, | 92 | static int page_cache_pipe_buf_pin(struct pipe_inode_info *pipe, |
| 94 | struct pipe_inode_info *info, | 93 | struct pipe_buffer *buf) |
| 95 | struct pipe_buffer *buf) | ||
| 96 | { | 94 | { |
| 97 | struct page *page = buf->page; | 95 | struct page *page = buf->page; |
| 98 | int err; | 96 | int err; |
| @@ -118,64 +116,45 @@ static void *page_cache_pipe_buf_map(struct file *file, | |||
| 118 | } | 116 | } |
| 119 | 117 | ||
| 120 | /* | 118 | /* |
| 121 | * Page is ok afterall, fall through to mapping. | 119 | * Page is ok afterall, we are done. |
| 122 | */ | 120 | */ |
| 123 | unlock_page(page); | 121 | unlock_page(page); |
| 124 | } | 122 | } |
| 125 | 123 | ||
| 126 | return kmap(page); | 124 | return 0; |
| 127 | error: | 125 | error: |
| 128 | unlock_page(page); | 126 | unlock_page(page); |
| 129 | return ERR_PTR(err); | 127 | return err; |
| 130 | } | ||
| 131 | |||
| 132 | static void page_cache_pipe_buf_unmap(struct pipe_inode_info *info, | ||
| 133 | struct pipe_buffer *buf) | ||
| 134 | { | ||
| 135 | kunmap(buf->page); | ||
| 136 | } | ||
| 137 | |||
| 138 | static void *user_page_pipe_buf_map(struct file *file, | ||
| 139 | struct pipe_inode_info *pipe, | ||
| 140 | struct pipe_buffer *buf) | ||
| 141 | { | ||
| 142 | return kmap(buf->page); | ||
| 143 | } | ||
| 144 | |||
| 145 | static void user_page_pipe_buf_unmap(struct pipe_inode_info *pipe, | ||
| 146 | struct pipe_buffer *buf) | ||
| 147 | { | ||
| 148 | kunmap(buf->page); | ||
| 149 | } | ||
| 150 | |||
| 151 | static void page_cache_pipe_buf_get(struct pipe_inode_info *info, | ||
| 152 | struct pipe_buffer *buf) | ||
| 153 | { | ||
| 154 | page_cache_get(buf->page); | ||
| 155 | } | 128 | } |
| 156 | 129 | ||
| 157 | static struct pipe_buf_operations page_cache_pipe_buf_ops = { | 130 | static struct pipe_buf_operations page_cache_pipe_buf_ops = { |
| 158 | .can_merge = 0, | 131 | .can_merge = 0, |
| 159 | .map = page_cache_pipe_buf_map, | 132 | .map = generic_pipe_buf_map, |
| 160 | .unmap = page_cache_pipe_buf_unmap, | 133 | .unmap = generic_pipe_buf_unmap, |
| 134 | .pin = page_cache_pipe_buf_pin, | ||
| 161 | .release = page_cache_pipe_buf_release, | 135 | .release = page_cache_pipe_buf_release, |
| 162 | .steal = page_cache_pipe_buf_steal, | 136 | .steal = page_cache_pipe_buf_steal, |
| 163 | .get = page_cache_pipe_buf_get, | 137 | .get = generic_pipe_buf_get, |
| 164 | }; | 138 | }; |
| 165 | 139 | ||
| 166 | static int user_page_pipe_buf_steal(struct pipe_inode_info *pipe, | 140 | static int user_page_pipe_buf_steal(struct pipe_inode_info *pipe, |
| 167 | struct pipe_buffer *buf) | 141 | struct pipe_buffer *buf) |
| 168 | { | 142 | { |
| 169 | return 1; | 143 | if (!(buf->flags & PIPE_BUF_FLAG_GIFT)) |
| 144 | return 1; | ||
| 145 | |||
| 146 | buf->flags |= PIPE_BUF_FLAG_LRU; | ||
| 147 | return generic_pipe_buf_steal(pipe, buf); | ||
| 170 | } | 148 | } |
| 171 | 149 | ||
| 172 | static struct pipe_buf_operations user_page_pipe_buf_ops = { | 150 | static struct pipe_buf_operations user_page_pipe_buf_ops = { |
| 173 | .can_merge = 0, | 151 | .can_merge = 0, |
| 174 | .map = user_page_pipe_buf_map, | 152 | .map = generic_pipe_buf_map, |
| 175 | .unmap = user_page_pipe_buf_unmap, | 153 | .unmap = generic_pipe_buf_unmap, |
| 154 | .pin = generic_pipe_buf_pin, | ||
| 176 | .release = page_cache_pipe_buf_release, | 155 | .release = page_cache_pipe_buf_release, |
| 177 | .steal = user_page_pipe_buf_steal, | 156 | .steal = user_page_pipe_buf_steal, |
| 178 | .get = page_cache_pipe_buf_get, | 157 | .get = generic_pipe_buf_get, |
| 179 | }; | 158 | }; |
| 180 | 159 | ||
| 181 | /* | 160 | /* |
| @@ -210,6 +189,9 @@ static ssize_t splice_to_pipe(struct pipe_inode_info *pipe, | |||
| 210 | buf->offset = spd->partial[page_nr].offset; | 189 | buf->offset = spd->partial[page_nr].offset; |
| 211 | buf->len = spd->partial[page_nr].len; | 190 | buf->len = spd->partial[page_nr].len; |
| 212 | buf->ops = spd->ops; | 191 | buf->ops = spd->ops; |
| 192 | if (spd->flags & SPLICE_F_GIFT) | ||
| 193 | buf->flags |= PIPE_BUF_FLAG_GIFT; | ||
| 194 | |||
| 213 | pipe->nrbufs++; | 195 | pipe->nrbufs++; |
| 214 | page_nr++; | 196 | page_nr++; |
| 215 | ret += buf->len; | 197 | ret += buf->len; |
| @@ -279,7 +261,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
| 279 | pgoff_t index, end_index; | 261 | pgoff_t index, end_index; |
| 280 | loff_t isize; | 262 | loff_t isize; |
| 281 | size_t total_len; | 263 | size_t total_len; |
| 282 | int error; | 264 | int error, page_nr; |
| 283 | struct splice_pipe_desc spd = { | 265 | struct splice_pipe_desc spd = { |
| 284 | .pages = pages, | 266 | .pages = pages, |
| 285 | .partial = partial, | 267 | .partial = partial, |
| @@ -299,47 +281,83 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
| 299 | * read-ahead if this is a non-zero offset (we are likely doing small | 281 | * read-ahead if this is a non-zero offset (we are likely doing small |
| 300 | * chunk splice and the page is already there) for a single page. | 282 | * chunk splice and the page is already there) for a single page. |
| 301 | */ | 283 | */ |
| 302 | if (!loff || spd.nr_pages > 1) | 284 | if (!loff || nr_pages > 1) |
| 303 | do_page_cache_readahead(mapping, in, index, spd.nr_pages); | 285 | page_cache_readahead(mapping, &in->f_ra, in, index, nr_pages); |
| 304 | 286 | ||
| 305 | /* | 287 | /* |
| 306 | * Now fill in the holes: | 288 | * Now fill in the holes: |
| 307 | */ | 289 | */ |
| 308 | error = 0; | 290 | error = 0; |
| 309 | total_len = 0; | 291 | total_len = 0; |
| 310 | for (spd.nr_pages = 0; spd.nr_pages < nr_pages; spd.nr_pages++, index++) { | ||
| 311 | unsigned int this_len; | ||
| 312 | 292 | ||
| 313 | if (!len) | 293 | /* |
| 314 | break; | 294 | * Lookup the (hopefully) full range of pages we need. |
| 295 | */ | ||
| 296 | spd.nr_pages = find_get_pages_contig(mapping, index, nr_pages, pages); | ||
| 315 | 297 | ||
| 298 | /* | ||
| 299 | * If find_get_pages_contig() returned fewer pages than we needed, | ||
| 300 | * allocate the rest. | ||
| 301 | */ | ||
| 302 | index += spd.nr_pages; | ||
| 303 | while (spd.nr_pages < nr_pages) { | ||
| 316 | /* | 304 | /* |
| 317 | * this_len is the max we'll use from this page | 305 | * Page could be there, find_get_pages_contig() breaks on |
| 318 | */ | 306 | * the first hole. |
| 319 | this_len = min_t(unsigned long, len, PAGE_CACHE_SIZE - loff); | ||
| 320 | find_page: | ||
| 321 | /* | ||
| 322 | * lookup the page for this index | ||
| 323 | */ | 307 | */ |
| 324 | page = find_get_page(mapping, index); | 308 | page = find_get_page(mapping, index); |
| 325 | if (!page) { | 309 | if (!page) { |
| 326 | /* | 310 | /* |
| 327 | * page didn't exist, allocate one | 311 | * Make sure the read-ahead engine is notified |
| 312 | * about this failure. | ||
| 313 | */ | ||
| 314 | handle_ra_miss(mapping, &in->f_ra, index); | ||
| 315 | |||
| 316 | /* | ||
| 317 | * page didn't exist, allocate one. | ||
| 328 | */ | 318 | */ |
| 329 | page = page_cache_alloc_cold(mapping); | 319 | page = page_cache_alloc_cold(mapping); |
| 330 | if (!page) | 320 | if (!page) |
| 331 | break; | 321 | break; |
| 332 | 322 | ||
| 333 | error = add_to_page_cache_lru(page, mapping, index, | 323 | error = add_to_page_cache_lru(page, mapping, index, |
| 334 | mapping_gfp_mask(mapping)); | 324 | mapping_gfp_mask(mapping)); |
| 335 | if (unlikely(error)) { | 325 | if (unlikely(error)) { |
| 336 | page_cache_release(page); | 326 | page_cache_release(page); |
| 327 | if (error == -EEXIST) | ||
| 328 | continue; | ||
| 337 | break; | 329 | break; |
| 338 | } | 330 | } |
| 339 | 331 | /* | |
| 340 | goto readpage; | 332 | * add_to_page_cache() locks the page, unlock it |
| 333 | * to avoid convoluting the logic below even more. | ||
| 334 | */ | ||
| 335 | unlock_page(page); | ||
| 341 | } | 336 | } |
| 342 | 337 | ||
| 338 | pages[spd.nr_pages++] = page; | ||
| 339 | index++; | ||
| 340 | } | ||
| 341 | |||
| 342 | /* | ||
| 343 | * Now loop over the map and see if we need to start IO on any | ||
| 344 | * pages, fill in the partial map, etc. | ||
| 345 | */ | ||
| 346 | index = *ppos >> PAGE_CACHE_SHIFT; | ||
| 347 | nr_pages = spd.nr_pages; | ||
| 348 | spd.nr_pages = 0; | ||
| 349 | for (page_nr = 0; page_nr < nr_pages; page_nr++) { | ||
| 350 | unsigned int this_len; | ||
| 351 | |||
| 352 | if (!len) | ||
| 353 | break; | ||
| 354 | |||
| 355 | /* | ||
| 356 | * this_len is the max we'll use from this page | ||
| 357 | */ | ||
| 358 | this_len = min_t(unsigned long, len, PAGE_CACHE_SIZE - loff); | ||
| 359 | page = pages[page_nr]; | ||
| 360 | |||
| 343 | /* | 361 | /* |
| 344 | * If the page isn't uptodate, we may need to start io on it | 362 | * If the page isn't uptodate, we may need to start io on it |
| 345 | */ | 363 | */ |
| @@ -360,7 +378,6 @@ find_page: | |||
| 360 | */ | 378 | */ |
| 361 | if (!page->mapping) { | 379 | if (!page->mapping) { |
| 362 | unlock_page(page); | 380 | unlock_page(page); |
| 363 | page_cache_release(page); | ||
| 364 | break; | 381 | break; |
| 365 | } | 382 | } |
| 366 | /* | 383 | /* |
| @@ -371,16 +388,20 @@ find_page: | |||
| 371 | goto fill_it; | 388 | goto fill_it; |
| 372 | } | 389 | } |
| 373 | 390 | ||
| 374 | readpage: | ||
| 375 | /* | 391 | /* |
| 376 | * need to read in the page | 392 | * need to read in the page |
| 377 | */ | 393 | */ |
| 378 | error = mapping->a_ops->readpage(in, page); | 394 | error = mapping->a_ops->readpage(in, page); |
| 379 | |||
| 380 | if (unlikely(error)) { | 395 | if (unlikely(error)) { |
| 381 | page_cache_release(page); | 396 | /* |
| 397 | * We really should re-lookup the page here, | ||
| 398 | * but it complicates things a lot. Instead | ||
| 399 | * lets just do what we already stored, and | ||
| 400 | * we'll get it the next time we are called. | ||
| 401 | */ | ||
| 382 | if (error == AOP_TRUNCATED_PAGE) | 402 | if (error == AOP_TRUNCATED_PAGE) |
| 383 | goto find_page; | 403 | error = 0; |
| 404 | |||
| 384 | break; | 405 | break; |
| 385 | } | 406 | } |
| 386 | 407 | ||
| @@ -389,10 +410,8 @@ readpage: | |||
| 389 | */ | 410 | */ |
| 390 | isize = i_size_read(mapping->host); | 411 | isize = i_size_read(mapping->host); |
| 391 | end_index = (isize - 1) >> PAGE_CACHE_SHIFT; | 412 | end_index = (isize - 1) >> PAGE_CACHE_SHIFT; |
| 392 | if (unlikely(!isize || index > end_index)) { | 413 | if (unlikely(!isize || index > end_index)) |
| 393 | page_cache_release(page); | ||
| 394 | break; | 414 | break; |
| 395 | } | ||
| 396 | 415 | ||
| 397 | /* | 416 | /* |
| 398 | * if this is the last page, see if we need to shrink | 417 | * if this is the last page, see if we need to shrink |
| @@ -400,27 +419,33 @@ readpage: | |||
| 400 | */ | 419 | */ |
| 401 | if (end_index == index) { | 420 | if (end_index == index) { |
| 402 | loff = PAGE_CACHE_SIZE - (isize & ~PAGE_CACHE_MASK); | 421 | loff = PAGE_CACHE_SIZE - (isize & ~PAGE_CACHE_MASK); |
| 403 | if (total_len + loff > isize) { | 422 | if (total_len + loff > isize) |
| 404 | page_cache_release(page); | ||
| 405 | break; | 423 | break; |
| 406 | } | ||
| 407 | /* | 424 | /* |
| 408 | * force quit after adding this page | 425 | * force quit after adding this page |
| 409 | */ | 426 | */ |
| 410 | nr_pages = spd.nr_pages; | 427 | len = this_len; |
| 411 | this_len = min(this_len, loff); | 428 | this_len = min(this_len, loff); |
| 412 | loff = 0; | 429 | loff = 0; |
| 413 | } | 430 | } |
| 414 | } | 431 | } |
| 415 | fill_it: | 432 | fill_it: |
| 416 | pages[spd.nr_pages] = page; | 433 | partial[page_nr].offset = loff; |
| 417 | partial[spd.nr_pages].offset = loff; | 434 | partial[page_nr].len = this_len; |
| 418 | partial[spd.nr_pages].len = this_len; | ||
| 419 | len -= this_len; | 435 | len -= this_len; |
| 420 | total_len += this_len; | 436 | total_len += this_len; |
| 421 | loff = 0; | 437 | loff = 0; |
| 438 | spd.nr_pages++; | ||
| 439 | index++; | ||
| 422 | } | 440 | } |
| 423 | 441 | ||
| 442 | /* | ||
| 443 | * Release any pages at the end, if we quit early. 'i' is how far | ||
| 444 | * we got, 'nr_pages' is how many pages are in the map. | ||
| 445 | */ | ||
| 446 | while (page_nr < nr_pages) | ||
| 447 | page_cache_release(pages[page_nr++]); | ||
| 448 | |||
| 424 | if (spd.nr_pages) | 449 | if (spd.nr_pages) |
| 425 | return splice_to_pipe(pipe, &spd); | 450 | return splice_to_pipe(pipe, &spd); |
| 426 | 451 | ||
| @@ -477,31 +502,21 @@ EXPORT_SYMBOL(generic_file_splice_read); | |||
| 477 | * Send 'sd->len' bytes to socket from 'sd->file' at position 'sd->pos' | 502 | * Send 'sd->len' bytes to socket from 'sd->file' at position 'sd->pos' |
| 478 | * using sendpage(). Return the number of bytes sent. | 503 | * using sendpage(). Return the number of bytes sent. |
| 479 | */ | 504 | */ |
| 480 | static int pipe_to_sendpage(struct pipe_inode_info *info, | 505 | static int pipe_to_sendpage(struct pipe_inode_info *pipe, |
| 481 | struct pipe_buffer *buf, struct splice_desc *sd) | 506 | struct pipe_buffer *buf, struct splice_desc *sd) |
| 482 | { | 507 | { |
| 483 | struct file *file = sd->file; | 508 | struct file *file = sd->file; |
| 484 | loff_t pos = sd->pos; | 509 | loff_t pos = sd->pos; |
| 485 | ssize_t ret; | 510 | int ret, more; |
| 486 | void *ptr; | ||
| 487 | int more; | ||
| 488 | |||
| 489 | /* | ||
| 490 | * Sub-optimal, but we are limited by the pipe ->map. We don't | ||
| 491 | * need a kmap'ed buffer here, we just want to make sure we | ||
| 492 | * have the page pinned if the pipe page originates from the | ||
| 493 | * page cache. | ||
| 494 | */ | ||
| 495 | ptr = buf->ops->map(file, info, buf); | ||
| 496 | if (IS_ERR(ptr)) | ||
| 497 | return PTR_ERR(ptr); | ||
| 498 | 511 | ||
| 499 | more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; | 512 | ret = buf->ops->pin(pipe, buf); |
| 513 | if (!ret) { | ||
| 514 | more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; | ||
| 500 | 515 | ||
| 501 | ret = file->f_op->sendpage(file, buf->page, buf->offset, sd->len, | 516 | ret = file->f_op->sendpage(file, buf->page, buf->offset, |
| 502 | &pos, more); | 517 | sd->len, &pos, more); |
| 518 | } | ||
| 503 | 519 | ||
| 504 | buf->ops->unmap(info, buf); | ||
| 505 | return ret; | 520 | return ret; |
| 506 | } | 521 | } |
| 507 | 522 | ||
| @@ -525,7 +540,7 @@ static int pipe_to_sendpage(struct pipe_inode_info *info, | |||
| 525 | * SPLICE_F_MOVE isn't set, or we cannot move the page, we simply create | 540 | * SPLICE_F_MOVE isn't set, or we cannot move the page, we simply create |
| 526 | * a new page in the output file page cache and fill/dirty that. | 541 | * a new page in the output file page cache and fill/dirty that. |
| 527 | */ | 542 | */ |
| 528 | static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf, | 543 | static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, |
| 529 | struct splice_desc *sd) | 544 | struct splice_desc *sd) |
| 530 | { | 545 | { |
| 531 | struct file *file = sd->file; | 546 | struct file *file = sd->file; |
| @@ -534,15 +549,14 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf, | |||
| 534 | unsigned int offset, this_len; | 549 | unsigned int offset, this_len; |
| 535 | struct page *page; | 550 | struct page *page; |
| 536 | pgoff_t index; | 551 | pgoff_t index; |
| 537 | char *src; | ||
| 538 | int ret; | 552 | int ret; |
| 539 | 553 | ||
| 540 | /* | 554 | /* |
| 541 | * make sure the data in this buffer is uptodate | 555 | * make sure the data in this buffer is uptodate |
| 542 | */ | 556 | */ |
| 543 | src = buf->ops->map(file, info, buf); | 557 | ret = buf->ops->pin(pipe, buf); |
| 544 | if (IS_ERR(src)) | 558 | if (unlikely(ret)) |
| 545 | return PTR_ERR(src); | 559 | return ret; |
| 546 | 560 | ||
| 547 | index = sd->pos >> PAGE_CACHE_SHIFT; | 561 | index = sd->pos >> PAGE_CACHE_SHIFT; |
| 548 | offset = sd->pos & ~PAGE_CACHE_MASK; | 562 | offset = sd->pos & ~PAGE_CACHE_MASK; |
| @@ -552,20 +566,25 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf, | |||
| 552 | this_len = PAGE_CACHE_SIZE - offset; | 566 | this_len = PAGE_CACHE_SIZE - offset; |
| 553 | 567 | ||
| 554 | /* | 568 | /* |
| 555 | * Reuse buf page, if SPLICE_F_MOVE is set. | 569 | * Reuse buf page, if SPLICE_F_MOVE is set and we are doing a full |
| 570 | * page. | ||
| 556 | */ | 571 | */ |
| 557 | if (sd->flags & SPLICE_F_MOVE) { | 572 | if ((sd->flags & SPLICE_F_MOVE) && this_len == PAGE_CACHE_SIZE) { |
| 558 | /* | 573 | /* |
| 559 | * If steal succeeds, buf->page is now pruned from the vm | 574 | * If steal succeeds, buf->page is now pruned from the |
| 560 | * side (LRU and page cache) and we can reuse it. The page | 575 | * pagecache and we can reuse it. The page will also be |
| 561 | * will also be looked on successful return. | 576 | * locked on successful return. |
| 562 | */ | 577 | */ |
| 563 | if (buf->ops->steal(info, buf)) | 578 | if (buf->ops->steal(pipe, buf)) |
| 564 | goto find_page; | 579 | goto find_page; |
| 565 | 580 | ||
| 566 | page = buf->page; | 581 | page = buf->page; |
| 567 | if (add_to_page_cache(page, mapping, index, gfp_mask)) | 582 | if (add_to_page_cache(page, mapping, index, gfp_mask)) { |
| 583 | unlock_page(page); | ||
| 568 | goto find_page; | 584 | goto find_page; |
| 585 | } | ||
| 586 | |||
| 587 | page_cache_get(page); | ||
| 569 | 588 | ||
| 570 | if (!(buf->flags & PIPE_BUF_FLAG_LRU)) | 589 | if (!(buf->flags & PIPE_BUF_FLAG_LRU)) |
| 571 | lru_cache_add(page); | 590 | lru_cache_add(page); |
| @@ -619,40 +638,55 @@ find_page: | |||
| 619 | } | 638 | } |
| 620 | 639 | ||
| 621 | ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); | 640 | ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); |
| 622 | if (ret == AOP_TRUNCATED_PAGE) { | 641 | if (unlikely(ret)) { |
| 642 | loff_t isize = i_size_read(mapping->host); | ||
| 643 | |||
| 644 | if (ret != AOP_TRUNCATED_PAGE) | ||
| 645 | unlock_page(page); | ||
| 623 | page_cache_release(page); | 646 | page_cache_release(page); |
| 624 | goto find_page; | 647 | if (ret == AOP_TRUNCATED_PAGE) |
| 625 | } else if (ret) | 648 | goto find_page; |
| 649 | |||
| 650 | /* | ||
| 651 | * prepare_write() may have instantiated a few blocks | ||
| 652 | * outside i_size. Trim these off again. | ||
| 653 | */ | ||
| 654 | if (sd->pos + this_len > isize) | ||
| 655 | vmtruncate(mapping->host, isize); | ||
| 656 | |||
| 626 | goto out; | 657 | goto out; |
| 658 | } | ||
| 627 | 659 | ||
| 628 | if (!(buf->flags & PIPE_BUF_FLAG_STOLEN)) { | 660 | if (buf->page != page) { |
| 629 | char *dst = kmap_atomic(page, KM_USER0); | 661 | /* |
| 662 | * Careful, ->map() uses KM_USER0! | ||
| 663 | */ | ||
| 664 | char *src = buf->ops->map(pipe, buf, 1); | ||
| 665 | char *dst = kmap_atomic(page, KM_USER1); | ||
| 630 | 666 | ||
| 631 | memcpy(dst + offset, src + buf->offset, this_len); | 667 | memcpy(dst + offset, src + buf->offset, this_len); |
| 632 | flush_dcache_page(page); | 668 | flush_dcache_page(page); |
| 633 | kunmap_atomic(dst, KM_USER0); | 669 | kunmap_atomic(dst, KM_USER1); |
| 670 | buf->ops->unmap(pipe, buf, src); | ||
| 634 | } | 671 | } |
| 635 | 672 | ||
| 636 | ret = mapping->a_ops->commit_write(file, page, offset, offset+this_len); | 673 | ret = mapping->a_ops->commit_write(file, page, offset, offset+this_len); |
| 637 | if (ret == AOP_TRUNCATED_PAGE) { | 674 | if (!ret) { |
| 675 | /* | ||
| 676 | * Return the number of bytes written and mark page as | ||
| 677 | * accessed, we are now done! | ||
| 678 | */ | ||
| 679 | ret = this_len; | ||
| 680 | mark_page_accessed(page); | ||
| 681 | balance_dirty_pages_ratelimited(mapping); | ||
| 682 | } else if (ret == AOP_TRUNCATED_PAGE) { | ||
| 638 | page_cache_release(page); | 683 | page_cache_release(page); |
| 639 | goto find_page; | 684 | goto find_page; |
| 640 | } else if (ret) | 685 | } |
| 641 | goto out; | ||
| 642 | |||
| 643 | /* | ||
| 644 | * Return the number of bytes written. | ||
| 645 | */ | ||
| 646 | ret = this_len; | ||
| 647 | mark_page_accessed(page); | ||
| 648 | balance_dirty_pages_ratelimited(mapping); | ||
| 649 | out: | 686 | out: |
| 650 | if (!(buf->flags & PIPE_BUF_FLAG_STOLEN)) | 687 | page_cache_release(page); |
| 651 | page_cache_release(page); | ||
| 652 | |||
| 653 | unlock_page(page); | 688 | unlock_page(page); |
| 654 | out_nomem: | 689 | out_nomem: |
| 655 | buf->ops->unmap(info, buf); | ||
| 656 | return ret; | 690 | return ret; |
| 657 | } | 691 | } |
| 658 | 692 | ||
| @@ -1060,7 +1094,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
| 1060 | */ | 1094 | */ |
| 1061 | static int get_iovec_page_array(const struct iovec __user *iov, | 1095 | static int get_iovec_page_array(const struct iovec __user *iov, |
| 1062 | unsigned int nr_vecs, struct page **pages, | 1096 | unsigned int nr_vecs, struct page **pages, |
| 1063 | struct partial_page *partial) | 1097 | struct partial_page *partial, int aligned) |
| 1064 | { | 1098 | { |
| 1065 | int buffers = 0, error = 0; | 1099 | int buffers = 0, error = 0; |
| 1066 | 1100 | ||
| @@ -1100,6 +1134,15 @@ static int get_iovec_page_array(const struct iovec __user *iov, | |||
| 1100 | * in the user pages. | 1134 | * in the user pages. |
| 1101 | */ | 1135 | */ |
| 1102 | off = (unsigned long) base & ~PAGE_MASK; | 1136 | off = (unsigned long) base & ~PAGE_MASK; |
| 1137 | |||
| 1138 | /* | ||
| 1139 | * If asked for alignment, the offset must be zero and the | ||
| 1140 | * length a multiple of the PAGE_SIZE. | ||
| 1141 | */ | ||
| 1142 | error = -EINVAL; | ||
| 1143 | if (aligned && (off || len & ~PAGE_MASK)) | ||
| 1144 | break; | ||
| 1145 | |||
| 1103 | npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT; | 1146 | npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT; |
| 1104 | if (npages > PIPE_BUFFERS - buffers) | 1147 | if (npages > PIPE_BUFFERS - buffers) |
| 1105 | npages = PIPE_BUFFERS - buffers; | 1148 | npages = PIPE_BUFFERS - buffers; |
| @@ -1115,7 +1158,7 @@ static int get_iovec_page_array(const struct iovec __user *iov, | |||
| 1115 | * Fill this contiguous range into the partial page map. | 1158 | * Fill this contiguous range into the partial page map. |
| 1116 | */ | 1159 | */ |
| 1117 | for (i = 0; i < error; i++) { | 1160 | for (i = 0; i < error; i++) { |
| 1118 | const int plen = min_t(size_t, len, PAGE_SIZE) - off; | 1161 | const int plen = min_t(size_t, len, PAGE_SIZE - off); |
| 1119 | 1162 | ||
| 1120 | partial[buffers].offset = off; | 1163 | partial[buffers].offset = off; |
| 1121 | partial[buffers].len = plen; | 1164 | partial[buffers].len = plen; |
| @@ -1193,7 +1236,8 @@ static long do_vmsplice(struct file *file, const struct iovec __user *iov, | |||
| 1193 | else if (unlikely(!nr_segs)) | 1236 | else if (unlikely(!nr_segs)) |
| 1194 | return 0; | 1237 | return 0; |
| 1195 | 1238 | ||
| 1196 | spd.nr_pages = get_iovec_page_array(iov, nr_segs, pages, partial); | 1239 | spd.nr_pages = get_iovec_page_array(iov, nr_segs, pages, partial, |
| 1240 | flags & SPLICE_F_GIFT); | ||
| 1197 | if (spd.nr_pages <= 0) | 1241 | if (spd.nr_pages <= 0) |
| 1198 | return spd.nr_pages; | 1242 | return spd.nr_pages; |
| 1199 | 1243 | ||
| @@ -1301,6 +1345,12 @@ static int link_pipe(struct pipe_inode_info *ipipe, | |||
| 1301 | obuf = opipe->bufs + nbuf; | 1345 | obuf = opipe->bufs + nbuf; |
| 1302 | *obuf = *ibuf; | 1346 | *obuf = *ibuf; |
| 1303 | 1347 | ||
| 1348 | /* | ||
| 1349 | * Don't inherit the gift flag, we need to | ||
| 1350 | * prevent multiple steals of this page. | ||
| 1351 | */ | ||
| 1352 | obuf->flags &= ~PIPE_BUF_FLAG_GIFT; | ||
| 1353 | |||
| 1304 | if (obuf->len > len) | 1354 | if (obuf->len > len) |
| 1305 | obuf->len = len; | 1355 | obuf->len = len; |
| 1306 | 1356 | ||
