public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
* review: fsblock zero - don't panic
@ 2006-08-10  5:58 Nathan Scott
  2006-08-11  3:26 ` David Chinner
  0 siblings, 1 reply; 7+ messages in thread
From: Nathan Scott @ 2006-08-10  5:58 UTC (permalink / raw)
  To: xfs

As part of attempting to understand what happened in a corruption
problem awhile back, and generally be a bit more defensive of our
precious primary superblock, some code was added to XFS to detect
(and panic) on any inode extents that start at block zero.

This has happened once or twice now, and when it does, we panic the
kernel.  This is not at all nice, as it means we take out the whole
system due to ondisk corruption.  This patch makes that code issue
a warning now, and fail whatever operation was in progress.

cheers.

-- 
Nathan


Index: xfs-linux/xfs_bmap.c
===================================================================
--- xfs-linux.orig/xfs_bmap.c	2006-08-08 15:59:14.396022750 +1000
+++ xfs-linux/xfs_bmap.c	2006-08-08 16:08:34.790988750 +1000
@@ -3722,16 +3722,19 @@ xfs_bmap_search_extents(
 
 	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,
+		cmn_err(CE_WARN, "Access to block zero: fs: <%s> inode: %lld "
+				 "start_block : %llx start_off : %llx "
+				 "blkcnt : %llx extent-state : %x lastx : %x\n",
+			ip->i_mount->m_fsname, (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);
-        }
-        return ep;
+			gotp->br_state, *lastxp);
+		ASSERT(0);
+		*eofp = 1;
+		return NULL;
+	}
+	return ep;
 }
 
 
Index: xfs-linux/xfs_iomap.c
===================================================================
--- xfs-linux.orig/xfs_iomap.c	2006-08-08 15:59:14.428024750 +1000
+++ xfs-linux/xfs_iomap.c	2006-08-08 16:18:40.116068500 +1000
@@ -536,23 +536,28 @@ 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;
 	}
 
-	*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,
+	if (unlikely(
+	    !(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock)) {
+		cmn_err(CE_WARN, "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,
+			(unsigned long long)ret_imap->br_blockcount,
 			ret_imap->br_state);
-        }
+		ASSERT(0);
+		error = EFSCORRUPTED;
+		goto error_out;
+	}
+
+	*ret_imap = imap;
+	*nmaps = 1;
 	return 0;
 
 error0:	/* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
@@ -715,16 +720,19 @@ retry:
 		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(
+	    !(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock)) {
+		cmn_err(CE_WARN, "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);
+		ASSERT(0);
+		return XFS_ERROR(EFSCORRUPTED);
 	}
 
 	*ret_imap = imap[0];
@@ -855,15 +863,15 @@ 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,
+			if (unlikely(!(io->io_flags & XFS_IOCORE_RT) &&
+				     !imap[i].br_startblock)) {
+				cmn_err(CE_WARN,
+					"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,
@@ -872,7 +880,9 @@ xfs_iomap_write_allocate(
 					(unsigned long long)
 				        	imap[i].br_blockcount,
 					imap[i].br_state);
-                        }
+				ASSERT(0);
+				return XFS_ERROR(EFSCORRUPTED);
+			}
 			if ((offset_fsb >= imap[i].br_startoff) &&
 			    (offset_fsb < (imap[i].br_startoff +
 					   imap[i].br_blockcount))) {
@@ -951,7 +961,7 @@ xfs_iomap_write_unwritten(
 		}
 		if (error) {
 			xfs_trans_cancel(tp, 0);
-			goto error0;
+			return XFS_ERROR(error);
 		}
 
 		xfs_ilock(ip, XFS_ILOCK_EXCL);
@@ -977,18 +987,22 @@ 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,
+		if (unlikely(
+		    !(io->io_flags & XFS_IOCORE_RT) && !imap.br_startblock)) {
+			cmn_err(CE_WARN, "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);
+			ASSERT(0);
+			return XFS_ERROR(EFSCORRUPTED);
         	}
 
 		if ((numblks_fsb = imap.br_blockcount) == 0) {
@@ -1009,6 +1023,5 @@ error_on_bmapi_transaction:
 	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);
 }

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: review: fsblock zero - don't panic
  2006-08-10  5:58 review: fsblock zero - don't panic Nathan Scott
@ 2006-08-11  3:26 ` David Chinner
  2006-08-16  4:28   ` Nathan Scott
  0 siblings, 1 reply; 7+ messages in thread
From: David Chinner @ 2006-08-11  3:26 UTC (permalink / raw)
  To: Nathan Scott; +Cc: xfs

On Thu, Aug 10, 2006 at 03:58:51PM +1000, Nathan Scott wrote:
> As part of attempting to understand what happened in a corruption
> problem awhile back, and generally be a bit more defensive of our
> precious primary superblock, some code was added to XFS to detect
> (and panic) on any inode extents that start at block zero.
> 
> This has happened once or twice now, and when it does, we panic the
> kernel.  This is not at all nice, as it means we take out the whole
> system due to ondisk corruption.  This patch makes that code issue
> a warning now, and fail whatever operation was in progress.

Looks OK.

FWIW:

> -	if ( !(io->io_flags & XFS_IOCORE_RT)  && !ret_imap->br_startblock) {
.....
> +	if (unlikely(
> +	    !(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock)) {

If you are hinting this branch to be unlikely, then we should also
check the start block first before checking the io_flags.  We only
need to check the io_flags if we are actually accessing block zero.
i.e.

+	if (unlikely(
+	    !ret_imap->br_startblock && !(io->io_flags & XFS_IOCORE_RT))) {

Cheers,

Dave.
-- 
Dave Chinner
Principal Engineer
SGI Australian Software Group

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: review: fsblock zero - don't panic
  2006-08-11  3:26 ` David Chinner
