]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/btrfs/extent_io.c
Merge tag 'for-4.16-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
[linux.git] / fs / btrfs / extent_io.c
index d43360b33ef67fb2e042504e6508e4f2097fede4..dfeb74a0be77c92c525745c3352d3e72759b377d 100644 (file)
@@ -21,6 +21,7 @@
 #include "locking.h"
 #include "rcu-string.h"
 #include "backref.h"
+#include "disk-io.h"
 
 static struct kmem_cache *extent_state_cache;
 static struct kmem_cache *extent_buffer_cache;
@@ -109,8 +110,6 @@ struct tree_entry {
 struct extent_page_data {
        struct bio *bio;
        struct extent_io_tree *tree;
-       get_extent_t *get_extent;
-
        /* tells writepage not to lock the state bits for this range
         * it still does the unlocking
         */
@@ -139,7 +138,8 @@ static void add_extent_changeset(struct extent_state *state, unsigned bits,
        BUG_ON(ret < 0);
 }
 
-static noinline void flush_write_bio(void *data);
+static void flush_write_bio(struct extent_page_data *epd);
+
 static inline struct btrfs_fs_info *
 tree_fs_info(struct extent_io_tree *tree)
 {
@@ -581,7 +581,7 @@ static void extent_io_tree_panic(struct extent_io_tree *tree, int err)
  *
  * This takes the tree lock, and returns 0 on success and < 0 on error.
  */
-static int __clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
+int __clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
                              unsigned bits, int wake, int delete,
                              struct extent_state **cached_state,
                              gfp_t mask, struct extent_changeset *changeset)
@@ -1295,10 +1295,10 @@ int set_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
 
 int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
                     unsigned bits, int wake, int delete,
-                    struct extent_state **cached, gfp_t mask)
+                    struct extent_state **cached)
 {
        return __clear_extent_bit(tree, start, end, bits, wake, delete,
-                                 cached, mask, NULL);
+                                 cached, GFP_NOFS, NULL);
 }
 
 int clear_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
@@ -1348,7 +1348,7 @@ int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end)
        if (err == -EEXIST) {
                if (failed_start > start)
                        clear_extent_bit(tree, start, failed_start - 1,
-                                        EXTENT_LOCKED, 1, 0, NULL, GFP_NOFS);
+                                        EXTENT_LOCKED, 1, 0, NULL);
                return 0;
        }
        return 1;
@@ -1648,7 +1648,7 @@ STATIC u64 find_lock_delalloc_range(struct inode *inode,
                             EXTENT_DELALLOC, 1, cached_state);
        if (!ret) {
                unlock_extent_cached(tree, delalloc_start, delalloc_end,
-                                    &cached_state, GFP_NOFS);
+                                    &cached_state);
                __unlock_for_delalloc(inode, locked_page,
                              delalloc_start, delalloc_end);
                cond_resched();
