Btrfs: shared seed device
[safe/jmp/linux-2.6] / fs / btrfs / inode.c
index 09efc94..0a28b77 100644 (file)
@@ -989,7 +989,6 @@ next_slot:
 
                if (extent_type == BTRFS_FILE_EXTENT_REG ||
                    extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
-                       struct btrfs_block_group_cache *block_group;
                        disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
                        extent_end = found_key.offset +
                                btrfs_file_extent_num_bytes(leaf, fi);
@@ -1007,9 +1006,7 @@ next_slot:
                                goto out_check;
                        if (btrfs_cross_ref_exist(trans, root, disk_bytenr))
                                goto out_check;
-                       block_group = btrfs_lookup_block_group(root->fs_info,
-                                                              disk_bytenr);
-                       if (!block_group || block_group->ro)
+                       if (btrfs_extent_readonly(root, disk_bytenr))
                                goto out_check;
                        disk_bytenr += btrfs_file_extent_offset(leaf, fi);
                        nocow = 1;
@@ -1221,7 +1218,7 @@ static int __btrfs_submit_bio_start(struct inode *inode, int rw, struct bio *bio
        struct btrfs_root *root = BTRFS_I(inode)->root;
        int ret = 0;
 
-       ret = btrfs_csum_one_bio(root, inode, bio);
+       ret = btrfs_csum_one_bio(root, inode, bio, 0, 0);
        BUG_ON(ret);
        return 0;
 }
@@ -1259,12 +1256,11 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
                btrfs_test_flag(inode, NODATASUM);
 
        if (!(rw & (1 << BIO_RW))) {
-
-               if (bio_flags & EXTENT_BIO_COMPRESSED)
+               if (bio_flags & EXTENT_BIO_COMPRESSED) {
                        return btrfs_submit_compressed_read(inode, bio,
                                                    mirror_num, bio_flags);
-               else if (!skip_sum)
-                       btrfs_lookup_bio_sums(root, inode, bio);
+               else if (!skip_sum)
+                       btrfs_lookup_bio_sums(root, inode, bio, NULL);
                goto mapit;
        } else if (!skip_sum) {
                /* we're doing a write, do the async checksumming */
@@ -1292,8 +1288,8 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans,
        btrfs_set_trans_block_group(trans, inode);
        list_for_each(cur, list) {
                sum = list_entry(cur, struct btrfs_ordered_sum, list);
-               btrfs_csum_file_blocks(trans, BTRFS_I(inode)->root,
-                                      inode, sum);
+               btrfs_csum_file_blocks(trans,
+                      BTRFS_I(inode)->root->fs_info->csum_root, sum);
        }
        return 0;
 }
@@ -1545,6 +1541,7 @@ struct io_failure_record {
        u64 start;
        u64 len;
        u64 logical;
+       unsigned long bio_flags;
        int last_mirror;
 };
 
@@ -1563,7 +1560,6 @@ static int btrfs_io_failed_hook(struct bio *failed_bio,
        int ret;
        int rw;
        u64 logical;
-       unsigned long bio_flags = 0;
 
        ret = get_state_private(failure_tree, start, &private);
        if (ret) {
@@ -1573,6 +1569,7 @@ static int btrfs_io_failed_hook(struct bio *failed_bio,
                failrec->start = start;
                failrec->len = end - start + 1;
                failrec->last_mirror = 0;
+               failrec->bio_flags = 0;
 
                spin_lock(&em_tree->lock);
                em = lookup_extent_mapping(em_tree, start, failrec->len);
@@ -1588,8 +1585,10 @@ static int btrfs_io_failed_hook(struct bio *failed_bio,
                }
                logical = start - em->start;
                logical = em->block_start + logical;
-               if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags))
-                       bio_flags = EXTENT_BIO_COMPRESSED;
+               if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) {
+                       logical = em->block_start;
+                       failrec->bio_flags = EXTENT_BIO_COMPRESSED;
+               }
                failrec->logical = logical;
                free_extent_map(em);
                set_extent_bits(failure_tree, start, end, EXTENT_LOCKED |
@@ -1626,6 +1625,7 @@ static int btrfs_io_failed_hook(struct bio *failed_bio,
        bio->bi_sector = failrec->logical >> 9;
        bio->bi_bdev = failed_bio->bi_bdev;
        bio->bi_size = 0;
+
        bio_add_page(bio, page, failrec->len, start - page_offset(page));
        if (failed_bio->bi_rw & (1 << BIO_RW))
                rw = WRITE;
@@ -1634,7 +1634,7 @@ static int btrfs_io_failed_hook(struct bio *failed_bio,
 
        BTRFS_I(inode)->io_tree.ops->submit_bio_hook(inode, rw, bio,
                                                      failrec->last_mirror,
-                                                     bio_flags);
+                                                     failrec->bio_flags);
        return 0;
 }
 
@@ -1688,9 +1688,14 @@ static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end,
        u32 csum = ~(u32)0;
        unsigned long flags;
 
+       if (PageChecked(page)) {
+               ClearPageChecked(page);
+               goto good;
+       }
        if (btrfs_test_opt(root, NODATASUM) ||
            btrfs_test_flag(inode, NODATASUM))
                return 0;
+
        if (state && state->start == start) {
                private = state->private;
                ret = 0;
@@ -1709,7 +1714,7 @@ static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end,
        }
        kunmap_atomic(kaddr, KM_IRQ0);
        local_irq_restore(flags);
-
+good:
        /* if the io failure tree for this inode is non-empty,
         * check to see if we've recovered from a failed IO
         */
@@ -1955,21 +1960,17 @@ void btrfs_read_locked_inode(struct inode *inode)
 
        inode_set_bytes(inode, btrfs_inode_nbytes(leaf, inode_item));
        BTRFS_I(inode)->generation = btrfs_inode_generation(leaf, inode_item);
+       BTRFS_I(inode)->sequence = btrfs_inode_sequence(leaf, inode_item);
        inode->i_generation = BTRFS_I(inode)->generation;
        inode->i_rdev = 0;
        rdev = btrfs_inode_rdev(leaf, inode_item);
 
        BTRFS_I(inode)->index_cnt = (u64)-1;
+       BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item);
 
        alloc_group_block = btrfs_inode_block_group(leaf, inode_item);
-       BTRFS_I(inode)->block_group = btrfs_lookup_block_group(root->fs_info,
-                                                      alloc_group_block);
-       BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item);
-       if (!BTRFS_I(inode)->block_group) {
-               BTRFS_I(inode)->block_group = btrfs_find_block_group(root,
-                                                NULL, 0,
-                                                BTRFS_BLOCK_GROUP_METADATA, 0);
-       }
+       BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0,
+                                               alloc_group_block, 0);
        btrfs_free_path(path);
        inode_item = NULL;
 
