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-04-16 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_iter.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_iter.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_iter.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 :                                         btrfs_info(BTRFS_I(inode)->root->fs_info,
     250                 :            :                                                    "no csum found for inode %llu start %llu",
     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_iter.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_iter.bi_size),
     451                 :            :                        GFP_NOFS);
     452         [ #  # ]:          0 :         if (!sums)
     453                 :            :                 return -ENOMEM;
     454                 :            : 
     455                 :          0 :         sums->len = bio->bi_iter.bi_size;
     456                 :          0 :         INIT_LIST_HEAD(&sums->list);
     457                 :            : 
     458         [ #  # ]:          0 :         if (contig)
     459                 :            :                 offset = file_start;
     460                 :            :         else
     461                 :          0 :                 offset = page_offset(bvec->bv_page) + bvec->bv_offset;
     462                 :            : 
     463                 :          0 :         ordered = btrfs_lookup_ordered_extent(inode, offset);
     464         [ #  # ]:          0 :         BUG_ON(!ordered); /* Logic error */
     465                 :          0 :         sums->bytenr = (u64)bio->bi_iter.bi_sector << 9;
     466                 :            :         index = 0;
     467                 :            : 
     468         [ #  # ]:          0 :         while (bio_index < bio->bi_vcnt) {
     469         [ #  # ]:          0 :                 if (!contig)
     470                 :          0 :                         offset = page_offset(bvec->bv_page) + bvec->bv_offset;
     471                 :            : 
     472 [ #  # ][ #  # ]:          0 :                 if (offset >= ordered->file_offset + ordered->len ||
     473                 :            :                     offset < ordered->file_offset) {
     474                 :            :                         unsigned long bytes_left;
     475                 :          0 :                         sums->len = this_sum_bytes;
     476                 :            :                         this_sum_bytes = 0;
     477                 :          0 :                         btrfs_add_ordered_sum(inode, ordered, sums);
     478                 :          0 :                         btrfs_put_ordered_extent(ordered);
     479                 :            : 
     480                 :          0 :                         bytes_left = bio->bi_iter.bi_size - total_bytes;
     481                 :            : 
     482                 :            :                         sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left),
     483                 :            :                                        GFP_NOFS);
     484         [ #  # ]:          0 :                         BUG_ON(!sums); /* -ENOMEM */
     485                 :          0 :                         sums->len = bytes_left;
     486                 :          0 :                         ordered = btrfs_lookup_ordered_extent(inode, offset);
     487         [ #  # ]:          0 :                         BUG_ON(!ordered); /* Logic error */
     488                 :          0 :                         sums->bytenr = ((u64)bio->bi_iter.bi_sector << 9) +
     489                 :            :                                        total_bytes;
     490                 :            :                         index = 0;
     491                 :            :                 }
     492                 :            : 
     493                 :          0 :                 data = kmap_atomic(bvec->bv_page);
     494                 :          0 :                 sums->sums[index] = ~(u32)0;
     495                 :          0 :                 sums->sums[index] = btrfs_csum_data(data + bvec->bv_offset,
     496                 :            :                                                     sums->sums[index],
     497                 :            :                                                     bvec->bv_len);
     498                 :          0 :                 kunmap_atomic(data);
     499                 :          0 :                 btrfs_csum_final(sums->sums[index],
     500                 :          0 :                                  (char *)(sums->sums + index));
     501                 :            : 
     502                 :          0 :                 bio_index++;
     503                 :          0 :                 index++;
     504                 :          0 :                 total_bytes += bvec->bv_len;
     505                 :          0 :                 this_sum_bytes += bvec->bv_len;
     506                 :          0 :                 offset += bvec->bv_len;
     507                 :          0 :                 bvec++;
     508                 :            :         }
     509                 :            :         this_sum_bytes = 0;
     510                 :          0 :         btrfs_add_ordered_sum(inode, ordered, sums);
     511                 :          0 :         btrfs_put_ordered_extent(ordered);
     512                 :          0 :         return 0;
     513                 :            : }
     514                 :            : 
     515                 :            : /*
     516                 :            :  * helper function for csum removal, this expects the
     517                 :            :  * key to describe the csum pointed to by the path, and it expects
     518                 :            :  * the csum to overlap the range [bytenr, len]
     519                 :            :  *
     520                 :            :  * The csum should not be entirely contained in the range and the
     521                 :            :  * range should not be entirely contained in the csum.
     522                 :            :  *
     523                 :            :  * This calls btrfs_truncate_item with the correct args based on the
     524                 :            :  * overlap, and fixes up the key as required.
     525                 :            :  */
     526                 :          0 : static noinline void truncate_one_csum(struct btrfs_root *root,
     527                 :            :                                        struct btrfs_path *path,
     528                 :            :                                        struct btrfs_key *key,
     529                 :            :                                        u64 bytenr, u64 len)
     530                 :            : {
     531                 :            :         struct extent_buffer *leaf;
     532                 :          0 :         u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
     533                 :            :         u64 csum_end;
     534                 :          0 :         u64 end_byte = bytenr + len;
     535                 :          0 :         u32 blocksize_bits = root->fs_info->sb->s_blocksize_bits;
     536                 :            : 
     537                 :          0 :         leaf = path->nodes[0];
     538                 :          0 :         csum_end = btrfs_item_size_nr(leaf, path->slots[0]) / csum_size;
     539                 :          0 :         csum_end <<= root->fs_info->sb->s_blocksize_bits;
     540                 :          0 :         csum_end += key->offset;
     541                 :            : 
     542 [ #  # ][ #  # ]:          0 :         if (key->offset < bytenr && csum_end <= end_byte) {
     543                 :            :                 /*
     544                 :            :                  *         [ bytenr - len ]
     545                 :            :                  *         [   ]
     546                 :            :                  *   [csum     ]
     547                 :            :                  *   A simple truncate off the end of the item
     548                 :            :                  */
     549                 :          0 :                 u32 new_size = (bytenr - key->offset) >> blocksize_bits;
     550                 :          0 :                 new_size *= csum_size;
     551                 :          0 :                 btrfs_truncate_item(root, path, new_size, 1);
     552 [ #  # ][ #  # ]:          0 :         } else if (key->offset >= bytenr && csum_end > end_byte &&
                 [ #  # ]
     553                 :          0 :                    end_byte > key->offset) {
     554                 :            :                 /*
     555                 :            :                  *         [ bytenr - len ]
     556                 :            :                  *                 [ ]
     557                 :            :                  *                 [csum     ]
     558                 :            :                  * we need to truncate from the beginning of the csum
     559                 :            :                  */
     560                 :          0 :                 u32 new_size = (csum_end - end_byte) >> blocksize_bits;
     561                 :          0 :                 new_size *= csum_size;
     562                 :            : 
     563                 :          0 :                 btrfs_truncate_item(root, path, new_size, 0);
     564                 :            : 
     565                 :          0 :                 key->offset = end_byte;
     566                 :          0 :                 btrfs_set_item_key_safe(root, path, key);
     567                 :            :         } else {
     568                 :          0 :                 BUG();
     569                 :            :         }
     570                 :          0 : }
     571                 :            : 
     572                 :            : /*
     573                 :            :  * deletes the csum items from the csum tree for a given
     574                 :            :  * range of bytes.
     575                 :            :  */
     576                 :          0 : int btrfs_del_csums(struct btrfs_trans_handle *trans,
     577                 :            :                     struct btrfs_root *root, u64 bytenr, u64 len)
     578                 :            : {
     579                 :            :         struct btrfs_path *path;
     580                 :            :         struct btrfs_key key;
     581                 :          0 :         u64 end_byte = bytenr + len;
     582                 :            :         u64 csum_end;
     583                 :            :         struct extent_buffer *leaf;
     584                 :            :         int ret;
     585                 :          0 :         u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
     586                 :          0 :         int blocksize_bits = root->fs_info->sb->s_blocksize_bits;
     587                 :            : 
     588                 :          0 :         root = root->fs_info->csum_root;
     589                 :            : 
     590                 :          0 :         path = btrfs_alloc_path();
     591         [ #  # ]:          0 :         if (!path)
     592                 :            :                 return -ENOMEM;
     593                 :            : 
     594                 :            :         while (1) {
     595                 :          0 :                 key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
     596                 :          0 :                 key.offset = end_byte - 1;
     597                 :          0 :                 key.type = BTRFS_EXTENT_CSUM_KEY;
     598                 :            : 
     599                 :          0 :                 path->leave_spinning = 1;
     600                 :          0 :                 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
     601         [ #  # ]:          0 :                 if (ret > 0) {
     602         [ #  # ]:          0 :                         if (path->slots[0] == 0)
     603                 :            :                                 break;
     604                 :          0 :                         path->slots[0]--;
     605         [ #  # ]:          0 :                 } else if (ret < 0) {
     606                 :            :                         break;
     607                 :            :                 }
     608                 :            : 
     609                 :          0 :                 leaf = path->nodes[0];
     610                 :          0 :                 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
     611                 :            : 
     612 [ #  # ][ #  # ]:          0 :                 if (key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
     613                 :            :                     key.type != BTRFS_EXTENT_CSUM_KEY) {
     614                 :            :                         break;
     615                 :            :                 }
     616                 :            : 
     617         [ #  # ]:          0 :                 if (key.offset >= end_byte)
     618                 :            :                         break;
     619                 :            : 
     620                 :          0 :                 csum_end = btrfs_item_size_nr(leaf, path->slots[0]) / csum_size;
     621                 :          0 :                 csum_end <<= blocksize_bits;
     622                 :          0 :                 csum_end += key.offset;
     623                 :            : 
     624                 :            :                 /* this csum ends before we start, we're done */
     625         [ #  # ]:          0 :                 if (csum_end <= bytenr)
     626                 :            :                         break;
     627                 :            : 
     628                 :            :                 /* delete the entire item, it is inside our range */
     629 [ #  # ][ #  # ]:          0 :                 if (key.offset >= bytenr && csum_end <= end_byte) {
     630                 :            :                         ret = btrfs_del_item(trans, root, path);
     631         [ #  # ]:          0 :                         if (ret)
     632                 :            :                                 goto out;
     633         [ #  # ]:          0 :                         if (key.offset == bytenr)
     634                 :            :                                 break;
     635 [ #  # ][ #  # ]:          0 :                 } else if (key.offset < bytenr && csum_end > end_byte) {
     636                 :            :                         unsigned long offset;
     637                 :            :                         unsigned long shift_len;
     638                 :            :                         unsigned long item_offset;
     639                 :            :                         /*
     640                 :            :                          *        [ bytenr - len ]
     641                 :            :                          *     [csum                ]
     642                 :            :                          *
     643                 :            :                          * Our bytes are in the middle of the csum,
     644                 :            :                          * we need to split this item and insert a new one.
     645                 :            :                          *
     646                 :            :                          * But we can't drop the path because the
     647                 :            :                          * csum could change, get removed, extended etc.
     648                 :            :                          *
     649                 :            :                          * The trick here is the max size of a csum item leaves
     650                 :            :                          * enough room in the tree block for a single
     651                 :            :                          * item header.  So, we split the item in place,
     652                 :            :                          * adding a new header pointing to the existing
     653                 :            :                          * bytes.  Then we loop around again and we have
     654                 :            :                          * a nicely formed csum item that we can neatly
     655                 :            :                          * truncate.
     656                 :            :                          */
     657                 :          0 :                         offset = (bytenr - key.offset) >> blocksize_bits;
     658                 :          0 :                         offset *= csum_size;
     659                 :            : 
     660                 :          0 :                         shift_len = (len >> blocksize_bits) * csum_size;
     661                 :            : 
     662                 :          0 :                         item_offset = btrfs_item_ptr_offset(leaf,
     663                 :            :                                                             path->slots[0]);
     664                 :            : 
     665                 :          0 :                         memset_extent_buffer(leaf, 0, item_offset + offset,
     666                 :            :                                              shift_len);
     667                 :          0 :                         key.offset = bytenr;
     668                 :            : 
     669                 :            :                         /*
     670                 :            :                          * btrfs_split_item returns -EAGAIN when the
     671                 :            :                          * item changed size or key
     672                 :            :                          */
     673                 :          0 :                         ret = btrfs_split_item(trans, root, path, &key, offset);
     674         [ #  # ]:          0 :                         if (ret && ret != -EAGAIN) {
     675                 :          0 :                                 btrfs_abort_transaction(trans, root, ret);
     676                 :          0 :                                 goto out;
     677                 :            :                         }
     678                 :            : 
     679                 :          0 :                         key.offset = end_byte - 1;
     680                 :            :                 } else {
     681                 :          0 :                         truncate_one_csum(root, path, &key, bytenr, len);
     682         [ #  # ]:          0 :                         if (key.offset < bytenr)
     683                 :            :                                 break;
     684                 :            :                 }
     685                 :          0 :                 btrfs_release_path(path);
     686                 :          0 :         }
     687                 :            :         ret = 0;
     688                 :            : out:
     689                 :          0 :         btrfs_free_path(path);
     690                 :          0 :         return ret;
     691                 :            : }
     692                 :            : 
     693                 :          0 : int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
     694                 :            :                            struct btrfs_root *root,
     695                 :            :                            struct btrfs_ordered_sum *sums)
     696                 :            : {
     697                 :            :         struct btrfs_key file_key;
     698                 :            :         struct btrfs_key found_key;
     699                 :            :         struct btrfs_path *path;
     700                 :            :         struct btrfs_csum_item *item;
     701                 :            :         struct btrfs_csum_item *item_end;
     702                 :            :         struct extent_buffer *leaf = NULL;
     703                 :            :         u64 next_offset;
     704                 :            :         u64 total_bytes = 0;
     705                 :            :         u64 csum_offset;
     706                 :            :         u64 bytenr;
     707                 :            :         u32 nritems;
     708                 :            :         u32 ins_size;
     709                 :            :         int index = 0;
     710                 :            :         int found_next;
     711                 :            :         int ret;
     712                 :          0 :         u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
     713                 :            : 
     714                 :          0 :         path = btrfs_alloc_path();
     715         [ #  # ]:          0 :         if (!path)
     716                 :            :                 return -ENOMEM;
     717                 :            : again:
     718                 :            :         next_offset = (u64)-1;
     719                 :            :         found_next = 0;
     720                 :          0 :         bytenr = sums->bytenr + total_bytes;
     721                 :          0 :         file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
     722                 :          0 :         file_key.offset = bytenr;
     723                 :            :         btrfs_set_key_type(&file_key, BTRFS_EXTENT_CSUM_KEY);
     724                 :            : 
     725                 :          0 :         item = btrfs_lookup_csum(trans, root, path, bytenr, 1);
     726         [ #  # ]:          0 :         if (!IS_ERR(item)) {
     727                 :            :                 ret = 0;
     728                 :          0 :                 leaf = path->nodes[0];
     729                 :          0 :                 item_end = btrfs_item_ptr(leaf, path->slots[0],
     730                 :            :                                           struct btrfs_csum_item);
     731                 :          0 :                 item_end = (struct btrfs_csum_item *)((char *)item_end +
     732                 :            :                            btrfs_item_size_nr(leaf, path->slots[0]));
     733                 :          0 :                 goto found;
     734                 :            :         }
     735                 :            :         ret = PTR_ERR(item);
     736         [ #  # ]:          0 :         if (ret != -EFBIG && ret != -ENOENT)
     737                 :            :                 goto fail_unlock;
     738                 :            : 
     739         [ #  # ]:          0 :         if (ret == -EFBIG) {
     740                 :            :                 u32 item_size;
     741                 :            :                 /* we found one, but it isn't big enough yet */
     742                 :          0 :                 leaf = path->nodes[0];
     743                 :          0 :                 item_size = btrfs_item_size_nr(leaf, path->slots[0]);
     744         [ #  # ]:          0 :                 if ((item_size / csum_size) >=
     745                 :          0 :                     MAX_CSUM_ITEMS(root, csum_size)) {
     746                 :            :                         /* already at max size, make a new one */
     747                 :            :                         goto insert;
     748                 :            :                 }
     749                 :            :         } else {
     750                 :          0 :                 int slot = path->slots[0] + 1;
     751                 :            :                 /* we didn't find a csum item, insert one */
     752                 :          0 :                 nritems = btrfs_header_nritems(path->nodes[0]);
     753         [ #  # ]:          0 :                 if (path->slots[0] >= nritems - 1) {
     754                 :          0 :                         ret = btrfs_next_leaf(root, path);
     755         [ #  # ]:          0 :                         if (ret == 1)
     756                 :            :                                 found_next = 1;
     757         [ #  # ]:          0 :                         if (ret != 0)
     758                 :            :                                 goto insert;
     759                 :            :                         slot = 0;
     760                 :            :                 }
     761                 :          0 :                 btrfs_item_key_to_cpu(path->nodes[0], &found_key, slot);
     762 [ #  # ][ #  # ]:          0 :                 if (found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
     763                 :            :                     found_key.type != BTRFS_EXTENT_CSUM_KEY) {
     764                 :            :                         found_next = 1;
     765                 :            :                         goto insert;
     766                 :            :                 }
     767                 :            :                 next_offset = found_key.offset;
     768                 :            :                 found_next = 1;
     769                 :          0 :                 goto insert;
     770                 :            :         }
     771                 :            : 
     772                 :            :         /*
     773                 :            :          * at this point, we know the tree has an item, but it isn't big
     774                 :            :          * enough yet to put our csum in.  Grow it
     775                 :            :          */
     776                 :          0 :         btrfs_release_path(path);
     777                 :          0 :         ret = btrfs_search_slot(trans, root, &file_key, path,
     778                 :            :                                 csum_size, 1);
     779         [ #  # ]:          0 :         if (ret < 0)
     780                 :            :                 goto fail_unlock;
     781                 :            : 
     782         [ #  # ]:          0 :         if (ret > 0) {
     783         [ #  # ]:          0 :                 if (path->slots[0] == 0)
     784                 :            :                         goto insert;
     785                 :          0 :                 path->slots[0]--;
     786                 :            :         }
     787                 :            : 
     788                 :          0 :         leaf = path->nodes[0];
     789                 :          0 :         btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
     790                 :          0 :         csum_offset = (bytenr - found_key.offset) >>
     791                 :          0 :                         root->fs_info->sb->s_blocksize_bits;
     792                 :            : 
     793 [ #  # ][ #  # ]:          0 :         if (btrfs_key_type(&found_key) != BTRFS_EXTENT_CSUM_KEY ||
     794         [ #  # ]:          0 :             found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
     795                 :          0 :             csum_offset >= MAX_CSUM_ITEMS(root, csum_size)) {
     796                 :            :                 goto insert;
     797                 :            :         }
     798                 :            : 
     799         [ #  # ]:          0 :         if (csum_offset == btrfs_item_size_nr(leaf, path->slots[0]) /
     800                 :            :             csum_size) {
     801                 :            :                 int extend_nr;
     802                 :            :                 u64 tmp;
     803                 :            :                 u32 diff;
     804                 :            :                 u32 free_space;
     805                 :            : 
     806         [ #  # ]:          0 :                 if (btrfs_leaf_free_space(root, leaf) <
     807                 :          0 :                                  sizeof(struct btrfs_item) + csum_size * 2)
     808                 :            :                         goto insert;
     809                 :            : 
     810                 :          0 :                 free_space = btrfs_leaf_free_space(root, leaf) -
     811                 :          0 :                                          sizeof(struct btrfs_item) - csum_size;
     812                 :          0 :                 tmp = sums->len - total_bytes;
     813                 :          0 :                 tmp >>= root->fs_info->sb->s_blocksize_bits;
     814         [ #  # ]:          0 :                 WARN_ON(tmp < 1);
     815                 :            : 
     816                 :          0 :                 extend_nr = max_t(int, 1, (int)tmp);
     817                 :          0 :                 diff = (csum_offset + extend_nr) * csum_size;
     818                 :          0 :                 diff = min(diff, MAX_CSUM_ITEMS(root, csum_size) * csum_size);
     819                 :            : 
     820                 :          0 :                 diff = diff - btrfs_item_size_nr(leaf, path->slots[0]);
     821                 :          0 :                 diff = min(free_space, diff);
     822                 :          0 :                 diff /= csum_size;
     823                 :          0 :                 diff *= csum_size;
     824                 :            : 
     825                 :          0 :                 btrfs_extend_item(root, path, diff);
     826                 :            :                 ret = 0;
     827                 :          0 :                 goto csum;
     828                 :            :         }
     829                 :            : 
     830                 :            : insert:
     831                 :          0 :         btrfs_release_path(path);
     832                 :            :         csum_offset = 0;
     833         [ #  # ]:          0 :         if (found_next) {
     834                 :            :                 u64 tmp;
     835                 :            : 
     836                 :          0 :                 tmp = sums->len - total_bytes;
     837                 :          0 :                 tmp >>= root->fs_info->sb->s_blocksize_bits;
     838                 :          0 :                 tmp = min(tmp, (next_offset - file_key.offset) >>
     839                 :            :                                          root->fs_info->sb->s_blocksize_bits);
     840                 :            : 
     841                 :          0 :                 tmp = max((u64)1, tmp);
     842                 :          0 :                 tmp = min(tmp, (u64)MAX_CSUM_ITEMS(root, csum_size));
     843                 :          0 :                 ins_size = csum_size * tmp;
     844                 :            :         } else {
     845                 :          0 :                 ins_size = csum_size;
     846                 :            :         }
     847                 :          0 :         path->leave_spinning = 1;
     848                 :            :         ret = btrfs_insert_empty_item(trans, root, path, &file_key,
     849                 :            :                                       ins_size);
     850                 :          0 :         path->leave_spinning = 0;
     851         [ #  # ]:          0 :         if (ret < 0)
     852                 :            :                 goto fail_unlock;
     853 [ #  # ][ #  # ]:          0 :         if (WARN_ON(ret != 0))
     854                 :            :                 goto fail_unlock;
     855                 :          0 :         leaf = path->nodes[0];
     856                 :            : csum:
     857                 :          0 :         item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
     858                 :          0 :         item_end = (struct btrfs_csum_item *)((unsigned char *)item +
     859                 :            :                                       btrfs_item_size_nr(leaf, path->slots[0]));
     860                 :          0 :         item = (struct btrfs_csum_item *)((unsigned char *)item +
     861                 :            :                                           csum_offset * csum_size);
     862                 :            : found:
     863                 :          0 :         ins_size = (u32)(sums->len - total_bytes) >>
     864                 :          0 :                    root->fs_info->sb->s_blocksize_bits;
     865                 :          0 :         ins_size *= csum_size;
     866                 :          0 :         ins_size = min_t(u32, (unsigned long)item_end - (unsigned long)item,
     867                 :            :                               ins_size);
     868                 :          0 :         write_extent_buffer(leaf, sums->sums + index, (unsigned long)item,
     869                 :            :                             ins_size);
     870                 :            : 
     871                 :          0 :         ins_size /= csum_size;
     872                 :          0 :         total_bytes += ins_size * root->sectorsize;
     873                 :          0 :         index += ins_size;
     874                 :            : 
     875                 :          0 :         btrfs_mark_buffer_dirty(path->nodes[0]);
     876         [ #  # ]:          0 :         if (total_bytes < sums->len) {
     877                 :          0 :                 btrfs_release_path(path);
     878                 :          0 :                 cond_resched();
     879                 :          0 :                 goto again;
     880                 :            :         }
     881                 :            : out:
     882                 :          0 :         btrfs_free_path(path);
     883                 :          0 :         return ret;
     884                 :            : 
     885                 :            : fail_unlock:
     886                 :            :         goto out;
     887                 :            : }

Generated by: LCOV version 1.9