diff options
Diffstat (limited to 'fs/nilfs2/segment.c')
-rw-r--r-- | fs/nilfs2/segment.c | 491 |
1 files changed, 243 insertions, 248 deletions
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 6eff66a070d5..69576a95e13f 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -141,7 +141,7 @@ int nilfs_init_transaction_cache(void) | |||
141 | } | 141 | } |
142 | 142 | ||
143 | /** | 143 | /** |
144 | * nilfs_detroy_transaction_cache - destroy the cache for transaction info | 144 | * nilfs_destroy_transaction_cache - destroy the cache for transaction info |
145 | * | 145 | * |
146 | * nilfs_destroy_transaction_cache() frees the slab cache for the struct | 146 | * nilfs_destroy_transaction_cache() frees the slab cache for the struct |
147 | * nilfs_transaction_info. | 147 | * nilfs_transaction_info. |
@@ -201,7 +201,7 @@ static int nilfs_prepare_segment_lock(struct nilfs_transaction_info *ti) | |||
201 | * This function allocates a nilfs_transaction_info struct to keep context | 201 | * This function allocates a nilfs_transaction_info struct to keep context |
202 | * information on it. It is initialized and hooked onto the current task in | 202 | * information on it. It is initialized and hooked onto the current task in |
203 | * the outermost call. If a pre-allocated struct is given to @ti, it is used | 203 | * the outermost call. If a pre-allocated struct is given to @ti, it is used |
204 | * instead; othewise a new struct is assigned from a slab. | 204 | * instead; otherwise a new struct is assigned from a slab. |
205 | * | 205 | * |
206 | * When @vacancy_check flag is set, this function will check the amount of | 206 | * When @vacancy_check flag is set, this function will check the amount of |
207 | * free space, and will wait for the GC to reclaim disk space if low capacity. | 207 | * free space, and will wait for the GC to reclaim disk space if low capacity. |
@@ -974,12 +974,12 @@ static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci, | |||
974 | nilfs->ns_nongc_ctime : sci->sc_seg_ctime); | 974 | nilfs->ns_nongc_ctime : sci->sc_seg_ctime); |
975 | raw_sr->sr_flags = 0; | 975 | raw_sr->sr_flags = 0; |
976 | 976 | ||
977 | nilfs_mdt_write_inode_direct( | 977 | nilfs_write_inode_common(nilfs_dat_inode(nilfs), (void *)raw_sr + |
978 | nilfs_dat_inode(nilfs), bh_sr, NILFS_SR_DAT_OFFSET(isz)); | 978 | NILFS_SR_DAT_OFFSET(isz), 1); |
979 | nilfs_mdt_write_inode_direct( | 979 | nilfs_write_inode_common(nilfs->ns_cpfile, (void *)raw_sr + |
980 | nilfs->ns_cpfile, bh_sr, NILFS_SR_CPFILE_OFFSET(isz)); | 980 | NILFS_SR_CPFILE_OFFSET(isz), 1); |
981 | nilfs_mdt_write_inode_direct( | 981 | nilfs_write_inode_common(nilfs->ns_sufile, (void *)raw_sr + |
982 | nilfs->ns_sufile, bh_sr, NILFS_SR_SUFILE_OFFSET(isz)); | 982 | NILFS_SR_SUFILE_OFFSET(isz), 1); |
983 | } | 983 | } |
984 | 984 | ||
985 | static void nilfs_redirty_inodes(struct list_head *head) | 985 | static void nilfs_redirty_inodes(struct list_head *head) |
@@ -1273,73 +1273,75 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode) | |||
1273 | return err; | 1273 | return err; |
1274 | } | 1274 | } |
1275 | 1275 | ||
1276 | static int nilfs_touch_segusage(struct inode *sufile, __u64 segnum) | 1276 | /** |
1277 | { | 1277 | * nilfs_segctor_begin_construction - setup segment buffer to make a new log |
1278 | struct buffer_head *bh_su; | 1278 | * @sci: nilfs_sc_info |
1279 | struct nilfs_segment_usage *raw_su; | 1279 | * @nilfs: nilfs object |
1280 | int err; | 1280 | */ |
1281 | |||
1282 | err = nilfs_sufile_get_segment_usage(sufile, segnum, &raw_su, &bh_su); | ||
1283 | if (unlikely(err)) | ||
1284 | return err; | ||
1285 | nilfs_mdt_mark_buffer_dirty(bh_su); | ||
1286 | nilfs_mdt_mark_dirty(sufile); | ||
1287 | nilfs_sufile_put_segment_usage(sufile, segnum, bh_su); | ||
1288 | return 0; | ||
1289 | } | ||
1290 | |||
1291 | static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci, | 1281 | static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci, |
1292 | struct the_nilfs *nilfs) | 1282 | struct the_nilfs *nilfs) |
1293 | { | 1283 | { |
1294 | struct nilfs_segment_buffer *segbuf, *n; | 1284 | struct nilfs_segment_buffer *segbuf, *prev; |
1295 | __u64 nextnum; | 1285 | __u64 nextnum; |
1296 | int err; | 1286 | int err, alloc = 0; |
1297 | 1287 | ||
1298 | if (list_empty(&sci->sc_segbufs)) { | 1288 | segbuf = nilfs_segbuf_new(sci->sc_super); |
1299 | segbuf = nilfs_segbuf_new(sci->sc_super); | 1289 | if (unlikely(!segbuf)) |
1300 | if (unlikely(!segbuf)) | 1290 | return -ENOMEM; |
1301 | return -ENOMEM; | ||
1302 | list_add(&segbuf->sb_list, &sci->sc_segbufs); | ||
1303 | } else | ||
1304 | segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs); | ||
1305 | 1291 | ||
1306 | nilfs_segbuf_map(segbuf, nilfs->ns_segnum, nilfs->ns_pseg_offset, | 1292 | if (list_empty(&sci->sc_write_logs)) { |
1307 | nilfs); | 1293 | nilfs_segbuf_map(segbuf, nilfs->ns_segnum, |
1294 | nilfs->ns_pseg_offset, nilfs); | ||
1295 | if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) { | ||
1296 | nilfs_shift_to_next_segment(nilfs); | ||
1297 | nilfs_segbuf_map(segbuf, nilfs->ns_segnum, 0, nilfs); | ||
1298 | } | ||
1308 | 1299 | ||
1309 | if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) { | 1300 | segbuf->sb_sum.seg_seq = nilfs->ns_seg_seq; |
1310 | nilfs_shift_to_next_segment(nilfs); | 1301 | nextnum = nilfs->ns_nextnum; |
1311 | nilfs_segbuf_map(segbuf, nilfs->ns_segnum, 0, nilfs); | 1302 | |
1303 | if (nilfs->ns_segnum == nilfs->ns_nextnum) | ||
1304 | /* Start from the head of a new full segment */ | ||
1305 | alloc++; | ||
1306 | } else { | ||
1307 | /* Continue logs */ | ||
1308 | prev = NILFS_LAST_SEGBUF(&sci->sc_write_logs); | ||
1309 | nilfs_segbuf_map_cont(segbuf, prev); | ||
1310 | segbuf->sb_sum.seg_seq = prev->sb_sum.seg_seq; | ||
1311 | nextnum = prev->sb_nextnum; | ||
1312 | |||
1313 | if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) { | ||
1314 | nilfs_segbuf_map(segbuf, prev->sb_nextnum, 0, nilfs); | ||
1315 | segbuf->sb_sum.seg_seq++; | ||
1316 | alloc++; | ||
1317 | } | ||
1312 | } | 1318 | } |
1313 | sci->sc_segbuf_nblocks = segbuf->sb_rest_blocks; | ||
1314 | 1319 | ||
1315 | err = nilfs_touch_segusage(nilfs->ns_sufile, segbuf->sb_segnum); | 1320 | err = nilfs_sufile_mark_dirty(nilfs->ns_sufile, segbuf->sb_segnum); |
1316 | if (unlikely(err)) | 1321 | if (err) |
1317 | return err; | 1322 | goto failed; |
1318 | 1323 | ||
1319 | if (nilfs->ns_segnum == nilfs->ns_nextnum) { | 1324 | if (alloc) { |
1320 | /* Start from the head of a new full segment */ | ||
1321 | err = nilfs_sufile_alloc(nilfs->ns_sufile, &nextnum); | 1325 | err = nilfs_sufile_alloc(nilfs->ns_sufile, &nextnum); |
1322 | if (unlikely(err)) | 1326 | if (err) |
1323 | return err; | 1327 | goto failed; |
1324 | } else | 1328 | } |
1325 | nextnum = nilfs->ns_nextnum; | ||
1326 | |||
1327 | segbuf->sb_sum.seg_seq = nilfs->ns_seg_seq; | ||
1328 | nilfs_segbuf_set_next_segnum(segbuf, nextnum, nilfs); | 1329 | nilfs_segbuf_set_next_segnum(segbuf, nextnum, nilfs); |
1329 | 1330 | ||
1330 | /* truncating segment buffers */ | 1331 | BUG_ON(!list_empty(&sci->sc_segbufs)); |
1331 | list_for_each_entry_safe_continue(segbuf, n, &sci->sc_segbufs, | 1332 | list_add_tail(&segbuf->sb_list, &sci->sc_segbufs); |
1332 | sb_list) { | 1333 | sci->sc_segbuf_nblocks = segbuf->sb_rest_blocks; |
1333 | list_del_init(&segbuf->sb_list); | ||
1334 | nilfs_segbuf_free(segbuf); | ||
1335 | } | ||
1336 | return 0; | 1334 | return 0; |
1335 | |||
1336 | failed: | ||
1337 | nilfs_segbuf_free(segbuf); | ||
1338 | return err; | ||
1337 | } | 1339 | } |
1338 | 1340 | ||
1339 | static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci, | 1341 | static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci, |
1340 | struct the_nilfs *nilfs, int nadd) | 1342 | struct the_nilfs *nilfs, int nadd) |
1341 | { | 1343 | { |
1342 | struct nilfs_segment_buffer *segbuf, *prev, *n; | 1344 | struct nilfs_segment_buffer *segbuf, *prev; |
1343 | struct inode *sufile = nilfs->ns_sufile; | 1345 | struct inode *sufile = nilfs->ns_sufile; |
1344 | __u64 nextnextnum; | 1346 | __u64 nextnextnum; |
1345 | LIST_HEAD(list); | 1347 | LIST_HEAD(list); |
@@ -1352,7 +1354,7 @@ static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci, | |||
1352 | * not be dirty. The following call ensures that the buffer is dirty | 1354 | * not be dirty. The following call ensures that the buffer is dirty |
1353 | * and will pin the buffer on memory until the sufile is written. | 1355 | * and will pin the buffer on memory until the sufile is written. |
1354 | */ | 1356 | */ |
1355 | err = nilfs_touch_segusage(sufile, prev->sb_nextnum); | 1357 | err = nilfs_sufile_mark_dirty(sufile, prev->sb_nextnum); |
1356 | if (unlikely(err)) | 1358 | if (unlikely(err)) |
1357 | return err; | 1359 | return err; |
1358 | 1360 | ||
@@ -1378,33 +1380,33 @@ static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci, | |||
1378 | list_add_tail(&segbuf->sb_list, &list); | 1380 | list_add_tail(&segbuf->sb_list, &list); |
1379 | prev = segbuf; | 1381 | prev = segbuf; |
1380 | } | 1382 | } |
1381 | list_splice(&list, sci->sc_segbufs.prev); | 1383 | list_splice_tail(&list, &sci->sc_segbufs); |
1382 | return 0; | 1384 | return 0; |
1383 | 1385 | ||
1384 | failed_segbuf: | 1386 | failed_segbuf: |
1385 | nilfs_segbuf_free(segbuf); | 1387 | nilfs_segbuf_free(segbuf); |
1386 | failed: | 1388 | failed: |
1387 | list_for_each_entry_safe(segbuf, n, &list, sb_list) { | 1389 | list_for_each_entry(segbuf, &list, sb_list) { |
1388 | ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum); | 1390 | ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum); |
1389 | WARN_ON(ret); /* never fails */ | 1391 | WARN_ON(ret); /* never fails */ |
1390 | list_del_init(&segbuf->sb_list); | ||
1391 | nilfs_segbuf_free(segbuf); | ||
1392 | } | 1392 | } |
1393 | nilfs_destroy_logs(&list); | ||
1393 | return err; | 1394 | return err; |
1394 | } | 1395 | } |
1395 | 1396 | ||
1396 | static void nilfs_segctor_free_incomplete_segments(struct nilfs_sc_info *sci, | 1397 | static void nilfs_free_incomplete_logs(struct list_head *logs, |
1397 | struct the_nilfs *nilfs) | 1398 | struct the_nilfs *nilfs) |
1398 | { | 1399 | { |
1399 | struct nilfs_segment_buffer *segbuf; | 1400 | struct nilfs_segment_buffer *segbuf, *prev; |
1400 | int ret, done = 0; | 1401 | struct inode *sufile = nilfs->ns_sufile; |
1402 | int ret; | ||
1401 | 1403 | ||
1402 | segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs); | 1404 | segbuf = NILFS_FIRST_SEGBUF(logs); |
1403 | if (nilfs->ns_nextnum != segbuf->sb_nextnum) { | 1405 | if (nilfs->ns_nextnum != segbuf->sb_nextnum) { |
1404 | ret = nilfs_sufile_free(nilfs->ns_sufile, segbuf->sb_nextnum); | 1406 | ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum); |
1405 | WARN_ON(ret); /* never fails */ | 1407 | WARN_ON(ret); /* never fails */ |
1406 | } | 1408 | } |
1407 | if (segbuf->sb_io_error) { | 1409 | if (atomic_read(&segbuf->sb_err)) { |
1408 | /* Case 1: The first segment failed */ | 1410 | /* Case 1: The first segment failed */ |
1409 | if (segbuf->sb_pseg_start != segbuf->sb_fseg_start) | 1411 | if (segbuf->sb_pseg_start != segbuf->sb_fseg_start) |
1410 | /* Case 1a: Partial segment appended into an existing | 1412 | /* Case 1a: Partial segment appended into an existing |
@@ -1413,106 +1415,54 @@ static void nilfs_segctor_free_incomplete_segments(struct nilfs_sc_info *sci, | |||
1413 | segbuf->sb_fseg_end); | 1415 | segbuf->sb_fseg_end); |
1414 | else /* Case 1b: New full segment */ | 1416 | else /* Case 1b: New full segment */ |
1415 | set_nilfs_discontinued(nilfs); | 1417 | set_nilfs_discontinued(nilfs); |
1416 | done++; | ||
1417 | } | ||
1418 | |||
1419 | list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) { | ||
1420 | ret = nilfs_sufile_free(nilfs->ns_sufile, segbuf->sb_nextnum); | ||
1421 | WARN_ON(ret); /* never fails */ | ||
1422 | if (!done && segbuf->sb_io_error) { | ||
1423 | if (segbuf->sb_segnum != nilfs->ns_nextnum) | ||
1424 | /* Case 2: extended segment (!= next) failed */ | ||
1425 | nilfs_sufile_set_error(nilfs->ns_sufile, | ||
1426 | segbuf->sb_segnum); | ||
1427 | done++; | ||
1428 | } | ||
1429 | } | ||
1430 | } | ||
1431 | |||
1432 | static void nilfs_segctor_clear_segment_buffers(struct nilfs_sc_info *sci) | ||
1433 | { | ||
1434 | struct nilfs_segment_buffer *segbuf; | ||
1435 | |||
1436 | list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) | ||
1437 | nilfs_segbuf_clear(segbuf); | ||
1438 | sci->sc_super_root = NULL; | ||
1439 | } | ||
1440 | |||
1441 | static void nilfs_segctor_destroy_segment_buffers(struct nilfs_sc_info *sci) | ||
1442 | { | ||
1443 | struct nilfs_segment_buffer *segbuf; | ||
1444 | |||
1445 | while (!list_empty(&sci->sc_segbufs)) { | ||
1446 | segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs); | ||
1447 | list_del_init(&segbuf->sb_list); | ||
1448 | nilfs_segbuf_free(segbuf); | ||
1449 | } | 1418 | } |
1450 | /* sci->sc_curseg = NULL; */ | ||
1451 | } | ||
1452 | |||
1453 | static void nilfs_segctor_end_construction(struct nilfs_sc_info *sci, | ||
1454 | struct the_nilfs *nilfs, int err) | ||
1455 | { | ||
1456 | if (unlikely(err)) { | ||
1457 | nilfs_segctor_free_incomplete_segments(sci, nilfs); | ||
1458 | if (sci->sc_stage.flags & NILFS_CF_SUFREED) { | ||
1459 | int ret; | ||
1460 | 1419 | ||
1461 | ret = nilfs_sufile_cancel_freev(nilfs->ns_sufile, | 1420 | prev = segbuf; |
1462 | sci->sc_freesegs, | 1421 | list_for_each_entry_continue(segbuf, logs, sb_list) { |
1463 | sci->sc_nfreesegs, | 1422 | if (prev->sb_nextnum != segbuf->sb_nextnum) { |
1464 | NULL); | 1423 | ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum); |
1465 | WARN_ON(ret); /* do not happen */ | 1424 | WARN_ON(ret); /* never fails */ |
1466 | } | 1425 | } |
1426 | if (atomic_read(&segbuf->sb_err) && | ||
1427 | segbuf->sb_segnum != nilfs->ns_nextnum) | ||
1428 | /* Case 2: extended segment (!= next) failed */ | ||
1429 | nilfs_sufile_set_error(sufile, segbuf->sb_segnum); | ||
1430 | prev = segbuf; | ||
1467 | } | 1431 | } |
1468 | nilfs_segctor_clear_segment_buffers(sci); | ||
1469 | } | 1432 | } |
1470 | 1433 | ||
1471 | static void nilfs_segctor_update_segusage(struct nilfs_sc_info *sci, | 1434 | static void nilfs_segctor_update_segusage(struct nilfs_sc_info *sci, |
1472 | struct inode *sufile) | 1435 | struct inode *sufile) |
1473 | { | 1436 | { |
1474 | struct nilfs_segment_buffer *segbuf; | 1437 | struct nilfs_segment_buffer *segbuf; |
1475 | struct buffer_head *bh_su; | ||
1476 | struct nilfs_segment_usage *raw_su; | ||
1477 | unsigned long live_blocks; | 1438 | unsigned long live_blocks; |
1478 | int ret; | 1439 | int ret; |
1479 | 1440 | ||
1480 | list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { | 1441 | list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { |
1481 | ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum, | ||
1482 | &raw_su, &bh_su); | ||
1483 | WARN_ON(ret); /* always succeed because bh_su is dirty */ | ||
1484 | live_blocks = segbuf->sb_sum.nblocks + | 1442 | live_blocks = segbuf->sb_sum.nblocks + |
1485 | (segbuf->sb_pseg_start - segbuf->sb_fseg_start); | 1443 | (segbuf->sb_pseg_start - segbuf->sb_fseg_start); |
1486 | raw_su->su_lastmod = cpu_to_le64(sci->sc_seg_ctime); | 1444 | ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum, |
1487 | raw_su->su_nblocks = cpu_to_le32(live_blocks); | 1445 | live_blocks, |
1488 | nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum, | 1446 | sci->sc_seg_ctime); |
1489 | bh_su); | 1447 | WARN_ON(ret); /* always succeed because the segusage is dirty */ |
1490 | } | 1448 | } |
1491 | } | 1449 | } |
1492 | 1450 | ||
1493 | static void nilfs_segctor_cancel_segusage(struct nilfs_sc_info *sci, | 1451 | static void nilfs_cancel_segusage(struct list_head *logs, struct inode *sufile) |
1494 | struct inode *sufile) | ||
1495 | { | 1452 | { |
1496 | struct nilfs_segment_buffer *segbuf; | 1453 | struct nilfs_segment_buffer *segbuf; |
1497 | struct buffer_head *bh_su; | ||
1498 | struct nilfs_segment_usage *raw_su; | ||
1499 | int ret; | 1454 | int ret; |
1500 | 1455 | ||
1501 | segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs); | 1456 | segbuf = NILFS_FIRST_SEGBUF(logs); |
1502 | ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum, | 1457 | ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum, |
1503 | &raw_su, &bh_su); | 1458 | segbuf->sb_pseg_start - |
1504 | WARN_ON(ret); /* always succeed because bh_su is dirty */ | 1459 | segbuf->sb_fseg_start, 0); |
1505 | raw_su->su_nblocks = cpu_to_le32(segbuf->sb_pseg_start - | 1460 | WARN_ON(ret); /* always succeed because the segusage is dirty */ |
1506 | segbuf->sb_fseg_start); | ||
1507 | nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum, bh_su); | ||
1508 | 1461 | ||
1509 | list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) { | 1462 | list_for_each_entry_continue(segbuf, logs, sb_list) { |
1510 | ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum, | 1463 | ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum, |
1511 | &raw_su, &bh_su); | 1464 | 0, 0); |
1512 | WARN_ON(ret); /* always succeed */ | 1465 | WARN_ON(ret); /* always succeed */ |
1513 | raw_su->su_nblocks = 0; | ||
1514 | nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum, | ||
1515 | bh_su); | ||
1516 | } | 1466 | } |
1517 | } | 1467 | } |
1518 | 1468 | ||
@@ -1520,17 +1470,15 @@ static void nilfs_segctor_truncate_segments(struct nilfs_sc_info *sci, | |||
1520 | struct nilfs_segment_buffer *last, | 1470 | struct nilfs_segment_buffer *last, |
1521 | struct inode *sufile) | 1471 | struct inode *sufile) |
1522 | { | 1472 | { |
1523 | struct nilfs_segment_buffer *segbuf = last, *n; | 1473 | struct nilfs_segment_buffer *segbuf = last; |
1524 | int ret; | 1474 | int ret; |
1525 | 1475 | ||
1526 | list_for_each_entry_safe_continue(segbuf, n, &sci->sc_segbufs, | 1476 | list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) { |
1527 | sb_list) { | ||
1528 | list_del_init(&segbuf->sb_list); | ||
1529 | sci->sc_segbuf_nblocks -= segbuf->sb_rest_blocks; | 1477 | sci->sc_segbuf_nblocks -= segbuf->sb_rest_blocks; |
1530 | ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum); | 1478 | ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum); |
1531 | WARN_ON(ret); | 1479 | WARN_ON(ret); |
1532 | nilfs_segbuf_free(segbuf); | ||
1533 | } | 1480 | } |
1481 | nilfs_truncate_logs(&sci->sc_segbufs, last); | ||
1534 | } | 1482 | } |
1535 | 1483 | ||
1536 | 1484 | ||
@@ -1569,7 +1517,7 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci, | |||
1569 | NULL); | 1517 | NULL); |
1570 | WARN_ON(err); /* do not happen */ | 1518 | WARN_ON(err); /* do not happen */ |
1571 | } | 1519 | } |
1572 | nilfs_segctor_clear_segment_buffers(sci); | 1520 | nilfs_clear_logs(&sci->sc_segbufs); |
1573 | 1521 | ||
1574 | err = nilfs_segctor_extend_segments(sci, nilfs, nadd); | 1522 | err = nilfs_segctor_extend_segments(sci, nilfs, nadd); |
1575 | if (unlikely(err)) | 1523 | if (unlikely(err)) |
@@ -1814,26 +1762,13 @@ static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci, | |||
1814 | } | 1762 | } |
1815 | 1763 | ||
1816 | static int nilfs_segctor_write(struct nilfs_sc_info *sci, | 1764 | static int nilfs_segctor_write(struct nilfs_sc_info *sci, |
1817 | struct backing_dev_info *bdi) | 1765 | struct the_nilfs *nilfs) |
1818 | { | 1766 | { |
1819 | struct nilfs_segment_buffer *segbuf; | 1767 | int ret; |
1820 | struct nilfs_write_info wi; | ||
1821 | int err, res; | ||
1822 | |||
1823 | wi.sb = sci->sc_super; | ||
1824 | wi.bh_sr = sci->sc_super_root; | ||
1825 | wi.bdi = bdi; | ||
1826 | |||
1827 | list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { | ||
1828 | nilfs_segbuf_prepare_write(segbuf, &wi); | ||
1829 | err = nilfs_segbuf_write(segbuf, &wi); | ||
1830 | 1768 | ||
1831 | res = nilfs_segbuf_wait(segbuf, &wi); | 1769 | ret = nilfs_write_logs(&sci->sc_segbufs, nilfs); |
1832 | err = err ? : res; | 1770 | list_splice_tail_init(&sci->sc_segbufs, &sci->sc_write_logs); |
1833 | if (err) | 1771 | return ret; |
1834 | return err; | ||
1835 | } | ||
1836 | return 0; | ||
1837 | } | 1772 | } |
1838 | 1773 | ||
1839 | static void __nilfs_end_page_io(struct page *page, int err) | 1774 | static void __nilfs_end_page_io(struct page *page, int err) |
@@ -1911,15 +1846,17 @@ static void nilfs_clear_copied_buffers(struct list_head *list, int err) | |||
1911 | } | 1846 | } |
1912 | } | 1847 | } |
1913 | 1848 | ||
1914 | static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci, | 1849 | static void nilfs_abort_logs(struct list_head *logs, struct page *failed_page, |
1915 | struct page *failed_page, int err) | 1850 | struct buffer_head *bh_sr, int err) |
1916 | { | 1851 | { |
1917 | struct nilfs_segment_buffer *segbuf; | 1852 | struct nilfs_segment_buffer *segbuf; |
1918 | struct page *bd_page = NULL, *fs_page = NULL; | 1853 | struct page *bd_page = NULL, *fs_page = NULL; |
1854 | struct buffer_head *bh; | ||
1919 | 1855 | ||
1920 | list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { | 1856 | if (list_empty(logs)) |
1921 | struct buffer_head *bh; | 1857 | return; |
1922 | 1858 | ||
1859 | list_for_each_entry(segbuf, logs, sb_list) { | ||
1923 | list_for_each_entry(bh, &segbuf->sb_segsum_buffers, | 1860 | list_for_each_entry(bh, &segbuf->sb_segsum_buffers, |
1924 | b_assoc_buffers) { | 1861 | b_assoc_buffers) { |
1925 | if (bh->b_page != bd_page) { | 1862 | if (bh->b_page != bd_page) { |
@@ -1931,7 +1868,7 @@ static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci, | |||
1931 | 1868 | ||
1932 | list_for_each_entry(bh, &segbuf->sb_payload_buffers, | 1869 | list_for_each_entry(bh, &segbuf->sb_payload_buffers, |
1933 | b_assoc_buffers) { | 1870 | b_assoc_buffers) { |
1934 | if (bh == sci->sc_super_root) { | 1871 | if (bh == bh_sr) { |
1935 | if (bh->b_page != bd_page) { | 1872 | if (bh->b_page != bd_page) { |
1936 | end_page_writeback(bd_page); | 1873 | end_page_writeback(bd_page); |
1937 | bd_page = bh->b_page; | 1874 | bd_page = bh->b_page; |
@@ -1941,7 +1878,7 @@ static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci, | |||
1941 | if (bh->b_page != fs_page) { | 1878 | if (bh->b_page != fs_page) { |
1942 | nilfs_end_page_io(fs_page, err); | 1879 | nilfs_end_page_io(fs_page, err); |
1943 | if (fs_page && fs_page == failed_page) | 1880 | if (fs_page && fs_page == failed_page) |
1944 | goto done; | 1881 | return; |
1945 | fs_page = bh->b_page; | 1882 | fs_page = bh->b_page; |
1946 | } | 1883 | } |
1947 | } | 1884 | } |
@@ -1950,8 +1887,34 @@ static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci, | |||
1950 | end_page_writeback(bd_page); | 1887 | end_page_writeback(bd_page); |
1951 | 1888 | ||
1952 | nilfs_end_page_io(fs_page, err); | 1889 | nilfs_end_page_io(fs_page, err); |
1953 | done: | 1890 | } |
1891 | |||
1892 | static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci, | ||
1893 | struct the_nilfs *nilfs, int err) | ||
1894 | { | ||
1895 | LIST_HEAD(logs); | ||
1896 | int ret; | ||
1897 | |||
1898 | list_splice_tail_init(&sci->sc_write_logs, &logs); | ||
1899 | ret = nilfs_wait_on_logs(&logs); | ||
1900 | if (ret) | ||
1901 | nilfs_abort_logs(&logs, NULL, sci->sc_super_root, ret); | ||
1902 | |||
1903 | list_splice_tail_init(&sci->sc_segbufs, &logs); | ||
1904 | nilfs_cancel_segusage(&logs, nilfs->ns_sufile); | ||
1905 | nilfs_free_incomplete_logs(&logs, nilfs); | ||
1954 | nilfs_clear_copied_buffers(&sci->sc_copied_buffers, err); | 1906 | nilfs_clear_copied_buffers(&sci->sc_copied_buffers, err); |
1907 | |||
1908 | if (sci->sc_stage.flags & NILFS_CF_SUFREED) { | ||
1909 | ret = nilfs_sufile_cancel_freev(nilfs->ns_sufile, | ||
1910 | sci->sc_freesegs, | ||
1911 | sci->sc_nfreesegs, | ||
1912 | NULL); | ||
1913 | WARN_ON(ret); /* do not happen */ | ||
1914 | } | ||
1915 | |||
1916 | nilfs_destroy_logs(&logs); | ||
1917 | sci->sc_super_root = NULL; | ||
1955 | } | 1918 | } |
1956 | 1919 | ||
1957 | static void nilfs_set_next_segment(struct the_nilfs *nilfs, | 1920 | static void nilfs_set_next_segment(struct the_nilfs *nilfs, |
@@ -1969,11 +1932,10 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) | |||
1969 | { | 1932 | { |
1970 | struct nilfs_segment_buffer *segbuf; | 1933 | struct nilfs_segment_buffer *segbuf; |
1971 | struct page *bd_page = NULL, *fs_page = NULL; | 1934 | struct page *bd_page = NULL, *fs_page = NULL; |
1972 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 1935 | struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs; |
1973 | struct the_nilfs *nilfs = sbi->s_nilfs; | ||
1974 | int update_sr = (sci->sc_super_root != NULL); | 1936 | int update_sr = (sci->sc_super_root != NULL); |
1975 | 1937 | ||
1976 | list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { | 1938 | list_for_each_entry(segbuf, &sci->sc_write_logs, sb_list) { |
1977 | struct buffer_head *bh; | 1939 | struct buffer_head *bh; |
1978 | 1940 | ||
1979 | list_for_each_entry(bh, &segbuf->sb_segsum_buffers, | 1941 | list_for_each_entry(bh, &segbuf->sb_segsum_buffers, |
@@ -2046,21 +2008,34 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) | |||
2046 | 2008 | ||
2047 | sci->sc_nblk_inc += sci->sc_nblk_this_inc; | 2009 | sci->sc_nblk_inc += sci->sc_nblk_this_inc; |
2048 | 2010 | ||
2049 | segbuf = NILFS_LAST_SEGBUF(&sci->sc_segbufs); | 2011 | segbuf = NILFS_LAST_SEGBUF(&sci->sc_write_logs); |
2050 | nilfs_set_next_segment(nilfs, segbuf); | 2012 | nilfs_set_next_segment(nilfs, segbuf); |
2051 | 2013 | ||
2052 | if (update_sr) { | 2014 | if (update_sr) { |
2053 | nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start, | 2015 | nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start, |
2054 | segbuf->sb_sum.seg_seq, nilfs->ns_cno++); | 2016 | segbuf->sb_sum.seg_seq, nilfs->ns_cno++); |
2055 | sbi->s_super->s_dirt = 1; | 2017 | set_nilfs_sb_dirty(nilfs); |
2056 | 2018 | ||
2057 | clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags); | 2019 | clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags); |
2058 | clear_bit(NILFS_SC_DIRTY, &sci->sc_flags); | 2020 | clear_bit(NILFS_SC_DIRTY, &sci->sc_flags); |
2059 | set_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags); | 2021 | set_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags); |
2022 | nilfs_segctor_clear_metadata_dirty(sci); | ||
2060 | } else | 2023 | } else |
2061 | clear_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags); | 2024 | clear_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags); |
2062 | } | 2025 | } |
2063 | 2026 | ||
2027 | static int nilfs_segctor_wait(struct nilfs_sc_info *sci) | ||
2028 | { | ||
2029 | int ret; | ||
2030 | |||
2031 | ret = nilfs_wait_on_logs(&sci->sc_write_logs); | ||
2032 | if (!ret) { | ||
2033 | nilfs_segctor_complete_write(sci); | ||
2034 | nilfs_destroy_logs(&sci->sc_write_logs); | ||
2035 | } | ||
2036 | return ret; | ||
2037 | } | ||
2038 | |||
2064 | static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci, | 2039 | static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci, |
2065 | struct nilfs_sb_info *sbi) | 2040 | struct nilfs_sb_info *sbi) |
2066 | { | 2041 | { |
@@ -2173,7 +2148,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | |||
2173 | /* Avoid empty segment */ | 2148 | /* Avoid empty segment */ |
2174 | if (sci->sc_stage.scnt == NILFS_ST_DONE && | 2149 | if (sci->sc_stage.scnt == NILFS_ST_DONE && |
2175 | NILFS_SEG_EMPTY(&sci->sc_curseg->sb_sum)) { | 2150 | NILFS_SEG_EMPTY(&sci->sc_curseg->sb_sum)) { |
2176 | nilfs_segctor_end_construction(sci, nilfs, 1); | 2151 | nilfs_segctor_abort_construction(sci, nilfs, 1); |
2177 | goto out; | 2152 | goto out; |
2178 | } | 2153 | } |
2179 | 2154 | ||
@@ -2187,7 +2162,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | |||
2187 | if (has_sr) { | 2162 | if (has_sr) { |
2188 | err = nilfs_segctor_fill_in_checkpoint(sci); | 2163 | err = nilfs_segctor_fill_in_checkpoint(sci); |
2189 | if (unlikely(err)) | 2164 | if (unlikely(err)) |
2190 | goto failed_to_make_up; | 2165 | goto failed_to_write; |
2191 | 2166 | ||
2192 | nilfs_segctor_fill_in_super_root(sci, nilfs); | 2167 | nilfs_segctor_fill_in_super_root(sci, nilfs); |
2193 | } | 2168 | } |
@@ -2195,47 +2170,51 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | |||
2195 | 2170 | ||
2196 | /* Write partial segments */ | 2171 | /* Write partial segments */ |
2197 | err = nilfs_segctor_prepare_write(sci, &failed_page); | 2172 | err = nilfs_segctor_prepare_write(sci, &failed_page); |
2198 | if (unlikely(err)) | 2173 | if (err) { |
2174 | nilfs_abort_logs(&sci->sc_segbufs, failed_page, | ||
2175 | sci->sc_super_root, err); | ||
2199 | goto failed_to_write; | 2176 | goto failed_to_write; |
2200 | 2177 | } | |
2201 | nilfs_segctor_fill_in_checksums(sci, nilfs->ns_crc_seed); | 2178 | nilfs_segctor_fill_in_checksums(sci, nilfs->ns_crc_seed); |
2202 | 2179 | ||
2203 | err = nilfs_segctor_write(sci, nilfs->ns_bdi); | 2180 | err = nilfs_segctor_write(sci, nilfs); |
2204 | if (unlikely(err)) | 2181 | if (unlikely(err)) |
2205 | goto failed_to_write; | 2182 | goto failed_to_write; |
2206 | 2183 | ||
2207 | nilfs_segctor_complete_write(sci); | 2184 | if (sci->sc_stage.scnt == NILFS_ST_DONE || |
2208 | 2185 | nilfs->ns_blocksize_bits != PAGE_CACHE_SHIFT) { | |
2209 | /* Commit segments */ | 2186 | /* |
2210 | if (has_sr) | 2187 | * At this point, we avoid double buffering |
2211 | nilfs_segctor_clear_metadata_dirty(sci); | 2188 | * for blocksize < pagesize because page dirty |
2212 | 2189 | * flag is turned off during write and dirty | |
2213 | nilfs_segctor_end_construction(sci, nilfs, 0); | 2190 | * buffers are not properly collected for |
2214 | 2191 | * pages crossing over segments. | |
2192 | */ | ||
2193 | err = nilfs_segctor_wait(sci); | ||
2194 | if (err) | ||
2195 | goto failed_to_write; | ||
2196 | } | ||
2215 | } while (sci->sc_stage.scnt != NILFS_ST_DONE); | 2197 | } while (sci->sc_stage.scnt != NILFS_ST_DONE); |
2216 | 2198 | ||
2199 | sci->sc_super_root = NULL; | ||
2200 | |||
2217 | out: | 2201 | out: |
2218 | nilfs_segctor_destroy_segment_buffers(sci); | ||
2219 | nilfs_segctor_check_out_files(sci, sbi); | 2202 | nilfs_segctor_check_out_files(sci, sbi); |
2220 | return err; | 2203 | return err; |
2221 | 2204 | ||
2222 | failed_to_write: | 2205 | failed_to_write: |
2223 | nilfs_segctor_abort_write(sci, failed_page, err); | ||
2224 | nilfs_segctor_cancel_segusage(sci, nilfs->ns_sufile); | ||
2225 | |||
2226 | failed_to_make_up: | ||
2227 | if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED) | 2206 | if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED) |
2228 | nilfs_redirty_inodes(&sci->sc_dirty_files); | 2207 | nilfs_redirty_inodes(&sci->sc_dirty_files); |
2229 | 2208 | ||
2230 | failed: | 2209 | failed: |
2231 | if (nilfs_doing_gc()) | 2210 | if (nilfs_doing_gc()) |
2232 | nilfs_redirty_inodes(&sci->sc_gc_inodes); | 2211 | nilfs_redirty_inodes(&sci->sc_gc_inodes); |
2233 | nilfs_segctor_end_construction(sci, nilfs, err); | 2212 | nilfs_segctor_abort_construction(sci, nilfs, err); |
2234 | goto out; | 2213 | goto out; |
2235 | } | 2214 | } |
2236 | 2215 | ||
2237 | /** | 2216 | /** |
2238 | * nilfs_secgtor_start_timer - set timer of background write | 2217 | * nilfs_segctor_start_timer - set timer of background write |
2239 | * @sci: nilfs_sc_info | 2218 | * @sci: nilfs_sc_info |
2240 | * | 2219 | * |
2241 | * If the timer has already been set, it ignores the new request. | 2220 | * If the timer has already been set, it ignores the new request. |
@@ -2440,43 +2419,43 @@ int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode, | |||
2440 | return err; | 2419 | return err; |
2441 | } | 2420 | } |
2442 | 2421 | ||
2443 | struct nilfs_segctor_req { | ||
2444 | int mode; | ||
2445 | __u32 seq_accepted; | ||
2446 | int sc_err; /* construction failure */ | ||
2447 | int sb_err; /* super block writeback failure */ | ||
2448 | }; | ||
2449 | |||
2450 | #define FLUSH_FILE_BIT (0x1) /* data file only */ | 2422 | #define FLUSH_FILE_BIT (0x1) /* data file only */ |
2451 | #define FLUSH_DAT_BIT (1 << NILFS_DAT_INO) /* DAT only */ | 2423 | #define FLUSH_DAT_BIT (1 << NILFS_DAT_INO) /* DAT only */ |
2452 | 2424 | ||
2453 | static void nilfs_segctor_accept(struct nilfs_sc_info *sci, | 2425 | /** |
2454 | struct nilfs_segctor_req *req) | 2426 | * nilfs_segctor_accept - record accepted sequence count of log-write requests |
2427 | * @sci: segment constructor object | ||
2428 | */ | ||
2429 | static void nilfs_segctor_accept(struct nilfs_sc_info *sci) | ||
2455 | { | 2430 | { |
2456 | req->sc_err = req->sb_err = 0; | ||
2457 | spin_lock(&sci->sc_state_lock); | 2431 | spin_lock(&sci->sc_state_lock); |
2458 | req->seq_accepted = sci->sc_seq_request; | 2432 | sci->sc_seq_accepted = sci->sc_seq_request; |
2459 | spin_unlock(&sci->sc_state_lock); | 2433 | spin_unlock(&sci->sc_state_lock); |
2460 | 2434 | ||
2461 | if (sci->sc_timer) | 2435 | if (sci->sc_timer) |
2462 | del_timer_sync(sci->sc_timer); | 2436 | del_timer_sync(sci->sc_timer); |
2463 | } | 2437 | } |
2464 | 2438 | ||
2465 | static void nilfs_segctor_notify(struct nilfs_sc_info *sci, | 2439 | /** |
2466 | struct nilfs_segctor_req *req) | 2440 | * nilfs_segctor_notify - notify the result of request to caller threads |
2441 | * @sci: segment constructor object | ||
2442 | * @mode: mode of log forming | ||
2443 | * @err: error code to be notified | ||
2444 | */ | ||
2445 | static void nilfs_segctor_notify(struct nilfs_sc_info *sci, int mode, int err) | ||
2467 | { | 2446 | { |
2468 | /* Clear requests (even when the construction failed) */ | 2447 | /* Clear requests (even when the construction failed) */ |
2469 | spin_lock(&sci->sc_state_lock); | 2448 | spin_lock(&sci->sc_state_lock); |
2470 | 2449 | ||
2471 | if (req->mode == SC_LSEG_SR) { | 2450 | if (mode == SC_LSEG_SR) { |
2472 | sci->sc_state &= ~NILFS_SEGCTOR_COMMIT; | 2451 | sci->sc_state &= ~NILFS_SEGCTOR_COMMIT; |
2473 | sci->sc_seq_done = req->seq_accepted; | 2452 | sci->sc_seq_done = sci->sc_seq_accepted; |
2474 | nilfs_segctor_wakeup(sci, req->sc_err ? : req->sb_err); | 2453 | nilfs_segctor_wakeup(sci, err); |
2475 | sci->sc_flush_request = 0; | 2454 | sci->sc_flush_request = 0; |
2476 | } else { | 2455 | } else { |
2477 | if (req->mode == SC_FLUSH_FILE) | 2456 | if (mode == SC_FLUSH_FILE) |
2478 | sci->sc_flush_request &= ~FLUSH_FILE_BIT; | 2457 | sci->sc_flush_request &= ~FLUSH_FILE_BIT; |
2479 | else if (req->mode == SC_FLUSH_DAT) | 2458 | else if (mode == SC_FLUSH_DAT) |
2480 | sci->sc_flush_request &= ~FLUSH_DAT_BIT; | 2459 | sci->sc_flush_request &= ~FLUSH_DAT_BIT; |
2481 | 2460 | ||
2482 | /* re-enable timer if checkpoint creation was not done */ | 2461 | /* re-enable timer if checkpoint creation was not done */ |
@@ -2487,30 +2466,37 @@ static void nilfs_segctor_notify(struct nilfs_sc_info *sci, | |||
2487 | spin_unlock(&sci->sc_state_lock); | 2466 | spin_unlock(&sci->sc_state_lock); |
2488 | } | 2467 | } |
2489 | 2468 | ||
2490 | static int nilfs_segctor_construct(struct nilfs_sc_info *sci, | 2469 | /** |
2491 | struct nilfs_segctor_req *req) | 2470 | * nilfs_segctor_construct - form logs and write them to disk |
2471 | * @sci: segment constructor object | ||
2472 | * @mode: mode of log forming | ||
2473 | */ | ||
2474 | static int nilfs_segctor_construct(struct nilfs_sc_info *sci, int mode) | ||
2492 | { | 2475 | { |
2493 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 2476 | struct nilfs_sb_info *sbi = sci->sc_sbi; |
2494 | struct the_nilfs *nilfs = sbi->s_nilfs; | 2477 | struct the_nilfs *nilfs = sbi->s_nilfs; |
2495 | int err = 0; | 2478 | int err = 0; |
2496 | 2479 | ||
2480 | nilfs_segctor_accept(sci); | ||
2481 | |||
2497 | if (nilfs_discontinued(nilfs)) | 2482 | if (nilfs_discontinued(nilfs)) |
2498 | req->mode = SC_LSEG_SR; | 2483 | mode = SC_LSEG_SR; |
2499 | if (!nilfs_segctor_confirm(sci)) { | 2484 | if (!nilfs_segctor_confirm(sci)) |
2500 | err = nilfs_segctor_do_construct(sci, req->mode); | 2485 | err = nilfs_segctor_do_construct(sci, mode); |
2501 | req->sc_err = err; | 2486 | |
2502 | } | ||
2503 | if (likely(!err)) { | 2487 | if (likely(!err)) { |
2504 | if (req->mode != SC_FLUSH_DAT) | 2488 | if (mode != SC_FLUSH_DAT) |
2505 | atomic_set(&nilfs->ns_ndirtyblks, 0); | 2489 | atomic_set(&nilfs->ns_ndirtyblks, 0); |
2506 | if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) && | 2490 | if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) && |
2507 | nilfs_discontinued(nilfs)) { | 2491 | nilfs_discontinued(nilfs)) { |
2508 | down_write(&nilfs->ns_sem); | 2492 | down_write(&nilfs->ns_sem); |
2509 | req->sb_err = nilfs_commit_super(sbi, | 2493 | err = nilfs_commit_super( |
2510 | nilfs_altsb_need_update(nilfs)); | 2494 | sbi, nilfs_altsb_need_update(nilfs)); |
2511 | up_write(&nilfs->ns_sem); | 2495 | up_write(&nilfs->ns_sem); |
2512 | } | 2496 | } |
2513 | } | 2497 | } |
2498 | |||
2499 | nilfs_segctor_notify(sci, mode, err); | ||
2514 | return err; | 2500 | return err; |
2515 | } | 2501 | } |
2516 | 2502 | ||
@@ -2541,7 +2527,6 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv, | |||
2541 | struct nilfs_sc_info *sci = NILFS_SC(sbi); | 2527 | struct nilfs_sc_info *sci = NILFS_SC(sbi); |
2542 | struct the_nilfs *nilfs = sbi->s_nilfs; | 2528 | struct the_nilfs *nilfs = sbi->s_nilfs; |
2543 | struct nilfs_transaction_info ti; | 2529 | struct nilfs_transaction_info ti; |
2544 | struct nilfs_segctor_req req = { .mode = SC_LSEG_SR }; | ||
2545 | int err; | 2530 | int err; |
2546 | 2531 | ||
2547 | if (unlikely(!sci)) | 2532 | if (unlikely(!sci)) |
@@ -2559,13 +2544,11 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv, | |||
2559 | 2544 | ||
2560 | sci->sc_freesegs = kbufs[4]; | 2545 | sci->sc_freesegs = kbufs[4]; |
2561 | sci->sc_nfreesegs = argv[4].v_nmembs; | 2546 | sci->sc_nfreesegs = argv[4].v_nmembs; |
2562 | list_splice_init(&nilfs->ns_gc_inodes, sci->sc_gc_inodes.prev); | 2547 | list_splice_tail_init(&nilfs->ns_gc_inodes, &sci->sc_gc_inodes); |
2563 | 2548 | ||
2564 | for (;;) { | 2549 | for (;;) { |
2565 | nilfs_segctor_accept(sci, &req); | 2550 | err = nilfs_segctor_construct(sci, SC_LSEG_SR); |
2566 | err = nilfs_segctor_construct(sci, &req); | ||
2567 | nilfs_remove_written_gcinodes(nilfs, &sci->sc_gc_inodes); | 2551 | nilfs_remove_written_gcinodes(nilfs, &sci->sc_gc_inodes); |
2568 | nilfs_segctor_notify(sci, &req); | ||
2569 | 2552 | ||
2570 | if (likely(!err)) | 2553 | if (likely(!err)) |
2571 | break; | 2554 | break; |
@@ -2575,6 +2558,16 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv, | |||
2575 | set_current_state(TASK_INTERRUPTIBLE); | 2558 | set_current_state(TASK_INTERRUPTIBLE); |
2576 | schedule_timeout(sci->sc_interval); | 2559 | schedule_timeout(sci->sc_interval); |
2577 | } | 2560 | } |
2561 | if (nilfs_test_opt(sbi, DISCARD)) { | ||
2562 | int ret = nilfs_discard_segments(nilfs, sci->sc_freesegs, | ||
2563 | sci->sc_nfreesegs); | ||
2564 | if (ret) { | ||
2565 | printk(KERN_WARNING | ||
2566 | "NILFS warning: error %d on discard request, " | ||
2567 | "turning discards off for the device\n", ret); | ||
2568 | nilfs_clear_opt(sbi, DISCARD); | ||
2569 | } | ||
2570 | } | ||
2578 | 2571 | ||
2579 | out_unlock: | 2572 | out_unlock: |
2580 | sci->sc_freesegs = NULL; | 2573 | sci->sc_freesegs = NULL; |
@@ -2588,13 +2581,9 @@ static void nilfs_segctor_thread_construct(struct nilfs_sc_info *sci, int mode) | |||
2588 | { | 2581 | { |
2589 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 2582 | struct nilfs_sb_info *sbi = sci->sc_sbi; |
2590 | struct nilfs_transaction_info ti; | 2583 | struct nilfs_transaction_info ti; |
2591 | struct nilfs_segctor_req req = { .mode = mode }; | ||
2592 | 2584 | ||
2593 | nilfs_transaction_lock(sbi, &ti, 0); | 2585 | nilfs_transaction_lock(sbi, &ti, 0); |
2594 | 2586 | nilfs_segctor_construct(sci, mode); | |
2595 | nilfs_segctor_accept(sci, &req); | ||
2596 | nilfs_segctor_construct(sci, &req); | ||
2597 | nilfs_segctor_notify(sci, &req); | ||
2598 | 2587 | ||
2599 | /* | 2588 | /* |
2600 | * Unclosed segment should be retried. We do this using sc_timer. | 2589 | * Unclosed segment should be retried. We do this using sc_timer. |
@@ -2650,6 +2639,7 @@ static int nilfs_segctor_flush_mode(struct nilfs_sc_info *sci) | |||
2650 | static int nilfs_segctor_thread(void *arg) | 2639 | static int nilfs_segctor_thread(void *arg) |
2651 | { | 2640 | { |
2652 | struct nilfs_sc_info *sci = (struct nilfs_sc_info *)arg; | 2641 | struct nilfs_sc_info *sci = (struct nilfs_sc_info *)arg; |
2642 | struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs; | ||
2653 | struct timer_list timer; | 2643 | struct timer_list timer; |
2654 | int timeout = 0; | 2644 | int timeout = 0; |
2655 | 2645 | ||
@@ -2695,7 +2685,6 @@ static int nilfs_segctor_thread(void *arg) | |||
2695 | } else { | 2685 | } else { |
2696 | DEFINE_WAIT(wait); | 2686 | DEFINE_WAIT(wait); |
2697 | int should_sleep = 1; | 2687 | int should_sleep = 1; |
2698 | struct the_nilfs *nilfs; | ||
2699 | 2688 | ||
2700 | prepare_to_wait(&sci->sc_wait_daemon, &wait, | 2689 | prepare_to_wait(&sci->sc_wait_daemon, &wait, |
2701 | TASK_INTERRUPTIBLE); | 2690 | TASK_INTERRUPTIBLE); |
@@ -2716,8 +2705,8 @@ static int nilfs_segctor_thread(void *arg) | |||
2716 | finish_wait(&sci->sc_wait_daemon, &wait); | 2705 | finish_wait(&sci->sc_wait_daemon, &wait); |
2717 | timeout = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) && | 2706 | timeout = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) && |
2718 | time_after_eq(jiffies, sci->sc_timer->expires)); | 2707 | time_after_eq(jiffies, sci->sc_timer->expires)); |
2719 | nilfs = sci->sc_sbi->s_nilfs; | 2708 | |
2720 | if (sci->sc_super->s_dirt && nilfs_sb_need_update(nilfs)) | 2709 | if (nilfs_sb_dirty(nilfs) && nilfs_sb_need_update(nilfs)) |
2721 | set_nilfs_discontinued(nilfs); | 2710 | set_nilfs_discontinued(nilfs); |
2722 | } | 2711 | } |
2723 | goto loop; | 2712 | goto loop; |
@@ -2788,6 +2777,7 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi) | |||
2788 | spin_lock_init(&sci->sc_state_lock); | 2777 | spin_lock_init(&sci->sc_state_lock); |
2789 | INIT_LIST_HEAD(&sci->sc_dirty_files); | 2778 | INIT_LIST_HEAD(&sci->sc_dirty_files); |
2790 | INIT_LIST_HEAD(&sci->sc_segbufs); | 2779 | INIT_LIST_HEAD(&sci->sc_segbufs); |
2780 | INIT_LIST_HEAD(&sci->sc_write_logs); | ||
2791 | INIT_LIST_HEAD(&sci->sc_gc_inodes); | 2781 | INIT_LIST_HEAD(&sci->sc_gc_inodes); |
2792 | INIT_LIST_HEAD(&sci->sc_copied_buffers); | 2782 | INIT_LIST_HEAD(&sci->sc_copied_buffers); |
2793 | 2783 | ||
@@ -2811,12 +2801,9 @@ static void nilfs_segctor_write_out(struct nilfs_sc_info *sci) | |||
2811 | do { | 2801 | do { |
2812 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 2802 | struct nilfs_sb_info *sbi = sci->sc_sbi; |
2813 | struct nilfs_transaction_info ti; | 2803 | struct nilfs_transaction_info ti; |
2814 | struct nilfs_segctor_req req = { .mode = SC_LSEG_SR }; | ||
2815 | 2804 | ||
2816 | nilfs_transaction_lock(sbi, &ti, 0); | 2805 | nilfs_transaction_lock(sbi, &ti, 0); |
2817 | nilfs_segctor_accept(sci, &req); | 2806 | ret = nilfs_segctor_construct(sci, SC_LSEG_SR); |
2818 | ret = nilfs_segctor_construct(sci, &req); | ||
2819 | nilfs_segctor_notify(sci, &req); | ||
2820 | nilfs_transaction_unlock(sbi); | 2807 | nilfs_transaction_unlock(sbi); |
2821 | 2808 | ||
2822 | } while (ret && retrycount-- > 0); | 2809 | } while (ret && retrycount-- > 0); |
@@ -2843,7 +2830,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | |||
2843 | || sci->sc_seq_request != sci->sc_seq_done); | 2830 | || sci->sc_seq_request != sci->sc_seq_done); |
2844 | spin_unlock(&sci->sc_state_lock); | 2831 | spin_unlock(&sci->sc_state_lock); |
2845 | 2832 | ||
2846 | if (flag || nilfs_segctor_confirm(sci)) | 2833 | if (flag || !nilfs_segctor_confirm(sci)) |
2847 | nilfs_segctor_write_out(sci); | 2834 | nilfs_segctor_write_out(sci); |
2848 | 2835 | ||
2849 | WARN_ON(!list_empty(&sci->sc_copied_buffers)); | 2836 | WARN_ON(!list_empty(&sci->sc_copied_buffers)); |
@@ -2855,6 +2842,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | |||
2855 | } | 2842 | } |
2856 | 2843 | ||
2857 | WARN_ON(!list_empty(&sci->sc_segbufs)); | 2844 | WARN_ON(!list_empty(&sci->sc_segbufs)); |
2845 | WARN_ON(!list_empty(&sci->sc_write_logs)); | ||
2858 | 2846 | ||
2859 | down_write(&sbi->s_nilfs->ns_segctor_sem); | 2847 | down_write(&sbi->s_nilfs->ns_segctor_sem); |
2860 | 2848 | ||
@@ -2866,7 +2854,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | |||
2866 | * @sbi: nilfs_sb_info | 2854 | * @sbi: nilfs_sb_info |
2867 | * | 2855 | * |
2868 | * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info, | 2856 | * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info, |
2869 | * initilizes it, and starts the segment constructor. | 2857 | * initializes it, and starts the segment constructor. |
2870 | * | 2858 | * |
2871 | * Return Value: On success, 0 is returned. On error, one of the following | 2859 | * Return Value: On success, 0 is returned. On error, one of the following |
2872 | * negative error code is returned. | 2860 | * negative error code is returned. |
@@ -2878,8 +2866,15 @@ int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi) | |||
2878 | struct the_nilfs *nilfs = sbi->s_nilfs; | 2866 | struct the_nilfs *nilfs = sbi->s_nilfs; |
2879 | int err; | 2867 | int err; |
2880 | 2868 | ||
2881 | /* Each field of nilfs_segctor is cleared through the initialization | 2869 | if (NILFS_SC(sbi)) { |
2882 | of super-block info */ | 2870 | /* |
2871 | * This happens if the filesystem was remounted | ||
2872 | * read/write after nilfs_error degenerated it into a | ||
2873 | * read-only mount. | ||
2874 | */ | ||
2875 | nilfs_detach_segment_constructor(sbi); | ||
2876 | } | ||
2877 | |||
2883 | sbi->s_sc_info = nilfs_segctor_new(sbi); | 2878 | sbi->s_sc_info = nilfs_segctor_new(sbi); |
2884 | if (!sbi->s_sc_info) | 2879 | if (!sbi->s_sc_info) |
2885 | return -ENOMEM; | 2880 | return -ENOMEM; |