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