diff options
-rw-r--r-- | fs/nilfs2/ioctl.c | 26 | ||||
-rw-r--r-- | fs/nilfs2/segbuf.c | 1 | ||||
-rw-r--r-- | fs/nilfs2/seglist.h | 6 | ||||
-rw-r--r-- | fs/nilfs2/segment.c | 130 | ||||
-rw-r--r-- | fs/nilfs2/segment.h | 11 | ||||
-rw-r--r-- | fs/nilfs2/sufile.h | 56 |
6 files changed, 74 insertions, 156 deletions
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index d6759b92006f..bdad7e4980b0 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c | |||
@@ -435,24 +435,6 @@ static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs, | |||
435 | return nmembs; | 435 | return nmembs; |
436 | } | 436 | } |
437 | 437 | ||
438 | static int nilfs_ioctl_free_segments(struct the_nilfs *nilfs, | ||
439 | struct nilfs_argv *argv, void *buf) | ||
440 | { | ||
441 | size_t nmembs = argv->v_nmembs; | ||
442 | struct nilfs_sb_info *sbi = nilfs->ns_writer; | ||
443 | int ret; | ||
444 | |||
445 | if (unlikely(!sbi)) { | ||
446 | /* never happens because called for a writable mount */ | ||
447 | WARN_ON(1); | ||
448 | return -EROFS; | ||
449 | } | ||
450 | ret = nilfs_segctor_add_segments_to_be_freed( | ||
451 | NILFS_SC(sbi), buf, nmembs); | ||
452 | |||
453 | return (ret < 0) ? ret : nmembs; | ||
454 | } | ||
455 | |||
456 | int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs, | 438 | int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs, |
457 | struct nilfs_argv *argv, void **kbufs) | 439 | struct nilfs_argv *argv, void **kbufs) |
458 | { | 440 | { |
@@ -491,14 +473,6 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs, | |||
491 | msg = "cannot mark copying blocks dirty"; | 473 | msg = "cannot mark copying blocks dirty"; |
492 | goto failed; | 474 | goto failed; |
493 | } | 475 | } |
494 | ret = nilfs_ioctl_free_segments(nilfs, &argv[4], kbufs[4]); | ||
495 | if (ret < 0) { | ||
496 | /* | ||
497 | * can safely abort because this operation is atomic. | ||
498 | */ | ||
499 | msg = "cannot set segments to be freed"; | ||
500 | goto failed; | ||
501 | } | ||
502 | return 0; | 476 | return 0; |
503 | 477 | ||
504 | failed: | 478 | failed: |
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c index 1e68821b4a9b..dc0277a306ca 100644 --- a/fs/nilfs2/segbuf.c +++ b/fs/nilfs2/segbuf.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/crc32.h> | 26 | #include <linux/crc32.h> |
27 | #include "page.h" | 27 | #include "page.h" |
28 | #include "segbuf.h" | 28 | #include "segbuf.h" |
29 | #include "seglist.h" | ||
30 | 29 | ||
31 | 30 | ||
32 | static struct kmem_cache *nilfs_segbuf_cachep; | 31 | static struct kmem_cache *nilfs_segbuf_cachep; |
diff --git a/fs/nilfs2/seglist.h b/fs/nilfs2/seglist.h index d39df9144e99..e448e40c1ecb 100644 --- a/fs/nilfs2/seglist.h +++ b/fs/nilfs2/seglist.h | |||
@@ -32,11 +32,6 @@ | |||
32 | struct nilfs_segment_entry { | 32 | struct nilfs_segment_entry { |
33 | __u64 segnum; | 33 | __u64 segnum; |
34 | 34 | ||
35 | #define NILFS_SLH_FREED 0x0001 /* The segment was freed provisonally. | ||
36 | It must be cancelled if | ||
37 | construction aborted */ | ||
38 | |||
39 | unsigned flags; | ||
40 | struct list_head list; | 35 | struct list_head list; |
41 | struct buffer_head *bh_su; | 36 | struct buffer_head *bh_su; |
42 | struct nilfs_segment_usage *raw_su; | 37 | struct nilfs_segment_usage *raw_su; |
@@ -52,7 +47,6 @@ nilfs_alloc_segment_entry(__u64 segnum) | |||
52 | 47 | ||
53 | if (likely(ent)) { | 48 | if (likely(ent)) { |
54 | ent->segnum = segnum; | 49 | ent->segnum = segnum; |
55 | ent->flags = 0; | ||
56 | ent->bh_su = NULL; | 50 | ent->bh_su = NULL; |
57 | ent->raw_su = NULL; | 51 | ent->raw_su = NULL; |
58 | INIT_LIST_HEAD(&ent->list); | 52 | INIT_LIST_HEAD(&ent->list); |
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 22c7f65c2403..aa977549919e 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include "sufile.h" | 39 | #include "sufile.h" |
40 | #include "cpfile.h" | 40 | #include "cpfile.h" |
41 | #include "ifile.h" | 41 | #include "ifile.h" |
42 | #include "seglist.h" | ||
43 | #include "segbuf.h" | 42 | #include "segbuf.h" |
44 | 43 | ||
45 | 44 | ||
@@ -79,7 +78,8 @@ enum { | |||
79 | /* State flags of collection */ | 78 | /* State flags of collection */ |
80 | #define NILFS_CF_NODE 0x0001 /* Collecting node blocks */ | 79 | #define NILFS_CF_NODE 0x0001 /* Collecting node blocks */ |
81 | #define NILFS_CF_IFILE_STARTED 0x0002 /* IFILE stage has started */ | 80 | #define NILFS_CF_IFILE_STARTED 0x0002 /* IFILE stage has started */ |
82 | #define NILFS_CF_HISTORY_MASK (NILFS_CF_IFILE_STARTED) | 81 | #define NILFS_CF_SUFREED 0x0004 /* segment usages has been freed */ |
82 | #define NILFS_CF_HISTORY_MASK (NILFS_CF_IFILE_STARTED | NILFS_CF_SUFREED) | ||
83 | 83 | ||
84 | /* Operations depending on the construction mode and file type */ | 84 | /* Operations depending on the construction mode and file type */ |
85 | struct nilfs_sc_operations { | 85 | struct nilfs_sc_operations { |
@@ -810,7 +810,7 @@ static int nilfs_segctor_clean(struct nilfs_sc_info *sci) | |||
810 | { | 810 | { |
811 | return list_empty(&sci->sc_dirty_files) && | 811 | return list_empty(&sci->sc_dirty_files) && |
812 | !test_bit(NILFS_SC_DIRTY, &sci->sc_flags) && | 812 | !test_bit(NILFS_SC_DIRTY, &sci->sc_flags) && |
813 | list_empty(&sci->sc_cleaning_segments) && | 813 | sci->sc_nfreesegs == 0 && |
814 | (!nilfs_doing_gc() || list_empty(&sci->sc_gc_inodes)); | 814 | (!nilfs_doing_gc() || list_empty(&sci->sc_gc_inodes)); |
815 | } | 815 | } |
816 | 816 | ||
@@ -1005,44 +1005,6 @@ static void nilfs_drop_collected_inodes(struct list_head *head) | |||
1005 | } | 1005 | } |
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | static void nilfs_segctor_cancel_free_segments(struct nilfs_sc_info *sci, | ||
1009 | struct inode *sufile) | ||
1010 | |||
1011 | { | ||
1012 | struct list_head *head = &sci->sc_cleaning_segments; | ||
1013 | struct nilfs_segment_entry *ent; | ||
1014 | int err; | ||
1015 | |||
1016 | list_for_each_entry(ent, head, list) { | ||
1017 | if (!(ent->flags & NILFS_SLH_FREED)) | ||
1018 | break; | ||
1019 | err = nilfs_sufile_cancel_free(sufile, ent->segnum); | ||
1020 | WARN_ON(err); /* do not happen */ | ||
1021 | ent->flags &= ~NILFS_SLH_FREED; | ||
1022 | } | ||
1023 | } | ||
1024 | |||
1025 | static int nilfs_segctor_prepare_free_segments(struct nilfs_sc_info *sci, | ||
1026 | struct inode *sufile) | ||
1027 | { | ||
1028 | struct list_head *head = &sci->sc_cleaning_segments; | ||
1029 | struct nilfs_segment_entry *ent; | ||
1030 | int err; | ||
1031 | |||
1032 | list_for_each_entry(ent, head, list) { | ||
1033 | err = nilfs_sufile_free(sufile, ent->segnum); | ||
1034 | if (unlikely(err)) | ||
1035 | return err; | ||
1036 | ent->flags |= NILFS_SLH_FREED; | ||
1037 | } | ||
1038 | return 0; | ||
1039 | } | ||
1040 | |||
1041 | static void nilfs_segctor_commit_free_segments(struct nilfs_sc_info *sci) | ||
1042 | { | ||
1043 | nilfs_dispose_segment_list(&sci->sc_cleaning_segments); | ||
1044 | } | ||
1045 | |||
1046 | static int nilfs_segctor_apply_buffers(struct nilfs_sc_info *sci, | 1008 | static int nilfs_segctor_apply_buffers(struct nilfs_sc_info *sci, |
1047 | struct inode *inode, | 1009 | struct inode *inode, |
1048 | struct list_head *listp, | 1010 | struct list_head *listp, |
@@ -1161,6 +1123,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode) | |||
1161 | struct the_nilfs *nilfs = sbi->s_nilfs; | 1123 | struct the_nilfs *nilfs = sbi->s_nilfs; |
1162 | struct list_head *head; | 1124 | struct list_head *head; |
1163 | struct nilfs_inode_info *ii; | 1125 | struct nilfs_inode_info *ii; |
1126 | size_t ndone; | ||
1164 | int err = 0; | 1127 | int err = 0; |
1165 | 1128 | ||
1166 | switch (sci->sc_stage.scnt) { | 1129 | switch (sci->sc_stage.scnt) { |
@@ -1250,10 +1213,16 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode) | |||
1250 | break; | 1213 | break; |
1251 | sci->sc_stage.scnt++; /* Fall through */ | 1214 | sci->sc_stage.scnt++; /* Fall through */ |
1252 | case NILFS_ST_SUFILE: | 1215 | case NILFS_ST_SUFILE: |
1253 | err = nilfs_segctor_prepare_free_segments(sci, | 1216 | err = nilfs_sufile_freev(nilfs->ns_sufile, sci->sc_freesegs, |
1254 | nilfs->ns_sufile); | 1217 | sci->sc_nfreesegs, &ndone); |
1255 | if (unlikely(err)) | 1218 | if (unlikely(err)) { |
1219 | nilfs_sufile_cancel_freev(nilfs->ns_sufile, | ||
1220 | sci->sc_freesegs, ndone, | ||
1221 | NULL); | ||
1256 | break; | 1222 | break; |
1223 | } | ||
1224 | sci->sc_stage.flags |= NILFS_CF_SUFREED; | ||
1225 | |||
1257 | err = nilfs_segctor_scan_file(sci, nilfs->ns_sufile, | 1226 | err = nilfs_segctor_scan_file(sci, nilfs->ns_sufile, |
1258 | &nilfs_sc_file_ops); | 1227 | &nilfs_sc_file_ops); |
1259 | if (unlikely(err)) | 1228 | if (unlikely(err)) |
@@ -1486,7 +1455,15 @@ static void nilfs_segctor_end_construction(struct nilfs_sc_info *sci, | |||
1486 | { | 1455 | { |
1487 | if (unlikely(err)) { | 1456 | if (unlikely(err)) { |
1488 | nilfs_segctor_free_incomplete_segments(sci, nilfs); | 1457 | nilfs_segctor_free_incomplete_segments(sci, nilfs); |
1489 | nilfs_segctor_cancel_free_segments(sci, nilfs->ns_sufile); | 1458 | if (sci->sc_stage.flags & NILFS_CF_SUFREED) { |
1459 | int ret; | ||
1460 | |||
1461 | ret = nilfs_sufile_cancel_freev(nilfs->ns_sufile, | ||
1462 | sci->sc_freesegs, | ||
1463 | sci->sc_nfreesegs, | ||
1464 | NULL); | ||
1465 | WARN_ON(ret); /* do not happen */ | ||
1466 | } | ||
1490 | } | 1467 | } |
1491 | nilfs_segctor_clear_segment_buffers(sci); | 1468 | nilfs_segctor_clear_segment_buffers(sci); |
1492 | } | 1469 | } |
@@ -1585,7 +1562,13 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci, | |||
1585 | if (mode != SC_LSEG_SR || sci->sc_stage.scnt < NILFS_ST_CPFILE) | 1562 | if (mode != SC_LSEG_SR || sci->sc_stage.scnt < NILFS_ST_CPFILE) |
1586 | break; | 1563 | break; |
1587 | 1564 | ||
1588 | nilfs_segctor_cancel_free_segments(sci, nilfs->ns_sufile); | 1565 | if (sci->sc_stage.flags & NILFS_CF_SUFREED) { |
1566 | err = nilfs_sufile_cancel_freev(nilfs->ns_sufile, | ||
1567 | sci->sc_freesegs, | ||
1568 | sci->sc_nfreesegs, | ||
1569 | NULL); | ||
1570 | WARN_ON(err); /* do not happen */ | ||
1571 | } | ||
1589 | nilfs_segctor_clear_segment_buffers(sci); | 1572 | nilfs_segctor_clear_segment_buffers(sci); |
1590 | 1573 | ||
1591 | err = nilfs_segctor_extend_segments(sci, nilfs, nadd); | 1574 | err = nilfs_segctor_extend_segments(sci, nilfs, nadd); |
@@ -2224,10 +2207,8 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | |||
2224 | nilfs_segctor_complete_write(sci); | 2207 | nilfs_segctor_complete_write(sci); |
2225 | 2208 | ||
2226 | /* Commit segments */ | 2209 | /* Commit segments */ |
2227 | if (has_sr) { | 2210 | if (has_sr) |
2228 | nilfs_segctor_commit_free_segments(sci); | ||
2229 | nilfs_segctor_clear_metadata_dirty(sci); | 2211 | nilfs_segctor_clear_metadata_dirty(sci); |
2230 | } | ||
2231 | 2212 | ||
2232 | nilfs_segctor_end_construction(sci, nilfs, 0); | 2213 | nilfs_segctor_end_construction(sci, nilfs, 0); |
2233 | 2214 | ||
@@ -2301,48 +2282,6 @@ void nilfs_flush_segment(struct super_block *sb, ino_t ino) | |||
2301 | /* assign bit 0 to data files */ | 2282 | /* assign bit 0 to data files */ |
2302 | } | 2283 | } |
2303 | 2284 | ||
2304 | int nilfs_segctor_add_segments_to_be_freed(struct nilfs_sc_info *sci, | ||
2305 | __u64 *segnum, size_t nsegs) | ||
2306 | { | ||
2307 | struct nilfs_segment_entry *ent; | ||
2308 | struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs; | ||
2309 | struct inode *sufile = nilfs->ns_sufile; | ||
2310 | LIST_HEAD(list); | ||
2311 | __u64 *pnum; | ||
2312 | size_t i; | ||
2313 | int err; | ||
2314 | |||
2315 | for (pnum = segnum, i = 0; i < nsegs; pnum++, i++) { | ||
2316 | ent = nilfs_alloc_segment_entry(*pnum); | ||
2317 | if (unlikely(!ent)) { | ||
2318 | err = -ENOMEM; | ||
2319 | goto failed; | ||
2320 | } | ||
2321 | list_add_tail(&ent->list, &list); | ||
2322 | |||
2323 | err = nilfs_open_segment_entry(ent, sufile); | ||
2324 | if (unlikely(err)) | ||
2325 | goto failed; | ||
2326 | |||
2327 | if (unlikely(!nilfs_segment_usage_dirty(ent->raw_su))) | ||
2328 | printk(KERN_WARNING "NILFS: unused segment is " | ||
2329 | "requested to be cleaned (segnum=%llu)\n", | ||
2330 | (unsigned long long)ent->segnum); | ||
2331 | nilfs_close_segment_entry(ent, sufile); | ||
2332 | } | ||
2333 | list_splice(&list, sci->sc_cleaning_segments.prev); | ||
2334 | return 0; | ||
2335 | |||
2336 | failed: | ||
2337 | nilfs_dispose_segment_list(&list); | ||
2338 | return err; | ||
2339 | } | ||
2340 | |||
2341 | void nilfs_segctor_clear_segments_to_be_freed(struct nilfs_sc_info *sci) | ||
2342 | { | ||
2343 | nilfs_dispose_segment_list(&sci->sc_cleaning_segments); | ||
2344 | } | ||
2345 | |||
2346 | struct nilfs_segctor_wait_request { | 2285 | struct nilfs_segctor_wait_request { |
2347 | wait_queue_t wq; | 2286 | wait_queue_t wq; |
2348 | __u32 seq; | 2287 | __u32 seq; |
@@ -2607,10 +2546,13 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv, | |||
2607 | err = nilfs_init_gcdat_inode(nilfs); | 2546 | err = nilfs_init_gcdat_inode(nilfs); |
2608 | if (unlikely(err)) | 2547 | if (unlikely(err)) |
2609 | goto out_unlock; | 2548 | goto out_unlock; |
2549 | |||
2610 | err = nilfs_ioctl_prepare_clean_segments(nilfs, argv, kbufs); | 2550 | err = nilfs_ioctl_prepare_clean_segments(nilfs, argv, kbufs); |
2611 | if (unlikely(err)) | 2551 | if (unlikely(err)) |
2612 | goto out_unlock; | 2552 | goto out_unlock; |
2613 | 2553 | ||
2554 | sci->sc_freesegs = kbufs[4]; | ||
2555 | sci->sc_nfreesegs = argv[4].v_nmembs; | ||
2614 | list_splice_init(&nilfs->ns_gc_inodes, sci->sc_gc_inodes.prev); | 2556 | list_splice_init(&nilfs->ns_gc_inodes, sci->sc_gc_inodes.prev); |
2615 | 2557 | ||
2616 | for (;;) { | 2558 | for (;;) { |
@@ -2629,6 +2571,8 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv, | |||
2629 | } | 2571 | } |
2630 | 2572 | ||
2631 | out_unlock: | 2573 | out_unlock: |
2574 | sci->sc_freesegs = NULL; | ||
2575 | sci->sc_nfreesegs = 0; | ||
2632 | nilfs_clear_gcdat_inode(nilfs); | 2576 | nilfs_clear_gcdat_inode(nilfs); |
2633 | nilfs_transaction_unlock(sbi); | 2577 | nilfs_transaction_unlock(sbi); |
2634 | return err; | 2578 | return err; |
@@ -2835,7 +2779,6 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi) | |||
2835 | INIT_LIST_HEAD(&sci->sc_dirty_files); | 2779 | INIT_LIST_HEAD(&sci->sc_dirty_files); |
2836 | INIT_LIST_HEAD(&sci->sc_segbufs); | 2780 | INIT_LIST_HEAD(&sci->sc_segbufs); |
2837 | INIT_LIST_HEAD(&sci->sc_gc_inodes); | 2781 | INIT_LIST_HEAD(&sci->sc_gc_inodes); |
2838 | INIT_LIST_HEAD(&sci->sc_cleaning_segments); | ||
2839 | INIT_LIST_HEAD(&sci->sc_copied_buffers); | 2782 | INIT_LIST_HEAD(&sci->sc_copied_buffers); |
2840 | 2783 | ||
2841 | sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT; | 2784 | sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT; |
@@ -2901,9 +2844,6 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | |||
2901 | nilfs_dispose_list(sbi, &sci->sc_dirty_files, 1); | 2844 | nilfs_dispose_list(sbi, &sci->sc_dirty_files, 1); |
2902 | } | 2845 | } |
2903 | 2846 | ||
2904 | if (!list_empty(&sci->sc_cleaning_segments)) | ||
2905 | nilfs_dispose_segment_list(&sci->sc_cleaning_segments); | ||
2906 | |||
2907 | WARN_ON(!list_empty(&sci->sc_segbufs)); | 2847 | WARN_ON(!list_empty(&sci->sc_segbufs)); |
2908 | 2848 | ||
2909 | down_write(&sbi->s_nilfs->ns_segctor_sem); | 2849 | down_write(&sbi->s_nilfs->ns_segctor_sem); |
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h index 476bdd5df5be..f36a851738e4 100644 --- a/fs/nilfs2/segment.h +++ b/fs/nilfs2/segment.h | |||
@@ -90,8 +90,9 @@ struct nilfs_segsum_pointer { | |||
90 | * @sc_nblk_inc: Block count of current generation | 90 | * @sc_nblk_inc: Block count of current generation |
91 | * @sc_dirty_files: List of files to be written | 91 | * @sc_dirty_files: List of files to be written |
92 | * @sc_gc_inodes: List of GC inodes having blocks to be written | 92 | * @sc_gc_inodes: List of GC inodes having blocks to be written |
93 | * @sc_cleaning_segments: List of segments to be freed through construction | ||
94 | * @sc_copied_buffers: List of copied buffers (buffer heads) to freeze data | 93 | * @sc_copied_buffers: List of copied buffers (buffer heads) to freeze data |
94 | * @sc_freesegs: array of segment numbers to be freed | ||
95 | * @sc_nfreesegs: number of segments on @sc_freesegs | ||
95 | * @sc_dsync_inode: inode whose data pages are written for a sync operation | 96 | * @sc_dsync_inode: inode whose data pages are written for a sync operation |
96 | * @sc_dsync_start: start byte offset of data pages | 97 | * @sc_dsync_start: start byte offset of data pages |
97 | * @sc_dsync_end: end byte offset of data pages (inclusive) | 98 | * @sc_dsync_end: end byte offset of data pages (inclusive) |
@@ -131,9 +132,11 @@ struct nilfs_sc_info { | |||
131 | 132 | ||
132 | struct list_head sc_dirty_files; | 133 | struct list_head sc_dirty_files; |
133 | struct list_head sc_gc_inodes; | 134 | struct list_head sc_gc_inodes; |
134 | struct list_head sc_cleaning_segments; | ||
135 | struct list_head sc_copied_buffers; | 135 | struct list_head sc_copied_buffers; |
136 | 136 | ||
137 | __u64 *sc_freesegs; | ||
138 | size_t sc_nfreesegs; | ||
139 | |||
137 | struct nilfs_inode_info *sc_dsync_inode; | 140 | struct nilfs_inode_info *sc_dsync_inode; |
138 | loff_t sc_dsync_start; | 141 | loff_t sc_dsync_start; |
139 | loff_t sc_dsync_end; | 142 | loff_t sc_dsync_end; |
@@ -225,10 +228,6 @@ extern void nilfs_flush_segment(struct super_block *, ino_t); | |||
225 | extern int nilfs_clean_segments(struct super_block *, struct nilfs_argv *, | 228 | extern int nilfs_clean_segments(struct super_block *, struct nilfs_argv *, |
226 | void **); | 229 | void **); |
227 | 230 | ||
228 | extern int nilfs_segctor_add_segments_to_be_freed(struct nilfs_sc_info *, | ||
229 | __u64 *, size_t); | ||
230 | extern void nilfs_segctor_clear_segments_to_be_freed(struct nilfs_sc_info *); | ||
231 | |||
232 | extern int nilfs_attach_segment_constructor(struct nilfs_sb_info *); | 231 | extern int nilfs_attach_segment_constructor(struct nilfs_sb_info *); |
233 | extern void nilfs_detach_segment_constructor(struct nilfs_sb_info *); | 232 | extern void nilfs_detach_segment_constructor(struct nilfs_sb_info *); |
234 | 233 | ||
diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h index e8e26279c261..fd6232e365ca 100644 --- a/fs/nilfs2/sufile.h +++ b/fs/nilfs2/sufile.h | |||
@@ -54,36 +54,16 @@ int nilfs_sufile_update(struct inode *, __u64, int, | |||
54 | void (*dofunc)(struct inode *, __u64, | 54 | void (*dofunc)(struct inode *, __u64, |
55 | struct buffer_head *, | 55 | struct buffer_head *, |
56 | struct buffer_head *)); | 56 | struct buffer_head *)); |
57 | void nilfs_sufile_do_cancel_free(struct inode *, __u64, struct buffer_head *, | ||
58 | struct buffer_head *); | ||
59 | void nilfs_sufile_do_scrap(struct inode *, __u64, struct buffer_head *, | 57 | void nilfs_sufile_do_scrap(struct inode *, __u64, struct buffer_head *, |
60 | struct buffer_head *); | 58 | struct buffer_head *); |
61 | void nilfs_sufile_do_free(struct inode *, __u64, struct buffer_head *, | 59 | void nilfs_sufile_do_free(struct inode *, __u64, struct buffer_head *, |
62 | struct buffer_head *); | 60 | struct buffer_head *); |
61 | void nilfs_sufile_do_cancel_free(struct inode *, __u64, struct buffer_head *, | ||
62 | struct buffer_head *); | ||
63 | void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *, | 63 | void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *, |
64 | struct buffer_head *); | 64 | struct buffer_head *); |
65 | 65 | ||
66 | /** | 66 | /** |
67 | * nilfs_sufile_cancel_free - | ||
68 | * @sufile: inode of segment usage file | ||
69 | * @segnum: segment number | ||
70 | * | ||
71 | * Description: | ||
72 | * | ||
73 | * Return Value: On success, 0 is returned. On error, one of the following | ||
74 | * negative error codes is returned. | ||
75 | * | ||
76 | * %-EIO - I/O error. | ||
77 | * | ||
78 | * %-ENOMEM - Insufficient amount of memory available. | ||
79 | */ | ||
80 | static inline int nilfs_sufile_cancel_free(struct inode *sufile, __u64 segnum) | ||
81 | { | ||
82 | return nilfs_sufile_update(sufile, segnum, 0, | ||
83 | nilfs_sufile_do_cancel_free); | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * nilfs_sufile_scrap - make a segment garbage | 67 | * nilfs_sufile_scrap - make a segment garbage |
88 | * @sufile: inode of segment usage file | 68 | * @sufile: inode of segment usage file |
89 | * @segnum: segment number to be freed | 69 | * @segnum: segment number to be freed |
@@ -104,6 +84,38 @@ static inline int nilfs_sufile_free(struct inode *sufile, __u64 segnum) | |||
104 | } | 84 | } |
105 | 85 | ||
106 | /** | 86 | /** |
87 | * nilfs_sufile_freev - free segments | ||
88 | * @sufile: inode of segment usage file | ||
89 | * @segnumv: array of segment numbers | ||
90 | * @nsegs: size of @segnumv array | ||
91 | * @ndone: place to store the number of freed segments | ||
92 | */ | ||
93 | static inline int nilfs_sufile_freev(struct inode *sufile, __u64 *segnumv, | ||
94 | size_t nsegs, size_t *ndone) | ||
95 | { | ||
96 | return nilfs_sufile_updatev(sufile, segnumv, nsegs, 0, ndone, | ||
97 | nilfs_sufile_do_free); | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * nilfs_sufile_cancel_freev - reallocate freeing segments | ||
102 | * @sufile: inode of segment usage file | ||
103 | * @segnumv: array of segment numbers | ||
104 | * @nsegs: size of @segnumv array | ||
105 | * @ndone: place to store the number of cancelled segments | ||
106 | * | ||
107 | * Return Value: On success, 0 is returned. On error, a negative error codes | ||
108 | * is returned. | ||
109 | */ | ||
110 | static inline int nilfs_sufile_cancel_freev(struct inode *sufile, | ||
111 | __u64 *segnumv, size_t nsegs, | ||
112 | size_t *ndone) | ||
113 | { | ||
114 | return nilfs_sufile_updatev(sufile, segnumv, nsegs, 0, ndone, | ||
115 | nilfs_sufile_do_cancel_free); | ||
116 | } | ||
117 | |||
118 | /** | ||
107 | * nilfs_sufile_set_error - mark a segment as erroneous | 119 | * nilfs_sufile_set_error - mark a segment as erroneous |
108 | * @sufile: inode of segment usage file | 120 | * @sufile: inode of segment usage file |
109 | * @segnum: segment number | 121 | * @segnum: segment number |