@@ -1744,7 +1744,7 @@ void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end,
                                 unsigned long page_ops)
 {
        clear_extent_bit(&BTRFS_I(inode)->io_tree, start, end, clear_bits, 1, 0,
-                        NULL, GFP_NOFS);
+                        NULL);
 
        __process_pages_contig(inode->i_mapping, locked_page,
                               start >> PAGE_SHIFT, end >> PAGE_SHIFT,
@@ -2027,7 +2027,8 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start,
        bio->bi_iter.bi_sector = sector;
        dev = bbio->stripes[bbio->mirror_num - 1].dev;
        btrfs_put_bbio(bbio);
-       if (!dev || !dev->bdev || !dev->writeable) {
+       if (!dev || !dev->bdev ||
+           !test_bit(BTRFS_DEV_STATE_WRITEABLE, &dev->dev_state)) {
                btrfs_bio_counter_dec(fs_info);
                bio_put(bio);
                return -EIO;
@@ -2493,7 +2494,7 @@ endio_readpage_release_extent(struct extent_io_tree *tree, u64 start, u64 len,
 
        if (uptodate && tree->track_uptodate)
                set_extent_uptodate(tree, start, end, &cached, GFP_ATOMIC);
-       unlock_extent_cached(tree, start, end, &cached, GFP_ATOMIC);
+       unlock_extent_cached_atomic(tree, start, end, &cached);
 }
 
 /*
@@ -2733,7 +2734,6 @@ static int __must_check submit_one_bio(struct bio *bio, int mirror_num,
        start = page_offset(page) + bvec->bv_offset;
 
        bio->bi_private = NULL;
-       bio_get(bio);
 
        if (tree->ops)
                ret = tree->ops->submit_bio_hook(tree->private_data, bio,
@@ -2741,7 +2741,6 @@ static int __must_check submit_one_bio(struct bio *bio, int mirror_num,
        else
                btrfsic_submit_bio(bio);
 
-       bio_put(bio);
        return blk_status_to_errno(ret);
 }
 
@@ -2943,8 +2942,7 @@ static int __do_readpage(struct extent_io_tree *tree,
                        set_extent_uptodate(tree, cur, cur + iosize - 1,
                                            &cached, GFP_NOFS);
                        unlock_extent_cached(tree, cur,
-                                            cur + iosize - 1,
-                                            &cached, GFP_NOFS);
+                                            cur + iosize - 1, &cached);
                        break;
                }
                em = __get_extent_map(inode, page, pg_offset, cur,
@@ -3037,8 +3035,7 @@ static int __do_readpage(struct extent_io_tree *tree,
                        set_extent_uptodate(tree, cur, cur + iosize - 1,
                                            &cached, GFP_NOFS);
                        unlock_extent_cached(tree, cur,
-                                            cur + iosize - 1,
-                                            &cached, GFP_NOFS);
+                                            cur + iosize - 1, &cached);
                        cur = cur + iosize;
                        pg_offset += iosize;
                        continue;
@@ -3093,9 +3090,8 @@ static int __do_readpage(struct extent_io_tree *tree,
 static inline void __do_contiguous_readpages(struct extent_io_tree *tree,
                                             struct page *pages[], int nr_pages,
                                             u64 start, u64 end,
-                                            get_extent_t *get_extent,
                                             struct extent_map **em_cached,
-                                            struct bio **bio, int mirror_num,
+                                            struct bio **bio,
                                             unsigned long *bio_flags,
                                             u64 *prev_em_start)
 {
@@ -3116,18 +3112,17 @@ static inline void __do_contiguous_readpages(struct extent_io_tree *tree,
        }
 
        for (index = 0; index < nr_pages; index++) {
-               __do_readpage(tree, pages[index], get_extent, em_cached, bio,
-                             mirror_num, bio_flags, 0, prev_em_start);
+               __do_readpage(tree, pages[index], btrfs_get_extent, em_cached,
+                               bio, 0, bio_flags, 0, prev_em_start);
                put_page(pages[index]);
        }
 }
 
 static void __extent_readpages(struct extent_io_tree *tree,
                               struct page *pages[],
-                              int nr_pages, get_extent_t *get_extent,
+                              int nr_pages,
                               struct extent_map **em_cached,
-                              struct bio **bio, int mirror_num,
-                              unsigned long *bio_flags,
+                              struct bio **bio, unsigned long *bio_flags,
                               u64 *prev_em_start)
 {
        u64 start = 0;
@@ -3147,8 +3142,8 @@ static void __extent_readpages(struct extent_io_tree *tree,
                } else {
                        __do_contiguous_readpages(tree, &pages[first_index],
                                                  index - first_index, start,
-                                                 end, get_extent, em_cached,
-                                                 bio, mirror_num, bio_flags,
+                                                 end, em_cached,
+                                                 bio, bio_flags,
                                                  prev_em_start);
                        start = page_start;
                        end = start + PAGE_SIZE - 1;
@@ -3159,9 +3154,8 @@ static void __extent_readpages(struct extent_io_tree *tree,
        if (end)
                __do_contiguous_readpages(tree, &pages[first_index],
                                          index - first_index, start,
-                                         end, get_extent, em_cached, bio,
-                                         mirror_num, bio_flags,
-                                         prev_em_start);
+                                         end, em_cached, bio,
+                                         bio_flags, prev_em_start);
 }
 
 static int __extent_read_full_page(struct extent_io_tree *tree,
@@ -3376,7 +3370,7 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
                                                         page_end, NULL, 1);
                        break;
                }
-               em = epd->get_extent(BTRFS_I(inode), page, pg_offset, cur,
+               em = btrfs_get_extent(BTRFS_I(inode), page, pg_offset, cur,
                                     end - cur + 1, 1);
                if (IS_ERR_OR_NULL(em)) {
                        SetPageError(page);
@@ -3459,10 +3453,9 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
  * and the end_io handler clears the writeback ranges
  */
 static int __extent_writepage(struct page *page, struct writeback_control *wbc,
-                             void *data)
+                             struct extent_page_data *epd)
 {
        struct inode *inode = page->mapping->host;
-       struct extent_page_data *epd = data;
        u64 start = page_offset(page);
        u64 page_end = start + PAGE_SIZE - 1;
        int ret;
@@ -3896,8 +3889,7 @@ int btree_write_cache_pages(struct address_space *mapping,
  * write_cache_pages - walk the list of dirty pages of the given address space and write all of them.
  * @mapping: address space structure to write
  * @wbc: subtract the number of written pages from *@wbc->nr_to_write
- * @writepage: function called for each page
- * @data: data passed to writepage function
+ * @data: data passed to __extent_writepage function
  *
  * If a page is already under I/O, write_cache_pages() skips it, even
  * if it's dirty.  This is desirable behaviour for memory-cleaning writeback,
@@ -3909,8 +3901,7 @@ int btree_write_cache_pages(struct address_space *mapping,
  */
 static int extent_write_cache_pages(struct address_space *mapping,
                             struct writeback_control *wbc,
-                            writepage_t writepage, void *data,
-                            void (*flush_fn)(void *))
+                            struct extent_page_data *epd)
 {
        struct inode *inode = mapping->host;
        int ret = 0;
@@ -3974,7 +3965,7 @@ static int extent_write_cache_pages(struct address_space *mapping,
                         * mapping
                         */
                        if (!trylock_page(page)) {
-                               flush_fn(data);
+                               flush_write_bio(epd);
                                lock_page(page);
                        }
 
@@ -3985,7 +3976,7 @@ static int extent_write_cache_pages(struct address_space *mapping,
 
                        if (wbc->sync_mode != WB_SYNC_NONE) {
                                if (PageWriteback(page))
-                                       flush_fn(data);
+                                       flush_write_bio(epd);
                                wait_on_page_writeback(page);
                        }
 
@@ -3995,7 +3986,7 @@ static int extent_write_cache_pages(struct address_space *mapping,
                                continue;
                        }
 
-                       ret = (*writepage)(page, wbc, data);
+                       ret = __extent_writepage(page, wbc, epd);
 
                        if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE)) {
                                unlock_page(page);
@@ -4043,7 +4034,7 @@ static int extent_write_cache_pages(struct address_space *mapping,
        return ret;
 }
 
-static void flush_epd_write_bio(struct extent_page_data *epd)
+static void flush_write_bio(struct extent_page_data *epd)
 {
        if (epd->bio) {
                int ret;
@@ -4054,37 +4045,28 @@ static void flush_epd_write_bio(struct extent_page_data *epd)
        }
 }
 
-static noinline void flush_write_bio(void *data)
-{
-       struct extent_page_data *epd = data;
-       flush_epd_write_bio(epd);
-}
-
-int extent_write_full_page(struct extent_io_tree *tree, struct page *page,
-                         get_extent_t *get_extent,
-                         struct writeback_control *wbc)
+int extent_write_full_page(struct page *page, struct writeback_control *wbc)
 {
        int ret;
        struct extent_page_data epd = {
                .bio = NULL,
-               .tree = tree,
-               .get_extent = get_extent,
+               .tree = &BTRFS_I(page->mapping->host)->io_tree,
                .extent_locked = 0,
                .sync_io = wbc->sync_mode == WB_SYNC_ALL,
        };
 
        ret = __extent_writepage(page, wbc, &epd);
 
-       flush_epd_write_bio(&epd);
+       flush_write_bio(&epd);
        return ret;
 }
 
-int extent_write_locked_range(struct extent_io_tree *tree, struct inode *inode,
-                             u64 start, u64 end, get_extent_t *get_extent,
+int extent_write_locked_range(struct inode *inode, u64 start, u64 end,
                              int mode)
 {
        int ret = 0;
        struct address_space *mapping = inode->i_mapping;
+       struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree;
        struct page *page;
        unsigned long nr_pages = (end - start + PAGE_SIZE) >>
                PAGE_SHIFT;
@@ -4092,7 +4074,6 @@ int extent_write_locked_range(struct extent_io_tree *tree, struct inode *inode,
        struct extent_page_data epd = {
                .bio = NULL,
                .tree = tree,
-               .get_extent = get_extent,
                .extent_locked = 1,
                .sync_io = mode == WB_SYNC_ALL,
        };
@@ -4118,34 +4099,30 @@ int extent_write_locked_range(struct extent_io_tree *tree, struct inode *inode,
                start += PAGE_SIZE;
        }
 
-       flush_epd_write_bio(&epd);
+       flush_write_bio(&epd);
        return ret;
 }
 
 int extent_writepages(struct extent_io_tree *tree,
                      struct address_space *mapping,
-                     get_extent_t *get_extent,
                      struct writeback_control *wbc)
 {
        int ret = 0;
        struct extent_page_data epd = {
                .bio = NULL,
                .tree = tree,
-               .get_extent = get_extent,
                .extent_locked = 0,
                .sync_io = wbc->sync_mode == WB_SYNC_ALL,
        };
 
-       ret = extent_write_cache_pages(mapping, wbc, __extent_writepage, &epd,
-                                      flush_write_bio);
-       flush_epd_write_bio(&epd);
+       ret = extent_write_cache_pages(mapping, wbc, &epd);
+       flush_write_bio(&epd);
        return ret;
 }
 
 int extent_readpages(struct extent_io_tree *tree,
                     struct address_space *mapping,
-                    struct list_head *pages, unsigned nr_pages,
-                    get_extent_t get_extent)
+                    struct list_head *pages, unsigned nr_pages)
 {
        struct bio *bio = NULL;
        unsigned page_idx;
@@ -4171,13 +4148,13 @@ int extent_readpages(struct extent_io_tree *tree,
                pagepool[nr++] = page;
                if (nr < ARRAY_SIZE(pagepool))
                        continue;
-               __extent_readpages(tree, pagepool, nr, get_extent, &em_cached,
-                                  &bio, 0, &bio_flags, &prev_em_start);
+               __extent_readpages(tree, pagepool, nr, &em_cached, &bio,
+                               &bio_flags, &prev_em_start);
                nr = 0;
        }
        if (nr)
-               __extent_readpages(tree, pagepool, nr, get_extent, &em_cached,
-                                  &bio, 0, &bio_flags, &prev_em_start);
+               __extent_readpages(tree, pagepool, nr, &em_cached, &bio,
+                               &bio_flags, &prev_em_start);
 
        if (em_cached)
                free_extent_map(em_cached);
@@ -4210,7 +4187,7 @@ int extent_invalidatepage(struct extent_io_tree *tree,
        clear_extent_bit(tree, start, end,
                         EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC |
                         EXTENT_DO_ACCOUNTING,
-                        1, 1, &cached_state, GFP_NOFS);
+                        1, 1, &cached_state);
        return 0;
 }
 
@@ -4235,9 +4212,9 @@ static int try_release_extent_state(struct extent_map_tree *map,
                 * at this point we can safely clear everything except the
                 * locked bit and the nodatasum bit
                 */
-               ret = clear_extent_bit(tree, start, end,
+               ret = __clear_extent_bit(tree, start, end,
                                 ~(EXTENT_LOCKED | EXTENT_NODATASUM),
-                                0, 0, NULL, mask);
+                                0, 0, NULL, mask, NULL);
 
                /* if clear_extent_bit failed for enomem reasons,
                 * we can't allow the release to continue.
@@ -4303,9 +4280,7 @@ int try_release_extent_mapping(struct extent_map_tree *map,
  * This maps until we find something past 'last'
  */
 static struct extent_map *get_extent_skip_holes(struct inode *inode,
-                                               u64 offset,
-                                               u64 last,
-                                               get_extent_t *get_extent)
+                                               u64 offset, u64 last)
 {
        u64 sectorsize = btrfs_inode_sectorsize(inode);
        struct extent_map *em;
@@ -4319,15 +4294,14 @@ static struct extent_map *get_extent_skip_holes(struct inode *inode,
                if (len == 0)
                        break;
                len = ALIGN(len, sectorsize);
-               em = get_extent(BTRFS_I(inode), NULL, 0, offset, len, 0);
+               em = btrfs_get_extent_fiemap(BTRFS_I(inode), NULL, 0, offset,
+                               len, 0);
                if (IS_ERR_OR_NULL(em))
                        return em;
 
                /* if this isn't a hole return it */
-               if (!test_bit(EXTENT_FLAG_VACANCY, &em->flags) &&
-                   em->block_start != EXTENT_MAP_HOLE) {
+               if (em->block_start != EXTENT_MAP_HOLE)
                        return em;
-               }
 
                /* this is a hole, advance to the next extent */
                offset = extent_map_end(em);
@@ -4452,7 +4426,7 @@ static int emit_last_fiemap_cache(struct btrfs_fs_info *fs_info,
 }
 
 int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
-               __u64 start, __u64 len, get_extent_t *get_extent)
+               __u64 start, __u64 len)
 {
        int ret = 0;
        u64 off = start;
@@ -4534,8 +4508,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
        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,
-                                  get_extent);
+       em = get_extent_skip_holes(inode, start, last_for_get_extent);
        if (!em)
                goto out;
        if (IS_ERR(em)) {
@@ -4623,8 +4596,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                }
 
                /* now scan forward to see if this is really the last extent. */
-               em = get_extent_skip_holes(inode, off, last_for_get_extent,
-                                          get_extent);
+               em = get_extent_skip_holes(inode, off, last_for_get_extent);
                if (IS_ERR(em)) {
                        ret = PTR_ERR(em);
                        goto out;
@@ -4648,7 +4620,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
 out:
        btrfs_free_path(path);
        unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len - 1,
-                            &cached_state, GFP_NOFS);
+                            &cached_state);
        return ret;
 }
 
@@ -5264,8 +5236,7 @@ int extent_buffer_uptodate(struct extent_buffer *eb)
 }
 
 int read_extent_buffer_pages(struct extent_io_tree *tree,
-                            struct extent_buffer *eb, int wait,
-                            get_extent_t *get_extent, int mirror_num)
+                            struct extent_buffer *eb, int wait, int mirror_num)
 {
        unsigned long i;
        struct page *page;
@@ -5325,7 +5296,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
 
                        ClearPageError(page);
                        err = __extent_read_full_page(tree, page,
-                                                     get_extent, &bio,
+                                                     btree_get_extent, &bio,
                                                      mirror_num, &bio_flags,
                                                      REQ_META);
                        if (err) {