xfs
[Top] [All Lists]

[PATCH 10/12] xfsprogs: introduce CRC support into mkfs.xfs

To: xfs@xxxxxxxxxxx
Subject: [PATCH 10/12] xfsprogs: introduce CRC support into mkfs.xfs
From: Dave Chinner <david@xxxxxxxxxxxxx>
Date: Tue, 22 Jan 2013 00:53:09 +1100
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1358776391-22140-1-git-send-email-david@xxxxxxxxxxxxx>
References: <1358776391-22140-1-git-send-email-david@xxxxxxxxxxxxx>
From: Dave Chinner <dchinner@xxxxxxxxxx>

Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
---
 copy/xfs_copy.c           |    5 +-
 db/sb.c                   |    6 +-
 include/libxfs.h          |   85 ++++++++++++++----------
 include/libxlog.h         |    2 +-
 include/xfs_sb.h          |    2 -
 libxfs/init.c             |   20 +++---
 libxfs/logitem.c          |    4 +-
 libxfs/rdwr.c             |  125 +++++++++++++++++++++-------------
 libxfs/trans.c            |    8 +--
 libxfs/xfs.h              |   17 +++--
 libxfs/xfs_alloc.c        |   10 +--
 libxfs/xfs_alloc_btree.c  |    6 +-
 libxfs/xfs_attr.c         |    2 +-
 libxfs/xfs_attr_leaf.c    |    2 +-
 libxfs/xfs_bmap_btree.c   |    6 +-
 libxfs/xfs_btree.c        |    8 +--
 libxfs/xfs_da_btree.c     |    4 +-
 libxfs/xfs_dir2_block.c   |    2 +-
 libxfs/xfs_dir2_data.c    |    6 +-
 libxfs/xfs_dir2_leaf.c    |    2 +-
 libxfs/xfs_dir2_node.c    |    2 +-
 libxfs/xfs_ialloc.c       |    6 +-
 libxfs/xfs_ialloc_btree.c |    6 +-
 libxfs/xfs_inode.c        |    4 +-
 libxfs/xfs_mount.c        |   18 +++--
 libxfs/xfs_symlink.c      |    8 +--
 logprint/logprint.c       |    3 +-
 mkfs/maxtrres.c           |    4 +-
 mkfs/proto.c              |    4 +-
 mkfs/xfs_mkfs.c           |  162 +++++++++++++++++++++++++++++++++++----------
 mkfs/xfs_mkfs.h           |   12 ++--
 repair/attr_repair.c      |    6 +-
 repair/dino_chunks.c      |    8 ++-
 repair/dinode.c           |   10 +--
 repair/dir.c              |    8 +--
 repair/dir2.c             |    2 +-
 repair/phase2.c           |    5 +-
 repair/phase3.c           |    2 +-
 repair/phase6.c           |    8 +--
 repair/prefetch.c         |    4 +-
 repair/rt.c               |    4 +-
 repair/scan.c             |   12 ++--
 repair/xfs_repair.c       |    7 +-
 43 files changed, 393 insertions(+), 234 deletions(-)

diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c
index c01e0b9..7dc7d9a 100644
--- a/copy/xfs_copy.c
+++ b/copy/xfs_copy.c
@@ -674,8 +674,11 @@ main(int argc, char **argv)
 
        /* prepare the mount structure */
 
-       sbp = libxfs_readbuf(xargs.ddev, XFS_SB_DADDR, 1, 0);
        memset(&mbuf, 0, sizeof(xfs_mount_t));
+       mbuf.m_ddev_targ.dev = xargs.ddev;
+       mbuf.m_ddev_targ.bt_mount = &mbuf;
+       sbp = libxfs_readbuf(mbuf.m_ddev_targ, XFS_SB_DADDR, 1, 0,
+                                                       &xfs_sb_buf_ops);
        sb = &mbuf.m_sb;
        libxfs_sb_from_disk(sb, XFS_BUF_TO_SBP(sbp));
 
diff --git a/db/sb.c b/db/sb.c
index d83db9c..f99210c 100644
--- a/db/sb.c
+++ b/db/sb.c
@@ -235,7 +235,8 @@ sb_logcheck(void)
                x.logdev = x.ddev;
        x.logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
        x.logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart);
