Merge branch 'for-3.11' of git://linux-nfs.org/~bfields/linux
[deliverable/linux.git] / fs / btrfs / file-item.c
index b193bf324a4123685483a7754537938267813734..a7bfc954180336348273f8e8f0f145b40581012e 100644 (file)
@@ -34,8 +34,7 @@
 
 #define MAX_ORDERED_SUM_BYTES(r) ((PAGE_SIZE - \
                                   sizeof(struct btrfs_ordered_sum)) / \
-                                  sizeof(struct btrfs_sector_sum) * \
-                                  (r)->sectorsize - (r)->sectorsize)
+                                  sizeof(u32) * (r)->sectorsize)
 
 int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
                             struct btrfs_root *root,
@@ -297,7 +296,6 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
        struct btrfs_path *path;
        struct extent_buffer *leaf;
        struct btrfs_ordered_sum *sums;
-       struct btrfs_sector_sum *sector_sum;
        struct btrfs_csum_item *item;
        LIST_HEAD(tmplist);
        unsigned long offset;
@@ -368,34 +366,28 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
                                      struct btrfs_csum_item);
                while (start < csum_end) {
                        size = min_t(size_t, csum_end - start,
-                                       MAX_ORDERED_SUM_BYTES(root));
+                                    MAX_ORDERED_SUM_BYTES(root));
                        sums = kzalloc(btrfs_ordered_sum_size(root, size),
-                                       GFP_NOFS);
+                                      GFP_NOFS);
                        if (!sums) {
                                ret = -ENOMEM;
                                goto fail;
                        }
 
-                       sector_sum = sums->sums;
                        sums->bytenr = start;
-                       sums->len = size;
+                       sums->len = (int)size;
 
                        offset = (start - key.offset) >>
                                root->fs_info->sb->s_blocksize_bits;
                        offset *= csum_size;
+                       size >>= root->fs_info->sb->s_blocksize_bits;
 
-                       while (size > 0) {
-                               read_extent_buffer(path->nodes[0],
-                                               &sector_sum->sum,
-                                               ((unsigned long)item) +
-                                               offset, csum_size);
-                               sector_sum->bytenr = start;
-
-                               size -= root->sectorsize;
-                               start += root->sectorsize;
-                               offset += csum_size;
-                               sector_sum++;
-                       }
+                       read_extent_buffer(path->nodes[0],
+                                          sums->sums,
+                                          ((unsigned long)item) + offset,
+                                          csum_size * size);
+
+                       start += root->sectorsize * size;
                        list_add_tail(&sums->list, &tmplist);
                }
                path->slots[0]++;
@@ -417,23 +409,20 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
                       struct bio *bio, u64 file_start, int contig)
 {
        struct btrfs_ordered_sum *sums;
-       struct btrfs_sector_sum *sector_sum;
        struct btrfs_ordered_extent *ordered;
        char *data;
        struct bio_vec *bvec = bio->bi_io_vec;
        int bio_index = 0;
+       int index;
        unsigned long total_bytes = 0;
        unsigned long this_sum_bytes = 0;
        u64 offset;
-       u64 disk_bytenr;
 
        WARN_ON(bio->bi_vcnt <= 0);
        sums = kzalloc(btrfs_ordered_sum_size(root, bio->bi_size), GFP_NOFS);
        if (!sums)
                return -ENOMEM;
 
-       sector_sum = sums->sums;
-       disk_bytenr = (u64)bio->bi_sector << 9;
        sums->len = bio->bi_size;
        INIT_LIST_HEAD(&sums->list);
 
@@ -444,7 +433,8 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
 
        ordered = btrfs_lookup_ordered_extent(inode, offset);
        BUG_ON(!ordered); /* Logic error */
-       sums->bytenr = ordered->start;
+       sums->bytenr = (u64)bio->bi_sector << 9;
+       index = 0;
 
        while (bio_index < bio->bi_vcnt) {
                if (!contig)
@@ -463,28 +453,27 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
                        sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left),
                                       GFP_NOFS);
                        BUG_ON(!sums); /* -ENOMEM */
-                       sector_sum = sums->sums;
                        sums->len = bytes_left;
                        ordered = btrfs_lookup_ordered_extent(inode, offset);
                        BUG_ON(!ordered); /* Logic error */
-                       sums->bytenr = ordered->start;
+                       sums->bytenr = ((u64)bio->bi_sector << 9) +
+                                      total_bytes;
+                       index = 0;
                }
 
                data = kmap_atomic(bvec->bv_page);
-               sector_sum->sum = ~(u32)0;
-               sector_sum->sum = btrfs_csum_data(data + bvec->bv_offset,
-                                                 sector_sum->sum,
-                                                 bvec->bv_len);
+               sums->sums[index] = ~(u32)0;
+               sums->sums[index] = btrfs_csum_data(data + bvec->bv_offset,
+                                                   sums->sums[index],
+                                                   bvec->bv_len);
                kunmap_atomic(data);
-               btrfs_csum_final(sector_sum->sum,
-                                (char *)&sector_sum->sum);
-               sector_sum->bytenr = disk_bytenr;
+               btrfs_csum_final(sums->sums[index],
+                                (char *)(sums->sums + index));
 
-               sector_sum++;
                bio_index++;
+               index++;
                total_bytes += bvec->bv_len;
                this_sum_bytes += bvec->bv_len;
-               disk_bytenr += bvec->bv_len;
                offset += bvec->bv_len;
                bvec++;
        }
