From: Dave Chinner Date: Tue, 25 Oct 2016 00:26:46 +0000 (+1100) Subject: xfs: fix superblock inprogress check X-Git-Tag: v4.9.0-rc1~121 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=85428dd23fd0e4f3c22b9a9d381d6de79e0d6469;p=thirdparty%2Fxfsprogs-dev.git xfs: fix superblock inprogress check Source kernel commit: f3d7ebdeb2c297bd26272384e955033493ca291c From inspection, the superblock sb_inprogress check is done in the verifier and triggered only for the primary superblock via a "bp->b_bn == XFS_SB_DADDR" check. Unfortunately, the primary superblock is an uncached buffer, and hence it is configured by xfs_buf_read_uncached() with: bp->b_bn = XFS_BUF_DADDR_NULL; /* always null for uncached buffers */ And so this check never triggers. Fix it. cc: Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- diff --git a/libxfs/libxfs_io.h b/libxfs/libxfs_io.h index 29ab5835a..6612d8fb4 100644 --- a/libxfs/libxfs_io.h +++ b/libxfs/libxfs_io.h @@ -75,7 +75,7 @@ typedef struct xfs_buf { int b_error; const struct xfs_buf_ops *b_ops; struct xfs_perag *b_pag; - struct xfs_buf_map *b_map; + struct xfs_buf_map *b_maps; int b_nmaps; #ifdef XFS_BUF_TRACING struct list_head b_lock_list; diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index 1103e2c1b..526bc6205 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -608,8 +608,8 @@ libxfs_initbuf_map(xfs_buf_t *bp, struct xfs_buftarg *btp, int i; bytes = sizeof(struct xfs_buf_map) * nmaps; - bp->b_map = malloc(bytes); - if (!bp->b_map) { + bp->b_maps = malloc(bytes); + if (!bp->b_maps) { fprintf(stderr, _("%s: %s can't malloc %u bytes: %s\n"), progname, __FUNCTION__, bytes, @@ -620,8 +620,8 @@ libxfs_initbuf_map(xfs_buf_t *bp, struct xfs_buftarg *btp, bytes = 0; for ( i = 0; i < nmaps; i++) { - bp->b_map[i].bm_bn = map[i].bm_bn; - bp->b_map[i].bm_len = map[i].bm_len; + bp->b_maps[i].bm_bn = map[i].bm_bn; + bp->b_maps[i].bm_len = map[i].bm_len; bytes += BBTOB(map[i].bm_len); } @@ -654,8 +654,8 @@ __libxfs_getbufr(int blen) list_del_init(&bp->b_node.cn_mru); free(bp->b_addr); bp->b_addr = NULL; - free(bp->b_map); - bp->b_map = NULL; + free(bp->b_maps); + bp->b_maps = NULL; } } else bp = kmem_zone_zalloc(xfs_buf_zone, 0); @@ -1024,8 +1024,8 @@ libxfs_readbufr_map(struct xfs_buftarg *btp, struct xfs_buf *bp, int flags) fd = libxfs_device_to_fd(btp->dev); buf = bp->b_addr; for (i = 0; i < bp->b_nmaps; i++) { - off64_t offset = LIBXFS_BBTOOFF64(bp->b_map[i].bm_bn); - int len = BBTOB(bp->b_map[i].bm_len); + off64_t offset = LIBXFS_BBTOOFF64(bp->b_maps[i].bm_bn); + int len = BBTOB(bp->b_maps[i].bm_len); error = __read_buf(fd, buf, len, offset, flags); if (error) { @@ -1142,8 +1142,8 @@ libxfs_writebufr(xfs_buf_t *bp) char *buf = bp->b_addr; for (i = 0; i < bp->b_nmaps; i++) { - off64_t offset = LIBXFS_BBTOOFF64(bp->b_map[i].bm_bn); - int len = BBTOB(bp->b_map[i].bm_len); + off64_t offset = LIBXFS_BBTOOFF64(bp->b_maps[i].bm_bn); + int len = BBTOB(bp->b_maps[i].bm_len); bp->b_error = __write_buf(fd, buf, len, offset, bp->b_flags); diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c index 4ff367724..f692ec8bd 100644 --- a/libxfs/xfs_sb.c +++ b/libxfs/xfs_sb.c @@ -568,7 +568,8 @@ xfs_sb_verify( * Only check the in progress field for the primary superblock as * mkfs.xfs doesn't clear it from secondary superblocks. */ - return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR, + return xfs_mount_validate_sb(mp, &sb, + bp->b_maps[0].bm_bn == XFS_SB_DADDR, check_version); }