aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Scott <nathans@sgi.com>2006-09-27 21:03:20 -0400
committerTim Shimmin <tes@sgi.com>2006-09-27 21:03:20 -0400
commit572d95f49f3652fffe8242c4498b85f4083e52ab (patch)
tree5c452a69a005a6a18dc80e4ab7090d6d8e230fc6
parent948ecdb4c118293d2f3e267eec642c30c5d3a056 (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.c2
-rw-r--r--fs/xfs/xfs_bmap.c27
-rw-r--r--fs/xfs/xfs_error.h1
-rw-r--r--fs/xfs/xfs_iomap.c89
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 */
3705xfs_bmap_search_extents( 3705xfs_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
171struct xfs_mount; 172struct 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
401STATIC int
402xfs_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
401int 418int
402xfs_iomap_write_direct( 419xfs_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
558error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ 569error0: /* 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);
1002error0:
1003 return XFS_ERROR(error); 982 return XFS_ERROR(error);
1004} 983}