Merge tag 'mmc-v4.5-rc1' of git://git.linaro.org/people/ulf.hansson/mmc
[cascardo/linux.git] / fs / btrfs / extent_io.c
index 9abe187..2e7c97a 100644 (file)
@@ -1285,20 +1285,6 @@ search_again:
 }
 
 /* wrappers around set/clear extent bit */
-int set_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
-                    gfp_t mask)
-{
-       return set_extent_bit(tree, start, end, EXTENT_DIRTY, NULL,
-                             NULL, mask);
-}
-
-int set_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
-                   unsigned bits, gfp_t mask)
-{
-       return set_extent_bit(tree, start, end, bits, NULL,
-                             NULL, mask);
-}
-
 int set_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
                           unsigned bits, gfp_t mask,
                           struct extent_changeset *changeset)
@@ -1323,17 +1309,6 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
                                  cached, mask, NULL);
 }
 
-int clear_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
-                     unsigned bits, gfp_t mask)
-{
-       int wake = 0;
-
-       if (bits & EXTENT_LOCKED)
-               wake = 1;
-
-       return clear_extent_bit(tree, start, end, bits, wake, 0, NULL, mask);
-}
-
 int clear_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
                             unsigned bits, gfp_t mask,
                             struct extent_changeset *changeset)
@@ -1348,63 +1323,18 @@ int clear_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
                                  changeset);
 }
 
-int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
-                       struct extent_state **cached_state, gfp_t mask)
-{
-       return set_extent_bit(tree, start, end,
-                             EXTENT_DELALLOC | EXTENT_UPTODATE,
-                             NULL, cached_state, mask);
-}
-
-int set_extent_defrag(struct extent_io_tree *tree, u64 start, u64 end,
-                     struct extent_state **cached_state, gfp_t mask)
-{
-       return set_extent_bit(tree, start, end,
-                             EXTENT_DELALLOC | EXTENT_UPTODATE | EXTENT_DEFRAG,
-                             NULL, cached_state, mask);
-}
-
-int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
-                      gfp_t mask)
-{
-       return clear_extent_bit(tree, start, end,
-                               EXTENT_DIRTY | EXTENT_DELALLOC |
-                               EXTENT_DO_ACCOUNTING, 0, 0, NULL, mask);
-}
-
-int set_extent_new(struct extent_io_tree *tree, u64 start, u64 end,
-                    gfp_t mask)
-{
-       return set_extent_bit(tree, start, end, EXTENT_NEW, NULL,
-                             NULL, mask);
-}
-
-int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end,
-                       struct extent_state **cached_state, gfp_t mask)
-{
-       return set_extent_bit(tree, start, end, EXTENT_UPTODATE, NULL,
-                             cached_state, mask);
-}
-
-int clear_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end,
-                         struct extent_state **cached_state, gfp_t mask)
-{
-       return clear_extent_bit(tree, start, end, EXTENT_UPTODATE, 0, 0,
-                               cached_state, mask);
-}
-
 /*
  * either insert or lock state struct between start and end use mask to tell
  * us if waiting is desired.
  */
 int lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
-                    unsigned bits, struct extent_state **cached_state)
+                    struct extent_state **cached_state)
 {
        int err;
        u64 failed_start;
 
        while (1) {
-               err = __set_extent_bit(tree, start, end, EXTENT_LOCKED | bits,
+               err = __set_extent_bit(tree, start, end, EXTENT_LOCKED,
                                       EXTENT_LOCKED, &failed_start,
                                       cached_state, GFP_NOFS, NULL);
                if (err == -EEXIST) {
@@ -1417,11 +1347,6 @@ int lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
        return err;
 }
 
-int lock_extent(struct extent_io_tree *tree, u64 start, u64 end)
-{
-       return lock_extent_bits(tree, start, end, 0, NULL);
-}
-
 int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end)
 {
        int err;
@@ -1438,20 +1363,7 @@ int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end)
        return 1;
 }
 
-int unlock_extent_cached(struct extent_io_tree *tree, u64 start, u64 end,
-                        struct extent_state **cached, gfp_t mask)
-{
-       return clear_extent_bit(tree, start, end, EXTENT_LOCKED, 1, 0, cached,
-                               mask);
-}
-
-int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end)
-{
-       return clear_extent_bit(tree, start, end, EXTENT_LOCKED, 1, 0, NULL,
-                               GFP_NOFS);
-}
-
-int extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end)
+void extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end)
 {
        unsigned long index = start >> PAGE_CACHE_SHIFT;
        unsigned long end_index = end >> PAGE_CACHE_SHIFT;
@@ -1464,10 +1376,9 @@ int extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end)
                page_cache_release(page);
                index++;
        }