-       log.l_dev = (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev;
+       log.l_dev.dev = (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev;
+       log.l_dev.bt_mount = mp;
        log.l_logsize = BBTOB(log.l_logBBsize);
        log.l_logBBsize = x.logBBsize;
        log.l_logBBstart = x.logBBstart;
@@ -266,8 +267,7 @@ sb_logzero(uuid_t *uuidp)
 
        dbprintf(_("Clearing log and setting UUID\n"));
 
-       if (libxfs_log_clear(
-                       (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev,
+       if (libxfs_log_clear(mp->m_logdev_targ,
                        XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
                        (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks),
                        uuidp,
diff --git a/include/libxfs.h b/include/libxfs.h
index 29767ef..f64e489 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -116,6 +116,16 @@ typedef struct {
 #define LIBXFS_EXCLUSIVELY     0x0010  /* disallow other accesses (O_EXCL) */
 #define LIBXFS_DIRECT          0x0020  /* can use direct I/O, not buffered */
 
+/*
+ * IO verifier callbacks need the xfs_mount pointer, so we have to behave
+ * somewhat like the kernel now for userspace IO in terms of having buftarg
+ * based devices...
+ */
+struct xfs_buftarg {
+       struct xfs_mount        *bt_mount;
+       dev_t                   dev;
+};
+
 extern char    *progname;
 extern int     libxfs_init (libxfs_init_t *);
 extern void    libxfs_destroy (void);
@@ -130,11 +140,12 @@ extern void       platform_findsizes(char *path, int fd, 
long long *sz, int *bsz);
 /* check or write log footer: specify device, log size in blocks & uuid */
 typedef xfs_caddr_t (libxfs_get_block_t)(xfs_caddr_t, int, void *);
 
-extern int     libxfs_log_clear (dev_t, xfs_daddr_t, uint, uuid_t *,
+extern int     libxfs_log_clear (struct xfs_buftarg, xfs_daddr_t, uint, uuid_t 
*,
                                int, int, int);
 extern int     libxfs_log_header (xfs_caddr_t, uuid_t *, int, int, int,
                                libxfs_get_block_t *, void *);
 
+
 /*
  * Define a user-level mount structure with all we need
  * in order to make use of the numerous XFS_* macros.
@@ -151,9 +162,12 @@ typedef struct xfs_mount {
        struct xfs_inode        *m_rbmip;       /* pointer to bitmap inode */
        struct xfs_inode        *m_rsumip;      /* pointer to summary inode */
        struct xfs_inode        *m_rootip;      /* pointer to root directory */
-       dev_t                   m_dev;
-       dev_t                   m_logdev;
-       dev_t                   m_rtdev;
+       struct xfs_buftarg      m_ddev_targ;
+       struct xfs_buftarg      m_logdev_targ;
+       struct xfs_buftarg      m_rtdev_targ;
+#define m_dev          m_ddev_targ
+#define m_logdev       m_logdev_targ
+#define m_rtdev                m_rtdev_targ
        __uint8_t               m_dircook_elog; /* log d-cookie entry bits */
        __uint8_t               m_blkbit_log;   /* blocklog + NBBY */
        __uint8_t               m_blkbb_log;    /* blocklog - BBSHIFT */
@@ -218,11 +232,6 @@ extern void        libxfs_rtmount_destroy (xfs_mount_t *);
 /*
  * Simple I/O interface
  */
-typedef struct xfs_buftarg {
-       struct xfs_mount        *bt_mount;
-       dev_t                   dev;
-} xfs_buftarg_t;
-
 #define XB_PAGES        2
 
 struct xfs_buf_map {
@@ -244,7 +253,8 @@ typedef struct xfs_buf {
        xfs_daddr_t             b_bn;
        unsigned                b_bcount;
        unsigned int            b_length;
-       dev_t                   b_dev;
+       struct xfs_buftarg      b_target;
+#define b_dev          b_target.dev
        pthread_mutex_t         b_lock;
        pthread_t               b_holder;
        unsigned int            b_recur;
@@ -254,7 +264,6 @@ typedef struct xfs_buf {
        void                    *b_addr;
        int                     b_error;
        const struct xfs_buf_ops *b_ops;
-       struct xfs_buftarg      *b_target;
        struct xfs_perag        *b_pag;
        struct xfs_buf_map      *b_map;
        int                     b_nmaps;
@@ -315,12 +324,12 @@ extern struct cache_operations    
libxfs_bcache_operations;
 
 #ifdef XFS_BUF_TRACING
 
-#define libxfs_readbuf(dev, daddr, len, flags) \
+#define libxfs_readbuf(dev, daddr, len, flags, ops) \
        libxfs_trace_readbuf(__FUNCTION__, __FILE__, __LINE__, \
-                           (dev), (daddr), (len), (flags))
-#define libxfs_readbuf_map(dev, map, nmaps, flags) \
+                           (dev), (daddr), (len), (flags), (ops))
+#define libxfs_readbuf_map(dev, map, nmaps, flags, ops) \
        libxfs_trace_readbuf_map(__FUNCTION__, __FILE__, __LINE__, \
-                           (dev), (map), (nmaps), (flags))
+                           (dev), (map), (nmaps), (flags), (ops))
 #define libxfs_writebuf(buf, flags) \
        libxfs_trace_writebuf(__FUNCTION__, __FILE__, __LINE__, \
                              (buf), (flags))
@@ -337,28 +346,34 @@ extern struct cache_operations    
libxfs_bcache_operations;
        libxfs_trace_putbuf(__FUNCTION__, __FILE__, __LINE__, (buf))
 
 extern xfs_buf_t *libxfs_trace_readbuf(const char *, const char *, int,
-                       dev_t, xfs_daddr_t, int, int);
+                       struct xfs_buftarg, xfs_daddr_t, int, int,
+                       const struct xfs_buf_ops *);
 extern xfs_buf_t *libxfs_trace_readbuf_map(const char *, const char *, int,
-                       dev_t, struct xfs_buf_map *, int, int);
+                       struct xfs_buftarg, struct xfs_buf_map *, int, int,
+                       const struct xfs_buf_ops *);
 extern int     libxfs_trace_writebuf(const char *, const char *, int,
                        xfs_buf_t *, int);
 extern xfs_buf_t *libxfs_trace_getbuf(const char *, const char *, int,
-                       dev_t, xfs_daddr_t, int);
+                       struct xfs_buftarg, xfs_daddr_t, int);
 extern xfs_buf_t *libxfs_trace_getbuf_map(const char *, const char *, int,
-                       dev_t, struct xfs_buf_map *, int);
+                       struct xfs_buftarg, struct xfs_buf_map *, int);
 extern xfs_buf_t *libxfs_trace_getbuf_flags(const char *, const char *, int,
-                       dev_t, xfs_daddr_t, int, unsigned int);
+                       struct xfs_buftarg, xfs_daddr_t, int, unsigned int);
 extern void    libxfs_trace_putbuf (const char *, const char *, int,
                        xfs_buf_t *);
 
 #else
 
-extern xfs_buf_t *libxfs_readbuf(dev_t, xfs_daddr_t, int, int);
-extern xfs_buf_t *libxfs_readbuf_map(dev_t, struct xfs_buf_map *, int, int);
+extern xfs_buf_t *libxfs_readbuf(struct xfs_buftarg, xfs_daddr_t, int, int,
+                       const struct xfs_buf_ops *);
+extern xfs_buf_t *libxfs_readbuf_map(struct xfs_buftarg, struct xfs_buf_map *,
+                       int, int, const struct xfs_buf_ops *);
 extern int     libxfs_writebuf(xfs_buf_t *, int);
-extern xfs_buf_t *libxfs_getbuf(dev_t, xfs_daddr_t, int);
-extern xfs_buf_t *libxfs_getbuf_map(dev_t, struct xfs_buf_map *, int);
-extern xfs_buf_t *libxfs_getbuf_flags(dev_t, xfs_daddr_t, int, unsigned int);
+extern xfs_buf_t *libxfs_getbuf(struct xfs_buftarg, xfs_daddr_t, int);
+extern xfs_buf_t *libxfs_getbuf_map(struct xfs_buftarg,
+                       struct xfs_buf_map *, int);
+extern xfs_buf_t *libxfs_getbuf_flags(struct xfs_buftarg, xfs_daddr_t,
+                       int, unsigned int);
 extern void    libxfs_putbuf (xfs_buf_t *);
 
 #endif
@@ -371,11 +386,11 @@ extern int        libxfs_bcache_overflowed(void);
 extern int     libxfs_bcache_usage(void);
 
 /* Buffer (Raw) Interfaces */
-extern xfs_buf_t *libxfs_getbufr(dev_t, xfs_daddr_t, int);
+extern xfs_buf_t *libxfs_getbufr(struct xfs_buftarg, xfs_daddr_t, int);
 extern void    libxfs_putbufr(xfs_buf_t *);
 
 extern int     libxfs_writebuf_int(xfs_buf_t *, int);
-extern int     libxfs_readbufr(dev_t, xfs_daddr_t, xfs_buf_t *, int, int);
+extern int     libxfs_readbufr(struct xfs_buftarg, xfs_daddr_t, xfs_buf_t *, 
int, int);
 
 extern int libxfs_bhash_size;
 extern int libxfs_ihash_size;
@@ -461,14 +476,15 @@ extern int        libxfs_trans_read_buf (xfs_mount_t *, 
xfs_trans_t *, dev_t,
                                xfs_daddr_t, int, uint, struct xfs_buf **);
 */
 
-struct xfs_buf *libxfs_trans_get_buf_map(struct xfs_trans *tp, dev_t dev,
-                                      struct xfs_buf_map *map, int nmaps,
-                                      uint flags);
+struct xfs_buf *libxfs_trans_get_buf_map(struct xfs_trans *tp,
+                                       struct xfs_buftarg dev,
+                                       struct xfs_buf_map *map, int nmaps,
+                                       uint flags);
 
 static inline struct xfs_buf *
 libxfs_trans_get_buf(
        struct xfs_trans        *tp,
-       dev_t                   dev,
+       struct xfs_buftarg      dev,
        xfs_daddr_t             blkno,
        int                     numblks,
        uint                    flags)
@@ -478,7 +494,8 @@ libxfs_trans_get_buf(
 }
 
 int            libxfs_trans_read_buf_map(struct xfs_mount *mp,
-                                      struct xfs_trans *tp, dev_t dev,
+                                      struct xfs_trans *tp,
+                                      struct xfs_buftarg dev,
                                       struct xfs_buf_map *map, int nmaps,
                                       uint flags, struct xfs_buf **bpp,
                                       const struct xfs_buf_ops *ops);
@@ -487,7 +504,7 @@ static inline int
 libxfs_trans_read_buf(
        struct xfs_mount        *mp,
        struct xfs_trans        *tp,
-       dev_t                   dev,
+       struct xfs_buftarg      dev,
        xfs_daddr_t             blkno,
        int                     numblks,
        uint                    flags,
@@ -507,7 +524,7 @@ typedef struct xfs_inode {
        xfs_mount_t             *i_mount;       /* fs mount struct ptr */
        xfs_ino_t               i_ino;          /* inode number (agno/agino) */
        struct xfs_imap         i_imap;         /* location for xfs_imap() */
-       dev_t                   i_dev;          /* dev for this inode */
+       struct xfs_buftarg                      i_dev;          /* dev for this 
inode */
        xfs_ifork_t             *i_afp;         /* attribute fork pointer */
        xfs_ifork_t             i_df;           /* data fork */
        xfs_trans_t             *i_transp;      /* ptr to owning transaction */
diff --git a/include/libxlog.h b/include/libxlog.h
index 36ede59..37cbc68 100644
--- a/include/libxlog.h
+++ b/include/libxlog.h
@@ -28,7 +28,7 @@ struct xlog {
        xfs_lsn_t       l_tail_lsn;     /* lsn of 1st LR w/ unflush buffers */
        xfs_lsn_t       l_last_sync_lsn;/* lsn of last LR on disk */
        xfs_mount_t     *l_mp;          /* mount point */
-       dev_t           l_dev;          /* dev_t of log */
+       struct xfs_buftarg l_dev;               /* dev_t of log */
        xfs_daddr_t     l_logBBstart;   /* start block of log */
        int             l_logsize;      /* size of log in bytes */
        int             l_logBBsize;    /* size of log in 512 byte chunks */
diff --git a/include/xfs_sb.h b/include/xfs_sb.h
index 1f8c1cd..d6709db 100644
--- a/include/xfs_sb.h
+++ b/include/xfs_sb.h
@@ -358,10 +358,8 @@ static inline int xfs_sb_good_version(xfs_sb_t *sbp)
 
                return 1;
        }
-#ifdef REMOVE_TO_ENABLE_CRC_SUPPORT
        if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5)
                return 1;
-#endif
 
        return 0;
 }
diff --git a/libxfs/init.c b/libxfs/init.c
index 1b11fb0..55a17d2 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -457,7 +457,7 @@ rtmount_init(
        sbp = &mp->m_sb;
        if (sbp->sb_rblocks == 0)
                return 0;
-       if (mp->m_rtdev == 0 && !(flags & LIBXFS_MOUNT_DEBUGGER)) {
+       if (mp->m_rtdev.dev == 0 && !(flags & LIBXFS_MOUNT_DEBUGGER)) {
                fprintf(stderr, _("%s: filesystem has a realtime subvolume\n"),
                        progname);
                return -1;
@@ -486,7 +486,7 @@ rtmount_init(
                return -1;
        }
        bp = libxfs_readbuf(mp->m_rtdev,
-                       d - XFS_FSB_TO_BB(mp, 1), XFS_FSB_TO_BB(mp, 1), 0);
+                       d - XFS_FSB_TO_BB(mp, 1), XFS_FSB_TO_BB(mp, 1), 0, 
NULL);
        if (bp == NULL) {
                fprintf(stderr, _("%s: realtime size check failed\n"),
                        progname);
@@ -634,9 +634,13 @@ libxfs_mount(
        xfs_sb_t        *sbp;
        int             error;
 
-       mp->m_dev = dev;
-       mp->m_rtdev = rtdev;
-       mp->m_logdev = logdev;
+       mp->m_ddev_targ.dev = dev;
+       mp->m_ddev_targ.bt_mount = mp;
+       mp->m_logdev_targ.dev = logdev;
+       mp->m_logdev_targ.bt_mount = mp;
+       mp->m_rtdev_targ.dev = rtdev;
+       mp->m_rtdev_targ.bt_mount = mp;
+
        mp->m_flags = (LIBXFS_MOUNT_32BITINODES|LIBXFS_MOUNT_32BITINOOPT);
        mp->m_sb = *sb;
        INIT_RADIX_TREE(&mp->m_perag_tree, GFP_KERNEL);
@@ -720,7 +724,7 @@ libxfs_mount(
 
        bp = libxfs_readbuf(mp->m_dev,
                        d - XFS_FSS_TO_BB(mp, 1), XFS_FSS_TO_BB(mp, 1),
-                       !(flags & LIBXFS_MOUNT_DEBUGGER));
+                       !(flags & LIBXFS_MOUNT_DEBUGGER), NULL);
        if (!bp) {
                fprintf(stderr, _("%s: data size check failed\n"), progname);
                if (!(flags & LIBXFS_MOUNT_DEBUGGER))
@@ -728,13 +732,13 @@ libxfs_mount(
        } else
                libxfs_putbuf(bp);
 
-       if (mp->m_logdev && mp->m_logdev != mp->m_dev) {
+       if (mp->m_logdev.dev && mp->m_logdev.dev != mp->m_dev.dev) {
                d = (xfs_daddr_t) XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
                if ( (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) ||
                     (!(bp = libxfs_readbuf(mp->m_logdev,
                                        d - XFS_FSB_TO_BB(mp, 1),
                                        XFS_FSB_TO_BB(mp, 1),
-                                       !(flags & LIBXFS_MOUNT_DEBUGGER)))) ) {
+                                       !(flags & LIBXFS_MOUNT_DEBUGGER), 
NULL))) ) {
                        fprintf(stderr, _("%s: log size checks failed\n"),
                                        progname);
                        if (!(flags & LIBXFS_MOUNT_DEBUGGER))
diff --git a/libxfs/logitem.c b/libxfs/logitem.c
index 84e4c14..f298aa0 100644
--- a/libxfs/logitem.c
+++ b/libxfs/logitem.c
@@ -32,7 +32,7 @@ kmem_zone_t   *xfs_ili_zone;          /* inode log item zone 
*/
 xfs_buf_t *
 xfs_trans_buf_item_match(
        xfs_trans_t             *tp,
-       dev_t                   dev,
+       struct xfs_buftarg      dev,
        struct xfs_buf_map      *map,
        int                     nmaps)
 {
@@ -47,7 +47,7 @@ xfs_trans_buf_item_match(
         list_for_each_entry(lidp, &tp->t_items, lid_trans) {
                 blip = (struct xfs_buf_log_item *)lidp->lid_item;
                 if (blip->bli_item.li_type == XFS_LI_BUF &&
-                   blip->bli_buf->b_dev == dev &&
+                   blip->bli_buf->b_target.dev == dev.dev &&
                    XFS_BUF_ADDR(blip->bli_buf) == map[0].bm_bn &&
                    blip->bli_buf->b_bcount == BBTOB(len)) {
                        ASSERT(blip->bli_buf->b_map_count == nmaps);
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index f2a6647..0629d50 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -102,7 +102,7 @@ static xfs_caddr_t next(xfs_caddr_t ptr, int offset, void 
*private)
 
 int
 libxfs_log_clear(
-       dev_t                   device,
+       struct xfs_buftarg      device,
        xfs_daddr_t             start,
        uint                    length,
        uuid_t                  *fs_uuid,
@@ -113,11 +113,11 @@ libxfs_log_clear(
        xfs_buf_t               *bp;
        int                     len;
 
-       if (!device || !fs_uuid)
+       if (!device.dev || !fs_uuid)
                return -EINVAL;
 
        /* first zero the log */
-       libxfs_device_zero(device, start, length);
+       libxfs_device_zero(device.dev, start, length);
 
        /* then write a log record header */
        len = ((version == 2) && sunit) ? BTOBB(sunit) : 2;
@@ -200,12 +200,15 @@ libxfs_log_header(
 #undef libxfs_getbuf_flags
 #undef libxfs_putbuf
 
-xfs_buf_t      *libxfs_readbuf(dev_t, xfs_daddr_t, int, int);
-xfs_buf_t      *libxfs_readbuf_map(dev_t, struct xfs_buf_map *, int, int);
+xfs_buf_t      *libxfs_readbuf(struct xfs_buftarg, xfs_daddr_t, int, int,
+                               const struct xfs_buf_map *);
+xfs_buf_t      *libxfs_readbuf_map(struct xfs_buftarg, struct xfs_buf_map *,
+                               int, int, const struct xfs_buf_map *);
 int            libxfs_writebuf(xfs_buf_t *, int);
-xfs_buf_t      *libxfs_getbuf(dev_t, xfs_daddr_t, int);
-xfs_buf_t      *libxfs_getbuf_map(dev_t, struct xfs_buf_map *, int);
-xfs_buf_t      *libxfs_getbuf_flags(dev_t, xfs_daddr_t, int, unsigned int);
+xfs_buf_t      *libxfs_getbuf(struct xfs_buftarg, xfs_daddr_t, int);
+xfs_buf_t      *libxfs_getbuf_map(struct xfs_buftarg, struct xfs_buf_map *, 
int);
+xfs_buf_t      *libxfs_getbuf_flags(struct xfs_buftarg, xfs_daddr_t, int,
+                               unsigned int);
 void           libxfs_putbuf (xfs_buf_t *);
 
 #define        __add_trace(bp, func, file, line)       \
@@ -219,18 +222,20 @@ do {                                              \
 
 xfs_buf_t *
 libxfs_trace_readbuf(const char *func, const char *file, int line,
-               dev_t dev, xfs_daddr_t blkno, int len, int flags)
+               struct xfs_buftarg dev, xfs_daddr_t blkno, int len, int flags,
+               const struct xfs_buf_ops *ops)
 {
-       xfs_buf_t       *bp = libxfs_readbuf(dev, blkno, len, flags);
+       xfs_buf_t       *bp = libxfs_readbuf(dev, blkno, len, flags, ops);
        __add_trace(bp, func, file, line);
        return bp;
 }
 
 xfs_buf_t *
 libxfs_trace_readbuf_map(const char *func, const char *file, int line,
-               dev_t dev, struct xfs_buf_map *map, int nmaps, int flags)
+               struct xfs_buftarg dev, struct xfs_buf_map *map, int nmaps, int 
flags,
+               const struct xfs_buf_ops *ops)
 {
-       xfs_buf_t       *bp = libxfs_readbuf_map(dev, map, nmaps, flags);
+       xfs_buf_t       *bp = libxfs_readbuf_map(dev, map, nmaps, flags, ops);
        __add_trace(bp, func, file, line);
        return bp;
 }
@@ -244,7 +249,7 @@ libxfs_trace_writebuf(const char *func, const char *file, 
int line, xfs_buf_t *b
 
 xfs_buf_t *
 libxfs_trace_getbuf(const char *func, const char *file, int line,
-               dev_t device, xfs_daddr_t blkno, int len)
+               struct xfs_buftarg device, xfs_daddr_t blkno, int len)
 {
        xfs_buf_t       *bp = libxfs_getbuf(device, blkno, len);
        __add_trace(bp, func, file, line);
@@ -253,7 +258,7 @@ libxfs_trace_getbuf(const char *func, const char *file, int 
line,
 
 xfs_buf_t *
 libxfs_trace_getbuf_map(const char *func, const char *file, int line,
-               dev_t device, struct xfs_buf_map *map, int nmaps)
+               struct xfs_buftarg device, struct xfs_buf_map *map, int nmaps)
 {
        xfs_buf_t       *bp = libxfs_getbuf_map(device, map, nmaps);
        __add_trace(bp, func, file, line);
@@ -262,7 +267,7 @@ libxfs_trace_getbuf_map(const char *func, const char *file, 
int line,
 
 xfs_buf_t *
 libxfs_trace_getbuf_flags(const char *func, const char *file, int line,
-               dev_t device, xfs_daddr_t blkno, int len, unsigned int flags)
+               struct xfs_buftarg device, xfs_daddr_t blkno, int len, unsigned 
int flags)
 {
        xfs_buf_t       *bp = libxfs_getbuf_flags(device, blkno, len, flags);
        __add_trace(bp, func, file, line);
@@ -284,7 +289,7 @@ xfs_buf_t *
 libxfs_getsb(xfs_mount_t *mp, int flags)
 {
        return libxfs_readbuf(mp->m_dev, XFS_SB_DADDR,
-                               XFS_FSS_TO_BB(mp, 1), flags);
+                               XFS_FSS_TO_BB(mp, 1), flags, &xfs_sb_buf_ops);
 }
 
 kmem_zone_t                    *xfs_buf_zone;
@@ -302,7 +307,7 @@ static struct cache_mru             xfs_buf_freelist =
  * buffer initialisation instead of a contiguous buffer.
  */
 struct xfs_bufkey {
-       dev_t                   device;
+       struct xfs_buftarg                      device;
        xfs_daddr_t             blkno;
        unsigned int            bblen;
        struct xfs_buf_map      *map;
@@ -322,7 +327,7 @@ libxfs_bcompare(struct cache_node *node, cache_key_t key)
        struct xfs_bufkey *bkey = (struct xfs_bufkey *)key;
 
 #ifdef IO_BCOMPARE_CHECK
-       if (bp->b_dev == bkey->device &&
+       if (bp->b_target.dev == bkey->device.dev &&
            bp->b_bn == bkey->blkno &&
            bp->b_bcount != BBTOB(bkey->bblen))
                fprintf(stderr, "%lx: Badness in key lookup (length)\n"
@@ -332,7 +337,7 @@ libxfs_bcompare(struct cache_node *node, cache_key_t key)
                        (unsigned long long)bkey->blkno, BBTOB(bkey->bblen));
 #endif
 
-       return (bp->b_dev == bkey->device &&
+       return (bp->b_target.dev == bkey->device.dev &&
                bp->b_bn == bkey->blkno &&
                bp->b_bcount == BBTOB(bkey->bblen));
 }
@@ -346,13 +351,14 @@ libxfs_bprint(xfs_buf_t *bp)
 }
 
 static void
-__initbuf(xfs_buf_t *bp, dev_t device, xfs_daddr_t bno, unsigned int bytes)
+__initbuf(xfs_buf_t *bp, struct xfs_buftarg device, xfs_daddr_t bno,
+               unsigned int bytes)
 {
        bp->b_flags = 0;
        bp->b_bn = bno;
        bp->b_bcount = bytes;
        bp->b_length = BTOBB(bytes);
-       bp->b_dev = device;
+       bp->b_target = device;
        bp->b_error = 0;
        if (!bp->b_addr)
                bp->b_addr = memalign(libxfs_device_alignment(), bytes);
@@ -372,13 +378,15 @@ __initbuf(xfs_buf_t *bp, dev_t device, xfs_daddr_t bno, 
unsigned int bytes)
 }
 
 static void
-libxfs_initbuf(xfs_buf_t *bp, dev_t device, xfs_daddr_t bno, unsigned int 
bytes)
+libxfs_initbuf(xfs_buf_t *bp, struct xfs_buftarg device, xfs_daddr_t bno,
+               unsigned int bytes)
 {
        __initbuf(bp, device, bno, bytes);
 }
 
 static void
-libxfs_initbuf_map(xfs_buf_t *bp, dev_t device, struct xfs_buf_map *map, int 
nmaps)
+libxfs_initbuf_map(xfs_buf_t *bp, struct xfs_buftarg device,
+               struct xfs_buf_map *map, int nmaps)
 {
        unsigned int bytes = 0;
        int i;
@@ -441,7 +449,7 @@ __libxfs_getbufr(int blen)
 }
 
 xfs_buf_t *
-libxfs_getbufr(dev_t device, xfs_daddr_t blkno, int bblen)
+libxfs_getbufr(struct xfs_buftarg device, xfs_daddr_t blkno, int bblen)
 {
        xfs_buf_t       *bp;
        int             blen = BBTOB(bblen);
@@ -459,7 +467,7 @@ libxfs_getbufr(dev_t device, xfs_daddr_t blkno, int bblen)
 }
 
 xfs_buf_t *
-libxfs_getbufr_map(dev_t device, xfs_daddr_t blkno, int bblen,
+libxfs_getbufr_map(struct xfs_buftarg device, xfs_daddr_t blkno, int bblen,
                struct xfs_buf_map *map, int nmaps)
 {
        xfs_buf_t       *bp;
@@ -552,9 +560,10 @@ out_put:
 }
 
 struct xfs_buf *
-libxfs_getbuf_flags(dev_t device, xfs_daddr_t blkno, int len, unsigned int 
flags)
+libxfs_getbuf_flags(struct xfs_buftarg device, xfs_daddr_t blkno, int len,
+               unsigned int flags)
 {
-       struct xfs_bufkey key = {0};
+       struct xfs_bufkey key = {{0}};
 
        key.device = device;
        key.blkno = blkno;
@@ -564,15 +573,15 @@ libxfs_getbuf_flags(dev_t device, xfs_daddr_t blkno, int 
len, unsigned int flags
 }
 
 struct xfs_buf *
-libxfs_getbuf(dev_t device, xfs_daddr_t blkno, int len)
+libxfs_getbuf(struct xfs_buftarg device, xfs_daddr_t blkno, int len)
 {
        return libxfs_getbuf_flags(device, blkno, len, 0);
 }
 
 struct xfs_buf *
-libxfs_getbuf_map(dev_t device, struct xfs_buf_map *map, int nmaps)
+libxfs_getbuf_map(struct xfs_buftarg device, struct xfs_buf_map *map, int 
nmaps)
 {
-       struct xfs_bufkey key = {0};
+       struct xfs_bufkey key = {{0}};
        int i;
 
        key.device = device;
@@ -610,9 +619,9 @@ libxfs_putbuf(xfs_buf_t *bp)
 void
 libxfs_purgebuf(xfs_buf_t *bp)
 {
-       struct xfs_bufkey key = {0};
+       struct xfs_bufkey key = {{0}};
 
-       key.device = bp->b_dev;
+       key.device = bp->b_target;
        key.blkno = bp->b_bn;
        key.bblen = bp->b_bcount >> BBSHIFT;
 
@@ -658,9 +667,10 @@ __read_buf(int fd, void *buf, int len, off64_t offset, int 
flags)
 }
 
 int
-libxfs_readbufr(dev_t dev, xfs_daddr_t blkno, xfs_buf_t *bp, int len, int 
flags)
+libxfs_readbufr(struct xfs_buftarg dev, xfs_daddr_t blkno, xfs_buf_t *bp,
+               int len, int flags)
 {
-       int     fd = libxfs_device_to_fd(dev);
+       int     fd = libxfs_device_to_fd(dev.dev);
        int     bytes = BBTOB(len);
        int     error;
 
@@ -668,7 +678,7 @@ libxfs_readbufr(dev_t dev, xfs_daddr_t blkno, xfs_buf_t 
*bp, int len, int flags)
 
        error = __read_buf(fd, bp->b_addr, bytes, LIBXFS_BBTOOFF64(blkno), 
flags);
        if (!error &&
-           bp->b_dev == dev &&
+           bp->b_target.dev == dev.dev &&
            bp->b_bn == blkno &&
            bp->b_bcount == bytes)
                bp->b_flags |= LIBXFS_B_UPTODATE;
@@ -681,22 +691,30 @@ libxfs_readbufr(dev_t dev, xfs_daddr_t blkno, xfs_buf_t 
*bp, int len, int flags)
 }
 
 xfs_buf_t *
-libxfs_readbuf(dev_t dev, xfs_daddr_t blkno, int len, int flags)
+libxfs_readbuf(struct xfs_buftarg dev, xfs_daddr_t blkno, int len, int flags,
+               const struct xfs_buf_ops *ops)
 {
        xfs_buf_t       *bp;
        int             error;
 
        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)
-                       bp->b_error = error;
-       }
+       if (!bp)
+               return NULL;
+       bp->b_ops = ops;
+       if ((bp->b_flags & (LIBXFS_B_UPTODATE|LIBXFS_B_DIRTY)))
+               return bp;
+
+       error = libxfs_readbufr(dev, blkno, bp, len, flags);
+       if (error)
+               bp->b_error = error;
+       else if (bp->b_ops)
+               bp->b_ops->verify_read(bp);
        return bp;
 }
 
 struct xfs_buf *
-libxfs_readbuf_map(dev_t dev, struct xfs_buf_map *map, int nmaps, int flags)
+libxfs_readbuf_map(struct xfs_buftarg dev, struct xfs_buf_map *map, int nmaps,
+               int flags, const struct xfs_buf_ops *ops)
 {
        xfs_buf_t       *bp;
        int             error = 0;
@@ -705,15 +723,19 @@ libxfs_readbuf_map(dev_t dev, struct xfs_buf_map *map, 
int nmaps, int flags)
        char            *buf;
 
        if (nmaps == 1)
-               return libxfs_readbuf(dev, map[0].bm_bn, map[0].bm_len, flags);
+               return libxfs_readbuf(dev, map[0].bm_bn, map[0].bm_len,
+                                       flags, ops);
 
        bp = libxfs_getbuf_map(dev, map, nmaps);
-       if (!bp || (bp->b_flags & (LIBXFS_B_UPTODATE|LIBXFS_B_DIRTY)))
+       if (!bp)
+               return NULL;
+       bp->b_ops = ops;
+       if ((bp->b_flags & (LIBXFS_B_UPTODATE|LIBXFS_B_DIRTY)))
                return bp;
 
        ASSERT(bp->b_nmaps = nmaps);
 
-       fd = libxfs_device_to_fd(dev);
+       fd = libxfs_device_to_fd(dev.dev);
        buf = bp->b_addr;
        for (i = 0; i < bp->b_nmaps; i++) {
                off64_t offset = LIBXFS_BBTOOFF64(bp->b_map[i].bm_bn);
@@ -731,8 +753,11 @@ libxfs_readbuf_map(dev_t dev, struct xfs_buf_map *map, int 
nmaps, int flags)
                offset += len;
        }
 
-       if (!error)
+       if (!error) {
                bp->b_flags |= LIBXFS_B_UPTODATE;
+               if (bp->b_ops)
+                       bp->b_ops->verify_read(bp);
+       }
 #ifdef IO_DEBUG
        printf("%lx: %s: read %lu bytes, error %d, blkno=%llu(%llu), %p\n",
                pthread_self(), __FUNCTION__, buf - (char *)bp->b_addr, error,
@@ -767,9 +792,15 @@ __write_buf(int fd, void *buf, int len, off64_t offset, 
int flags)
 int
 libxfs_writebufr(xfs_buf_t *bp)
 {
-       int     fd = libxfs_device_to_fd(bp->b_dev);
+       int     fd = libxfs_device_to_fd(bp->b_target.dev);
        int     error = 0;
 
+       if (bp->b_ops) {
+               bp->b_ops->verify_write(bp);
+               if (bp->b_error)
+                       return error;
+       }
+
        if (!(bp->b_flags & LIBXFS_B_DISCONTIG)) {
                error = __write_buf(fd, bp->b_addr, bp->b_bcount,
                                    LIBXFS_BBTOOFF64(bp->b_bn), bp->b_flags);
diff --git a/libxfs/trans.c b/libxfs/trans.c
index 619aad1..f4e42ea 100644
--- a/libxfs/trans.c
+++ b/libxfs/trans.c
@@ -386,7 +386,7 @@ libxfs_trans_bhold(
 xfs_buf_t *
 libxfs_trans_get_buf_map(
        xfs_trans_t             *tp,
-       dev_t                   dev,
+       struct xfs_buftarg      dev,
        struct xfs_buf_map      *map,
        int                     nmaps,
        uint                    f)
@@ -465,7 +465,7 @@ int
 libxfs_trans_read_buf_map(
        xfs_mount_t             *mp,
        xfs_trans_t             *tp,
-       dev_t                   dev,
+       struct xfs_buftarg      dev,
        struct xfs_buf_map      *map,
        int                     nmaps,
        uint                    flags,
@@ -479,7 +479,7 @@ libxfs_trans_read_buf_map(
        *bpp = NULL;
 
        if (tp == NULL) {
-               bp = libxfs_readbuf_map(dev, map, nmaps, flags);
+               bp = libxfs_readbuf_map(dev, map, nmaps, flags, ops);
                if (!bp) {
                        return (flags & XBF_TRYLOCK) ?
                                EAGAIN : XFS_ERROR(ENOMEM);
@@ -498,7 +498,7 @@ libxfs_trans_read_buf_map(
                goto done;
        }
 
-       bp = libxfs_readbuf_map(dev, map, nmaps, flags);
+       bp = libxfs_readbuf_map(dev, map, nmaps, flags, ops);
        if (!bp) {
                return (flags & XBF_TRYLOCK) ?
                        EAGAIN : XFS_ERROR(ENOMEM);
diff --git a/libxfs/xfs.h b/libxfs/xfs.h
index e03f6c7..398e48c 100644
--- a/libxfs/xfs.h
+++ b/libxfs/xfs.h
@@ -52,9 +52,16 @@ typedef __uint32_t           inst_t;         /* an 
instruction */
 #define EWRONGFS       EINVAL
 #endif
 
+#if 0
 #define m_ddev_targp                   m_dev
 #define m_logdev_targp                 m_logdev
 #define m_rtdev_targp                  m_rtdev
+#endif
+
+#define m_ddev_targp                   m_ddev_targ
+#define m_logdev_targp                 m_logdev_targ
+#define m_rtdev_targp                  m_rtdev_targ
+
 #define xfs_error_level                        0
 
 #define STATIC                         static
@@ -179,12 +186,8 @@ roundup_pow_of_two(uint v)
 
 #define xfs_incore(bt,blkno,len,lockit)        0
 #define xfs_buf_relse(bp)              libxfs_putbuf(bp)
-#define xfs_read_buf(mp,devp,blkno,len,f,bpp)  \
-                                       (*(bpp) = libxfs_readbuf((devp), \
-                                                       (blkno), (len), 1), 0)
-#define xfs_buf_get(devp,blkno,len,f)  \
-                                       (libxfs_getbuf((devp), (blkno), (len)))
-#define xfs_bwrite(mp,bp)              libxfs_writebuf((bp), 0)
+#define xfs_buf_get(devp,blkno,len,f)  (libxfs_getbuf((devp), (blkno), (len)))
+#define xfs_bwrite(bp)                 libxfs_writebuf((bp), 0)
 
 #define XBRW_READ                      LIBXFS_BREAD
 #define XBRW_WRITE                     LIBXFS_BWRITE
@@ -363,7 +366,7 @@ void xfs_buf_item_init (xfs_buf_t *, xfs_mount_t *);
 void xfs_buf_item_log (xfs_buf_log_item_t *, uint, uint);
 
 /* xfs_trans_buf.c */
-xfs_buf_t *xfs_trans_buf_item_match(xfs_trans_t *, dev_t,
+xfs_buf_t *xfs_trans_buf_item_match(xfs_trans_t *, struct xfs_buftarg,
                        struct xfs_buf_map *, int);
 
 /* local source files */
diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c
index d8f3566..bc9995d 100644
--- a/libxfs/xfs_alloc.c
+++ b/libxfs/xfs_alloc.c
@@ -414,7 +414,7 @@ static bool
 xfs_agfl_verify(
        struct xfs_buf  *bp)
 {
-       struct xfs_mount *mp = bp->b_target->bt_mount;
+       struct xfs_mount *mp = bp->b_target.bt_mount;
        struct xfs_agfl *agfl = XFS_BUF_TO_AGFL(bp);
        int             i;
 
@@ -443,7 +443,7 @@ static void
 xfs_agfl_read_verify(
        struct xfs_buf  *bp)
 {
-       struct xfs_mount *mp = bp->b_target->bt_mount;
+       struct xfs_mount *mp = bp->b_target.bt_mount;
        int             agfl_ok = 1;
 
        /*
@@ -470,7 +470,7 @@ static void
 xfs_agfl_write_verify(
        struct xfs_buf  *bp)
 {
-       struct xfs_mount *mp = bp->b_target->bt_mount;
+       struct xfs_mount *mp = bp->b_target.bt_mount;
        struct xfs_buf_log_item *bip = bp->b_fspriv;
 
        /* no verification of non-crc AGFLs */
@@ -2205,7 +2205,7 @@ static void
 xfs_agf_read_verify(
        struct xfs_buf  *bp)
 {
-       struct xfs_mount *mp = bp->b_target->bt_mount;
+       struct xfs_mount *mp = bp->b_target.bt_mount;
        int             agf_ok = 1;
 
        if (xfs_sb_version_hascrc(&mp->m_sb))
@@ -2225,7 +2225,7 @@ static void
 xfs_agf_write_verify(
        struct xfs_buf  *bp)
 {
-       struct xfs_mount *mp = bp->b_target->bt_mount;
+       struct xfs_mount *mp = bp->b_target.bt_mount;
        struct xfs_buf_log_item *bip = bp->b_fspriv;
 
        if (!xfs_agf_verify(mp, bp)) {
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index 949c96d..a845a15 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -258,7 +258,7 @@ static bool
 xfs_allocbt_verify(
        struct xfs_buf          *bp)
 {
-       struct xfs_mount        *mp = bp->b_target->bt_mount;
+       struct xfs_mount        *mp = bp->b_target.bt_mount;
        struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
        struct xfs_perag        *pag = bp->b_pag;
        unsigned int            level;
@@ -337,7 +337,7 @@ xfs_allocbt_read_verify(
              xfs_allocbt_verify(bp))) {
                trace_xfs_btree_corrupt(bp, _RET_IP_);
                XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
-                                    bp->b_target->bt_mount, bp->b_addr);
+                                    bp->b_target.bt_mount, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
        }
 }
@@ -349,7 +349,7 @@ xfs_allocbt_write_verify(
        if (!xfs_allocbt_verify(bp)) {
                trace_xfs_btree_corrupt(bp, _RET_IP_);
                XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
-                                    bp->b_target->bt_mount, bp->b_addr);
+                                    bp->b_target.bt_mount, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
        }
        xfs_btree_sblock_calc_crc(bp);
diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c
index 0450dca..8c6365c 100644
--- a/libxfs/xfs_attr.c
+++ b/libxfs/xfs_attr.c
@@ -1695,7 +1695,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
                if (tmp < buflen)
                        xfs_buf_zero(bp, tmp, buflen - tmp);
 
-               error = xfs_bwrite(mp, bp);     /* GROT: NOTE: synchronous 
write */
+               error = xfs_bwrite(bp); /* GROT: NOTE: synchronous write */
                xfs_buf_relse(bp);
                if (error)
                        return error;
diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c
index 85cb31d..57f99eb 100644
--- a/libxfs/xfs_attr_leaf.c
+++ b/libxfs/xfs_attr_leaf.c
@@ -61,7 +61,7 @@ static void
 xfs_attr_leaf_verify(
        struct xfs_buf          *bp)
 {
-       struct xfs_mount        *mp = bp->b_target->bt_mount;
+       struct xfs_mount        *mp = bp->b_target.bt_mount;
        struct xfs_attr_leaf_hdr *hdr = bp->b_addr;
        int                     block_ok = 0;
 
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 473db4a..761ef29 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -704,7 +704,7 @@ static bool
 xfs_bmbt_verify(
        struct xfs_buf          *bp)
 {
-       struct xfs_mount        *mp = bp->b_target->bt_mount;
+       struct xfs_mount        *mp = bp->b_target.bt_mount;
        struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
        unsigned int            level;
 
@@ -764,7 +764,7 @@ xfs_bmbt_read_verify(
              xfs_bmbt_verify(bp))) {
                trace_xfs_btree_corrupt(bp, _RET_IP_);
                XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
-                                    bp->b_target->bt_mount, bp->b_addr);
+                                    bp->b_target.bt_mount, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
        }
 
@@ -778,7 +778,7 @@ xfs_bmbt_write_verify(
                xfs_warn(bp->b_target->bt_mount, "bmbt daddr 0x%llx failed", 
bp->b_bn);
                trace_xfs_btree_corrupt(bp, _RET_IP_);
                XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
-                                    bp->b_target->bt_mount, bp->b_addr);
+                                    bp->b_target.bt_mount, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
                return;
        }
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index a7c19e9..0d36584 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -214,7 +214,7 @@ xfs_btree_lblock_calc_crc(
        struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
        struct xfs_buf_log_item *bip = bp->b_fspriv;
 
-       if (!xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
+       if (!xfs_sb_version_hascrc(&bp->b_target.bt_mount->m_sb))
                return;
        if (bip)
                block->bb_u.l.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
@@ -226,7 +226,7 @@ bool
 xfs_btree_lblock_verify_crc(
        struct xfs_buf          *bp)
 {
-       if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
+       if (xfs_sb_version_hascrc(&bp->b_target.bt_mount->m_sb))
                return xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
                                        XFS_BTREE_LBLOCK_CRC_OFF);
        return true;
@@ -247,7 +247,7 @@ xfs_btree_sblock_calc_crc(
        struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
        struct xfs_buf_log_item *bip = bp->b_fspriv;
 
-       if (!xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
+       if (!xfs_sb_version_hascrc(&bp->b_target.bt_mount->m_sb))
                return;
        if (bip)
                block->bb_u.s.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
@@ -259,7 +259,7 @@ bool
 xfs_btree_sblock_verify_crc(
        struct xfs_buf          *bp)
 {
-       if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
+       if (xfs_sb_version_hascrc(&bp->b_target.bt_mount->m_sb))
                return xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
                                        XFS_BTREE_SBLOCK_CRC_OFF);
        return true;
diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c
index a31d353..738caee 100644
--- a/libxfs/xfs_da_btree.c
+++ b/libxfs/xfs_da_btree.c
@@ -74,7 +74,7 @@ static void
 xfs_da_node_verify(
        struct xfs_buf          *bp)
 {
-       struct xfs_mount        *mp = bp->b_target->bt_mount;
+       struct xfs_mount        *mp = bp->b_target.bt_mount;
        struct xfs_da_node_hdr *hdr = bp->b_addr;
        int                     block_ok = 0;
 
@@ -106,7 +106,7 @@ static void
 xfs_da_node_read_verify(
        struct xfs_buf          *bp)
 {
-       struct xfs_mount        *mp = bp->b_target->bt_mount;
+       struct xfs_mount        *mp = bp->b_target.bt_mount;
        struct xfs_da_blkinfo   *info = bp->b_addr;
 
        switch (be16_to_cpu(info->magic)) {
diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c
index 7397faa..2655542 100644
--- a/libxfs/xfs_dir2_block.c
+++ b/libxfs/xfs_dir2_block.c
@@ -44,7 +44,7 @@ static void
 xfs_dir2_block_verify(
        struct xfs_buf          *bp)
 {
-       struct xfs_mount        *mp = bp->b_target->bt_mount;
+       struct xfs_mount        *mp = bp->b_target.bt_mount;
        struct xfs_dir2_data_hdr *hdr = bp->b_addr;
        int                     block_ok = 0;
 
diff --git a/libxfs/xfs_dir2_data.c b/libxfs/xfs_dir2_data.c
index eb86739..bc3a1b5 100644
--- a/libxfs/xfs_dir2_data.c
+++ b/libxfs/xfs_dir2_data.c
@@ -47,7 +47,7 @@ __xfs_dir2_data_check(
        int                     stale;          /* count of stale leaves */
        struct xfs_name         name;
 
-       mp = bp->b_target->bt_mount;
+       mp = bp->b_target.bt_mount;
        hdr = bp->b_addr;
        bf = hdr->bestfree;
        p = (char *)(hdr + 1);
@@ -173,7 +173,7 @@ static void
 xfs_dir2_data_verify(
        struct xfs_buf          *bp)
 {
-       struct xfs_mount        *mp = bp->b_target->bt_mount;
+       struct xfs_mount        *mp = bp->b_target.bt_mount;
        struct xfs_dir2_data_hdr *hdr = bp->b_addr;
        int                     block_ok = 0;
 
@@ -195,7 +195,7 @@ static void
 xfs_dir2_data_reada_verify(
        struct xfs_buf          *bp)
 {
-       struct xfs_mount        *mp = bp->b_target->bt_mount;
+       struct xfs_mount        *mp = bp->b_target.bt_mount;
        struct xfs_dir2_data_hdr *hdr = bp->b_addr;
 
        switch (be32_to_cpu(hdr->magic)) {
diff --git a/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c
index d303813..12e6f86 100644
--- a/libxfs/xfs_dir2_leaf.c
+++ b/libxfs/xfs_dir2_leaf.c
@@ -37,7 +37,7 @@ xfs_dir2_leaf_verify(
        struct xfs_buf          *bp,
        __be16                  magic)
 {
-       struct xfs_mount        *mp = bp->b_target->bt_mount;
+       struct xfs_mount        *mp = bp->b_target.bt_mount;
        struct xfs_dir2_leaf_hdr *hdr = bp->b_addr;
        int                     block_ok = 0;
 
diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c
index 649f677..80df3af 100644
--- a/libxfs/xfs_dir2_node.c
+++ b/libxfs/xfs_dir2_node.c
@@ -44,7 +44,7 @@ static void
 xfs_dir2_free_verify(
        struct xfs_buf          *bp)
 {
-       struct xfs_mount        *mp = bp->b_target->bt_mount;
+       struct xfs_mount        *mp = bp->b_target.bt_mount;
        struct xfs_dir2_free_hdr *hdr = bp->b_addr;
        int                     block_ok = 0;
 
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 625e119..5e49a7d 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -1306,7 +1306,7 @@ static bool
 xfs_agi_verify(
        struct xfs_buf  *bp)
 {
-       struct xfs_mount *mp = bp->b_target->bt_mount;
+       struct xfs_mount *mp = bp->b_target.bt_mount;
        struct xfs_agi  *agi = XFS_BUF_TO_AGI(bp);
 
        if (xfs_sb_version_hascrc(&mp->m_sb) &&
@@ -1337,7 +1337,7 @@ static void
 xfs_agi_read_verify(
        struct xfs_buf  *bp)
 {
-       struct xfs_mount *mp = bp->b_target->bt_mount;
+       struct xfs_mount *mp = bp->b_target.bt_mount;
        int             agi_ok = 1;
 
        if (xfs_sb_version_hascrc(&mp->m_sb))
@@ -1356,7 +1356,7 @@ static void
 xfs_agi_write_verify(
        struct xfs_buf  *bp)
 {
-       struct xfs_mount *mp = bp->b_target->bt_mount;
+       struct xfs_mount *mp = bp->b_target.bt_mount;
        struct xfs_buf_log_item *bip = bp->b_fspriv;
 
        if (!xfs_agi_verify(bp)) {
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index ee036bf..d7c865f 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -167,7 +167,7 @@ static int
 xfs_inobt_verify(
        struct xfs_buf          *bp)
 {
-       struct xfs_mount        *mp = bp->b_target->bt_mount;
+       struct xfs_mount        *mp = bp->b_target.bt_mount;
        struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
        struct xfs_perag        *pag = bp->b_pag;
        unsigned int            level;
@@ -222,7 +222,7 @@ xfs_inobt_read_verify(
              xfs_inobt_verify(bp))) {
                trace_xfs_btree_corrupt(bp, _RET_IP_);
                XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
-                                    bp->b_target->bt_mount, bp->b_addr);
+                                    bp->b_target.bt_mount, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
        }
 }
@@ -234,7 +234,7 @@ xfs_inobt_write_verify(
        if (!xfs_inobt_verify(bp)) {
                trace_xfs_btree_corrupt(bp, _RET_IP_);
                XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
-                                    bp->b_target->bt_mount, bp->b_addr);
+                                    bp->b_target.bt_mount, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
        }
        xfs_btree_sblock_calc_crc(bp);
diff --git a/libxfs/xfs_inode.c b/libxfs/xfs_inode.c
index b700599..24265cf 100644
--- a/libxfs/xfs_inode.c
+++ b/libxfs/xfs_inode.c
@@ -92,7 +92,7 @@ static void
 xfs_inode_buf_verify(
        struct xfs_buf  *bp)
 {
-       struct xfs_mount *mp = bp->b_target->bt_mount;
+       struct xfs_mount *mp = bp->b_target.bt_mount;
        int             i;
        int             ni;
 
@@ -237,7 +237,7 @@ xfs_iformat(
        }
 
        if (unlikely((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) &&
-                    !ip->i_mount->m_rtdev)) {
+                    !ip->i_mount->m_rtdev.dev)) {
                xfs_warn(ip->i_mount,
                        "corrupt dinode %Lu, has realtime flag set.",
                        ip->i_ino);
diff --git a/libxfs/xfs_mount.c b/libxfs/xfs_mount.c
index ed8c770..6ff2773 100644
--- a/libxfs/xfs_mount.c
+++ b/libxfs/xfs_mount.c
@@ -113,6 +113,9 @@ xfs_perag_put(struct xfs_perag *pag)
 
 /*
  * Check the validity of the SB found.
+ *
+ * We don't check the in-progress flag here because it is set by userspace
+ * utilities to indicate operations are in progress....
  */
 STATIC int
 xfs_mount_validate_sb(
@@ -139,7 +142,7 @@ xfs_mount_validate_sb(
        }
 
        if (unlikely(
-           sbp->sb_logstart == 0 && mp->m_logdev == mp->m_dev)) {
+           sbp->sb_logstart == 0 && mp->m_logdev.dev == mp->m_dev.dev)) {
                xfs_warn(mp,
                "filesystem is marked as having an external log; "
                "specify logdev on the mount command line.");
@@ -147,7 +150,7 @@ xfs_mount_validate_sb(
        }
 
        if (unlikely(
-           sbp->sb_logstart != 0 && mp->m_logdev != mp->m_dev)) {
+           sbp->sb_logstart != 0 && mp->m_logdev.dev != mp->m_dev.dev)) {
                xfs_warn(mp,
                "filesystem is marked as having an internal log; "
                "do not specify logdev on the mount command line.");
@@ -203,11 +206,6 @@ xfs_mount_validate_sb(
        }
 
 
-       if (check_inprogress && sbp->sb_inprogress) {
-               xfs_warn(mp, "Offline file system operation in progress!");
-               return XFS_ERROR(EFSCORRUPTED);
-       }
-
        /*
         * Version 1 directory format has never worked on Linux.
         */
@@ -335,7 +333,7 @@ static int
 xfs_sb_verify(
        struct xfs_buf  *bp)
 {
-       struct xfs_mount *mp = bp->b_target->bt_mount;
+       struct xfs_mount *mp = bp->b_target.bt_mount;
        struct xfs_sb   sb;
 
        xfs_sb_from_disk(&sb, XFS_BUF_TO_SBP(bp));
@@ -358,7 +356,7 @@ static void
 xfs_sb_read_verify(
        struct xfs_buf  *bp)
 {
-       struct xfs_mount *mp = bp->b_target->bt_mount;
+       struct xfs_mount *mp = bp->b_target.bt_mount;
        struct xfs_dsb  *dsb = XFS_BUF_TO_SBP(bp);
        int             error;
 
@@ -412,7 +410,7 @@ static void
 xfs_sb_write_verify(
        struct xfs_buf          *bp)
 {
-       struct xfs_mount        *mp = bp->b_target->bt_mount;
+       struct xfs_mount        *mp = bp->b_target.bt_mount;
        struct xfs_buf_log_item *bip = bp->b_fspriv;
        int                     error;
 
diff --git a/libxfs/xfs_symlink.c b/libxfs/xfs_symlink.c
index e018abc..6c42de7 100644
--- a/libxfs/xfs_symlink.c
+++ b/libxfs/xfs_symlink.c
@@ -29,7 +29,7 @@ xfs_symlink_blocks(
 /*
  * XXX: this need to be used by mkfs/proto.c to create symlinks.
  */
-static int
+int
 xfs_symlink_hdr_set(
        struct xfs_mount        *mp,
        xfs_ino_t               ino,
@@ -84,7 +84,7 @@ static bool
 xfs_symlink_verify(
        struct xfs_buf          *bp)
 {
-       struct xfs_mount        *mp = bp->b_target->bt_mount;
+       struct xfs_mount        *mp = bp->b_target.bt_mount;
        struct xfs_dsymlink_hdr *dsl = bp->b_addr;
 
        if (!xfs_sb_version_hascrc(&mp->m_sb))
@@ -108,7 +108,7 @@ static void
 xfs_symlink_read_verify(
        struct xfs_buf  *bp)
 {
-       struct xfs_mount *mp = bp->b_target->bt_mount;
+       struct xfs_mount *mp = bp->b_target.bt_mount;
 
        /* no verification of non-crc buffers */
        if (!xfs_sb_version_hascrc(&mp->m_sb))
@@ -126,7 +126,7 @@ static void
 xfs_symlink_write_verify(
        struct xfs_buf  *bp)
 {
-       struct xfs_mount *mp = bp->b_target->bt_mount;
+       struct xfs_mount *mp = bp->b_target.bt_mount;
        struct xfs_buf_log_item *bip = bp->b_fspriv;
 
        /* no verification of non-crc buffers */
diff --git a/logprint/logprint.c b/logprint/logprint.c
index 2a01780..5452e87 100644
--- a/logprint/logprint.c
+++ b/logprint/logprint.c
@@ -230,7 +230,8 @@ main(int argc, char **argv)
 
        ASSERT(x.logBBsize <= INT_MAX);
 
-       log.l_dev         = x.logdev;
+       log.l_dev.dev     = x.logdev;
+       log.l_dev.bt_mount = &mount;
        log.l_logsize     = BBTOB(x.logBBsize);
        log.l_logBBstart  = x.logBBstart;
        log.l_logBBsize   = x.logBBsize;
diff --git a/mkfs/maxtrres.c b/mkfs/maxtrres.c
index 33dee52..d88b3ab 100644
--- a/mkfs/maxtrres.c
+++ b/mkfs/maxtrres.c
@@ -72,6 +72,7 @@ max_trans_res_by_mount(
 
 int
 max_trans_res(
+       int             crcs_enabled,
        int             dirversion,
        int             sectorlog,
        int             blocklog,
@@ -95,7 +96,8 @@ max_trans_res(
        sbp->sb_inodesize = 1 << inodelog;
        sbp->sb_inopblock = 1 << (blocklog - inodelog);
        sbp->sb_dirblklog = dirblocklog - blocklog;
-       sbp->sb_versionnum = XFS_SB_VERSION_4 |
+       sbp->sb_versionnum =
+                       (crcs_enabled ? XFS_SB_VERSION_5 : XFS_SB_VERSION_4) |
                        (dirversion == 2 ? XFS_SB_VERSION_DIRV2BIT : 0);
 
        libxfs_mount(&mount, sbp, 0,0,0,0);
diff --git a/mkfs/proto.c b/mkfs/proto.c
index 56eed31..4254f8a 100644
--- a/mkfs/proto.c
+++ b/mkfs/proto.c
@@ -676,7 +676,7 @@ rtinit(
                                error);
                }
                for (i = 0, ep = map; i < nmap; i++, ep++) {
-                       libxfs_device_zero(mp->m_dev,
+                       libxfs_device_zero(mp->m_ddev_targ.dev,
                                XFS_FSB_TO_DADDR(mp, ep->br_startblock),
                                XFS_FSB_TO_BB(mp, ep->br_blockcount));
                        bno += ep->br_blockcount;
@@ -713,7 +713,7 @@ rtinit(
                                error);
                }
                for (i = 0, ep = map; i < nmap; i++, ep++) {
-                       libxfs_device_zero(mp->m_dev,
+                       libxfs_device_zero(mp->m_ddev_targ.dev,
                                XFS_FSB_TO_DADDR(mp, ep->br_startblock),
                                XFS_FSB_TO_BB(mp, ep->br_blockcount));
                        bno += ep->br_blockcount;
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 577880b..2df7871 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -178,6 +178,12 @@ char       *sopts[] = {
        NULL
 };
 
+char   *mopts[] = {
+#define        M_CRC           0
+       "crc",
+       NULL
+};
+
 #define TERABYTES(count, blog) ((__uint64_t)(count) << (40 - (blog)))
 #define GIGABYTES(count, blog) ((__uint64_t)(count) << (30 - (blog)))
 #define MEGABYTES(count, blog) ((__uint64_t)(count) << (20 - (blog)))
@@ -952,6 +958,7 @@ main(
        libxfs_init_t           xi;
        struct fs_topology      ft;
        int                     lazy_sb_counters;
+       int                     crcs_enabled;
 
        progname = basename(argv[0]);
        setlocale(LC_ALL, "");
@@ -983,13 +990,14 @@ main(
        force_overwrite = 0;
        worst_freelist = 0;
        lazy_sb_counters = 1;
+       crcs_enabled = 0;
        memset(&fsx, 0, sizeof(fsx));
 
        memset(&xi, 0, sizeof(xi));
        xi.isdirect = LIBXFS_DIRECT;
        xi.isreadonly = LIBXFS_EXCLUSIVELY;
 
-       while ((c = getopt(argc, argv, "b:d:i:l:L:n:KNp:qr:s:CfV")) != EOF) {
+       while ((c = getopt(argc, argv, "b:d:i:l:L:m:n:KNp:qr:s:CfV")) != EOF) {
                switch (c) {
                case 'C':
                case 'f':
@@ -1455,6 +1463,25 @@ main(
                                illegal(optarg, "L");
                        label = optarg;
                        break;
+               case 'm':
+                       p = optarg;
+                       while (*p != '\0') {
+                               char    *value;
+
+                               switch (getsubopt(&p, (constpp)mopts, &value)) {
+                               case M_CRC:
+                                       if (!value || *value == '\0')
+                                               reqval('m', mopts, M_CRC);
+                                       c = atoi(value);
+                                       if (c < 0 || c > 1)
+                                               illegal(value, "m crc");
+                                       crcs_enabled = c;
+                                       break;
+                               default:
+                                       unknown('m', value);
+                               }
+                       }
+                       break;
                case 'n':
                        p = optarg;
                        while (*p != '\0') {
@@ -1774,9 +1801,17 @@ _("block size %d cannot be smaller than logical sector 
size %d\n"),
                inodelog = blocklog - libxfs_highbit32(inopblock);
                isize = 1 << inodelog;
        } else if (!ilflag && !isflag) {
-               inodelog = XFS_DINODE_DFL_LOG;
+               inodelog = crcs_enabled ? XFS_DINODE_DFL_CRC_LOG
+                                       : XFS_DINODE_DFL_LOG;
                isize = 1 << inodelog;
        }
+       if (crcs_enabled && inodelog < XFS_DINODE_DFL_CRC_LOG) {
+               fprintf(stderr,
+               _("Minimum inode size for CRCs is %d bytes\n"),
+                       1 << XFS_DINODE_DFL_CRC_LOG);
+               usage();
+       }
+
        if (xi.lisfile && (!logsize || !xi.logname)) {
                fprintf(stderr,
                _("if -l file then -l name and -l size are required\n"));
@@ -2025,7 +2060,7 @@ reported by the device (%u).\n"),
                        sectorsize, xi.rtbsize);
        }
 
-       max_tr_res = max_trans_res(dirversion,
+       max_tr_res = max_trans_res(crcs_enabled, dirversion,
                                   sectorlog, blocklog, inodelog, dirblocklog);
        ASSERT(max_tr_res);
        min_logblocks = max_tr_res * XFS_MIN_LOG_FACTOR;
@@ -2295,7 +2330,7 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
                 */
                if (!logsize) {
                        logblocks = MIN(logblocks,
-                                       agsize - XFS_PREALLOC_BLOCKS(mp));
+                                       XFS_ALLOC_AG_MAX_USABLE(mp));
                }
                if (logblocks > agsize - XFS_PREALLOC_BLOCKS(mp)) {
                        fprintf(stderr,
@@ -2338,6 +2373,7 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
                printf(_(
                   "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n"
                   "         =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n"
+                  "         =%-22s crc=%-5u\n"
                   "data     =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n"
                   "         =%-22s sunit=%-6u swidth=%u blks\n"
                   "naming   =version %-14u bsize=%-6u ascii-ci=%d\n"
@@ -2346,6 +2382,7 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
                   "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"),
                        dfile, isize, (long long)agcount, (long long)agsize,
                        "", sectorsize, attrversion, projid32bit,
+                       "", crcs_enabled,
                        "", blocksize, (long long)dblocks, imaxpct,
                        "", dsunit, dswidth,
                        dirversion, dirblocksize, nci,
@@ -2411,9 +2448,10 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
                sbp->sb_logsectlog = 0;
                sbp->sb_logsectsize = 0;
        }
-       sbp->sb_features2 = XFS_SB_VERSION2_MKFS(lazy_sb_counters,
+       sbp->sb_features2 = XFS_SB_VERSION2_MKFS(crcs_enabled, lazy_sb_counters,
                                        attrversion == 2, projid32bit == 1, 0);
-       sbp->sb_versionnum = XFS_SB_VERSION_MKFS(iaflag, dsunit != 0,
+       sbp->sb_versionnum = XFS_SB_VERSION_MKFS(crcs_enabled, iaflag,
+                                       dsunit != 0,
                                        logversion == 2, attrversion == 1,
                                        (sectorsize != BBSIZE ||
                                                        lsectorsize != BBSIZE),
@@ -2435,13 +2473,16 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
         * swap (somewhere around the page size), jfs (32k),
         * ext[2,3] and reiserfs (64k) - and hopefully all else.
         */
-       buf = libxfs_getbuf(xi.ddev, 0, BTOBB(WHACK_SIZE));
+       mp->m_ddev_targ.dev = xi.ddev;
+       mp->m_ddev_targ.bt_mount = mp;
+       buf = libxfs_getbuf(mp->m_ddev_targ, 0, BTOBB(WHACK_SIZE));
        memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE);
        libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
        libxfs_purgebuf(buf);
 
        /* OK, now write the superblock */
-       buf = libxfs_getbuf(xi.ddev, XFS_SB_DADDR, XFS_FSS_TO_BB(mp, 1));
+       buf = libxfs_getbuf(mp->m_ddev_targ, XFS_SB_DADDR, XFS_FSS_TO_BB(mp, 
1));
+       buf->b_ops = &xfs_sb_buf_ops;
        memset(XFS_BUF_PTR(buf), 0, sectorsize);
        libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp, XFS_SB_ALL_BITS);
        libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
@@ -2460,10 +2501,11 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
        /*
         * Zero out the end of the device, to obliterate any
         * old MD RAID (or other) metadata at the end of the device.
-        * (MD sb is ~64k from the end, take out a wider swath to be sure)
+        * (MD sb is ~64k from the end, take out a wider swath to be sure)
         */
        if (!xi.disfile) {
-               buf = libxfs_getbuf(xi.ddev, (xi.dsize - BTOBB(WHACK_SIZE)),
+               buf = libxfs_getbuf(mp->m_ddev_targ,
+                                   (xi.dsize - BTOBB(WHACK_SIZE)),
                                    BTOBB(WHACK_SIZE));
                memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE);
                libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
@@ -2475,10 +2517,13 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
         */
        if (loginternal)
                xi.logdev = xi.ddev;
-       if (xi.logdev)
-               libxfs_log_clear(xi.logdev, XFS_FSB_TO_DADDR(mp, logstart),
+       if (xi.logdev) {
+               mp->m_logdev_targ.dev = xi.ddev;
+               libxfs_log_clear(mp->m_logdev_targ,
+                       XFS_FSB_TO_DADDR(mp, logstart),
                        (xfs_extlen_t)XFS_FSB_TO_BB(mp, logblocks),
                        &sbp->sb_uuid, logversion, lsunit, XLOG_FMT);
+       }
 
        mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 1);
        if (mp == NULL) {
@@ -2487,13 +2532,22 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
                exit(1);
        }
 
+       /*
+        * XXX: this code is effectively shared with the kernel growfs code.
+        * These initialisations should be pulled into libxfs to keep the
+        * kernel/userspace header initialisation code the same.
+        */
        for (agno = 0; agno < agcount; agno++) {
+               struct xfs_agfl *agfl;
+               int             bucket;
+
                /*
                 * Superblock.
                 */
-               buf = libxfs_getbuf(xi.ddev,
+               buf = libxfs_getbuf(mp->m_ddev_targ,
                                XFS_AG_DADDR(mp, agno, XFS_SB_DADDR),
                                XFS_FSS_TO_BB(mp, 1));
+               buf->b_ops = &xfs_sb_buf_ops;
                memset(XFS_BUF_PTR(buf), 0, sectorsize);
                libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp, 
XFS_SB_ALL_BITS);
                libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
@@ -2501,9 +2555,10 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
                /*
                 * AG header block: freespace
                 */
-               buf = libxfs_getbuf(mp->m_dev,
+               buf = libxfs_getbuf(mp->m_ddev_targ,
                                XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
                                XFS_FSS_TO_BB(mp, 1));
+               buf->b_ops = &xfs_agf_buf_ops;
                agf = XFS_BUF_TO_AGF(buf);
                memset(agf, 0, sectorsize);
                if (agno == agcount - 1)
@@ -2522,6 +2577,9 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
                nbmblocks = (xfs_extlen_t)(agsize - XFS_PREALLOC_BLOCKS(mp));
                agf->agf_freeblks = cpu_to_be32(nbmblocks);
                agf->agf_longest = cpu_to_be32(nbmblocks);
+               if (xfs_sb_version_hascrc(&mp->m_sb))
+                       platform_uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_uuid);
+
                if (loginternal && agno == logagno) {
                        be32_add_cpu(&agf->agf_freeblks, -logblocks);
                        agf->agf_longest = cpu_to_be32(agsize -
@@ -2532,12 +2590,33 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
                libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
 
                /*
+                * AG freelist header block
+                */
+               buf = libxfs_getbuf(mp->m_ddev_targ,
+                               XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
+                               XFS_FSS_TO_BB(mp, 1));
+               buf->b_ops = &xfs_agfl_buf_ops;
+               agfl = XFS_BUF_TO_AGFL(buf);
+               /* setting to 0xff results in initialisation to NULLAGBLOCK */
+               memset(agfl, 0xff, sectorsize);
+               if (xfs_sb_version_hascrc(&mp->m_sb)) {
+                       agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
+                       agfl->agfl_seqno = cpu_to_be32(agno);
+                       platform_uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_uuid);
+                       for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++)
+                               agfl->agfl_bno[bucket] = 
cpu_to_be32(NULLAGBLOCK);
+               }
+
+               libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
+
+               /*
                 * AG header block: inodes
                 */
-               buf = libxfs_getbuf(mp->m_dev,
+               buf = libxfs_getbuf(mp->m_ddev_targ,
                                XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
                                XFS_FSS_TO_BB(mp, 1));
                agi = XFS_BUF_TO_AGI(buf);
+               buf->b_ops = &xfs_agi_buf_ops;
                memset(agi, 0, sectorsize);
                agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
                agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
@@ -2549,6 +2628,8 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
                agi->agi_freecount = 0;
                agi->agi_newino = cpu_to_be32(NULLAGINO);
                agi->agi_dirino = cpu_to_be32(NULLAGINO);
+               if (xfs_sb_version_hascrc(&mp->m_sb))
+                       platform_uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_uuid);
                for (c = 0; c < XFS_AGI_UNLINKED_BUCKETS; c++)
                        agi->agi_unlinked[c] = cpu_to_be32(NULLAGINO);
                libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
@@ -2556,16 +2637,19 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
                /*
                 * BNO btree root block
                 */
-               buf = libxfs_getbuf(mp->m_dev,
+               buf = libxfs_getbuf(mp->m_ddev_targ,
                                XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)),
                                bsize);
+               buf->b_ops = &xfs_allocbt_buf_ops;
                block = XFS_BUF_TO_BLOCK(buf);
                memset(block, 0, blocksize);
-               block->bb_magic = cpu_to_be32(XFS_ABTB_MAGIC);
-               block->bb_level = 0;
-               block->bb_numrecs = cpu_to_be16(1);
-               block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK);
-               block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK);
+               if (xfs_sb_version_hascrc(&mp->m_sb))
+                       xfs_btree_init_block(mp, buf, XFS_ABTB_CRC_MAGIC, 0, 1,
+                                               agno, XFS_BTREE_CRC_BLOCKS);
+               else
+                       xfs_btree_init_block(mp, buf, XFS_ABTB_MAGIC, 0, 1,
+                                               agno, 0);
+
                arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
                arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
                if (loginternal && agno == logagno) {
@@ -2599,16 +2683,19 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
                /*
                 * CNT btree root block
                 */
-               buf = libxfs_getbuf(mp->m_dev,
+               buf = libxfs_getbuf(mp->m_ddev_targ,
                                XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)),
                                bsize);
+               buf->b_ops = &xfs_allocbt_buf_ops;
                block = XFS_BUF_TO_BLOCK(buf);
                memset(block, 0, blocksize);
-               block->bb_magic = cpu_to_be32(XFS_ABTC_MAGIC);
-               block->bb_level = 0;
-               block->bb_numrecs = cpu_to_be16(1);
-               block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK);
-               block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK);
+               if (xfs_sb_version_hascrc(&mp->m_sb))
+                       xfs_btree_init_block(mp, buf, XFS_ABTC_CRC_MAGIC, 0, 1,
+                                               agno, XFS_BTREE_CRC_BLOCKS);
+               else
+                       xfs_btree_init_block(mp, buf, XFS_ABTC_MAGIC, 0, 1,
+                                               agno, 0);
+
                arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
                arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
                if (loginternal && agno == logagno) {
@@ -2632,16 +2719,18 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
                /*
                 * INO btree root block
                 */
-               buf = libxfs_getbuf(mp->m_dev,
+               buf = libxfs_getbuf(mp->m_ddev_targ,
                                XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)),
                                bsize);
+               buf->b_ops = &xfs_inobt_buf_ops;
                block = XFS_BUF_TO_BLOCK(buf);
                memset(block, 0, blocksize);
-               block->bb_magic = cpu_to_be32(XFS_IBT_MAGIC);
-               block->bb_level = 0;
-               block->bb_numrecs = 0;
-               block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK);
-               block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK);
+               if (xfs_sb_version_hascrc(&mp->m_sb))
+                       xfs_btree_init_block(mp, buf, XFS_IBT_CRC_MAGIC, 0, 0,
+                                               agno, XFS_BTREE_CRC_BLOCKS);
+               else
+                       xfs_btree_init_block(mp, buf, XFS_IBT_MAGIC, 0, 0,
+                                               agno, 0);
                libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
        }
 
@@ -2656,7 +2745,7 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
        /*
         * Make sure we can write the last block in the realtime area.
         */
-       if (mp->m_rtdev && rtblocks > 0) {
+       if (mp->m_rtdev.dev && rtblocks > 0) {
                buf = libxfs_getbuf(mp->m_rtdev,
                                XFS_FSB_TO_BB(mp, rtblocks - 1LL), bsize);
                memset(XFS_BUF_PTR(buf), 0, blocksize);
@@ -2710,7 +2799,7 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
                                XFS_AGB_TO_DADDR(mp, mp->m_sb.sb_agcount-1,
                                        XFS_SB_DADDR),
                                XFS_FSS_TO_BB(mp, 1),
-                               LIBXFS_EXIT_ON_FAILURE);
+                               LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops);
                XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(
                                                        mp->m_sb.sb_rootino);
                libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
@@ -2722,7 +2811,7 @@ an AG size that is one stripe unit smaller, for example 
%llu.\n"),
                                XFS_AGB_TO_DADDR(mp, (mp->m_sb.sb_agcount-1)/2,
                                        XFS_SB_DADDR),
                                XFS_FSS_TO_BB(mp, 1),
-                               LIBXFS_EXIT_ON_FAILURE);
+                               LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops);
                        XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(
                                                        mp->m_sb.sb_rootino);
                        libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
@@ -2878,6 +2967,7 @@ usage( void )
 {
        fprintf(stderr, _("Usage: %s\n\
 /* blocksize */                [-b log=n|size=num]\n\
+/* metadata */         [-m crc=[0|1]\n\
 /* data subvol */      [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
                            (sunit=value,swidth=value|su=num,sw=num),\n\
                            sectlog=n|sectsize=num\n\
diff --git a/mkfs/xfs_mkfs.h b/mkfs/xfs_mkfs.h
index f25a7f3..d10e444 100644
--- a/mkfs/xfs_mkfs.h
+++ b/mkfs/xfs_mkfs.h
@@ -23,9 +23,9 @@
                  XFS_SB_VERSION_EXTFLGBIT | \
                  XFS_SB_VERSION_DIRV2BIT)
 
-#define XFS_SB_VERSION_MKFS(ia,dia,log2,attr1,sflag,ci,more) (\
-       ((ia)||(dia)||(log2)||(attr1)||(sflag)||(ci)||(more)) ? \
-       ( XFS_SB_VERSION_4 |                                            \
+#define XFS_SB_VERSION_MKFS(crc,ia,dia,log2,attr1,sflag,ci,more) (\
+       ((crc)||(ia)||(dia)||(log2)||(attr1)||(sflag)||(ci)||(more)) ? \
+       (((crc) ? XFS_SB_VERSION_5 : XFS_SB_VERSION_4) |                \
                ((ia) ? XFS_SB_VERSION_ALIGNBIT : 0) |                  \
                ((dia) ? XFS_SB_VERSION_DALIGNBIT : 0) |                \
                ((log2) ? XFS_SB_VERSION_LOGV2BIT : 0) |                \
@@ -36,15 +36,17 @@
                XFS_DFL_SB_VERSION_BITS |                               \
        0 ) : XFS_SB_VERSION_1 )
 
-#define XFS_SB_VERSION2_MKFS(lazycount, attr2, projid32bit, parent) (\
+#define XFS_SB_VERSION2_MKFS(crc, lazycount, attr2, projid32bit, parent) (\
        ((lazycount) ? XFS_SB_VERSION2_LAZYSBCOUNTBIT : 0) |            \
        ((attr2) ? XFS_SB_VERSION2_ATTR2BIT : 0) |                      \
        ((projid32bit) ? XFS_SB_VERSION2_PROJID32BIT : 0) |             \
        ((parent) ? XFS_SB_VERSION2_PARENTBIT : 0) |                    \
+       ((crc) ? XFS_SB_VERSION2_CRCBIT : 0) |                          \
        0 )
 
 #define        XFS_DFL_BLOCKSIZE_LOG   12              /* 4096 byte blocks */
 #define        XFS_DINODE_DFL_LOG      8               /* 256 byte inodes */
+#define        XFS_DINODE_DFL_CRC_LOG  9               /* 512 byte inodes for 
CRCs */
 #define        XFS_MIN_DATA_BLOCKS     100
 #define        XFS_MIN_INODE_PERBLOCK  2               /* min inodes per block 
*/
 #define        XFS_DFL_IMAXIMUM_PCT    25              /* max % of space for 
inodes */
@@ -79,7 +81,7 @@ extern void parse_proto (xfs_mount_t *mp, struct fsxattr 
*fsx, char **pp);
 extern void res_failed (int err);
 
 /* maxtrres.c */
-extern int max_trans_res (int dirversion,
+extern int max_trans_res (int crcs_enabled, int dirversion,
                int sectorlog, int blocklog, int inodelog, int dirblocklog);
 
 #endif /* __XFS_MKFS_H__ */
diff --git a/repair/attr_repair.c b/repair/attr_repair.c
index bab65b1..590363f 100644
--- a/repair/attr_repair.c
+++ b/repair/attr_repair.c
@@ -344,7 +344,7 @@ rmtval_get(xfs_mount_t *mp, xfs_ino_t ino, blkmap_t *blkmap,
                        break;
                }
                bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno),
-                               XFS_FSB_TO_BB(mp, 1), 0);
+                               XFS_FSB_TO_BB(mp, 1), 0, NULL);
                if (!bp) {
                        do_warn(
        _("can't read remote block for attributes of inode %" PRIu64 "\n"), 
ino);
@@ -673,7 +673,7 @@ process_leaf_attr_level(xfs_mount_t *mp,
                }
 
                bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, dev_bno),
-                                       XFS_FSB_TO_BB(mp, 1), 0);
+                                       XFS_FSB_TO_BB(mp, 1), 0, NULL);
                if (!bp) {
                        do_warn(
        _("can't read file block %u (fsbno %" PRIu64 ") for attribute fork of 
inode %" PRIu64 "\n"),
@@ -855,7 +855,7 @@ process_longform_attr(
        }
 
        bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno),
-                               XFS_FSB_TO_BB(mp, 1), 0);
+                               XFS_FSB_TO_BB(mp, 1), 0, NULL);
        if (!bp) {
                do_warn(
        _("can't read block 0 of inode %" PRIu64 " attribute fork\n"),
diff --git a/repair/dino_chunks.c b/repair/dino_chunks.c
index 4d14c57..3e7e225 100644
--- a/repair/dino_chunks.c
+++ b/repair/dino_chunks.c
@@ -53,7 +53,7 @@ check_aginode_block(xfs_mount_t       *mp,
         * so no one else will overlap them.
         */
        bp = libxfs_readbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, agbno),
-                       XFS_FSB_TO_BB(mp, 1), 0);
+                       XFS_FSB_TO_BB(mp, 1), 0, NULL);
        if (!bp) {
                do_warn(_("cannot read agbno (%u/%u), disk block %" PRId64 
"\n"),
                        agno, agbno, XFS_AGB_TO_DADDR(mp, agno, agbno));
@@ -66,6 +66,8 @@ check_aginode_block(xfs_mount_t       *mp,
                                XFS_OFFBNO_TO_AGINO(mp, agbno, i)))
                        cnt++;
        }
+       if (cnt)
+               bp->b_ops = &xfs_inode_buf_ops;
 
        libxfs_putbuf(bp);
        return(cnt);
@@ -626,7 +628,8 @@ process_inode_chunk(
 
                bplist[bp_index] = libxfs_readbuf(mp->m_dev,
                                        XFS_AGB_TO_DADDR(mp, agno, agbno),
-                                       XFS_FSB_TO_BB(mp, blks_per_cluster), 0);
+                                       XFS_FSB_TO_BB(mp, blks_per_cluster), 0,
+                                       NULL);
                if (!bplist[bp_index]) {
                        do_warn(_("cannot read inode %" PRIu64 ", disk block %" 
PRId64 ", cnt %d\n"),
                                XFS_AGINO_TO_INO(mp, agno, 
first_irec->ino_startnum),
@@ -640,6 +643,7 @@ process_inode_chunk(
                        return(1);
                }
                agbno += blks_per_cluster;
+               bplist[bp_index]->b_ops = &xfs_inode_buf_ops;
 
                pftrace("readbuf %p (%llu, %d) in AG %d", bplist[bp_index],
                        (long long)XFS_BUF_ADDR(bplist[bp_index]),
diff --git a/repair/dinode.c b/repair/dinode.c
index f564216..7a75dc8 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -837,7 +837,8 @@ get_agino_buf(xfs_mount_t    *mp,
 
        size = XFS_FSB_TO_BB(mp, MAX(1, XFS_INODES_PER_CHUNK/inodes_per_block));
        bp = libxfs_readbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno,
-               XFS_AGINO_TO_AGBNO(mp, irec->ino_startnum)), size, 0);
+               XFS_AGINO_TO_AGBNO(mp, irec->ino_startnum)), size, 0,
+               &xfs_inode_buf_ops);
        if (!bp) {
                do_warn(_("cannot read inode (%u/%u), disk block %" PRIu64 
"\n"),
                        agno, irec->ino_startnum,
@@ -948,7 +949,7 @@ getfunc_btree(xfs_mount_t           *mp,
        ASSERT(verify_dfsbno(mp, fsbno));
 
        bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno),
-                               XFS_FSB_TO_BB(mp, 1), 0);
+                               XFS_FSB_TO_BB(mp, 1), 0, NULL);
        if (!bp) {
                do_error(_("cannot read bmap block %" PRIu64 "\n"), fsbno);
                return(NULLDFSBNO);
@@ -1005,7 +1006,7 @@ _("- # of bmap records in inode %" PRIu64 " less than 
minimum (%u, min - %u), pr
                 */
                libxfs_putbuf(bp);
                bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno),
-                                       XFS_FSB_TO_BB(mp, 1), 0);
+                                       XFS_FSB_TO_BB(mp, 1), 0, NULL);
                if (!bp) {
                        do_error(_("cannot read bmap block %" PRIu64 "\n"),
                                fsbno);
@@ -1502,7 +1503,8 @@ process_symlink(
                        if (fsbno != NULLDFSBNO)
                                bp = libxfs_readbuf(mp->m_dev,
                                                XFS_FSB_TO_DADDR(mp, fsbno),
-                                               XFS_FSB_TO_BB(mp, 1), 0);
+                                               XFS_FSB_TO_BB(mp, 1), 0,
+                                               &xfs_symlink_buf_ops);
                        if (!bp || fsbno == NULLDFSBNO) {
                                do_warn(
 _("cannot read inode %" PRIu64 ", file block %d, disk block %" PRIu64 "\n"),
diff --git a/repair/dir.c b/repair/dir.c
index daca17d..1f313f5 100644
--- a/repair/dir.c
+++ b/repair/dir.c
@@ -761,7 +761,7 @@ traverse_int_dablock(xfs_mount_t    *mp,
                        goto error_out;
 
                bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno),
-                               XFS_FSB_TO_BB(mp, 1), 0);
+                               XFS_FSB_TO_BB(mp, 1), 0, NULL);
                if (!bp) {
                        if (whichfork == XFS_DATA_FORK)
                                do_warn(
@@ -1135,7 +1135,7 @@ verify_da_path(xfs_mount_t        *mp,
                }
 
                bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno),
-                               XFS_FSB_TO_BB(mp, 1), 0);
+                               XFS_FSB_TO_BB(mp, 1), 0, NULL);
                if (!bp) {
                        do_warn(
        _("can't read block %u (%" PRIu64 ") for directory inode %" PRIu64 
"\n"),
@@ -2251,7 +2251,7 @@ process_leaf_dir_level(xfs_mount_t        *mp,
                bd_addr = (xfs_daddr_t)XFS_FSB_TO_DADDR(mp, dev_bno);
 
                bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, dev_bno),
-                                       XFS_FSB_TO_BB(mp, 1), 0);
+                                       XFS_FSB_TO_BB(mp, 1), 0, NULL);
                if (!bp) {
                        do_warn(
        _("can't read file block %u (fsbno %" PRIu64 ", daddr %" PRId64 ") "
@@ -2512,7 +2512,7 @@ process_leaf_dir(
                return(1);
        }
        bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno),
-                       XFS_FSB_TO_BB(mp, 1), 0);
+                       XFS_FSB_TO_BB(mp, 1), 0, NULL);
        if (!bp) {
                do_warn(_("can't read block 0 for directory inode %" PRIu64 
"\n"),
                        ino);
diff --git a/repair/dir2.c b/repair/dir2.c
index c455c83..d853c44 100644
--- a/repair/dir2.c
+++ b/repair/dir2.c
@@ -105,7 +105,7 @@ da_read_buf(
                map[i].bm_bn = XFS_FSB_TO_DADDR(mp, bmp[i].startblock);
                map[i].bm_len = XFS_FSB_TO_BB(mp, bmp[i].blockcount);
        }
-       bp = libxfs_readbuf_map(mp->m_dev, map, nex, 0);
+       bp = libxfs_readbuf_map(mp->m_dev, map, nex, 0, NULL);
        if (map != map_array)
                free(map);
        return bp;
diff --git a/repair/phase2.c b/repair/phase2.c
index 23b457a..5a4cf10 100644
--- a/repair/phase2.c
+++ b/repair/phase2.c
@@ -48,7 +48,8 @@ zero_log(xfs_mount_t *mp)
        x.logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
        x.logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart);
 
-       log.l_dev = logdev;
+       log.l_dev.dev = logdev;
+       log.l_dev.bt_mount = mp;
        log.l_logsize = BBTOB(x.logBBsize);
        log.l_logBBsize = x.logBBsize;
        log.l_logBBstart = x.logBBstart;
@@ -92,7 +93,7 @@ zero_log(xfs_mount_t *mp)
                }
        }
 
-       libxfs_log_clear(logdev,
+       libxfs_log_clear(log.l_dev,
                XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
                (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks),
                &mp->m_sb.sb_uuid,
diff --git a/repair/phase3.c b/repair/phase3.c
index 80c66b5..3e43938 100644
--- a/repair/phase3.c
+++ b/repair/phase3.c
@@ -40,7 +40,7 @@ process_agi_unlinked(
 
        bp = libxfs_readbuf(mp->m_dev,
                        XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
-                       mp->m_sb.sb_sectsize/BBSIZE, 0);
+                       mp->m_sb.sb_sectsize/BBSIZE, 0, &xfs_agi_buf_ops);
        if (!bp)
                do_error(_("cannot read agi block %" PRId64 " for ag %u\n"),
                        XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), agno);
diff --git a/repair/phase6.c b/repair/phase6.c
index 136bb4f..b9e0cc3 100644
--- a/repair/phase6.c
+++ b/repair/phase6.c
@@ -512,7 +512,7 @@ mk_rbmino(xfs_mount_t *mp)
                                error);
                }
                for (i = 0, ep = map; i < nmap; i++, ep++) {
-                       libxfs_device_zero(mp->m_dev,
+                       libxfs_device_zero(mp->m_ddev_targ.dev,
                                XFS_FSB_TO_DADDR(mp, ep->br_startblock),
                                XFS_FSB_TO_BB(mp, ep->br_blockcount));
                        bno += ep->br_blockcount;
@@ -767,7 +767,7 @@ mk_rsumino(xfs_mount_t *mp)
                                error);
                }
                for (i = 0, ep = map; i < nmap; i++, ep++) {
-                       libxfs_device_zero(mp->m_dev,
+                       libxfs_device_zero(mp->m_ddev_targ.dev,
                                      XFS_FSB_TO_DADDR(mp, ep->br_startblock),
                                      XFS_FSB_TO_BB(mp, ep->br_blockcount));
                        bno += ep->br_blockcount;
@@ -1255,7 +1255,7 @@ _("can't map block %d in %s inode %" PRIu64 ", xfs_bmapi 
returns %d, nmap = %d\n
                 */
 
                bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno),
-                               XFS_FSB_TO_BB(mp, 1), 0);
+                               XFS_FSB_TO_BB(mp, 1), 0, NULL);
 
                if (!bp) {
                        do_warn(
@@ -1621,7 +1621,7 @@ longform_dir_entry_check(xfs_mount_t      *mp,
                skipit = 0;
 
                bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno),
-                               XFS_FSB_TO_BB(mp, 1), 0);
+                               XFS_FSB_TO_BB(mp, 1), 0, NULL);
 
                if (!bp) {
                        do_error(
diff --git a/repair/prefetch.c b/repair/prefetch.c
index b787663..ebe00c2 100644
--- a/repair/prefetch.c
+++ b/repair/prefetch.c
@@ -222,7 +222,7 @@ pf_scan_lbtree(
        int                     rc;
 
        bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, dbno),
-                       XFS_FSB_TO_BB(mp, 1), 0);
+                       XFS_FSB_TO_BB(mp, 1), 0, NULL);
        if (!bp)
                return 0;
 
@@ -722,7 +722,7 @@ init_prefetch(
        xfs_mount_t             *pmp)
 {
        mp = pmp;
-       mp_fd = libxfs_device_to_fd(mp->m_dev);
+       mp_fd = libxfs_device_to_fd(mp->m_ddev_targ.dev);
        pf_max_bytes = sysconf(_SC_PAGE_SIZE) << 7;
        pf_max_bbs = pf_max_bytes >> BBSHIFT;
        pf_max_fsbs = pf_max_bytes >> mp->m_sb.sb_blocklog;
diff --git a/repair/rt.c b/repair/rt.c
index d6ecd56..042ff46 100644
--- a/repair/rt.c
+++ b/repair/rt.c
@@ -206,7 +206,7 @@ process_rtbitmap(xfs_mount_t        *mp,
                        continue;
                }
                bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno),
-                               XFS_FSB_TO_BB(mp, 1));
+                               XFS_FSB_TO_BB(mp, 1), NULL);
                if (!bp) {
                        do_warn(_("can't read block %d for rtbitmap inode\n"),
                                        bmbno);
@@ -268,7 +268,7 @@ process_rtsummary(xfs_mount_t       *mp,
                        continue;
                }
                bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno),
-                               XFS_FSB_TO_BB(mp, 1));
+                               XFS_FSB_TO_BB(mp, 1), NULL);
                if (!bp) {
                        do_warn(_("can't read block %d for rtsummary inode\n"),
                                        sumbno);
diff --git a/repair/scan.c b/repair/scan.c
index 5345094..9f0ddaf 100644
--- a/repair/scan.c
+++ b/repair/scan.c
@@ -85,7 +85,7 @@ scan_sbtree(
        xfs_buf_t       *bp;
 
        bp = libxfs_readbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, root),
-                       XFS_FSB_TO_BB(mp, 1), 0);
+                       XFS_FSB_TO_BB(mp, 1), 0, NULL);
        if (!bp) {
                do_error(_("can't read btree block %d/%d\n"), agno, root);
                return;
@@ -130,7 +130,7 @@ scan_lbtree(
        int             dirty = 0;
 
        bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, root),
-                     XFS_FSB_TO_BB(mp, 1), 0);
+                     XFS_FSB_TO_BB(mp, 1), 0, NULL);
        if (!bp)  {
                do_error(_("can't read btree block %d/%d\n"),
                        XFS_FSB_TO_AGNO(mp, root),
@@ -1060,7 +1060,7 @@ scan_freelist(
 
        agflbuf = libxfs_readbuf(mp->m_dev,
                                 XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
-                                XFS_FSS_TO_BB(mp, 1), 0);
+                                XFS_FSS_TO_BB(mp, 1), 0, &xfs_agfl_buf_ops);
        if (!agflbuf)  {
                do_abort(_("can't read agfl block for ag %d\n"), agno);
                return;
@@ -1196,7 +1196,7 @@ scan_ag(
        int             status;
 
        sbbuf = libxfs_readbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_SB_DADDR),
-                               XFS_FSS_TO_BB(mp, 1), 0);
+                               XFS_FSS_TO_BB(mp, 1), 0, &xfs_sb_buf_ops);
        if (!sbbuf)  {
                do_error(_("can't get root superblock for ag %d\n"), agno);
                return;
@@ -1212,7 +1212,7 @@ scan_ag(
 
        agfbuf = libxfs_readbuf(mp->m_dev,
                        XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
-                       XFS_FSS_TO_BB(mp, 1), 0);
+                       XFS_FSS_TO_BB(mp, 1), 0, &xfs_agf_buf_ops);
        if (!agfbuf)  {
                do_error(_("can't read agf block for ag %d\n"), agno);
                libxfs_putbuf(sbbuf);
@@ -1223,7 +1223,7 @@ scan_ag(
 
        agibuf = libxfs_readbuf(mp->m_dev,
                        XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
-                       XFS_FSS_TO_BB(mp, 1), 0);
+                       XFS_FSS_TO_BB(mp, 1), 0, &xfs_agi_buf_ops);
        if (!agibuf)  {
                do_error(_("can't read agi block for ag %d\n"), agno);
                libxfs_putbuf(agfbuf);
diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
index 67a7446..167b1f6 100644
--- a/repair/xfs_repair.c
+++ b/repair/xfs_repair.c
@@ -558,9 +558,12 @@ main(int argc, char **argv)
        }
 
        /* prepare the mount structure */
-       sbp = libxfs_readbuf(x.ddev, XFS_SB_DADDR,
-                               1 << (XFS_MAX_SECTORSIZE_LOG - BBSHIFT), 0);
        memset(&xfs_m, 0, sizeof(xfs_mount_t));
+       xfs_m.m_ddev_targ.dev = x.ddev;
+       xfs_m.m_ddev_targ.bt_mount = &xfs_m;
+       sbp = libxfs_readbuf(xfs_m.m_ddev_targ, XFS_SB_DADDR,
+                               1 << (XFS_MAX_SECTORSIZE_LOG - BBSHIFT), 0,
+                               &xfs_sb_buf_ops);
        libxfs_sb_from_disk(&xfs_m.m_sb, XFS_BUF_TO_SBP(sbp));
 
        /*
-- 
1.7.10

<Prev in Thread] Current Thread [Next in Thread>