diff options
| author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2009-11-24 11:04:21 -0500 |
|---|---|---|
| committer | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2009-11-30 07:05:57 -0500 |
| commit | 9284ad2a9016ad631460caf8fd01fc21d84f118c (patch) | |
| tree | 6ef77d51ca75017a1632bf215703ed9ee12feade /fs/nilfs2 | |
| parent | 5f1586d0dd8f6eeecf6c0d35cbca6291afd6f1cc (diff) | |
nilfs2: relocate io status variables to segment buffer
This moves io status variables in nilfs_write_info struct to
nilfs_segment_buffer struct.
This is a preparation to hide nilfs_write_info in segment buffer code.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Diffstat (limited to 'fs/nilfs2')
| -rw-r--r-- | fs/nilfs2/segbuf.c | 59 | ||||
| -rw-r--r-- | fs/nilfs2/segbuf.h | 16 | ||||
| -rw-r--r-- | fs/nilfs2/segment.c | 19 |
3 files changed, 44 insertions, 50 deletions
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c index c71b689bdbce..d86056ca9a27 100644 --- a/fs/nilfs2/segbuf.c +++ b/fs/nilfs2/segbuf.c | |||
| @@ -63,6 +63,11 @@ struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *sb) | |||
| 63 | INIT_LIST_HEAD(&segbuf->sb_list); | 63 | INIT_LIST_HEAD(&segbuf->sb_list); |
| 64 | INIT_LIST_HEAD(&segbuf->sb_segsum_buffers); | 64 | INIT_LIST_HEAD(&segbuf->sb_segsum_buffers); |
| 65 | INIT_LIST_HEAD(&segbuf->sb_payload_buffers); | 65 | INIT_LIST_HEAD(&segbuf->sb_payload_buffers); |
| 66 | |||
| 67 | init_completion(&segbuf->sb_bio_event); | ||
| 68 | atomic_set(&segbuf->sb_err, 0); | ||
| 69 | segbuf->sb_nbio = 0; | ||
| 70 | |||
| 66 | return segbuf; | 71 | return segbuf; |
| 67 | } | 72 | } |
| 68 | 73 | ||
| @@ -132,8 +137,6 @@ int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned flags, | |||
| 132 | segbuf->sb_sum.sumbytes = sizeof(struct nilfs_segment_summary); | 137 | segbuf->sb_sum.sumbytes = sizeof(struct nilfs_segment_summary); |
| 133 | segbuf->sb_sum.nfinfo = segbuf->sb_sum.nfileblk = 0; | 138 | segbuf->sb_sum.nfinfo = segbuf->sb_sum.nfileblk = 0; |
| 134 | segbuf->sb_sum.ctime = ctime; | 139 | segbuf->sb_sum.ctime = ctime; |
| 135 | |||
| 136 | segbuf->sb_io_error = 0; | ||
| 137 | return 0; | 140 | return 0; |
| 138 | } | 141 | } |
| 139 | 142 | ||
| @@ -247,7 +250,7 @@ void nilfs_release_buffers(struct list_head *list) | |||
| 247 | static void nilfs_end_bio_write(struct bio *bio, int err) | 250 | static void nilfs_end_bio_write(struct bio *bio, int err) |
| 248 | { | 251 | { |
| 249 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | 252 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); |
| 250 | struct nilfs_write_info *wi = bio->bi_private; | 253 | struct nilfs_segment_buffer *segbuf = bio->bi_private; |
| 251 | 254 | ||
| 252 | if (err == -EOPNOTSUPP) { | 255 | if (err == -EOPNOTSUPP) { |
| 253 | set_bit(BIO_EOPNOTSUPP, &bio->bi_flags); | 256 | set_bit(BIO_EOPNOTSUPP, &bio->bi_flags); |
| @@ -256,21 +259,22 @@ static void nilfs_end_bio_write(struct bio *bio, int err) | |||
| 256 | } | 259 | } |
| 257 | 260 | ||
| 258 | if (!uptodate) | 261 | if (!uptodate) |
| 259 | atomic_inc(&wi->err); | 262 | atomic_inc(&segbuf->sb_err); |
| 260 | 263 | ||
| 261 | bio_put(bio); | 264 | bio_put(bio); |
| 262 | complete(&wi->bio_event); | 265 | complete(&segbuf->sb_bio_event); |
| 263 | } | 266 | } |
| 264 | 267 | ||
| 265 | static int nilfs_submit_seg_bio(struct nilfs_write_info *wi, int mode) | 268 | static int nilfs_segbuf_submit_bio(struct nilfs_segment_buffer *segbuf, |
| 269 | struct nilfs_write_info *wi, int mode) | ||
| 266 | { | 270 | { |
| 267 | struct bio *bio = wi->bio; | 271 | struct bio *bio = wi->bio; |
| 268 | int err; | 272 | int err; |
| 269 | 273 | ||
| 270 | if (wi->nbio > 0 && bdi_write_congested(wi->bdi)) { | 274 | if (segbuf->sb_nbio > 0 && bdi_write_congested(wi->bdi)) { |
| 271 | wait_for_completion(&wi->bio_event); | 275 | wait_for_completion(&segbuf->sb_bio_event); |
| 272 | wi->nbio--; | 276 | segbuf->sb_nbio--; |
| 273 | if (unlikely(atomic_read(&wi->err))) { | 277 | if (unlikely(atomic_read(&segbuf->sb_err))) { |
| 274 | bio_put(bio); | 278 | bio_put(bio); |
| 275 | err = -EIO; | 279 | err = -EIO; |
| 276 | goto failed; | 280 | goto failed; |
| @@ -278,7 +282,7 @@ static int nilfs_submit_seg_bio(struct nilfs_write_info *wi, int mode) | |||
| 278 | } | 282 | } |
| 279 | 283 | ||
| 280 | bio->bi_end_io = nilfs_end_bio_write; | 284 | bio->bi_end_io = nilfs_end_bio_write; |
| 281 | bio->bi_private = wi; | 285 | bio->bi_private = segbuf; |
| 282 | bio_get(bio); | 286 | bio_get(bio); |
| 283 | submit_bio(mode, bio); | 287 | submit_bio(mode, bio); |
| 284 | if (bio_flagged(bio, BIO_EOPNOTSUPP)) { | 288 | if (bio_flagged(bio, BIO_EOPNOTSUPP)) { |
| @@ -286,7 +290,7 @@ static int nilfs_submit_seg_bio(struct nilfs_write_info *wi, int mode) | |||
| 286 | err = -EOPNOTSUPP; | 290 | err = -EOPNOTSUPP; |
| 287 | goto failed; | 291 | goto failed; |
| 288 | } | 292 | } |
| 289 | wi->nbio++; | 293 | segbuf->sb_nbio++; |
| 290 | bio_put(bio); | 294 | bio_put(bio); |
| 291 | 295 | ||
| 292 | wi->bio = NULL; | 296 | wi->bio = NULL; |
| @@ -336,15 +340,12 @@ void nilfs_segbuf_prepare_write(struct nilfs_segment_buffer *segbuf, | |||
| 336 | wi->max_pages = bio_get_nr_vecs(wi->sb->s_bdev); | 340 | wi->max_pages = bio_get_nr_vecs(wi->sb->s_bdev); |
| 337 | wi->nr_vecs = min(wi->max_pages, wi->rest_blocks); | 341 | wi->nr_vecs = min(wi->max_pages, wi->rest_blocks); |
| 338 | wi->start = wi->end = 0; | 342 | wi->start = wi->end = 0; |
| 339 | wi->nbio = 0; | ||
| 340 | wi->blocknr = segbuf->sb_pseg_start; | 343 | wi->blocknr = segbuf->sb_pseg_start; |
| 341 | |||
| 342 | atomic_set(&wi->err, 0); | ||
| 343 | init_completion(&wi->bio_event); | ||
| 344 | } | 344 | } |
| 345 | 345 | ||
| 346 | static int nilfs_submit_bh(struct nilfs_write_info *wi, struct buffer_head *bh, | 346 | static int nilfs_segbuf_submit_bh(struct nilfs_segment_buffer *segbuf, |
| 347 | int mode) | 347 | struct nilfs_write_info *wi, |
| 348 | struct buffer_head *bh, int mode) | ||
| 348 | { | 349 | { |
| 349 | int len, err; | 350 | int len, err; |
| 350 | 351 | ||
| @@ -363,7 +364,7 @@ static int nilfs_submit_bh(struct nilfs_write_info *wi, struct buffer_head *bh, | |||
| 363 | return 0; | 364 | return 0; |
| 364 | } | 365 | } |
| 365 | /* bio is FULL */ | 366 | /* bio is FULL */ |
| 366 | err = nilfs_submit_seg_bio(wi, mode); | 367 | err = nilfs_segbuf_submit_bio(segbuf, wi, mode); |
| 367 | /* never submit current bh */ | 368 | /* never submit current bh */ |
| 368 | if (likely(!err)) | 369 | if (likely(!err)) |
| 369 | goto repeat; | 370 | goto repeat; |
| @@ -377,13 +378,13 @@ int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf, | |||
| 377 | int res = 0, rw = WRITE; | 378 | int res = 0, rw = WRITE; |
| 378 | 379 | ||
| 379 | list_for_each_entry(bh, &segbuf->sb_segsum_buffers, b_assoc_buffers) { | 380 | list_for_each_entry(bh, &segbuf->sb_segsum_buffers, b_assoc_buffers) { |
| 380 | res = nilfs_submit_bh(wi, bh, rw); | 381 | res = nilfs_segbuf_submit_bh(segbuf, wi, bh, rw); |
| 381 | if (unlikely(res)) | 382 | if (unlikely(res)) |
| 382 | goto failed_bio; | 383 | goto failed_bio; |
| 383 | } | 384 | } |
| 384 | 385 | ||
| 385 | list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) { | 386 | list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) { |
| 386 | res = nilfs_submit_bh(wi, bh, rw); | 387 | res = nilfs_segbuf_submit_bh(segbuf, wi, bh, rw); |
| 387 | if (unlikely(res)) | 388 | if (unlikely(res)) |
| 388 | goto failed_bio; | 389 | goto failed_bio; |
| 389 | } | 390 | } |
| @@ -394,7 +395,7 @@ int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf, | |||
| 394 | * submission. | 395 | * submission. |
| 395 | */ | 396 | */ |
| 396 | rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); | 397 | rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); |
| 397 | res = nilfs_submit_seg_bio(wi, rw); | 398 | res = nilfs_segbuf_submit_bio(segbuf, wi, rw); |
| 398 | } | 399 | } |
| 399 | 400 | ||
| 400 | failed_bio: | 401 | failed_bio: |
| @@ -403,29 +404,27 @@ int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf, | |||
| 403 | 404 | ||
| 404 | /** | 405 | /** |
| 405 | * nilfs_segbuf_wait - wait for completion of requested BIOs | 406 | * nilfs_segbuf_wait - wait for completion of requested BIOs |
| 406 | * @wi: nilfs_write_info | 407 | * @segbuf: segment buffer |
| 407 | * | 408 | * |
| 408 | * Return Value: On Success, 0 is returned. On Error, one of the following | 409 | * Return Value: On Success, 0 is returned. On Error, one of the following |
| 409 | * negative error code is returned. | 410 | * negative error code is returned. |
| 410 | * | 411 | * |
| 411 | * %-EIO - I/O error | 412 | * %-EIO - I/O error |
| 412 | */ | 413 | */ |
| 413 | int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf, | 414 | int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf) |
| 414 | struct nilfs_write_info *wi) | ||
| 415 | { | 415 | { |
| 416 | int err = 0; | 416 | int err = 0; |
| 417 | 417 | ||
| 418 | if (!wi->nbio) | 418 | if (!segbuf->sb_nbio) |
| 419 | return 0; | 419 | return 0; |
| 420 | 420 | ||
| 421 | do { | 421 | do { |
| 422 | wait_for_completion(&wi->bio_event); | 422 | wait_for_completion(&segbuf->sb_bio_event); |
| 423 | } while (--wi->nbio > 0); | 423 | } while (--segbuf->sb_nbio > 0); |
| 424 | 424 | ||
| 425 | if (unlikely(atomic_read(&wi->err) > 0)) { | 425 | if (unlikely(atomic_read(&segbuf->sb_err) > 0)) { |
| 426 | printk(KERN_ERR "NILFS: IO error writing segment\n"); | 426 | printk(KERN_ERR "NILFS: IO error writing segment\n"); |
| 427 | err = -EIO; | 427 | err = -EIO; |
| 428 | segbuf->sb_io_error = 1; | ||
| 429 | } | 428 | } |
| 430 | return err; | 429 | return err; |
| 431 | } | 430 | } |
diff --git a/fs/nilfs2/segbuf.h b/fs/nilfs2/segbuf.h index 0c3076f4e592..bd076cca37a8 100644 --- a/fs/nilfs2/segbuf.h +++ b/fs/nilfs2/segbuf.h | |||
| @@ -77,7 +77,9 @@ struct nilfs_segsum_info { | |||
| 77 | * @sb_rest_blocks: Number of residual blocks in the current segment | 77 | * @sb_rest_blocks: Number of residual blocks in the current segment |
| 78 | * @sb_segsum_buffers: List of buffers for segment summaries | 78 | * @sb_segsum_buffers: List of buffers for segment summaries |
| 79 | * @sb_payload_buffers: List of buffers for segment payload | 79 | * @sb_payload_buffers: List of buffers for segment payload |
| 80 | * @sb_io_error: I/O error status | 80 | * @sb_nbio: Number of flying bio requests |
| 81 | * @sb_err: I/O error status | ||
| 82 | * @sb_bio_event: Completion event of log writing | ||
| 81 | */ | 83 | */ |
| 82 | struct nilfs_segment_buffer { | 84 | struct nilfs_segment_buffer { |
| 83 | struct super_block *sb_super; | 85 | struct super_block *sb_super; |
| @@ -96,7 +98,9 @@ struct nilfs_segment_buffer { | |||
| 96 | struct list_head sb_payload_buffers; /* including super root */ | 98 | struct list_head sb_payload_buffers; /* including super root */ |
| 97 | 99 | ||
| 98 | /* io status */ | 100 | /* io status */ |
| 99 | int sb_io_error; | 101 | int sb_nbio; |
| 102 | atomic_t sb_err; | ||
| 103 | struct completion sb_bio_event; | ||
| 100 | }; | 104 | }; |
| 101 | 105 | ||
| 102 | #define NILFS_LIST_SEGBUF(head) \ | 106 | #define NILFS_LIST_SEGBUF(head) \ |
| @@ -177,11 +181,6 @@ struct nilfs_write_info { | |||
| 177 | int nr_vecs; | 181 | int nr_vecs; |
| 178 | sector_t blocknr; | 182 | sector_t blocknr; |
| 179 | 183 | ||
| 180 | int nbio; | ||
| 181 | atomic_t err; | ||
| 182 | struct completion bio_event; | ||
| 183 | /* completion event of segment write */ | ||
| 184 | |||
| 185 | /* | 184 | /* |
| 186 | * The following fields must be set explicitly | 185 | * The following fields must be set explicitly |
| 187 | */ | 186 | */ |
| @@ -195,7 +194,6 @@ void nilfs_segbuf_prepare_write(struct nilfs_segment_buffer *, | |||
| 195 | struct nilfs_write_info *); | 194 | struct nilfs_write_info *); |
| 196 | int nilfs_segbuf_write(struct nilfs_segment_buffer *, | 195 | int nilfs_segbuf_write(struct nilfs_segment_buffer *, |
| 197 | struct nilfs_write_info *); | 196 | struct nilfs_write_info *); |
| 198 | int nilfs_segbuf_wait(struct nilfs_segment_buffer *, | 197 | int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf); |
| 199 | struct nilfs_write_info *); | ||
| 200 | 198 | ||
| 201 | #endif /* _NILFS_SEGBUF_H */ | 199 | #endif /* _NILFS_SEGBUF_H */ |
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 79acf4d66e88..cb004ebe7895 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
| @@ -1382,14 +1382,14 @@ static void nilfs_segctor_free_incomplete_segments(struct nilfs_sc_info *sci, | |||
| 1382 | struct the_nilfs *nilfs) | 1382 | struct the_nilfs *nilfs) |
| 1383 | { | 1383 | { |
| 1384 | struct nilfs_segment_buffer *segbuf; | 1384 | struct nilfs_segment_buffer *segbuf; |
| 1385 | int ret, done = 0; | 1385 | int ret; |
| 1386 | 1386 | ||
| 1387 | segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs); | 1387 | segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs); |
| 1388 | if (nilfs->ns_nextnum != segbuf->sb_nextnum) { | 1388 | if (nilfs->ns_nextnum != segbuf->sb_nextnum) { |
| 1389 | ret = nilfs_sufile_free(nilfs->ns_sufile, segbuf->sb_nextnum); | 1389 | ret = nilfs_sufile_free(nilfs->ns_sufile, segbuf->sb_nextnum); |
| 1390 | WARN_ON(ret); /* never fails */ | 1390 | WARN_ON(ret); /* never fails */ |
| 1391 | } | 1391 | } |
| 1392 | if (segbuf->sb_io_error) { | 1392 | if (atomic_read(&segbuf->sb_err)) { |
| 1393 | /* Case 1: The first segment failed */ | 1393 | /* Case 1: The first segment failed */ |
| 1394 | if (segbuf->sb_pseg_start != segbuf->sb_fseg_start) | 1394 | if (segbuf->sb_pseg_start != segbuf->sb_fseg_start) |
| 1395 | /* Case 1a: Partial segment appended into an existing | 1395 | /* Case 1a: Partial segment appended into an existing |
| @@ -1398,19 +1398,16 @@ static void nilfs_segctor_free_incomplete_segments(struct nilfs_sc_info *sci, | |||
| 1398 | segbuf->sb_fseg_end); | 1398 | segbuf->sb_fseg_end); |
| 1399 | else /* Case 1b: New full segment */ | 1399 | else /* Case 1b: New full segment */ |
| 1400 | set_nilfs_discontinued(nilfs); | 1400 | set_nilfs_discontinued(nilfs); |
| 1401 | done++; | ||
| 1402 | } | 1401 | } |
| 1403 | 1402 | ||
| 1404 | list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) { | 1403 | list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) { |
| 1405 | ret = nilfs_sufile_free(nilfs->ns_sufile, segbuf->sb_nextnum); | 1404 | ret = nilfs_sufile_free(nilfs->ns_sufile, segbuf->sb_nextnum); |
| 1406 | WARN_ON(ret); /* never fails */ | 1405 | WARN_ON(ret); /* never fails */ |
| 1407 | if (!done && segbuf->sb_io_error) { | 1406 | if (atomic_read(&segbuf->sb_err) && |
| 1408 | if (segbuf->sb_segnum != nilfs->ns_nextnum) | 1407 | segbuf->sb_segnum != nilfs->ns_nextnum) |
| 1409 | /* Case 2: extended segment (!= next) failed */ | 1408 | /* Case 2: extended segment (!= next) failed */ |
| 1410 | nilfs_sufile_set_error(nilfs->ns_sufile, | 1409 | nilfs_sufile_set_error(nilfs->ns_sufile, |
| 1411 | segbuf->sb_segnum); | 1410 | segbuf->sb_segnum); |
| 1412 | done++; | ||
| 1413 | } | ||
| 1414 | } | 1411 | } |
| 1415 | } | 1412 | } |
| 1416 | 1413 | ||
| @@ -1801,7 +1798,7 @@ static int nilfs_segctor_write(struct nilfs_sc_info *sci, | |||
| 1801 | nilfs_segbuf_prepare_write(segbuf, &wi); | 1798 | nilfs_segbuf_prepare_write(segbuf, &wi); |
| 1802 | err = nilfs_segbuf_write(segbuf, &wi); | 1799 | err = nilfs_segbuf_write(segbuf, &wi); |
| 1803 | 1800 | ||
| 1804 | res = nilfs_segbuf_wait(segbuf, &wi); | 1801 | res = nilfs_segbuf_wait(segbuf); |
| 1805 | err = err ? : res; | 1802 | err = err ? : res; |
| 1806 | if (err) | 1803 | if (err) |
| 1807 | return err; | 1804 | return err; |
