btrfs: Refactor main loop in extent_readpages
[sfrench/cifs-2.6.git] / fs / btrfs / extent_io.c
index b2769e92b55640ab8413b5d252c94ffec053591b..7b489988d81197f1f71bef41e489f18b44a195c3 100644 (file)
@@ -1452,16 +1452,16 @@ out:
  * find a contiguous range of bytes in the file marked as delalloc, not
  * more than 'max_bytes'.  start and end are used to return the range,
  *
- * 1 is returned if we find something, 0 if nothing was in the tree
+ * true is returned if we find something, false if nothing was in the tree
  */
-static noinline u64 find_delalloc_range(struct extent_io_tree *tree,
+static noinline bool find_delalloc_range(struct extent_io_tree *tree,
                                        u64 *start, u64 *end, u64 max_bytes,
                                        struct extent_state **cached_state)
 {
        struct rb_node *node;
        struct extent_state *state;
        u64 cur_start = *start;
-       u64 found = 0;
+       bool found = false;
        u64 total_bytes = 0;
 
        spin_lock(&tree->lock);
@@ -1472,8 +1472,7 @@ static noinline u64 find_delalloc_range(struct extent_io_tree *tree,
         */
        node = tree_search(tree, cur_start);
        if (!node) {
-               if (!found)
-                       *end = (u64)-1;
+               *end = (u64)-1;
                goto out;
        }
 
@@ -1493,7 +1492,7 @@ static noinline u64 find_delalloc_range(struct extent_io_tree *tree,
                        *cached_state = state;
                        refcount_inc(&state->refs);
                }
-               found++;
+               found = true;
                *end = state->end;
                cur_start = state->end + 1;
                node = rb_next(node);
@@ -1551,13 +1550,14 @@ static noinline int lock_delalloc_pages(struct inode *inode,
 }
 
 /*
- * find a contiguous range of bytes in the file marked as delalloc, not
- * more than 'max_bytes'.  start and end are used to return the range,
+ * Find and lock a contiguous range of bytes in the file marked as delalloc, no
+ * more than @max_bytes.  @Start and @end are used to return the range,
  *
- * 1 is returned if we find something, 0 if nothing was in the tree
+ * Return: true if we find something
+ *         false if nothing was in the tree
  */
 EXPORT_FOR_TESTS
-noinline_for_stack u64 find_lock_delalloc_range(struct inode *inode,
+noinline_for_stack bool find_lock_delalloc_range(struct inode *inode,
                                    struct extent_io_tree *tree,
                                    struct page *locked_page, u64 *start,
                                    u64 *end)
@@ -1565,7 +1565,7 @@ noinline_for_stack u64 find_lock_delalloc_range(struct inode *inode,
        u64 max_bytes = BTRFS_MAX_EXTENT_SIZE;
        u64 delalloc_start;
        u64 delalloc_end;
-       u64 found;
+       bool found;
        struct extent_state *cached_state = NULL;
        int ret;
        int loops = 0;
@@ -1580,7 +1580,7 @@ again:
                *start = delalloc_start;
                *end = delalloc_end;
                free_extent_state(cached_state);
-               return 0;
+               return false;
        }
 
        /*
@@ -1612,7 +1612,7 @@ again:
                        loops = 1;
                        goto again;
                } else {
-                       found = 0;
+                       found = false;
                        goto out_failed;
                }
        }
@@ -2585,7 +2585,7 @@ readpage_ok:
                        unsigned off;
 
                        /* Zero out the end if this page straddles i_size */
-                       off = i_size & (PAGE_SIZE-1);
+                       off = offset_in_page(i_size);
                        if (page->index == end_index && off)
                                zero_user_segment(page, off, PAGE_SIZE);
                        SetPageUptodate(page);
@@ -2888,7 +2888,7 @@ static int __do_readpage(struct extent_io_tree *tree,
 
        if (page->index == last_byte >> PAGE_SHIFT) {
                char *userpage;
-               size_t zero_offset = last_byte & (PAGE_SIZE - 1);
+               size_t zero_offset = offset_in_page(last_byte);
 
                if (zero_offset) {
                        iosize = PAGE_SIZE - zero_offset;
@@ -3195,7 +3195,7 @@ static noinline_for_stack int writepage_delalloc(struct inode *inode,
 {
        struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree;
        u64 page_end = delalloc_start + PAGE_SIZE - 1;
-       u64 nr_delalloc;
+       bool found;
        u64 delalloc_to_write = 0;
        u64 delalloc_end = 0;
        int ret;
@@ -3203,11 +3203,11 @@ static noinline_for_stack int writepage_delalloc(struct inode *inode,
 
 
        while (delalloc_end < page_end) {
-               nr_delalloc = find_lock_delalloc_range(inode, tree,
+               found = find_lock_delalloc_range(inode, tree,
                                               page,
                                               &delalloc_start,
                                               &delalloc_end);
-               if (nr_delalloc == 0) {
+               if (!found) {
                        delalloc_start = delalloc_end + 1;
                        continue;
                }
@@ -3432,7 +3432,7 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
 
        ClearPageError(page);
 
-       pg_offset = i_size & (PAGE_SIZE - 1);
+       pg_offset = offset_in_page(i_size);
        if (page->index > end_index ||
           (page->index == end_index && !pg_offset)) {
                page->mapping->a_ops->invalidatepage(page, 0, PAGE_SIZE);
@@ -4094,42 +4094,36 @@ int extent_readpages(struct address_space *mapping, struct list_head *pages,
                     unsigned nr_pages)
 {
        struct bio *bio = NULL;
-       unsigned page_idx;
        unsigned long bio_flags = 0;
        struct page *pagepool[16];
-       struct page *page;
        struct extent_map *em_cached = NULL;
        struct extent_io_tree *tree = &BTRFS_I(mapping->host)->io_tree;
        int nr = 0;
        u64 prev_em_start = (u64)-1;
 
-       for (page_idx = 0; page_idx < nr_pages; page_idx++) {
-               page = list_entry(pages->prev, struct page, lru);
+       while (!list_empty(pages)) {
+               for (nr = 0; nr < ARRAY_SIZE(pagepool) && !list_empty(pages);) {
+                       struct page *page = list_entry(pages->prev,
+                                                      struct page, lru);
 
-               prefetchw(&page->flags);
-               list_del(&page->lru);
-               if (add_to_page_cache_lru(page, mapping,
-                                       page->index,
-                                       readahead_gfp_mask(mapping))) {
-                       put_page(page);
-                       continue;
+                       prefetchw(&page->flags);
+                       list_del(&page->lru);
+                       if (add_to_page_cache_lru(page, mapping, page->index,
+                                               readahead_gfp_mask(mapping))) {
+                               put_page(page);
+                               continue;
+                       }
+
+                       pagepool[nr++] = page;
                }
 
-               pagepool[nr++] = page;
-               if (nr < ARRAY_SIZE(pagepool))
-                       continue;
                __extent_readpages(tree, pagepool, nr, &em_cached, &bio,
-                               &bio_flags, &prev_em_start);
-               nr = 0;
+                                  &bio_flags, &prev_em_start);
        }
-       if (nr)
-               __extent_readpages(tree, pagepool, nr, &em_cached, &bio,
-                               &bio_flags, &prev_em_start);
 
        if (em_cached)
                free_extent_map(em_cached);
 
-       BUG_ON(!list_empty(pages));
        if (bio)
                return submit_one_bio(bio, 0, bio_flags);
        return 0;
@@ -5307,7 +5301,7 @@ void read_extent_buffer(const struct extent_buffer *eb, void *dstv,
        struct page *page;
        char *kaddr;
        char *dst = (char *)dstv;
-       size_t start_offset = eb->start & ((u64)PAGE_SIZE - 1);
+       size_t start_offset = offset_in_page(eb->start);
        unsigned long i = (start_offset + start) >> PAGE_SHIFT;
 
        if (start + len > eb->len) {
@@ -5317,7 +5311,7 @@ void read_extent_buffer(const struct extent_buffer *eb, void *dstv,
                return;
        }
 
-       offset = (start_offset + start) & (PAGE_SIZE - 1);
+       offset = offset_in_page(start_offset + start);
 
        while (len > 0) {
                page = eb->pages[i];
@@ -5342,14 +5336,14 @@ int read_extent_buffer_to_user(const struct extent_buffer *eb,
        struct page *page;
        char *kaddr;
        char __user *dst = (char __user *)dstv;
-       size_t start_offset = eb->start & ((u64)PAGE_SIZE - 1);
+       size_t start_offset = offset_in_page(eb->start);
        unsigned long i = (start_offset + start) >> PAGE_SHIFT;
        int ret = 0;
 
        WARN_ON(start > eb->len);
        WARN_ON(start + len > eb->start + eb->len);
 
-       offset = (start_offset + start) & (PAGE_SIZE - 1);
+       offset = offset_in_page(start_offset + start);
 
        while (len > 0) {
                page = eb->pages[i];
@@ -5383,7 +5377,7 @@ int map_private_extent_buffer(const struct extent_buffer *eb,
        size_t offset;
        char *kaddr;
        struct page *p;
-       size_t start_offset = eb->start & ((u64)PAGE_SIZE - 1);
+       size_t start_offset = offset_in_page(eb->start);
        unsigned long i = (start_offset + start) >> PAGE_SHIFT;
        unsigned long end_i = (start_offset + start + min_len - 1) >>
                PAGE_SHIFT;
@@ -5420,14 +5414,14 @@ int memcmp_extent_buffer(const struct extent_buffer *eb, const void *ptrv,
        struct page *page;
        char *kaddr;
        char *ptr = (char *)ptrv;
-       size_t start_offset = eb->start & ((u64)PAGE_SIZE - 1);
+       size_t start_offset = offset_in_page(eb->start);
        unsigned long i = (start_offset + start) >> PAGE_SHIFT;
        int ret = 0;
 
        WARN_ON(start > eb->len);
        WARN_ON(start + len > eb->start + eb->len);
 
-       offset = (start_offset + start) & (PAGE_SIZE - 1);
+       offset = offset_in_page(start_offset + start);
 
        while (len > 0) {
                page = eb->pages[i];
@@ -5476,13 +5470,13 @@ void write_extent_buffer(struct extent_buffer *eb, const void *srcv,
        struct page *page;
        char *kaddr;
        char *src = (char *)srcv;
-       size_t start_offset = eb->start & ((u64)PAGE_SIZE - 1);
+       size_t start_offset = offset_in_page(eb->start);
        unsigned long i = (start_offset + start) >> PAGE_SHIFT;
 
        WARN_ON(start > eb->len);
        WARN_ON(start + len > eb->start + eb->len);
 
-       offset = (start_offset + start) & (PAGE_SIZE - 1);
+       offset = offset_in_page(start_offset + start);
 
        while (len > 0) {
                page = eb->pages[i];
@@ -5506,13 +5500,13 @@ void memzero_extent_buffer(struct extent_buffer *eb, unsigned long start,
        size_t offset;
        struct page *page;
        char *kaddr;
-       size_t start_offset = eb->start & ((u64)PAGE_SIZE - 1);
+       size_t start_offset = offset_in_page(eb->start);
        unsigned long i = (start_offset + start) >> PAGE_SHIFT;
 
        WARN_ON(start > eb->len);
        WARN_ON(start + len > eb->start + eb->len);
 
-       offset = (start_offset + start) & (PAGE_SIZE - 1);
+       offset = offset_in_page(start_offset + start);
 
        while (len > 0) {
                page = eb->pages[i];
@@ -5551,13 +5545,12 @@ void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src,
        size_t offset;
        struct page *page;
        char *kaddr;
-       size_t start_offset = dst->start & ((u64)PAGE_SIZE - 1);
+       size_t start_offset = offset_in_page(dst->start);
        unsigned long i = (start_offset + dst_offset) >> PAGE_SHIFT;
 
        WARN_ON(src->len != dst_len);
 
-       offset = (start_offset + dst_offset) &
-               (PAGE_SIZE - 1);
+       offset = offset_in_page(start_offset + dst_offset);
 
        while (len > 0) {
                page = dst->pages[i];
@@ -5593,7 +5586,7 @@ static inline void eb_bitmap_offset(struct extent_buffer *eb,
                                    unsigned long *page_index,
                                    size_t *page_offset)
 {
-       size_t start_offset = eb->start & ((u64)PAGE_SIZE - 1);
+       size_t start_offset = offset_in_page(eb->start);
        size_t byte_offset = BIT_BYTE(nr);
        size_t offset;
 
@@ -5605,7 +5598,7 @@ static inline void eb_bitmap_offset(struct extent_buffer *eb,
        offset = start_offset + start + byte_offset;
 
        *page_index = offset >> PAGE_SHIFT;
-       *page_offset = offset & (PAGE_SIZE - 1);
+       *page_offset = offset_in_page(offset);
 }
 
 /**
@@ -5747,7 +5740,7 @@ void memcpy_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
        size_t cur;
        size_t dst_off_in_page;
        size_t src_off_in_page;
-       size_t start_offset = dst->start & ((u64)PAGE_SIZE - 1);
+       size_t start_offset = offset_in_page(dst->start);
        unsigned long dst_i;
        unsigned long src_i;
 
@@ -5765,10 +5758,8 @@ void memcpy_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
        }
 
        while (len > 0) {
-               dst_off_in_page = (start_offset + dst_offset) &
-                       (PAGE_SIZE - 1);
-               src_off_in_page = (start_offset + src_offset) &
-                       (PAGE_SIZE - 1);
+               dst_off_in_page = offset_in_page(start_offset + dst_offset);
+               src_off_in_page = offset_in_page(start_offset + src_offset);
 
                dst_i = (start_offset + dst_offset) >> PAGE_SHIFT;
                src_i = (start_offset + src_offset) >> PAGE_SHIFT;
@@ -5796,7 +5787,7 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
        size_t src_off_in_page;
        unsigned long dst_end = dst_offset + len - 1;
        unsigned long src_end = src_offset + len - 1;
-       size_t start_offset = dst->start & ((u64)PAGE_SIZE - 1);
+       size_t start_offset = offset_in_page(dst->start);
        unsigned long dst_i;
        unsigned long src_i;
 
@@ -5820,10 +5811,8 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
                dst_i = (start_offset + dst_end) >> PAGE_SHIFT;
                src_i = (start_offset + src_end) >> PAGE_SHIFT;
 
-               dst_off_in_page = (start_offset + dst_end) &
-                       (PAGE_SIZE - 1);
-               src_off_in_page = (start_offset + src_end) &
-                       (PAGE_SIZE - 1);
+               dst_off_in_page = offset_in_page(start_offset + dst_end);
+               src_off_in_page = offset_in_page(start_offset + src_end);
 
                cur = min_t(unsigned long, len, src_off_in_page + 1);
                cur = min(cur, dst_off_in_page + 1);