diff options
-rw-r--r-- | fs/nilfs2/sufile.c | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c index 88344728f216..e9b4cec0d3ef 100644 --- a/fs/nilfs2/sufile.c +++ b/fs/nilfs2/sufile.c | |||
@@ -31,6 +31,16 @@ | |||
31 | #include "sufile.h" | 31 | #include "sufile.h" |
32 | 32 | ||
33 | 33 | ||
34 | struct nilfs_sufile_info { | ||
35 | struct nilfs_mdt_info mi; | ||
36 | unsigned long ncleansegs; | ||
37 | }; | ||
38 | |||
39 | static inline struct nilfs_sufile_info *NILFS_SUI(struct inode *sufile) | ||
40 | { | ||
41 | return (struct nilfs_sufile_info *)NILFS_MDT(sufile); | ||
42 | } | ||
43 | |||
34 | static inline unsigned long | 44 | static inline unsigned long |
35 | nilfs_sufile_segment_usages_per_block(const struct inode *sufile) | 45 | nilfs_sufile_segment_usages_per_block(const struct inode *sufile) |
36 | { | 46 | { |
@@ -300,6 +310,7 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump) | |||
300 | header->sh_last_alloc = cpu_to_le64(segnum); | 310 | header->sh_last_alloc = cpu_to_le64(segnum); |
301 | kunmap_atomic(kaddr, KM_USER0); | 311 | kunmap_atomic(kaddr, KM_USER0); |
302 | 312 | ||
313 | NILFS_SUI(sufile)->ncleansegs--; | ||
303 | nilfs_mdt_mark_buffer_dirty(header_bh); | 314 | nilfs_mdt_mark_buffer_dirty(header_bh); |
304 | nilfs_mdt_mark_buffer_dirty(su_bh); | 315 | nilfs_mdt_mark_buffer_dirty(su_bh); |
305 | nilfs_mdt_mark_dirty(sufile); | 316 | nilfs_mdt_mark_dirty(sufile); |
@@ -342,6 +353,8 @@ void nilfs_sufile_do_cancel_free(struct inode *sufile, __u64 segnum, | |||
342 | kunmap_atomic(kaddr, KM_USER0); | 353 | kunmap_atomic(kaddr, KM_USER0); |
343 | 354 | ||
344 | nilfs_sufile_mod_counter(header_bh, -1, 1); | 355 | nilfs_sufile_mod_counter(header_bh, -1, 1); |
356 | NILFS_SUI(sufile)->ncleansegs--; | ||
357 | |||
345 | nilfs_mdt_mark_buffer_dirty(su_bh); | 358 | nilfs_mdt_mark_buffer_dirty(su_bh); |
346 | nilfs_mdt_mark_dirty(sufile); | 359 | nilfs_mdt_mark_dirty(sufile); |
347 | } | 360 | } |
@@ -371,6 +384,8 @@ void nilfs_sufile_do_scrap(struct inode *sufile, __u64 segnum, | |||
371 | kunmap_atomic(kaddr, KM_USER0); | 384 | kunmap_atomic(kaddr, KM_USER0); |
372 | 385 | ||
373 | nilfs_sufile_mod_counter(header_bh, clean ? (u64)-1 : 0, dirty ? 0 : 1); | 386 | nilfs_sufile_mod_counter(header_bh, clean ? (u64)-1 : 0, dirty ? 0 : 1); |
387 | NILFS_SUI(sufile)->ncleansegs -= clean; | ||
388 | |||
374 | nilfs_mdt_mark_buffer_dirty(su_bh); | 389 | nilfs_mdt_mark_buffer_dirty(su_bh); |
375 | nilfs_mdt_mark_dirty(sufile); | 390 | nilfs_mdt_mark_dirty(sufile); |
376 | } | 391 | } |
@@ -400,6 +415,8 @@ void nilfs_sufile_do_free(struct inode *sufile, __u64 segnum, | |||
400 | nilfs_mdt_mark_buffer_dirty(su_bh); | 415 | nilfs_mdt_mark_buffer_dirty(su_bh); |
401 | 416 | ||
402 | nilfs_sufile_mod_counter(header_bh, 1, sudirty ? (u64)-1 : 0); | 417 | nilfs_sufile_mod_counter(header_bh, 1, sudirty ? (u64)-1 : 0); |
418 | NILFS_SUI(sufile)->ncleansegs++; | ||
419 | |||
403 | nilfs_mdt_mark_dirty(sufile); | 420 | nilfs_mdt_mark_dirty(sufile); |
404 | } | 421 | } |
405 | 422 | ||
@@ -541,13 +558,8 @@ int nilfs_sufile_get_stat(struct inode *sufile, struct nilfs_sustat *sustat) | |||
541 | */ | 558 | */ |
542 | int nilfs_sufile_get_ncleansegs(struct inode *sufile, unsigned long *nsegsp) | 559 | int nilfs_sufile_get_ncleansegs(struct inode *sufile, unsigned long *nsegsp) |
543 | { | 560 | { |
544 | struct nilfs_sustat sustat; | 561 | *nsegsp = NILFS_SUI(sufile)->ncleansegs; |
545 | int ret; | 562 | return 0; |
546 | |||
547 | ret = nilfs_sufile_get_stat(sufile, &sustat); | ||
548 | if (ret == 0) | ||
549 | *nsegsp = sustat.ss_ncleansegs; | ||
550 | return ret; | ||
551 | } | 563 | } |
552 | 564 | ||
553 | void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum, | 565 | void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum, |
@@ -568,8 +580,10 @@ void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum, | |||
568 | nilfs_segment_usage_set_error(su); | 580 | nilfs_segment_usage_set_error(su); |
569 | kunmap_atomic(kaddr, KM_USER0); | 581 | kunmap_atomic(kaddr, KM_USER0); |
570 | 582 | ||
571 | if (suclean) | 583 | if (suclean) { |
572 | nilfs_sufile_mod_counter(header_bh, -1, 0); | 584 | nilfs_sufile_mod_counter(header_bh, -1, 0); |
585 | NILFS_SUI(sufile)->ncleansegs--; | ||
586 | } | ||
573 | nilfs_mdt_mark_buffer_dirty(su_bh); | 587 | nilfs_mdt_mark_buffer_dirty(su_bh); |
574 | nilfs_mdt_mark_dirty(sufile); | 588 | nilfs_mdt_mark_dirty(sufile); |
575 | } | 589 | } |
@@ -656,7 +670,25 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf, | |||
656 | */ | 670 | */ |
657 | int nilfs_sufile_read(struct inode *sufile, struct nilfs_inode *raw_inode) | 671 | int nilfs_sufile_read(struct inode *sufile, struct nilfs_inode *raw_inode) |
658 | { | 672 | { |
659 | return nilfs_read_inode_common(sufile, raw_inode); | 673 | struct nilfs_sufile_info *sui = NILFS_SUI(sufile); |
674 | struct buffer_head *header_bh; | ||
675 | struct nilfs_sufile_header *header; | ||
676 | void *kaddr; | ||
677 | int ret; | ||
678 | |||
679 | ret = nilfs_read_inode_common(sufile, raw_inode); | ||
680 | if (ret < 0) | ||
681 | return ret; | ||
682 | |||
683 | ret = nilfs_sufile_get_header_block(sufile, &header_bh); | ||
684 | if (!ret) { | ||
685 | kaddr = kmap_atomic(header_bh->b_page, KM_USER0); | ||
686 | header = kaddr + bh_offset(header_bh); | ||
687 | sui->ncleansegs = le64_to_cpu(header->sh_ncleansegs); | ||
688 | kunmap_atomic(kaddr, KM_USER0); | ||
689 | brelse(header_bh); | ||
690 | } | ||
691 | return ret; | ||
660 | } | 692 | } |
661 | 693 | ||
662 | /** | 694 | /** |
@@ -668,7 +700,8 @@ struct inode *nilfs_sufile_new(struct the_nilfs *nilfs, size_t susize) | |||
668 | { | 700 | { |
669 | struct inode *sufile; | 701 | struct inode *sufile; |
670 | 702 | ||
671 | sufile = nilfs_mdt_new(nilfs, NULL, NILFS_SUFILE_INO, 0); | 703 | sufile = nilfs_mdt_new(nilfs, NULL, NILFS_SUFILE_INO, |
704 | sizeof(struct nilfs_sufile_info)); | ||
672 | if (sufile) | 705 | if (sufile) |
673 | nilfs_mdt_set_entry_size(sufile, susize, | 706 | nilfs_mdt_set_entry_size(sufile, susize, |
674 | sizeof(struct nilfs_sufile_header)); | 707 | sizeof(struct nilfs_sufile_header)); |