Btrfs: sparse files!
authorChris Mason <chris.mason@oracle.com>
Thu, 24 May 2007 17:35:57 +0000 (13:35 -0400)
committerDavid Woodhouse <dwmw2@hera.kernel.org>
Thu, 24 May 2007 17:35:57 +0000 (13:35 -0400)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/ctree.h
fs/btrfs/extent-tree.c
fs/btrfs/file-item.c
fs/btrfs/super.c

index 3330004..e8f7411 100644 (file)
@@ -1180,6 +1180,7 @@ int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
 int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
                               struct btrfs_root *root,
                               u64 objectid, u64 pos, u64 offset,
+                              u64 disk_num_blocks,
                               u64 num_blocks);
 int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
                             struct btrfs_root *root,
index e3c6bfe..a366415 100644 (file)
@@ -443,6 +443,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
        buf_leaf = btrfs_buffer_leaf(buf);
        for (i = 0; i < btrfs_header_nritems(&buf_node->header); i++) {
                if (leaf) {
+                       u64 disk_blocknr;
                        key = &buf_leaf->items[i].key;
                        if (btrfs_disk_key_type(key) != BTRFS_EXTENT_DATA_KEY)
                                continue;
@@ -451,8 +452,10 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
                        if (btrfs_file_extent_type(fi) ==
                            BTRFS_FILE_EXTENT_INLINE)
                                continue;
-                       ret = btrfs_inc_extent_ref(trans, root,
-                                   btrfs_file_extent_disk_blocknr(fi),
+                       disk_blocknr = btrfs_file_extent_disk_blocknr(fi);
+                       if (disk_blocknr == 0)
+                               continue;
+                       ret = btrfs_inc_extent_ref(trans, root, disk_blocknr,
                                    btrfs_file_extent_disk_num_blocks(fi));
                        BUG_ON(ret);
                } else {
@@ -1248,6 +1251,7 @@ static int drop_leaf_ref(struct btrfs_trans_handle *trans,
        leaf = btrfs_buffer_leaf(cur);
        nritems = btrfs_header_nritems(&leaf->header);
        for (i = 0; i < nritems; i++) {
+               u64 disk_blocknr;
                key = &leaf->items[i].key;
                if (btrfs_disk_key_type(key) != BTRFS_EXTENT_DATA_KEY)
                        continue;
@@ -1258,8 +1262,10 @@ static int drop_leaf_ref(struct btrfs_trans_handle *trans,
                 * FIXME make sure to insert a trans record that
                 * repeats the snapshot del on crash
                 */
-               ret = btrfs_free_extent(trans, root,
-                                       btrfs_file_extent_disk_blocknr(fi),
+               disk_blocknr = btrfs_file_extent_disk_blocknr(fi);
+               if (disk_blocknr == 0)
+                       continue;
+               ret = btrfs_free_extent(trans, root, disk_blocknr,
                                        btrfs_file_extent_disk_num_blocks(fi),
                                        0);
                BUG_ON(ret);
index a66709e..7990b57 100644 (file)
@@ -9,7 +9,8 @@
 int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
                               struct btrfs_root *root,
                               u64 objectid, u64 pos,
-                              u64 offset, u64 num_blocks)
+                              u64 offset, u64 disk_num_blocks,
+                              u64 num_blocks)
 {
        int ret = 0;
        struct btrfs_file_extent_item *item;
@@ -30,7 +31,7 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
        item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0],
                              struct btrfs_file_extent_item);
        btrfs_set_file_extent_disk_blocknr(item, offset);
-       btrfs_set_file_extent_disk_num_blocks(item, num_blocks);
+       btrfs_set_file_extent_disk_num_blocks(item, disk_num_blocks);
        btrfs_set_file_extent_offset(item, 0);
        btrfs_set_file_extent_num_blocks(item, num_blocks);
        btrfs_set_file_extent_generation(item, trans->transid);
@@ -176,14 +177,14 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
        if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY ||
            found_key.objectid != objectid ||
            csum_offset >= MAX_CSUM_ITEMS(root)) {
-               WARN_ON(1);
                goto insert;
        }
        if (csum_offset >= btrfs_item_size(leaf->items + path->slots[0]) /
            BTRFS_CRC32_SIZE) {
                u32 diff = (csum_offset + 1) * BTRFS_CRC32_SIZE;
                diff = diff - btrfs_item_size(leaf->items + path->slots[0]);
-               WARN_ON(diff != BTRFS_CRC32_SIZE);
+               if (diff != BTRFS_CRC32_SIZE)
+                       goto insert;
                ret = btrfs_extend_item(trans, root, path, diff);
                BUG_ON(ret);
                goto csum;
@@ -241,7 +242,7 @@ int btrfs_csum_verify_file_block(struct btrfs_root *root,
                ret = PTR_ERR(item);
                /* a csum that isn't present is a preallocated region. */
                if (ret == -ENOENT || ret == -EFBIG)
-                       ret = 1;
+                       ret = -ENOENT;
                goto fail;
        }
 
Simple merge