public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] improve libxfs / xfs_repair I/O error handling
@ 2011-09-20 21:59 Christoph Hellwig
  2011-09-20 21:59 ` [PATCH 1/4] libxfs: handle read errors in libxfs_trans_read_buf Christoph Hellwig
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Christoph Hellwig @ 2011-09-20 21:59 UTC (permalink / raw)
  To: xfs

This series fixes various issues with handling of I/O errors in libxfs.
The most important one is patch 1, which fixes a regression introduced
in xfsprogs 3.0.0 that makes xfs_repair segfault for many read I/O errors.

I would recommend distributors to backport this patch to their releases.

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* [PATCH 1/4] libxfs: handle read errors in libxfs_trans_read_buf
  2011-09-20 21:59 [PATCH 0/4] improve libxfs / xfs_repair I/O error handling Christoph Hellwig
@ 2011-09-20 21:59 ` Christoph Hellwig
  2011-09-21 18:45   ` Alex Elder
  2011-09-20 21:59 ` [PATCH 2/4] libxfs: save errno before possibly overwriting it Christoph Hellwig
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Christoph Hellwig @ 2011-09-20 21:59 UTC (permalink / raw)
  To: xfs

[-- Attachment #1: libxfs-do-not-ignore-read-errors --]
[-- Type: text/plain, Size: 1992 bytes --]

Libxfs_readbuf may return a NULL buffer to indicate that an error happend
during the read, but we currently ignore that if libxfs_trans_read_buf
is called with a NULL transaction pointer.  Fix this by copying the
relevant code from the kernel version of the routine, and also tidy
the code up a bit by using a common exit label.

This fixes a regression that was introduced in xfsprogs 3.0.0 by commit

	"Implement buffer and inode caching in libxfs, groundwork for a
	 parallel version of xfs_repair."

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: xfsprogs-dev/libxfs/trans.c
===================================================================
--- xfsprogs-dev.orig/libxfs/trans.c	2011-09-20 20:33:48.000000000 +0000
+++ xfsprogs-dev/libxfs/trans.c	2011-09-20 20:35:24.000000000 +0000
@@ -478,9 +478,15 @@ libxfs_trans_read_buf(
 	xfs_buf_log_item_t	*bip;
 	xfs_buftarg_t		bdev;
 
+	*bpp = NULL;
+
 	if (tp == NULL) {
-		*bpp = libxfs_readbuf(dev, blkno, len, flags);
-		return 0;
+		bp = libxfs_readbuf(dev, blkno, len, flags);
+		if (!bp) {
+			return (flags & XBF_TRYLOCK) ?
+				EAGAIN : XFS_ERROR(ENOMEM);
+		}
+		goto done;
 	}
 
 	bdev.dev = dev;
@@ -490,15 +496,15 @@ libxfs_trans_read_buf(
 		ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
 		bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
 		bip->bli_recur++;
-		*bpp = bp;
-		return 0;
+		goto done;
 	}
 
 	bp = libxfs_readbuf(dev, blkno, len, flags);
-       if (!bp){
-               *bpp = NULL;
-               return errno;
-       }
+	if (!bp) {
+		return (flags & XBF_TRYLOCK) ?
+			EAGAIN : XFS_ERROR(ENOMEM);
+	}
+
 #ifdef XACT_DEBUG
 	fprintf(stderr, "trans_read_buf buffer %p, transaction %p\n", bp, tp);
 #endif
@@ -510,6 +516,7 @@ libxfs_trans_read_buf(
 
 	/* initialise b_fsprivate2 so we can find it incore */
 	XFS_BUF_SET_FSPRIVATE2(bp, tp);
+done:
 	*bpp = bp;
 	return 0;
 }

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* [PATCH 2/4] libxfs: save errno before possibly overwriting it
  2011-09-20 21:59 [PATCH 0/4] improve libxfs / xfs_repair I/O error handling Christoph Hellwig
  2011-09-20 21:59 ` [PATCH 1/4] libxfs: handle read errors in libxfs_trans_read_buf Christoph Hellwig
@ 2011-09-20 21:59 ` Christoph Hellwig
  2011-09-21 18:45   ` Alex Elder
  2011-09-20 21:59 ` [PATCH 3/4] libxfs: handle short reads in libxfs_readbufr Christoph Hellwig
  2011-09-20 21:59 ` [PATCH 4/4] libxfs: add b_error Christoph Hellwig
  3 siblings, 1 reply; 11+ messages in thread
From: Christoph Hellwig @ 2011-09-20 21:59 UTC (permalink / raw)
  To: xfs

[-- Attachment #1: libxfs-fix-errno --]
[-- Type: text/plain, Size: 1584 bytes --]

Save away errno for a later error return before possibly overwriting
it in fprintf.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: xfsprogs-dev/libxfs/rdwr.c
===================================================================
--- xfsprogs-dev.orig/libxfs/rdwr.c	2011-09-20 20:41:09.000000000 +0000
+++ xfsprogs-dev/libxfs/rdwr.c	2011-09-20 20:43:28.000000000 +0000
@@ -454,15 +454,17 @@ libxfs_readbufr(dev_t dev, xfs_daddr_t b
 {
 	int	fd = libxfs_device_to_fd(dev);
 	int	bytes = BBTOB(len);
+	int	error;
 
 	ASSERT(BBTOB(len) <= bp->b_bcount);
 
 	if (pread64(fd, bp->b_addr, bytes, LIBXFS_BBTOOFF64(blkno)) < 0) {
+		error = errno;
 		fprintf(stderr, _("%s: read failed: %s\n"),
-			progname, strerror(errno));
+			progname, strerror(error));
 		if (flags & LIBXFS_EXIT_ON_FAILURE)
 			exit(1);
-		return errno;
+		return error;
 	}
 #ifdef IO_DEBUG
 	printf("%lx: %s: read %u bytes, blkno=%llu(%llu), %p\n",
@@ -498,14 +500,16 @@ libxfs_writebufr(xfs_buf_t *bp)
 {
 	int	sts;
 	int	fd = libxfs_device_to_fd(bp->b_dev);
+	int	error;
 
 	sts = pwrite64(fd, bp->b_addr, bp->b_bcount, LIBXFS_BBTOOFF64(bp->b_blkno));
 	if (sts < 0) {
+		error = errno;
 		fprintf(stderr, _("%s: pwrite64 failed: %s\n"),
-			progname, strerror(errno));
+			progname, strerror(error));
 		if (bp->b_flags & LIBXFS_B_EXIT)
 			exit(1);
-		return errno;
+		return error;
 	}
 	else if (sts != bp->b_bcount) {
 		fprintf(stderr, _("%s: error - wrote only %d of %d bytes\n"),

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* [PATCH 3/4] libxfs: handle short reads in libxfs_readbufr
  2011-09-20 21:59 [PATCH 0/4] improve libxfs / xfs_repair I/O error handling Christoph Hellwig
  2011-09-20 21:59 ` [PATCH 1/4] libxfs: handle read errors in libxfs_trans_read_buf Christoph Hellwig
  2011-09-20 21:59 ` [PATCH 2/4] libxfs: save errno before possibly overwriting it Christoph Hellwig
@ 2011-09-20 21:59 ` Christoph Hellwig
  2011-09-21 18:45   ` Alex Elder
  2011-09-20 21:59 ` [PATCH 4/4] libxfs: add b_error Christoph Hellwig
  3 siblings, 1 reply; 11+ messages in thread
From: Christoph Hellwig @ 2011-09-20 21:59 UTC (permalink / raw)
  To: xfs

[-- Attachment #1: libxfs-handle-short-reads --]
[-- Type: text/plain, Size: 1645 bytes --]

Copy the code from libxfs_writebufr to handle short reads, and also
tidy up a formatting issue found in the libxfs_writebufr copy.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: xfsprogs-dev/libxfs/rdwr.c
===================================================================
--- xfsprogs-dev.orig/libxfs/rdwr.c	2011-09-20 20:43:28.000000000 +0000
+++ xfsprogs-dev/libxfs/rdwr.c	2011-09-20 20:43:49.000000000 +0000
@@ -455,16 +455,24 @@ libxfs_readbufr(dev_t dev, xfs_daddr_t b
 	int	fd = libxfs_device_to_fd(dev);
 	int	bytes = BBTOB(len);
 	int	error;
+	int	sts;
 
 	ASSERT(BBTOB(len) <= bp->b_bcount);
 
-	if (pread64(fd, bp->b_addr, bytes, LIBXFS_BBTOOFF64(blkno)) < 0) {
+	sts = pread64(fd, bp->b_addr, bytes, LIBXFS_BBTOOFF64(blkno));
+	if (sts < 0) {
 		error = errno;
 		fprintf(stderr, _("%s: read failed: %s\n"),
 			progname, strerror(error));
 		if (flags & LIBXFS_EXIT_ON_FAILURE)
 			exit(1);
 		return error;
+	} else if (sts != bytes) {
+		fprintf(stderr, _("%s: error - read only %d of %d bytes\n"),
+			progname, sts, bytes);
+		if (flags & LIBXFS_EXIT_ON_FAILURE)
+			exit(1);
+		return EIO;
 	}
 #ifdef IO_DEBUG
 	printf("%lx: %s: read %u bytes, blkno=%llu(%llu), %p\n",
@@ -510,8 +518,7 @@ libxfs_writebufr(xfs_buf_t *bp)
 		if (bp->b_flags & LIBXFS_B_EXIT)
 			exit(1);
 		return error;
-	}
-	else if (sts != bp->b_bcount) {
+	} else if (sts != bp->b_bcount) {
 		fprintf(stderr, _("%s: error - wrote only %d of %d bytes\n"),
 			progname, sts, bp->b_bcount);
 		if (bp->b_flags & LIBXFS_B_EXIT)

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* [PATCH 4/4] libxfs: add b_error
  2011-09-20 21:59 [PATCH 0/4] improve libxfs / xfs_repair I/O error handling Christoph Hellwig
                   ` (2 preceding siblings ...)
  2011-09-20 21:59 ` [PATCH 3/4] libxfs: handle short reads in libxfs_readbufr Christoph Hellwig
@ 2011-09-20 21:59 ` Christoph Hellwig
  2011-09-21 18:45   ` Alex Elder
  3 siblings, 1 reply; 11+ messages in thread
From: Christoph Hellwig @ 2011-09-20 21:59 UTC (permalink / raw)
  To: xfs

[-- Attachment #1: libxfs-add-b_error --]
[-- Type: text/plain, Size: 2657 bytes --]

Add a b_error field to struct xfs_buf so that we can return the exact error
fro libxfs_readbuf.  And explicit error return would be nice, but this
requires large changes to common code that should be done on the kernel
side first.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: xfsprogs-dev/include/libxfs.h
===================================================================
--- xfsprogs-dev.orig/include/libxfs.h	2011-09-20 20:44:23.000000000 +0000
+++ xfsprogs-dev/include/libxfs.h	2011-09-20 20:44:32.000000000 +0000
@@ -230,6 +230,7 @@ typedef struct xfs_buf {
 	void			*b_fsprivate2;
 	void			*b_fsprivate3;
 	char			*b_addr;
+	int			b_error;
 #ifdef XFS_BUF_TRACING
 	struct list_head	b_lock_list;
 	const char		*b_func;
Index: xfsprogs-dev/libxfs/rdwr.c
===================================================================
--- xfsprogs-dev.orig/libxfs/rdwr.c	2011-09-20 20:44:37.000000000 +0000
+++ xfsprogs-dev/libxfs/rdwr.c	2011-09-20 20:45:22.000000000 +0000
@@ -314,6 +314,7 @@ libxfs_initbuf(xfs_buf_t *bp, dev_t devi
 	bp->b_blkno = bno;
 	bp->b_bcount = bytes;
 	bp->b_dev = device;
+	bp->b_error = 0;
 	if (!bp->b_addr)
 		bp->b_addr = memalign(libxfs_device_alignment(), bytes);
 	if (!bp->b_addr) {
@@ -495,10 +496,8 @@ libxfs_readbuf(dev_t dev, xfs_daddr_t bl
 	bp = libxfs_getbuf(dev, blkno, len);
 	if (bp && !(bp->b_flags & (LIBXFS_B_UPTODATE|LIBXFS_B_DIRTY))) {
 		error = libxfs_readbufr(dev, blkno, bp, len, flags);
-		if (error) {
-			libxfs_putbuf(bp);
-			return NULL;
-		}
+		if (error)
+			bp->b_error = error;
 	}
 	return bp;
 }
Index: xfsprogs-dev/libxfs/trans.c
===================================================================
--- xfsprogs-dev.orig/libxfs/trans.c	2011-09-20 20:45:29.000000000 +0000
+++ xfsprogs-dev/libxfs/trans.c	2011-09-20 20:46:34.000000000 +0000
@@ -477,6 +477,7 @@ libxfs_trans_read_buf(
 	xfs_buf_t		*bp;
 	xfs_buf_log_item_t	*bip;
 	xfs_buftarg_t		bdev;
+	int			error;
 
 	*bpp = NULL;
 
@@ -486,6 +487,8 @@ libxfs_trans_read_buf(
 			return (flags & XBF_TRYLOCK) ?
 				EAGAIN : XFS_ERROR(ENOMEM);
 		}
+		if (bp->b_error)
+			goto out_relse;
 		goto done;
 	}
 
@@ -504,6 +507,8 @@ libxfs_trans_read_buf(
 		return (flags & XBF_TRYLOCK) ?
 			EAGAIN : XFS_ERROR(ENOMEM);
 	}
+	if (bp->b_error)
+		goto out_relse;
 
 #ifdef XACT_DEBUG
 	fprintf(stderr, "trans_read_buf buffer %p, transaction %p\n", bp, tp);
@@ -519,6 +524,10 @@ libxfs_trans_read_buf(
 done:
 	*bpp = bp;
 	return 0;
+out_relse:
+	error = bp->b_error;
+	xfs_buf_relse(bp);
+	return error;
 }
 
 /*

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH 1/4] libxfs: handle read errors in libxfs_trans_read_buf
  2011-09-20 21:59 ` [PATCH 1/4] libxfs: handle read errors in libxfs_trans_read_buf Christoph Hellwig
@ 2011-09-21 18:45   ` Alex Elder
  2011-09-21 19:49     ` Christoph Hellwig
  0 siblings, 1 reply; 11+ messages in thread
From: Alex Elder @ 2011-09-21 18:45 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: xfs

On Tue, 2011-09-20 at 17:59 -0400, Christoph Hellwig wrote:
> Libxfs_readbuf may return a NULL buffer to indicate that an error happend
> during the read, but we currently ignore that if libxfs_trans_read_buf
> is called with a NULL transaction pointer.  Fix this by copying the
> relevant code from the kernel version of the routine, and also tidy
> the code up a bit by using a common exit label.
> 
> This fixes a regression that was introduced in xfsprogs 3.0.0 by commit
> 
> 	"Implement buffer and inode caching in libxfs, groundwork for a
> 	 parallel version of xfs_repair."
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Probably wouldn't hurt to initialize b_fsprivate2 even
if the transaction pointer is null.  Looks good though.

Reviewed-by: Alex Elder <aelder@sgi.com>

. . .
> @@ -510,6 +516,7 @@ libxfs_trans_read_buf(
>  
>  	/* initialise b_fsprivate2 so we can find it incore */
>  	XFS_BUF_SET_FSPRIVATE2(bp, tp);
> +done:
>  	*bpp = bp;
>  	return 0;
>  }


_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH 2/4] libxfs: save errno before possibly overwriting it
  2011-09-20 21:59 ` [PATCH 2/4] libxfs: save errno before possibly overwriting it Christoph Hellwig
@ 2011-09-21 18:45   ` Alex Elder
  0 siblings, 0 replies; 11+ messages in thread
From: Alex Elder @ 2011-09-21 18:45 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: xfs

On Tue, 2011-09-20 at 17:59 -0400, Christoph Hellwig wrote:
> Save away errno for a later error return before possibly overwriting
> it in fprintf.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Looks good.

Reviewed-by: Alex Elder <aelder@sgi.com>


_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH 3/4] libxfs: handle short reads in libxfs_readbufr
  2011-09-20 21:59 ` [PATCH 3/4] libxfs: handle short reads in libxfs_readbufr Christoph Hellwig
@ 2011-09-21 18:45   ` Alex Elder
  0 siblings, 0 replies; 11+ messages in thread
From: Alex Elder @ 2011-09-21 18:45 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: xfs

On Tue, 2011-09-20 at 17:59 -0400, Christoph Hellwig wrote:
> Copy the code from libxfs_writebufr to handle short reads, and also
> tidy up a formatting issue found in the libxfs_writebufr copy.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

That LIBXFS_B_EXIT == LIBXFS_EXIT_ON_FAILURE is a bad thing.
It might be nice if libxfs_readbuf() and libxfs_writebuf()
encoded that piece of information the same way (in b_flags).

Anyway, what you have here looks good.

Reviewed-by: Alex Elder <aelder@sgi.com>


_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH 4/4] libxfs: add b_error
  2011-09-20 21:59 ` [PATCH 4/4] libxfs: add b_error Christoph Hellwig
@ 2011-09-21 18:45   ` Alex Elder
  0 siblings, 0 replies; 11+ messages in thread
From: Alex Elder @ 2011-09-21 18:45 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: xfs

On Tue, 2011-09-20 at 17:59 -0400, Christoph Hellwig wrote:
> Add a b_error field to struct xfs_buf so that we can return the exact error
> fro libxfs_readbuf.  And explicit error return would be nice, but this
> requires large changes to common code that should be done on the kernel
> side first.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Looks good.

Reviewed-by: Alex Elder <aelder@sgi.com>


_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH 1/4] libxfs: handle read errors in libxfs_trans_read_buf
  2011-09-21 18:45   ` Alex Elder
@ 2011-09-21 19:49     ` Christoph Hellwig
  2011-09-21 20:13       ` Alex Elder
  0 siblings, 1 reply; 11+ messages in thread
From: Christoph Hellwig @ 2011-09-21 19:49 UTC (permalink / raw)
  To: Alex Elder; +Cc: xfs

On Wed, Sep 21, 2011 at 01:45:07PM -0500, Alex Elder wrote:
> Probably wouldn't hurt to initialize b_fsprivate2 even
> if the transaction pointer is null.  Looks good though.

It would - given that another transaction could be set in there.
Fairly unlikely in userspace, but quite possible in the kernel.

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH 1/4] libxfs: handle read errors in libxfs_trans_read_buf
  2011-09-21 19:49     ` Christoph Hellwig
@ 2011-09-21 20:13       ` Alex Elder
  0 siblings, 0 replies; 11+ messages in thread
From: Alex Elder @ 2011-09-21 20:13 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: xfs

On Wed, 2011-09-21 at 15:49 -0400, Christoph Hellwig wrote:
> On Wed, Sep 21, 2011 at 01:45:07PM -0500, Alex Elder wrote:
> > Probably wouldn't hurt to initialize b_fsprivate2 even
> > if the transaction pointer is null.  Looks good though.
> 
> It would - given that another transaction could be set in there.
> Fairly unlikely in userspace, but quite possible in the kernel.
> 

You're right.	-Alex

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

end of thread, other threads:[~2011-09-21 20:13 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-09-20 21:59 [PATCH 0/4] improve libxfs / xfs_repair I/O error handling Christoph Hellwig
2011-09-20 21:59 ` [PATCH 1/4] libxfs: handle read errors in libxfs_trans_read_buf Christoph Hellwig
2011-09-21 18:45   ` Alex Elder
2011-09-21 19:49     ` Christoph Hellwig
2011-09-21 20:13       ` Alex Elder
2011-09-20 21:59 ` [PATCH 2/4] libxfs: save errno before possibly overwriting it Christoph Hellwig
2011-09-21 18:45   ` Alex Elder
2011-09-20 21:59 ` [PATCH 3/4] libxfs: handle short reads in libxfs_readbufr Christoph Hellwig
2011-09-21 18:45   ` Alex Elder
2011-09-20 21:59 ` [PATCH 4/4] libxfs: add b_error Christoph Hellwig
2011-09-21 18:45   ` Alex Elder

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