aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/meta_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/meta_io.c')
-rw-r--r--fs/gfs2/meta_io.c173
1 files changed, 76 insertions, 97 deletions
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index 6b52aacb0736..d3708af0a4d1 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -273,19 +273,16 @@ void gfs2_meta_inval(struct gfs2_glock *gl)
273/** 273/**
274 * gfs2_meta_sync - Sync all buffers associated with a glock 274 * gfs2_meta_sync - Sync all buffers associated with a glock
275 * @gl: The glock 275 * @gl: The glock
276 * @flags: DIO_START | DIO_WAIT
277 * 276 *
278 */ 277 */
279 278
280void gfs2_meta_sync(struct gfs2_glock *gl, int flags) 279void gfs2_meta_sync(struct gfs2_glock *gl)
281{ 280{
282 struct address_space *mapping = gl->gl_aspace->i_mapping; 281 struct address_space *mapping = gl->gl_aspace->i_mapping;
283 int error = 0; 282 int error;
284 283
285 if (flags & DIO_START) 284 filemap_fdatawrite(mapping);
286 filemap_fdatawrite(mapping); 285 error = filemap_fdatawait(mapping);
287 if (!error && (flags & DIO_WAIT))
288 error = filemap_fdatawait(mapping);
289 286
290 if (error) 287 if (error)
291 gfs2_io_error(gl->gl_sbd); 288 gfs2_io_error(gl->gl_sbd);
@@ -377,7 +374,7 @@ struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno)
377 * gfs2_meta_read - Read a block from disk 374 * gfs2_meta_read - Read a block from disk
378 * @gl: The glock covering the block 375 * @gl: The glock covering the block
379 * @blkno: The block number 376 * @blkno: The block number
380 * @flags: flags to gfs2_dreread() 377 * @flags: flags
381 * @bhp: the place where the buffer is returned (NULL on failure) 378 * @bhp: the place where the buffer is returned (NULL on failure)
382 * 379 *
383 * Returns: errno 380 * Returns: errno
@@ -386,45 +383,43 @@ struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno)
386int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, 383int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
387 struct buffer_head **bhp) 384 struct buffer_head **bhp)
388{ 385{
389 int error;
390
391 *bhp = getbuf(gl->gl_sbd, gl->gl_aspace, blkno, CREATE); 386 *bhp = getbuf(gl->gl_sbd, gl->gl_aspace, blkno, CREATE);
392 error = gfs2_meta_reread(gl->gl_sbd, *bhp, flags); 387 if (!buffer_uptodate(*bhp))
393 if (error) 388 ll_rw_block(READ, 1, bhp);
394 brelse(*bhp); 389 if (flags & DIO_WAIT) {
390 int error = gfs2_meta_wait(gl->gl_sbd, *bhp);
391 if (error) {
392 brelse(*bhp);
393 return error;
394 }
395 }
395 396
396 return error; 397 return 0;
397} 398}
398 399
399/** 400/**
400 * gfs2_meta_reread - Reread a block from disk 401 * gfs2_meta_wait - Reread a block from disk
401 * @sdp: the filesystem 402 * @sdp: the filesystem
402 * @bh: The block to read 403 * @bh: The block to wait for
403 * @flags: Flags that control the read
404 * 404 *
405 * Returns: errno 405 * Returns: errno
406 */ 406 */
407 407
408int gfs2_meta_reread(struct gfs2_sbd *sdp, struct buffer_head *bh, int flags) 408int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh)
409{ 409{
410 if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) 410 if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
411 return -EIO; 411 return -EIO;
412 412
413 if ((flags & DIO_START) && !buffer_uptodate(bh)) 413 wait_on_buffer(bh);
414 ll_rw_block(READ, 1, &bh);
415
416 if (flags & DIO_WAIT) {
417 wait_on_buffer(bh);
418 414
419 if (!buffer_uptodate(bh)) { 415 if (!buffer_uptodate(bh)) {
420 struct gfs2_trans *tr = current->journal_info; 416 struct gfs2_trans *tr = current->journal_info;
421 if (tr && tr->tr_touched) 417 if (tr && tr->tr_touched)
422 gfs2_io_error_bh(sdp, bh); 418 gfs2_io_error_bh(sdp, bh);
423 return -EIO; 419 return -EIO;
424 }
425 if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
426 return -EIO;
427 } 420 }
421 if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
422 return -EIO;
428 423
429 return 0; 424 return 0;
430} 425}
@@ -635,67 +630,57 @@ void gfs2_meta_cache_flush(struct gfs2_inode *ip)
635int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, 630int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
636 int new, struct buffer_head **bhp) 631 int new, struct buffer_head **bhp)
637{ 632{
638 struct buffer_head *bh, **bh_slot = ip->i_cache + height; 633 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
639 int error; 634 struct gfs2_glock *gl = ip->i_gl;
635 struct buffer_head *bh = NULL, **bh_slot = ip->i_cache + height;
636 int in_cache = 0;
640 637
641 spin_lock(&ip->i_spin); 638 spin_lock(&ip->i_spin);
642 bh = *bh_slot; 639 if (*bh_slot && (*bh_slot)->b_blocknr == num) {
643 if (bh) { 640 bh = *bh_slot;
644 if (bh->b_blocknr == num) 641 get_bh(bh);
645 get_bh(bh); 642 in_cache = 1;
646 else
647 bh = NULL;
648 } 643 }
649 spin_unlock(&ip->i_spin); 644 spin_unlock(&ip->i_spin);
650 645
651 if (bh) { 646 if (!bh)
652 if (new) 647 bh = getbuf(gl->gl_sbd, gl->gl_aspace, num, CREATE);
653 meta_prep_new(bh);
654 else {
655 error = gfs2_meta_reread(GFS2_SB(&ip->i_inode), bh,
656 DIO_START | DIO_WAIT);
657 if (error) {
658 brelse(bh);
659 return error;
660 }
661 }
662 } else {
663 if (new)
664 bh = gfs2_meta_new(ip->i_gl, num);
665 else {
666 error = gfs2_meta_read(ip->i_gl, num,
667 DIO_START | DIO_WAIT, &bh);
668 if (error)
669 return error;
670 }
671 648
672 spin_lock(&ip->i_spin); 649 if (!bh)
673 if (*bh_slot != bh) { 650 return -ENOBUFS;
674 brelse(*bh_slot);
675 *bh_slot = bh;
676 get_bh(bh);
677 }
678 spin_unlock(&ip->i_spin);
679 }
680 651
681 if (new) { 652 if (new) {
682 if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), height)) { 653 if (gfs2_assert_warn(sdp, height))
683 brelse(bh); 654 goto err;
684 return -EIO; 655 meta_prep_new(bh);
685 }
686 gfs2_trans_add_bh(ip->i_gl, bh, 1); 656 gfs2_trans_add_bh(ip->i_gl, bh, 1);
687 gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); 657 gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN);
688 gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header)); 658 gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header));
659 } else {
660 u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI;
661 if (!buffer_uptodate(bh)) {
662 ll_rw_block(READ, 1, &bh);
663 if (gfs2_meta_wait(sdp, bh))
664 goto err;
665 }
666 if (gfs2_metatype_check(sdp, bh, mtype))
667 goto err;
668 }
689 669
690 } else if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, 670 if (!in_cache) {
691 (height) ? GFS2_METATYPE_IN : GFS2_METATYPE_DI)) { 671 spin_lock(&ip->i_spin);
692 brelse(bh); 672 if (*bh_slot)
693 return -EIO; 673 brelse(*bh_slot);
674 *bh_slot = bh;
675 get_bh(bh);
676 spin_unlock(&ip->i_spin);
694 } 677 }
695 678
696 *bhp = bh; 679 *bhp = bh;
697
698 return 0; 680 return 0;
681err:
682 brelse(bh);
683 return -EIO;
699} 684}
700 685
701/** 686/**
@@ -704,19 +689,21 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
704 * @dblock: the starting disk block 689 * @dblock: the starting disk block
705 * @extlen: the number of blocks in the extent 690 * @extlen: the number of blocks in the extent
706 * 691 *
692 * returns: the first buffer in the extent
707 */ 693 */
708 694
709void gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) 695struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen)
710{ 696{
711 struct gfs2_sbd *sdp = gl->gl_sbd; 697 struct gfs2_sbd *sdp = gl->gl_sbd;
712 struct inode *aspace = gl->gl_aspace; 698 struct inode *aspace = gl->gl_aspace;
713 struct buffer_head *first_bh, *bh; 699 struct buffer_head *first_bh, *bh;
714 u32 max_ra = gfs2_tune_get(sdp, gt_max_readahead) >> 700 u32 max_ra = gfs2_tune_get(sdp, gt_max_readahead) >>
715 sdp->sd_sb.sb_bsize_shift; 701 sdp->sd_sb.sb_bsize_shift;
716 int error;
717 702
718 if (!extlen || !max_ra) 703 BUG_ON(!extlen);
719 return; 704
705 if (max_ra < 1)
706 max_ra = 1;
720 if (extlen > max_ra) 707 if (extlen > max_ra)
721 extlen = max_ra; 708 extlen = max_ra;
722 709
@@ -724,11 +711,8 @@ void gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen)
724 711
725 if (buffer_uptodate(first_bh)) 712 if (buffer_uptodate(first_bh))
726 goto out; 713 goto out;
727 if (!buffer_locked(first_bh)) { 714 if (!buffer_locked(first_bh))
728 error = gfs2_meta_reread(sdp, first_bh, DIO_START); 715 ll_rw_block(READ, 1, &first_bh);
729 if (error)
730 goto out;
731 }
732 716
733 dblock++; 717 dblock++;
734 extlen--; 718 extlen--;
@@ -736,23 +720,18 @@ void gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen)
736 while (extlen) { 720 while (extlen) {
737 bh = getbuf(sdp, aspace, dblock, CREATE); 721 bh = getbuf(sdp, aspace, dblock, CREATE);
738 722
739 if (!buffer_uptodate(bh) && !buffer_locked(bh)) { 723 if (!buffer_uptodate(bh) && !buffer_locked(bh))
740 error = gfs2_meta_reread(sdp, bh, DIO_START); 724 ll_rw_block(READA, 1, &bh);
741 brelse(bh); 725 brelse(bh);
742 if (error)
743 goto out;
744 } else
745 brelse(bh);
746
747 dblock++; 726 dblock++;
748 extlen--; 727 extlen--;
749 728 if (!buffer_locked(first_bh) && buffer_uptodate(first_bh))
750 if (buffer_uptodate(first_bh)) 729 goto out;
751 break;
752 } 730 }
753 731
732 wait_on_buffer(first_bh);
754out: 733out:
755 brelse(first_bh); 734 return first_bh;
756} 735}
757 736
758/** 737/**