-       return 0;
 }
 
-int extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end)
+void extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end)
 {
        unsigned long index = start >> PAGE_CACHE_SHIFT;
        unsigned long end_index = end >> PAGE_CACHE_SHIFT;
@@ -1481,13 +1392,12 @@ int extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end)
                page_cache_release(page);
                index++;
        }
-       return 0;
 }
 
 /*
  * helper function to set both pages and extents in the tree writeback
  */
-static int set_range_writeback(struct extent_io_tree *tree, u64 start, u64 end)
+static void set_range_writeback(struct extent_io_tree *tree, u64 start, u64 end)
 {
        unsigned long index = start >> PAGE_CACHE_SHIFT;
        unsigned long end_index = end >> PAGE_CACHE_SHIFT;
@@ -1500,7 +1410,6 @@ static int set_range_writeback(struct extent_io_tree *tree, u64 start, u64 end)
                page_cache_release(page);
                index++;
        }
-       return 0;
 }
 
 /* find the first state struct with 'bits' set after 'start', and
@@ -1800,7 +1709,7 @@ again:
        BUG_ON(ret); /* Only valid values are 0 and -EAGAIN */
 
        /* step three, lock the state bits for the whole range */
-       lock_extent_bits(tree, delalloc_start, delalloc_end, 0, &cached_state);
+       lock_extent_bits(tree, delalloc_start, delalloc_end, &cached_state);
 
        /* then test to make sure it is all still delalloc */
        ret = test_range_bit(tree, delalloc_start, delalloc_end,
@@ -1820,7 +1729,7 @@ out_failed:
        return found;
 }
 
-int extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end,
+void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end,
                                 struct page *locked_page,
                                 unsigned clear_bits,
                                 unsigned long page_ops)
@@ -1835,7 +1744,7 @@ int extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end,
 
        clear_extent_bit(tree, start, end, clear_bits, 1, 0, NULL, GFP_NOFS);
        if (page_ops == 0)
-               return 0;
+               return;
 
        if ((page_ops & PAGE_SET_ERROR) && nr_pages > 0)
                mapping_set_error(inode->i_mapping, -EIO);
@@ -1869,7 +1778,6 @@ int extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end,
                index += ret;
                cond_resched();
        }
-       return 0;
 }
 
 /*
@@ -2516,7 +2424,7 @@ static int bio_readpage_error(struct bio *failed_bio, u64 phy_offset,
 
 /* lots and lots of room for performance fixes in the end_bio funcs */
 
-int end_extent_writepage(struct page *page, int err, u64 start, u64 end)
+void end_extent_writepage(struct page *page, int err, u64 start, u64 end)
 {
        int uptodate = (err == 0);
        struct extent_io_tree *tree;
@@ -2537,7 +2445,6 @@ int end_extent_writepage(struct page *page, int err, u64 start, u64 end)
                ret = ret < 0 ? ret : -EIO;
                mapping_set_error(page->mapping, ret);
        }