@ 2006-08-16  4:28   ` Nathan Scott
  2006-08-16  6:47     ` David Chinner
  2006-08-16  7:23     ` Stewart Smith
  0 siblings, 2 replies; 7+ messages in thread
From: Nathan Scott @ 2006-08-16  4:28 UTC (permalink / raw)
  To: David Chinner; +Cc: xfs

On Fri, Aug 11, 2006 at 01:26:26PM +1000, David Chinner wrote:
> ...
> Looks OK.

Thanks mate.

> ...
> If you are hinting this branch to be unlikely, then we should also
> check the start block first before checking the io_flags.  We only
> need to check the io_flags if we are actually accessing block zero.

I've rolled this into a new version.  I also got prodded to still
provide an option to panic on detecting this, for debugging - so I
rewrote this to report through the panic_mask mechanism, which now
gives us the option to optionally panic if need be... could you do
a second pass over this for me?

cheers.

-- 
Nathan


Index: xfs-linux/xfs_bmap.c
===================================================================
--- xfs-linux.orig/xfs_bmap.c	2006-08-15 15:22:53.198187750 +1000
+++ xfs-linux/xfs_bmap.c	2006-08-16 12:40:49.669518000 +1000
@@ -3705,7 +3705,7 @@ STATIC xfs_bmbt_rec_t *                 
 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,25 +3713,28 @@ 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);
-        }
-        return ep;
+			gotp->br_state, *lastxp);
+		*lastxp = NULLEXTNUM;
+		*eofp = 1;
+		return NULL;
+	}
+	return ep;
 }
 
 
Index: xfs-linux/xfs_iomap.c
===================================================================
--- xfs-linux.orig/xfs_iomap.c	2006-08-15 15:22:53.238190250 +1000
+++ xfs-linux/xfs_iomap.c	2006-08-16 12:40:41.385000250 +1000
@@ -536,23 +536,27 @@ 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;
 	}
 
-	*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,
+	if (unlikely(!ret_imap->br_startblock &&
+		     !(io->io_flags & XFS_IOCORE_RT))) {
+		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)ret_imap->br_startblock,
 			(unsigned long long)ret_imap->br_startoff,
-                        (unsigned long long)ret_imap->br_blockcount,
+			(unsigned long long)ret_imap->br_blockcount,
 			ret_imap->br_state);
-        }
+		error = EFSCORRUPTED;
+		goto error_out;
+	}
+
+	*ret_imap = imap;
+	*nmaps = 1;
 	return 0;
 
 error0:	/* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
@@ -715,16 +719,18 @@ retry:
 		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,
+	if (unlikely(!ret_imap->br_startblock &&
+		     !(io->io_flags & XFS_IOCORE_RT))) {
+		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)ret_imap->br_startblock,
 			(unsigned long long)ret_imap->br_startoff,
-                        (unsigned long long)ret_imap->br_blockcount,
+			(unsigned long long)ret_imap->br_blockcount,
 			ret_imap->br_state);
+		return XFS_ERROR(EFSCORRUPTED);
 	}
 
 	*ret_imap = imap[0];
@@ -855,16 +861,14 @@ 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,
+			if (unlikely(!imap[i].br_startblock &&
+				     !(io->io_flags & XFS_IOCORE_RT))) {
+				xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, mp,
+					"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[i].br_startblock,
 					(unsigned long long)
@@ -872,7 +876,8 @@ xfs_iomap_write_allocate(
 					(unsigned long long)
 				        	imap[i].br_blockcount,
 					imap[i].br_state);
-                        }
+				return XFS_ERROR(EFSCORRUPTED);
+			}
 			if ((offset_fsb >= imap[i].br_startoff) &&
 			    (offset_fsb < (imap[i].br_startoff +
 					   imap[i].br_blockcount))) {
@@ -951,7 +956,7 @@ xfs_iomap_write_unwritten(
 		}
 		if (error) {
 			xfs_trans_cancel(tp, 0);
-			goto error0;
+			return XFS_ERROR(error);
 		}
 
 		xfs_ilock(ip, XFS_ILOCK_EXCL);
@@ -977,19 +982,21 @@ 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,
+		if (unlikely(!imap.br_startblock &&
+			     !(io->io_flags & XFS_IOCORE_RT))) {
+				xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, mp,
+					"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 XFS_ERROR(EFSCORRUPTED);
+		}
 
 		if ((numblks_fsb = imap.br_blockcount) == 0) {
 			/*
@@ -1009,6 +1016,5 @@ error_on_bmapi_transaction:
 	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);
 }
Index: xfs-linux/linux-2.4/xfs_globals.c
===================================================================
--- xfs-linux.orig/linux-2.4/xfs_globals.c	2006-08-16 11:35:46.090456000 +1000
+++ xfs-linux/linux-2.4/xfs_globals.c	2006-08-16 11:35:51.546797000 +1000
@@ -37,7 +37,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,	60*100	},
 	.probe_dmapi	= {	0,	0,	1	},
Index: xfs-linux/linux-2.6/xfs_globals.c
===================================================================
--- xfs-linux.orig/linux-2.6/xfs_globals.c	2006-08-16 11:35:46.182461750 +1000
+++ xfs-linux/linux-2.6/xfs_globals.c	2006-08-16 11:36:59.859066250 +1000
@@ -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},
 	.probe_dmapi	= {	0,		0,		1	},
Index: xfs-linux/xfs_error.h
===================================================================
--- xfs-linux.orig/xfs_error.h	2006-08-16 11:35:03.599800500 +1000
+++ xfs-linux/xfs_error.h	2006-08-16 12:40:15.755398500 +1000
@@ -167,6 +167,7 @@ extern int xfs_errortag_clearall_umount(
 #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 */

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: review: fsblock zero - don't panic
  2006-08-16  4:28   ` Nathan Scott
