[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>
This commit is contained in:
parent
948ecdb4c1
commit
572d95f49f
4 changed files with 50 additions and 67 deletions
|
@ -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 */
|
||||||
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(
|
||||||
{
|
{
|
||||||
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);
|
||||||
#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(
|
||||||
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(
|
||||||
* 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(
|
||||||
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(
|
||||||
* 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(
|
||||||
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(
|
||||||
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(
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue