diff options
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r-- | fs/btrfs/tree-log.c | 89 |
1 files changed, 48 insertions, 41 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 741666a7676a..af57dd2b43d4 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -17,6 +17,7 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
20 | #include <linux/slab.h> | ||
20 | #include "ctree.h" | 21 | #include "ctree.h" |
21 | #include "transaction.h" | 22 | #include "transaction.h" |
22 | #include "disk-io.h" | 23 | #include "disk-io.h" |
@@ -445,7 +446,7 @@ static noinline struct inode *read_one_inode(struct btrfs_root *root, | |||
445 | key.objectid = objectid; | 446 | key.objectid = objectid; |
446 | key.type = BTRFS_INODE_ITEM_KEY; | 447 | key.type = BTRFS_INODE_ITEM_KEY; |
447 | key.offset = 0; | 448 | key.offset = 0; |
448 | inode = btrfs_iget(root->fs_info->sb, &key, root); | 449 | inode = btrfs_iget(root->fs_info->sb, &key, root, NULL); |
449 | if (IS_ERR(inode)) { | 450 | if (IS_ERR(inode)) { |
450 | inode = NULL; | 451 | inode = NULL; |
451 | } else if (is_bad_inode(inode)) { | 452 | } else if (is_bad_inode(inode)) { |
@@ -542,8 +543,8 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
542 | 543 | ||
543 | saved_nbytes = inode_get_bytes(inode); | 544 | saved_nbytes = inode_get_bytes(inode); |
544 | /* drop any overlapping extents */ | 545 | /* drop any overlapping extents */ |
545 | ret = btrfs_drop_extents(trans, root, inode, | 546 | ret = btrfs_drop_extents(trans, inode, start, extent_end, |
546 | start, extent_end, extent_end, start, &alloc_hint, 1); | 547 | &alloc_hint, 1); |
547 | BUG_ON(ret); | 548 | BUG_ON(ret); |
548 | 549 | ||
549 | if (found_type == BTRFS_FILE_EXTENT_REG || | 550 | if (found_type == BTRFS_FILE_EXTENT_REG || |
@@ -930,6 +931,17 @@ out_nowrite: | |||
930 | return 0; | 931 | return 0; |
931 | } | 932 | } |
932 | 933 | ||
934 | static int insert_orphan_item(struct btrfs_trans_handle *trans, | ||
935 | struct btrfs_root *root, u64 offset) | ||
936 | { | ||
937 | int ret; | ||
938 | ret = btrfs_find_orphan_item(root, offset); | ||
939 | if (ret > 0) | ||
940 | ret = btrfs_insert_orphan_item(trans, root, offset); | ||
941 | return ret; | ||
942 | } | ||
943 | |||
944 | |||
933 | /* | 945 | /* |
934 | * There are a few corners where the link count of the file can't | 946 | * There are a few corners where the link count of the file can't |
935 | * be properly maintained during replay. So, instead of adding | 947 | * be properly maintained during replay. So, instead of adding |
@@ -997,9 +1009,13 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans, | |||
997 | } | 1009 | } |
998 | BTRFS_I(inode)->index_cnt = (u64)-1; | 1010 | BTRFS_I(inode)->index_cnt = (u64)-1; |
999 | 1011 | ||
1000 | if (inode->i_nlink == 0 && S_ISDIR(inode->i_mode)) { | 1012 | if (inode->i_nlink == 0) { |
1001 | ret = replay_dir_deletes(trans, root, NULL, path, | 1013 | if (S_ISDIR(inode->i_mode)) { |
1002 | inode->i_ino, 1); | 1014 | ret = replay_dir_deletes(trans, root, NULL, path, |
1015 | inode->i_ino, 1); | ||
1016 | BUG_ON(ret); | ||
1017 | } | ||
1018 | ret = insert_orphan_item(trans, root, inode->i_ino); | ||
1003 | BUG_ON(ret); | 1019 | BUG_ON(ret); |
1004 | } | 1020 | } |
1005 | btrfs_free_path(path); | 1021 | btrfs_free_path(path); |
@@ -1587,7 +1603,6 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb, | |||
1587 | /* inode keys are done during the first stage */ | 1603 | /* inode keys are done during the first stage */ |
1588 | if (key.type == BTRFS_INODE_ITEM_KEY && | 1604 | if (key.type == BTRFS_INODE_ITEM_KEY && |
1589 | wc->stage == LOG_WALK_REPLAY_INODES) { | 1605 | wc->stage == LOG_WALK_REPLAY_INODES) { |
1590 | struct inode *inode; | ||
1591 | struct btrfs_inode_item *inode_item; | 1606 | struct btrfs_inode_item *inode_item; |
1592 | u32 mode; | 1607 | u32 mode; |
1593 | 1608 | ||
@@ -1603,31 +1618,16 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb, | |||
1603 | eb, i, &key); | 1618 | eb, i, &key); |
1604 | BUG_ON(ret); | 1619 | BUG_ON(ret); |
1605 | 1620 | ||
1606 | /* for regular files, truncate away | 1621 | /* for regular files, make sure corresponding |
1607 | * extents past the new EOF | 1622 | * orhpan item exist. extents past the new EOF |
1623 | * will be truncated later by orphan cleanup. | ||
1608 | */ | 1624 | */ |
1609 | if (S_ISREG(mode)) { | 1625 | if (S_ISREG(mode)) { |
1610 | inode = read_one_inode(root, | 1626 | ret = insert_orphan_item(wc->trans, root, |
1611 | key.objectid); | 1627 | key.objectid); |
1612 | BUG_ON(!inode); | ||
1613 | |||
1614 | ret = btrfs_truncate_inode_items(wc->trans, | ||
1615 | root, inode, inode->i_size, | ||
1616 | BTRFS_EXTENT_DATA_KEY); | ||
1617 | BUG_ON(ret); | 1628 | BUG_ON(ret); |
1618 | |||
1619 | /* if the nlink count is zero here, the iput | ||
1620 | * will free the inode. We bump it to make | ||
1621 | * sure it doesn't get freed until the link | ||
1622 | * count fixup is done | ||
1623 | */ | ||
1624 | if (inode->i_nlink == 0) { | ||
1625 | btrfs_inc_nlink(inode); | ||
1626 | btrfs_update_inode(wc->trans, | ||
1627 | root, inode); | ||
1628 | } | ||
1629 | iput(inode); | ||
1630 | } | 1629 | } |
1630 | |||
1631 | ret = link_to_fixup_dir(wc->trans, root, | 1631 | ret = link_to_fixup_dir(wc->trans, root, |
1632 | path, key.objectid); | 1632 | path, key.objectid); |
1633 | BUG_ON(ret); | 1633 | BUG_ON(ret); |
@@ -1977,10 +1977,11 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
1977 | { | 1977 | { |
1978 | int index1; | 1978 | int index1; |
1979 | int index2; | 1979 | int index2; |
1980 | int mark; | ||
1980 | int ret; | 1981 | int ret; |
1981 | struct btrfs_root *log = root->log_root; | 1982 | struct btrfs_root *log = root->log_root; |
1982 | struct btrfs_root *log_root_tree = root->fs_info->log_root_tree; | 1983 | struct btrfs_root *log_root_tree = root->fs_info->log_root_tree; |
1983 | u64 log_transid = 0; | 1984 | unsigned long log_transid = 0; |
1984 | 1985 | ||
1985 | mutex_lock(&root->log_mutex); | 1986 | mutex_lock(&root->log_mutex); |
1986 | index1 = root->log_transid % 2; | 1987 | index1 = root->log_transid % 2; |
@@ -2014,24 +2015,29 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
2014 | goto out; | 2015 | goto out; |
2015 | } | 2016 | } |
2016 | 2017 | ||
2018 | log_transid = root->log_transid; | ||
2019 | if (log_transid % 2 == 0) | ||
2020 | mark = EXTENT_DIRTY; | ||
2021 | else | ||
2022 | mark = EXTENT_NEW; | ||
2023 | |||
2017 | /* we start IO on all the marked extents here, but we don't actually | 2024 | /* we start IO on all the marked extents here, but we don't actually |
2018 | * wait for them until later. | 2025 | * wait for them until later. |
2019 | */ | 2026 | */ |
2020 | ret = btrfs_write_marked_extents(log, &log->dirty_log_pages); | 2027 | ret = btrfs_write_marked_extents(log, &log->dirty_log_pages, mark); |
2021 | BUG_ON(ret); | 2028 | BUG_ON(ret); |
2022 | 2029 | ||
2023 | btrfs_set_root_node(&log->root_item, log->node); | 2030 | btrfs_set_root_node(&log->root_item, log->node); |
2024 | 2031 | ||
2025 | root->log_batch = 0; | 2032 | root->log_batch = 0; |
2026 | log_transid = root->log_transid; | ||
2027 | root->log_transid++; | 2033 | root->log_transid++; |
2028 | log->log_transid = root->log_transid; | 2034 | log->log_transid = root->log_transid; |
2029 | root->log_start_pid = 0; | 2035 | root->log_start_pid = 0; |
2030 | smp_mb(); | 2036 | smp_mb(); |
2031 | /* | 2037 | /* |
2032 | * log tree has been flushed to disk, new modifications of | 2038 | * IO has been started, blocks of the log tree have WRITTEN flag set |
2033 | * the log will be written to new positions. so it's safe to | 2039 | * in their headers. new modifications of the log will be written to |
2034 | * allow log writers to go in. | 2040 | * new positions. so it's safe to allow log writers to go in. |
2035 | */ | 2041 | */ |
2036 | mutex_unlock(&root->log_mutex); | 2042 | mutex_unlock(&root->log_mutex); |
2037 | 2043 | ||
@@ -2052,7 +2058,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
2052 | 2058 | ||
2053 | index2 = log_root_tree->log_transid % 2; | 2059 | index2 = log_root_tree->log_transid % 2; |
2054 | if (atomic_read(&log_root_tree->log_commit[index2])) { | 2060 | if (atomic_read(&log_root_tree->log_commit[index2])) { |
2055 | btrfs_wait_marked_extents(log, &log->dirty_log_pages); | 2061 | btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); |
2056 | wait_log_commit(trans, log_root_tree, | 2062 | wait_log_commit(trans, log_root_tree, |
2057 | log_root_tree->log_transid); | 2063 | log_root_tree->log_transid); |
2058 | mutex_unlock(&log_root_tree->log_mutex); | 2064 | mutex_unlock(&log_root_tree->log_mutex); |
@@ -2072,16 +2078,17 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
2072 | * check the full commit flag again | 2078 | * check the full commit flag again |
2073 | */ | 2079 | */ |
2074 | if (root->fs_info->last_trans_log_full_commit == trans->transid) { | 2080 | if (root->fs_info->last_trans_log_full_commit == trans->transid) { |
2075 | btrfs_wait_marked_extents(log, &log->dirty_log_pages); | 2081 | btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); |
2076 | mutex_unlock(&log_root_tree->log_mutex); | 2082 | mutex_unlock(&log_root_tree->log_mutex); |
2077 | ret = -EAGAIN; | 2083 | ret = -EAGAIN; |
2078 | goto out_wake_log_root; | 2084 | goto out_wake_log_root; |
2079 | } | 2085 | } |
2080 | 2086 | ||
2081 | ret = btrfs_write_and_wait_marked_extents(log_root_tree, | 2087 | ret = btrfs_write_and_wait_marked_extents(log_root_tree, |
2082 | &log_root_tree->dirty_log_pages); | 2088 | &log_root_tree->dirty_log_pages, |
2089 | EXTENT_DIRTY | EXTENT_NEW); | ||
2083 | BUG_ON(ret); | 2090 | BUG_ON(ret); |
2084 | btrfs_wait_marked_extents(log, &log->dirty_log_pages); | 2091 | btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); |
2085 | 2092 | ||
2086 | btrfs_set_super_log_root(&root->fs_info->super_for_commit, | 2093 | btrfs_set_super_log_root(&root->fs_info->super_for_commit, |
2087 | log_root_tree->node->start); | 2094 | log_root_tree->node->start); |
@@ -2147,12 +2154,12 @@ int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root) | |||
2147 | 2154 | ||
2148 | while (1) { | 2155 | while (1) { |
2149 | ret = find_first_extent_bit(&log->dirty_log_pages, | 2156 | ret = find_first_extent_bit(&log->dirty_log_pages, |
2150 | 0, &start, &end, EXTENT_DIRTY); | 2157 | 0, &start, &end, EXTENT_DIRTY | EXTENT_NEW); |
2151 | if (ret) | 2158 | if (ret) |
2152 | break; | 2159 | break; |
2153 | 2160 | ||
2154 | clear_extent_dirty(&log->dirty_log_pages, | 2161 | clear_extent_bits(&log->dirty_log_pages, start, end, |
2155 | start, end, GFP_NOFS); | 2162 | EXTENT_DIRTY | EXTENT_NEW, GFP_NOFS); |
2156 | } | 2163 | } |
2157 | 2164 | ||
2158 | if (log->log_transid > 0) { | 2165 | if (log->log_transid > 0) { |