@ 2006-08-16  6:47     ` David Chinner
  2006-08-16  6:57       ` Nathan Scott
  2006-08-16  7:23     ` Stewart Smith
  1 sibling, 1 reply; 7+ messages in thread
From: David Chinner @ 2006-08-16  6:47 UTC (permalink / raw)
  To: Nathan Scott; +Cc: xfs

On Wed, Aug 16, 2006 at 02:28:01PM +1000, Nathan Scott wrote:
> On Fri, Aug 11, 2006 at 01:26:26PM +1000, David Chinner wrote:
> > ...
> > Looks OK.
> 
> Thanks mate.
> 
> > ...
> > If you are hinting this branch to be unlikely, then we should also
> > check the start block first before checking the io_flags.  We only
> > need to check the io_flags if we are actually accessing block zero.
> 
> I've rolled this into a new version.  I also got prodded to still
> provide an option to panic on detecting this, for debugging - so I
> rewrote this to report through the panic_mask mechanism, which now
> gives us the option to optionally panic if need be... could you do
> a second pass over this for me?

Couple of things:

> Index: xfs-linux/xfs_iomap.c
> ===================================================================
> --- xfs-linux.orig/xfs_iomap.c	2006-08-15 15:22:53.238190250 +1000
> +++ xfs-linux/xfs_iomap.c	2006-08-16 12:40:41.385000250 +1000
> @@ -536,23 +536,27 @@ 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;
>  	}
>  
> -	*ret_imap = imap;
> -	*nmaps = 1;
> -	if ( !(io->io_flags & XFS_IOCORE_RT)  && !ret_imap->br_startblock) {

Here we check imap for block zero access....

> -                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,
> +	if (unlikely(!ret_imap->br_startblock &&

and now you're checking ret_imap for zero block access. Shouldn't that
be checking imap?

> +		     !(io->io_flags & XFS_IOCORE_RT))) {
> +		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)ret_imap->br_startblock,
>  			(unsigned long long)ret_imap->br_startoff,
> -                        (unsigned long long)ret_imap->br_blockcount,
> +			(unsigned long long)ret_imap->br_blockcount,
>  			ret_imap->br_state);

FWIW, given the number of times this exact same code is given, a
wrapper function for it would clean up the code quite a bit. i.e.

		xfs_cmn_err_fsblock_zero(ip, ret_imap);

would replace the above mess....

> -        }
> +		error = EFSCORRUPTED;
> +		goto error_out;
> +	}
> +
> +	*ret_imap = imap;
> +	*nmaps = 1;
>  	return 0;
>  
>  error0:	/* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
> @@ -715,16 +719,18 @@ retry:
>  		goto retry;
>  	}
>  
> -	if (!(io->io_flags & XFS_IOCORE_RT)  && !ret_imap->br_startblock) {

And this one checks ret_imap for block zero, not imap[0].

One of these original checks was buggy - which one should we be checking,
ret_imap that is being passed into the function or imap that is what was
returned  by the XFS_BMAPI call?

Cheers,

Dave.
-- 
Dave Chinner
Principal Engineer
SGI Australian Software Group

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: review: fsblock zero - don't panic
  2006-08-16  6:47     ` David Chinner
