diff options
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r-- | fs/btrfs/tree-log.c | 208 |
1 files changed, 118 insertions, 90 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index f997ec0c1ba4..592396c6dc47 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -333,13 +333,13 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans, | |||
333 | goto insert; | 333 | goto insert; |
334 | 334 | ||
335 | if (item_size == 0) { | 335 | if (item_size == 0) { |
336 | btrfs_release_path(root, path); | 336 | btrfs_release_path(path); |
337 | return 0; | 337 | return 0; |
338 | } | 338 | } |
339 | dst_copy = kmalloc(item_size, GFP_NOFS); | 339 | dst_copy = kmalloc(item_size, GFP_NOFS); |
340 | src_copy = kmalloc(item_size, GFP_NOFS); | 340 | src_copy = kmalloc(item_size, GFP_NOFS); |
341 | if (!dst_copy || !src_copy) { | 341 | if (!dst_copy || !src_copy) { |
342 | btrfs_release_path(root, path); | 342 | btrfs_release_path(path); |
343 | kfree(dst_copy); | 343 | kfree(dst_copy); |
344 | kfree(src_copy); | 344 | kfree(src_copy); |
345 | return -ENOMEM; | 345 | return -ENOMEM; |
@@ -361,13 +361,13 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans, | |||
361 | * sync | 361 | * sync |
362 | */ | 362 | */ |
363 | if (ret == 0) { | 363 | if (ret == 0) { |
364 | btrfs_release_path(root, path); | 364 | btrfs_release_path(path); |
365 | return 0; | 365 | return 0; |
366 | } | 366 | } |
367 | 367 | ||
368 | } | 368 | } |
369 | insert: | 369 | insert: |
370 | btrfs_release_path(root, path); | 370 | btrfs_release_path(path); |
371 | /* try to insert the key into the destination tree */ | 371 | /* try to insert the key into the destination tree */ |
372 | ret = btrfs_insert_empty_item(trans, root, path, | 372 | ret = btrfs_insert_empty_item(trans, root, path, |
373 | key, item_size); | 373 | key, item_size); |
@@ -382,7 +382,6 @@ insert: | |||
382 | } else if (found_size < item_size) { | 382 | } else if (found_size < item_size) { |
383 | ret = btrfs_extend_item(trans, root, path, | 383 | ret = btrfs_extend_item(trans, root, path, |
384 | item_size - found_size); | 384 | item_size - found_size); |
385 | BUG_ON(ret); | ||
386 | } | 385 | } |
387 | } else if (ret) { | 386 | } else if (ret) { |
388 | return ret; | 387 | return ret; |
@@ -438,7 +437,7 @@ insert: | |||
438 | } | 437 | } |
439 | no_copy: | 438 | no_copy: |
440 | btrfs_mark_buffer_dirty(path->nodes[0]); | 439 | btrfs_mark_buffer_dirty(path->nodes[0]); |
441 | btrfs_release_path(root, path); | 440 | btrfs_release_path(path); |
442 | return 0; | 441 | return 0; |
443 | } | 442 | } |
444 | 443 | ||
@@ -519,7 +518,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
519 | * file. This must be done before the btrfs_drop_extents run | 518 | * file. This must be done before the btrfs_drop_extents run |
520 | * so we don't try to drop this extent. | 519 | * so we don't try to drop this extent. |
521 | */ | 520 | */ |
522 | ret = btrfs_lookup_file_extent(trans, root, path, inode->i_ino, | 521 | ret = btrfs_lookup_file_extent(trans, root, path, btrfs_ino(inode), |
523 | start, 0); | 522 | start, 0); |
524 | 523 | ||
525 | if (ret == 0 && | 524 | if (ret == 0 && |
@@ -544,11 +543,11 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
544 | * we don't have to do anything | 543 | * we don't have to do anything |
545 | */ | 544 | */ |
546 | if (memcmp(&cmp1, &cmp2, sizeof(cmp1)) == 0) { | 545 | if (memcmp(&cmp1, &cmp2, sizeof(cmp1)) == 0) { |
547 | btrfs_release_path(root, path); | 546 | btrfs_release_path(path); |
548 | goto out; | 547 | goto out; |
549 | } | 548 | } |
550 | } | 549 | } |
551 | btrfs_release_path(root, path); | 550 | btrfs_release_path(path); |
552 | 551 | ||
553 | saved_nbytes = inode_get_bytes(inode); | 552 | saved_nbytes = inode_get_bytes(inode); |
554 | /* drop any overlapping extents */ | 553 | /* drop any overlapping extents */ |
@@ -590,6 +589,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
590 | ins.objectid, ins.offset, | 589 | ins.objectid, ins.offset, |
591 | 0, root->root_key.objectid, | 590 | 0, root->root_key.objectid, |
592 | key->objectid, offset); | 591 | key->objectid, offset); |
592 | BUG_ON(ret); | ||
593 | } else { | 593 | } else { |
594 | /* | 594 | /* |
595 | * insert the extent pointer in the extent | 595 | * insert the extent pointer in the extent |
@@ -600,7 +600,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
600 | key->objectid, offset, &ins); | 600 | key->objectid, offset, &ins); |
601 | BUG_ON(ret); | 601 | BUG_ON(ret); |
602 | } | 602 | } |
603 | btrfs_release_path(root, path); | 603 | btrfs_release_path(path); |
604 | 604 | ||
605 | if (btrfs_file_extent_compression(eb, item)) { | 605 | if (btrfs_file_extent_compression(eb, item)) { |
606 | csum_start = ins.objectid; | 606 | csum_start = ins.objectid; |
@@ -614,7 +614,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
614 | 614 | ||
615 | ret = btrfs_lookup_csums_range(root->log_root, | 615 | ret = btrfs_lookup_csums_range(root->log_root, |
616 | csum_start, csum_end - 1, | 616 | csum_start, csum_end - 1, |
617 | &ordered_sums); | 617 | &ordered_sums, 0); |
618 | BUG_ON(ret); | 618 | BUG_ON(ret); |
619 | while (!list_empty(&ordered_sums)) { | 619 | while (!list_empty(&ordered_sums)) { |
620 | struct btrfs_ordered_sum *sums; | 620 | struct btrfs_ordered_sum *sums; |
@@ -629,7 +629,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
629 | kfree(sums); | 629 | kfree(sums); |
630 | } | 630 | } |
631 | } else { | 631 | } else { |
632 | btrfs_release_path(root, path); | 632 | btrfs_release_path(path); |
633 | } | 633 | } |
634 | } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { | 634 | } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { |
635 | /* inline extents are easy, we just overwrite them */ | 635 | /* inline extents are easy, we just overwrite them */ |
@@ -675,10 +675,13 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans, | |||
675 | return -ENOMEM; | 675 | return -ENOMEM; |
676 | 676 | ||
677 | read_extent_buffer(leaf, name, (unsigned long)(di + 1), name_len); | 677 | read_extent_buffer(leaf, name, (unsigned long)(di + 1), name_len); |
678 | btrfs_release_path(root, path); | 678 | btrfs_release_path(path); |
679 | 679 | ||
680 | inode = read_one_inode(root, location.objectid); | 680 | inode = read_one_inode(root, location.objectid); |
681 | BUG_ON(!inode); | 681 | if (!inode) { |
682 | kfree(name); | ||
683 | return -EIO; | ||
684 | } | ||
682 | 685 | ||
683 | ret = link_to_fixup_dir(trans, root, path, location.objectid); | 686 | ret = link_to_fixup_dir(trans, root, path, location.objectid); |
684 | BUG_ON(ret); | 687 | BUG_ON(ret); |
@@ -713,7 +716,7 @@ static noinline int inode_in_dir(struct btrfs_root *root, | |||
713 | goto out; | 716 | goto out; |
714 | } else | 717 | } else |
715 | goto out; | 718 | goto out; |
716 | btrfs_release_path(root, path); | 719 | btrfs_release_path(path); |
717 | 720 | ||
718 | di = btrfs_lookup_dir_item(NULL, root, path, dirid, name, name_len, 0); | 721 | di = btrfs_lookup_dir_item(NULL, root, path, dirid, name, name_len, 0); |
719 | if (di && !IS_ERR(di)) { | 722 | if (di && !IS_ERR(di)) { |
@@ -724,7 +727,7 @@ static noinline int inode_in_dir(struct btrfs_root *root, | |||
724 | goto out; | 727 | goto out; |
725 | match = 1; | 728 | match = 1; |
726 | out: | 729 | out: |
727 | btrfs_release_path(root, path); | 730 | btrfs_release_path(path); |
728 | return match; | 731 | return match; |
729 | } | 732 | } |
730 | 733 | ||
@@ -817,7 +820,10 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, | |||
817 | return -ENOENT; | 820 | return -ENOENT; |
818 | 821 | ||
819 | inode = read_one_inode(root, key->objectid); | 822 | inode = read_one_inode(root, key->objectid); |
820 | BUG_ON(!inode); | 823 | if (!inode) { |
824 | iput(dir); | ||
825 | return -EIO; | ||
826 | } | ||
821 | 827 | ||
822 | ref_ptr = btrfs_item_ptr_offset(eb, slot); | 828 | ref_ptr = btrfs_item_ptr_offset(eb, slot); |
823 | ref_end = ref_ptr + btrfs_item_size_nr(eb, slot); | 829 | ref_end = ref_ptr + btrfs_item_size_nr(eb, slot); |
@@ -832,7 +838,7 @@ again: | |||
832 | read_extent_buffer(eb, name, (unsigned long)(ref + 1), namelen); | 838 | read_extent_buffer(eb, name, (unsigned long)(ref + 1), namelen); |
833 | 839 | ||
834 | /* if we already have a perfect match, we're done */ | 840 | /* if we already have a perfect match, we're done */ |
835 | if (inode_in_dir(root, path, dir->i_ino, inode->i_ino, | 841 | if (inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode), |
836 | btrfs_inode_ref_index(eb, ref), | 842 | btrfs_inode_ref_index(eb, ref), |
837 | name, namelen)) { | 843 | name, namelen)) { |
838 | goto out; | 844 | goto out; |
@@ -884,7 +890,7 @@ again: | |||
884 | if (!backref_in_log(log, key, victim_name, | 890 | if (!backref_in_log(log, key, victim_name, |
885 | victim_name_len)) { | 891 | victim_name_len)) { |
886 | btrfs_inc_nlink(inode); | 892 | btrfs_inc_nlink(inode); |
887 | btrfs_release_path(root, path); | 893 | btrfs_release_path(path); |
888 | 894 | ||
889 | ret = btrfs_unlink_inode(trans, root, dir, | 895 | ret = btrfs_unlink_inode(trans, root, dir, |
890 | inode, victim_name, | 896 | inode, victim_name, |
@@ -901,7 +907,7 @@ again: | |||
901 | */ | 907 | */ |
902 | search_done = 1; | 908 | search_done = 1; |
903 | } | 909 | } |
904 | btrfs_release_path(root, path); | 910 | btrfs_release_path(path); |
905 | 911 | ||
906 | insert: | 912 | insert: |
907 | /* insert our name */ | 913 | /* insert our name */ |
@@ -922,7 +928,7 @@ out: | |||
922 | BUG_ON(ret); | 928 | BUG_ON(ret); |
923 | 929 | ||
924 | out_nowrite: | 930 | out_nowrite: |
925 | btrfs_release_path(root, path); | 931 | btrfs_release_path(path); |
926 | iput(dir); | 932 | iput(dir); |
927 | iput(inode); | 933 | iput(inode); |
928 | return 0; | 934 | return 0; |
@@ -960,8 +966,9 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans, | |||
960 | unsigned long ptr; | 966 | unsigned long ptr; |
961 | unsigned long ptr_end; | 967 | unsigned long ptr_end; |
962 | int name_len; | 968 | int name_len; |
969 | u64 ino = btrfs_ino(inode); | ||
963 | 970 | ||
964 | key.objectid = inode->i_ino; | 971 | key.objectid = ino; |
965 | key.type = BTRFS_INODE_REF_KEY; | 972 | key.type = BTRFS_INODE_REF_KEY; |
966 | key.offset = (u64)-1; | 973 | key.offset = (u64)-1; |
967 | 974 | ||
@@ -980,7 +987,7 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans, | |||
980 | } | 987 | } |
981 | btrfs_item_key_to_cpu(path->nodes[0], &key, | 988 | btrfs_item_key_to_cpu(path->nodes[0], &key, |
982 | path->slots[0]); | 989 | path->slots[0]); |
983 | if (key.objectid != inode->i_ino || | 990 | if (key.objectid != ino || |
984 | key.type != BTRFS_INODE_REF_KEY) | 991 | key.type != BTRFS_INODE_REF_KEY) |
985 | break; | 992 | break; |
986 | ptr = btrfs_item_ptr_offset(path->nodes[0], path->slots[0]); | 993 | ptr = btrfs_item_ptr_offset(path->nodes[0], path->slots[0]); |
@@ -999,9 +1006,9 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans, | |||
999 | if (key.offset == 0) | 1006 | if (key.offset == 0) |
1000 | break; | 1007 | break; |
1001 | key.offset--; | 1008 | key.offset--; |
1002 | btrfs_release_path(root, path); | 1009 | btrfs_release_path(path); |
1003 | } | 1010 | } |
1004 | btrfs_release_path(root, path); | 1011 | btrfs_release_path(path); |
1005 | if (nlink != inode->i_nlink) { | 1012 | if (nlink != inode->i_nlink) { |
1006 | inode->i_nlink = nlink; | 1013 | inode->i_nlink = nlink; |
1007 | btrfs_update_inode(trans, root, inode); | 1014 | btrfs_update_inode(trans, root, inode); |
@@ -1011,10 +1018,10 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans, | |||
1011 | if (inode->i_nlink == 0) { | 1018 | if (inode->i_nlink == 0) { |
1012 | if (S_ISDIR(inode->i_mode)) { | 1019 | if (S_ISDIR(inode->i_mode)) { |
1013 | ret = replay_dir_deletes(trans, root, NULL, path, | 1020 | ret = replay_dir_deletes(trans, root, NULL, path, |
1014 | inode->i_ino, 1); | 1021 | ino, 1); |
1015 | BUG_ON(ret); | 1022 | BUG_ON(ret); |
1016 | } | 1023 | } |
1017 | ret = insert_orphan_item(trans, root, inode->i_ino); | 1024 | ret = insert_orphan_item(trans, root, ino); |
1018 | BUG_ON(ret); | 1025 | BUG_ON(ret); |
1019 | } | 1026 | } |
1020 | btrfs_free_path(path); | 1027 | btrfs_free_path(path); |
@@ -1050,11 +1057,13 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, | |||
1050 | break; | 1057 | break; |
1051 | 1058 | ||
1052 | ret = btrfs_del_item(trans, root, path); | 1059 | ret = btrfs_del_item(trans, root, path); |
1053 | BUG_ON(ret); | 1060 | if (ret) |
1061 | goto out; | ||
1054 | 1062 | ||
1055 | btrfs_release_path(root, path); | 1063 | btrfs_release_path(path); |
1056 | inode = read_one_inode(root, key.offset); | 1064 | inode = read_one_inode(root, key.offset); |
1057 | BUG_ON(!inode); | 1065 | if (!inode) |
1066 | return -EIO; | ||
1058 | 1067 | ||
1059 | ret = fixup_inode_link_count(trans, root, inode); | 1068 | ret = fixup_inode_link_count(trans, root, inode); |
1060 | BUG_ON(ret); | 1069 | BUG_ON(ret); |
@@ -1068,8 +1077,10 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, | |||
1068 | */ | 1077 | */ |
1069 | key.offset = (u64)-1; | 1078 | key.offset = (u64)-1; |
1070 | } | 1079 | } |
1071 | btrfs_release_path(root, path); | 1080 | ret = 0; |
1072 | return 0; | 1081 | out: |
1082 | btrfs_release_path(path); | ||
1083 | return ret; | ||
1073 | } | 1084 | } |
1074 | 1085 | ||
1075 | 1086 | ||
@@ -1088,7 +1099,8 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans, | |||
1088 | struct inode *inode; | 1099 | struct inode *inode; |
1089 | 1100 | ||
1090 | inode = read_one_inode(root, objectid); | 1101 | inode = read_one_inode(root, objectid); |
1091 | BUG_ON(!inode); | 1102 | if (!inode) |
1103 | return -EIO; | ||
1092 | 1104 | ||
1093 | key.objectid = BTRFS_TREE_LOG_FIXUP_OBJECTID; | 1105 | key.objectid = BTRFS_TREE_LOG_FIXUP_OBJECTID; |
1094 | btrfs_set_key_type(&key, BTRFS_ORPHAN_ITEM_KEY); | 1106 | btrfs_set_key_type(&key, BTRFS_ORPHAN_ITEM_KEY); |
@@ -1096,7 +1108,7 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans, | |||
1096 | 1108 | ||
1097 | ret = btrfs_insert_empty_item(trans, root, path, &key, 0); | 1109 | ret = btrfs_insert_empty_item(trans, root, path, &key, 0); |
1098 | 1110 | ||
1099 | btrfs_release_path(root, path); | 1111 | btrfs_release_path(path); |
1100 | if (ret == 0) { | 1112 | if (ret == 0) { |
1101 | btrfs_inc_nlink(inode); | 1113 | btrfs_inc_nlink(inode); |
1102 | btrfs_update_inode(trans, root, inode); | 1114 | btrfs_update_inode(trans, root, inode); |
@@ -1175,7 +1187,8 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, | |||
1175 | int ret; | 1187 | int ret; |
1176 | 1188 | ||
1177 | dir = read_one_inode(root, key->objectid); | 1189 | dir = read_one_inode(root, key->objectid); |
1178 | BUG_ON(!dir); | 1190 | if (!dir) |
1191 | return -EIO; | ||
1179 | 1192 | ||
1180 | name_len = btrfs_dir_name_len(eb, di); | 1193 | name_len = btrfs_dir_name_len(eb, di); |
1181 | name = kmalloc(name_len, GFP_NOFS); | 1194 | name = kmalloc(name_len, GFP_NOFS); |
@@ -1192,7 +1205,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, | |||
1192 | exists = 1; | 1205 | exists = 1; |
1193 | else | 1206 | else |
1194 | exists = 0; | 1207 | exists = 0; |
1195 | btrfs_release_path(root, path); | 1208 | btrfs_release_path(path); |
1196 | 1209 | ||
1197 | if (key->type == BTRFS_DIR_ITEM_KEY) { | 1210 | if (key->type == BTRFS_DIR_ITEM_KEY) { |
1198 | dst_di = btrfs_lookup_dir_item(trans, root, path, key->objectid, | 1211 | dst_di = btrfs_lookup_dir_item(trans, root, path, key->objectid, |
@@ -1205,7 +1218,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, | |||
1205 | } else { | 1218 | } else { |
1206 | BUG(); | 1219 | BUG(); |
1207 | } | 1220 | } |
1208 | if (!dst_di || IS_ERR(dst_di)) { | 1221 | if (IS_ERR_OR_NULL(dst_di)) { |
1209 | /* we need a sequence number to insert, so we only | 1222 | /* we need a sequence number to insert, so we only |
1210 | * do inserts for the BTRFS_DIR_INDEX_KEY types | 1223 | * do inserts for the BTRFS_DIR_INDEX_KEY types |
1211 | */ | 1224 | */ |
@@ -1236,13 +1249,13 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, | |||
1236 | if (key->type == BTRFS_DIR_INDEX_KEY) | 1249 | if (key->type == BTRFS_DIR_INDEX_KEY) |
1237 | goto insert; | 1250 | goto insert; |
1238 | out: | 1251 | out: |
1239 | btrfs_release_path(root, path); | 1252 | btrfs_release_path(path); |
1240 | kfree(name); | 1253 | kfree(name); |
1241 | iput(dir); | 1254 | iput(dir); |
1242 | return 0; | 1255 | return 0; |
1243 | 1256 | ||
1244 | insert: | 1257 | insert: |
1245 | btrfs_release_path(root, path); | 1258 | btrfs_release_path(path); |
1246 | ret = insert_one_name(trans, root, path, key->objectid, key->offset, | 1259 | ret = insert_one_name(trans, root, path, key->objectid, key->offset, |
1247 | name, name_len, log_type, &log_key); | 1260 | name, name_len, log_type, &log_key); |
1248 | 1261 | ||
@@ -1363,7 +1376,7 @@ next: | |||
1363 | *end_ret = found_end; | 1376 | *end_ret = found_end; |
1364 | ret = 0; | 1377 | ret = 0; |
1365 | out: | 1378 | out: |
1366 | btrfs_release_path(root, path); | 1379 | btrfs_release_path(path); |
1367 | return ret; | 1380 | return ret; |
1368 | } | 1381 | } |
1369 | 1382 | ||
@@ -1426,12 +1439,15 @@ again: | |||
1426 | dir_key->offset, | 1439 | dir_key->offset, |
1427 | name, name_len, 0); | 1440 | name, name_len, 0); |
1428 | } | 1441 | } |
1429 | if (!log_di || IS_ERR(log_di)) { | 1442 | if (IS_ERR_OR_NULL(log_di)) { |
1430 | btrfs_dir_item_key_to_cpu(eb, di, &location); | 1443 | btrfs_dir_item_key_to_cpu(eb, di, &location); |
1431 | btrfs_release_path(root, path); | 1444 | btrfs_release_path(path); |
1432 | btrfs_release_path(log, log_path); | 1445 | btrfs_release_path(log_path); |
1433 | inode = read_one_inode(root, location.objectid); | 1446 | inode = read_one_inode(root, location.objectid); |
1434 | BUG_ON(!inode); | 1447 | if (!inode) { |
1448 | kfree(name); | ||
1449 | return -EIO; | ||
1450 | } | ||
1435 | 1451 | ||
1436 | ret = link_to_fixup_dir(trans, root, | 1452 | ret = link_to_fixup_dir(trans, root, |
1437 | path, location.objectid); | 1453 | path, location.objectid); |
@@ -1453,7 +1469,7 @@ again: | |||
1453 | ret = 0; | 1469 | ret = 0; |
1454 | goto out; | 1470 | goto out; |
1455 | } | 1471 | } |
1456 | btrfs_release_path(log, log_path); | 1472 | btrfs_release_path(log_path); |
1457 | kfree(name); | 1473 | kfree(name); |
1458 | 1474 | ||
1459 | ptr = (unsigned long)(di + 1); | 1475 | ptr = (unsigned long)(di + 1); |
@@ -1461,8 +1477,8 @@ again: | |||
1461 | } | 1477 | } |
1462 | ret = 0; | 1478 | ret = 0; |
1463 | out: | 1479 | out: |
1464 | btrfs_release_path(root, path); | 1480 | btrfs_release_path(path); |
1465 | btrfs_release_path(log, log_path); | 1481 | btrfs_release_path(log_path); |
1466 | return ret; | 1482 | return ret; |
1467 | } | 1483 | } |
1468 | 1484 | ||
@@ -1550,7 +1566,7 @@ again: | |||
1550 | break; | 1566 | break; |
1551 | dir_key.offset = found_key.offset + 1; | 1567 | dir_key.offset = found_key.offset + 1; |
1552 | } | 1568 | } |
1553 | btrfs_release_path(root, path); | 1569 | btrfs_release_path(path); |
1554 | if (range_end == (u64)-1) | 1570 | if (range_end == (u64)-1) |
1555 | break; | 1571 | break; |
1556 | range_start = range_end + 1; | 1572 | range_start = range_end + 1; |
@@ -1561,11 +1577,11 @@ next_type: | |||
1561 | if (key_type == BTRFS_DIR_LOG_ITEM_KEY) { | 1577 | if (key_type == BTRFS_DIR_LOG_ITEM_KEY) { |
1562 | key_type = BTRFS_DIR_LOG_INDEX_KEY; | 1578 | key_type = BTRFS_DIR_LOG_INDEX_KEY; |
1563 | dir_key.type = BTRFS_DIR_INDEX_KEY; | 1579 | dir_key.type = BTRFS_DIR_INDEX_KEY; |
1564 | btrfs_release_path(root, path); | 1580 | btrfs_release_path(path); |
1565 | goto again; | 1581 | goto again; |
1566 | } | 1582 | } |
1567 | out: | 1583 | out: |
1568 | btrfs_release_path(root, path); | 1584 | btrfs_release_path(path); |
1569 | btrfs_free_path(log_path); | 1585 | btrfs_free_path(log_path); |
1570 | iput(dir); | 1586 | iput(dir); |
1571 | return ret; | 1587 | return ret; |
@@ -2093,7 +2109,9 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
2093 | * the running transaction open, so a full commit can't hop | 2109 | * the running transaction open, so a full commit can't hop |
2094 | * in and cause problems either. | 2110 | * in and cause problems either. |
2095 | */ | 2111 | */ |
2112 | btrfs_scrub_pause_super(root); | ||
2096 | write_ctree_super(trans, root->fs_info->tree_root, 1); | 2113 | write_ctree_super(trans, root->fs_info->tree_root, 1); |
2114 | btrfs_scrub_continue_super(root); | ||
2097 | ret = 0; | 2115 | ret = 0; |
2098 | 2116 | ||
2099 | mutex_lock(&root->log_mutex); | 2117 | mutex_lock(&root->log_mutex); |
@@ -2197,6 +2215,7 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, | |||
2197 | int ret; | 2215 | int ret; |
2198 | int err = 0; | 2216 | int err = 0; |
2199 | int bytes_del = 0; | 2217 | int bytes_del = 0; |
2218 | u64 dir_ino = btrfs_ino(dir); | ||
2200 | 2219 | ||
2201 | if (BTRFS_I(dir)->logged_trans < trans->transid) | 2220 | if (BTRFS_I(dir)->logged_trans < trans->transid) |
2202 | return 0; | 2221 | return 0; |
@@ -2214,7 +2233,7 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, | |||
2214 | goto out_unlock; | 2233 | goto out_unlock; |
2215 | } | 2234 | } |
2216 | 2235 | ||
2217 | di = btrfs_lookup_dir_item(trans, log, path, dir->i_ino, | 2236 | di = btrfs_lookup_dir_item(trans, log, path, dir_ino, |
2218 | name, name_len, -1); | 2237 | name, name_len, -1); |
2219 | if (IS_ERR(di)) { | 2238 | if (IS_ERR(di)) { |
2220 | err = PTR_ERR(di); | 2239 | err = PTR_ERR(di); |
@@ -2225,8 +2244,8 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, | |||
2225 | bytes_del += name_len; | 2244 | bytes_del += name_len; |
2226 | BUG_ON(ret); | 2245 | BUG_ON(ret); |
2227 | } | 2246 | } |
2228 | btrfs_release_path(log, path); | 2247 | btrfs_release_path(path); |
2229 | di = btrfs_lookup_dir_index_item(trans, log, path, dir->i_ino, | 2248 | di = btrfs_lookup_dir_index_item(trans, log, path, dir_ino, |
2230 | index, name, name_len, -1); | 2249 | index, name, name_len, -1); |
2231 | if (IS_ERR(di)) { | 2250 | if (IS_ERR(di)) { |
2232 | err = PTR_ERR(di); | 2251 | err = PTR_ERR(di); |
@@ -2244,10 +2263,10 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, | |||
2244 | if (bytes_del) { | 2263 | if (bytes_del) { |
2245 | struct btrfs_key key; | 2264 | struct btrfs_key key; |
2246 | 2265 | ||
2247 | key.objectid = dir->i_ino; | 2266 | key.objectid = dir_ino; |
2248 | key.offset = 0; | 2267 | key.offset = 0; |
2249 | key.type = BTRFS_INODE_ITEM_KEY; | 2268 | key.type = BTRFS_INODE_ITEM_KEY; |
2250 | btrfs_release_path(log, path); | 2269 | btrfs_release_path(path); |
2251 | 2270 | ||
2252 | ret = btrfs_search_slot(trans, log, &key, path, 0, 1); | 2271 | ret = btrfs_search_slot(trans, log, &key, path, 0, 1); |
2253 | if (ret < 0) { | 2272 | if (ret < 0) { |
@@ -2269,7 +2288,7 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, | |||
2269 | btrfs_mark_buffer_dirty(path->nodes[0]); | 2288 | btrfs_mark_buffer_dirty(path->nodes[0]); |
2270 | } else | 2289 | } else |
2271 | ret = 0; | 2290 | ret = 0; |
2272 | btrfs_release_path(log, path); | 2291 | btrfs_release_path(path); |
2273 | } | 2292 | } |
2274 | fail: | 2293 | fail: |
2275 | btrfs_free_path(path); | 2294 | btrfs_free_path(path); |
@@ -2303,7 +2322,7 @@ int btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans, | |||
2303 | log = root->log_root; | 2322 | log = root->log_root; |
2304 | mutex_lock(&BTRFS_I(inode)->log_mutex); | 2323 | mutex_lock(&BTRFS_I(inode)->log_mutex); |
2305 | 2324 | ||
2306 | ret = btrfs_del_inode_ref(trans, log, name, name_len, inode->i_ino, | 2325 | ret = btrfs_del_inode_ref(trans, log, name, name_len, btrfs_ino(inode), |
2307 | dirid, &index); | 2326 | dirid, &index); |
2308 | mutex_unlock(&BTRFS_I(inode)->log_mutex); | 2327 | mutex_unlock(&BTRFS_I(inode)->log_mutex); |
2309 | if (ret == -ENOSPC) { | 2328 | if (ret == -ENOSPC) { |
@@ -2344,7 +2363,7 @@ static noinline int insert_dir_log_key(struct btrfs_trans_handle *trans, | |||
2344 | struct btrfs_dir_log_item); | 2363 | struct btrfs_dir_log_item); |
2345 | btrfs_set_dir_log_end(path->nodes[0], item, last_offset); | 2364 | btrfs_set_dir_log_end(path->nodes[0], item, last_offset); |
2346 | btrfs_mark_buffer_dirty(path->nodes[0]); | 2365 | btrfs_mark_buffer_dirty(path->nodes[0]); |
2347 | btrfs_release_path(log, path); | 2366 | btrfs_release_path(path); |
2348 | return 0; | 2367 | return 0; |
2349 | } | 2368 | } |
2350 | 2369 | ||
@@ -2369,13 +2388,14 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2369 | int nritems; | 2388 | int nritems; |
2370 | u64 first_offset = min_offset; | 2389 | u64 first_offset = min_offset; |
2371 | u64 last_offset = (u64)-1; | 2390 | u64 last_offset = (u64)-1; |
2391 | u64 ino = btrfs_ino(inode); | ||
2372 | 2392 | ||
2373 | log = root->log_root; | 2393 | log = root->log_root; |
2374 | max_key.objectid = inode->i_ino; | 2394 | max_key.objectid = ino; |
2375 | max_key.offset = (u64)-1; | 2395 | max_key.offset = (u64)-1; |
2376 | max_key.type = key_type; | 2396 | max_key.type = key_type; |
2377 | 2397 | ||
2378 | min_key.objectid = inode->i_ino; | 2398 | min_key.objectid = ino; |
2379 | min_key.type = key_type; | 2399 | min_key.type = key_type; |
2380 | min_key.offset = min_offset; | 2400 | min_key.offset = min_offset; |
2381 | 2401 | ||
@@ -2388,18 +2408,17 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2388 | * we didn't find anything from this transaction, see if there | 2408 | * we didn't find anything from this transaction, see if there |
2389 | * is anything at all | 2409 | * is anything at all |
2390 | */ | 2410 | */ |
2391 | if (ret != 0 || min_key.objectid != inode->i_ino || | 2411 | if (ret != 0 || min_key.objectid != ino || min_key.type != key_type) { |
2392 | min_key.type != key_type) { | 2412 | min_key.objectid = ino; |
2393 | min_key.objectid = inode->i_ino; | ||
2394 | min_key.type = key_type; | 2413 | min_key.type = key_type; |
2395 | min_key.offset = (u64)-1; | 2414 | min_key.offset = (u64)-1; |
2396 | btrfs_release_path(root, path); | 2415 | btrfs_release_path(path); |
2397 | ret = btrfs_search_slot(NULL, root, &min_key, path, 0, 0); | 2416 | ret = btrfs_search_slot(NULL, root, &min_key, path, 0, 0); |
2398 | if (ret < 0) { | 2417 | if (ret < 0) { |
2399 | btrfs_release_path(root, path); | 2418 | btrfs_release_path(path); |
2400 | return ret; | 2419 | return ret; |
2401 | } | 2420 | } |
2402 | ret = btrfs_previous_item(root, path, inode->i_ino, key_type); | 2421 | ret = btrfs_previous_item(root, path, ino, key_type); |
2403 | 2422 | ||
2404 | /* if ret == 0 there are items for this type, | 2423 | /* if ret == 0 there are items for this type, |
2405 | * create a range to tell us the last key of this type. | 2424 | * create a range to tell us the last key of this type. |
@@ -2417,7 +2436,7 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2417 | } | 2436 | } |
2418 | 2437 | ||
2419 | /* go backward to find any previous key */ | 2438 | /* go backward to find any previous key */ |
2420 | ret = btrfs_previous_item(root, path, inode->i_ino, key_type); | 2439 | ret = btrfs_previous_item(root, path, ino, key_type); |
2421 | if (ret == 0) { | 2440 | if (ret == 0) { |
2422 | struct btrfs_key tmp; | 2441 | struct btrfs_key tmp; |
2423 | btrfs_item_key_to_cpu(path->nodes[0], &tmp, path->slots[0]); | 2442 | btrfs_item_key_to_cpu(path->nodes[0], &tmp, path->slots[0]); |
@@ -2432,7 +2451,7 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2432 | } | 2451 | } |
2433 | } | 2452 | } |
2434 | } | 2453 | } |
2435 | btrfs_release_path(root, path); | 2454 | btrfs_release_path(path); |
2436 | 2455 | ||
2437 | /* find the first key from this transaction again */ | 2456 | /* find the first key from this transaction again */ |
2438 | ret = btrfs_search_slot(NULL, root, &min_key, path, 0, 0); | 2457 | ret = btrfs_search_slot(NULL, root, &min_key, path, 0, 0); |
@@ -2452,8 +2471,7 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2452 | for (i = path->slots[0]; i < nritems; i++) { | 2471 | for (i = path->slots[0]; i < nritems; i++) { |
2453 | btrfs_item_key_to_cpu(src, &min_key, i); | 2472 | btrfs_item_key_to_cpu(src, &min_key, i); |
2454 | 2473 | ||
2455 | if (min_key.objectid != inode->i_ino || | 2474 | if (min_key.objectid != ino || min_key.type != key_type) |
2456 | min_key.type != key_type) | ||
2457 | goto done; | 2475 | goto done; |
2458 | ret = overwrite_item(trans, log, dst_path, src, i, | 2476 | ret = overwrite_item(trans, log, dst_path, src, i, |
2459 | &min_key); | 2477 | &min_key); |
@@ -2474,7 +2492,7 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2474 | goto done; | 2492 | goto done; |
2475 | } | 2493 | } |
2476 | btrfs_item_key_to_cpu(path->nodes[0], &tmp, path->slots[0]); | 2494 | btrfs_item_key_to_cpu(path->nodes[0], &tmp, path->slots[0]); |
2477 | if (tmp.objectid != inode->i_ino || tmp.type != key_type) { | 2495 | if (tmp.objectid != ino || tmp.type != key_type) { |
2478 | last_offset = (u64)-1; | 2496 | last_offset = (u64)-1; |
2479 | goto done; | 2497 | goto done; |
2480 | } | 2498 | } |
@@ -2490,8 +2508,8 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2490 | } | 2508 | } |
2491 | } | 2509 | } |
2492 | done: | 2510 | done: |
2493 | btrfs_release_path(root, path); | 2511 | btrfs_release_path(path); |
2494 | btrfs_release_path(log, dst_path); | 2512 | btrfs_release_path(dst_path); |
2495 | 2513 | ||
2496 | if (err == 0) { | 2514 | if (err == 0) { |
2497 | *last_offset_ret = last_offset; | 2515 | *last_offset_ret = last_offset; |
@@ -2500,8 +2518,7 @@ done: | |||
2500 | * is valid | 2518 | * is valid |
2501 | */ | 2519 | */ |
2502 | ret = insert_dir_log_key(trans, log, path, key_type, | 2520 | ret = insert_dir_log_key(trans, log, path, key_type, |
2503 | inode->i_ino, first_offset, | 2521 | ino, first_offset, last_offset); |
2504 | last_offset); | ||
2505 | if (ret) | 2522 | if (ret) |
2506 | err = ret; | 2523 | err = ret; |
2507 | } | 2524 | } |
@@ -2587,10 +2604,11 @@ static int drop_objectid_items(struct btrfs_trans_handle *trans, | |||
2587 | break; | 2604 | break; |
2588 | 2605 | ||
2589 | ret = btrfs_del_item(trans, log, path); | 2606 | ret = btrfs_del_item(trans, log, path); |
2590 | BUG_ON(ret); | 2607 | if (ret) |
2591 | btrfs_release_path(log, path); | 2608 | break; |
2609 | btrfs_release_path(path); | ||
2592 | } | 2610 | } |
2593 | btrfs_release_path(log, path); | 2611 | btrfs_release_path(path); |
2594 | return ret; | 2612 | return ret; |
2595 | } | 2613 | } |
2596 | 2614 | ||
@@ -2665,6 +2683,9 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, | |||
2665 | extent = btrfs_item_ptr(src, start_slot + i, | 2683 | extent = btrfs_item_ptr(src, start_slot + i, |
2666 | struct btrfs_file_extent_item); | 2684 | struct btrfs_file_extent_item); |
2667 | 2685 | ||
2686 | if (btrfs_file_extent_generation(src, extent) < trans->transid) | ||
2687 | continue; | ||
2688 | |||
2668 | found_type = btrfs_file_extent_type(src, extent); | 2689 | found_type = btrfs_file_extent_type(src, extent); |
2669 | if (found_type == BTRFS_FILE_EXTENT_REG || | 2690 | if (found_type == BTRFS_FILE_EXTENT_REG || |
2670 | found_type == BTRFS_FILE_EXTENT_PREALLOC) { | 2691 | found_type == BTRFS_FILE_EXTENT_PREALLOC) { |
@@ -2689,14 +2710,14 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, | |||
2689 | ret = btrfs_lookup_csums_range( | 2710 | ret = btrfs_lookup_csums_range( |
2690 | log->fs_info->csum_root, | 2711 | log->fs_info->csum_root, |
2691 | ds + cs, ds + cs + cl - 1, | 2712 | ds + cs, ds + cs + cl - 1, |
2692 | &ordered_sums); | 2713 | &ordered_sums, 0); |
2693 | BUG_ON(ret); | 2714 | BUG_ON(ret); |
2694 | } | 2715 | } |
2695 | } | 2716 | } |
2696 | } | 2717 | } |
2697 | 2718 | ||
2698 | btrfs_mark_buffer_dirty(dst_path->nodes[0]); | 2719 | btrfs_mark_buffer_dirty(dst_path->nodes[0]); |
2699 | btrfs_release_path(log, dst_path); | 2720 | btrfs_release_path(dst_path); |
2700 | kfree(ins_data); | 2721 | kfree(ins_data); |
2701 | 2722 | ||
2702 | /* | 2723 | /* |
@@ -2745,6 +2766,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
2745 | int nritems; | 2766 | int nritems; |
2746 | int ins_start_slot = 0; | 2767 | int ins_start_slot = 0; |
2747 | int ins_nr; | 2768 | int ins_nr; |
2769 | u64 ino = btrfs_ino(inode); | ||
2748 | 2770 | ||
2749 | log = root->log_root; | 2771 | log = root->log_root; |
2750 | 2772 | ||
@@ -2757,11 +2779,11 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
2757 | return -ENOMEM; | 2779 | return -ENOMEM; |
2758 | } | 2780 | } |
2759 | 2781 | ||
2760 | min_key.objectid = inode->i_ino; | 2782 | min_key.objectid = ino; |
2761 | min_key.type = BTRFS_INODE_ITEM_KEY; | 2783 | min_key.type = BTRFS_INODE_ITEM_KEY; |
2762 | min_key.offset = 0; | 2784 | min_key.offset = 0; |
2763 | 2785 | ||
2764 | max_key.objectid = inode->i_ino; | 2786 | max_key.objectid = ino; |
2765 | 2787 | ||
2766 | /* today the code can only do partial logging of directories */ | 2788 | /* today the code can only do partial logging of directories */ |
2767 | if (!S_ISDIR(inode->i_mode)) | 2789 | if (!S_ISDIR(inode->i_mode)) |
@@ -2773,6 +2795,13 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
2773 | max_key.type = (u8)-1; | 2795 | max_key.type = (u8)-1; |
2774 | max_key.offset = (u64)-1; | 2796 | max_key.offset = (u64)-1; |
2775 | 2797 | ||
2798 | ret = btrfs_commit_inode_delayed_items(trans, inode); | ||
2799 | if (ret) { | ||
2800 | btrfs_free_path(path); | ||
2801 | btrfs_free_path(dst_path); | ||
2802 | return ret; | ||
2803 | } | ||
2804 | |||
2776 | mutex_lock(&BTRFS_I(inode)->log_mutex); | 2805 | mutex_lock(&BTRFS_I(inode)->log_mutex); |
2777 | 2806 | ||
2778 | /* | 2807 | /* |
@@ -2784,8 +2813,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
2784 | 2813 | ||
2785 | if (inode_only == LOG_INODE_EXISTS) | 2814 | if (inode_only == LOG_INODE_EXISTS) |
2786 | max_key_type = BTRFS_XATTR_ITEM_KEY; | 2815 | max_key_type = BTRFS_XATTR_ITEM_KEY; |
2787 | ret = drop_objectid_items(trans, log, path, | 2816 | ret = drop_objectid_items(trans, log, path, ino, max_key_type); |
2788 | inode->i_ino, max_key_type); | ||
2789 | } else { | 2817 | } else { |
2790 | ret = btrfs_truncate_inode_items(trans, log, inode, 0, 0); | 2818 | ret = btrfs_truncate_inode_items(trans, log, inode, 0, 0); |
2791 | } | 2819 | } |
@@ -2803,7 +2831,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
2803 | break; | 2831 | break; |
2804 | again: | 2832 | again: |
2805 | /* note, ins_nr might be > 0 here, cleanup outside the loop */ | 2833 | /* note, ins_nr might be > 0 here, cleanup outside the loop */ |
2806 | if (min_key.objectid != inode->i_ino) | 2834 | if (min_key.objectid != ino) |
2807 | break; | 2835 | break; |
2808 | if (min_key.type > max_key.type) | 2836 | if (min_key.type > max_key.type) |
2809 | break; | 2837 | break; |
@@ -2845,7 +2873,7 @@ next_slot: | |||
2845 | } | 2873 | } |
2846 | ins_nr = 0; | 2874 | ins_nr = 0; |
2847 | } | 2875 | } |
2848 | btrfs_release_path(root, path); | 2876 | btrfs_release_path(path); |
2849 | 2877 | ||
2850 | if (min_key.offset < (u64)-1) | 2878 | if (min_key.offset < (u64)-1) |
2851 | min_key.offset++; | 2879 | min_key.offset++; |
@@ -2868,8 +2896,8 @@ next_slot: | |||
2868 | } | 2896 | } |
2869 | WARN_ON(ins_nr); | 2897 | WARN_ON(ins_nr); |
2870 | if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->i_mode)) { | 2898 | if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->i_mode)) { |
2871 | btrfs_release_path(root, path); | 2899 | btrfs_release_path(path); |
2872 | btrfs_release_path(log, dst_path); | 2900 | btrfs_release_path(dst_path); |
2873 | ret = log_directory_changes(trans, root, inode, path, dst_path); | 2901 | ret = log_directory_changes(trans, root, inode, path, dst_path); |
2874 | if (ret) { | 2902 | if (ret) { |
2875 | err = ret; | 2903 | err = ret; |
@@ -3136,7 +3164,7 @@ again: | |||
3136 | } | 3164 | } |
3137 | btrfs_item_key_to_cpu(path->nodes[0], &found_key, | 3165 | btrfs_item_key_to_cpu(path->nodes[0], &found_key, |
3138 | path->slots[0]); | 3166 | path->slots[0]); |
3139 | btrfs_release_path(log_root_tree, path); | 3167 | btrfs_release_path(path); |
3140 | if (found_key.objectid != BTRFS_TREE_LOG_OBJECTID) | 3168 | if (found_key.objectid != BTRFS_TREE_LOG_OBJECTID) |
3141 | break; | 3169 | break; |
3142 | 3170 | ||
@@ -3171,7 +3199,7 @@ again: | |||
3171 | if (found_key.offset == 0) | 3199 | if (found_key.offset == 0) |
3172 | break; | 3200 | break; |
3173 | } | 3201 | } |
3174 | btrfs_release_path(log_root_tree, path); | 3202 | btrfs_release_path(path); |
3175 | 3203 | ||
3176 | /* step one is to pin it all, step two is to replay just inodes */ | 3204 | /* step one is to pin it all, step two is to replay just inodes */ |
3177 | if (wc.pin) { | 3205 | if (wc.pin) { |