diff options
author | Nathan Scott <nathans@sgi.com> | 2006-09-27 21:03:20 -0400 |
---|---|---|
committer | Tim Shimmin <tes@sgi.com> | 2006-09-27 21:03:20 -0400 |
commit | 572d95f49f3652fffe8242c4498b85f4083e52ab (patch) | |
tree | 5c452a69a005a6a18dc80e4ab7090d6d8e230fc6 | |
parent | 948ecdb4c118293d2f3e267eec642c30c5d3a056 (diff) |
[XFS] Improve error handling for the zero-fsblock extent detection code.
SGI-PV: 955302
SGI-Modid: xfs-linux-melb:xfs-kern:26802a
Signed-off-by: Nathan Scott <nathans@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
-rw-r--r-- | fs/xfs/linux-2.6/xfs_globals.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap.c | 27 | ||||
-rw-r--r-- | fs/xfs/xfs_error.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_iomap.c | 89 |
4 files changed, 51 insertions, 68 deletions
diff --git a/fs/xfs/linux-2.6/xfs_globals.c b/fs/xfs/linux-2.6/xfs_globals.c index 6c162c3dde7e..ed3a5e1b4b67 100644 --- a/fs/xfs/linux-2.6/xfs_globals.c +++ b/fs/xfs/linux-2.6/xfs_globals.c | |||
@@ -34,7 +34,7 @@ xfs_param_t xfs_params = { | |||
34 | .restrict_chown = { 0, 1, 1 }, | 34 | .restrict_chown = { 0, 1, 1 }, |
35 | .sgid_inherit = { 0, 0, 1 }, | 35 | .sgid_inherit = { 0, 0, 1 }, |
36 | .symlink_mode = { 0, 0, 1 }, | 36 | .symlink_mode = { 0, 0, 1 }, |
37 | .panic_mask = { 0, 0, 127 }, | 37 | .panic_mask = { 0, 0, 255 }, |
38 | .error_level = { 0, 3, 11 }, | 38 | .error_level = { 0, 3, 11 }, |
39 | .syncd_timer = { 1*100, 30*100, 7200*100}, | 39 | .syncd_timer = { 1*100, 30*100, 7200*100}, |
40 | .stats_clear = { 0, 0, 1 }, | 40 | .stats_clear = { 0, 0, 1 }, |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index e28146fe046a..5b050c06795f 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -3705,7 +3705,7 @@ STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */ | |||
3705 | xfs_bmap_search_extents( | 3705 | xfs_bmap_search_extents( |
3706 | xfs_inode_t *ip, /* incore inode pointer */ | 3706 | xfs_inode_t *ip, /* incore inode pointer */ |
3707 | xfs_fileoff_t bno, /* block number searched for */ | 3707 | xfs_fileoff_t bno, /* block number searched for */ |
3708 | int whichfork, /* data or attr fork */ | 3708 | int fork, /* data or attr fork */ |
3709 | int *eofp, /* out: end of file found */ | 3709 | int *eofp, /* out: end of file found */ |
3710 | xfs_extnum_t *lastxp, /* out: last extent index */ | 3710 | xfs_extnum_t *lastxp, /* out: last extent index */ |
3711 | xfs_bmbt_irec_t *gotp, /* out: extent entry found */ | 3711 | xfs_bmbt_irec_t *gotp, /* out: extent entry found */ |
@@ -3713,25 +3713,28 @@ xfs_bmap_search_extents( | |||
3713 | { | 3713 | { |
3714 | xfs_ifork_t *ifp; /* inode fork pointer */ | 3714 | xfs_ifork_t *ifp; /* inode fork pointer */ |
3715 | xfs_bmbt_rec_t *ep; /* extent record pointer */ | 3715 | xfs_bmbt_rec_t *ep; /* extent record pointer */ |
3716 | int rt; /* realtime flag */ | ||
3717 | 3716 | ||
3718 | XFS_STATS_INC(xs_look_exlist); | 3717 | XFS_STATS_INC(xs_look_exlist); |
3719 | ifp = XFS_IFORK_PTR(ip, whichfork); | 3718 | ifp = XFS_IFORK_PTR(ip, fork); |
3720 | 3719 | ||
3721 | ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp); | 3720 | ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp); |
3722 | 3721 | ||
3723 | rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); | 3722 | if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) && |
3724 | if (unlikely(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM))) { | 3723 | !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) { |
3725 | cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld " | 3724 | xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount, |
3726 | "start_block : %llx start_off : %llx blkcnt : %llx " | 3725 | "Access to block zero in inode %llu " |
3727 | "extent-state : %x \n", | 3726 | "start_block: %llx start_off: %llx " |
3728 | (ip->i_mount)->m_fsname, (long long)ip->i_ino, | 3727 | "blkcnt: %llx extent-state: %x lastx: %x\n", |
3728 | (unsigned long long)ip->i_ino, | ||
3729 | (unsigned long long)gotp->br_startblock, | 3729 | (unsigned long long)gotp->br_startblock, |
3730 | (unsigned long long)gotp->br_startoff, | 3730 | (unsigned long long)gotp->br_startoff, |
3731 | (unsigned long long)gotp->br_blockcount, | 3731 | (unsigned long long)gotp->br_blockcount, |
3732 | gotp->br_state); | 3732 | gotp->br_state, *lastxp); |
3733 | } | 3733 | *lastxp = NULLEXTNUM; |
3734 | return ep; | 3734 | *eofp = 1; |
3735 | return NULL; | ||
3736 | } | ||
3737 | return ep; | ||
3735 | } | 3738 | } |
3736 | 3739 | ||
3737 | 3740 | ||
diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h index f90fd500b940..0893e16b7d83 100644 --- a/fs/xfs/xfs_error.h +++ b/fs/xfs/xfs_error.h | |||
@@ -167,6 +167,7 @@ extern int xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud); | |||
167 | #define XFS_PTAG_SHUTDOWN_CORRUPT 0x00000010 | 167 | #define XFS_PTAG_SHUTDOWN_CORRUPT 0x00000010 |
168 | #define XFS_PTAG_SHUTDOWN_IOERROR 0x00000020 | 168 | #define XFS_PTAG_SHUTDOWN_IOERROR 0x00000020 |
169 | #define XFS_PTAG_SHUTDOWN_LOGERROR 0x00000040 | 169 | #define XFS_PTAG_SHUTDOWN_LOGERROR 0x00000040 |
170 | #define XFS_PTAG_FSBLOCK_ZERO 0x00000080 | ||
170 | 171 | ||
171 | struct xfs_mount; | 172 | struct xfs_mount; |
172 | /* PRINTFLIKE4 */ | 173 | /* PRINTFLIKE4 */ |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index f1949c16df15..19655124da78 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -398,6 +398,23 @@ xfs_flush_space( | |||
398 | return 1; | 398 | return 1; |
399 | } | 399 | } |
400 | 400 | ||
401 | STATIC int | ||
402 | xfs_cmn_err_fsblock_zero( | ||
403 | xfs_inode_t *ip, | ||
404 | xfs_bmbt_irec_t *imap) | ||
405 | { | ||
406 | xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount, | ||
407 | "Access to block zero in inode %llu " | ||
408 | "start_block: %llx start_off: %llx " | ||
409 | "blkcnt: %llx extent-state: %x\n", | ||
410 | (unsigned long long)ip->i_ino, | ||
411 | (unsigned long long)imap->br_startblock, | ||
412 | (unsigned long long)imap->br_startoff, | ||
413 | (unsigned long long)imap->br_blockcount, | ||
414 | imap->br_state); | ||
415 | return EFSCORRUPTED; | ||
416 | } | ||
417 | |||
401 | int | 418 | int |
402 | xfs_iomap_write_direct( | 419 | xfs_iomap_write_direct( |
403 | xfs_inode_t *ip, | 420 | xfs_inode_t *ip, |
@@ -536,23 +553,17 @@ xfs_iomap_write_direct( | |||
536 | * Copy any maps to caller's array and return any error. | 553 | * Copy any maps to caller's array and return any error. |
537 | */ | 554 | */ |
538 | if (nimaps == 0) { | 555 | if (nimaps == 0) { |
539 | error = (ENOSPC); | 556 | error = ENOSPC; |
557 | goto error_out; | ||
558 | } | ||
559 | |||
560 | if (unlikely(!imap.br_startblock && !(io->io_flags & XFS_IOCORE_RT))) { | ||
561 | error = xfs_cmn_err_fsblock_zero(ip, &imap); | ||
540 | goto error_out; | 562 | goto error_out; |
541 | } | 563 | } |
542 | 564 | ||
543 | *ret_imap = imap; | 565 | *ret_imap = imap; |
544 | *nmaps = 1; | 566 | *nmaps = 1; |
545 | if ( !(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) { | ||
546 | cmn_err(CE_PANIC,"Access to block zero: fs <%s> inode: %lld " | ||
547 | "start_block : %llx start_off : %llx blkcnt : %llx " | ||
548 | "extent-state : %x \n", | ||
549 | (ip->i_mount)->m_fsname, | ||
550 | (long long)ip->i_ino, | ||
551 | (unsigned long long)ret_imap->br_startblock, | ||
552 | (unsigned long long)ret_imap->br_startoff, | ||
553 | (unsigned long long)ret_imap->br_blockcount, | ||
554 | ret_imap->br_state); | ||
555 | } | ||
556 | return 0; | 567 | return 0; |
557 | 568 | ||
558 | error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ | 569 | error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ |
@@ -715,17 +726,8 @@ retry: | |||
715 | goto retry; | 726 | goto retry; |
716 | } | 727 | } |
717 | 728 | ||
718 | if (!(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) { | 729 | if (unlikely(!imap[0].br_startblock && !(io->io_flags & XFS_IOCORE_RT))) |
719 | cmn_err(CE_PANIC,"Access to block zero: fs <%s> inode: %lld " | 730 | return xfs_cmn_err_fsblock_zero(ip, &imap[0]); |
720 | "start_block : %llx start_off : %llx blkcnt : %llx " | ||
721 | "extent-state : %x \n", | ||
722 | (ip->i_mount)->m_fsname, | ||
723 | (long long)ip->i_ino, | ||
724 | (unsigned long long)ret_imap->br_startblock, | ||
725 | (unsigned long long)ret_imap->br_startoff, | ||
726 | (unsigned long long)ret_imap->br_blockcount, | ||
727 | ret_imap->br_state); | ||
728 | } | ||
729 | 731 | ||
730 | *ret_imap = imap[0]; | 732 | *ret_imap = imap[0]; |
731 | *nmaps = 1; | 733 | *nmaps = 1; |
@@ -853,24 +855,10 @@ xfs_iomap_write_allocate( | |||
853 | * See if we were able to allocate an extent that | 855 | * See if we were able to allocate an extent that |
854 | * covers at least part of the callers request | 856 | * covers at least part of the callers request |
855 | */ | 857 | */ |
856 | |||
857 | for (i = 0; i < nimaps; i++) { | 858 | for (i = 0; i < nimaps; i++) { |
858 | if (!(io->io_flags & XFS_IOCORE_RT) && | 859 | if (unlikely(!imap[i].br_startblock && |
859 | !imap[i].br_startblock) { | 860 | !(io->io_flags & XFS_IOCORE_RT))) |
860 | cmn_err(CE_PANIC,"Access to block zero: " | 861 | return xfs_cmn_err_fsblock_zero(ip, &imap[i]); |
861 | "fs <%s> inode: %lld " | ||
862 | "start_block : %llx start_off : %llx " | ||
863 | "blkcnt : %llx extent-state : %x \n", | ||
864 | (ip->i_mount)->m_fsname, | ||
865 | (long long)ip->i_ino, | ||
866 | (unsigned long long) | ||
867 | imap[i].br_startblock, | ||
868 | (unsigned long long) | ||
869 | imap[i].br_startoff, | ||
870 | (unsigned long long) | ||
871 | imap[i].br_blockcount, | ||
872 | imap[i].br_state); | ||
873 | } | ||
874 | if ((offset_fsb >= imap[i].br_startoff) && | 862 | if ((offset_fsb >= imap[i].br_startoff) && |
875 | (offset_fsb < (imap[i].br_startoff + | 863 | (offset_fsb < (imap[i].br_startoff + |
876 | imap[i].br_blockcount))) { | 864 | imap[i].br_blockcount))) { |
@@ -941,7 +929,7 @@ xfs_iomap_write_unwritten( | |||
941 | XFS_WRITE_LOG_COUNT); | 929 | XFS_WRITE_LOG_COUNT); |
942 | if (error) { | 930 | if (error) { |
943 | xfs_trans_cancel(tp, 0); | 931 | xfs_trans_cancel(tp, 0); |
944 | goto error0; | 932 | return XFS_ERROR(error); |
945 | } | 933 | } |
946 | 934 | ||
947 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 935 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
@@ -967,19 +955,11 @@ xfs_iomap_write_unwritten( | |||
967 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); | 955 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); |
968 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 956 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
969 | if (error) | 957 | if (error) |
970 | goto error0; | 958 | return XFS_ERROR(error); |
971 | 959 | ||
972 | if ( !(io->io_flags & XFS_IOCORE_RT) && !imap.br_startblock) { | 960 | if (unlikely(!imap.br_startblock && |
973 | cmn_err(CE_PANIC,"Access to block zero: fs <%s> " | 961 | !(io->io_flags & XFS_IOCORE_RT))) |
974 | "inode: %lld start_block : %llx start_off : " | 962 | return xfs_cmn_err_fsblock_zero(ip, &imap); |
975 | "%llx blkcnt : %llx extent-state : %x \n", | ||
976 | (ip->i_mount)->m_fsname, | ||
977 | (long long)ip->i_ino, | ||
978 | (unsigned long long)imap.br_startblock, | ||
979 | (unsigned long long)imap.br_startoff, | ||
980 | (unsigned long long)imap.br_blockcount, | ||
981 | imap.br_state); | ||
982 | } | ||
983 | 963 | ||
984 | if ((numblks_fsb = imap.br_blockcount) == 0) { | 964 | if ((numblks_fsb = imap.br_blockcount) == 0) { |
985 | /* | 965 | /* |
@@ -999,6 +979,5 @@ error_on_bmapi_transaction: | |||
999 | xfs_bmap_cancel(&free_list); | 979 | xfs_bmap_cancel(&free_list); |
1000 | xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT)); | 980 | xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT)); |
1001 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 981 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
1002 | error0: | ||
1003 | return XFS_ERROR(error); | 982 | return XFS_ERROR(error); |
1004 | } | 983 | } |