-       return 0;
 }
 
 /*
@@ -2579,9 +2486,7 @@ static void end_bio_extent_writepage(struct bio *bio)
                start = page_offset(page);
                end = start + bvec->bv_offset + bvec->bv_len - 1;
 
-               if (end_extent_writepage(page, bio->bi_error, start, end))
-                       continue;
-
+               end_extent_writepage(page, bio->bi_error, start, end);
                end_page_writeback(page);
        }
 
@@ -4326,7 +4231,7 @@ int extent_invalidatepage(struct extent_io_tree *tree,
        if (start > end)
                return 0;
 
-       lock_extent_bits(tree, start, end, 0, &cached_state);
+       lock_extent_bits(tree, start, end, &cached_state);
        wait_on_page_writeback(page);
        clear_extent_bit(tree, start, end,
                         EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC |
@@ -4387,7 +4292,7 @@ int try_release_extent_mapping(struct extent_map_tree *map,
        u64 end = start + PAGE_CACHE_SIZE - 1;
 
        if (gfpflags_allow_blocking(mask) &&
-           page->mapping->host->i_size > 16 * 1024 * 1024) {
+           page->mapping->host->i_size > SZ_16M) {
                u64 len;
                while (start <= end) {
                        len = end - start + 1;
@@ -4536,7 +4441,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                last_for_get_extent = isize;
        }
 
-       lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len - 1, 0,
+       lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len - 1,
                         &cached_state);
 
        em = get_extent_skip_holes(inode, start, last_for_get_extent,
@@ -4797,24 +4702,14 @@ struct extent_buffer *btrfs_clone_extent_buffer(struct extent_buffer *src)
        return new;
 }
 
-struct extent_buffer *alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info,
-                                               u64 start)
+struct extent_buffer *__alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info,
+                                                 u64 start, unsigned long len)
 {
        struct extent_buffer *eb;
-       unsigned long len;
        unsigned long num_pages;
        unsigned long i;
 
-       if (!fs_info) {
-               /*
-                * Called only from tests that don't always have a fs_info
-                * available, but we know that nodesize is 4096
-                */
-               len = 4096;
-       } else {
-               len = fs_info->tree_root->nodesize;
-       }
-       num_pages = num_extent_pages(0, len);
+       num_pages = num_extent_pages(start, len);
 
        eb = __alloc_extent_buffer(fs_info, start, len);
        if (!eb)
@@ -4837,6 +4732,24 @@ err:
        return NULL;
 }
 
+struct extent_buffer *alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info,
+                                               u64 start)
+{
+       unsigned long len;
+
+       if (!fs_info) {
+               /*
+                * Called only from tests that don't always have a fs_info
+                * available, but we know that nodesize is 4096
+                */
+               len = 4096;
+       } else {
+               len = fs_info->tree_root->nodesize;
+       }
+
+       return __alloc_dummy_extent_buffer(fs_info, start, len);
+}
+
 static void check_buffer_tree_ref(struct extent_buffer *eb)
 {
        int refs;
@@ -5227,7 +5140,7 @@ int set_extent_buffer_dirty(struct extent_buffer *eb)
        return was_dirty;
 }
 
-int clear_extent_buffer_uptodate(struct extent_buffer *eb)
+void clear_extent_buffer_uptodate(struct extent_buffer *eb)
 {
        unsigned long i;
        struct page *page;
@@ -5240,10 +5153,9 @@ int clear_extent_buffer_uptodate(struct extent_buffer *eb)
                if (page)
                        ClearPageUptodate(page);
        }
-       return 0;
 }
 
-int set_extent_buffer_uptodate(struct extent_buffer *eb)
+void set_extent_buffer_uptodate(struct extent_buffer *eb)
 {
        unsigned long i;
        struct page *page;
@@ -5255,7 +5167,6 @@ int set_extent_buffer_uptodate(struct extent_buffer *eb)
                page = eb->pages[i];
                SetPageUptodate(page);
        }
-       return 0;
 }
 
 int extent_buffer_uptodate(struct extent_buffer *eb)
@@ -5594,6 +5505,155 @@ void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src,
        }
 }
 
