diff options
Diffstat (limited to 'fs/btrfs/delayed-inode.c')
-rw-r--r-- | fs/btrfs/delayed-inode.c | 147 |
1 files changed, 100 insertions, 47 deletions
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 34836036f01b..0b278b117cbe 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
@@ -875,7 +875,6 @@ static int btrfs_insert_delayed_item(struct btrfs_trans_handle *trans, | |||
875 | struct btrfs_delayed_item *delayed_item) | 875 | struct btrfs_delayed_item *delayed_item) |
876 | { | 876 | { |
877 | struct extent_buffer *leaf; | 877 | struct extent_buffer *leaf; |
878 | struct btrfs_item *item; | ||
879 | char *ptr; | 878 | char *ptr; |
880 | int ret; | 879 | int ret; |
881 | 880 | ||
@@ -886,7 +885,6 @@ static int btrfs_insert_delayed_item(struct btrfs_trans_handle *trans, | |||
886 | 885 | ||
887 | leaf = path->nodes[0]; | 886 | leaf = path->nodes[0]; |
888 | 887 | ||
889 | item = btrfs_item_nr(leaf, path->slots[0]); | ||
890 | ptr = btrfs_item_ptr(leaf, path->slots[0], char); | 888 | ptr = btrfs_item_ptr(leaf, path->slots[0], char); |
891 | 889 | ||
892 | write_extent_buffer(leaf, delayed_item->data, (unsigned long)ptr, | 890 | write_extent_buffer(leaf, delayed_item->data, (unsigned long)ptr, |
@@ -1065,32 +1063,25 @@ static void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node) | |||
1065 | } | 1063 | } |
1066 | } | 1064 | } |
1067 | 1065 | ||
1068 | static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, | 1066 | static int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, |
1069 | struct btrfs_root *root, | 1067 | struct btrfs_root *root, |
1070 | struct btrfs_path *path, | 1068 | struct btrfs_path *path, |
1071 | struct btrfs_delayed_node *node) | 1069 | struct btrfs_delayed_node *node) |
1072 | { | 1070 | { |
1073 | struct btrfs_key key; | 1071 | struct btrfs_key key; |
1074 | struct btrfs_inode_item *inode_item; | 1072 | struct btrfs_inode_item *inode_item; |
1075 | struct extent_buffer *leaf; | 1073 | struct extent_buffer *leaf; |
1076 | int ret; | 1074 | int ret; |
1077 | 1075 | ||
1078 | mutex_lock(&node->mutex); | ||
1079 | if (!node->inode_dirty) { | ||
1080 | mutex_unlock(&node->mutex); | ||
1081 | return 0; | ||
1082 | } | ||
1083 | |||
1084 | key.objectid = node->inode_id; | 1076 | key.objectid = node->inode_id; |
1085 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | 1077 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); |
1086 | key.offset = 0; | 1078 | key.offset = 0; |
1079 | |||
1087 | ret = btrfs_lookup_inode(trans, root, path, &key, 1); | 1080 | ret = btrfs_lookup_inode(trans, root, path, &key, 1); |
1088 | if (ret > 0) { | 1081 | if (ret > 0) { |
1089 | btrfs_release_path(path); | 1082 | btrfs_release_path(path); |
1090 | mutex_unlock(&node->mutex); | ||
1091 | return -ENOENT; | 1083 | return -ENOENT; |
1092 | } else if (ret < 0) { | 1084 | } else if (ret < 0) { |
1093 | mutex_unlock(&node->mutex); | ||
1094 | return ret; | 1085 | return ret; |
1095 | } | 1086 | } |
1096 | 1087 | ||
@@ -1105,11 +1096,47 @@ static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, | |||
1105 | 1096 | ||
1106 | btrfs_delayed_inode_release_metadata(root, node); | 1097 | btrfs_delayed_inode_release_metadata(root, node); |
1107 | btrfs_release_delayed_inode(node); | 1098 | btrfs_release_delayed_inode(node); |
1108 | mutex_unlock(&node->mutex); | ||
1109 | 1099 | ||
1110 | return 0; | 1100 | return 0; |
1111 | } | 1101 | } |
1112 | 1102 | ||
1103 | static inline int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, | ||
1104 | struct btrfs_root *root, | ||
1105 | struct btrfs_path *path, | ||
1106 | struct btrfs_delayed_node *node) | ||
1107 | { | ||
1108 | int ret; | ||
1109 | |||
1110 | mutex_lock(&node->mutex); | ||
1111 | if (!node->inode_dirty) { | ||
1112 | mutex_unlock(&node->mutex); | ||
1113 | return 0; | ||
1114 | } | ||
1115 | |||
1116 | ret = __btrfs_update_delayed_inode(trans, root, path, node); | ||
1117 | mutex_unlock(&node->mutex); | ||
1118 | return ret; | ||
1119 | } | ||
1120 | |||
1121 | static inline int | ||
1122 | __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | ||
1123 | struct btrfs_path *path, | ||
1124 | struct btrfs_delayed_node *node) | ||
1125 | { | ||
1126 | int ret; | ||
1127 | |||
1128 | ret = btrfs_insert_delayed_items(trans, path, node->root, node); | ||
1129 | if (ret) | ||
1130 | return ret; | ||
1131 | |||
1132 | ret = btrfs_delete_delayed_items(trans, path, node->root, node); | ||
1133 | if (ret) | ||
1134 | return ret; | ||
1135 | |||
1136 | ret = btrfs_update_delayed_inode(trans, node->root, path, node); | ||
1137 | return ret; | ||
1138 | } | ||
1139 | |||
1113 | /* | 1140 | /* |
1114 | * Called when committing the transaction. | 1141 | * Called when committing the transaction. |
1115 | * Returns 0 on success. | 1142 | * Returns 0 on success. |
@@ -1119,7 +1146,6 @@ static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, | |||
1119 | static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | 1146 | static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans, |
1120 | struct btrfs_root *root, int nr) | 1147 | struct btrfs_root *root, int nr) |
1121 | { | 1148 | { |
1122 | struct btrfs_root *curr_root = root; | ||
1123 | struct btrfs_delayed_root *delayed_root; | 1149 | struct btrfs_delayed_root *delayed_root; |
1124 | struct btrfs_delayed_node *curr_node, *prev_node; | 1150 | struct btrfs_delayed_node *curr_node, *prev_node; |
1125 | struct btrfs_path *path; | 1151 | struct btrfs_path *path; |
@@ -1142,15 +1168,8 @@ static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | |||
1142 | 1168 | ||
1143 | curr_node = btrfs_first_delayed_node(delayed_root); | 1169 | curr_node = btrfs_first_delayed_node(delayed_root); |
1144 | while (curr_node && (!count || (count && nr--))) { | 1170 | while (curr_node && (!count || (count && nr--))) { |
1145 | curr_root = curr_node->root; | 1171 | ret = __btrfs_commit_inode_delayed_items(trans, path, |
1146 | ret = btrfs_insert_delayed_items(trans, path, curr_root, | 1172 | curr_node); |
1147 | curr_node); | ||
1148 | if (!ret) | ||
1149 | ret = btrfs_delete_delayed_items(trans, path, | ||
1150 | curr_root, curr_node); | ||
1151 | if (!ret) | ||
1152 | ret = btrfs_update_delayed_inode(trans, curr_root, | ||
1153 | path, curr_node); | ||
1154 | if (ret) { | 1173 | if (ret) { |
1155 | btrfs_release_delayed_node(curr_node); | 1174 | btrfs_release_delayed_node(curr_node); |
1156 | curr_node = NULL; | 1175 | curr_node = NULL; |
@@ -1183,51 +1202,93 @@ int btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans, | |||
1183 | return __btrfs_run_delayed_items(trans, root, nr); | 1202 | return __btrfs_run_delayed_items(trans, root, nr); |
1184 | } | 1203 | } |
1185 | 1204 | ||
1186 | static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | 1205 | int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, |
1187 | struct btrfs_delayed_node *node) | 1206 | struct inode *inode) |
1188 | { | 1207 | { |
1208 | struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode); | ||
1189 | struct btrfs_path *path; | 1209 | struct btrfs_path *path; |
1190 | struct btrfs_block_rsv *block_rsv; | 1210 | struct btrfs_block_rsv *block_rsv; |
1191 | int ret; | 1211 | int ret; |
1192 | 1212 | ||
1213 | if (!delayed_node) | ||
1214 | return 0; | ||
1215 | |||
1216 | mutex_lock(&delayed_node->mutex); | ||
1217 | if (!delayed_node->count) { | ||
1218 | mutex_unlock(&delayed_node->mutex); | ||
1219 | btrfs_release_delayed_node(delayed_node); | ||
1220 | return 0; | ||
1221 | } | ||
1222 | mutex_unlock(&delayed_node->mutex); | ||
1223 | |||
1193 | path = btrfs_alloc_path(); | 1224 | path = btrfs_alloc_path(); |
1194 | if (!path) | 1225 | if (!path) |
1195 | return -ENOMEM; | 1226 | return -ENOMEM; |
1196 | path->leave_spinning = 1; | 1227 | path->leave_spinning = 1; |
1197 | 1228 | ||
1198 | block_rsv = trans->block_rsv; | 1229 | block_rsv = trans->block_rsv; |
1199 | trans->block_rsv = &node->root->fs_info->delayed_block_rsv; | 1230 | trans->block_rsv = &delayed_node->root->fs_info->delayed_block_rsv; |
1200 | 1231 | ||
1201 | ret = btrfs_insert_delayed_items(trans, path, node->root, node); | 1232 | ret = __btrfs_commit_inode_delayed_items(trans, path, delayed_node); |
1202 | if (!ret) | ||
1203 | ret = btrfs_delete_delayed_items(trans, path, node->root, node); | ||
1204 | if (!ret) | ||
1205 | ret = btrfs_update_delayed_inode(trans, node->root, path, node); | ||
1206 | btrfs_free_path(path); | ||
1207 | 1233 | ||
1234 | btrfs_release_delayed_node(delayed_node); | ||
1235 | btrfs_free_path(path); | ||
1208 | trans->block_rsv = block_rsv; | 1236 | trans->block_rsv = block_rsv; |
1237 | |||
1209 | return ret; | 1238 | return ret; |
1210 | } | 1239 | } |
1211 | 1240 | ||
1212 | int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | 1241 | int btrfs_commit_inode_delayed_inode(struct inode *inode) |
1213 | struct inode *inode) | ||
1214 | { | 1242 | { |
1243 | struct btrfs_trans_handle *trans; | ||
1215 | struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode); | 1244 | struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode); |
1245 | struct btrfs_path *path; | ||
1246 | struct btrfs_block_rsv *block_rsv; | ||
1216 | int ret; | 1247 | int ret; |
1217 | 1248 | ||
1218 | if (!delayed_node) | 1249 | if (!delayed_node) |
1219 | return 0; | 1250 | return 0; |
1220 | 1251 | ||
1221 | mutex_lock(&delayed_node->mutex); | 1252 | mutex_lock(&delayed_node->mutex); |
1222 | if (!delayed_node->count) { | 1253 | if (!delayed_node->inode_dirty) { |
1223 | mutex_unlock(&delayed_node->mutex); | 1254 | mutex_unlock(&delayed_node->mutex); |
1224 | btrfs_release_delayed_node(delayed_node); | 1255 | btrfs_release_delayed_node(delayed_node); |
1225 | return 0; | 1256 | return 0; |
1226 | } | 1257 | } |
1227 | mutex_unlock(&delayed_node->mutex); | 1258 | mutex_unlock(&delayed_node->mutex); |
1228 | 1259 | ||
1229 | ret = __btrfs_commit_inode_delayed_items(trans, delayed_node); | 1260 | trans = btrfs_join_transaction(delayed_node->root); |
1261 | if (IS_ERR(trans)) { | ||
1262 | ret = PTR_ERR(trans); | ||
1263 | goto out; | ||
1264 | } | ||
1265 | |||
1266 | path = btrfs_alloc_path(); | ||
1267 | if (!path) { | ||
1268 | ret = -ENOMEM; | ||
1269 | goto trans_out; | ||
1270 | } | ||
1271 | path->leave_spinning = 1; | ||
1272 | |||
1273 | block_rsv = trans->block_rsv; | ||
1274 | trans->block_rsv = &delayed_node->root->fs_info->delayed_block_rsv; | ||
1275 | |||
1276 | mutex_lock(&delayed_node->mutex); | ||
1277 | if (delayed_node->inode_dirty) | ||
1278 | ret = __btrfs_update_delayed_inode(trans, delayed_node->root, | ||
1279 | path, delayed_node); | ||
1280 | else | ||
1281 | ret = 0; | ||
1282 | mutex_unlock(&delayed_node->mutex); | ||
1283 | |||
1284 | btrfs_free_path(path); | ||
1285 | trans->block_rsv = block_rsv; | ||
1286 | trans_out: | ||
1287 | btrfs_end_transaction(trans, delayed_node->root); | ||
1288 | btrfs_btree_balance_dirty(delayed_node->root); | ||
1289 | out: | ||
1230 | btrfs_release_delayed_node(delayed_node); | 1290 | btrfs_release_delayed_node(delayed_node); |
1291 | |||
1231 | return ret; | 1292 | return ret; |
1232 | } | 1293 | } |
1233 | 1294 | ||
@@ -1258,7 +1319,6 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work) | |||
1258 | struct btrfs_root *root; | 1319 | struct btrfs_root *root; |
1259 | struct btrfs_block_rsv *block_rsv; | 1320 | struct btrfs_block_rsv *block_rsv; |
1260 | int need_requeue = 0; | 1321 | int need_requeue = 0; |
1261 | int ret; | ||
1262 | 1322 | ||
1263 | async_node = container_of(work, struct btrfs_async_delayed_node, work); | 1323 | async_node = container_of(work, struct btrfs_async_delayed_node, work); |
1264 | 1324 | ||
@@ -1277,14 +1337,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work) | |||
1277 | block_rsv = trans->block_rsv; | 1337 | block_rsv = trans->block_rsv; |
1278 | trans->block_rsv = &root->fs_info->delayed_block_rsv; | 1338 | trans->block_rsv = &root->fs_info->delayed_block_rsv; |
1279 | 1339 | ||
1280 | ret = btrfs_insert_delayed_items(trans, path, root, delayed_node); | 1340 | __btrfs_commit_inode_delayed_items(trans, path, delayed_node); |
1281 | if (!ret) | ||
1282 | ret = btrfs_delete_delayed_items(trans, path, root, | ||
1283 | delayed_node); | ||
1284 | |||
1285 | if (!ret) | ||
1286 | btrfs_update_delayed_inode(trans, root, path, delayed_node); | ||
1287 | |||
1288 | /* | 1341 | /* |
1289 | * Maybe new delayed items have been inserted, so we need requeue | 1342 | * Maybe new delayed items have been inserted, so we need requeue |
1290 | * the work. Besides that, we must dequeue the empty delayed nodes | 1343 | * the work. Besides that, we must dequeue the empty delayed nodes |