Commit e29df395 authored by Ryusuke Konishi's avatar Ryusuke Konishi

nilfs2: add iterator for segment buffers

This adds a few iterator functions for segment buffers to make it easy
to handle multiple series of logs.
Signed-off-by: default avatarRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
parent 9c965bac
...@@ -234,7 +234,7 @@ void nilfs_segbuf_fill_in_data_crc(struct nilfs_segment_buffer *segbuf, ...@@ -234,7 +234,7 @@ void nilfs_segbuf_fill_in_data_crc(struct nilfs_segment_buffer *segbuf,
raw_sum->ss_datasum = cpu_to_le32(crc); raw_sum->ss_datasum = cpu_to_le32(crc);
} }
void nilfs_release_buffers(struct list_head *list) static void nilfs_release_buffers(struct list_head *list)
{ {
struct buffer_head *bh, *n; struct buffer_head *bh, *n;
...@@ -256,6 +256,49 @@ void nilfs_release_buffers(struct list_head *list) ...@@ -256,6 +256,49 @@ void nilfs_release_buffers(struct list_head *list)
} }
} }
static void nilfs_segbuf_clear(struct nilfs_segment_buffer *segbuf)
{
nilfs_release_buffers(&segbuf->sb_segsum_buffers);
nilfs_release_buffers(&segbuf->sb_payload_buffers);
}
/*
* Iterators for segment buffers
*/
void nilfs_clear_logs(struct list_head *logs)
{
struct nilfs_segment_buffer *segbuf;
list_for_each_entry(segbuf, logs, sb_list)
nilfs_segbuf_clear(segbuf);
}
void nilfs_truncate_logs(struct list_head *logs,
struct nilfs_segment_buffer *last)
{
struct nilfs_segment_buffer *n, *segbuf;
segbuf = list_prepare_entry(last, logs, sb_list);
list_for_each_entry_safe_continue(segbuf, n, logs, sb_list) {
list_del_init(&segbuf->sb_list);
nilfs_segbuf_clear(segbuf);
nilfs_segbuf_free(segbuf);
}
}
int nilfs_wait_on_logs(struct list_head *logs)
{
struct nilfs_segment_buffer *segbuf;
int err;
list_for_each_entry(segbuf, logs, sb_list) {
err = nilfs_segbuf_wait(segbuf);
if (err)
return err;
}
return 0;
}
/* /*
* BIO operations * BIO operations
*/ */
......
...@@ -164,16 +164,18 @@ nilfs_segbuf_add_file_buffer(struct nilfs_segment_buffer *segbuf, ...@@ -164,16 +164,18 @@ nilfs_segbuf_add_file_buffer(struct nilfs_segment_buffer *segbuf,
segbuf->sb_sum.nfileblk++; segbuf->sb_sum.nfileblk++;
} }
void nilfs_release_buffers(struct list_head *);
static inline void nilfs_segbuf_clear(struct nilfs_segment_buffer *segbuf)
{
nilfs_release_buffers(&segbuf->sb_segsum_buffers);
nilfs_release_buffers(&segbuf->sb_payload_buffers);
}
int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf, int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
struct the_nilfs *nilfs); struct the_nilfs *nilfs);
int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf); int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf);
void nilfs_clear_logs(struct list_head *logs);
void nilfs_truncate_logs(struct list_head *logs,
struct nilfs_segment_buffer *last);
int nilfs_wait_on_logs(struct list_head *logs);
static inline void nilfs_destroy_logs(struct list_head *logs)
{
nilfs_truncate_logs(logs, NULL);
}
#endif /* _NILFS_SEGBUF_H */ #endif /* _NILFS_SEGBUF_H */
...@@ -1276,7 +1276,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode) ...@@ -1276,7 +1276,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci, static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci,
struct the_nilfs *nilfs) struct the_nilfs *nilfs)
{ {
struct nilfs_segment_buffer *segbuf, *n; struct nilfs_segment_buffer *segbuf;
__u64 nextnum; __u64 nextnum;
int err; int err;
...@@ -1313,18 +1313,14 @@ static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci, ...@@ -1313,18 +1313,14 @@ static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci,
nilfs_segbuf_set_next_segnum(segbuf, nextnum, nilfs); nilfs_segbuf_set_next_segnum(segbuf, nextnum, nilfs);
/* truncating segment buffers */ /* truncating segment buffers */
list_for_each_entry_safe_continue(segbuf, n, &sci->sc_segbufs, nilfs_truncate_logs(&sci->sc_segbufs, segbuf);
sb_list) {
list_del_init(&segbuf->sb_list);
nilfs_segbuf_free(segbuf);
}
return 0; return 0;
} }
static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci, static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci,
struct the_nilfs *nilfs, int nadd) struct the_nilfs *nilfs, int nadd)
{ {
struct nilfs_segment_buffer *segbuf, *prev, *n; struct nilfs_segment_buffer *segbuf, *prev;
struct inode *sufile = nilfs->ns_sufile; struct inode *sufile = nilfs->ns_sufile;
__u64 nextnextnum; __u64 nextnextnum;
LIST_HEAD(list); LIST_HEAD(list);
...@@ -1369,12 +1365,11 @@ static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci, ...@@ -1369,12 +1365,11 @@ static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci,
failed_segbuf: failed_segbuf:
nilfs_segbuf_free(segbuf); nilfs_segbuf_free(segbuf);
failed: failed:
list_for_each_entry_safe(segbuf, n, &list, sb_list) { list_for_each_entry(segbuf, &list, sb_list) {
ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum); ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
WARN_ON(ret); /* never fails */ WARN_ON(ret); /* never fails */
list_del_init(&segbuf->sb_list);
nilfs_segbuf_free(segbuf);
} }
nilfs_destroy_logs(&list);
return err; return err;
} }
...@@ -1411,27 +1406,6 @@ static void nilfs_segctor_free_incomplete_segments(struct nilfs_sc_info *sci, ...@@ -1411,27 +1406,6 @@ static void nilfs_segctor_free_incomplete_segments(struct nilfs_sc_info *sci,
} }
} }
static void nilfs_segctor_clear_segment_buffers(struct nilfs_sc_info *sci)
{
struct nilfs_segment_buffer *segbuf;
list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list)
nilfs_segbuf_clear(segbuf);
sci->sc_super_root = NULL;
}
static void nilfs_segctor_destroy_segment_buffers(struct nilfs_sc_info *sci)
{
struct nilfs_segment_buffer *segbuf;
while (!list_empty(&sci->sc_segbufs)) {
segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
list_del_init(&segbuf->sb_list);
nilfs_segbuf_free(segbuf);
}
/* sci->sc_curseg = NULL; */
}
static void nilfs_segctor_end_construction(struct nilfs_sc_info *sci, static void nilfs_segctor_end_construction(struct nilfs_sc_info *sci,
struct the_nilfs *nilfs, int err) struct the_nilfs *nilfs, int err)
{ {
...@@ -1447,7 +1421,8 @@ static void nilfs_segctor_end_construction(struct nilfs_sc_info *sci, ...@@ -1447,7 +1421,8 @@ static void nilfs_segctor_end_construction(struct nilfs_sc_info *sci,
WARN_ON(ret); /* do not happen */ WARN_ON(ret); /* do not happen */
} }
} }
nilfs_segctor_clear_segment_buffers(sci); nilfs_clear_logs(&sci->sc_segbufs);
sci->sc_super_root = NULL;
} }
static void nilfs_segctor_update_segusage(struct nilfs_sc_info *sci, static void nilfs_segctor_update_segusage(struct nilfs_sc_info *sci,
...@@ -1490,17 +1465,15 @@ static void nilfs_segctor_truncate_segments(struct nilfs_sc_info *sci, ...@@ -1490,17 +1465,15 @@ static void nilfs_segctor_truncate_segments(struct nilfs_sc_info *sci,
struct nilfs_segment_buffer *last, struct nilfs_segment_buffer *last,
struct inode *sufile) struct inode *sufile)
{ {
struct nilfs_segment_buffer *segbuf = last, *n; struct nilfs_segment_buffer *segbuf = last;
int ret; int ret;
list_for_each_entry_safe_continue(segbuf, n, &sci->sc_segbufs, list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) {
sb_list) {
list_del_init(&segbuf->sb_list);
sci->sc_segbuf_nblocks -= segbuf->sb_rest_blocks; sci->sc_segbuf_nblocks -= segbuf->sb_rest_blocks;
ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum); ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
WARN_ON(ret); WARN_ON(ret);
nilfs_segbuf_free(segbuf);
} }
nilfs_truncate_logs(&sci->sc_segbufs, last);
} }
...@@ -1539,7 +1512,7 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci, ...@@ -1539,7 +1512,7 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
NULL); NULL);
WARN_ON(err); /* do not happen */ WARN_ON(err); /* do not happen */
} }
nilfs_segctor_clear_segment_buffers(sci); nilfs_clear_logs(&sci->sc_segbufs);
err = nilfs_segctor_extend_segments(sci, nilfs, nadd); err = nilfs_segctor_extend_segments(sci, nilfs, nadd);
if (unlikely(err)) if (unlikely(err))
...@@ -2179,7 +2152,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) ...@@ -2179,7 +2152,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
} while (sci->sc_stage.scnt != NILFS_ST_DONE); } while (sci->sc_stage.scnt != NILFS_ST_DONE);
out: out:
nilfs_segctor_destroy_segment_buffers(sci); nilfs_destroy_logs(&sci->sc_segbufs);
nilfs_segctor_check_out_files(sci, sbi); nilfs_segctor_check_out_files(sci, sbi);
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment