xfs: Move handling of missing page into one place in xfs_find_get_desired_pgoff()
[sfrench/cifs-2.6.git] / fs / xfs / xfs_file.c
index 35703a80137208b81cb38ab91ce50e28d80a19f2..5fb5a0958a1485db46a2f753446c11828ff1913e 100644 (file)
@@ -1043,49 +1043,17 @@ xfs_find_get_desired_pgoff(
 
        index = startoff >> PAGE_SHIFT;
        endoff = XFS_FSB_TO_B(mp, map->br_startoff + map->br_blockcount);
-       end = endoff >> PAGE_SHIFT;
+       end = (endoff - 1) >> PAGE_SHIFT;
        do {
                int             want;
                unsigned        nr_pages;
                unsigned int    i;
 
-               want = min_t(pgoff_t, end - index, PAGEVEC_SIZE);
+               want = min_t(pgoff_t, end - index, PAGEVEC_SIZE - 1) + 1;
                nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index,
                                          want);
-               /*
-                * No page mapped into given range.  If we are searching holes
-                * and if this is the first time we got into the loop, it means
-                * that the given offset is landed in a hole, return it.
-                *
-                * If we have already stepped through some block buffers to find
-                * holes but they all contains data.  In this case, the last
-                * offset is already updated and pointed to the end of the last
-                * mapped page, if it does not reach the endpoint to search,
-                * that means there should be a hole between them.
-                */
-               if (nr_pages == 0) {
-                       /* Data search found nothing */
-                       if (type == DATA_OFF)
-                               break;
-
-                       ASSERT(type == HOLE_OFF);
-                       if (lastoff == startoff || lastoff < endoff) {
-                               found = true;
-                               *offset = lastoff;
-                       }
-                       break;
-               }
-
-               /*
-                * At lease we found one page.  If this is the first time we
-                * step into the loop, and if the first page index offset is
-                * greater than the given search offset, a hole was found.
-                */
-               if (type == HOLE_OFF && lastoff == startoff &&
-                   lastoff < page_offset(pvec.pages[0])) {
-                       found = true;
+               if (nr_pages == 0)
                        break;
-               }
 
                for (i = 0; i < nr_pages; i++) {
                        struct page     *page = pvec.pages[i];
@@ -1098,18 +1066,18 @@ xfs_find_get_desired_pgoff(
                         * file mapping. However, page->index will not change
                         * because we have a reference on the page.
                         *
-                        * Searching done if the page index is out of range.
-                        * If the current offset is not reaches the end of
-                        * the specified search range, there should be a hole
-                        * between them.
+                        * If current page offset is beyond where we've ended,
+                        * we've found a hole.
                         */
-                       if (page->index > end) {
-                               if (type == HOLE_OFF && lastoff < endoff) {
-                                       *offset = lastoff;
-                                       found = true;
-                               }
+                       if (type == HOLE_OFF && lastoff < endoff &&
+                           lastoff < page_offset(pvec.pages[i])) {
+                               found = true;
+                               *offset = lastoff;
                                goto out;
                        }
+                       /* Searching done if the page index is out of range. */
+                       if (page->index > end)
+                               goto out;
 
                        lock_page(page);
                        /*
@@ -1151,21 +1119,20 @@ xfs_find_get_desired_pgoff(
 
                /*
                 * The number of returned pages less than our desired, search
-                * done.  In this case, nothing was found for searching data,
-                * but we found a hole behind the last offset.
+                * done.
                 */
-               if (nr_pages < want) {
-                       if (type == HOLE_OFF) {
-                               *offset = lastoff;
-                               found = true;
-                       }
+               if (nr_pages < want)
                        break;
-               }
 
                index = pvec.pages[i - 1]->index + 1;
                pagevec_release(&pvec);
        } while (index <= end);
 
+       /* No page at lastoff and we are not done - we found a hole. */
+       if (type == HOLE_OFF && lastoff < endoff) {
+               *offset = lastoff;
+               found = true;
+       }
 out:
        pagevec_release(&pvec);
        return found;