Commit 8a78cb1f1b98e5ea970674e0f049832d19e76ace

Authored by Christoph Hellwig
Committed by Darrick J. Wong
1 parent b84e772299

fs: move page_cache_seek_hole_data to iomap.c

This function is only used by the iomap code, depends on being called
from it, and will soon stop poking into buffer head internals.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Showing 3 changed files with 116 additions and 116 deletions Side-by-side Diff

... ... @@ -3427,120 +3427,6 @@
3427 3427 }
3428 3428 EXPORT_SYMBOL(bh_submit_read);
3429 3429  
3430   -/*
3431   - * Seek for SEEK_DATA / SEEK_HOLE within @page, starting at @lastoff.
3432   - *
3433   - * Returns the offset within the file on success, and -ENOENT otherwise.
3434   - */
3435   -static loff_t
3436   -page_seek_hole_data(struct page *page, loff_t lastoff, int whence)
3437   -{
3438   - loff_t offset = page_offset(page);
3439   - struct buffer_head *bh, *head;
3440   - bool seek_data = whence == SEEK_DATA;
3441   -
3442   - if (lastoff < offset)
3443   - lastoff = offset;
3444   -
3445   - bh = head = page_buffers(page);
3446   - do {
3447   - offset += bh->b_size;
3448   - if (lastoff >= offset)
3449   - continue;
3450   -
3451   - /*
3452   - * Unwritten extents that have data in the page cache covering
3453   - * them can be identified by the BH_Unwritten state flag.
3454   - * Pages with multiple buffers might have a mix of holes, data
3455   - * and unwritten extents - any buffer with valid data in it
3456   - * should have BH_Uptodate flag set on it.
3457   - */
3458   -
3459   - if ((buffer_unwritten(bh) || buffer_uptodate(bh)) == seek_data)
3460   - return lastoff;
3461   -
3462   - lastoff = offset;
3463   - } while ((bh = bh->b_this_page) != head);
3464   - return -ENOENT;
3465   -}
3466   -
3467   -/*
3468   - * Seek for SEEK_DATA / SEEK_HOLE in the page cache.
3469   - *
3470   - * Within unwritten extents, the page cache determines which parts are holes
3471   - * and which are data: unwritten and uptodate buffer heads count as data;
3472   - * everything else counts as a hole.
3473   - *
3474   - * Returns the resulting offset on successs, and -ENOENT otherwise.
3475   - */
3476   -loff_t
3477   -page_cache_seek_hole_data(struct inode *inode, loff_t offset, loff_t length,
3478   - int whence)
3479   -{
3480   - pgoff_t index = offset >> PAGE_SHIFT;
3481   - pgoff_t end = DIV_ROUND_UP(offset + length, PAGE_SIZE);
3482   - loff_t lastoff = offset;
3483   - struct pagevec pvec;
3484   -
3485   - if (length <= 0)
3486   - return -ENOENT;
3487   -
3488   - pagevec_init(&pvec);
3489   -
3490   - do {
3491   - unsigned nr_pages, i;
3492   -
3493   - nr_pages = pagevec_lookup_range(&pvec, inode->i_mapping, &index,
3494   - end - 1);
3495   - if (nr_pages == 0)
3496   - break;
3497   -
3498   - for (i = 0; i < nr_pages; i++) {
3499   - struct page *page = pvec.pages[i];
3500   -
3501   - /*
3502   - * At this point, the page may be truncated or
3503   - * invalidated (changing page->mapping to NULL), or
3504   - * even swizzled back from swapper_space to tmpfs file
3505   - * mapping. However, page->index will not change
3506   - * because we have a reference on the page.
3507   - *
3508   - * If current page offset is beyond where we've ended,
3509   - * we've found a hole.
3510   - */
3511   - if (whence == SEEK_HOLE &&
3512   - lastoff < page_offset(page))
3513   - goto check_range;
3514   -
3515   - lock_page(page);
3516   - if (likely(page->mapping == inode->i_mapping) &&
3517   - page_has_buffers(page)) {
3518   - lastoff = page_seek_hole_data(page, lastoff, whence);
3519   - if (lastoff >= 0) {
3520   - unlock_page(page);
3521   - goto check_range;
3522   - }
3523   - }
3524   - unlock_page(page);
3525   - lastoff = page_offset(page) + PAGE_SIZE;
3526   - }
3527   - pagevec_release(&pvec);
3528   - } while (index < end);
3529   -
3530   - /* When no page at lastoff and we are not done, we found a hole. */
3531   - if (whence != SEEK_HOLE)
3532   - goto not_found;
3533   -
3534   -check_range:
3535   - if (lastoff < offset + length)
3536   - goto out;
3537   -not_found:
3538   - lastoff = -ENOENT;
3539   -out:
3540   - pagevec_release(&pvec);
3541   - return lastoff;
3542   -}
3543   -
3544 3430 void __init buffer_init(void)
3545 3431 {
3546 3432 unsigned long nrpages;
... ... @@ -20,6 +20,7 @@
20 20 #include <linux/mm.h>
21 21 #include <linux/swap.h>
22 22 #include <linux/pagemap.h>
  23 +#include <linux/pagevec.h>
23 24 #include <linux/file.h>
24 25 #include <linux/uio.h>
25 26 #include <linux/backing-dev.h>
... ... @@ -591,6 +592,121 @@
591 592 return 0;
592 593 }
593 594 EXPORT_SYMBOL_GPL(iomap_fiemap);
  595 +
  596 +/*
  597 + * Seek for SEEK_DATA / SEEK_HOLE within @page, starting at @lastoff.
  598 + *
  599 + * Returns the offset within the file on success, and -ENOENT otherwise.
  600 + */
  601 +static loff_t
  602 +page_seek_hole_data(struct page *page, loff_t lastoff, int whence)
  603 +{
  604 + loff_t offset = page_offset(page);
  605 + struct buffer_head *bh, *head;
  606 + bool seek_data = whence == SEEK_DATA;
  607 +
  608 + if (lastoff < offset)
  609 + lastoff = offset;
  610 +
  611 + bh = head = page_buffers(page);
  612 + do {
  613 + offset += bh->b_size;
  614 + if (lastoff >= offset)
  615 + continue;
  616 +
  617 + /*
  618 + * Unwritten extents that have data in the page cache covering
  619 + * them can be identified by the BH_Unwritten state flag.
  620 + * Pages with multiple buffers might have a mix of holes, data
  621 + * and unwritten extents - any buffer with valid data in it
  622 + * should have BH_Uptodate flag set on it.
  623 + */
  624 +
  625 + if ((buffer_unwritten(bh) || buffer_uptodate(bh)) == seek_data)
  626 + return lastoff;
  627 +
  628 + lastoff = offset;
  629 + } while ((bh = bh->b_this_page) != head);
  630 + return -ENOENT;
  631 +}
  632 +
  633 +/*
  634 + * Seek for SEEK_DATA / SEEK_HOLE in the page cache.
  635 + *
  636 + * Within unwritten extents, the page cache determines which parts are holes
  637 + * and which are data: unwritten and uptodate buffer heads count as data;
  638 + * everything else counts as a hole.
  639 + *
  640 + * Returns the resulting offset on successs, and -ENOENT otherwise.
  641 + */
  642 +static loff_t
  643 +page_cache_seek_hole_data(struct inode *inode, loff_t offset, loff_t length,
  644 + int whence)
  645 +{
  646 + pgoff_t index = offset >> PAGE_SHIFT;
  647 + pgoff_t end = DIV_ROUND_UP(offset + length, PAGE_SIZE);
  648 + loff_t lastoff = offset;
  649 + struct pagevec pvec;
  650 +
  651 + if (length <= 0)
  652 + return -ENOENT;
  653 +
  654 + pagevec_init(&pvec);
  655 +
  656 + do {
  657 + unsigned nr_pages, i;
  658 +
  659 + nr_pages = pagevec_lookup_range(&pvec, inode->i_mapping, &index,
  660 + end - 1);
  661 + if (nr_pages == 0)
  662 + break;
  663 +
  664 + for (i = 0; i < nr_pages; i++) {
  665 + struct page *page = pvec.pages[i];
  666 +
  667 + /*
  668 + * At this point, the page may be truncated or
  669 + * invalidated (changing page->mapping to NULL), or
  670 + * even swizzled back from swapper_space to tmpfs file
  671 + * mapping. However, page->index will not change
  672 + * because we have a reference on the page.
  673 + *
  674 + * If current page offset is beyond where we've ended,
  675 + * we've found a hole.
  676 + */
  677 + if (whence == SEEK_HOLE &&
  678 + lastoff < page_offset(page))
  679 + goto check_range;
  680 +
  681 + lock_page(page);
  682 + if (likely(page->mapping == inode->i_mapping) &&
  683 + page_has_buffers(page)) {
  684 + lastoff = page_seek_hole_data(page, lastoff, whence);
  685 + if (lastoff >= 0) {
  686 + unlock_page(page);
  687 + goto check_range;
  688 + }
  689 + }
  690 + unlock_page(page);
  691 + lastoff = page_offset(page) + PAGE_SIZE;
  692 + }
  693 + pagevec_release(&pvec);
  694 + } while (index < end);
  695 +
  696 + /* When no page at lastoff and we are not done, we found a hole. */
  697 + if (whence != SEEK_HOLE)
  698 + goto not_found;
  699 +
  700 +check_range:
  701 + if (lastoff < offset + length)
  702 + goto out;
  703 +not_found:
  704 + lastoff = -ENOENT;
  705 +out:
  706 + pagevec_release(&pvec);
  707 + return lastoff;
  708 +}
  709 +
594 710  
595 711 static loff_t
596 712 iomap_seek_hole_actor(struct inode *inode, loff_t offset, loff_t length,
include/linux/buffer_head.h
... ... @@ -205,8 +205,6 @@
205 205 sector_t bblock, unsigned blocksize);
206 206 int bh_uptodate_or_lock(struct buffer_head *bh);
207 207 int bh_submit_read(struct buffer_head *bh);
208   -loff_t page_cache_seek_hole_data(struct inode *inode, loff_t offset,
209   - loff_t length, int whence);
210 208  
211 209 extern int buffer_heads_over_limit;
212 210