]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: fix superblock inprogress check
authorDave Chinner <dchinner@redhat.com>
Tue, 25 Oct 2016 00:26:46 +0000 (11:26 +1100)
committerDave Chinner <david@fromorbit.com>
Tue, 25 Oct 2016 00:26:46 +0000 (11:26 +1100)
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: <stable@vger.kernel.org>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
libxfs/libxfs_io.h
libxfs/rdwr.c
libxfs/xfs_sb.c

index 29ab5835a244ab451200a4ab803ff7eb9f7f075c..6612d8fb47e9f7737f500ba2ac773cab2470c599 100644 (file)
@@ -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;
index 1103e2c1bf1bec9dfeb7fbcae0e249f218506fb7..526bc6205c14633bca14cee6679fb38608e5296f 100644 (file)
@@ -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);
index 4ff3677247b9e3cfe04602b2b781edcb1a590965..f692ec8bdac28ce99744745bffaa784a0f1d1756 100644 (file)
@@ -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);
 }