]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/btrfs/file-item.c
Merge tag 'omap-for-v3.16/fixes-rc6' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / fs / btrfs / file-item.c
index 127555b29f587fab26de53b9a52f137f958ce3f5..f46cfe45d68629ff1a05406ef693cf73a6036381 100644 (file)
@@ -281,10 +281,10 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
 found:
                csum += count * csum_size;
                nblocks -= count;
+               bio_index += count;
                while (count--) {
                        disk_bytenr += bvec->bv_len;
                        offset += bvec->bv_len;
-                       bio_index++;
                        bvec++;
                }
        }
@@ -750,7 +750,7 @@ again:
                int slot = path->slots[0] + 1;
                /* we didn't find a csum item, insert one */
                nritems = btrfs_header_nritems(path->nodes[0]);
-               if (path->slots[0] >= nritems - 1) {
+               if (!nritems || (path->slots[0] >= nritems - 1)) {
                        ret = btrfs_next_leaf(root, path);
                        if (ret == 1)
                                found_next = 1;
@@ -885,3 +885,79 @@ out:
 fail_unlock:
        goto out;
 }
+
+void btrfs_extent_item_to_extent_map(struct inode *inode,
+                                    const struct btrfs_path *path,
+                                    struct btrfs_file_extent_item *fi,
+                                    const bool new_inline,
+                                    struct extent_map *em)
+{
+       struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct extent_buffer *leaf = path->nodes[0];
+       const int slot = path->slots[0];
+       struct btrfs_key key;
+       u64 extent_start, extent_end;
+       u64 bytenr;
+       u8 type = btrfs_file_extent_type(leaf, fi);
+       int compress_type = btrfs_file_extent_compression(leaf, fi);
+
+       em->bdev = root->fs_info->fs_devices->latest_bdev;
+       btrfs_item_key_to_cpu(leaf, &key, slot);
+       extent_start = key.offset;
+
+       if (type == BTRFS_FILE_EXTENT_REG ||
+           type == BTRFS_FILE_EXTENT_PREALLOC) {
+               extent_end = extent_start +
+                       btrfs_file_extent_num_bytes(leaf, fi);
+       } else if (type == BTRFS_FILE_EXTENT_INLINE) {
+               size_t size;
+               size = btrfs_file_extent_inline_len(leaf, slot, fi);
+               extent_end = ALIGN(extent_start + size, root->sectorsize);
+       }
+
+       em->ram_bytes = btrfs_file_extent_ram_bytes(leaf, fi);
+       if (type == BTRFS_FILE_EXTENT_REG ||
+           type == BTRFS_FILE_EXTENT_PREALLOC) {
+               em->start = extent_start;
+               em->len = extent_end - extent_start;
+               em->orig_start = extent_start -
+                       btrfs_file_extent_offset(leaf, fi);
+               em->orig_block_len = btrfs_file_extent_disk_num_bytes(leaf, fi);
+               bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
+               if (bytenr == 0) {
+                       em->block_start = EXTENT_MAP_HOLE;
+                       return;
+               }
+               if (compress_type != BTRFS_COMPRESS_NONE) {
+                       set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
+                       em->compress_type = compress_type;
+                       em->block_start = bytenr;
+                       em->block_len = em->orig_block_len;
+               } else {
+                       bytenr += btrfs_file_extent_offset(leaf, fi);
+                       em->block_start = bytenr;
+                       em->block_len = em->len;
+                       if (type == BTRFS_FILE_EXTENT_PREALLOC)
+                               set_bit(EXTENT_FLAG_PREALLOC, &em->flags);
+               }
+       } else if (type == BTRFS_FILE_EXTENT_INLINE) {
+               em->block_start = EXTENT_MAP_INLINE;
+               em->start = extent_start;
+               em->len = extent_end - extent_start;
+               /*
+                * Initialize orig_start and block_len with the same values
+                * as in inode.c:btrfs_get_extent().
+                */
+               em->orig_start = EXTENT_MAP_HOLE;
+               em->block_len = (u64)-1;
+               if (!new_inline && compress_type != BTRFS_COMPRESS_NONE) {
+                       set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
+                       em->compress_type = compress_type;
+               }
+       } else {
+               btrfs_err(root->fs_info,
+                         "unknown file extent item type %d, inode %llu, offset %llu, root %llu",
+                         type, btrfs_ino(inode), extent_start,
+                         root->root_key.objectid);
+       }
+}