diff options
-rw-r--r-- | fs/nilfs2/segment.c | 32 | ||||
-rw-r--r-- | fs/nilfs2/sufile.c | 37 | ||||
-rw-r--r-- | fs/nilfs2/sufile.h | 2 |
3 files changed, 49 insertions, 22 deletions
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 3ae4a3849f81..097f9c467fef 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -1457,21 +1457,16 @@ static void nilfs_segctor_update_segusage(struct nilfs_sc_info *sci, | |||
1457 | struct inode *sufile) | 1457 | struct inode *sufile) |
1458 | { | 1458 | { |
1459 | struct nilfs_segment_buffer *segbuf; | 1459 | struct nilfs_segment_buffer *segbuf; |
1460 | struct buffer_head *bh_su; | ||
1461 | struct nilfs_segment_usage *raw_su; | ||
1462 | unsigned long live_blocks; | 1460 | unsigned long live_blocks; |
1463 | int ret; | 1461 | int ret; |
1464 | 1462 | ||
1465 | list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { | 1463 | list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { |
1466 | ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum, | ||
1467 | &raw_su, &bh_su); | ||
1468 | WARN_ON(ret); /* always succeed because bh_su is dirty */ | ||
1469 | live_blocks = segbuf->sb_sum.nblocks + | 1464 | live_blocks = segbuf->sb_sum.nblocks + |
1470 | (segbuf->sb_pseg_start - segbuf->sb_fseg_start); | 1465 | (segbuf->sb_pseg_start - segbuf->sb_fseg_start); |
1471 | raw_su->su_lastmod = cpu_to_le64(sci->sc_seg_ctime); | 1466 | ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum, |
1472 | raw_su->su_nblocks = cpu_to_le32(live_blocks); | 1467 | live_blocks, |
1473 | nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum, | 1468 | sci->sc_seg_ctime); |
1474 | bh_su); | 1469 | WARN_ON(ret); /* always succeed because the segusage is dirty */ |
1475 | } | 1470 | } |
1476 | } | 1471 | } |
1477 | 1472 | ||
@@ -1479,25 +1474,18 @@ static void nilfs_segctor_cancel_segusage(struct nilfs_sc_info *sci, | |||
1479 | struct inode *sufile) | 1474 | struct inode *sufile) |
1480 | { | 1475 | { |
1481 | struct nilfs_segment_buffer *segbuf; | 1476 | struct nilfs_segment_buffer *segbuf; |
1482 | struct buffer_head *bh_su; | ||
1483 | struct nilfs_segment_usage *raw_su; | ||
1484 | int ret; | 1477 | int ret; |
1485 | 1478 | ||
1486 | segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs); | 1479 | segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs); |
1487 | ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum, | 1480 | ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum, |
1488 | &raw_su, &bh_su); | 1481 | segbuf->sb_pseg_start - |
1489 | WARN_ON(ret); /* always succeed because bh_su is dirty */ | 1482 | segbuf->sb_fseg_start, 0); |
1490 | raw_su->su_nblocks = cpu_to_le32(segbuf->sb_pseg_start - | 1483 | WARN_ON(ret); /* always succeed because the segusage is dirty */ |
1491 | segbuf->sb_fseg_start); | ||
1492 | nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum, bh_su); | ||
1493 | 1484 | ||
1494 | list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) { | 1485 | list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) { |
1495 | ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum, | 1486 | ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum, |
1496 | &raw_su, &bh_su); | 1487 | 0, 0); |
1497 | WARN_ON(ret); /* always succeed */ | 1488 | WARN_ON(ret); /* always succeed */ |
1498 | raw_su->su_nblocks = 0; | ||
1499 | nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum, | ||
1500 | bh_su); | ||
1501 | } | 1489 | } |
1502 | } | 1490 | } |
1503 | 1491 | ||
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c index d560f882a868..3eed998df1c8 100644 --- a/fs/nilfs2/sufile.c +++ b/fs/nilfs2/sufile.c | |||
@@ -521,6 +521,43 @@ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum) | |||
521 | } | 521 | } |
522 | 522 | ||
523 | /** | 523 | /** |
524 | * nilfs_sufile_set_segment_usage - set usage of a segment | ||
525 | * @sufile: inode of segment usage file | ||
526 | * @segnum: segment number | ||
527 | * @nblocks: number of live blocks in the segment | ||
528 | * @modtime: modification time (option) | ||
529 | */ | ||
530 | int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum, | ||
531 | unsigned long nblocks, time_t modtime) | ||
532 | { | ||
533 | struct buffer_head *bh; | ||
534 | struct nilfs_segment_usage *su; | ||
535 | void *kaddr; | ||
536 | int ret; | ||
537 | |||
538 | down_write(&NILFS_MDT(sufile)->mi_sem); | ||
539 | ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh); | ||
540 | if (ret < 0) | ||
541 | goto out_sem; | ||
542 | |||
543 | kaddr = kmap_atomic(bh->b_page, KM_USER0); | ||
544 | su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr); | ||
545 | WARN_ON(nilfs_segment_usage_error(su)); | ||
546 | if (modtime) | ||
547 | su->su_lastmod = cpu_to_le64(modtime); | ||
548 | su->su_nblocks = cpu_to_le32(nblocks); | ||
549 | kunmap_atomic(kaddr, KM_USER0); | ||
550 | |||
551 | nilfs_mdt_mark_buffer_dirty(bh); | ||
552 | nilfs_mdt_mark_dirty(sufile); | ||
553 | brelse(bh); | ||
554 | |||
555 | out_sem: | ||
556 | up_write(&NILFS_MDT(sufile)->mi_sem); | ||
557 | return ret; | ||
558 | } | ||
559 | |||
560 | /** | ||
524 | * nilfs_sufile_get_stat - get segment usage statistics | 561 | * nilfs_sufile_get_stat - get segment usage statistics |
525 | * @sufile: inode of segment usage file | 562 | * @sufile: inode of segment usage file |
526 | * @stat: pointer to a structure of segment usage statistics | 563 | * @stat: pointer to a structure of segment usage statistics |
diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h index 4146a652aed1..e1186bf3b964 100644 --- a/fs/nilfs2/sufile.h +++ b/fs/nilfs2/sufile.h | |||
@@ -43,6 +43,8 @@ int nilfs_sufile_get_segment_usage(struct inode *, __u64, | |||
43 | void nilfs_sufile_put_segment_usage(struct inode *, __u64, | 43 | void nilfs_sufile_put_segment_usage(struct inode *, __u64, |
44 | struct buffer_head *); | 44 | struct buffer_head *); |
45 | int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum); | 45 | int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum); |
46 | int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum, | ||
47 | unsigned long nblocks, time_t modtime); | ||
46 | int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *); | 48 | int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *); |
47 | ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned, | 49 | ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned, |
48 | size_t); | 50 | size_t); |