Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ xfs_param_t xfs_params = {
	.restrict_chown	= {	0,		1,		1	},
	.sgid_inherit	= {	0,		0,		1	},
	.symlink_mode	= {	0,		0,		1	},
	.panic_mask	= {	0,		0,		127	},
	.panic_mask	= {	0,		0,		255	},
	.error_level	= {	0,		3,		11	},
	.syncd_timer	= {	1*100,		30*100,		7200*100},
	.stats_clear	= {	0,		0,		1	},
+15 −12
Original line number Diff line number Diff line
@@ -3705,7 +3705,7 @@ STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */
xfs_bmap_search_extents(
	xfs_inode_t     *ip,            /* incore inode pointer */
	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 */
	xfs_extnum_t    *lastxp,        /* out: last extent index */
	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_bmbt_rec_t  *ep;            /* extent record pointer */
	int		rt;		/* realtime flag    */

	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);

	rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
	if (unlikely(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM))) {
                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,
	if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) &&
		     !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) {
		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 lastx: %x\n",
			(unsigned long long)ip->i_ino,
			(unsigned long long)gotp->br_startblock,
			(unsigned long long)gotp->br_startoff,
			(unsigned long long)gotp->br_blockcount,
			gotp->br_state);
			gotp->br_state, *lastxp);
		*lastxp = NULLEXTNUM;
		*eofp = 1;
		return NULL;
	}
	return ep;
}
+1 −0
Original line number Diff line number Diff line
@@ -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_IOERROR	0x00000020
#define		XFS_PTAG_SHUTDOWN_LOGERROR	0x00000040
#define		XFS_PTAG_FSBLOCK_ZERO		0x00000080

struct xfs_mount;
/* PRINTFLIKE4 */
+34 −55
Original line number Diff line number Diff line
@@ -398,6 +398,23 @@ xfs_flush_space(
	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
xfs_iomap_write_direct(
	xfs_inode_t	*ip,
@@ -536,23 +553,17 @@ xfs_iomap_write_direct(
	 * Copy any maps to caller's array and return any error.
	 */
	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;
	}

	*ret_imap = imap;
	*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;

error0:	/* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
@@ -715,17 +726,8 @@ xfs_iomap_write_delay(
		goto retry;
	}

	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);
	}
	if (unlikely(!imap[0].br_startblock && !(io->io_flags & XFS_IOCORE_RT)))
		return xfs_cmn_err_fsblock_zero(ip, &imap[0]);

	*ret_imap = imap[0];
	*nmaps = 1;
@@ -853,24 +855,10 @@ xfs_iomap_write_allocate(
		 * See if we were able to allocate an extent that
		 * covers at least part of the callers request
		 */

		for (i = 0; i < nimaps; i++) {
			if (!(io->io_flags & XFS_IOCORE_RT)  &&
			    !imap[i].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)
						imap[i].br_startblock,
					(unsigned long long)
						imap[i].br_startoff,
					(unsigned long long)
				        	imap[i].br_blockcount,
					imap[i].br_state);
                        }
			if (unlikely(!imap[i].br_startblock &&
				     !(io->io_flags & XFS_IOCORE_RT)))
				return xfs_cmn_err_fsblock_zero(ip, &imap[i]);
			if ((offset_fsb >= imap[i].br_startoff) &&
			    (offset_fsb < (imap[i].br_startoff +
					   imap[i].br_blockcount))) {
@@ -941,7 +929,7 @@ xfs_iomap_write_unwritten(
				XFS_WRITE_LOG_COUNT);
		if (error) {
			xfs_trans_cancel(tp, 0);
			goto error0;
			return XFS_ERROR(error);
		}

		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);
		xfs_iunlock(ip, XFS_ILOCK_EXCL);
		if (error)
			goto error0;
			return XFS_ERROR(error);

		if ( !(io->io_flags & XFS_IOCORE_RT)  && !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)imap.br_startblock,
				(unsigned long long)imap.br_startoff,
				(unsigned long long)imap.br_blockcount,
				imap.br_state);
        	}
		if (unlikely(!imap.br_startblock &&
			     !(io->io_flags & XFS_IOCORE_RT)))
			return xfs_cmn_err_fsblock_zero(ip, &imap);

		if ((numblks_fsb = imap.br_blockcount) == 0) {
			/*
@@ -999,6 +979,5 @@ xfs_iomap_write_unwritten(
	xfs_bmap_cancel(&free_list);
	xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT));
	xfs_iunlock(ip, XFS_ILOCK_EXCL);
error0:
	return XFS_ERROR(error);
}