LCOV - code coverage report
Current view: top level - fs/btrfs - file-item.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 374 0.0 %
Date: 2014-02-18 Functions: 0 12 0.0 %
Branches: 0 210 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2007 Oracle.  All rights reserved.
       3                 :            :  *
       4                 :            :  * This program is free software; you can redistribute it and/or
       5                 :            :  * modify it under the terms of the GNU General Public
       6                 :            :  * License v2 as published by the Free Software Foundation.
       7                 :            :  *
       8                 :            :  * This program is distributed in the hope that it will be useful,
       9                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      10                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      11                 :            :  * General Public License for more details.
      12                 :            :  *
      13                 :            :  * You should have received a copy of the GNU General Public
      14                 :            :  * License along with this program; if not, write to the
      15                 :            :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      16                 :            :  * Boston, MA 021110-1307, USA.
      17                 :            :  */
      18                 :            : 
      19                 :            : #include <linux/bio.h>
      20                 :            : #include <linux/slab.h>
      21                 :            : #include <linux/pagemap.h>
      22                 :            : #include <linux/highmem.h>
      23                 :            : #include "ctree.h"
      24                 :            : #include "disk-io.h"
      25                 :            : #include "transaction.h"
      26                 :            : #include "volumes.h"
      27                 :            : #include "print-tree.h"
      28                 :            : 
      29                 :            : #define __MAX_CSUM_ITEMS(r, size) ((unsigned long)(((BTRFS_LEAF_DATA_SIZE(r) - \
      30                 :            :                                    sizeof(struct btrfs_item) * 2) / \
      31                 :            :                                   size) - 1))
      32                 :            : 
      33                 :            : #define MAX_CSUM_ITEMS(r, size) (min_t(u32, __MAX_CSUM_ITEMS(r, size), \
      34                 :            :                                        PAGE_CACHE_SIZE))
      35                 :            : 
      36                 :            : #define MAX_ORDERED_SUM_BYTES(r) ((PAGE_SIZE - \
      37                 :            :                                    sizeof(struct btrfs_ordered_sum)) / \
      38                 :            :                                    sizeof(u32) * (r)->sectorsize)
      39                 :            : 
      40                 :          0 : int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
      41                 :            :                              struct btrfs_root *root,
      42                 :            :                              u64 objectid, u64 pos,
      43                 :            :                              u64 disk_offset, u64 disk_num_bytes,
      44                 :            :                              u64 num_bytes, u64 offset, u64 ram_bytes,
      45                 :            :                              u8 compression, u8 encryption, u16 other_encoding)
      46                 :            : {
      47                 :            :         int ret = 0;
      48                 :            :         struct btrfs_file_extent_item *item;
      49                 :            :         struct btrfs_key file_key;
      50                 :            :         struct btrfs_path *path;
      51                 :            :         struct extent_buffer *leaf;
      52                 :            : 
      53                 :          0 :         path = btrfs_alloc_path();
      54         [ #  # ]:          0 :         if (!path)
      55                 :            :                 return -ENOMEM;
      56                 :          0 :         file_key.objectid = objectid;
      57                 :          0 :         file_key.offset = pos;
      58                 :            :         btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY);
      59                 :            : 
      60                 :          0 :         path->leave_spinning = 1;
      61                 :            :         ret = btrfs_insert_empty_item(trans, root, path, &file_key,
      62                 :            :                                       sizeof(*item));
      63         [ #  # ]:          0 :         if (ret < 0)
      64                 :            :                 goto out;
      65         [ #  # ]:          0 :         BUG_ON(ret); /* Can't happen */
      66                 :          0 :         leaf = path->nodes[0];
      67                 :          0 :         item = btrfs_item_ptr(leaf, path->slots[0],
      68                 :            :                               struct btrfs_file_extent_item);
      69                 :            :         btrfs_set_file_extent_disk_bytenr(leaf, item, disk_offset);
      70                 :            :         btrfs_set_file_extent_disk_num_bytes(leaf, item, disk_num_bytes);
      71                 :            :         btrfs_set_file_extent_offset(leaf, item, offset);
      72                 :            :         btrfs_set_file_extent_num_bytes(leaf, item, num_bytes);
      73                 :            :         btrfs_set_file_extent_ram_bytes(leaf, item, ram_bytes);
      74                 :          0 :         btrfs_set_file_extent_generation(leaf, item, trans->transid);
      75                 :            :         btrfs_set_file_extent_type(leaf, item, BTRFS_FILE_EXTENT_REG);
      76                 :            :         btrfs_set_file_extent_compression(leaf, item, compression);
      77                 :            :         btrfs_set_file_extent_encryption(leaf, item, encryption);
      78                 :            :         btrfs_set_file_extent_other_encoding(leaf, item, other_encoding);
      79                 :            : 
      80                 :          0 :         btrfs_mark_buffer_dirty(leaf);
      81                 :            : out:
      82                 :          0 :         btrfs_free_path(path);
      83                 :          0 :         return ret;
      84                 :            : }
      85                 :            : 
      86                 :            : static struct btrfs_csum_item *
      87                 :          0 : btrfs_lookup_csum(struct btrfs_trans_handle *trans,
      88                 :            :                   struct btrfs_root *root,
      89                 :            :                   struct btrfs_path *path,
      90                 :            :                   u64 bytenr, int cow)
      91                 :            : {
      92                 :            :         int ret;
      93                 :            :         struct btrfs_key file_key;
      94                 :            :         struct btrfs_key found_key;
      95                 :            :         struct btrfs_csum_item *item;
      96                 :            :         struct extent_buffer *leaf;
      97                 :            :         u64 csum_offset = 0;
      98                 :          0 :         u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
      99                 :            :         int csums_in_item;
     100                 :            : 
     101                 :          0 :         file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
     102                 :          0 :         file_key.offset = bytenr;
     103                 :            :         btrfs_set_key_type(&file_key, BTRFS_EXTENT_CSUM_KEY);
     104                 :          0 :         ret = btrfs_search_slot(trans, root, &file_key, path, 0, cow);
     105         [ #  # ]:          0 :         if (ret < 0)
     106                 :            :                 goto fail;
     107                 :          0 :         leaf = path->nodes[0];
     108         [ #  # ]:          0 :         if (ret > 0) {
     109                 :            :                 ret = 1;
     110         [ #  # ]:          0 :                 if (path->slots[0] == 0)
     111                 :            :                         goto fail;
     112                 :          0 :                 path->slots[0]--;
     113                 :            :                 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
     114         [ #  # ]:          0 :                 if (btrfs_key_type(&found_key) != BTRFS_EXTENT_CSUM_KEY)
     115                 :            :                         goto fail;
     116                 :            : 
     117                 :          0 :                 csum_offset = (bytenr - found_key.offset) >>
     118                 :          0 :                                 root->fs_info->sb->s_blocksize_bits;
     119                 :          0 :                 csums_in_item = btrfs_item_size_nr(leaf, path->slots[0]);
     120                 :          0 :                 csums_in_item /= csum_size;
     121                 :            : 
     122         [ #  # ]:          0 :                 if (csum_offset == csums_in_item) {
     123                 :            :                         ret = -EFBIG;
     124                 :            :                         goto fail;
     125         [ #  # ]:          0 :                 } else if (csum_offset > csums_in_item) {
     126                 :            :                         goto fail;
     127                 :            :                 }
     128                 :            :         }
     129                 :          0 :         item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
     130                 :          0 :         item = (struct btrfs_csum_item *)((unsigned char *)item +
     131                 :            :                                           csum_offset * csum_size);
     132                 :          0 :         return item;
     133                 :            : fail:
     134         [ #  # ]:          0 :         if (ret > 0)
     135                 :            :                 ret = -ENOENT;
     136                 :          0 :         return ERR_PTR(ret);
     137                 :            : }
     138                 :            : 
     139                 :          0 : int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
     140                 :            :                              struct btrfs_root *root,
     141                 :            :                              struct btrfs_path *path, u64 objectid,
     142                 :            :                              u64 offset, int mod)
     143                 :            : {
     144                 :            :         int ret;
     145                 :            :         struct btrfs_key file_key;
     146         [ #  # ]:          0 :         int ins_len = mod < 0 ? -1 : 0;
     147                 :          0 :         int cow = mod != 0;
     148                 :            : 
     149                 :          0 :         file_key.objectid = objectid;
     150                 :          0 :         file_key.offset = offset;
     151                 :            :         btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY);
     152                 :          0 :         ret = btrfs_search_slot(trans, root, &file_key, path, ins_len, cow);
     153                 :          0 :         return ret;
     154                 :            : }
     155                 :            : 
     156                 :          0 : static void btrfs_io_bio_endio_readpage(struct btrfs_io_bio *bio, int err)
     157                 :            : {
     158                 :          0 :         kfree(bio->csum_allocated);
     159                 :          0 : }
     160                 :            : 
     161                 :          0 : static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
     162                 :            :                                    struct inode *inode, struct bio *bio,
     163                 :            :                                    u64 logical_offset, u32 *dst, int dio)
     164                 :            : {
     165                 :          0 :         struct bio_vec *bvec = bio->bi_io_vec;
     166                 :            :         struct btrfs_io_bio *btrfs_bio = btrfs_io_bio(bio);
     167                 :            :         struct btrfs_csum_item *item = NULL;
     168                 :          0 :         struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
     169                 :            :         struct btrfs_path *path;
     170                 :            :         u8 *csum;
     171                 :            :         u64 offset = 0;
     172                 :            :         u64 item_start_offset = 0;
     173                 :            :         u64 item_last_offset = 0;
     174                 :            :         u64 disk_bytenr;
     175                 :            :         u32 diff;
     176                 :            :         int nblocks;
     177                 :            :         int bio_index = 0;
     178                 :            :         int count;
     179                 :          0 :         u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
     180                 :            : 
     181                 :          0 :         path = btrfs_alloc_path();
     182         [ #  # ]:          0 :         if (!path)
     183                 :            :                 return -ENOMEM;
     184                 :            : 
     185                 :          0 :         nblocks = bio->bi_size >> inode->i_sb->s_blocksize_bits;
     186         [ #  # ]:          0 :         if (!dst) {
     187         [ #  # ]:          0 :                 if (nblocks * csum_size > BTRFS_BIO_INLINE_CSUM_SIZE) {
     188                 :          0 :                         btrfs_bio->csum_allocated = kmalloc(nblocks * csum_size,
     189                 :            :                                                             GFP_NOFS);
     190         [ #  # ]:          0 :                         if (!btrfs_bio->csum_allocated) {
     191                 :          0 :                                 btrfs_free_path(path);
     192                 :            :                                 return -ENOMEM;
     193                 :            :                         }
     194                 :          0 :                         btrfs_bio->csum = btrfs_bio->csum_allocated;
     195                 :          0 :                         btrfs_bio->end_io = btrfs_io_bio_endio_readpage;
     196                 :            :                 } else {
     197                 :          0 :                         btrfs_bio->csum = btrfs_bio->csum_inline;
     198                 :            :                 }
     199                 :          0 :                 csum = btrfs_bio->csum;
     200                 :            :         } else {
     201                 :            :                 csum = (u8 *)dst;
     202                 :            :         }
     203                 :            : 
     204         [ #  # ]:          0 :         if (bio->bi_size > PAGE_CACHE_SIZE * 8)
     205                 :          0 :                 path->reada = 2;
     206                 :            : 
     207         [ #  # ]:          0 :         WARN_ON(bio->bi_vcnt <= 0);
     208                 :            : 
     209                 :            :         /*
     210                 :            :          * the free space stuff is only read when it hasn't been
     211                 :            :          * updated in the current transaction.  So, we can safely
     212                 :            :          * read from the commit root and sidestep a nasty deadlock
     213                 :            :          * between reading the free space cache and updating the csum tree.
     214                 :            :          */
     215         [ #  # ]:          0 :         if (btrfs_is_free_space_inode(inode)) {
     216                 :          0 :                 path->search_commit_root = 1;
     217                 :          0 :                 path->skip_locking = 1;
     218                 :            :         }
     219                 :            : 
     220                 :          0 :         disk_bytenr = (u64)bio->bi_sector << 9;
     221         [ #  # ]:          0 :         if (dio)
     222                 :            :                 offset = logical_offset;
     223         [ #  # ]:          0 :         while (bio_index < bio->bi_vcnt) {
     224         [ #  # ]:          0 :                 if (!dio)
     225                 :          0 :                         offset = page_offset(bvec->bv_page) + bvec->bv_offset;
     226                 :          0 :                 count = btrfs_find_ordered_sum(inode, offset, disk_bytenr,
     227                 :            :                                                (u32 *)csum, nblocks);
     228         [ #  # ]:          0 :                 if (count)
     229                 :            :                         goto found;
     230                 :            : 
     231 [ #  # ][ #  # ]:          0 :                 if (!item || disk_bytenr < item_start_offset ||
     232                 :            :                     disk_bytenr >= item_last_offset) {
     233                 :            :                         struct btrfs_key found_key;
     234                 :            :                         u32 item_size;
     235                 :            : 
     236         [ #  # ]:          0 :                         if (item)
     237                 :          0 :                                 btrfs_release_path(path);
     238                 :          0 :                         item = btrfs_lookup_csum(NULL, root->fs_info->csum_root,
     239                 :            :                                                  path, disk_bytenr, 0);
     240         [ #  # ]:          0 :                         if (IS_ERR(item)) {
     241                 :            :                                 count = 1;
     242         [ #  # ]:          0 :                                 memset(csum, 0, csum_size);
     243         [ #  # ]:          0 :                                 if (BTRFS_I(inode)->root->root_key.objectid ==
     244                 :            :                                     BTRFS_DATA_RELOC_TREE_OBJECTID) {
     245                 :          0 :                                         set_extent_bits(io_tree, offset,
     246                 :          0 :                                                 offset + bvec->bv_len - 1,
     247                 :            :                                                 EXTENT_NODATASUM, GFP_NOFS);
     248                 :            :                                 } else {
     249                 :          0 :                                         printk(KERN_INFO "btrfs no csum found "
     250                 :            :                                                "for inode %llu start %llu\n",
     251                 :            :                                                btrfs_ino(inode), offset);
     252                 :            :                                 }
     253                 :            :                                 item = NULL;
     254                 :          0 :                                 btrfs_release_path(path);
     255                 :            :                                 goto found;
     256                 :            :                         }
     257                 :          0 :                         btrfs_item_key_to_cpu(path->nodes[0], &found_key,
     258                 :            :                                               path->slots[0]);
     259                 :            : 
     260                 :            :                         item_start_offset = found_key.offset;
     261                 :          0 :                         item_size = btrfs_item_size_nr(path->nodes[0],
     262                 :            :                                                        path->slots[0]);
     263                 :          0 :                         item_last_offset = item_start_offset +
     264                 :          0 :                                 (item_size / csum_size) *
     265                 :          0 :                                 root->sectorsize;
     266                 :          0 :                         item = btrfs_item_ptr(path->nodes[0], path->slots[0],
     267                 :            :                                               struct btrfs_csum_item);
     268                 :            :                 }
     269                 :            :                 /*
     270                 :            :                  * this byte range must be able to fit inside
     271                 :            :                  * a single leaf so it will also fit inside a u32
     272                 :            :                  */
     273                 :          0 :                 diff = disk_bytenr - item_start_offset;
     274                 :          0 :                 diff = diff / root->sectorsize;
     275                 :          0 :                 diff = diff * csum_size;
     276                 :          0 :                 count = min_t(int, nblocks, (item_last_offset - disk_bytenr) >>
     277                 :            :                                             inode->i_sb->s_blocksize_bits);
     278                 :          0 :                 read_extent_buffer(path->nodes[0], csum,
     279                 :          0 :                                    ((unsigned long)item) + diff,
     280                 :          0 :                                    csum_size * count);
     281                 :            : found:
     282                 :          0 :                 csum += count * csum_size;
     283                 :          0 :                 nblocks -= count;
     284         [ #  # ]:          0 :                 while (count--) {
     285                 :          0 :                         disk_bytenr += bvec->bv_len;
     286                 :          0 :                         offset += bvec->bv_len;
     287                 :          0 :                         bio_index++;
     288                 :          0 :                         bvec++;
     289                 :            :                 }
     290                 :            :         }
     291                 :          0 :         btrfs_free_path(path);
     292                 :            :         return 0;
     293                 :            : }
     294                 :            : 
     295                 :          0 : int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode,
     296                 :            :                           struct bio *bio, u32 *dst)
     297                 :            : {
     298                 :          0 :         return __btrfs_lookup_bio_sums(root, inode, bio, 0, dst, 0);
     299                 :            : }
     300                 :            : 
     301                 :          0 : int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode,
     302                 :            :                               struct btrfs_dio_private *dip, struct bio *bio,
     303                 :            :                               u64 offset)
     304                 :            : {
     305                 :          0 :         int len = (bio->bi_sector << 9) - dip->disk_bytenr;
     306                 :          0 :         u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
     307                 :            :         int ret;
     308                 :            : 
     309                 :          0 :         len >>= inode->i_sb->s_blocksize_bits;
     310                 :          0 :         len *= csum_size;
     311                 :            : 
     312                 :          0 :         ret = __btrfs_lookup_bio_sums(root, inode, bio, offset,
     313                 :          0 :                                       (u32 *)(dip->csum + len), 1);
     314                 :          0 :         return ret;
     315                 :            : }
     316                 :            : 
     317                 :          0 : int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
     318                 :            :                              struct list_head *list, int search_commit)
     319                 :            : {
     320                 :            :         struct btrfs_key key;
     321                 :            :         struct btrfs_path *path;
     322                 :          0 :         struct extent_buffer *leaf;
     323                 :            :         struct btrfs_ordered_sum *sums;
     324                 :            :         struct btrfs_csum_item *item;
     325                 :          0 :         LIST_HEAD(tmplist);
     326                 :            :         unsigned long offset;
     327                 :            :         int ret;
     328                 :            :         size_t size;
     329                 :            :         u64 csum_end;
     330                 :          0 :         u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
     331                 :            : 
     332                 :            :         ASSERT(start == ALIGN(start, root->sectorsize) &&
     333                 :            :                (end + 1) == ALIGN(end + 1, root->sectorsize));
     334                 :            : 
     335                 :          0 :         path = btrfs_alloc_path();
     336         [ #  # ]:          0 :         if (!path)
     337                 :            :                 return -ENOMEM;
     338                 :            : 
     339         [ #  # ]:          0 :         if (search_commit) {
     340                 :          0 :                 path->skip_locking = 1;
     341                 :          0 :                 path->reada = 2;
     342                 :          0 :                 path->search_commit_root = 1;
     343                 :            :         }
     344                 :            : 
     345                 :          0 :         key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
     346                 :          0 :         key.offset = start;
     347                 :          0 :         key.type = BTRFS_EXTENT_CSUM_KEY;
     348                 :            : 
     349                 :          0 :         ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
     350         [ #  # ]:          0 :         if (ret < 0)
     351                 :            :                 goto fail;
     352 [ #  # ][ #  # ]:          0 :         if (ret > 0 && path->slots[0] > 0) {
     353                 :          0 :                 leaf = path->nodes[0];
     354                 :          0 :                 btrfs_item_key_to_cpu(leaf, &key, path->slots[0] - 1);
     355 [ #  # ][ #  # ]:          0 :                 if (key.objectid == BTRFS_EXTENT_CSUM_OBJECTID &&
     356                 :            :                     key.type == BTRFS_EXTENT_CSUM_KEY) {
     357                 :          0 :                         offset = (start - key.offset) >>
     358                 :          0 :                                  root->fs_info->sb->s_blocksize_bits;
     359         [ #  # ]:          0 :                         if (offset * csum_size <
     360                 :          0 :                             btrfs_item_size_nr(leaf, path->slots[0] - 1))
     361                 :          0 :                                 path->slots[0]--;
     362                 :            :                 }
     363                 :            :         }
     364                 :            : 
     365         [ #  # ]:          0 :         while (start <= end) {
     366                 :          0 :                 leaf = path->nodes[0];
     367         [ #  # ]:          0 :                 if (path->slots[0] >= btrfs_header_nritems(leaf)) {
     368                 :          0 :                         ret = btrfs_next_leaf(root, path);
     369         [ #  # ]:          0 :                         if (ret < 0)
     370                 :            :                                 goto fail;
     371         [ #  # ]:          0 :                         if (ret > 0)
     372                 :            :                                 break;
     373                 :          0 :                         leaf = path->nodes[0];
     374                 :            :                 }
     375                 :            : 
     376                 :          0 :                 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
     377 [ #  # ][ #  # ]:          0 :                 if (key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
     378         [ #  # ]:          0 :                     key.type != BTRFS_EXTENT_CSUM_KEY ||
     379                 :            :                     key.offset > end)
     380                 :            :                         break;
     381                 :            : 
     382         [ #  # ]:          0 :                 if (key.offset > start)
     383                 :            :                         start = key.offset;
     384                 :            : 
     385                 :          0 :                 size = btrfs_item_size_nr(leaf, path->slots[0]);
     386                 :          0 :                 csum_end = key.offset + (size / csum_size) * root->sectorsize;
     387         [ #  # ]:          0 :                 if (csum_end <= start) {
     388                 :          0 :                         path->slots[0]++;
     389                 :          0 :                         continue;
     390                 :            :                 }
     391                 :            : 
     392                 :          0 :                 csum_end = min(csum_end, end + 1);
     393                 :          0 :                 item = btrfs_item_ptr(path->nodes[0], path->slots[0],
     394                 :            :                                       struct btrfs_csum_item);
     395         [ #  # ]:          0 :                 while (start < csum_end) {
     396                 :          0 :                         size = min_t(size_t, csum_end - start,
     397                 :            :                                      MAX_ORDERED_SUM_BYTES(root));
     398                 :            :                         sums = kzalloc(btrfs_ordered_sum_size(root, size),
     399                 :            :                                        GFP_NOFS);
     400         [ #  # ]:          0 :                         if (!sums) {
     401                 :            :                                 ret = -ENOMEM;
     402                 :            :                                 goto fail;
     403                 :            :                         }
     404                 :            : 
     405                 :          0 :                         sums->bytenr = start;
     406                 :          0 :                         sums->len = (int)size;
     407                 :            : 
     408                 :          0 :                         offset = (start - key.offset) >>
     409                 :          0 :                                 root->fs_info->sb->s_blocksize_bits;
     410                 :          0 :                         offset *= csum_size;
     411                 :          0 :                         size >>= root->fs_info->sb->s_blocksize_bits;
     412                 :            : 
     413                 :          0 :                         read_extent_buffer(path->nodes[0],
     414                 :          0 :                                            sums->sums,
     415                 :            :                                            ((unsigned long)item) + offset,
     416                 :          0 :                                            csum_size * size);
     417                 :            : 
     418                 :          0 :                         start += root->sectorsize * size;
     419                 :          0 :                         list_add_tail(&sums->list, &tmplist);
     420                 :            :                 }
     421                 :          0 :                 path->slots[0]++;
     422                 :            :         }
     423                 :            :         ret = 0;
     424                 :            : fail:
     425 [ #  # ][ #  # ]:          0 :         while (ret < 0 && !list_empty(&tmplist)) {
     426                 :            :                 sums = list_entry(&tmplist, struct btrfs_ordered_sum, list);
     427                 :            :                 list_del(&sums->list);
     428                 :          0 :                 kfree(sums);
     429                 :            :         }
     430                 :            :         list_splice_tail(&tmplist, list);
     431                 :            : 
     432                 :          0 :         btrfs_free_path(path);
     433                 :          0 :         return ret;
     434                 :            : }
     435                 :            : 
     436                 :          0 : int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
     437                 :            :                        struct bio *bio, u64 file_start, int contig)
     438                 :            : {
     439                 :            :         struct btrfs_ordered_sum *sums;
     440                 :            :         struct btrfs_ordered_extent *ordered;
     441                 :            :         char *data;
     442                 :          0 :         struct bio_vec *bvec = bio->bi_io_vec;
     443                 :            :         int bio_index = 0;
     444                 :            :         int index;
     445                 :            :         unsigned long total_bytes = 0;
     446                 :            :         unsigned long this_sum_bytes = 0;
     447                 :            :         u64 offset;
     448                 :            : 
     449         [ #  # ]:          0 :         WARN_ON(bio->bi_vcnt <= 0);
     450                 :          0 :         sums = kzalloc(btrfs_ordered_sum_size(root, bio->bi_size), GFP_NOFS);
     451         [ #  # ]:          0 :         if (!sums)
     452                 :            :                 return -ENOMEM;
     453                 :            : 
     454                 :          0 :         sums->len = bio->bi_size;
     455                 :          0 :         INIT_LIST_HEAD(&sums->list);
     456                 :            : 
     457         [ #  # ]:          0 :         if (contig)
     458                 :            :                 offset = file_start;
     459                 :            :         else
     460                 :          0 :                 offset = page_offset(bvec->bv_page) + bvec->bv_offset;
     461                 :            : 
     462                 :          0 :         ordered = btrfs_lookup_ordered_extent(inode, offset);
     463         [ #  # ]:          0 :         BUG_ON(!ordered); /* Logic error */
     464                 :          0 :         sums->bytenr = (u64)bio->bi_sector << 9;
     465                 :            :         index = 0;
     466                 :            : 
     467         [ #  # ]:          0 :         while (bio_index < bio->bi_vcnt) {
     468         [ #  # ]:          0 :                 if (!contig)
     469                 :          0 :                         offset = page_offset(bvec->bv_page) + bvec->bv_offset;
     470                 :            : 
     471 [ #  # ][ #  # ]:          0 :                 if (offset >= ordered->file_offset + ordered->len ||
     472                 :            :                     offset < ordered->file_offset) {
     473                 :            :                         unsigned long bytes_left;
     474                 :          0 :                         sums->len = this_sum_bytes;
     475                 :            :                         this_sum_bytes = 0;
     476                 :          0 :                         btrfs_add_ordered_sum(inode, ordered, sums);
     477                 :          0 :                         btrfs_put_ordered_extent(ordered);
     478                 :            : 
     479                 :          0 :                         bytes_left = bio->bi_size - total_bytes;
     480                 :            : 
     481                 :            :                         sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left),
     482                 :            :                                        GFP_NOFS);
     483         [ #  # ]:          0 :                         BUG_ON(!sums); /* -ENOMEM */
     484                 :          0 :                         sums->len = bytes_left;
     485                 :          0 :                         ordered = btrfs_lookup_ordered_extent(inode, offset);
     486         [ #  # ]:          0 :                         BUG_ON(!ordered); /* Logic error */
     487                 :          0 :                         sums->bytenr = ((u64)bio->bi_sector << 9) +
     488                 :            :                                        total_bytes;
     489                 :            :                         index = 0;
     490                 :            :                 }
     491                 :            : 
     492                 :          0 :                 data = kmap_atomic(bvec->bv_page);
     493                 :          0 :                 sums->sums[index] = ~(u32)0;
     494                 :          0 :                 sums->sums[index] = btrfs_csum_data(data + bvec->bv_offset,
     495                 :            :                                                     sums->sums[index],
     496                 :            :                                                     bvec->bv_len);
     497                 :          0 :                 kunmap_atomic(data);
     498                 :          0 :                 btrfs_csum_final(sums->sums[index],
     499                 :          0 :                                  (char *)(sums->sums + index));
     500                 :            : 
     501                 :          0 :                 bio_index++;
     502                 :          0 :                 index++;
     503                 :          0 :                 total_bytes += bvec->bv_len;
     504                 :          0 :                 this_sum_bytes += bvec->bv_len;
     505                 :          0 :                 offset += bvec->bv_len;
     506                 :          0 :                 bvec++;
     507                 :            :         }
     508                 :            :         this_sum_bytes = 0;
     509                 :          0 :         btrfs_add_ordered_sum(inode, ordered, sums);
     510                 :          0 :         btrfs_put_ordered_extent(ordered);
     511                 :          0 :         return 0;
     512                 :            : }
     513                 :            : 
     514                 :            : /*
     515                 :            :  * helper function for csum removal, this expects the
     516                 :            :  * key to describe the csum pointed to by the path, and it expects
     517                 :            :  * the csum to overlap the range [bytenr, len]
     518                 :            :  *
     519                 :            :  * The csum should not be entirely contained in the range and the
     520                 :            :  * range should not be entirely contained in the csum.
     521                 :            :  *
     522                 :            :  * This calls btrfs_truncate_item with the correct args based on the
     523                 :            :  * overlap, and fixes up the key as required.
     524                 :            :  */
     525                 :          0 : static noinline void truncate_one_csum(struct btrfs_root *root,
     526                 :            :                                        struct btrfs_path *path,
     527                 :            :                                        struct btrfs_key *key,
     528                 :            :                                        u64 bytenr, u64 len)
     529                 :            : {
     530                 :            :         struct extent_buffer *leaf;
     531                 :          0 :         u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
     532                 :            :         u64 csum_end;
     533                 :          0 :         u64 end_byte = bytenr + len;
     534                 :          0 :         u32 blocksize_bits = root->fs_info->sb->s_blocksize_bits;
     535                 :            : 
     536                 :          0 :         leaf = path->nodes[0];
     537                 :          0 :         csum_end = btrfs_item_size_nr(leaf, path->slots[0]) / csum_size;
     538                 :          0 :         csum_end <<= root->fs_info->sb->s_blocksize_bits;
     539                 :          0 :         csum_end += key->offset;
     540                 :            : 
     541 [ #  # ][ #  # ]:          0 :         if (key->offset < bytenr && csum_end <= end_byte) {
     542                 :            :                 /*
     543                 :            :                  *         [ bytenr - len ]
     544                 :            :                  *         [   ]
     545                 :            :                  *   [csum     ]
     546                 :            :                  *   A simple truncate off the end of the item
     547                 :            :                  */
     548                 :          0 :                 u32 new_size = (bytenr - key->offset) >> blocksize_bits;
     549                 :          0 :                 new_size *= csum_size;
     550                 :          0 :                 btrfs_truncate_item(root, path, new_size, 1);
     551 [ #  # ][ #  # ]:          0 :         } else if (key->offset >= bytenr && csum_end > end_byte &&
                 [ #  # ]
     552                 :          0 :                    end_byte > key->offset) {
     553                 :            :                 /*
     554                 :            :                  *         [ bytenr - len ]
     555                 :            :                  *                 [ ]
     556                 :            :                  *                 [csum     ]
     557                 :            :                  * we need to truncate from the beginning of the csum
     558                 :            :                  */
     559                 :          0 :                 u32 new_size = (csum_end - end_byte) >> blocksize_bits;
     560                 :          0 :                 new_size *= csum_size;
     561                 :            : 
     562                 :          0 :                 btrfs_truncate_item(root, path, new_size, 0);
     563                 :            : 
     564                 :          0 :                 key->offset = end_byte;
     565                 :          0 :                 btrfs_set_item_key_safe(root, path, key);
     566                 :            :         } else {
     567                 :          0 :                 BUG();
     568                 :            :         }
     569                 :          0 : }
     570                 :            : 
     571                 :            : /*
     572                 :            :  * deletes the csum items from the csum tree for a given
     573                 :            :  * range of bytes.
     574                 :            :  */
     575                 :          0 : int btrfs_del_csums(struct btrfs_trans_handle *trans,
     576                 :            :                     struct btrfs_root *root, u64 bytenr, u64 len)
     577                 :            : {
     578                 :            :         struct btrfs_path *path;
     579                 :            :         struct btrfs_key key;
     580                 :          0 :         u64 end_byte = bytenr + len;
     581                 :            :         u64 csum_end;
     582                 :            :         struct extent_buffer *leaf;
     583                 :            :         int ret;
     584                 :          0 :         u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
     585                 :          0 :         int blocksize_bits = root->fs_info->sb->s_blocksize_bits;
     586                 :            : 
     587                 :          0 :         root = root->fs_info->csum_root;
     588                 :            : 
     589                 :          0 :         path = btrfs_alloc_path();
     590         [ #  # ]:          0 :         if (!path)
     591                 :            :                 return -ENOMEM;
     592                 :            : 
     593                 :            :         while (1) {
     594                 :          0 :                 key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
     595                 :          0 :                 key.offset = end_byte - 1;
     596                 :          0 :                 key.type = BTRFS_EXTENT_CSUM_KEY;
     597                 :            : 
     598                 :          0 :                 path->leave_spinning = 1;
     599                 :          0 :                 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
     600         [ #  # ]:          0 :                 if (ret > 0) {
     601         [ #  # ]:          0 :                         if (path->slots[0] == 0)
     602                 :            :                                 break;
     603                 :          0 :                         path->slots[0]--;
     604         [ #  # ]:          0 :                 } else if (ret < 0) {
     605                 :            :                         break;
     606                 :            :                 }
     607                 :            : 
     608                 :          0 :                 leaf = path->nodes[0];
     609                 :          0 :                 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
     610                 :            : 
     611 [ #  # ][ #  # ]:          0 :                 if (key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
     612                 :            :                     key.type != BTRFS_EXTENT_CSUM_KEY) {
     613                 :            :                         break;
     614                 :            :                 }
     615                 :            : 
     616         [ #  # ]:          0 :                 if (key.offset >= end_byte)
     617                 :            :                         break;
     618                 :            : 
     619                 :          0 :                 csum_end = btrfs_item_size_nr(leaf, path->slots[0]) / csum_size;
     620                 :          0 :                 csum_end <<= blocksize_bits;
     621                 :          0 :                 csum_end += key.offset;
     622                 :            : 
     623                 :            :                 /* this csum ends before we start, we're done */
     624         [ #  # ]:          0 :                 if (csum_end <= bytenr)
     625                 :            :                         break;
     626                 :            : 
     627                 :            :                 /* delete the entire item, it is inside our range */
     628 [ #  # ][ #  # ]:          0 :                 if (key.offset >= bytenr && csum_end <= end_byte) {
     629                 :            :                         ret = btrfs_del_item(trans, root, path);
     630         [ #  # ]:          0 :                         if (ret)
     631                 :            :                                 goto out;
     632         [ #  # ]:          0 :                         if (key.offset == bytenr)
     633                 :            :                                 break;
     634 [ #  # ][ #  # ]:          0 :                 } else if (key.offset < bytenr && csum_end > end_byte) {
     635                 :            :                         unsigned long offset;
     636                 :            :                         unsigned long shift_len;
     637                 :            :                         unsigned long item_offset;
     638                 :            :                         /*
     639                 :            :                          *        [ bytenr - len ]
     640                 :            :                          *     [csum                ]
     641                 :            :                          *
     642                 :            :                          * Our bytes are in the middle of the csum,
     643                 :            :                          * we need to split this item and insert a new one.
     644                 :            :                          *
     645                 :            :                          * But we can't drop the path because the
     646                 :            :                          * csum could change, get removed, extended etc.
     647                 :            :                          *
     648                 :            :                          * The trick here is the max size of a csum item leaves
     649                 :            :                          * enough room in the tree block for a single
     650                 :            :                          * item header.  So, we split the item in place,
     651                 :            :                          * adding a new header pointing to the existing
     652                 :            :                          * bytes.  Then we loop around again and we have
     653                 :            :                          * a nicely formed csum item that we can neatly
     654                 :            :                          * truncate.
     655                 :            :                          */
     656                 :          0 :                         offset = (bytenr - key.offset) >> blocksize_bits;
     657                 :          0 :                         offset *= csum_size;
     658                 :            : 
     659                 :          0 :                         shift_len = (len >> blocksize_bits) * csum_size;
     660                 :            : 
     661                 :          0 :                         item_offset = btrfs_item_ptr_offset(leaf,
     662                 :            :                                                             path->slots[0]);
     663                 :            : 
     664                 :          0 :                         memset_extent_buffer(leaf, 0, item_offset + offset,
     665                 :            :                                              shift_len);
     666                 :          0 :                         key.offset = bytenr;
     667                 :            : 
     668                 :            :                         /*
     669                 :            :                          * btrfs_split_item returns -EAGAIN when the
     670                 :            :                          * item changed size or key
     671                 :            :                          */
     672                 :          0 :                         ret = btrfs_split_item(trans, root, path, &key, offset);
     673         [ #  # ]:          0 :                         if (ret && ret != -EAGAIN) {
     674                 :          0 :                                 btrfs_abort_transaction(trans, root, ret);
     675                 :          0 :                                 goto out;
     676                 :            :                         }
     677                 :            : 
     678                 :          0 :                         key.offset = end_byte - 1;
     679                 :            :                 } else {
     680                 :          0 :                         truncate_one_csum(root, path, &key, bytenr, len);
     681         [ #  # ]:          0 :                         if (key.offset < bytenr)
     682                 :            :                                 break;
     683                 :            :                 }
     684                 :          0 :                 btrfs_release_path(path);
     685                 :          0 :         }
     686                 :            :         ret = 0;
     687                 :            : out:
     688                 :          0 :         btrfs_free_path(path);
     689                 :          0 :         return ret;
     690                 :            : }
     691                 :            : 
     692                 :          0 : int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
     693                 :            :                            struct btrfs_root *root,
     694                 :            :                            struct btrfs_ordered_sum *sums)
     695                 :            : {
     696                 :            :         struct btrfs_key file_key;
     697                 :            :         struct btrfs_key found_key;
     698                 :            :         struct btrfs_path *path;
     699                 :            :         struct btrfs_csum_item *item;
     700                 :            :         struct btrfs_csum_item *item_end;
     701                 :            :         struct extent_buffer *leaf = NULL;
     702                 :            :         u64 next_offset;
     703                 :            :         u64 total_bytes = 0;
     704                 :            :         u64 csum_offset;
     705                 :            :         u64 bytenr;
     706                 :            :         u32 nritems;
     707                 :            :         u32 ins_size;
     708                 :            :         int index = 0;
     709                 :            :         int found_next;
     710                 :            :         int ret;
     711                 :          0 :         u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
     712                 :            : 
     713                 :          0 :         path = btrfs_alloc_path();
     714         [ #  # ]:          0 :         if (!path)
     715                 :            :                 return -ENOMEM;
     716                 :            : again:
     717                 :            :         next_offset = (u64)-1;
     718                 :            :         found_next = 0;
     719                 :          0 :         bytenr = sums->bytenr + total_bytes;
     720                 :          0 :         file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
     721                 :          0 :         file_key.offset = bytenr;
     722                 :            :         btrfs_set_key_type(&file_key, BTRFS_EXTENT_CSUM_KEY);
     723                 :            : 
     724                 :          0 :         item = btrfs_lookup_csum(trans, root, path, bytenr, 1);
     725         [ #  # ]:          0 :         if (!IS_ERR(item)) {
     726                 :            :                 ret = 0;
     727                 :          0 :                 leaf = path->nodes[0];
     728                 :          0 :                 item_end = btrfs_item_ptr(leaf, path->slots[0],
     729                 :            :                                           struct btrfs_csum_item);
     730                 :          0 :                 item_end = (struct btrfs_csum_item *)((char *)item_end +
     731                 :            :                            btrfs_item_size_nr(leaf, path->slots[0]));
     732                 :          0 :                 goto found;
     733                 :            :         }
     734                 :            :         ret = PTR_ERR(item);
     735         [ #  # ]:          0 :         if (ret != -EFBIG && ret != -ENOENT)
     736                 :            :                 goto fail_unlock;
     737                 :            : 
     738         [ #  # ]:          0 :         if (ret == -EFBIG) {
     739                 :            :                 u32 item_size;
     740                 :            :                 /* we found one, but it isn't big enough yet */
     741                 :          0 :                 leaf = path->nodes[0];
     742                 :          0 :                 item_size = btrfs_item_size_nr(leaf, path->slots[0]);
     743         [ #  # ]:          0 :                 if ((item_size / csum_size) >=
     744                 :          0 :                     MAX_CSUM_ITEMS(root, csum_size)) {
     745                 :            :                         /* already at max size, make a new one */
     746                 :            :                         goto insert;
     747                 :            :                 }
     748                 :            :         } else {
     749                 :          0 :                 int slot = path->slots[0] + 1;
     750                 :            :                 /* we didn't find a csum item, insert one */
     751                 :          0 :                 nritems = btrfs_header_nritems(path->nodes[0]);
     752         [ #  # ]:          0 :                 if (path->slots[0] >= nritems - 1) {
     753                 :          0 :                         ret = btrfs_next_leaf(root, path);
     754         [ #  # ]:          0 :                         if (ret == 1)
     755                 :            :                                 found_next = 1;
     756         [ #  # ]:          0 :                         if (ret != 0)
     757                 :            :                                 goto insert;
     758                 :            :                         slot = 0;
     759                 :            :                 }
     760                 :          0 :                 btrfs_item_key_to_cpu(path->nodes[0], &found_key, slot);
     761 [ #  # ][ #  # ]:          0 :                 if (found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
     762                 :            :                     found_key.type != BTRFS_EXTENT_CSUM_KEY) {
     763                 :            :                         found_next = 1;
     764                 :            :                         goto insert;
     765                 :            :                 }
     766                 :            :                 next_offset = found_key.offset;
     767                 :            :                 found_next = 1;
     768                 :          0 :                 goto insert;
     769                 :            :         }
     770                 :            : 
     771                 :            :         /*
     772                 :            :          * at this point, we know the tree has an item, but it isn't big
     773                 :            :          * enough yet to put our csum in.  Grow it
     774                 :            :          */
     775                 :          0 :         btrfs_release_path(path);
     776                 :          0 :         ret = btrfs_search_slot(trans, root, &file_key, path,
     777                 :            :                                 csum_size, 1);
     778         [ #  # ]:          0 :         if (ret < 0)
     779                 :            :                 goto fail_unlock;
     780                 :            : 
     781         [ #  # ]:          0 :         if (ret > 0) {
     782         [ #  # ]:          0 :                 if (path->slots[0] == 0)
     783                 :            :                         goto insert;
     784                 :          0 :                 path->slots[0]--;
     785                 :            :         }
     786                 :            : 
     787                 :          0 :         leaf = path->nodes[0];
     788                 :          0 :         btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
     789                 :          0 :         csum_offset = (bytenr - found_key.offset) >>
     790                 :          0 :                         root->fs_info->sb->s_blocksize_bits;
     791                 :            : 
     792 [ #  # ][ #  # ]:          0 :         if (btrfs_key_type(&found_key) != BTRFS_EXTENT_CSUM_KEY ||
     793         [ #  # ]:          0 :             found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
     794                 :          0 :             csum_offset >= MAX_CSUM_ITEMS(root, csum_size)) {
     795                 :            :                 goto insert;
     796                 :            :         }
     797                 :            : 
     798         [ #  # ]:          0 :         if (csum_offset == btrfs_item_size_nr(leaf, path->slots[0]) /
     799                 :            :             csum_size) {
     800                 :            :                 int extend_nr;
     801                 :            :                 u64 tmp;
     802                 :            :                 u32 diff;
     803                 :            :                 u32 free_space;
     804                 :            : 
     805         [ #  # ]:          0 :                 if (btrfs_leaf_free_space(root, leaf) <
     806                 :          0 :                                  sizeof(struct btrfs_item) + csum_size * 2)
     807                 :            :                         goto insert;
     808                 :            : 
     809                 :          0 :                 free_space = btrfs_leaf_free_space(root, leaf) -
     810                 :          0 :                                          sizeof(struct btrfs_item) - csum_size;
     811                 :          0 :                 tmp = sums->len - total_bytes;
     812                 :          0 :                 tmp >>= root->fs_info->sb->s_blocksize_bits;
     813         [ #  # ]:          0 :                 WARN_ON(tmp < 1);
     814                 :            : 
     815                 :          0 :                 extend_nr = max_t(int, 1, (int)tmp);
     816                 :          0 :                 diff = (csum_offset + extend_nr) * csum_size;
     817                 :          0 :                 diff = min(diff, MAX_CSUM_ITEMS(root, csum_size) * csum_size);
     818                 :            : 
     819                 :          0 :                 diff = diff - btrfs_item_size_nr(leaf, path->slots[0]);
     820                 :          0 :                 diff = min(free_space, diff);
     821                 :          0 :                 diff /= csum_size;
     822                 :          0 :                 diff *= csum_size;
     823                 :            : 
     824                 :          0 :                 btrfs_extend_item(root, path, diff);
     825                 :            :                 ret = 0;
     826                 :          0 :                 goto csum;
     827                 :            :         }
     828                 :            : 
     829                 :            : insert:
     830                 :          0 :         btrfs_release_path(path);
     831                 :            :         csum_offset = 0;
     832         [ #  # ]:          0 :         if (found_next) {
     833                 :            :                 u64 tmp;
     834                 :            : 
     835                 :          0 :                 tmp = sums->len - total_bytes;
     836                 :          0 :                 tmp >>= root->fs_info->sb->s_blocksize_bits;
     837                 :          0 :                 tmp = min(tmp, (next_offset - file_key.offset) >>
     838                 :            :                                          root->fs_info->sb->s_blocksize_bits);
     839                 :            : 
     840                 :          0 :                 tmp = max((u64)1, tmp);
     841                 :          0 :                 tmp = min(tmp, (u64)MAX_CSUM_ITEMS(root, csum_size));
     842                 :          0 :                 ins_size = csum_size * tmp;
     843                 :            :         } else {
     844                 :          0 :                 ins_size = csum_size;
     845                 :            :         }
     846                 :          0 :         path->leave_spinning = 1;
     847                 :            :         ret = btrfs_insert_empty_item(trans, root, path, &file_key,
     848                 :            :                                       ins_size);
     849                 :          0 :         path->leave_spinning = 0;
     850         [ #  # ]:          0 :         if (ret < 0)
     851                 :            :                 goto fail_unlock;
     852 [ #  # ][ #  # ]:          0 :         if (WARN_ON(ret != 0))
     853                 :            :                 goto fail_unlock;
     854                 :          0 :         leaf = path->nodes[0];
     855                 :            : csum:
     856                 :          0 :         item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
     857                 :          0 :         item_end = (struct btrfs_csum_item *)((unsigned char *)item +
     858                 :            :                                       btrfs_item_size_nr(leaf, path->slots[0]));
     859                 :          0 :         item = (struct btrfs_csum_item *)((unsigned char *)item +
     860                 :            :                                           csum_offset * csum_size);
     861                 :            : found:
     862                 :          0 :         ins_size = (u32)(sums->len - total_bytes) >>
     863                 :          0 :                    root->fs_info->sb->s_blocksize_bits;
     864                 :          0 :         ins_size *= csum_size;
     865                 :          0 :         ins_size = min_t(u32, (unsigned long)item_end - (unsigned long)item,
     866                 :            :                               ins_size);
     867                 :          0 :         write_extent_buffer(leaf, sums->sums + index, (unsigned long)item,
     868                 :            :                             ins_size);
     869                 :            : 
     870                 :          0 :         ins_size /= csum_size;
     871                 :          0 :         total_bytes += ins_size * root->sectorsize;
     872                 :          0 :         index += ins_size;
     873                 :            : 
     874                 :          0 :         btrfs_mark_buffer_dirty(path->nodes[0]);
     875         [ #  # ]:          0 :         if (total_bytes < sums->len) {
     876                 :          0 :                 btrfs_release_path(path);
     877                 :          0 :                 cond_resched();
     878                 :          0 :                 goto again;
     879                 :            :         }
     880                 :            : out:
     881                 :          0 :         btrfs_free_path(path);
     882                 :          0 :         return ret;
     883                 :            : 
     884                 :            : fail_unlock:
     885                 :            :         goto out;
     886                 :            : }

Generated by: LCOV version 1.9