|
17 | 17 | #include <linux/bio.h>
|
18 | 18 | #include <linux/fs.h>
|
19 | 19 | #include <linux/list_sort.h>
|
20 |
| -#include <linux/blkdev.h> |
21 | 20 |
|
22 |
| -#include "bmap.h" |
23 | 21 | #include "dir.h"
|
24 | 22 | #include "gfs2.h"
|
25 | 23 | #include "incore.h"
|
@@ -195,6 +193,7 @@ static void gfs2_end_log_write_bh(struct gfs2_sbd *sdp, struct bio_vec *bvec,
|
195 | 193 | /**
|
196 | 194 | * gfs2_end_log_write - end of i/o to the log
|
197 | 195 | * @bio: The bio
|
| 196 | + * @error: Status of i/o request |
198 | 197 | *
|
199 | 198 | * Each bio_vec contains either data from the pagecache or data
|
200 | 199 | * relating to the log itself. Here we iterate over the bio_vec
|
@@ -231,19 +230,20 @@ static void gfs2_end_log_write(struct bio *bio)
|
231 | 230 | /**
|
232 | 231 | * gfs2_log_submit_bio - Submit any pending log bio
|
233 | 232 | * @biop: Address of the bio pointer
|
234 |
| - * @opf: REQ_OP | op_flags |
| 233 | + * @op: REQ_OP |
| 234 | + * @op_flags: req_flag_bits |
235 | 235 | *
|
236 | 236 | * Submit any pending part-built or full bio to the block device. If
|
237 | 237 | * there is no pending bio, then this is a no-op.
|
238 | 238 | */
|
239 | 239 |
|
240 |
| -void gfs2_log_submit_bio(struct bio **biop, int opf) |
| 240 | +void gfs2_log_submit_bio(struct bio **biop, int op, int op_flags) |
241 | 241 | {
|
242 | 242 | struct bio *bio = *biop;
|
243 | 243 | if (bio) {
|
244 | 244 | struct gfs2_sbd *sdp = bio->bi_private;
|
245 | 245 | atomic_inc(&sdp->sd_log_in_flight);
|
246 |
| - bio->bi_opf = opf; |
| 246 | + bio_set_op_attrs(bio, op, op_flags); |
247 | 247 | submit_bio(bio);
|
248 | 248 | *biop = NULL;
|
249 | 249 | }
|
@@ -304,7 +304,7 @@ static struct bio *gfs2_log_get_bio(struct gfs2_sbd *sdp, u64 blkno,
|
304 | 304 | nblk >>= sdp->sd_fsb2bb_shift;
|
305 | 305 | if (blkno == nblk && !flush)
|
306 | 306 | return bio;
|
307 |
| - gfs2_log_submit_bio(biop, op); |
| 307 | + gfs2_log_submit_bio(biop, op, 0); |
308 | 308 | }
|
309 | 309 |
|
310 | 310 | *biop = gfs2_log_alloc_bio(sdp, blkno, end_io);
|
@@ -375,184 +375,6 @@ void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page)
|
375 | 375 | gfs2_log_bmap(sdp));
|
376 | 376 | }
|
377 | 377 |
|
378 |
| -/** |
379 |
| - * gfs2_end_log_read - end I/O callback for reads from the log |
380 |
| - * @bio: The bio |
381 |
| - * |
382 |
| - * Simply unlock the pages in the bio. The main thread will wait on them and |
383 |
| - * process them in order as necessary. |
384 |
| - */ |
385 |
| - |
386 |
| -static void gfs2_end_log_read(struct bio *bio) |
387 |
| -{ |
388 |
| - struct page *page; |
389 |
| - struct bio_vec *bvec; |
390 |
| - int i; |
391 |
| - |
392 |
| - bio_for_each_segment_all(bvec, bio, i) { |
393 |
| - page = bvec->bv_page; |
394 |
| - if (bio->bi_status) { |
395 |
| - int err = blk_status_to_errno(bio->bi_status); |
396 |
| - |
397 |
| - SetPageError(page); |
398 |
| - mapping_set_error(page->mapping, err); |
399 |
| - } |
400 |
| - unlock_page(page); |
401 |
| - } |
402 |
| - |
403 |
| - bio_put(bio); |
404 |
| -} |
405 |
| - |
406 |
| -/** |
407 |
| - * gfs2_jhead_pg_srch - Look for the journal head in a given page. |
408 |
| - * @jd: The journal descriptor |
409 |
| - * @page: The page to look in |
410 |
| - * |
411 |
| - * Returns: 1 if found, 0 otherwise. |
412 |
| - */ |
413 |
| - |
414 |
| -static bool gfs2_jhead_pg_srch(struct gfs2_jdesc *jd, |
415 |
| - struct gfs2_log_header_host *head, |
416 |
| - struct page *page) |
417 |
| -{ |
418 |
| - struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
419 |
| - struct gfs2_log_header_host uninitialized_var(lh); |
420 |
| - void *kaddr = kmap_atomic(page); |
421 |
| - unsigned int offset; |
422 |
| - bool ret = false; |
423 |
| - |
424 |
| - for (offset = 0; offset < PAGE_SIZE; offset += sdp->sd_sb.sb_bsize) { |
425 |
| - if (!__get_log_header(sdp, kaddr + offset, 0, &lh)) { |
426 |
| - if (lh.lh_sequence > head->lh_sequence) |
427 |
| - *head = lh; |
428 |
| - else { |
429 |
| - ret = true; |
430 |
| - break; |
431 |
| - } |
432 |
| - } |
433 |
| - } |
434 |
| - kunmap_atomic(kaddr); |
435 |
| - return ret; |
436 |
| -} |
437 |
| - |
438 |
| -/** |
439 |
| - * gfs2_jhead_process_page - Search/cleanup a page |
440 |
| - * @jd: The journal descriptor |
441 |
| - * @index: Index of the page to look into |
442 |
| - * @done: If set, perform only cleanup, else search and set if found. |
443 |
| - * |
444 |
| - * Find the page with 'index' in the journal's mapping. Search the page for |
445 |
| - * the journal head if requested (cleanup == false). Release refs on the |
446 |
| - * page so the page cache can reclaim it (put_page() twice). We grabbed a |
447 |
| - * reference on this page two times, first when we did a find_or_create_page() |
448 |
| - * to obtain the page to add it to the bio and second when we do a |
449 |
| - * find_get_page() here to get the page to wait on while I/O on it is being |
450 |
| - * completed. |
451 |
| - * This function is also used to free up a page we might've grabbed but not |
452 |
| - * used. Maybe we added it to a bio, but not submitted it for I/O. Or we |
453 |
| - * submitted the I/O, but we already found the jhead so we only need to drop |
454 |
| - * our references to the page. |
455 |
| - */ |
456 |
| - |
457 |
| -static void gfs2_jhead_process_page(struct gfs2_jdesc *jd, unsigned long index, |
458 |
| - struct gfs2_log_header_host *head, |
459 |
| - bool *done) |
460 |
| -{ |
461 |
| - struct page *page; |
462 |
| - |
463 |
| - page = find_get_page(jd->jd_inode->i_mapping, index); |
464 |
| - wait_on_page_locked(page); |
465 |
| - |
466 |
| - if (PageError(page)) |
467 |
| - *done = true; |
468 |
| - |
469 |
| - if (!*done) |
470 |
| - *done = gfs2_jhead_pg_srch(jd, head, page); |
471 |
| - |
472 |
| - put_page(page); /* Once for find_get_page */ |
473 |
| - put_page(page); /* Once more for find_or_create_page */ |
474 |
| -} |
475 |
| - |
476 |
| -/** |
477 |
| - * gfs2_find_jhead - find the head of a log |
478 |
| - * @jd: The journal descriptor |
479 |
| - * @head: The log descriptor for the head of the log is returned here |
480 |
| - * |
481 |
| - * Do a search of a journal by reading it in large chunks using bios and find |
482 |
| - * the valid log entry with the highest sequence number. (i.e. the log head) |
483 |
| - * |
484 |
| - * Returns: 0 on success, errno otherwise |
485 |
| - */ |
486 |
| - |
487 |
| -int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head) |
488 |
| -{ |
489 |
| - struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
490 |
| - struct address_space *mapping = jd->jd_inode->i_mapping; |
491 |
| - struct gfs2_journal_extent *je; |
492 |
| - u32 block, read_idx = 0, submit_idx = 0, index = 0; |
493 |
| - int shift = PAGE_SHIFT - sdp->sd_sb.sb_bsize_shift; |
494 |
| - int blocks_per_page = 1 << shift, sz, ret = 0; |
495 |
| - struct bio *bio = NULL; |
496 |
| - struct page *page; |
497 |
| - bool done = false; |
498 |
| - errseq_t since; |
499 |
| - |
500 |
| - memset(head, 0, sizeof(*head)); |
501 |
| - if (list_empty(&jd->extent_list)) |
502 |
| - gfs2_map_journal_extents(sdp, jd); |
503 |
| - |
504 |
| - since = filemap_sample_wb_err(mapping); |
505 |
| - list_for_each_entry(je, &jd->extent_list, list) { |
506 |
| - for (block = 0; block < je->blocks; block += blocks_per_page) { |
507 |
| - index = (je->lblock + block) >> shift; |
508 |
| - |
509 |
| - page = find_or_create_page(mapping, index, GFP_NOFS); |
510 |
| - if (!page) { |
511 |
| - ret = -ENOMEM; |
512 |
| - done = true; |
513 |
| - goto out; |
514 |
| - } |
515 |
| - |
516 |
| - if (bio) { |
517 |
| - sz = bio_add_page(bio, page, PAGE_SIZE, 0); |
518 |
| - if (sz == PAGE_SIZE) |
519 |
| - goto page_added; |
520 |
| - submit_idx = index; |
521 |
| - submit_bio(bio); |
522 |
| - bio = NULL; |
523 |
| - } |
524 |
| - |
525 |
| - bio = gfs2_log_alloc_bio(sdp, |
526 |
| - je->dblock + (index << shift), |
527 |
| - gfs2_end_log_read); |
528 |
| - bio->bi_opf = REQ_OP_READ; |
529 |
| - sz = bio_add_page(bio, page, PAGE_SIZE, 0); |
530 |
| - gfs2_assert_warn(sdp, sz == PAGE_SIZE); |
531 |
| - |
532 |
| -page_added: |
533 |
| - if (submit_idx <= read_idx + BIO_MAX_PAGES) { |
534 |
| - /* Keep at least one bio in flight */ |
535 |
| - continue; |
536 |
| - } |
537 |
| - |
538 |
| - gfs2_jhead_process_page(jd, read_idx++, head, &done); |
539 |
| - if (done) |
540 |
| - goto out; /* found */ |
541 |
| - } |
542 |
| - } |
543 |
| - |
544 |
| -out: |
545 |
| - if (bio) |
546 |
| - submit_bio(bio); |
547 |
| - while (read_idx <= index) |
548 |
| - gfs2_jhead_process_page(jd, read_idx++, head, &done); |
549 |
| - |
550 |
| - if (!ret) |
551 |
| - ret = filemap_check_wb_err(mapping, since); |
552 |
| - |
553 |
| - return ret; |
554 |
| -} |
555 |
| - |
556 | 378 | static struct page *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type,
|
557 | 379 | u32 ld_length, u32 ld_data1)
|
558 | 380 | {
|
|
0 commit comments