@@ -2035,11 +2036,11 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,
 
        btrfs_set_inode_nbytes(leaf, item, inode_get_bytes(inode));
        btrfs_set_inode_generation(leaf, item, BTRFS_I(inode)->generation);
+       btrfs_set_inode_sequence(leaf, item, BTRFS_I(inode)->sequence);
        btrfs_set_inode_transid(leaf, item, trans->transid);
        btrfs_set_inode_rdev(leaf, item, inode->i_rdev);
        btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags);
-       btrfs_set_inode_block_group(leaf, item,
-                                   BTRFS_I(inode)->block_group->key.objectid);
+       btrfs_set_inode_block_group(leaf, item, BTRFS_I(inode)->block_group);
 }
 
 /*
@@ -2243,6 +2244,7 @@ fail:
        return err;
 }
 
+#if 0
 /*
  * when truncating bytes in a file, it is possible to avoid reading
  * the leaves that contain only checksum items.  This can be the
@@ -2410,6 +2412,8 @@ out:
        return ret;
 }
 
+#endif
+
 /*
  * this can truncate away extent items, csum items and directory items.
  * It starts at a high offset and removes keys until it can't find
@@ -2459,9 +2463,6 @@ noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
 
        btrfs_init_path(path);
 
-       ret = drop_csum_leaves(trans, root, path, inode, new_size);
-       BUG_ON(ret);
-
 search_again:
        ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
        if (ret < 0) {
@@ -2509,16 +2510,11 @@ search_again:
                        }
                        item_end--;
                }
-               if (found_type == BTRFS_CSUM_ITEM_KEY) {
-                       ret = btrfs_csum_truncate(trans, root, path,
-                                                 new_size);
-                       BUG_ON(ret);
-               }
                if (item_end < new_size) {
                        if (found_type == BTRFS_DIR_ITEM_KEY) {
                                found_type = BTRFS_INODE_ITEM_KEY;
                        } else if (found_type == BTRFS_EXTENT_ITEM_KEY) {
-                               found_type = BTRFS_CSUM_ITEM_KEY;
+                               found_type = BTRFS_EXTENT_DATA_KEY;
                        } else if (found_type == BTRFS_EXTENT_DATA_KEY) {
                                found_type = BTRFS_XATTR_ITEM_KEY;
                        } else if (found_type == BTRFS_XATTR_ITEM_KEY) {
@@ -2942,6 +2938,7 @@ static noinline void init_btrfs_i(struct inode *inode)
        bi->i_default_acl = NULL;
 
        bi->generation = 0;
+       bi->sequence = 0;
        bi->last_trans = 0;
        bi->logged_trans = 0;
        bi->delalloc_bytes = 0;
@@ -2956,7 +2953,6 @@ static noinline void init_btrfs_i(struct inode *inode)
                             inode->i_mapping, GFP_NOFS);
        INIT_LIST_HEAD(&BTRFS_I(inode)->delalloc_inodes);
        btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree);
-       mutex_init(&BTRFS_I(inode)->csum_mutex);
        mutex_init(&BTRFS_I(inode)->extent_mutex);
        mutex_init(&BTRFS_I(inode)->log_mutex);
 }
@@ -3353,14 +3349,11 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
                                     struct btrfs_root *root,
                                     struct inode *dir,
                                     const char *name, int name_len,
-                                    u64 ref_objectid,
-                                    u64 objectid,
-                                    struct btrfs_block_group_cache *group,
-                                    int mode, u64 *index)
+                                    u64 ref_objectid, u64 objectid,
+                                    u64 alloc_hint, int mode, u64 *index)
 {
        struct inode *inode;
        struct btrfs_inode_item *inode_item;
-       struct btrfs_block_group_cache *new_inode_group;
        struct btrfs_key *location;
        struct btrfs_path *path;
        struct btrfs_inode_ref *ref;
@@ -3396,13 +3389,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
                owner = 0;
        else
                owner = 1;
-       new_inode_group = btrfs_find_block_group(root, group, 0,
-                                      BTRFS_BLOCK_GROUP_METADATA, owner);
-       if (!new_inode_group) {
-               printk("find_block group failed\n");
-               new_inode_group = group;
-       }
-       BTRFS_I(inode)->block_group = new_inode_group;
+       BTRFS_I(inode)->block_group =
+                       btrfs_find_block_group(root, 0, alloc_hint, owner);
 
        key[0].objectid = objectid;
        btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY);
@@ -4361,16 +4349,16 @@ out:
 /*
  * create a new subvolume directory/inode (helper for the ioctl).
  */
-int btrfs_create_subvol_root(struct btrfs_root *new_root, struct dentry *dentry,
-               struct btrfs_trans_handle *trans, u64 new_dirid,
-               struct btrfs_block_group_cache *block_group)
+int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
+                            struct btrfs_root *new_root, struct dentry *dentry,
+                            u64 new_dirid, u64 alloc_hint)
 {
        struct inode *inode;
        int error;
        u64 index = 0;
 
        inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid,
-                               new_dirid, block_group, S_IFDIR | 0700, &index);
+                               new_dirid, alloc_hint, S_IFDIR | 0700, &index);
        if (IS_ERR(inode))
                return PTR_ERR(inode);
        inode->i_op = &btrfs_dir_inode_operations;