diff options
Diffstat (limited to 'fs/btrfs/delayed-inode.c')
-rw-r--r-- | fs/btrfs/delayed-inode.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index fe4cd0f1cef1..03e3748d84d0 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
@@ -115,6 +115,7 @@ static struct btrfs_delayed_node *btrfs_get_delayed_node(struct inode *inode) | |||
115 | return NULL; | 115 | return NULL; |
116 | } | 116 | } |
117 | 117 | ||
118 | /* Will return either the node or PTR_ERR(-ENOMEM) */ | ||
118 | static struct btrfs_delayed_node *btrfs_get_or_create_delayed_node( | 119 | static struct btrfs_delayed_node *btrfs_get_or_create_delayed_node( |
119 | struct inode *inode) | 120 | struct inode *inode) |
120 | { | 121 | { |
@@ -836,10 +837,8 @@ static int btrfs_batch_insert_items(struct btrfs_trans_handle *trans, | |||
836 | btrfs_clear_path_blocking(path, NULL, 0); | 837 | btrfs_clear_path_blocking(path, NULL, 0); |
837 | 838 | ||
838 | /* insert the keys of the items */ | 839 | /* insert the keys of the items */ |
839 | ret = setup_items_for_insert(trans, root, path, keys, data_size, | 840 | setup_items_for_insert(trans, root, path, keys, data_size, |
840 | total_data_size, total_size, nitems); | 841 | total_data_size, total_size, nitems); |
841 | if (ret) | ||
842 | goto error; | ||
843 | 842 | ||
844 | /* insert the dir index items */ | 843 | /* insert the dir index items */ |
845 | slot = path->slots[0]; | 844 | slot = path->slots[0]; |
@@ -1108,16 +1107,25 @@ static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, | |||
1108 | return 0; | 1107 | return 0; |
1109 | } | 1108 | } |
1110 | 1109 | ||
1111 | /* Called when committing the transaction. */ | 1110 | /* |
1111 | * Called when committing the transaction. | ||
1112 | * Returns 0 on success. | ||
1113 | * Returns < 0 on error and returns with an aborted transaction with any | ||
1114 | * outstanding delayed items cleaned up. | ||
1115 | */ | ||
1112 | int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | 1116 | int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, |
1113 | struct btrfs_root *root) | 1117 | struct btrfs_root *root) |
1114 | { | 1118 | { |
1119 | struct btrfs_root *curr_root = root; | ||
1115 | struct btrfs_delayed_root *delayed_root; | 1120 | struct btrfs_delayed_root *delayed_root; |
1116 | struct btrfs_delayed_node *curr_node, *prev_node; | 1121 | struct btrfs_delayed_node *curr_node, *prev_node; |
1117 | struct btrfs_path *path; | 1122 | struct btrfs_path *path; |
1118 | struct btrfs_block_rsv *block_rsv; | 1123 | struct btrfs_block_rsv *block_rsv; |
1119 | int ret = 0; | 1124 | int ret = 0; |
1120 | 1125 | ||
1126 | if (trans->aborted) | ||
1127 | return -EIO; | ||
1128 | |||
1121 | path = btrfs_alloc_path(); | 1129 | path = btrfs_alloc_path(); |
1122 | if (!path) | 1130 | if (!path) |
1123 | return -ENOMEM; | 1131 | return -ENOMEM; |
@@ -1130,17 +1138,18 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | |||
1130 | 1138 | ||
1131 | curr_node = btrfs_first_delayed_node(delayed_root); | 1139 | curr_node = btrfs_first_delayed_node(delayed_root); |
1132 | while (curr_node) { | 1140 | while (curr_node) { |
1133 | root = curr_node->root; | 1141 | curr_root = curr_node->root; |
1134 | ret = btrfs_insert_delayed_items(trans, path, root, | 1142 | ret = btrfs_insert_delayed_items(trans, path, curr_root, |
1135 | curr_node); | 1143 | curr_node); |
1136 | if (!ret) | 1144 | if (!ret) |
1137 | ret = btrfs_delete_delayed_items(trans, path, root, | 1145 | ret = btrfs_delete_delayed_items(trans, path, |
1138 | curr_node); | 1146 | curr_root, curr_node); |
1139 | if (!ret) | 1147 | if (!ret) |
1140 | ret = btrfs_update_delayed_inode(trans, root, path, | 1148 | ret = btrfs_update_delayed_inode(trans, curr_root, |
1141 | curr_node); | 1149 | path, curr_node); |
1142 | if (ret) { | 1150 | if (ret) { |
1143 | btrfs_release_delayed_node(curr_node); | 1151 | btrfs_release_delayed_node(curr_node); |
1152 | btrfs_abort_transaction(trans, root, ret); | ||
1144 | break; | 1153 | break; |
1145 | } | 1154 | } |
1146 | 1155 | ||
@@ -1151,6 +1160,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | |||
1151 | 1160 | ||
1152 | btrfs_free_path(path); | 1161 | btrfs_free_path(path); |
1153 | trans->block_rsv = block_rsv; | 1162 | trans->block_rsv = block_rsv; |
1163 | |||
1154 | return ret; | 1164 | return ret; |
1155 | } | 1165 | } |
1156 | 1166 | ||
@@ -1371,6 +1381,7 @@ void btrfs_balance_delayed_items(struct btrfs_root *root) | |||
1371 | btrfs_wq_run_delayed_node(delayed_root, root, 0); | 1381 | btrfs_wq_run_delayed_node(delayed_root, root, 0); |
1372 | } | 1382 | } |
1373 | 1383 | ||
1384 | /* Will return 0 or -ENOMEM */ | ||
1374 | int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, | 1385 | int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, |
1375 | struct btrfs_root *root, const char *name, | 1386 | struct btrfs_root *root, const char *name, |
1376 | int name_len, struct inode *dir, | 1387 | int name_len, struct inode *dir, |