From: Christoph Hellwig Date: Tue, 20 Sep 2011 21:59:18 +0000 (+0000) Subject: libxfs: handle read errors in libxfs_trans_read_buf X-Git-Tag: v3.1.6~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=00aea09fd64aa351bdbb716c936ad24bdcfe91a9;p=thirdparty%2Fxfsprogs-dev.git libxfs: handle read errors in libxfs_trans_read_buf 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 Signed-off-by: Alex Elder --- diff --git a/libxfs/trans.c b/libxfs/trans.c index 2b1c80684..86a6ac7fd 100644 --- a/libxfs/trans.c +++ b/libxfs/trans.c @@ -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; }