diff options
Diffstat (limited to 'fs/btrfs/delayed-inode.c')
-rw-r--r-- | fs/btrfs/delayed-inode.c | 298 |
1 files changed, 190 insertions, 108 deletions
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 34836036f01b..14fce27b4780 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
@@ -22,8 +22,9 @@ | |||
22 | #include "disk-io.h" | 22 | #include "disk-io.h" |
23 | #include "transaction.h" | 23 | #include "transaction.h" |
24 | 24 | ||
25 | #define BTRFS_DELAYED_WRITEBACK 400 | 25 | #define BTRFS_DELAYED_WRITEBACK 512 |
26 | #define BTRFS_DELAYED_BACKGROUND 100 | 26 | #define BTRFS_DELAYED_BACKGROUND 128 |
27 | #define BTRFS_DELAYED_BATCH 16 | ||
27 | 28 | ||
28 | static struct kmem_cache *delayed_node_cache; | 29 | static struct kmem_cache *delayed_node_cache; |
29 | 30 | ||
@@ -494,6 +495,15 @@ static int __btrfs_add_delayed_deletion_item(struct btrfs_delayed_node *node, | |||
494 | BTRFS_DELAYED_DELETION_ITEM); | 495 | BTRFS_DELAYED_DELETION_ITEM); |
495 | } | 496 | } |
496 | 497 | ||
498 | static void finish_one_item(struct btrfs_delayed_root *delayed_root) | ||
499 | { | ||
500 | int seq = atomic_inc_return(&delayed_root->items_seq); | ||
501 | if ((atomic_dec_return(&delayed_root->items) < | ||
502 | BTRFS_DELAYED_BACKGROUND || seq % BTRFS_DELAYED_BATCH == 0) && | ||
503 | waitqueue_active(&delayed_root->wait)) | ||
504 | wake_up(&delayed_root->wait); | ||
505 | } | ||
506 | |||
497 | static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) | 507 | static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) |
498 | { | 508 | { |
499 | struct rb_root *root; | 509 | struct rb_root *root; |
@@ -512,10 +522,8 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) | |||
512 | 522 | ||
513 | rb_erase(&delayed_item->rb_node, root); | 523 | rb_erase(&delayed_item->rb_node, root); |
514 | delayed_item->delayed_node->count--; | 524 | delayed_item->delayed_node->count--; |
515 | if (atomic_dec_return(&delayed_root->items) < | 525 | |
516 | BTRFS_DELAYED_BACKGROUND && | 526 | finish_one_item(delayed_root); |
517 | waitqueue_active(&delayed_root->wait)) | ||
518 | wake_up(&delayed_root->wait); | ||
519 | } | 527 | } |
520 | 528 | ||
521 | static void btrfs_release_delayed_item(struct btrfs_delayed_item *item) | 529 | static void btrfs_release_delayed_item(struct btrfs_delayed_item *item) |
@@ -875,7 +883,6 @@ static int btrfs_insert_delayed_item(struct btrfs_trans_handle *trans, | |||
875 | struct btrfs_delayed_item *delayed_item) | 883 | struct btrfs_delayed_item *delayed_item) |
876 | { | 884 | { |
877 | struct extent_buffer *leaf; | 885 | struct extent_buffer *leaf; |
878 | struct btrfs_item *item; | ||
879 | char *ptr; | 886 | char *ptr; |
880 | int ret; | 887 | int ret; |
881 | 888 | ||
@@ -886,7 +893,6 @@ static int btrfs_insert_delayed_item(struct btrfs_trans_handle *trans, | |||
886 | 893 | ||
887 | leaf = path->nodes[0]; | 894 | leaf = path->nodes[0]; |
888 | 895 | ||
889 | item = btrfs_item_nr(leaf, path->slots[0]); | ||
890 | ptr = btrfs_item_ptr(leaf, path->slots[0], char); | 896 | ptr = btrfs_item_ptr(leaf, path->slots[0], char); |
891 | 897 | ||
892 | write_extent_buffer(leaf, delayed_item->data, (unsigned long)ptr, | 898 | write_extent_buffer(leaf, delayed_item->data, (unsigned long)ptr, |
@@ -1058,39 +1064,29 @@ static void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node) | |||
1058 | delayed_node->count--; | 1064 | delayed_node->count--; |
1059 | 1065 | ||
1060 | delayed_root = delayed_node->root->fs_info->delayed_root; | 1066 | delayed_root = delayed_node->root->fs_info->delayed_root; |
1061 | if (atomic_dec_return(&delayed_root->items) < | 1067 | finish_one_item(delayed_root); |
1062 | BTRFS_DELAYED_BACKGROUND && | ||
1063 | waitqueue_active(&delayed_root->wait)) | ||
1064 | wake_up(&delayed_root->wait); | ||
1065 | } | 1068 | } |
1066 | } | 1069 | } |
1067 | 1070 | ||
1068 | static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, | 1071 | static int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, |
1069 | struct btrfs_root *root, | 1072 | struct btrfs_root *root, |
1070 | struct btrfs_path *path, | 1073 | struct btrfs_path *path, |
1071 | struct btrfs_delayed_node *node) | 1074 | struct btrfs_delayed_node *node) |
1072 | { | 1075 | { |
1073 | struct btrfs_key key; | 1076 | struct btrfs_key key; |
1074 | struct btrfs_inode_item *inode_item; | 1077 | struct btrfs_inode_item *inode_item; |
1075 | struct extent_buffer *leaf; | 1078 | struct extent_buffer *leaf; |
1076 | int ret; | 1079 | int ret; |
1077 | 1080 | ||
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; | 1081 | key.objectid = node->inode_id; |
1085 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | 1082 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); |
1086 | key.offset = 0; | 1083 | key.offset = 0; |
1084 | |||
1087 | ret = btrfs_lookup_inode(trans, root, path, &key, 1); | 1085 | ret = btrfs_lookup_inode(trans, root, path, &key, 1); |
1088 | if (ret > 0) { | 1086 | if (ret > 0) { |
1089 | btrfs_release_path(path); | 1087 | btrfs_release_path(path); |
1090 | mutex_unlock(&node->mutex); | ||
1091 | return -ENOENT; | 1088 | return -ENOENT; |
1092 | } else if (ret < 0) { | 1089 | } else if (ret < 0) { |
1093 | mutex_unlock(&node->mutex); | ||
1094 | return ret; | 1090 | return ret; |
1095 | } | 1091 | } |
1096 | 1092 | ||
@@ -1105,11 +1101,47 @@ static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, | |||
1105 | 1101 | ||
1106 | btrfs_delayed_inode_release_metadata(root, node); | 1102 | btrfs_delayed_inode_release_metadata(root, node); |
1107 | btrfs_release_delayed_inode(node); | 1103 | btrfs_release_delayed_inode(node); |
1108 | mutex_unlock(&node->mutex); | ||
1109 | 1104 | ||
1110 | return 0; | 1105 | return 0; |
1111 | } | 1106 | } |
1112 | 1107 | ||
1108 | static inline int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, | ||
1109 | struct btrfs_root *root, | ||
1110 | struct btrfs_path *path, | ||
1111 | struct btrfs_delayed_node *node) | ||
1112 | { | ||
1113 | int ret; | ||
1114 | |||
1115 | mutex_lock(&node->mutex); | ||
1116 | if (!node->inode_dirty) { | ||
1117 | mutex_unlock(&node->mutex); | ||
1118 | return 0; | ||
1119 | } | ||
1120 | |||
1121 | ret = __btrfs_update_delayed_inode(trans, root, path, node); | ||
1122 | mutex_unlock(&node->mutex); | ||
1123 | return ret; | ||
1124 | } | ||
1125 | |||
1126 | static inline int | ||
1127 | __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | ||
1128 | struct btrfs_path *path, | ||
1129 | struct btrfs_delayed_node *node) | ||
1130 | { | ||
1131 | int ret; | ||
1132 | |||
1133 | ret = btrfs_insert_delayed_items(trans, path, node->root, node); | ||
1134 | if (ret) | ||
1135 | return ret; | ||
1136 | |||
1137 | ret = btrfs_delete_delayed_items(trans, path, node->root, node); | ||
1138 | if (ret) | ||
1139 | return ret; | ||
1140 | |||
1141 | ret = btrfs_update_delayed_inode(trans, node->root, path, node); | ||
1142 | return ret; | ||
1143 | } | ||
1144 | |||
1113 | /* | 1145 | /* |
1114 | * Called when committing the transaction. | 1146 | * Called when committing the transaction. |
1115 | * Returns 0 on success. | 1147 | * Returns 0 on success. |
@@ -1119,7 +1151,6 @@ static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, | |||
1119 | static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | 1151 | static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans, |
1120 | struct btrfs_root *root, int nr) | 1152 | struct btrfs_root *root, int nr) |
1121 | { | 1153 | { |
1122 | struct btrfs_root *curr_root = root; | ||
1123 | struct btrfs_delayed_root *delayed_root; | 1154 | struct btrfs_delayed_root *delayed_root; |
1124 | struct btrfs_delayed_node *curr_node, *prev_node; | 1155 | struct btrfs_delayed_node *curr_node, *prev_node; |
1125 | struct btrfs_path *path; | 1156 | struct btrfs_path *path; |
@@ -1142,15 +1173,8 @@ static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | |||
1142 | 1173 | ||
1143 | curr_node = btrfs_first_delayed_node(delayed_root); | 1174 | curr_node = btrfs_first_delayed_node(delayed_root); |
1144 | while (curr_node && (!count || (count && nr--))) { | 1175 | while (curr_node && (!count || (count && nr--))) { |
1145 | curr_root = curr_node->root; | 1176 | ret = __btrfs_commit_inode_delayed_items(trans, path, |
1146 | ret = btrfs_insert_delayed_items(trans, path, curr_root, | 1177 | 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) { | 1178 | if (ret) { |
1155 | btrfs_release_delayed_node(curr_node); | 1179 | btrfs_release_delayed_node(curr_node); |
1156 | curr_node = NULL; | 1180 | curr_node = NULL; |
@@ -1183,51 +1207,93 @@ int btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans, | |||
1183 | return __btrfs_run_delayed_items(trans, root, nr); | 1207 | return __btrfs_run_delayed_items(trans, root, nr); |
1184 | } | 1208 | } |
1185 | 1209 | ||
1186 | static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | 1210 | int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, |
1187 | struct btrfs_delayed_node *node) | 1211 | struct inode *inode) |
1188 | { | 1212 | { |
1213 | struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode); | ||
1189 | struct btrfs_path *path; | 1214 | struct btrfs_path *path; |
1190 | struct btrfs_block_rsv *block_rsv; | 1215 | struct btrfs_block_rsv *block_rsv; |
1191 | int ret; | 1216 | int ret; |
1192 | 1217 | ||
1218 | if (!delayed_node) | ||
1219 | return 0; | ||
1220 | |||
1221 | mutex_lock(&delayed_node->mutex); | ||
1222 | if (!delayed_node->count) { | ||
1223 | mutex_unlock(&delayed_node->mutex); | ||
1224 | btrfs_release_delayed_node(delayed_node); | ||
1225 | return 0; | ||
1226 | } | ||
1227 | mutex_unlock(&delayed_node->mutex); | ||
1228 | |||
1193 | path = btrfs_alloc_path(); | 1229 | path = btrfs_alloc_path(); |
1194 | if (!path) | 1230 | if (!path) |
1195 | return -ENOMEM; | 1231 | return -ENOMEM; |
1196 | path->leave_spinning = 1; | 1232 | path->leave_spinning = 1; |
1197 | 1233 | ||
1198 | block_rsv = trans->block_rsv; | 1234 | block_rsv = trans->block_rsv; |
1199 | trans->block_rsv = &node->root->fs_info->delayed_block_rsv; | 1235 | trans->block_rsv = &delayed_node->root->fs_info->delayed_block_rsv; |
1200 | 1236 | ||
1201 | ret = btrfs_insert_delayed_items(trans, path, node->root, node); | 1237 | 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 | 1238 | ||
1239 | btrfs_release_delayed_node(delayed_node); | ||
1240 | btrfs_free_path(path); | ||
1208 | trans->block_rsv = block_rsv; | 1241 | trans->block_rsv = block_rsv; |
1242 | |||
1209 | return ret; | 1243 | return ret; |
1210 | } | 1244 | } |
1211 | 1245 | ||
1212 | int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | 1246 | int btrfs_commit_inode_delayed_inode(struct inode *inode) |
1213 | struct inode *inode) | ||
1214 | { | 1247 | { |
1248 | struct btrfs_trans_handle *trans; | ||
1215 | struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode); | 1249 | struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode); |
1250 | struct btrfs_path *path; | ||
1251 | struct btrfs_block_rsv *block_rsv; | ||
1216 | int ret; | 1252 | int ret; |
1217 | 1253 | ||
1218 | if (!delayed_node) | 1254 | if (!delayed_node) |
1219 | return 0; | 1255 | return 0; |
1220 | 1256 | ||
1221 | mutex_lock(&delayed_node->mutex); | 1257 | mutex_lock(&delayed_node->mutex); |
1222 | if (!delayed_node->count) { | 1258 | if (!delayed_node->inode_dirty) { |
1223 | mutex_unlock(&delayed_node->mutex); | 1259 | mutex_unlock(&delayed_node->mutex); |
1224 | btrfs_release_delayed_node(delayed_node); | 1260 | btrfs_release_delayed_node(delayed_node); |
1225 | return 0; | 1261 | return 0; |
1226 | } | 1262 | } |
1227 | mutex_unlock(&delayed_node->mutex); | 1263 | mutex_unlock(&delayed_node->mutex); |
1228 | 1264 | ||
1229 | ret = __btrfs_commit_inode_delayed_items(trans, delayed_node); | 1265 | trans = btrfs_join_transaction(delayed_node->root); |
1266 | if (IS_ERR(trans)) { | ||
1267 | ret = PTR_ERR(trans); | ||
1268 | goto out; | ||
1269 | } | ||
1270 | |||
1271 | path = btrfs_alloc_path(); | ||
1272 | if (!path) { | ||
1273 | ret = -ENOMEM; | ||
1274 | goto trans_out; | ||
1275 | } | ||
1276 | path->leave_spinning = 1; | ||
1277 | |||
1278 | block_rsv = trans->block_rsv; | ||
1279 | trans->block_rsv = &delayed_node->root->fs_info->delayed_block_rsv; | ||
1280 | |||
1281 | mutex_lock(&delayed_node->mutex); | ||
1282 | if (delayed_node->inode_dirty) | ||
1283 | ret = __btrfs_update_delayed_inode(trans, delayed_node->root, | ||
1284 | path, delayed_node); | ||
1285 | else | ||
1286 | ret = 0; | ||
1287 | mutex_unlock(&delayed_node->mutex); | ||
1288 | |||
1289 | btrfs_free_path(path); | ||
1290 | trans->block_rsv = block_rsv; | ||
1291 | trans_out: | ||
1292 | btrfs_end_transaction(trans, delayed_node->root); | ||
1293 | btrfs_btree_balance_dirty(delayed_node->root); | ||
1294 | out: | ||
1230 | btrfs_release_delayed_node(delayed_node); | 1295 | btrfs_release_delayed_node(delayed_node); |
1296 | |||
1231 | return ret; | 1297 | return ret; |
1232 | } | 1298 | } |
1233 | 1299 | ||
@@ -1243,48 +1309,49 @@ void btrfs_remove_delayed_node(struct inode *inode) | |||
1243 | btrfs_release_delayed_node(delayed_node); | 1309 | btrfs_release_delayed_node(delayed_node); |
1244 | } | 1310 | } |
1245 | 1311 | ||
1246 | struct btrfs_async_delayed_node { | 1312 | struct btrfs_async_delayed_work { |
1247 | struct btrfs_root *root; | 1313 | struct btrfs_delayed_root *delayed_root; |
1248 | struct btrfs_delayed_node *delayed_node; | 1314 | int nr; |
1249 | struct btrfs_work work; | 1315 | struct btrfs_work work; |
1250 | }; | 1316 | }; |
1251 | 1317 | ||
1252 | static void btrfs_async_run_delayed_node_done(struct btrfs_work *work) | 1318 | static void btrfs_async_run_delayed_root(struct btrfs_work *work) |
1253 | { | 1319 | { |
1254 | struct btrfs_async_delayed_node *async_node; | 1320 | struct btrfs_async_delayed_work *async_work; |
1321 | struct btrfs_delayed_root *delayed_root; | ||
1255 | struct btrfs_trans_handle *trans; | 1322 | struct btrfs_trans_handle *trans; |
1256 | struct btrfs_path *path; | 1323 | struct btrfs_path *path; |
1257 | struct btrfs_delayed_node *delayed_node = NULL; | 1324 | struct btrfs_delayed_node *delayed_node = NULL; |
1258 | struct btrfs_root *root; | 1325 | struct btrfs_root *root; |
1259 | struct btrfs_block_rsv *block_rsv; | 1326 | struct btrfs_block_rsv *block_rsv; |
1260 | int need_requeue = 0; | 1327 | int total_done = 0; |
1261 | int ret; | ||
1262 | 1328 | ||
1263 | async_node = container_of(work, struct btrfs_async_delayed_node, work); | 1329 | async_work = container_of(work, struct btrfs_async_delayed_work, work); |
1330 | delayed_root = async_work->delayed_root; | ||
1264 | 1331 | ||
1265 | path = btrfs_alloc_path(); | 1332 | path = btrfs_alloc_path(); |
1266 | if (!path) | 1333 | if (!path) |
1267 | goto out; | 1334 | goto out; |
1268 | path->leave_spinning = 1; | ||
1269 | 1335 | ||
1270 | delayed_node = async_node->delayed_node; | 1336 | again: |
1337 | if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND / 2) | ||
1338 | goto free_path; | ||
1339 | |||
1340 | delayed_node = btrfs_first_prepared_delayed_node(delayed_root); | ||
1341 | if (!delayed_node) | ||
1342 | goto free_path; | ||
1343 | |||
1344 | path->leave_spinning = 1; | ||
1271 | root = delayed_node->root; | 1345 | root = delayed_node->root; |
1272 | 1346 | ||
1273 | trans = btrfs_join_transaction(root); | 1347 | trans = btrfs_join_transaction(root); |
1274 | if (IS_ERR(trans)) | 1348 | if (IS_ERR(trans)) |
1275 | goto free_path; | 1349 | goto release_path; |
1276 | 1350 | ||
1277 | block_rsv = trans->block_rsv; | 1351 | block_rsv = trans->block_rsv; |
1278 | trans->block_rsv = &root->fs_info->delayed_block_rsv; | 1352 | trans->block_rsv = &root->fs_info->delayed_block_rsv; |
1279 | 1353 | ||
1280 | ret = btrfs_insert_delayed_items(trans, path, root, delayed_node); | 1354 | __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 | /* | 1355 | /* |
1289 | * Maybe new delayed items have been inserted, so we need requeue | 1356 | * Maybe new delayed items have been inserted, so we need requeue |
1290 | * the work. Besides that, we must dequeue the empty delayed nodes | 1357 | * the work. Besides that, we must dequeue the empty delayed nodes |
@@ -1310,57 +1377,47 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work) | |||
1310 | * Task1 will sleep until the transaction is commited. | 1377 | * Task1 will sleep until the transaction is commited. |
1311 | */ | 1378 | */ |
1312 | mutex_lock(&delayed_node->mutex); | 1379 | mutex_lock(&delayed_node->mutex); |
1313 | if (delayed_node->count) | 1380 | btrfs_dequeue_delayed_node(root->fs_info->delayed_root, delayed_node); |
1314 | need_requeue = 1; | ||
1315 | else | ||
1316 | btrfs_dequeue_delayed_node(root->fs_info->delayed_root, | ||
1317 | delayed_node); | ||
1318 | mutex_unlock(&delayed_node->mutex); | 1381 | mutex_unlock(&delayed_node->mutex); |
1319 | 1382 | ||
1320 | trans->block_rsv = block_rsv; | 1383 | trans->block_rsv = block_rsv; |
1321 | btrfs_end_transaction_dmeta(trans, root); | 1384 | btrfs_end_transaction_dmeta(trans, root); |
1322 | btrfs_btree_balance_dirty_nodelay(root); | 1385 | btrfs_btree_balance_dirty_nodelay(root); |
1386 | |||
1387 | release_path: | ||
1388 | btrfs_release_path(path); | ||
1389 | total_done++; | ||
1390 | |||
1391 | btrfs_release_prepared_delayed_node(delayed_node); | ||
1392 | if (async_work->nr == 0 || total_done < async_work->nr) | ||
1393 | goto again; | ||
1394 | |||
1323 | free_path: | 1395 | free_path: |
1324 | btrfs_free_path(path); | 1396 | btrfs_free_path(path); |
1325 | out: | 1397 | out: |
1326 | if (need_requeue) | 1398 | wake_up(&delayed_root->wait); |
1327 | btrfs_requeue_work(&async_node->work); | 1399 | kfree(async_work); |
1328 | else { | ||
1329 | btrfs_release_prepared_delayed_node(delayed_node); | ||
1330 | kfree(async_node); | ||
1331 | } | ||
1332 | } | 1400 | } |
1333 | 1401 | ||
1402 | |||
1334 | static int btrfs_wq_run_delayed_node(struct btrfs_delayed_root *delayed_root, | 1403 | static int btrfs_wq_run_delayed_node(struct btrfs_delayed_root *delayed_root, |
1335 | struct btrfs_root *root, int all) | 1404 | struct btrfs_root *root, int nr) |
1336 | { | 1405 | { |
1337 | struct btrfs_async_delayed_node *async_node; | 1406 | struct btrfs_async_delayed_work *async_work; |
1338 | struct btrfs_delayed_node *curr; | ||
1339 | int count = 0; | ||
1340 | 1407 | ||
1341 | again: | 1408 | if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND) |
1342 | curr = btrfs_first_prepared_delayed_node(delayed_root); | ||
1343 | if (!curr) | ||
1344 | return 0; | 1409 | return 0; |
1345 | 1410 | ||
1346 | async_node = kmalloc(sizeof(*async_node), GFP_NOFS); | 1411 | async_work = kmalloc(sizeof(*async_work), GFP_NOFS); |
1347 | if (!async_node) { | 1412 | if (!async_work) |
1348 | btrfs_release_prepared_delayed_node(curr); | ||
1349 | return -ENOMEM; | 1413 | return -ENOMEM; |
1350 | } | ||
1351 | |||
1352 | async_node->root = root; | ||
1353 | async_node->delayed_node = curr; | ||
1354 | 1414 | ||
1355 | async_node->work.func = btrfs_async_run_delayed_node_done; | 1415 | async_work->delayed_root = delayed_root; |
1356 | async_node->work.flags = 0; | 1416 | async_work->work.func = btrfs_async_run_delayed_root; |
1357 | 1417 | async_work->work.flags = 0; | |
1358 | btrfs_queue_worker(&root->fs_info->delayed_workers, &async_node->work); | 1418 | async_work->nr = nr; |
1359 | count++; | ||
1360 | |||
1361 | if (all || count < 4) | ||
1362 | goto again; | ||
1363 | 1419 | ||
1420 | btrfs_queue_worker(&root->fs_info->delayed_workers, &async_work->work); | ||
1364 | return 0; | 1421 | return 0; |
1365 | } | 1422 | } |
1366 | 1423 | ||
@@ -1371,30 +1428,55 @@ void btrfs_assert_delayed_root_empty(struct btrfs_root *root) | |||
1371 | WARN_ON(btrfs_first_delayed_node(delayed_root)); | 1428 | WARN_ON(btrfs_first_delayed_node(delayed_root)); |
1372 | } | 1429 | } |
1373 | 1430 | ||
1431 | static int refs_newer(struct btrfs_delayed_root *delayed_root, | ||
1432 | int seq, int count) | ||
1433 | { | ||
1434 | int val = atomic_read(&delayed_root->items_seq); | ||
1435 | |||
1436 | if (val < seq || val >= seq + count) | ||
1437 | return 1; | ||
1438 | return 0; | ||
1439 | } | ||
1440 | |||
1374 | void btrfs_balance_delayed_items(struct btrfs_root *root) | 1441 | void btrfs_balance_delayed_items(struct btrfs_root *root) |
1375 | { | 1442 | { |
1376 | struct btrfs_delayed_root *delayed_root; | 1443 | struct btrfs_delayed_root *delayed_root; |
1444 | int seq; | ||
1377 | 1445 | ||
1378 | delayed_root = btrfs_get_delayed_root(root); | 1446 | delayed_root = btrfs_get_delayed_root(root); |
1379 | 1447 | ||
1380 | if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND) | 1448 | if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND) |
1381 | return; | 1449 | return; |
1382 | 1450 | ||
1451 | seq = atomic_read(&delayed_root->items_seq); | ||
1452 | |||
1383 | if (atomic_read(&delayed_root->items) >= BTRFS_DELAYED_WRITEBACK) { | 1453 | if (atomic_read(&delayed_root->items) >= BTRFS_DELAYED_WRITEBACK) { |
1384 | int ret; | 1454 | int ret; |
1385 | ret = btrfs_wq_run_delayed_node(delayed_root, root, 1); | 1455 | DEFINE_WAIT(__wait); |
1456 | |||
1457 | ret = btrfs_wq_run_delayed_node(delayed_root, root, 0); | ||
1386 | if (ret) | 1458 | if (ret) |
1387 | return; | 1459 | return; |
1388 | 1460 | ||
1389 | wait_event_interruptible_timeout( | 1461 | while (1) { |
1390 | delayed_root->wait, | 1462 | prepare_to_wait(&delayed_root->wait, &__wait, |
1391 | (atomic_read(&delayed_root->items) < | 1463 | TASK_INTERRUPTIBLE); |
1392 | BTRFS_DELAYED_BACKGROUND), | 1464 | |
1393 | HZ); | 1465 | if (refs_newer(delayed_root, seq, |
1394 | return; | 1466 | BTRFS_DELAYED_BATCH) || |
1467 | atomic_read(&delayed_root->items) < | ||
1468 | BTRFS_DELAYED_BACKGROUND) { | ||
1469 | break; | ||
1470 | } | ||
1471 | if (!signal_pending(current)) | ||
1472 | schedule(); | ||
1473 | else | ||
1474 | break; | ||
1475 | } | ||
1476 | finish_wait(&delayed_root->wait, &__wait); | ||
1395 | } | 1477 | } |
1396 | 1478 | ||
1397 | btrfs_wq_run_delayed_node(delayed_root, root, 0); | 1479 | btrfs_wq_run_delayed_node(delayed_root, root, BTRFS_DELAYED_BATCH); |
1398 | } | 1480 | } |
1399 | 1481 | ||
1400 | /* Will return 0 or -ENOMEM */ | 1482 | /* Will return 0 or -ENOMEM */ |