@@ -672,62 +661,46 @@ out:
        return ret;
 }
 
-static u64 btrfs_sector_sum_left(struct btrfs_ordered_sum *sums,
-                                struct btrfs_sector_sum *sector_sum,
-                                u64 total_bytes, u64 sectorsize)
-{
-       u64 tmp = sectorsize;
-       u64 next_sector = sector_sum->bytenr;
-       struct btrfs_sector_sum *next = sector_sum + 1;
-
-       while ((tmp + total_bytes) < sums->len) {
-               if (next_sector + sectorsize != next->bytenr)
-                       break;
-               tmp += sectorsize;
-               next_sector = next->bytenr;
-               next++;
-       }
-       return tmp;
-}
-
 int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
                           struct btrfs_root *root,
                           struct btrfs_ordered_sum *sums)
 {
-       u64 bytenr;
-       int ret;
        struct btrfs_key file_key;
        struct btrfs_key found_key;
-       u64 next_offset;
-       u64 total_bytes = 0;
-       int found_next;
        struct btrfs_path *path;
        struct btrfs_csum_item *item;
        struct btrfs_csum_item *item_end;
        struct extent_buffer *leaf = NULL;
+       u64 next_offset;
+       u64 total_bytes = 0;
        u64 csum_offset;
-       struct btrfs_sector_sum *sector_sum;
+       u64 bytenr;
        u32 nritems;
        u32 ins_size;
+       int index = 0;
+       int found_next;
+       int ret;
        u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
 
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
-
-       sector_sum = sums->sums;
 again:
        next_offset = (u64)-1;
        found_next = 0;
+       bytenr = sums->bytenr + total_bytes;
        file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
-       file_key.offset = sector_sum->bytenr;
-       bytenr = sector_sum->bytenr;
+       file_key.offset = bytenr;
        btrfs_set_key_type(&file_key, BTRFS_EXTENT_CSUM_KEY);
 
-       item = btrfs_lookup_csum(trans, root, path, sector_sum->bytenr, 1);
+       item = btrfs_lookup_csum(trans, root, path, bytenr, 1);
        if (!IS_ERR(item)) {
-               leaf = path->nodes[0];
                ret = 0;
+               leaf = path->nodes[0];
+               item_end = btrfs_item_ptr(leaf, path->slots[0],
+                                         struct btrfs_csum_item);
+               item_end = (struct btrfs_csum_item *)((char *)item_end +
+                          btrfs_item_size_nr(leaf, path->slots[0]));
                goto found;
        }
        ret = PTR_ERR(item);
@@ -807,8 +780,7 @@ again:
 
                free_space = btrfs_leaf_free_space(root, leaf) -
                                         sizeof(struct btrfs_item) - csum_size;
-               tmp = btrfs_sector_sum_left(sums, sector_sum, total_bytes,
-                                           root->sectorsize);
+               tmp = sums->len - total_bytes;
                tmp >>= root->fs_info->sb->s_blocksize_bits;
                WARN_ON(tmp < 1);
 
@@ -822,6 +794,7 @@ again:
                diff *= csum_size;
 
                btrfs_extend_item(root, path, diff);
+               ret = 0;
                goto csum;
        }
 
@@ -831,8 +804,7 @@ insert:
        if (found_next) {
                u64 tmp;
 
-               tmp = btrfs_sector_sum_left(sums, sector_sum, total_bytes,
-                                           root->sectorsize);
+               tmp = sums->len - total_bytes;
                tmp >>= root->fs_info->sb->s_blocksize_bits;
                tmp = min(tmp, (next_offset - file_key.offset) >>
                                         root->fs_info->sb->s_blocksize_bits);
@@ -853,31 +825,25 @@ insert:
                WARN_ON(1);
                goto fail_unlock;
        }
-csum:
        leaf = path->nodes[0];
+csum:
        item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
-       ret = 0;
+       item_end = (struct btrfs_csum_item *)((unsigned char *)item +
+                                     btrfs_item_size_nr(leaf, path->slots[0]));
        item = (struct btrfs_csum_item *)((unsigned char *)item +
                                          csum_offset * csum_size);
 found:
-       item_end = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
-       item_end = (struct btrfs_csum_item *)((unsigned char *)item_end +
-                                     btrfs_item_size_nr(leaf, path->slots[0]));
-next_sector:
-
-       write_extent_buffer(leaf, &sector_sum->sum, (unsigned long)item, csum_size);
-
-       total_bytes += root->sectorsize;
-       sector_sum++;
-       if (total_bytes < sums->len) {
-               item = (struct btrfs_csum_item *)((char *)item +
-                                                 csum_size);
-               if (item < item_end && bytenr + PAGE_CACHE_SIZE ==
-                   sector_sum->bytenr) {
-                       bytenr = sector_sum->bytenr;
-                       goto next_sector;
-               }
-       }
+       ins_size = (u32)(sums->len - total_bytes) >>
+                  root->fs_info->sb->s_blocksize_bits;
+       ins_size *= csum_size;
+       ins_size = min_t(u32, (unsigned long)item_end - (unsigned long)item,
+                             ins_size);
+       write_extent_buffer(leaf, sums->sums + index, (unsigned long)item,
+                           ins_size);
+
+       ins_size /= csum_size;
+       total_bytes += ins_size * root->sectorsize;
+       index += ins_size;
 
        btrfs_mark_buffer_dirty(path->nodes[0]);
        if (total_bytes < sums->len) {
This page took 0.044279 seconds and 5 git commands to generate.