btrfs: move tree block wait and write helpers to tree-log
[sfrench/cifs-2.6.git] / fs / btrfs / disk-io.c
index 4f11a83304aeae25d565b9126c7f033d6a65da98..b29bb6e1a283521f7a7970a8ce398e9f5c4f5a57 100644 (file)
@@ -285,7 +285,7 @@ static int csum_tree_block(struct extent_buffer *buf, u8 *result)
                 */
                err = map_private_extent_buffer(buf, offset, 32,
                                        &kaddr, &map_start, &map_len);
-               if (err)
+               if (WARN_ON(err))
                        return err;
                cur_len = min(len, map_len - (offset - map_start));
                crc = btrfs_csum_data(kaddr + offset - map_start,
@@ -394,9 +394,9 @@ static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
        return ret;
 }
 
-static int verify_level_key(struct btrfs_fs_info *fs_info,
-                           struct extent_buffer *eb, int level,
-                           struct btrfs_key *first_key, u64 parent_transid)
+int btrfs_verify_level_key(struct btrfs_fs_info *fs_info,
+                          struct extent_buffer *eb, int level,
+                          struct btrfs_key *first_key, u64 parent_transid)
 {
        int found_level;
        struct btrfs_key found_key;
@@ -404,12 +404,11 @@ static int verify_level_key(struct btrfs_fs_info *fs_info,
 
        found_level = btrfs_header_level(eb);
        if (found_level != level) {
-#ifdef CONFIG_BTRFS_DEBUG
-               WARN_ON(1);
+               WARN(IS_ENABLED(CONFIG_BTRFS_DEBUG),
+                    KERN_ERR "BTRFS: tree level check failed\n");
                btrfs_err(fs_info,
 "tree level mismatch detected, bytenr=%llu level expected=%u has=%u",
                          eb->start, level, found_level);
-#endif
                return -EIO;
        }
 
@@ -430,9 +429,9 @@ static int verify_level_key(struct btrfs_fs_info *fs_info,
                btrfs_item_key_to_cpu(eb, &found_key, 0);
        ret = btrfs_comp_cpu_keys(first_key, &found_key);
 
-#ifdef CONFIG_BTRFS_DEBUG
        if (ret) {
-               WARN_ON(1);
+               WARN(IS_ENABLED(CONFIG_BTRFS_DEBUG),
+                    KERN_ERR "BTRFS: tree first key check failed\n");
                btrfs_err(fs_info,
 "tree first key mismatch detected, bytenr=%llu parent_transid=%llu key expected=(%llu,%u,%llu) has=(%llu,%u,%llu)",
                          eb->start, parent_transid, first_key->objectid,
@@ -440,7 +439,6 @@ static int verify_level_key(struct btrfs_fs_info *fs_info,
                          found_key.objectid, found_key.type,
                          found_key.offset);
        }
-#endif
        return ret;
 }
 
@@ -473,8 +471,8 @@ static int btree_read_extent_buffer_pages(struct btrfs_fs_info *fs_info,
                        if (verify_parent_transid(io_tree, eb,
                                                   parent_transid, 0))
                                ret = -EIO;
-                       else if (verify_level_key(fs_info, eb, level,
-                                                 first_key, parent_transid))
+                       else if (btrfs_verify_level_key(fs_info, eb, level,
+                                               first_key, parent_transid))
                                ret = -EUCLEAN;
                        else
                                break;
@@ -664,6 +662,10 @@ static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
 
        if (!ret)
                set_extent_buffer_uptodate(eb);
+       else
+               btrfs_err(fs_info,
+                         "block=%llu read time tree block corruption detected",
+                         eb->start);
 err:
        if (reads_done &&
            test_and_clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags))
@@ -1021,13 +1023,18 @@ void readahead_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr)
 {
        struct extent_buffer *buf = NULL;
        struct inode *btree_inode = fs_info->btree_inode;
+       int ret;
 
        buf = btrfs_find_create_tree_block(fs_info, bytenr);
        if (IS_ERR(buf))
                return;
-       read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree,
-                                buf, WAIT_NONE, 0);
-       free_extent_buffer(buf);
+
+       ret = read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree, buf,
+                       WAIT_NONE, 0);
+       if (ret < 0)
+               free_extent_buffer_stale(buf);
+       else
+               free_extent_buffer(buf);
 }
 
 int reada_tree_block_flagged(struct btrfs_fs_info *fs_info, u64 bytenr,
@@ -1047,12 +1054,12 @@ int reada_tree_block_flagged(struct btrfs_fs_info *fs_info, u64 bytenr,
        ret = read_extent_buffer_pages(io_tree, buf, WAIT_PAGE_LOCK,
                                       mirror_num);
        if (ret) {
-               free_extent_buffer(buf);
+               free_extent_buffer_stale(buf);
                return ret;
        }
 
        if (test_bit(EXTENT_BUFFER_CORRUPT, &buf->bflags)) {
-               free_extent_buffer(buf);
+               free_extent_buffer_stale(buf);
                return -EIO;
        } else if (extent_buffer_uptodate(buf)) {
                *eb = buf;
@@ -1071,19 +1078,6 @@ struct extent_buffer *btrfs_find_create_tree_block(
        return alloc_extent_buffer(fs_info, bytenr);
 }
 
-
-int btrfs_write_tree_block(struct extent_buffer *buf)
-{
-       return filemap_fdatawrite_range(buf->pages[0]->mapping, buf->start,
-                                       buf->start + buf->len - 1);
-}
-
-void btrfs_wait_tree_block_writeback(struct extent_buffer *buf)
-{
-       filemap_fdatawait_range(buf->pages[0]->mapping,
-                               buf->start, buf->start + buf->len - 1);
-}
-
 /*
  * Read tree block at logical address @bytenr and do variant basic but critical
  * verification.
@@ -1106,7 +1100,7 @@ struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
        ret = btree_read_extent_buffer_pages(fs_info, buf, parent_transid,
                                             level, first_key);
        if (ret) {
-               free_extent_buffer(buf);
+               free_extent_buffer_stale(buf);
                return ERR_PTR(ret);
        }
        return buf;
@@ -1211,7 +1205,8 @@ static void __setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info,
        root->log_transid_committed = -1;
        root->last_log_commit = 0;
        if (!dummy)
-               extent_io_tree_init(&root->dirty_log_pages, NULL);
+               extent_io_tree_init(fs_info, &root->dirty_log_pages,
+                                   IO_TREE_ROOT_DIRTY_LOG_PAGES, NULL);
 
        memset(&root->root_key, 0, sizeof(root->root_key));
        memset(&root->root_item, 0, sizeof(root->root_item));
@@ -2141,8 +2136,9 @@ static void btrfs_init_btree_inode(struct btrfs_fs_info *fs_info)
        inode->i_mapping->a_ops = &btree_aops;
 
        RB_CLEAR_NODE(&BTRFS_I(inode)->rb_node);
-       extent_io_tree_init(&BTRFS_I(inode)->io_tree, inode);
-       BTRFS_I(inode)->io_tree.track_uptodate = 0;
+       extent_io_tree_init(fs_info, &BTRFS_I(inode)->io_tree,
+                           IO_TREE_INODE_IO, inode);
+       BTRFS_I(inode)->io_tree.track_uptodate = false;
        extent_map_tree_init(&BTRFS_I(inode)->extent_tree);
 
        BTRFS_I(inode)->io_tree.ops = &btree_extent_io_ops;
@@ -2751,8 +2747,10 @@ int open_ctree(struct super_block *sb,
        fs_info->block_group_cache_tree = RB_ROOT;
        fs_info->first_logical_byte = (u64)-1;
 
-       extent_io_tree_init(&fs_info->freed_extents[0], NULL);
-       extent_io_tree_init(&fs_info->freed_extents[1], NULL);
+       extent_io_tree_init(fs_info, &fs_info->freed_extents[0],
+                           IO_TREE_FS_INFO_FREED_EXTENTS0, NULL);
+       extent_io_tree_init(fs_info, &fs_info->freed_extents[1],
+                           IO_TREE_FS_INFO_FREED_EXTENTS1, NULL);
        fs_info->pinned_extents = &fs_info->freed_extents[0];
        set_bit(BTRFS_FS_BARRIER, &fs_info->flags);