diff options
| -rw-r--r-- | fs/btrfs/ctree.h | 15 | ||||
| -rw-r--r-- | fs/btrfs/delayed-inode.c | 32 | ||||
| -rw-r--r-- | fs/btrfs/delayed-inode.h | 5 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 12 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 4 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 1 | ||||
| -rw-r--r-- | fs/btrfs/ioctl.c | 2 | ||||
| -rw-r--r-- | fs/btrfs/relocation.c | 30 | ||||
| -rw-r--r-- | fs/btrfs/sysfs.c | 146 | ||||
| -rw-r--r-- | fs/btrfs/transaction.c | 114 | ||||
| -rw-r--r-- | fs/btrfs/tree-log.c | 2 |
11 files changed, 174 insertions, 189 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 378b5b4443f3..300628795fdb 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -967,6 +967,12 @@ struct btrfs_fs_info { | |||
| 967 | struct srcu_struct subvol_srcu; | 967 | struct srcu_struct subvol_srcu; |
| 968 | 968 | ||
| 969 | spinlock_t trans_lock; | 969 | spinlock_t trans_lock; |
| 970 | /* | ||
| 971 | * the reloc mutex goes with the trans lock, it is taken | ||
| 972 | * during commit to protect us from the relocation code | ||
| 973 | */ | ||
| 974 | struct mutex reloc_mutex; | ||
| 975 | |||
| 970 | struct list_head trans_list; | 976 | struct list_head trans_list; |
| 971 | struct list_head hashers; | 977 | struct list_head hashers; |
| 972 | struct list_head dead_roots; | 978 | struct list_head dead_roots; |
| @@ -1172,6 +1178,14 @@ struct btrfs_root { | |||
| 1172 | u32 type; | 1178 | u32 type; |
| 1173 | 1179 | ||
| 1174 | u64 highest_objectid; | 1180 | u64 highest_objectid; |
| 1181 | |||
| 1182 | /* btrfs_record_root_in_trans is a multi-step process, | ||
| 1183 | * and it can race with the balancing code. But the | ||
| 1184 | * race is very small, and only the first time the root | ||
| 1185 | * is added to each transaction. So in_trans_setup | ||
| 1186 | * is used to tell us when more checks are required | ||
| 1187 | */ | ||
| 1188 | unsigned long in_trans_setup; | ||
| 1175 | int ref_cows; | 1189 | int ref_cows; |
| 1176 | int track_dirty; | 1190 | int track_dirty; |
| 1177 | int in_radix; | 1191 | int in_radix; |
| @@ -1181,7 +1195,6 @@ struct btrfs_root { | |||
| 1181 | struct btrfs_key defrag_max; | 1195 | struct btrfs_key defrag_max; |
| 1182 | int defrag_running; | 1196 | int defrag_running; |
| 1183 | char *name; | 1197 | char *name; |
| 1184 | int in_sysfs; | ||
| 1185 | 1198 | ||
| 1186 | /* the dirty list is only used by non-reference counted roots */ | 1199 | /* the dirty list is only used by non-reference counted roots */ |
| 1187 | struct list_head dirty_list; | 1200 | struct list_head dirty_list; |
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 6462c29d2d37..f1cbd028f7b3 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
| @@ -297,7 +297,6 @@ struct btrfs_delayed_item *btrfs_alloc_delayed_item(u32 data_len) | |||
| 297 | item->data_len = data_len; | 297 | item->data_len = data_len; |
| 298 | item->ins_or_del = 0; | 298 | item->ins_or_del = 0; |
| 299 | item->bytes_reserved = 0; | 299 | item->bytes_reserved = 0; |
| 300 | item->block_rsv = NULL; | ||
| 301 | item->delayed_node = NULL; | 300 | item->delayed_node = NULL; |
| 302 | atomic_set(&item->refs, 1); | 301 | atomic_set(&item->refs, 1); |
| 303 | } | 302 | } |
| @@ -593,10 +592,8 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans, | |||
| 593 | 592 | ||
| 594 | num_bytes = btrfs_calc_trans_metadata_size(root, 1); | 593 | num_bytes = btrfs_calc_trans_metadata_size(root, 1); |
| 595 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); | 594 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); |
| 596 | if (!ret) { | 595 | if (!ret) |
| 597 | item->bytes_reserved = num_bytes; | 596 | item->bytes_reserved = num_bytes; |
| 598 | item->block_rsv = dst_rsv; | ||
| 599 | } | ||
| 600 | 597 | ||
| 601 | return ret; | 598 | return ret; |
| 602 | } | 599 | } |
| @@ -604,10 +601,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, | 601 | static void btrfs_delayed_item_release_metadata(struct btrfs_root *root, |
| 605 | struct btrfs_delayed_item *item) | 602 | struct btrfs_delayed_item *item) |
| 606 | { | 603 | { |
| 604 | struct btrfs_block_rsv *rsv; | ||
| 605 | |||
| 607 | if (!item->bytes_reserved) | 606 | if (!item->bytes_reserved) |
| 608 | return; | 607 | return; |
| 609 | 608 | ||
| 610 | btrfs_block_rsv_release(root, item->block_rsv, | 609 | rsv = &root->fs_info->global_block_rsv; |
| 610 | btrfs_block_rsv_release(root, rsv, | ||
| 611 | item->bytes_reserved); | 611 | item->bytes_reserved); |
| 612 | } | 612 | } |
| 613 | 613 | ||
| @@ -1014,6 +1014,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | |||
| 1014 | struct btrfs_delayed_root *delayed_root; | 1014 | struct btrfs_delayed_root *delayed_root; |
| 1015 | struct btrfs_delayed_node *curr_node, *prev_node; | 1015 | struct btrfs_delayed_node *curr_node, *prev_node; |
| 1016 | struct btrfs_path *path; | 1016 | struct btrfs_path *path; |
| 1017 | struct btrfs_block_rsv *block_rsv; | ||
| 1017 | int ret = 0; | 1018 | int ret = 0; |
| 1018 | 1019 | ||
| 1019 | path = btrfs_alloc_path(); | 1020 | path = btrfs_alloc_path(); |
| @@ -1021,6 +1022,9 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | |||
| 1021 | return -ENOMEM; | 1022 | return -ENOMEM; |
| 1022 | path->leave_spinning = 1; | 1023 | path->leave_spinning = 1; |
| 1023 | 1024 | ||
| 1025 | block_rsv = trans->block_rsv; | ||
| 1026 | trans->block_rsv = &root->fs_info->global_block_rsv; | ||
| 1027 | |||
| 1024 | delayed_root = btrfs_get_delayed_root(root); | 1028 | delayed_root = btrfs_get_delayed_root(root); |
| 1025 | 1029 | ||
| 1026 | curr_node = btrfs_first_delayed_node(delayed_root); | 1030 | curr_node = btrfs_first_delayed_node(delayed_root); |
| @@ -1045,6 +1049,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | |||
| 1045 | } | 1049 | } |
| 1046 | 1050 | ||
| 1047 | btrfs_free_path(path); | 1051 | btrfs_free_path(path); |
| 1052 | trans->block_rsv = block_rsv; | ||
| 1048 | return ret; | 1053 | return ret; |
| 1049 | } | 1054 | } |
| 1050 | 1055 | ||
| @@ -1052,6 +1057,7 @@ static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | |||
| 1052 | struct btrfs_delayed_node *node) | 1057 | struct btrfs_delayed_node *node) |
| 1053 | { | 1058 | { |
| 1054 | struct btrfs_path *path; | 1059 | struct btrfs_path *path; |
| 1060 | struct btrfs_block_rsv *block_rsv; | ||
| 1055 | int ret; | 1061 | int ret; |
| 1056 | 1062 | ||
| 1057 | path = btrfs_alloc_path(); | 1063 | path = btrfs_alloc_path(); |
| @@ -1059,6 +1065,9 @@ static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | |||
| 1059 | return -ENOMEM; | 1065 | return -ENOMEM; |
| 1060 | path->leave_spinning = 1; | 1066 | path->leave_spinning = 1; |
| 1061 | 1067 | ||
| 1068 | block_rsv = trans->block_rsv; | ||
| 1069 | trans->block_rsv = &node->root->fs_info->global_block_rsv; | ||
| 1070 | |||
| 1062 | ret = btrfs_insert_delayed_items(trans, path, node->root, node); | 1071 | ret = btrfs_insert_delayed_items(trans, path, node->root, node); |
| 1063 | if (!ret) | 1072 | if (!ret) |
| 1064 | ret = btrfs_delete_delayed_items(trans, path, node->root, node); | 1073 | ret = btrfs_delete_delayed_items(trans, path, node->root, node); |
| @@ -1066,6 +1075,7 @@ static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | |||
| 1066 | ret = btrfs_update_delayed_inode(trans, node->root, path, node); | 1075 | ret = btrfs_update_delayed_inode(trans, node->root, path, node); |
| 1067 | btrfs_free_path(path); | 1076 | btrfs_free_path(path); |
| 1068 | 1077 | ||
| 1078 | trans->block_rsv = block_rsv; | ||
| 1069 | return ret; | 1079 | return ret; |
| 1070 | } | 1080 | } |
| 1071 | 1081 | ||
| @@ -1116,6 +1126,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work) | |||
| 1116 | struct btrfs_path *path; | 1126 | struct btrfs_path *path; |
| 1117 | struct btrfs_delayed_node *delayed_node = NULL; | 1127 | struct btrfs_delayed_node *delayed_node = NULL; |
| 1118 | struct btrfs_root *root; | 1128 | struct btrfs_root *root; |
| 1129 | struct btrfs_block_rsv *block_rsv; | ||
| 1119 | unsigned long nr = 0; | 1130 | unsigned long nr = 0; |
| 1120 | int need_requeue = 0; | 1131 | int need_requeue = 0; |
| 1121 | int ret; | 1132 | int ret; |
| @@ -1134,6 +1145,9 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work) | |||
| 1134 | if (IS_ERR(trans)) | 1145 | if (IS_ERR(trans)) |
| 1135 | goto free_path; | 1146 | goto free_path; |
| 1136 | 1147 | ||
| 1148 | block_rsv = trans->block_rsv; | ||
| 1149 | trans->block_rsv = &root->fs_info->global_block_rsv; | ||
| 1150 | |||
| 1137 | ret = btrfs_insert_delayed_items(trans, path, root, delayed_node); | 1151 | ret = btrfs_insert_delayed_items(trans, path, root, delayed_node); |
| 1138 | if (!ret) | 1152 | if (!ret) |
| 1139 | ret = btrfs_delete_delayed_items(trans, path, root, | 1153 | ret = btrfs_delete_delayed_items(trans, path, root, |
| @@ -1176,6 +1190,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work) | |||
| 1176 | 1190 | ||
| 1177 | nr = trans->blocks_used; | 1191 | nr = trans->blocks_used; |
| 1178 | 1192 | ||
