diff options
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r-- | fs/btrfs/tree-log.c | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index c599e8c2a53..a794b9f6013 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -519,7 +519,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
519 | * file. This must be done before the btrfs_drop_extents run | 519 | * file. This must be done before the btrfs_drop_extents run |
520 | * so we don't try to drop this extent. | 520 | * so we don't try to drop this extent. |
521 | */ | 521 | */ |
522 | ret = btrfs_lookup_file_extent(trans, root, path, inode->i_ino, | 522 | ret = btrfs_lookup_file_extent(trans, root, path, btrfs_ino(inode), |
523 | start, 0); | 523 | start, 0); |
524 | 524 | ||
525 | if (ret == 0 && | 525 | if (ret == 0 && |
@@ -832,7 +832,7 @@ again: | |||
832 | read_extent_buffer(eb, name, (unsigned long)(ref + 1), namelen); | 832 | read_extent_buffer(eb, name, (unsigned long)(ref + 1), namelen); |
833 | 833 | ||
834 | /* if we already have a perfect match, we're done */ | 834 | /* if we already have a perfect match, we're done */ |
835 | if (inode_in_dir(root, path, dir->i_ino, inode->i_ino, | 835 | if (inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode), |
836 | btrfs_inode_ref_index(eb, ref), | 836 | btrfs_inode_ref_index(eb, ref), |
837 | name, namelen)) { | 837 | name, namelen)) { |
838 | goto out; | 838 | goto out; |
@@ -960,8 +960,9 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans, | |||
960 | unsigned long ptr; | 960 | unsigned long ptr; |
961 | unsigned long ptr_end; | 961 | unsigned long ptr_end; |
962 | int name_len; | 962 | int name_len; |
963 | u64 ino = btrfs_ino(inode); | ||
963 | 964 | ||
964 | key.objectid = inode->i_ino; | 965 | key.objectid = ino; |
965 | key.type = BTRFS_INODE_REF_KEY; | 966 | key.type = BTRFS_INODE_REF_KEY; |
966 | key.offset = (u64)-1; | 967 | key.offset = (u64)-1; |
967 | 968 | ||
@@ -980,7 +981,7 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans, | |||
980 | } | 981 | } |
981 | btrfs_item_key_to_cpu(path->nodes[0], &key, | 982 | btrfs_item_key_to_cpu(path->nodes[0], &key, |
982 | path->slots[0]); | 983 | path->slots[0]); |
983 | if (key.objectid != inode->i_ino || | 984 | if (key.objectid != ino || |
984 | key.type != BTRFS_INODE_REF_KEY) | 985 | key.type != BTRFS_INODE_REF_KEY) |
985 | break; | 986 | break; |
986 | ptr = btrfs_item_ptr_offset(path->nodes[0], path->slots[0]); | 987 | ptr = btrfs_item_ptr_offset(path->nodes[0], path->slots[0]); |
@@ -1011,10 +1012,10 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans, | |||
1011 | if (inode->i_nlink == 0) { | 1012 | if (inode->i_nlink == 0) { |
1012 | if (S_ISDIR(inode->i_mode)) { | 1013 | if (S_ISDIR(inode->i_mode)) { |
1013 | ret = replay_dir_deletes(trans, root, NULL, path, | 1014 | ret = replay_dir_deletes(trans, root, NULL, path, |
1014 | inode->i_ino, 1); | 1015 | ino, 1); |
1015 | BUG_ON(ret); | 1016 | BUG_ON(ret); |
1016 | } | 1017 | } |
1017 | ret = insert_orphan_item(trans, root, inode->i_ino); | 1018 | ret = insert_orphan_item(trans, root, ino); |
1018 | BUG_ON(ret); | 1019 | BUG_ON(ret); |
1019 | } | 1020 | } |
1020 | btrfs_free_path(path); | 1021 | btrfs_free_path(path); |
@@ -2197,6 +2198,7 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, | |||
2197 | int ret; | 2198 | int ret; |
2198 | int err = 0; | 2199 | int err = 0; |
2199 | int bytes_del = 0; | 2200 | int bytes_del = 0; |
2201 | u64 dir_ino = btrfs_ino(dir); | ||
2200 | 2202 | ||
2201 | if (BTRFS_I(dir)->logged_trans < trans->transid) | 2203 | if (BTRFS_I(dir)->logged_trans < trans->transid) |
2202 | return 0; | 2204 | return 0; |
@@ -2214,7 +2216,7 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, | |||
2214 | goto out_unlock; | 2216 | goto out_unlock; |
2215 | } | 2217 | } |
2216 | 2218 | ||
2217 | di = btrfs_lookup_dir_item(trans, log, path, dir->i_ino, | 2219 | di = btrfs_lookup_dir_item(trans, log, path, dir_ino, |
2218 | name, name_len, -1); | 2220 | name, name_len, -1); |
2219 | if (IS_ERR(di)) { | 2221 | if (IS_ERR(di)) { |
2220 | err = PTR_ERR(di); | 2222 | err = PTR_ERR(di); |
@@ -2226,7 +2228,7 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, | |||
2226 | BUG_ON(ret); | 2228 | BUG_ON(ret); |
2227 | } | 2229 | } |
2228 | btrfs_release_path(path); | 2230 | btrfs_release_path(path); |
2229 | di = btrfs_lookup_dir_index_item(trans, log, path, dir->i_ino, | 2231 | di = btrfs_lookup_dir_index_item(trans, log, path, dir_ino, |
2230 | index, name, name_len, -1); | 2232 | index, name, name_len, -1); |
2231 | if (IS_ERR(di)) { | 2233 | if (IS_ERR(di)) { |
2232 | err = PTR_ERR(di); | 2234 | err = PTR_ERR(di); |
@@ -2244,7 +2246,7 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, | |||
2244 | if (bytes_del) { | 2246 | if (bytes_del) { |
2245 | struct btrfs_key key; | 2247 | struct btrfs_key key; |
2246 | 2248 | ||
2247 | key.objectid = dir->i_ino; | 2249 | key.objectid = dir_ino; |
2248 | key.offset = 0; | 2250 | key.offset = 0; |
2249 | key.type = BTRFS_INODE_ITEM_KEY; | 2251 | key.type = BTRFS_INODE_ITEM_KEY; |
2250 | btrfs_release_path(path); | 2252 | btrfs_release_path(path); |
@@ -2303,7 +2305,7 @@ int btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans, | |||
2303 | log = root->log_root; | 2305 | log = root->log_root; |
2304 | mutex_lock(&BTRFS_I(inode)->log_mutex); | 2306 | mutex_lock(&BTRFS_I(inode)->log_mutex); |
2305 | 2307 | ||
2306 | ret = btrfs_del_inode_ref(trans, log, name, name_len, inode->i_ino, | 2308 | ret = btrfs_del_inode_ref(trans, log, name, name_len, btrfs_ino(inode), |
2307 | dirid, &index); | 2309 | dirid, &index); |
2308 | mutex_unlock(&BTRFS_I(inode)->log_mutex); | 2310 | mutex_unlock(&BTRFS_I(inode)->log_mutex); |
2309 | if (ret == -ENOSPC) { | 2311 | if (ret == -ENOSPC) { |
@@ -2369,13 +2371,14 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2369 | int nritems; | 2371 | int nritems; |
2370 | u64 first_offset = min_offset; | 2372 | u64 first_offset = min_offset; |
2371 | u64 last_offset = (u64)-1; | 2373 | u64 last_offset = (u64)-1; |
2374 | u64 ino = btrfs_ino(inode); | ||
2372 | 2375 | ||
2373 | log = root->log_root; | 2376 | log = root->log_root; |
2374 | max_key.objectid = inode->i_ino; | 2377 | max_key.objectid = ino; |
2375 | max_key.offset = (u64)-1; | 2378 | max_key.offset = (u64)-1; |
2376 | max_key.type = key_type; | 2379 | max_key.type = key_type; |
2377 | 2380 | ||
2378 | min_key.objectid = inode->i_ino; | 2381 | min_key.objectid = ino; |
2379 | min_key.type = key_type; | 2382 | min_key.type = key_type; |
2380 | min_key.offset = min_offset; | 2383 | min_key.offset = min_offset; |
2381 | 2384 | ||
@@ -2388,9 +2391,8 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2388 | * we didn't find anything from this transaction, see if there | 2391 | * we didn't find anything from this transaction, see if there |
2389 | * is anything at all | 2392 | * is anything at all |
2390 | */ | 2393 | */ |
2391 | if (ret != 0 || min_key.objectid != inode->i_ino || | 2394 | if (ret != 0 || min_key.objectid != ino || min_key.type != key_type) { |
2392 | min_key.type != key_type) { | 2395 | min_key.objectid = ino; |
2393 | min_key.objectid = inode->i_ino; | ||
2394 | min_key.type = key_type; | 2396 | min_key.type = key_type; |
2395 | min_key.offset = (u64)-1; | 2397 | min_key.offset = (u64)-1; |
2396 | btrfs_release_path(path); | 2398 | btrfs_release_path(path); |
@@ -2399,7 +2401,7 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2399 | btrfs_release_path(path); | 2401 | btrfs_release_path(path); |
2400 | return ret; | 2402 | return ret; |
2401 | } | 2403 | } |
2402 | ret = btrfs_previous_item(root, path, inode->i_ino, key_type); | 2404 | ret = btrfs_previous_item(root, path, ino, key_type); |
2403 | 2405 | ||
2404 | /* if ret == 0 there are items for this type, | 2406 | /* if ret == 0 there are items for this type, |
2405 | * create a range to tell us the last key of this type. | 2407 | * create a range to tell us the last key of this type. |
@@ -2417,7 +2419,7 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2417 | } | 2419 | } |
2418 | 2420 | ||
2419 | /* go backward to find any previous key */ | 2421 | /* go backward to find any previous key */ |
2420 | ret = btrfs_previous_item(root, path, inode->i_ino, key_type); | 2422 | ret = btrfs_previous_item(root, path, ino, key_type); |
2421 | if (ret == 0) { | 2423 | if (ret == 0) { |
2422 | struct btrfs_key tmp; | 2424 | struct btrfs_key tmp; |
2423 | btrfs_item_key_to_cpu(path->nodes[0], &tmp, path->slots[0]); | 2425 | btrfs_item_key_to_cpu(path->nodes[0], &tmp, path->slots[0]); |
@@ -2452,8 +2454,7 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2452 | for (i = path->slots[0]; i < nritems; i++) { | 2454 | for (i = path->slots[0]; i < nritems; i++) { |
2453 | btrfs_item_key_to_cpu(src, &min_key, i); | 2455 | btrfs_item_key_to_cpu(src, &min_key, i); |
2454 | 2456 | ||
2455 | if (min_key.objectid != inode->i_ino || | 2457 | if (min_key.objectid != ino || min_key.type != key_type) |
2456 | min_key.type != key_type) | ||
2457 | goto done; | 2458 | goto done; |
2458 | ret = overwrite_item(trans, log, dst_path, src, i, | 2459 | ret = overwrite_item(trans, log, dst_path, src, i, |
2459 | &min_key); | 2460 | &min_key); |
@@ -2474,7 +2475,7 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2474 | goto done; | 2475 | goto done; |
2475 | } | 2476 | } |
2476 | btrfs_item_key_to_cpu(path->nodes[0], &tmp, path->slots[0]); | 2477 | btrfs_item_key_to_cpu(path->nodes[0], &tmp, path->slots[0]); |
2477 | if (tmp.objectid != inode->i_ino || tmp.type != key_type) { | 2478 | if (tmp.objectid != ino || tmp.type != key_type) { |
2478 | last_offset = (u64)-1; | 2479 | last_offset = (u64)-1; |
2479 | goto done; | 2480 | goto done; |
2480 | } | 2481 | } |
@@ -2500,8 +2501,7 @@ done: | |||
2500 | * is valid | 2501 | * is valid |
2501 | */ | 2502 | */ |
2502 | ret = insert_dir_log_key(trans, log, path, key_type, | 2503 | ret = insert_dir_log_key(trans, log, path, key_type, |
2503 | inode->i_ino, first_offset, | 2504 | ino, first_offset, last_offset); |
2504 | last_offset); | ||
2505 | if (ret) | 2505 | if (ret) |
2506 | err = ret; | 2506 | err = ret; |
2507 | } | 2507 | } |
@@ -2745,6 +2745,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
2745 | int nritems; | 2745 | int nritems; |
2746 | int ins_start_slot = 0; | 2746 | int ins_start_slot = 0; |
2747 | int ins_nr; | 2747 | int ins_nr; |
2748 | u64 ino = btrfs_ino(inode); | ||
2748 | 2749 | ||
2749 | log = root->log_root; | 2750 | log = root->log_root; |
2750 | 2751 | ||
@@ -2757,11 +2758,11 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
2757 | return -ENOMEM; | 2758 | return -ENOMEM; |
2758 | } | 2759 | } |
2759 | 2760 | ||
2760 | min_key.objectid = inode->i_ino; | 2761 | min_key.objectid = ino; |
2761 | min_key.type = BTRFS_INODE_ITEM_KEY; | 2762 | min_key.type = BTRFS_INODE_ITEM_KEY; |
2762 | min_key.offset = 0; | 2763 | min_key.offset = 0; |
2763 | 2764 | ||
2764 | max_key.objectid = inode->i_ino; | 2765 | max_key.objectid = ino; |
2765 | 2766 | ||
2766 | /* today the code can only do partial logging of directories */ | 2767 | /* today the code can only do partial logging of directories */ |
2767 | if (!S_ISDIR(inode->i_mode)) | 2768 | if (!S_ISDIR(inode->i_mode)) |
@@ -2773,6 +2774,13 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
2773 | max_key.type = (u8)-1; | 2774 | max_key.type = (u8)-1; |
2774 | max_key.offset = (u64)-1; | 2775 | max_key.offset = (u64)-1; |
2775 | 2776 | ||
2777 | ret = btrfs_commit_inode_delayed_items(trans, inode); | ||
2778 | if (ret) { | ||
2779 | btrfs_free_path(path); | ||
2780 | btrfs_free_path(dst_path); | ||
2781 | return ret; | ||
2782 | } | ||
2783 | |||
2776 | mutex_lock(&BTRFS_I(inode)->log_mutex); | 2784 | mutex_lock(&BTRFS_I(inode)->log_mutex); |
2777 | 2785 | ||
2778 | /* | 2786 | /* |
@@ -2784,8 +2792,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
2784 | 2792 | ||
2785 | if (inode_only == LOG_INODE_EXISTS) | 2793 | if (inode_only == LOG_INODE_EXISTS) |
2786 | max_key_type = BTRFS_XATTR_ITEM_KEY; | 2794 | max_key_type = BTRFS_XATTR_ITEM_KEY; |
2787 | ret = drop_objectid_items(trans, log, path, | 2795 | ret = drop_objectid_items(trans, log, path, ino, max_key_type); |
2788 | inode->i_ino, max_key_type); | ||
2789 | } else { | 2796 | } else { |
2790 | ret = btrfs_truncate_inode_items(trans, log, inode, 0, 0); | 2797 | ret = btrfs_truncate_inode_items(trans, log, inode, 0, 0); |
2791 | } | 2798 | } |
@@ -2803,7 +2810,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
2803 | break; | 2810 | break; |
2804 | again: | 2811 | again: |
2805 | /* note, ins_nr might be > 0 here, cleanup outside the loop */ | 2812 | /* note, ins_nr might be > 0 here, cleanup outside the loop */ |
2806 | if (min_key.objectid != inode->i_ino) | 2813 | if (min_key.objectid != ino) |
2807 | break; | 2814 | break; |
2808 | if (min_key.type > max_key.type) | 2815 | if (min_key.type > max_key.type) |
2809 | break; | 2816 | break; |