diff options
Diffstat (limited to 'fs/nilfs2/segbuf.c')
-rw-r--r-- | fs/nilfs2/segbuf.c | 70 |
1 files changed, 40 insertions, 30 deletions
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c index 17851f77f73..2e6a2723b8f 100644 --- a/fs/nilfs2/segbuf.c +++ b/fs/nilfs2/segbuf.c | |||
@@ -40,35 +40,10 @@ struct nilfs_write_info { | |||
40 | sector_t blocknr; | 40 | sector_t blocknr; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | |||
44 | static int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf, | 43 | static int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf, |
45 | struct the_nilfs *nilfs); | 44 | struct the_nilfs *nilfs); |
46 | static int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf); | 45 | static int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf); |
47 | 46 | ||
48 | |||
49 | static struct kmem_cache *nilfs_segbuf_cachep; | ||
50 | |||
51 | static void nilfs_segbuf_init_once(void *obj) | ||
52 | { | ||
53 | memset(obj, 0, sizeof(struct nilfs_segment_buffer)); | ||
54 | } | ||
55 | |||
56 | int __init nilfs_init_segbuf_cache(void) | ||
57 | { | ||
58 | nilfs_segbuf_cachep = | ||
59 | kmem_cache_create("nilfs2_segbuf_cache", | ||
60 | sizeof(struct nilfs_segment_buffer), | ||
61 | 0, SLAB_RECLAIM_ACCOUNT, | ||
62 | nilfs_segbuf_init_once); | ||
63 | |||
64 | return (nilfs_segbuf_cachep == NULL) ? -ENOMEM : 0; | ||
65 | } | ||
66 | |||
67 | void nilfs_destroy_segbuf_cache(void) | ||
68 | { | ||
69 | kmem_cache_destroy(nilfs_segbuf_cachep); | ||
70 | } | ||
71 | |||
72 | struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *sb) | 47 | struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *sb) |
73 | { | 48 | { |
74 | struct nilfs_segment_buffer *segbuf; | 49 | struct nilfs_segment_buffer *segbuf; |
@@ -81,6 +56,7 @@ struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *sb) | |||
81 | INIT_LIST_HEAD(&segbuf->sb_list); | 56 | INIT_LIST_HEAD(&segbuf->sb_list); |
82 | INIT_LIST_HEAD(&segbuf->sb_segsum_buffers); | 57 | INIT_LIST_HEAD(&segbuf->sb_segsum_buffers); |
83 | INIT_LIST_HEAD(&segbuf->sb_payload_buffers); | 58 | INIT_LIST_HEAD(&segbuf->sb_payload_buffers); |
59 | segbuf->sb_super_root = NULL; | ||
84 | 60 | ||
85 | init_completion(&segbuf->sb_bio_event); | 61 | init_completion(&segbuf->sb_bio_event); |
86 | atomic_set(&segbuf->sb_err, 0); | 62 | atomic_set(&segbuf->sb_err, 0); |
@@ -158,7 +134,7 @@ int nilfs_segbuf_extend_payload(struct nilfs_segment_buffer *segbuf, | |||
158 | } | 134 | } |
159 | 135 | ||
160 | int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned flags, | 136 | int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned flags, |
161 | time_t ctime) | 137 | time_t ctime, __u64 cno) |
162 | { | 138 | { |
163 | int err; | 139 | int err; |
164 | 140 | ||
@@ -171,6 +147,7 @@ int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned flags, | |||
171 | segbuf->sb_sum.sumbytes = sizeof(struct nilfs_segment_summary); | 147 | segbuf->sb_sum.sumbytes = sizeof(struct nilfs_segment_summary); |
172 | segbuf->sb_sum.nfinfo = segbuf->sb_sum.nfileblk = 0; | 148 | segbuf->sb_sum.nfinfo = segbuf->sb_sum.nfileblk = 0; |
173 | segbuf->sb_sum.ctime = ctime; | 149 | segbuf->sb_sum.ctime = ctime; |
150 | segbuf->sb_sum.cno = cno; | ||
174 | return 0; | 151 | return 0; |
175 | } | 152 | } |
176 | 153 | ||
@@ -196,13 +173,14 @@ void nilfs_segbuf_fill_in_segsum(struct nilfs_segment_buffer *segbuf) | |||
196 | raw_sum->ss_nfinfo = cpu_to_le32(segbuf->sb_sum.nfinfo); | 173 | raw_sum->ss_nfinfo = cpu_to_le32(segbuf->sb_sum.nfinfo); |
197 | raw_sum->ss_sumbytes = cpu_to_le32(segbuf->sb_sum.sumbytes); | 174 | raw_sum->ss_sumbytes = cpu_to_le32(segbuf->sb_sum.sumbytes); |
198 | raw_sum->ss_pad = 0; | 175 | raw_sum->ss_pad = 0; |
176 | raw_sum->ss_cno = cpu_to_le64(segbuf->sb_sum.cno); | ||
199 | } | 177 | } |
200 | 178 | ||
201 | /* | 179 | /* |
202 | * CRC calculation routines | 180 | * CRC calculation routines |
203 | */ | 181 | */ |
204 | void nilfs_segbuf_fill_in_segsum_crc(struct nilfs_segment_buffer *segbuf, | 182 | static void |
205 | u32 seed) | 183 | nilfs_segbuf_fill_in_segsum_crc(struct nilfs_segment_buffer *segbuf, u32 seed) |
206 | { | 184 | { |
207 | struct buffer_head *bh; | 185 | struct buffer_head *bh; |
208 | struct nilfs_segment_summary *raw_sum; | 186 | struct nilfs_segment_summary *raw_sum; |
@@ -229,8 +207,8 @@ void nilfs_segbuf_fill_in_segsum_crc(struct nilfs_segment_buffer *segbuf, | |||
229 | raw_sum->ss_sumsum = cpu_to_le32(crc); | 207 | raw_sum->ss_sumsum = cpu_to_le32(crc); |
230 | } | 208 | } |
231 | 209 | ||
232 | void nilfs_segbuf_fill_in_data_crc(struct nilfs_segment_buffer *segbuf, | 210 | static void nilfs_segbuf_fill_in_data_crc(struct nilfs_segment_buffer *segbuf, |
233 | u32 seed) | 211 | u32 seed) |
234 | { | 212 | { |
235 | struct buffer_head *bh; | 213 | struct buffer_head *bh; |
236 | struct nilfs_segment_summary *raw_sum; | 214 | struct nilfs_segment_summary *raw_sum; |
@@ -256,6 +234,20 @@ void nilfs_segbuf_fill_in_data_crc(struct nilfs_segment_buffer *segbuf, | |||
256 | raw_sum->ss_datasum = cpu_to_le32(crc); | 234 | raw_sum->ss_datasum = cpu_to_le32(crc); |
257 | } | 235 | } |
258 | 236 | ||
237 | static void | ||
238 | nilfs_segbuf_fill_in_super_root_crc(struct nilfs_segment_buffer *segbuf, | ||
239 | u32 seed) | ||
240 | { | ||
241 | struct nilfs_super_root *raw_sr; | ||
242 | u32 crc; | ||
243 | |||
244 | raw_sr = (struct nilfs_super_root *)segbuf->sb_super_root->b_data; | ||
245 | crc = crc32_le(seed, | ||
246 | (unsigned char *)raw_sr + sizeof(raw_sr->sr_sum), | ||
247 | NILFS_SR_BYTES - sizeof(raw_sr->sr_sum)); | ||
248 | raw_sr->sr_sum = cpu_to_le32(crc); | ||
249 | } | ||
250 | |||
259 | static void nilfs_release_buffers(struct list_head *list) | 251 | static void nilfs_release_buffers(struct list_head *list) |
260 | { | 252 | { |
261 | struct buffer_head *bh, *n; | 253 | struct buffer_head *bh, *n; |
@@ -282,6 +274,7 @@ static void nilfs_segbuf_clear(struct nilfs_segment_buffer *segbuf) | |||
282 | { | 274 | { |
283 | nilfs_release_buffers(&segbuf->sb_segsum_buffers); | 275 | nilfs_release_buffers(&segbuf->sb_segsum_buffers); |
284 | nilfs_release_buffers(&segbuf->sb_payload_buffers); | 276 | nilfs_release_buffers(&segbuf->sb_payload_buffers); |
277 | segbuf->sb_super_root = NULL; | ||
285 | } | 278 | } |
286 | 279 | ||
287 | /* | 280 | /* |
@@ -334,6 +327,23 @@ int nilfs_wait_on_logs(struct list_head *logs) | |||
334 | return ret; | 327 | return ret; |
335 | } | 328 | } |
336 | 329 | ||
330 | /** | ||
331 | * nilfs_add_checksums_on_logs - add checksums on the logs | ||
332 | * @logs: list of segment buffers storing target logs | ||
333 | * @seed: checksum seed value | ||
334 | */ | ||
335 | void nilfs_add_checksums_on_logs(struct list_head *logs, u32 seed) | ||
336 | { | ||
337 | struct nilfs_segment_buffer *segbuf; | ||
338 | |||
339 | list_for_each_entry(segbuf, logs, sb_list) { | ||
340 | if (segbuf->sb_super_root) | ||
341 | nilfs_segbuf_fill_in_super_root_crc(segbuf, seed); | ||
342 | nilfs_segbuf_fill_in_segsum_crc(segbuf, seed); | ||
343 | nilfs_segbuf_fill_in_data_crc(segbuf, seed); | ||
344 | } | ||
345 | } | ||
346 | |||
337 | /* | 347 | /* |
338 | * BIO operations | 348 | * BIO operations |
339 | */ | 349 | */ |