+/*
+ * The extent buffer bitmap operations are done with byte granularity because
+ * bitmap items are not guaranteed to be aligned to a word and therefore a
+ * single word in a bitmap may straddle two pages in the extent buffer.
+ */
+#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE)
+#define BYTE_MASK ((1 << BITS_PER_BYTE) - 1)
+#define BITMAP_FIRST_BYTE_MASK(start) \
+       ((BYTE_MASK << ((start) & (BITS_PER_BYTE - 1))) & BYTE_MASK)
+#define BITMAP_LAST_BYTE_MASK(nbits) \
+       (BYTE_MASK >> (-(nbits) & (BITS_PER_BYTE - 1)))
+
+/*
+ * eb_bitmap_offset() - calculate the page and offset of the byte containing the
+ * given bit number
+ * @eb: the extent buffer
+ * @start: offset of the bitmap item in the extent buffer
+ * @nr: bit number
+ * @page_index: return index of the page in the extent buffer that contains the
+ * given bit number
+ * @page_offset: return offset into the page given by page_index
+ *
+ * This helper hides the ugliness of finding the byte in an extent buffer which
+ * contains a given bit.
+ */
+static inline void eb_bitmap_offset(struct extent_buffer *eb,
+                                   unsigned long start, unsigned long nr,
+                                   unsigned long *page_index,
+                                   size_t *page_offset)
+{
+       size_t start_offset = eb->start & ((u64)PAGE_CACHE_SIZE - 1);
+       size_t byte_offset = BIT_BYTE(nr);
+       size_t offset;
+
+       /*
+        * The byte we want is the offset of the extent buffer + the offset of
+        * the bitmap item in the extent buffer + the offset of the byte in the
+        * bitmap item.
+        */
+       offset = start_offset + start + byte_offset;
+
+       *page_index = offset >> PAGE_CACHE_SHIFT;
+       *page_offset = offset & (PAGE_CACHE_SIZE - 1);
+}
+
+/**
+ * extent_buffer_test_bit - determine whether a bit in a bitmap item is set
+ * @eb: the extent buffer
+ * @start: offset of the bitmap item in the extent buffer
+ * @nr: bit number to test
+ */
+int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start,
+                          unsigned long nr)
+{
+       char *kaddr;
+       struct page *page;
+       unsigned long i;
+       size_t offset;
+
+       eb_bitmap_offset(eb, start, nr, &i, &offset);
+       page = eb->pages[i];
+       WARN_ON(!PageUptodate(page));
+       kaddr = page_address(page);
+       return 1U & (kaddr[offset] >> (nr & (BITS_PER_BYTE - 1)));
+}
+
+/**
+ * extent_buffer_bitmap_set - set an area of a bitmap
+ * @eb: the extent buffer
+ * @start: offset of the bitmap item in the extent buffer
+ * @pos: bit number of the first bit
+ * @len: number of bits to set
+ */
+void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,
+                             unsigned long pos, unsigned long len)
+{
+       char *kaddr;
+       struct page *page;
+       unsigned long i;
+       size_t offset;
+       const unsigned int size = pos + len;
+       int bits_to_set = BITS_PER_BYTE - (pos % BITS_PER_BYTE);
+       unsigned int mask_to_set = BITMAP_FIRST_BYTE_MASK(pos);
+
+       eb_bitmap_offset(eb, start, pos, &i, &offset);
+       page = eb->pages[i];
+       WARN_ON(!PageUptodate(page));
+       kaddr = page_address(page);
+
+       while (len >= bits_to_set) {
+               kaddr[offset] |= mask_to_set;
+               len -= bits_to_set;
+               bits_to_set = BITS_PER_BYTE;
+               mask_to_set = ~0U;
+               if (++offset >= PAGE_CACHE_SIZE && len > 0) {
+                       offset = 0;
+                       page = eb->pages[++i];
+                       WARN_ON(!PageUptodate(page));
+                       kaddr = page_address(page);
+               }
+       }
+       if (len) {
+               mask_to_set &= BITMAP_LAST_BYTE_MASK(size);
+               kaddr[offset] |= mask_to_set;
+       }
+}
+
+
+/**
+ * extent_buffer_bitmap_clear - clear an area of a bitmap
+ * @eb: the extent buffer
+ * @start: offset of the bitmap item in the extent buffer
+ * @pos: bit number of the first bit
+ * @len: number of bits to clear
+ */
+void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start,
+                               unsigned long pos, unsigned long len)
+{
+       char *kaddr;
+       struct page *page;
+       unsigned long i;
+       size_t offset;
+       const unsigned int size = pos + len;
+       int bits_to_clear = BITS_PER_BYTE - (pos % BITS_PER_BYTE);
+       unsigned int mask_to_clear = BITMAP_FIRST_BYTE_MASK(pos);
+
+       eb_bitmap_offset(eb, start, pos, &i, &offset);
+       page = eb->pages[i];
+       WARN_ON(!PageUptodate(page));
+       kaddr = page_address(page);
+
+       while (len >= bits_to_clear) {
+               kaddr[offset] &= ~mask_to_clear;
+               len -= bits_to_clear;
+               bits_to_clear = BITS_PER_BYTE;
+               mask_to_clear = ~0U;
+               if (++offset >= PAGE_CACHE_SIZE && len > 0) {
+                       offset = 0;
+                       page = eb->pages[++i];
+                       WARN_ON(!PageUptodate(page));
+                       kaddr = page_address(page);
+               }
+       }
+       if (len) {
+               mask_to_clear &= BITMAP_LAST_BYTE_MASK(size);
+               kaddr[offset] &= ~mask_to_clear;
+       }
+}
+
 static inline bool areas_overlap(unsigned long src, unsigned long dst, unsigned long len)
 {
        unsigned long distance = (src > dst) ? src - dst : dst - src;