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