OSDN Git Service

Merge tag 'for-5.8-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
[tomoyo/tomoyo-test1.git] / fs / btrfs / extent_io.c
index 22db0b2..68c9605 100644 (file)
@@ -2333,7 +2333,7 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start,
        return 0;
 }
 
-int btrfs_repair_eb_io_failure(struct extent_buffer *eb, int mirror_num)
+int btrfs_repair_eb_io_failure(const struct extent_buffer *eb, int mirror_num)
 {
        struct btrfs_fs_info *fs_info = eb->fs_info;
        u64 start = eb->start;
@@ -3099,22 +3099,16 @@ static int submit_extent_page(unsigned int opf,
 static void attach_extent_buffer_page(struct extent_buffer *eb,
                                      struct page *page)
 {
-       if (!PagePrivate(page)) {
-               SetPagePrivate(page);
-               get_page(page);
-               set_page_private(page, (unsigned long)eb);
-       } else {
+       if (!PagePrivate(page))
+               attach_page_private(page, eb);
+       else
                WARN_ON(page->private != (unsigned long)eb);
-       }
 }
 
 void set_page_extent_mapped(struct page *page)
 {
-       if (!PagePrivate(page)) {
-               SetPagePrivate(page);
-               get_page(page);
-               set_page_private(page, EXTENT_PAGE_PRIVATE);
-       }
+       if (!PagePrivate(page))
+               attach_page_private(page, (void *)EXTENT_PAGE_PRIVATE);
 }
 
 static struct extent_map *
@@ -4390,51 +4384,32 @@ int extent_writepages(struct address_space *mapping,
        return ret;
 }
 
-int extent_readpages(struct address_space *mapping, struct list_head *pages,
-                    unsigned nr_pages)
+void extent_readahead(struct readahead_control *rac)
 {
        struct bio *bio = NULL;
        unsigned long bio_flags = 0;
        struct page *pagepool[16];
        struct extent_map *em_cached = NULL;
-       int nr = 0;
        u64 prev_em_start = (u64)-1;
+       int nr;
 
-       while (!list_empty(pages)) {
-               u64 contig_end = 0;
+       while ((nr = readahead_page_batch(rac, pagepool))) {
+               u64 contig_start = page_offset(pagepool[0]);
+               u64 contig_end = page_offset(pagepool[nr - 1]) + PAGE_SIZE - 1;
 
-               for (nr = 0; nr < ARRAY_SIZE(pagepool) && !list_empty(pages);) {
-                       struct page *page = lru_to_page(pages);
+               ASSERT(contig_start + nr * PAGE_SIZE - 1 == contig_end);
 
-                       prefetchw(&page->flags);
-                       list_del(&page->lru);
-                       if (add_to_page_cache_lru(page, mapping, page->index,
-                                               readahead_gfp_mask(mapping))) {
-                               put_page(page);
-                               break;
-                       }
-
-                       pagepool[nr++] = page;
-                       contig_end = page_offset(page) + PAGE_SIZE - 1;
-               }
-
-               if (nr) {
-                       u64 contig_start = page_offset(pagepool[0]);
-
-                       ASSERT(contig_start + nr * PAGE_SIZE - 1 == contig_end);
-
-                       contiguous_readpages(pagepool, nr, contig_start,
-                                    contig_end, &em_cached, &bio, &bio_flags,
-                                    &prev_em_start);
-               }
+               contiguous_readpages(pagepool, nr, contig_start, contig_end,
+                               &em_cached, &bio, &bio_flags, &prev_em_start);
        }
 
        if (em_cached)
                free_extent_map(em_cached);
 
-       if (bio)
-               return submit_one_bio(bio, 0, bio_flags);
-       return 0;
+       if (bio) {
+               if (submit_one_bio(bio, 0, bio_flags))
+                       return;
+       }
 }
 
 /*
@@ -4910,7 +4885,7 @@ static void __free_extent_buffer(struct extent_buffer *eb)
        kmem_cache_free(extent_buffer_cache, eb);
 }
 
-int extent_buffer_under_io(struct extent_buffer *eb)
+int extent_buffer_under_io(const struct extent_buffer *eb)
 {
        return (atomic_read(&eb->io_pages) ||
                test_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags) ||
@@ -4952,10 +4927,7 @@ static void btrfs_release_extent_buffer_pages(struct extent_buffer *eb)
                         * We need to make sure we haven't be attached
                         * to a new eb.
                         */
-                       ClearPagePrivate(page);
-                       set_page_private(page, 0);
-                       /* One for the page private */
-                       put_page(page);
+                       detach_page_private(page);
                }
 
                if (mapped)
@@ -5018,7 +4990,7 @@ __alloc_extent_buffer(struct btrfs_fs_info *fs_info, u64 start,
        return eb;
 }
 
-struct extent_buffer *btrfs_clone_extent_buffer(struct extent_buffer *src)
+struct extent_buffer *btrfs_clone_extent_buffer(const struct extent_buffer *src)
 {
        int i;
        struct page *p;
@@ -5424,7 +5396,7 @@ void free_extent_buffer_stale(struct extent_buffer *eb)
        release_extent_buffer(eb);
 }
 
-void clear_extent_buffer_dirty(struct extent_buffer *eb)
+void clear_extent_buffer_dirty(const struct extent_buffer *eb)
 {
        int i;
        int num_pages;
@@ -5622,8 +5594,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 = offset_in_page(eb->start);
-       unsigned long i = (start_offset + start) >> PAGE_SHIFT;
+       unsigned long i = start >> PAGE_SHIFT;
 
        if (start + len > eb->len) {
                WARN(1, KERN_ERR "btrfs bad mapping eb start %llu len %lu, wanted %lu %lu\n",
@@ -5632,7 +5603,7 @@ void read_extent_buffer(const struct extent_buffer *eb, void *dstv,
                return;
        }
 
-       offset = offset_in_page(start_offset + start);
+       offset = offset_in_page(start);
 
        while (len > 0) {
                page = eb->pages[i];
@@ -5657,14 +5628,13 @@ 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 = offset_in_page(eb->start);
-       unsigned long i = (start_offset + start) >> PAGE_SHIFT;
+       unsigned long i = start >> PAGE_SHIFT;
        int ret = 0;
 
        WARN_ON(start > eb->len);
        WARN_ON(start + len > eb->start + eb->len);
 
-       offset = offset_in_page(start_offset + start);
+       offset = offset_in_page(start);
 
        while (len > 0) {
                page = eb->pages[i];
@@ -5685,48 +5655,6 @@ int read_extent_buffer_to_user(const struct extent_buffer *eb,
        return ret;
 }
 
-/*
- * return 0 if the item is found within a page.
- * return 1 if the item spans two pages.
- * return -EINVAL otherwise.
- */
-int map_private_extent_buffer(const struct extent_buffer *eb,
-                             unsigned long start, unsigned long min_len,
-                             char **map, unsigned long *map_start,
-                             unsigned long *map_len)
-{
-       size_t offset;
-       char *kaddr;
-       struct page *p;
-       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;
-
-       if (start + min_len > eb->len) {
-               WARN(1, KERN_ERR "btrfs bad mapping eb start %llu len %lu, wanted %lu %lu\n",
-                      eb->start, eb->len, start, min_len);
-               return -EINVAL;
-       }
-
-       if (i != end_i)
-               return 1;
-
-       if (i == 0) {
-               offset = start_offset;
-               *map_start = 0;
-       } else {
-               offset = 0;
-               *map_start = ((u64)i << PAGE_SHIFT) - start_offset;
-       }
-
-       p = eb->pages[i];
-       kaddr = page_address(p);
-       *map = kaddr + offset;
-       *map_len = PAGE_SIZE - offset;
-       return 0;
-}
-
 int memcmp_extent_buffer(const struct extent_buffer *eb, const void *ptrv,
                         unsigned long start, unsigned long len)
 {
@@ -5735,14 +5663,13 @@ 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 = offset_in_page(eb->start);
-       unsigned long i = (start_offset + start) >> PAGE_SHIFT;
+       unsigned long i = start >> PAGE_SHIFT;
        int ret = 0;
 
        WARN_ON(start > eb->len);
        WARN_ON(start + len > eb->start + eb->len);
 
-       offset = offset_in_page(start_offset + start);
+       offset = offset_in_page(start);
 
        while (len > 0) {
                page = eb->pages[i];
@@ -5762,7 +5689,7 @@ int memcmp_extent_buffer(const struct extent_buffer *eb, const void *ptrv,
        return ret;
 }
 
-void write_extent_buffer_chunk_tree_uuid(struct extent_buffer *eb,
+void write_extent_buffer_chunk_tree_uuid(const struct extent_buffer *eb,
                const void *srcv)
 {
        char *kaddr;
@@ -5773,7 +5700,7 @@ void write_extent_buffer_chunk_tree_uuid(struct extent_buffer *eb,
                        BTRFS_FSID_SIZE);
 }
 
-void write_extent_buffer_fsid(struct extent_buffer *eb, const void *srcv)
+void write_extent_buffer_fsid(const struct extent_buffer *eb, const void *srcv)
 {
        char *kaddr;
 
@@ -5783,7 +5710,7 @@ void write_extent_buffer_fsid(struct extent_buffer *eb, const void *srcv)
                        BTRFS_FSID_SIZE);
 }
 
-void write_extent_buffer(struct extent_buffer *eb, const void *srcv,
+void write_extent_buffer(const struct extent_buffer *eb, const void *srcv,
                         unsigned long start, unsigned long len)
 {
        size_t cur;
@@ -5791,13 +5718,12 @@ void write_extent_buffer(struct extent_buffer *eb, const void *srcv,
        struct page *page;
        char *kaddr;
        char *src = (char *)srcv;
-       size_t start_offset = offset_in_page(eb->start);
-       unsigned long i = (start_offset + start) >> PAGE_SHIFT;
+       unsigned long i = start >> PAGE_SHIFT;
 
        WARN_ON(start > eb->len);
        WARN_ON(start + len > eb->start + eb->len);
 
-       offset = offset_in_page(start_offset + start);
+       offset = offset_in_page(start);
 
        while (len > 0) {
                page = eb->pages[i];
@@ -5814,20 +5740,19 @@ void write_extent_buffer(struct extent_buffer *eb, const void *srcv,
        }
 }
 
-void memzero_extent_buffer(struct extent_buffer *eb, unsigned long start,
+void memzero_extent_buffer(const struct extent_buffer *eb, unsigned long start,
                unsigned long len)
 {
        size_t cur;
        size_t offset;
        struct page *page;
        char *kaddr;
-       size_t start_offset = offset_in_page(eb->start);
-       unsigned long i = (start_offset + start) >> PAGE_SHIFT;
+       unsigned long i = start >> PAGE_SHIFT;
 
        WARN_ON(start > eb->len);
        WARN_ON(start + len > eb->start + eb->len);
 
-       offset = offset_in_page(start_offset + start);
+       offset = offset_in_page(start);
 
        while (len > 0) {
                page = eb->pages[i];
@@ -5843,8 +5768,8 @@ void memzero_extent_buffer(struct extent_buffer *eb, unsigned long start,
        }
 }
 
-void copy_extent_buffer_full(struct extent_buffer *dst,
-                            struct extent_buffer *src)
+void copy_extent_buffer_full(const struct extent_buffer *dst,
+                            const struct extent_buffer *src)
 {
        int i;
        int num_pages;
@@ -5857,7 +5782,8 @@ void copy_extent_buffer_full(struct extent_buffer *dst,
                                page_address(src->pages[i]));
 }
 
-void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src,
+void copy_extent_buffer(const struct extent_buffer *dst,
+                       const struct extent_buffer *src,
                        unsigned long dst_offset, unsigned long src_offset,
                        unsigned long len)
 {
@@ -5866,12 +5792,11 @@ void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src,
        size_t offset;
        struct page *page;
        char *kaddr;
-       size_t start_offset = offset_in_page(dst->start);
-       unsigned long i = (start_offset + dst_offset) >> PAGE_SHIFT;
+       unsigned long i = dst_offset >> PAGE_SHIFT;
 
        WARN_ON(src->len != dst_len);
 
-       offset = offset_in_page(start_offset + dst_offset);
+       offset = offset_in_page(dst_offset);
 
        while (len > 0) {
                page = dst->pages[i];
@@ -5902,12 +5827,11 @@ void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src,
  * 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,
+static inline void eb_bitmap_offset(const struct extent_buffer *eb,
                                    unsigned long start, unsigned long nr,
                                    unsigned long *page_index,
                                    size_t *page_offset)
 {
-       size_t start_offset = offset_in_page(eb->start);
        size_t byte_offset = BIT_BYTE(nr);
        size_t offset;
 
@@ -5916,7 +5840,7 @@ static inline void eb_bitmap_offset(struct extent_buffer *eb,
         * the bitmap item in the extent buffer + the offset of the byte in the
         * bitmap item.
         */
-       offset = start_offset + start + byte_offset;
+       offset = start + byte_offset;
 
        *page_index = offset >> PAGE_SHIFT;
        *page_offset = offset_in_page(offset);
@@ -5928,7 +5852,7 @@ static inline void eb_bitmap_offset(struct extent_buffer *eb,
  * @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,
+int extent_buffer_test_bit(const struct extent_buffer *eb, unsigned long start,
                           unsigned long nr)
 {
        u8 *kaddr;
@@ -5950,7 +5874,7 @@ int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start,
  * @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,
+void extent_buffer_bitmap_set(const struct extent_buffer *eb, unsigned long start,
                              unsigned long pos, unsigned long len)
 {
        u8 *kaddr;
@@ -5992,8 +5916,9 @@ void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,
  * @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)
+void extent_buffer_bitmap_clear(const struct extent_buffer *eb,
+                               unsigned long start, unsigned long pos,
+                               unsigned long len)
 {
        u8 *kaddr;
        struct page *page;
@@ -6054,14 +5979,14 @@ static void copy_pages(struct page *dst_page, struct page *src_page,
                memcpy(dst_kaddr + dst_off, src_kaddr + src_off, len);
 }
 
-void memcpy_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
-                          unsigned long src_offset, unsigned long len)
+void memcpy_extent_buffer(const struct extent_buffer *dst,
+                         unsigned long dst_offset, unsigned long src_offset,
+                         unsigned long len)
 {
        struct btrfs_fs_info *fs_info = dst->fs_info;
        size_t cur;
        size_t dst_off_in_page;
        size_t src_off_in_page;
-       size_t start_offset = offset_in_page(dst->start);
        unsigned long dst_i;
        unsigned long src_i;
 
@@ -6079,11 +6004,11 @@ void memcpy_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
        }
 
        while (len > 0) {
-               dst_off_in_page = offset_in_page(start_offset + dst_offset);
-               src_off_in_page = offset_in_page(start_offset + src_offset);
+               dst_off_in_page = offset_in_page(dst_offset);
+               src_off_in_page = offset_in_page(src_offset);
 
-               dst_i = (start_offset + dst_offset) >> PAGE_SHIFT;
-               src_i = (start_offset + src_offset) >> PAGE_SHIFT;
+               dst_i = dst_offset >> PAGE_SHIFT;
+               src_i = src_offset >> PAGE_SHIFT;
 
                cur = min(len, (unsigned long)(PAGE_SIZE -
                                               src_off_in_page));
@@ -6099,8 +6024,9 @@ void memcpy_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
        }
 }
 
-void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
-                          unsigned long src_offset, unsigned long len)
+void memmove_extent_buffer(const struct extent_buffer *dst,
+                          unsigned long dst_offset, unsigned long src_offset,
+                          unsigned long len)
 {
        struct btrfs_fs_info *fs_info = dst->fs_info;
        size_t cur;
@@ -6108,7 +6034,6 @@ 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 = offset_in_page(dst->start);
        unsigned long dst_i;
        unsigned long src_i;
 
@@ -6129,11 +6054,11 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
                return;
        }
        while (len > 0) {
-               dst_i = (start_offset + dst_end) >> PAGE_SHIFT;
-               src_i = (start_offset + src_end) >> PAGE_SHIFT;
+               dst_i = dst_end >> PAGE_SHIFT;
+               src_i = src_end >> PAGE_SHIFT;
 
-               dst_off_in_page = offset_in_page(start_offset + dst_end);
-               src_off_in_page = offset_in_page(start_offset + src_end);
+               dst_off_in_page = offset_in_page(dst_end);
+               src_off_in_page = offset_in_page(src_end);
 
                cur = min_t(unsigned long, len, src_off_in_page + 1);
                cur = min(cur, dst_off_in_page + 1);