diff options
Diffstat (limited to 'fs/gfs2/log.c')
-rw-r--r-- | fs/gfs2/log.c | 76 |
1 files changed, 36 insertions, 40 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index f4beeb9c81c1..9a2ca8be7647 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -482,70 +482,66 @@ static void log_flush_wait(struct gfs2_sbd *sdp) | |||
482 | } | 482 | } |
483 | } | 483 | } |
484 | 484 | ||
485 | static int bd_cmp(void *priv, struct list_head *a, struct list_head *b) | 485 | static int ip_cmp(void *priv, struct list_head *a, struct list_head *b) |
486 | { | 486 | { |
487 | struct gfs2_bufdata *bda, *bdb; | 487 | struct gfs2_inode *ipa, *ipb; |
488 | 488 | ||
489 | bda = list_entry(a, struct gfs2_bufdata, bd_list); | 489 | ipa = list_entry(a, struct gfs2_inode, i_ordered); |
490 | bdb = list_entry(b, struct gfs2_bufdata, bd_list); | 490 | ipb = list_entry(b, struct gfs2_inode, i_ordered); |
491 | 491 | ||
492 | if (bda->bd_bh->b_blocknr < bdb->bd_bh->b_blocknr) | 492 | if (ipa->i_no_addr < ipb->i_no_addr) |
493 | return -1; | 493 | return -1; |
494 | if (bda->bd_bh->b_blocknr > bdb->bd_bh->b_blocknr) | 494 | if (ipa->i_no_addr > ipb->i_no_addr) |
495 | return 1; | 495 | return 1; |
496 | return 0; | 496 | return 0; |
497 | } | 497 | } |
498 | 498 | ||
499 | static void gfs2_ordered_write(struct gfs2_sbd *sdp) | 499 | static void gfs2_ordered_write(struct gfs2_sbd *sdp) |
500 | { | 500 | { |
501 | struct gfs2_bufdata *bd; | 501 | struct gfs2_inode *ip; |
502 | struct buffer_head *bh; | ||
503 | LIST_HEAD(written); | 502 | LIST_HEAD(written); |
504 | 503 | ||
505 | gfs2_log_lock(sdp); | 504 | spin_lock(&sdp->sd_ordered_lock); |
506 | list_sort(NULL, &sdp->sd_log_le_ordered, &bd_cmp); | 505 | list_sort(NULL, &sdp->sd_log_le_ordered, &ip_cmp); |
507 | while (!list_empty(&sdp->sd_log_le_ordered)) { | 506 | while (!list_empty(&sdp->sd_log_le_ordered)) { |
508 | bd = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_bufdata, bd_list); | 507 | ip = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_inode, i_ordered); |
509 | list_move(&bd->bd_list, &written); | 508 | list_move(&ip->i_ordered, &written); |
510 | bh = bd->bd_bh; | 509 | if (ip->i_inode.i_mapping->nrpages == 0) |
511 | if (!buffer_dirty(bh)) | ||
512 | continue; | 510 | continue; |
513 | get_bh(bh); | 511 | spin_unlock(&sdp->sd_ordered_lock); |
514 | gfs2_log_unlock(sdp); | 512 | filemap_fdatawrite(ip->i_inode.i_mapping); |
515 | lock_buffer(bh); | 513 | spin_lock(&sdp->sd_ordered_lock); |
516 | if (buffer_mapped(bh) && test_clear_buffer_dirty(bh)) { | ||
517 | bh->b_end_io = end_buffer_write_sync; | ||
518 | submit_bh(WRITE_SYNC, bh); | ||
519 | } else { | ||
520 | unlock_buffer(bh); | ||
521 | brelse(bh); | ||
522 | } | ||
523 | gfs2_log_lock(sdp); | ||
524 | } | 514 | } |
525 | list_splice(&written, &sdp->sd_log_le_ordered); | 515 | list_splice(&written, &sdp->sd_log_le_ordered); |
526 | gfs2_log_unlock(sdp); | 516 | spin_unlock(&sdp->sd_ordered_lock); |
527 | } | 517 | } |
528 | 518 | ||
529 | static void gfs2_ordered_wait(struct gfs2_sbd *sdp) | 519 | static void gfs2_ordered_wait(struct gfs2_sbd *sdp) |
530 | { | 520 | { |
531 | struct gfs2_bufdata *bd; | 521 | struct gfs2_inode *ip; |
532 | struct buffer_head *bh; | ||
533 | 522 | ||
534 | gfs2_log_lock(sdp); | 523 | spin_lock(&sdp->sd_ordered_lock); |
535 | while (!list_empty(&sdp->sd_log_le_ordered)) { | 524 | while (!list_empty(&sdp->sd_log_le_ordered)) { |
536 | bd = list_entry(sdp->sd_log_le_ordered.prev, struct gfs2_bufdata, bd_list); | 525 | ip = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_inode, i_ordered); |
537 | bh = bd->bd_bh; | 526 | list_del(&ip->i_ordered); |
538 | if (buffer_locked(bh)) { | 527 | WARN_ON(!test_and_clear_bit(GIF_ORDERED, &ip->i_flags)); |
539 | get_bh(bh); | 528 | if (ip->i_inode.i_mapping->nrpages == 0) |
540 | gfs2_log_unlock(sdp); | ||
541 | wait_on_buffer(bh); | ||
542 | brelse(bh); | ||
543 | gfs2_log_lock(sdp); | ||
544 | continue; | 529 | continue; |
545 | } | 530 | spin_unlock(&sdp->sd_ordered_lock); |
546 | list_del_init(&bd->bd_list); | 531 | filemap_fdatawait(ip->i_inode.i_mapping); |
532 | spin_lock(&sdp->sd_ordered_lock); | ||
547 | } | 533 | } |
548 | gfs2_log_unlock(sdp); | 534 | spin_unlock(&sdp->sd_ordered_lock); |
535 | } | ||
536 | |||
537 | void gfs2_ordered_del_inode(struct gfs2_inode *ip) | ||
538 | { | ||
539 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
540 | |||
541 | spin_lock(&sdp->sd_ordered_lock); | ||
542 | if (test_and_clear_bit(GIF_ORDERED, &ip->i_flags)) | ||
543 | list_del(&ip->i_ordered); | ||
544 | spin_unlock(&sdp->sd_ordered_lock); | ||
549 | } | 545 | } |
550 | 546 | ||
551 | /** | 547 | /** |