aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2009-05-16 10:44:55 -0400
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2009-06-10 10:41:09 -0400
commit071cb4b81987a28c7ac2702003cff3e61684a630 (patch)
tree41e2f5a6d0e12d4ccc49850992ce6bfee68dd00e /fs/nilfs2
parentdda54f4b872512eba484c38631bd6ae5b5716f41 (diff)
nilfs2: eliminate removal list of segments
This will clean up the removal list of segments and the related functions from segment.c and ioctl.c, which have hurt code readability. This elimination is applied by using nilfs_sufile_updatev() previously introduced in the patch ("nilfs2: add sufile function that can modify multiple segment usages"). Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Diffstat (limited to 'fs/nilfs2')
-rw-r--r--fs/nilfs2/ioctl.c26
-rw-r--r--fs/nilfs2/segbuf.c1
-rw-r--r--fs/nilfs2/seglist.h6
-rw-r--r--fs/nilfs2/segment.c130
-rw-r--r--fs/nilfs2/segment.h11
-rw-r--r--fs/nilfs2/sufile.h56
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
438static 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
456int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs, 438int 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
32static struct kmem_cache *nilfs_segbuf_cachep; 31static 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 @@
32struct nilfs_segment_entry { 32struct 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 */
85struct nilfs_sc_operations { 85struct 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
1008static 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
1025static 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
1041static void nilfs_segctor_commit_free_segments(struct nilfs_sc_info *sci)
1042{
1043 nilfs_dispose_segment_list(&sci->sc_cleaning_segments);
1044}
1045
1046static int nilfs_segctor_apply_buffers(struct nilfs_sc_info *sci, 1008static 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
2304int 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
2341void nilfs_segctor_clear_segments_to_be_freed(struct nilfs_sc_info *sci)
2342{
2343 nilfs_dispose_segment_list(&sci->sc_cleaning_segments);
2344}
2345
2346struct nilfs_segctor_wait_request { 2285struct 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);
225extern int nilfs_clean_segments(struct super_block *, struct nilfs_argv *, 228extern int nilfs_clean_segments(struct super_block *, struct nilfs_argv *,
226 void **); 229 void **);
227 230
228extern int nilfs_segctor_add_segments_to_be_freed(struct nilfs_sc_info *,
229 __u64 *, size_t);
230extern void nilfs_segctor_clear_segments_to_be_freed(struct nilfs_sc_info *);
231
232extern int nilfs_attach_segment_constructor(struct nilfs_sb_info *); 231extern int nilfs_attach_segment_constructor(struct nilfs_sb_info *);
233extern void nilfs_detach_segment_constructor(struct nilfs_sb_info *); 232extern 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 *));
57void nilfs_sufile_do_cancel_free(struct inode *, __u64, struct buffer_head *,
58 struct buffer_head *);
59void nilfs_sufile_do_scrap(struct inode *, __u64, struct buffer_head *, 57void nilfs_sufile_do_scrap(struct inode *, __u64, struct buffer_head *,
60 struct buffer_head *); 58 struct buffer_head *);
61void nilfs_sufile_do_free(struct inode *, __u64, struct buffer_head *, 59void nilfs_sufile_do_free(struct inode *, __u64, struct buffer_head *,
62 struct buffer_head *); 60 struct buffer_head *);
61void nilfs_sufile_do_cancel_free(struct inode *, __u64, struct buffer_head *,
62 struct buffer_head *);
63void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *, 63void 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 */
80static 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 */
93static 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 */
110static 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