diff options
Diffstat (limited to 'fs/btrfs/delayed-inode.c')
| -rw-r--r-- | fs/btrfs/delayed-inode.c | 136 |
1 files changed, 107 insertions, 29 deletions
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 6462c29d2d37..98c68e658a9b 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
| @@ -82,19 +82,16 @@ static inline struct btrfs_delayed_root *btrfs_get_delayed_root( | |||
| 82 | return root->fs_info->delayed_root; | 82 | return root->fs_info->delayed_root; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | static struct btrfs_delayed_node *btrfs_get_or_create_delayed_node( | 85 | static struct btrfs_delayed_node *btrfs_get_delayed_node(struct inode *inode) |
| 86 | struct inode *inode) | ||
| 87 | { | 86 | { |
| 88 | struct btrfs_delayed_node *node; | ||
| 89 | struct btrfs_inode *btrfs_inode = BTRFS_I(inode); | 87 | struct btrfs_inode *btrfs_inode = BTRFS_I(inode); |
| 90 | struct btrfs_root *root = btrfs_inode->root; | 88 | struct btrfs_root *root = btrfs_inode->root; |
| 91 | u64 ino = btrfs_ino(inode); | 89 | u64 ino = btrfs_ino(inode); |
| 92 | int ret; | 90 | struct btrfs_delayed_node *node; |
| 93 | 91 | ||
| 94 | again: | ||
| 95 | node = ACCESS_ONCE(btrfs_inode->delayed_node); | 92 | node = ACCESS_ONCE(btrfs_inode->delayed_node); |
| 96 | if (node) { | 93 | if (node) { |
| 97 | atomic_inc(&node->refs); /* can be accessed */ | 94 | atomic_inc(&node->refs); |
| 98 | return node; | 95 | return node; |
| 99 | } | 96 | } |
| 100 | 97 | ||
| @@ -102,8 +99,10 @@ again: | |||
| 102 | node = radix_tree_lookup(&root->delayed_nodes_tree, ino); | 99 | node = radix_tree_lookup(&root->delayed_nodes_tree, ino); |
| 103 | if (node) { | 100 | if (node) { |
| 104 | if (btrfs_inode->delayed_node) { | 101 | if (btrfs_inode->delayed_node) { |
| 102 | atomic_inc(&node->refs); /* can be accessed */ | ||
| 103 | BUG_ON(btrfs_inode->delayed_node != node); | ||
| 105 | spin_unlock(&root->inode_lock); | 104 | spin_unlock(&root->inode_lock); |
| 106 | goto again; | 105 | return node; |
| 107 | } | 106 | } |
| 108 | btrfs_inode->delayed_node = node; | 107 | btrfs_inode->delayed_node = node; |
| 109 | atomic_inc(&node->refs); /* can be accessed */ | 108 | atomic_inc(&node->refs); /* can be accessed */ |
| @@ -113,6 +112,23 @@ again: | |||
| 113 | } | 112 | } |
| 114 | spin_unlock(&root->inode_lock); | 113 | spin_unlock(&root->inode_lock); |
| 115 | 114 | ||
| 115 | return NULL; | ||
| 116 | } | ||
| 117 | |||
| 118 | static struct btrfs_delayed_node *btrfs_get_or_create_delayed_node( | ||
| 119 | struct inode *inode) | ||
| 120 | { | ||
| 121 | struct btrfs_delayed_node *node; | ||
| 122 | struct btrfs_inode *btrfs_inode = BTRFS_I(inode); | ||
| 123 | struct btrfs_root *root = btrfs_inode->root; | ||
| 124 | u64 ino = btrfs_ino(inode); | ||
| 125 | int ret; | ||
| 126 | |||
| 127 | again: | ||
| 128 | node = btrfs_get_delayed_node(inode); | ||
| 129 | if (node) | ||
| 130 | return node; | ||
| 131 | |||
| 116 | node = kmem_cache_alloc(delayed_node_cache, GFP_NOFS); | 132 | node = kmem_cache_alloc(delayed_node_cache, GFP_NOFS); |
| 117 | if (!node) | 133 | if (!node) |
| 118 | return ERR_PTR(-ENOMEM); | 134 | return ERR_PTR(-ENOMEM); |
| @@ -297,7 +313,6 @@ struct btrfs_delayed_item *btrfs_alloc_delayed_item(u32 data_len) | |||
| 297 | item->data_len = data_len; | 313 | item->data_len = data_len; |
| 298 | item->ins_or_del = 0; | 314 | item->ins_or_del = 0; |
| 299 | item->bytes_reserved = 0; | 315 | item->bytes_reserved = 0; |
| 300 | item->block_rsv = NULL; | ||
| 301 | item->delayed_node = NULL; | 316 | item->delayed_node = NULL; |
| 302 | atomic_set(&item->refs, 1); | 317 | atomic_set(&item->refs, 1); |
| 303 | } | 318 | } |
| @@ -549,19 +564,6 @@ struct btrfs_delayed_item *__btrfs_next_delayed_item( | |||
| 549 | return next; | 564 | return next; |
| 550 | } | 565 | } |
| 551 | 566 | ||
| 552 | static inline struct btrfs_delayed_node *btrfs_get_delayed_node( | ||
| 553 | struct inode *inode) | ||
| 554 | { | ||
| 555 | struct btrfs_inode *btrfs_inode = BTRFS_I(inode); | ||
| 556 | struct btrfs_delayed_node *delayed_node; | ||
| 557 | |||
| 558 | delayed_node = btrfs_inode->delayed_node; | ||
| 559 | if (delayed_node) | ||
| 560 | atomic_inc(&delayed_node->refs); | ||
| 561 | |||
| 562 | return delayed_node; | ||
| 563 | } | ||
| 564 | |||
| 565 | static inline struct btrfs_root *btrfs_get_fs_root(struct btrfs_root *root, | 567 | static inline struct btrfs_root *btrfs_get_fs_root(struct btrfs_root *root, |
| 566 | u64 root_id) | 568 | u64 root_id) |
| 567 | { | 569 | { |
| @@ -593,10 +595,8 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans, | |||
| 593 | 595 | ||
| 594 | num_bytes = btrfs_calc_trans_metadata_size(root, 1); | 596 | num_bytes = btrfs_calc_trans_metadata_size(root, 1); |
| 595 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); | 597 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); |
| 596 | if (!ret) { | 598 | if (!ret) |
| 597 | item->bytes_reserved = num_bytes; | 599 | item->bytes_reserved = num_bytes; |
| 598 | item->block_rsv = dst_rsv; | ||
| 599 | } | ||
| 600 | 600 | ||
| 601 | return ret; | 601 | return ret; |
| 602 | } | 602 | } |
| @@ -604,10 +604,13 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans, | |||
| 604 | static void btrfs_delayed_item_release_metadata(struct btrfs_root *root, | 604 | static void btrfs_delayed_item_release_metadata(struct btrfs_root *root, |
| 605 | struct btrfs_delayed_item *item) | 605 | struct btrfs_delayed_item *item) |
| 606 | { | 606 | { |
| 607 | struct btrfs_block_rsv *rsv; | ||
| 608 | |||
| 607 | if (!item->bytes_reserved) | 609 | if (!item->bytes_reserved) |
| 608 | return; | 610 | return; |
| 609 | 611 | ||
| 610 | btrfs_block_rsv_release(root, item->block_rsv, | 612 | rsv = &root->fs_info->global_block_rsv; |
| 613 | btrfs_block_rsv_release(root, rsv, | ||
| 611 | item->bytes_reserved); | 614 | item->bytes_reserved); |
| 612 | } | 615 | } |
| 613 | 616 | ||
| @@ -1014,6 +1017,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | |||
| 1014 | struct btrfs_delayed_root *delayed_root; | 1017 | struct btrfs_delayed_root *delayed_root; |
| 1015 | struct btrfs_delayed_node *curr_node, *prev_node; | 1018 | struct btrfs_delayed_node *curr_node, *prev_node; |
| 1016 | struct btrfs_path *path; | 1019 | struct btrfs_path *path; |
| 1020 | struct btrfs_block_rsv *block_rsv; | ||
| 1017 | int ret = 0; | 1021 | int ret = 0; |
| 1018 | 1022 | ||
| 1019 | path = btrfs_alloc_path(); | 1023 | path = btrfs_alloc_path(); |
| @@ -1021,6 +1025,9 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | |||
| 1021 | return -ENOMEM; | 1025 | return -ENOMEM; |
| 1022 | path->leave_spinning = 1; | 1026 | path->leave_spinning = 1; |
| 1023 | 1027 | ||
| 1028 | block_rsv = trans->block_rsv; | ||
| 1029 | trans->block_rsv = &root->fs_info->global_block_rsv; | ||
| 1030 | |||
| 1024 | delayed_root = btrfs_get_delayed_root(root); | 1031 | delayed_root = btrfs_get_delayed_root(root); |
| 1025 | 1032 | ||
| 1026 | curr_node = btrfs_first_delayed_node(delayed_root); | 1033 | curr_node = btrfs_first_delayed_node(delayed_root); |
| @@ -1045,6 +1052,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | |||
| 1045 | } | 1052 | } |
| 1046 | 1053 | ||
| 1047 | btrfs_free_path(path); | 1054 | btrfs_free_path(path); |
| 1055 | trans->block_rsv = block_rsv; | ||
| 1048 | return ret; | 1056 | return ret; |
| 1049 | } | 1057 | } |
| 1050 | 1058 | ||
| @@ -1052,6 +1060,7 @@ static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | |||
| 1052 | struct btrfs_delayed_node *node) | 1060 | struct btrfs_delayed_node *node) |
| 1053 | { | 1061 | { |
| 1054 | struct btrfs_path *path; | 1062 | struct btrfs_path *path; |
| 1063 | struct btrfs_block_rsv *block_rsv; | ||
| 1055 | int ret; | 1064 | int ret; |
| 1056 | 1065 | ||
| 1057 | path = btrfs_alloc_path(); | 1066 | path = btrfs_alloc_path(); |
| @@ -1059,6 +1068,9 @@ static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | |||
| 1059 | return -ENOMEM; | 1068 | return -ENOMEM; |
| 1060 | path->leave_spinning = 1; | 1069 | path->leave_spinning = 1; |
| 1061 | 1070 | ||
| 1071 | block_rsv = trans->block_rsv; | ||
| 1072 | trans->block_rsv = &node->root->fs_info->global_block_rsv; | ||
| 1073 | |||
| 1062 | ret = btrfs_insert_delayed_items(trans, path, node->root, node); | 1074 | ret = btrfs_insert_delayed_items(trans, path, node->root, node); |
| 1063 | if (!ret) | 1075 | if (!ret) |
| 1064 | ret = btrfs_delete_delayed_items(trans, path, node->root, node); | 1076 | ret = btrfs_delete_delayed_items(trans, path, node->root, node); |
| @@ -1066,6 +1078,7 @@ static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | |||
| 1066 | ret = btrfs_update_delayed_inode(trans, node->root, path, node); | 1078 | ret = btrfs_update_delayed_inode(trans, node->root, path, node); |
| 1067 | btrfs_free_path(path); | 1079 | btrfs_free_path(path); |
| 1068 | 1080 | ||
| 1081 | trans->block_rsv = block_rsv; | ||
| 1069 | return ret; | 1082 | return ret; |
| 1070 | } | 1083 | } |
| 1071 | 1084 | ||
| @@ -1116,6 +1129,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work) | |||
| 1116 | struct btrfs_path *path; | 1129 | struct btrfs_path *path; |
| 1117 | struct btrfs_delayed_node *delayed_node = NULL; | 1130 | struct btrfs_delayed_node *delayed_node = NULL; |
| 1118 | struct btrfs_root *root; | 1131 | struct btrfs_root *root; |
| 1132 | struct btrfs_block_rsv *block_rsv; | ||
| 1119 | unsigned long nr = 0; | 1133 | unsigned long nr = 0; |
| 1120 | int need_requeue = 0; | 1134 | int need_requeue = 0; |
| 1121 | int ret; | 1135 | int ret; |
| @@ -1134,6 +1148,9 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work) | |||
| 1134 | if (IS_ERR(trans)) | 1148 | if (IS_ERR(trans)) |
| 1135 | goto free_path; | 1149 | goto free_path; |
| 1136 | 1150 | ||
| 1151 | block_rsv = trans->block_rsv; | ||
| 1152 | trans->block_rsv = &root->fs_info->global_block_rsv; | ||
| 1153 | |||
| 1137 | ret = btrfs_insert_delayed_items(trans, path, root, delayed_node); | 1154 | ret = btrfs_insert_delayed_items(trans, path, root, delayed_node); |
| 1138 | if (!ret) | 1155 | if (!ret) |
| 1139 | ret = btrfs_delete_delayed_items(trans, path, root, | 1156 | ret = btrfs_delete_delayed_items(trans, path, root, |
| @@ -1176,6 +1193,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work) | |||
| 1176 | 1193 | ||
| 1177 | nr = trans->blocks_used; | 1194 | nr = trans->blocks_used; |
| 1178 | 1195 | ||
| 1196 | trans->block_rsv = block_rsv; | ||
| 1179 | btrfs_end_transaction_dmeta(trans, root); | 1197 | btrfs_end_transaction_dmeta(trans, root); |
| 1180 | __btrfs_btree_balance_dirty(root, nr); | 1198 | __btrfs_btree_balance_dirty(root, nr); |
| 1181 | free_path: | 1199 | free_path: |
| @@ -1222,6 +1240,13 @@ again: | |||
| 1222 | return 0; | 1240 | return 0; |
| 1223 | } | 1241 | } |
| 1224 | 1242 | ||
| 1243 | void btrfs_assert_delayed_root_empty(struct btrfs_root *root) | ||
| 1244 | { | ||
| 1245 | struct btrfs_delayed_root *delayed_root; | ||
| 1246 | delayed_root = btrfs_get_delayed_root(root); | ||
| 1247 | WARN_ON(btrfs_first_delayed_node(delayed_root)); | ||
| 1248 | } | ||
| 1249 | |||
| 1225 | void btrfs_balance_delayed_items(struct btrfs_root *root) | 1250 | void btrfs_balance_delayed_items(struct btrfs_root *root) |
| 1226 | { | 1251 | { |
| 1227 | struct btrfs_delayed_root *delayed_root; | 1252 | struct btrfs_delayed_root *delayed_root; |
| @@ -1382,8 +1407,7 @@ end: | |||
| 1382 | 1407 | ||
| 1383 | int btrfs_inode_delayed_dir_index_count(struct inode *inode) | 1408 | int btrfs_inode_delayed_dir_index_count(struct inode *inode) |
| 1384 | { | 1409 | { |
| 1385 | struct btrfs_delayed_node *delayed_node = BTRFS_I(inode)->delayed_node; | 1410 | struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode); |
| 1386 | int ret = 0; | ||
| 1387 | 1411 | ||
| 1388 | if (!delayed_node) | 1412 | if (!delayed_node) |
| 1389 | return -ENOENT; | 1413 | return -ENOENT; |
| @@ -1393,11 +1417,14 @@ int btrfs_inode_delayed_dir_index_count(struct inode *inode) | |||
| 1393 | * a new directory index is added into the delayed node and index_cnt | 1417 | * a new directory index is added into the delayed node and index_cnt |
| 1394 | * is updated now. So we needn't lock the delayed node. | 1418 | * is updated now. So we needn't lock the delayed node. |
| 1395 | */ | 1419 | */ |
| 1396 | if (!delayed_node->index_cnt) | 1420 | if (!delayed_node->index_cnt) { |
| 1421 | btrfs_release_delayed_node(delayed_node); | ||
| 1397 | return -EINVAL; | 1422 | return -EINVAL; |
| 1423 | } | ||
| 1398 | 1424 | ||
| 1399 | BTRFS_I(inode)->index_cnt = delayed_node->index_cnt; | 1425 | BTRFS_I(inode)->index_cnt = delayed_node->index_cnt; |
| 1400 | return ret; | 1426 | btrfs_release_delayed_node(delayed_node); |
| 1427 | return 0; | ||
| 1401 | } | 1428 | } |
| 1402 | 1429 | ||
| 1403 | void btrfs_get_delayed_items(struct inode *inode, struct list_head *ins_list, | 1430 | void btrfs_get_delayed_items(struct inode *inode, struct list_head *ins_list, |
| @@ -1591,6 +1618,57 @@ static void fill_stack_inode_item(struct btrfs_trans_handle *trans, | |||
| 1591 | inode->i_ctime.tv_nsec); | 1618 | inode->i_ctime.tv_nsec); |
| 1592 | } | 1619 | } |
| 1593 | 1620 | ||
| 1621 | int btrfs_fill_inode(struct inode *inode, u32 *rdev) | ||
| 1622 | { | ||
| 1623 | struct btrfs_delayed_node *delayed_node; | ||
| 1624 | struct btrfs_inode_item *inode_item; | ||
| 1625 | struct btrfs_timespec *tspec; | ||
| 1626 | |||
| 1627 | delayed_node = btrfs_get_delayed_node(inode); | ||
| 1628 | if (!delayed_node) | ||
| 1629 | return -ENOENT; | ||
| 1630 | |||
| 1631 | mutex_lock(&delayed_node->mutex); | ||
| 1632 | if (!delayed_node->inode_dirty) { | ||
| 1633 | mutex_unlock(&delayed_node->mutex); | ||
| 1634 | btrfs_release_delayed_node(delayed_node); | ||
| 1635 | return -ENOENT; | ||
| 1636 | } | ||
| 1637 | |||
| 1638 | inode_item = &delayed_node->inode_item; | ||
| 1639 | |||
| 1640 | inode->i_uid = btrfs_stack_inode_uid(inode_item); | ||
| 1641 | inode->i_gid = btrfs_stack_inode_gid(inode_item); | ||
| 1642 | btrfs_i_size_write(inode, btrfs_stack_inode_size(inode_item)); | ||
| 1643 | inode->i_mode = btrfs_stack_inode_mode(inode_item); | ||
| 1644 | inode->i_nlink = btrfs_stack_inode_nlink(inode_item); | ||
| 1645 | inode_set_bytes(inode, btrfs_stack_inode_nbytes(inode_item)); | ||
| 1646 | BTRFS_I(inode)->generation = btrfs_stack_inode_generation(inode_item); | ||
| 1647 | BTRFS_I(inode)->sequence = btrfs_stack_inode_sequence(inode_item); | ||
| 1648 | inode->i_rdev = 0; | ||
| 1649 | *rdev = btrfs_stack_inode_rdev(inode_item); | ||
| 1650 | BTRFS_I(inode)->flags = btrfs_stack_inode_flags(inode_item); | ||
| 1651 | |||
| 1652 | tspec = btrfs_inode_atime(inode_item); | ||
| 1653 | inode->i_atime.tv_sec = btrfs_stack_timespec_sec(tspec); | ||
| 1654 | inode->i_atime.tv_nsec = btrfs_stack_timespec_nsec(tspec); | ||
| 1655 | |||
| 1656 | tspec = btrfs_inode_mtime(inode_item); | ||
| 1657 | inode->i_mtime.tv_sec = btrfs_stack_timespec_sec(tspec); | ||
| 1658 | inode->i_mtime.tv_nsec = btrfs_stack_timespec_nsec(tspec); | ||
| 1659 | |||
| 1660 | tspec = btrfs_inode_ctime(inode_item); | ||
| 1661 | inode->i_ctime.tv_sec = btrfs_stack_timespec_sec(tspec); | ||
| 1662 | inode->i_ctime.tv_nsec = btrfs_stack_timespec_nsec(tspec); | ||
| 1663 | |||
| 1664 | inode->i_generation = BTRFS_I(inode)->generation; | ||
| 1665 | BTRFS_I(inode)->index_cnt = (u64)-1; | ||
| 1666 | |||
| 1667 | mutex_unlock(&delayed_node->mutex); | ||
| 1668 | btrfs_release_delayed_node(delayed_node); | ||
| 1669 | return 0; | ||
| 1670 | } | ||
| 1671 | |||
| 1594 | int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, | 1672 | int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, |
| 1595 | struct btrfs_root *root, struct inode *inode) | 1673 | struct btrfs_root *root, struct inode *inode) |
| 1596 | { | 1674 | { |