@ 2006-08-16  6:57       ` Nathan Scott
  0 siblings, 0 replies; 7+ messages in thread
From: Nathan Scott @ 2006-08-16  6:57 UTC (permalink / raw)
  To: David Chinner; +Cc: xfs

On Wed, Aug 16, 2006 at 04:47:25PM +1000, David Chinner wrote:
> On Wed, Aug 16, 2006 at 02:28:01PM +1000, Nathan Scott wrote:
> ...
> 		xfs_cmn_err_fsblock_zero(ip, ret_imap);
> 
> would replace the above mess....

Will do.

> > -	if (!(io->io_flags & XFS_IOCORE_RT)  && !ret_imap->br_startblock) {
> 
> And this one checks ret_imap for block zero, not imap[0].
> 
> One of these original checks was buggy - which one should we be checking,
> ret_imap that is being passed into the function or imap that is what was
> returned  by the XFS_BMAPI call?

The latter I think - I'll look more closely tomorrow, and fix that up.

cheers.

-- 
Nathan

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: review: fsblock zero - don't panic
  2006-08-16  4:28   ` Nathan Scott
  2006-08-16  6:47     ` David Chinner
@ 2006-08-16  7:23     ` Stewart Smith
  2006-08-16 23:45       ` Nathan Scott
  1 sibling, 1 reply; 7+ messages in thread
From: Stewart Smith @ 2006-08-16  7:23 UTC (permalink / raw)
  To: Nathan Scott; +Cc: David Chinner, xfs

[-- Attachment #1: Type: text/plain, Size: 4880 bytes --]

On Wed, 2006-08-16 at 14:28 +1000, Nathan Scott wrote:
> On Fri, Aug 11, 2006 at 01:26:26PM +1000, David Chinner wrote:
> > ...
> > Looks OK.
> 
> Thanks mate.
> 
> > ...
> > If you are hinting this branch to be unlikely, then we should also
> > check the start block first before checking the io_flags.  We only
> > need to check the io_flags if we are actually accessing block zero.
> 
> I've rolled this into a new version.  I also got prodded to still
> provide an option to panic on detecting this, for debugging - so I
> rewrote this to report through the panic_mask mechanism, which now
> gives us the option to optionally panic if need be... could you do
> a second pass over this for me?
> 
> cheers.
> 
> -- 
> Nathan
> 
> 
> Index: xfs-linux/xfs_bmap.c
> ===================================================================
> --- xfs-linux.orig/xfs_bmap.c	2006-08-15 15:22:53.198187750 +1000
> +++ xfs-linux/xfs_bmap.c	2006-08-16 12:40:49.669518000 +1000
> @@ -3705,7 +3705,7 @@ STATIC xfs_bmbt_rec_t *                 
>  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,25 +3713,28 @@ 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);
> -        }
> -        return ep;
> +			gotp->br_state, *lastxp);
> +		*lastxp = NULLEXTNUM;
> +		*eofp = 1;
> +		return NULL;
> +	}
> +	return ep;
>  }
>  
> 
> Index: xfs-linux/xfs_iomap.c
> ===================================================================
> --- xfs-linux.orig/xfs_iomap.c	2006-08-15 15:22:53.238190250 +1000
> +++ xfs-linux/xfs_iomap.c	2006-08-16 12:40:41.385000250 +1000
> @@ -536,23 +536,27 @@ 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;
>  	}
>  
> -	*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,
> +	if (unlikely(!ret_imap->br_startblock &&
> +		     !(io->io_flags & XFS_IOCORE_RT))) {
> +		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)ret_imap->br_startblock,
>  			(unsigned long long)ret_imap->br_startoff,
> -                        (unsigned long long)ret_imap->br_blockcount,
> +			(unsigned long long)ret_imap->br_blockcount,
>  			ret_imap->br_state);
> -        }
> +		error = EFSCORRUPTED;

should this be XFS_ERROR(EFSCORRUPTED) ?

perhaps change to use it for consistency if the conversion is done in
error_out?

> +		goto error_out;

-- 
Stewart Smith (stewart@flamingspork.com)
http://www.flamingspork.com/


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: review: fsblock zero - don't panic
  2006-08-16  7:23     ` Stewart Smith
@ 2006-08-16 23:45       ` Nathan Scott
  0 siblings, 0 replies; 7+ messages in thread
From: Nathan Scott @ 2006-08-16 23:45 UTC (permalink / raw)
  To: Stewart Smith; +Cc: David Chinner, xfs

On Wed, Aug 16, 2006 at 03:23:33PM +0800, Stewart Smith wrote:
> On Wed, 2006-08-16 at 14:28 +1000, Nathan Scott wrote:
> > +		error = EFSCORRUPTED;
> 
> should this be XFS_ERROR(EFSCORRUPTED) ?

*nod*, will do, thanks.

cheers.

-- 
Nathan

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2006-08-16 23:47 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-10  5:58 review: fsblock zero - don't panic Nathan Scott
2006-08-11  3:26 ` David Chinner
2006-08-16  4:28   ` Nathan Scott
2006-08-16  6:47     ` David Chinner
2006-08-16  6:57       ` Nathan Scott
2006-08-16  7:23     ` Stewart Smith
2006-08-16 23:45       ` Nathan Scott

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox