Commit 572d95f4 authored by Nathan Scott's avatar Nathan Scott Committed by Tim Shimmin

[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: default avatarNathan Scott <nathans@sgi.com>
Signed-off-by: default avatarTim Shimmin <tes@sgi.com>
parent 948ecdb4
...@@ -34,7 +34,7 @@ xfs_param_t xfs_params = { ...@@ -34,7 +34,7 @@ xfs_param_t xfs_params = {
.restrict_chown = { 0, 1, 1 }, .restrict_chown = { 0, 1, 1 },
.sgid_inherit = { 0, 0, 1 }, .sgid_inherit = { 0, 0, 1 },
.symlink_mode = { 0, 0, 1 }, .symlink_mode = { 0, 0, 1 },
.panic_mask = { 0, 0, 127 }, .panic_mask = { 0, 0, 255 },
.error_level = { 0, 3, 11 }, .error_level = { 0, 3, 11 },
.syncd_timer = { 1*100, 30*100, 7200*100}, .syncd_timer = { 1*100, 30*100, 7200*100},
.stats_clear = { 0, 0, 1 }, .stats_clear = { 0, 0, 1 },
......
...@@ -3705,7 +3705,7 @@ STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */ ...@@ -3705,7 +3705,7 @@ STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */
xfs_bmap_search_extents( xfs_bmap_search_extents(
xfs_inode_t *ip, /* incore inode pointer */ xfs_inode_t *ip, /* incore inode pointer */
xfs_fileoff_t bno, /* block number searched for */ xfs_fileoff_t bno, /* block number searched for */
int whichfork, /* data or attr fork */ int fork, /* data or attr fork */
int *eofp, /* out: end of file found */ int *eofp, /* out: end of file found */
xfs_extnum_t *lastxp, /* out: last extent index */ xfs_extnum_t *lastxp, /* out: last extent index */
xfs_bmbt_irec_t *gotp, /* out: extent entry found */ xfs_bmbt_irec_t *gotp, /* out: extent entry found */
...@@ -3713,23 +3713,26 @@ xfs_bmap_search_extents( ...@@ -3713,23 +3713,26 @@ xfs_bmap_search_extents(
{ {
xfs_ifork_t *ifp; /* inode fork pointer */ xfs_ifork_t *ifp; /* inode fork pointer */
xfs_bmbt_rec_t *ep; /* extent record pointer */ xfs_bmbt_rec_t *ep; /* extent record pointer */
int rt; /* realtime flag */
XFS_STATS_INC(xs_look_exlist); XFS_STATS_INC(xs_look_exlist);
ifp = XFS_IFORK_PTR(ip, whichfork); ifp = XFS_IFORK_PTR(ip, fork);
ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp); ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp);
rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) &&
if (unlikely(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM))) { !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) {
cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld " xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount,
"start_block : %llx start_off : %llx blkcnt : %llx " "Access to block zero in inode %llu "
"extent-state : %x \n", "start_block: %llx start_off: %llx "
(ip->i_mount)->m_fsname, (long long)ip->i_ino, "blkcnt: %llx extent-state: %x lastx: %x\n",
(unsigned long long)ip->i_ino,
(unsigned long long)gotp->br_startblock, (unsigned long long)gotp->br_startblock,
(unsigned long long)gotp->br_startoff, (unsigned long long)gotp->br_startoff,
(unsigned long long)gotp->br_blockcount, (unsigned long long)gotp->br_blockcount,
gotp->br_state); gotp->br_state, *lastxp);
*lastxp = NULLEXTNUM;
*eofp = 1;
return NULL;
} }
return ep; return ep;
} }
......
...@@ -167,6 +167,7 @@ extern int xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud); ...@@ -167,6 +167,7 @@ extern int xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud);
#define XFS_PTAG_SHUTDOWN_CORRUPT 0x00000010 #define XFS_PTAG_SHUTDOWN_CORRUPT 0x00000010
#define XFS_PTAG_SHUTDOWN_IOERROR 0x00000020 #define XFS_PTAG_SHUTDOWN_IOERROR 0x00000020
#define XFS_PTAG_SHUTDOWN_LOGERROR 0x00000040 #define XFS_PTAG_SHUTDOWN_LOGERROR 0x00000040
#define XFS_PTAG_FSBLOCK_ZERO 0x00000080
struct xfs_mount; struct xfs_mount;
/* PRINTFLIKE4 */ /* PRINTFLIKE4 */
......
...@@ -398,6 +398,23 @@ xfs_flush_space( ...@@ -398,6 +398,23 @@ xfs_flush_space(
return 1; return 1;
} }
STATIC int
xfs_cmn_err_fsblock_zero(
xfs_inode_t *ip,
xfs_bmbt_irec_t *imap)
{
xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount,
"Access to block zero in inode %llu "
"start_block: %llx start_off: %llx "
"blkcnt: %llx extent-state: %x\n",
(unsigned long long)ip->i_ino,
(unsigned long long)imap->br_startblock,
(unsigned long long)imap->br_startoff,
(unsigned long long)imap->br_blockcount,
imap->br_state);
return EFSCORRUPTED;
}
int int
xfs_iomap_write_direct( xfs_iomap_write_direct(
xfs_inode_t *ip, xfs_inode_t *ip,
...@@ -536,23 +553,17 @@ xfs_iomap_write_direct( ...@@ -536,23 +553,17 @@ xfs_iomap_write_direct(
* Copy any maps to caller's array and return any error. * Copy any maps to caller's array and return any error.
*/ */
if (nimaps == 0) { if (nimaps == 0) {
error = (ENOSPC); error = ENOSPC;
goto error_out;
}
if (unlikely(!imap.br_startblock && !(io->io_flags & XFS_IOCORE_RT))) {
error = xfs_cmn_err_fsblock_zero(ip, &imap);
goto error_out; goto error_out;
} }
*ret_imap = imap; *ret_imap = imap;
*nmaps = 1; *nmaps = 1;
if ( !(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) {
cmn_err(CE_PANIC,"Access to block zero: fs <%s> inode: %lld "
"start_block : %llx start_off : %llx blkcnt : %llx "
"extent-state : %x \n",
(ip->i_mount)->m_fsname,
(long long)ip->i_ino,
(unsigned long long)ret_imap->br_startblock,
(unsigned long long)ret_imap->br_startoff,
(unsigned long long)ret_imap->br_blockcount,
ret_imap->br_state);
}
return 0; return 0;
error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
...@@ -715,17 +726,8 @@ xfs_iomap_write_delay( ...@@ -715,17 +726,8 @@ xfs_iomap_write_delay(
goto retry; goto retry;
} }
if (!(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) { if (unlikely(!imap[0].br_startblock && !(io->io_flags & XFS_IOCORE_RT)))
cmn_err(CE_PANIC,"Access to block zero: fs <%s> inode: %lld " return xfs_cmn_err_fsblock_zero(ip, &imap[0]);
"start_block : %llx start_off : %llx blkcnt : %llx "
"extent-state : %x \n",
(ip->i_mount)->m_fsname,
(long long)ip->i_ino,
(unsigned long long)ret_imap->br_startblock,
(unsigned long long)ret_imap->br_startoff,
(unsigned long long)ret_imap->br_blockcount,
ret_imap->br_state);
}
*ret_imap = imap[0]; *ret_imap = imap[0];
*nmaps = 1; *nmaps = 1;
...@@ -853,24 +855,10 @@ xfs_iomap_write_allocate( ...@@ -853,24 +855,10 @@ xfs_iomap_write_allocate(
* See if we were able to allocate an extent that * See if we were able to allocate an extent that
* covers at least part of the callers request * covers at least part of the callers request
*/ */
for (i = 0; i < nimaps; i++) { for (i = 0; i < nimaps; i++) {
if (!(io->io_flags & XFS_IOCORE_RT) && if (unlikely(!imap[i].br_startblock &&
!imap[i].br_startblock) { !(io->io_flags & XFS_IOCORE_RT)))
cmn_err(CE_PANIC,"Access to block zero: " return xfs_cmn_err_fsblock_zero(ip, &imap[i]);
"fs <%s> inode: %lld "
"start_block : %llx start_off : %llx "
"blkcnt : %llx extent-state : %x \n",
(ip->i_mount)->m_fsname,
(long long)ip->i_ino,
(unsigned long long)
imap[i].br_startblock,
(unsigned long long)
imap[i].br_startoff,
(unsigned long long)
imap[i].br_blockcount,
imap[i].br_state);
}
if ((offset_fsb >= imap[i].br_startoff) && if ((offset_fsb >= imap[i].br_startoff) &&
(offset_fsb < (imap[i].br_startoff + (offset_fsb < (imap[i].br_startoff +
imap[i].br_blockcount))) { imap[i].br_blockcount))) {
...@@ -941,7 +929,7 @@ xfs_iomap_write_unwritten( ...@@ -941,7 +929,7 @@ xfs_iomap_write_unwritten(
XFS_WRITE_LOG_COUNT); XFS_WRITE_LOG_COUNT);
if (error) { if (error) {
xfs_trans_cancel(tp, 0); xfs_trans_cancel(tp, 0);
goto error0; return XFS_ERROR(error);
} }
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
...@@ -967,19 +955,11 @@ xfs_iomap_write_unwritten( ...@@ -967,19 +955,11 @@ xfs_iomap_write_unwritten(
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_iunlock(ip, XFS_ILOCK_EXCL);
if (error) if (error)
goto error0; return XFS_ERROR(error);
if ( !(io->io_flags & XFS_IOCORE_RT) && !imap.br_startblock) { if (unlikely(!imap.br_startblock &&
cmn_err(CE_PANIC,"Access to block zero: fs <%s> " !(io->io_flags & XFS_IOCORE_RT)))
"inode: %lld start_block : %llx start_off : " return xfs_cmn_err_fsblock_zero(ip, &imap);
"%llx blkcnt : %llx extent-state : %x \n",
(ip->i_mount)->m_fsname,
(long long)ip->i_ino,
(unsigned long long)imap.br_startblock,
(unsigned long long)imap.br_startoff,
(unsigned long long)imap.br_blockcount,
imap.br_state);
}
if ((numblks_fsb = imap.br_blockcount) == 0) { if ((numblks_fsb = imap.br_blockcount) == 0) {
/* /*
...@@ -999,6 +979,5 @@ xfs_iomap_write_unwritten( ...@@ -999,6 +979,5 @@ xfs_iomap_write_unwritten(
xfs_bmap_cancel(&free_list); xfs_bmap_cancel(&free_list);
xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT)); xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT));
xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_iunlock(ip, XFS_ILOCK_EXCL);
error0:
return XFS_ERROR(error); return XFS_ERROR(error);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment