/* prepare the mount structure */
- sbp = libxfs_readbuf(xargs.ddev, XFS_SB_DADDR, 1, 0);
memset(&mbuf, 0, sizeof(xfs_mount_t));
+ libxfs_buftarg_init(&mbuf, xargs.ddev, xargs.logdev, xargs.rtdev);
+ sbp = libxfs_readbuf(mbuf.m_ddev_targp, XFS_SB_DADDR, 1, 0,
+ &xfs_sb_buf_ops);
sb = &mbuf.m_sb;
libxfs_sb_from_disk(sb, XFS_BUF_TO_SBP(sbp));
}
memset(&log, 0, sizeof(log));
- if (!x.logdev)
- x.logdev = x.ddev;
+ libxfs_buftarg_init(mp, x.ddev, x.logdev, x.rtdev);
x.logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
x.logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart);
x.lbsize = BBSIZE;
if (xfs_sb_version_hassector(&mp->m_sb))
x.lbsize <<= (mp->m_sb.sb_logsectlog - BBSHIFT);
- log.l_dev = (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev;
+ log.l_dev = mp->m_logdev_targp;
log.l_logsize = BBTOB(log.l_logBBsize);
log.l_logBBsize = x.logBBsize;
log.l_logBBstart = x.logBBstart;
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_targp,
XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
(xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks),
uuidp,
#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 void libxfs_buftarg_init(struct xfs_mount *mp, dev_t ddev,
+ dev_t logdev, dev_t rtdev);
+
extern char *progname;
extern int libxfs_init (libxfs_init_t *);
extern void libxfs_destroy (void);
extern int libxfs_device_to_fd (dev_t);
extern dev_t libxfs_device_open (char *, int, int, int);
-extern void libxfs_device_zero (dev_t, xfs_daddr_t, uint);
+extern void libxfs_device_zero(struct xfs_buftarg *, xfs_daddr_t, uint);
extern void libxfs_device_close (dev_t);
extern int libxfs_device_alignment (void);
extern void libxfs_report(FILE *);
/* 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 *,
- int, int, int);
+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.
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_targp;
+ struct xfs_buftarg *m_logdev_targp;
+ struct xfs_buftarg *m_rtdev_targp;
+#define m_dev m_ddev_targp
+#define m_logdev m_logdev_targp
+#define m_rtdev m_rtdev_targp
__uint8_t m_dircook_elog; /* log d-cookie entry bits */
__uint8_t m_blkbit_log; /* blocklog + NBBY */
__uint8_t m_blkbb_log; /* blocklog - BBSHIFT */
/*
* 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 {
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;
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;
#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))
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
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;
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 *btp,
+ 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 *btp,
xfs_daddr_t blkno,
int numblks,
uint flags)
{
DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
- return libxfs_trans_get_buf_map(tp, dev, &map, 1, flags);
+ return libxfs_trans_get_buf_map(tp, btp, &map, 1, flags);
}
int libxfs_trans_read_buf_map(struct xfs_mount *mp,
- struct xfs_trans *tp, dev_t dev,
+ struct xfs_trans *tp,
+ struct xfs_buftarg *btp,
struct xfs_buf_map *map, int nmaps,
uint flags, struct xfs_buf **bpp,
const struct xfs_buf_ops *ops);
libxfs_trans_read_buf(
struct xfs_mount *mp,
struct xfs_trans *tp,
- dev_t dev,
+ struct xfs_buftarg *btp,
xfs_daddr_t blkno,
int numblks,
uint flags,
const struct xfs_buf_ops *ops)
{
DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
- return libxfs_trans_read_buf_map(mp, tp, dev, &map, 1,
+ return libxfs_trans_read_buf_map(mp, tp, btp, &map, 1,
flags, bpp, ops);
}
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 */
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 */
extern struct xfs_dir2_data_free *xfs_dir2_data_freefind(
struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_unused *dup);
+extern const struct xfs_buf_ops xfs_dir3_block_buf_ops;
+extern const struct xfs_buf_ops xfs_dir3_leafn_buf_ops;
+extern const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops;
+extern const struct xfs_buf_ops xfs_dir3_free_buf_ops;
+extern const struct xfs_buf_ops xfs_dir3_data_buf_ops;
+
+
#endif /* __XFS_DIR2_H__ */
sbp = &mp->m_sb;
if (sbp->sb_rblocks == 0)
return 0;
- if (mp->m_rtdev == 0 && !(flags & LIBXFS_MOUNT_DEBUGGER)) {
+ if (mp->m_rtdev_targp->dev == 0 && !(flags & LIBXFS_MOUNT_DEBUGGER)) {
fprintf(stderr, _("%s: filesystem has a realtime subvolume\n"),
progname);
return -1;
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);
return error;
}
+static struct xfs_buftarg *
+libxfs_buftarg_alloc(
+ struct xfs_mount *mp,
+ dev_t dev)
+{
+ struct xfs_buftarg *btp;
+
+ btp = malloc(sizeof(*btp));
+ if (!btp) {
+ fprintf(stderr, _("%s: buftarg init failed\n"),
+ progname);
+ exit(1);
+ }
+ btp->bt_mount = mp;
+ btp->dev = dev;
+ return btp;
+}
+
+void
+libxfs_buftarg_init(
+ struct xfs_mount *mp,
+ dev_t dev,
+ dev_t logdev,
+ dev_t rtdev)
+{
+ if (mp->m_ddev_targp) {
+ /* should already have all buftargs initialised */
+ if (mp->m_ddev_targp->dev != dev ||
+ mp->m_ddev_targp->bt_mount != mp) {
+ fprintf(stderr,
+ _("%s: bad buftarg reinit, ddev\n"),
+ progname);
+ exit(1);
+ }
+ if (!logdev || logdev == dev) {
+ if (mp->m_logdev_targp != mp->m_ddev_targp) {
+ fprintf(stderr,
+ _("%s: bad buftarg reinit, ldev mismatch\n"),
+ progname);
+ exit(1);
+ }
+ } else if (mp->m_logdev_targp->dev != logdev ||
+ mp->m_logdev_targp->bt_mount != mp) {
+ fprintf(stderr,
+ _("%s: bad buftarg reinit, logdev\n"),
+ progname);
+ exit(1);
+ }
+ if (rtdev && (mp->m_rtdev_targp->dev != rtdev ||
+ mp->m_rtdev_targp->bt_mount != mp)) {
+ fprintf(stderr,
+ _("%s: bad buftarg reinit, rtdev\n"),
+ progname);
+ exit(1);
+ }
+ return;
+ }
+
+ mp->m_ddev_targp = libxfs_buftarg_alloc(mp, dev);
+ if (!logdev || logdev == dev)
+ mp->m_logdev_targp = mp->m_ddev_targp;
+ else
+ mp->m_logdev_targp = libxfs_buftarg_alloc(mp, logdev);
+ mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, rtdev);
+}
+
/*
* Mount structure initialization, provides a filled-in xfs_mount_t
* such that the numerous XFS_* macros can be used. If dev is zero,
xfs_sb_t *sbp;
int error;
- mp->m_dev = dev;
- mp->m_rtdev = rtdev;
- mp->m_logdev = logdev;
+ libxfs_buftarg_init(mp, dev, logdev, rtdev);
+
mp->m_flags = (LIBXFS_MOUNT_32BITINODES|LIBXFS_MOUNT_32BITINOOPT);
mp->m_sb = *sb;
INIT_RADIX_TREE(&mp->m_perag_tree, GFP_KERNEL);
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))
} else
libxfs_putbuf(bp);
- if (mp->m_logdev && mp->m_logdev != mp->m_dev) {
+ if (mp->m_logdev_targp->dev &&
+ mp->m_logdev_targp->dev != mp->m_ddev_targp->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,
+ (!(bp = libxfs_readbuf(mp->m_logdev_targp,
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))
xfs_buf_t *
xfs_trans_buf_item_match(
xfs_trans_t *tp,
- dev_t dev,
+ struct xfs_buftarg *btp,
struct xfs_buf_map *map,
int nmaps)
{
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 == btp->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);
#define IO_BCOMPARE_CHECK
void
-libxfs_device_zero(dev_t dev, xfs_daddr_t start, uint len)
+libxfs_device_zero(struct xfs_buftarg *btp, xfs_daddr_t start, uint len)
{
xfs_off_t start_offset, end_offset, offset;
ssize_t zsize, bytes;
}
memset(z, 0, zsize);
- fd = libxfs_device_to_fd(dev);
+ fd = libxfs_device_to_fd(btp->dev);
start_offset = LIBXFS_BBTOOFF64(start);
if ((lseek64(fd, start_offset, SEEK_SET)) < 0) {
int
libxfs_log_clear(
- dev_t device,
+ struct xfs_buftarg *btp,
xfs_daddr_t start,
uint length,
uuid_t *fs_uuid,
xfs_buf_t *bp;
int len;
- if (!device || !fs_uuid)
+ if (!btp->dev || !fs_uuid)
return -EINVAL;
/* first zero the log */
- libxfs_device_zero(device, start, length);
+ libxfs_device_zero(btp, start, length);
/* then write a log record header */
len = ((version == 2) && sunit) ? BTOBB(sunit) : 2;
len = MAX(len, 2);
- bp = libxfs_getbufr(device, start, len);
+ bp = libxfs_getbufr(btp, start, len);
libxfs_log_header(XFS_BUF_PTR(bp),
fs_uuid, version, sunit, fmt, next, bp);
bp->b_flags |= LIBXFS_B_DIRTY;
#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) \
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 *btp, 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(btp, 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 *btp, 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(btp, map, nmaps, flags, ops);
__add_trace(bp, func, file, line);
return bp;
}
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 *btp, xfs_daddr_t blkno, int len)
{
- xfs_buf_t *bp = libxfs_getbuf(device, blkno, len);
+ xfs_buf_t *bp = libxfs_getbuf(btp, blkno, len);
__add_trace(bp, func, file, line);
return bp;
}
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 *btp, struct xfs_buf_map *map, int nmaps)
{
- xfs_buf_t *bp = libxfs_getbuf_map(device, map, nmaps);
+ xfs_buf_t *bp = libxfs_getbuf_map(btp, map, nmaps);
__add_trace(bp, func, file, line);
return bp;
}
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 *btp, xfs_daddr_t blkno, int len, unsigned int flags)
{
- xfs_buf_t *bp = libxfs_getbuf_flags(device, blkno, len, flags);
+ xfs_buf_t *bp = libxfs_getbuf_flags(btp, blkno, len, flags);
__add_trace(bp, func, file, line);
return bp;
}
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);
+ return libxfs_readbuf(mp->m_ddev_targp, XFS_SB_DADDR,
+ XFS_FSS_TO_BB(mp, 1), flags, &xfs_sb_buf_ops);
}
kmem_zone_t *xfs_buf_zone;
* buffer initialisation instead of a contiguous buffer.
*/
struct xfs_bufkey {
- dev_t device;
+ struct xfs_buftarg *buftarg;
xfs_daddr_t blkno;
unsigned int bblen;
struct xfs_buf_map *map;
struct xfs_bufkey *bkey = (struct xfs_bufkey *)key;
#ifdef IO_BCOMPARE_CHECK
- if (bp->b_dev == bkey->device &&
+ if (bp->b_target->dev == bkey->buftarg->dev &&
bp->b_bn == bkey->blkno &&
bp->b_bcount != BBTOB(bkey->bblen))
fprintf(stderr, "%lx: Badness in key lookup (length)\n"
(unsigned long long)bkey->blkno, BBTOB(bkey->bblen));
#endif
- return (bp->b_dev == bkey->device &&
+ return (bp->b_target->dev == bkey->buftarg->dev &&
bp->b_bn == bkey->blkno &&
bp->b_bcount == BBTOB(bkey->bblen));
}
}
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 *btp, 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 = btp;
bp->b_error = 0;
if (!bp->b_addr)
bp->b_addr = memalign(libxfs_device_alignment(), bytes);
pthread_mutex_init(&bp->b_lock, NULL);
bp->b_holder = 0;
bp->b_recur = 0;
+ bp->b_ops = NULL;
}
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 *btp, xfs_daddr_t bno,
+ unsigned int bytes)
{
- __initbuf(bp, device, bno, bytes);
+ __initbuf(bp, btp, 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 *btp,
+ struct xfs_buf_map *map, int nmaps)
{
unsigned int bytes = 0;
int i;
bytes += BBTOB(map[i].bm_len);
}
- __initbuf(bp, device, map[0].bm_bn, bytes);
+ __initbuf(bp, btp, map[0].bm_bn, bytes);
bp->b_flags |= LIBXFS_B_DISCONTIG;
}
}
xfs_buf_t *
-libxfs_getbufr(dev_t device, xfs_daddr_t blkno, int bblen)
+libxfs_getbufr(struct xfs_buftarg *btp, xfs_daddr_t blkno, int bblen)
{
xfs_buf_t *bp;
int blen = BBTOB(bblen);
bp =__libxfs_getbufr(blen);
if (bp)
- libxfs_initbuf(bp, device, blkno, blen);
+ libxfs_initbuf(bp, btp, blkno, blen);
#ifdef IO_DEBUG
printf("%lx: %s: allocated %u bytes buffer, key=0x%llx(0x%llx), %p\n",
pthread_self(), __FUNCTION__, blen,
}
xfs_buf_t *
-libxfs_getbufr_map(dev_t device, xfs_daddr_t blkno, int bblen,
+libxfs_getbufr_map(struct xfs_buftarg *btp, xfs_daddr_t blkno, int bblen,
struct xfs_buf_map *map, int nmaps)
{
xfs_buf_t *bp;
bp =__libxfs_getbufr(blen);
if (bp)
- libxfs_initbuf_map(bp, device, map, nmaps);
+ libxfs_initbuf_map(bp, btp, map, nmaps);
#ifdef IO_DEBUG
printf("%lx: %s: allocated %u bytes buffer, key=0x%llx(0x%llx), %p\n",
pthread_self(), __FUNCTION__, blen,
}
struct xfs_buf *
-libxfs_getbuf_flags(dev_t device, xfs_daddr_t blkno, int len, unsigned int flags)
+libxfs_getbuf_flags(struct xfs_buftarg *btp, xfs_daddr_t blkno, int len,
+ unsigned int flags)
{
struct xfs_bufkey key = {0};
- key.device = device;
+ key.buftarg = btp;
key.blkno = blkno;
key.bblen = len;
}
struct xfs_buf *
-libxfs_getbuf(dev_t device, xfs_daddr_t blkno, int len)
+libxfs_getbuf(struct xfs_buftarg *btp, xfs_daddr_t blkno, int len)
{
- return libxfs_getbuf_flags(device, blkno, len, 0);
+ return libxfs_getbuf_flags(btp, 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 *btp, struct xfs_buf_map *map, int nmaps)
{
struct xfs_bufkey key = {0};
int i;
- key.device = device;
+ key.buftarg = btp;
key.blkno = map[0].bm_bn;
for (i = 0; i < nmaps; i++) {
key.bblen += map[i].bm_len;
{
struct xfs_bufkey key = {0};
- key.device = bp->b_dev;
+ key.buftarg = bp->b_target;
key.blkno = bp->b_bn;
- key.bblen = bp->b_bcount >> BBSHIFT;
+ key.bblen = bp->b_length;
cache_node_purge(libxfs_bcache, &key, (struct cache_node *)bp);
}
if (bufkey->map)
return (struct cache_node *)
- libxfs_getbufr_map(bufkey->device,
+ libxfs_getbufr_map(bufkey->buftarg,
bufkey->blkno, bufkey->bblen,
bufkey->map, bufkey->nmaps);
- return (struct cache_node *)libxfs_getbufr(bufkey->device,
+ return (struct cache_node *)libxfs_getbufr(bufkey->buftarg,
bufkey->blkno, bufkey->bblen);
}
}
int
-libxfs_readbufr(dev_t dev, xfs_daddr_t blkno, xfs_buf_t *bp, int len, int flags)
+libxfs_readbufr(struct xfs_buftarg *btp, 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(btp->dev);
int bytes = BBTOB(len);
int error;
error = __read_buf(fd, bp->b_addr, bytes, LIBXFS_BBTOOFF64(blkno), flags);
if (!error &&
- bp->b_dev == dev &&
+ bp->b_target->dev == btp->dev &&
bp->b_bn == blkno &&
bp->b_bcount == bytes)
bp->b_flags |= LIBXFS_B_UPTODATE;
}
xfs_buf_t *
-libxfs_readbuf(dev_t dev, xfs_daddr_t blkno, int len, int flags)
+libxfs_readbuf(struct xfs_buftarg *btp, 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;
- }
+ bp = libxfs_getbuf(btp, blkno, len);
+ if (!bp)
+ return NULL;
+ if ((bp->b_flags & (LIBXFS_B_UPTODATE|LIBXFS_B_DIRTY)))
+ return bp;
+
+ /*
+ * only set the ops on a cache miss (i.e. first physical read) as the
+ * verifier may change the ops to match the typ eof buffer it contains.
+ * A cache hit might reset the verifier to the original type if we set
+ * it again, but it won't get called again and set to match the buffer
+ * contents. *cough* xfs_da_node_buf_ops *cough*.
+ */
+ bp->b_error = 0;
+ bp->b_ops = ops;
+ error = libxfs_readbufr(btp, 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 *btp, struct xfs_buf_map *map, int nmaps,
+ int flags, const struct xfs_buf_ops *ops)
{
xfs_buf_t *bp;
int error = 0;
char *buf;
if (nmaps == 1)
- return libxfs_readbuf(dev, map[0].bm_bn, map[0].bm_len, flags);
+ return libxfs_readbuf(btp, 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)))
+ bp = libxfs_getbuf_map(btp, map, nmaps);
+ if (!bp)
+ return NULL;
+
+ bp->b_error = 0;
+ 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(btp->dev);
buf = bp->b_addr;
for (i = 0; i < bp->b_nmaps; i++) {
off64_t offset = LIBXFS_BBTOOFF64(bp->b_map[i].bm_bn);
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,
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;
+ /*
+ * we never write buffers that are marked stale. This indicates they
+ * contain data that has been invalidated, and even if the buffer is
+ * dirty it must *never* be written. Verifiers are wonderful for finding
+ * bugs like this. Make sure the error is obvious as to the cause.
+ */
+ if (bp->b_flags & LIBXFS_B_STALE) {
+ bp->b_error = ESTALE;
+ return bp->b_error;
+ }
+
+ /*
+ * clear any pre-existing error status on the buffer. This can occur if
+ * the buffer is corrupt on disk and the repair process doesn't clear
+ * the error before fixing and writing it back.
+ */
+ bp->b_error = 0;
+ if (bp->b_ops) {
+ bp->b_ops->verify_write(bp);
+ if (bp->b_error) {
+ fprintf(stderr,
+ _("%s: write verifer failed on bno 0x%llx/0x%x\n"),
+ __func__, (long long)bp->b_bn, bp->b_bcount);
+ return bp->b_error;
+ }
+ }
+
+ if (bp->b_ops) {
+ bp->b_ops->verify_write(bp);
+ if (bp->b_error)
+ return bp->b_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);
xfs_buf_t *
libxfs_trans_get_buf_map(
xfs_trans_t *tp,
- dev_t dev,
+ struct xfs_buftarg *btp,
struct xfs_buf_map *map,
int nmaps,
uint f)
xfs_buf_log_item_t *bip;
if (tp == NULL)
- return libxfs_getbuf_map(dev, map, nmaps);
+ return libxfs_getbuf_map(btp, map, nmaps);
- bp = xfs_trans_buf_item_match(tp, dev, map, nmaps);
+ bp = xfs_trans_buf_item_match(tp, btp, map, nmaps);
if (bp != NULL) {
ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
return bp;
}
- bp = libxfs_getbuf_map(dev, map, nmaps);
+ bp = libxfs_getbuf_map(btp, map, nmaps);
if (bp == NULL)
return NULL;
#ifdef XACT_DEBUG
libxfs_trans_read_buf_map(
xfs_mount_t *mp,
xfs_trans_t *tp,
- dev_t dev,
+ struct xfs_buftarg *btp,
struct xfs_buf_map *map,
int nmaps,
uint flags,
*bpp = NULL;
if (tp == NULL) {
- bp = libxfs_readbuf_map(dev, map, nmaps, flags);
+ bp = libxfs_readbuf_map(btp, map, nmaps, flags, ops);
if (!bp) {
return (flags & XBF_TRYLOCK) ?
EAGAIN : XFS_ERROR(ENOMEM);
goto done;
}
- bp = xfs_trans_buf_item_match(tp, dev, map, nmaps);
+ bp = xfs_trans_buf_item_match(tp, btp, map, nmaps);
if (bp != NULL) {
ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
goto done;
}
- bp = libxfs_readbuf_map(dev, map, nmaps, flags);
+ bp = libxfs_readbuf_map(btp, map, nmaps, flags, ops);
if (!bp) {
return (flags & XBF_TRYLOCK) ?
EAGAIN : XFS_ERROR(ENOMEM);
#define EWRONGFS EINVAL
#endif
-#define m_ddev_targp m_dev
-#define m_logdev_targp m_logdev
-#define m_rtdev_targp m_rtdev
#define xfs_error_level 0
#define STATIC static
NULL; \
})
#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_buf_get(devp,blkno,len,f) (libxfs_getbuf((devp), (blkno), (len)))
#define xfs_bwrite(bp) libxfs_writebuf((bp), 0)
#define XBRW_READ LIBXFS_BREAD
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 */
const unsigned char *name, int len);
/* xfs_dir2_block.c */
-extern const struct xfs_buf_ops xfs_dir3_block_buf_ops;
-
extern int xfs_dir2_block_addname(struct xfs_da_args *args);
extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent,
xfs_off_t *offset, filldir_t filldir);
#define xfs_dir3_data_check(dp,bp)
#endif
-extern const struct xfs_buf_ops xfs_dir3_data_buf_ops;
-extern const struct xfs_buf_ops xfs_dir3_free_buf_ops;
-
extern int __xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp);
extern int xfs_dir3_data_read(struct xfs_trans *tp, struct xfs_inode *dp,
xfs_dablk_t bno, xfs_daddr_t mapped_bno, struct xfs_buf **bpp);
xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);
/* xfs_dir2_leaf.c */
-extern const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops;
-extern const struct xfs_buf_ops xfs_dir3_leafn_buf_ops;
-
extern int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp,
xfs_dablk_t fbno, xfs_daddr_t mappedbno, struct xfs_buf **bpp);
extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
+ memset(&mount, 0, sizeof(mount));
progname = basename(argv[0]);
while ((c = getopt(argc, argv, "bC:cdefl:iqnors:tDVv")) != EOF) {
exit(1);
logstat(&mount);
+ libxfs_buftarg_init(&mount, x.ddev, x.logdev, x.rtdev);
logfd = (x.logfd < 0) ? x.dfd : x.logfd;
ASSERT(x.logBBsize <= INT_MAX);
- log.l_dev = x.logdev;
+ log.l_dev = mount.m_logdev_targp;
log.l_logsize = BBTOB(x.logBBsize);
log.l_logBBstart = x.logBBstart;
log.l_logBBsize = x.logBBsize;
error);
}
for (i = 0, ep = map; i < nmap; i++, ep++) {
- libxfs_device_zero(mp->m_dev,
+ libxfs_device_zero(mp->m_ddev_targp,
XFS_FSB_TO_DADDR(mp, ep->br_startblock),
XFS_FSB_TO_BB(mp, ep->br_blockcount));
bno += ep->br_blockcount;
error);
}
for (i = 0, ep = map; i < nmap; i++, ep++) {
- libxfs_device_zero(mp->m_dev,
+ libxfs_device_zero(mp->m_ddev_targp,
XFS_FSB_TO_DADDR(mp, ep->br_startblock),
XFS_FSB_TO_BB(mp, ep->br_blockcount));
bno += ep->br_blockcount;
* 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));
+ libxfs_buftarg_init(mp, xi.ddev, xi.logdev, xi.rtdev);
+ buf = libxfs_getbuf(mp->m_ddev_targp, 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_targp, 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);
/*
* 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_targp,
+ (xi.dsize - BTOBB(WHACK_SIZE)),
BTOBB(WHACK_SIZE));
memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE);
libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
}
/*
- * Zero the log if there is one.
+ * Zero the log....
*/
- if (loginternal)
- xi.logdev = xi.ddev;
- if (xi.logdev)
- libxfs_log_clear(xi.logdev, XFS_FSB_TO_DADDR(mp, logstart),
- (xfs_extlen_t)XFS_FSB_TO_BB(mp, logblocks),
- &sbp->sb_uuid, logversion, lsunit, XLOG_FMT);
+ libxfs_log_clear(mp->m_logdev_targp,
+ 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) {
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++) {
/*
* Superblock.
*/
- buf = libxfs_getbuf(xi.ddev,
+ buf = libxfs_getbuf(mp->m_ddev_targp,
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);
/*
* AG header block: freespace
*/
- buf = libxfs_getbuf(mp->m_dev,
+ buf = libxfs_getbuf(mp->m_ddev_targp,
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)
/*
* AG header block: inodes
*/
- buf = libxfs_getbuf(mp->m_dev,
+ buf = libxfs_getbuf(mp->m_ddev_targp,
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);
/*
* BNO btree root block
*/
- buf = libxfs_getbuf(mp->m_dev,
+ buf = libxfs_getbuf(mp->m_ddev_targp,
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);
/*
* CNT btree root block
*/
- buf = libxfs_getbuf(mp->m_dev,
+ buf = libxfs_getbuf(mp->m_ddev_targp,
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);
/*
* INO btree root block
*/
- buf = libxfs_getbuf(mp->m_dev,
+ buf = libxfs_getbuf(mp->m_ddev_targp,
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);
/*
* Touch last block, make fs the right size if it's a file.
*/
- buf = libxfs_getbuf(mp->m_dev,
+ buf = libxfs_getbuf(mp->m_ddev_targp,
(xfs_daddr_t)XFS_FSB_TO_BB(mp, dblocks - 1LL), bsize);
memset(XFS_BUF_PTR(buf), 0, blocksize);
libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
/*
* Make sure we can write the last block in the realtime area.
*/
- if (mp->m_rtdev && rtblocks > 0) {
- buf = libxfs_getbuf(mp->m_rtdev,
+ if (mp->m_rtdev_targp->dev && rtblocks > 0) {
+ buf = libxfs_getbuf(mp->m_rtdev_targp,
XFS_FSB_TO_BB(mp, rtblocks - 1LL), bsize);
memset(XFS_BUF_PTR(buf), 0, blocksize);
libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
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);
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);
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, &xfs_da3_node_buf_ops);
if (!bp) {
if (whichfork == XFS_DATA_FORK)
do_warn(
}
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_da3_node_buf_ops);
if (!bp) {
do_warn(
_("can't read block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"),
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);
}
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"),
}
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"),
* 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));
XFS_OFFBNO_TO_AGINO(mp, agbno, i)))
cnt++;
}
+ if (cnt)
+ bp->b_ops = &xfs_inode_buf_ops;
libxfs_putbuf(bp);
return(cnt);
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),
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]),
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,
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);
*/
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);
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"),
da_read_buf(
xfs_mount_t *mp,
int nex,
- bmap_ext_t *bmp)
+ bmap_ext_t *bmp,
+ const struct xfs_buf_ops *ops)
{
#define MAP_ARRAY_SZ 4
struct xfs_buf_map map_array[MAP_ARRAY_SZ];
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, ops);
if (map != map_array)
free(map);
return bp;
if (nex == 0)
goto error_out;
- bp = da_read_buf(mp, nex, bmp);
+ bp = da_read_buf(mp, nex, bmp, &xfs_da3_node_buf_ops);
if (bmp != &lbmp)
free(bmp);
if (bp == NULL) {
return(1);
}
- bp = da_read_buf(mp, nex, bmp);
+ bp = da_read_buf(mp, nex, bmp, &xfs_da3_node_buf_ops);
if (bmp != &lbmp)
free(bmp);
mp->m_dirdatablk, ino);
return 1;
}
- bp = da_read_buf(mp, nex, bmp);
+ bp = da_read_buf(mp, nex, bmp, &xfs_dir3_block_buf_ops);
if (bmp != &lbmp)
free(bmp);
if (bp == NULL) {
da_bno, ino);
goto error_out;
}
- bp = da_read_buf(mp, nex, bmp);
+ bp = da_read_buf(mp, nex, bmp, &xfs_dir3_leafn_buf_ops);
if (bmp != &lbmp)
free(bmp);
bmp = NULL;
dbno, ino);
continue;
}
- bp = da_read_buf(mp, nex, bmp);
+ bp = da_read_buf(mp, nex, bmp, &xfs_dir3_data_buf_ops);
if (bmp != &lbmp)
free(bmp);
if (bp == NULL) {
int error;
struct xlog log;
xfs_daddr_t head_blk, tail_blk;
- dev_t logdev = (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev;
memset(&log, 0, sizeof(log));
- if (!x.logdev)
- 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);
x.lbsize = BBSIZE;
if (xfs_sb_version_hassector(&mp->m_sb))
x.lbsize <<= (mp->m_sb.sb_logsectlog - BBSHIFT);
- log.l_dev = logdev;
+ log.l_dev = mp->m_logdev_targp;
log.l_logsize = BBTOB(x.logBBsize);
log.l_logBBsize = x.logBBsize;
log.l_logBBstart = x.logBBstart;
}
}
- 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,
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);
error);
}
for (i = 0, ep = map; i < nmap; i++, ep++) {
- libxfs_device_zero(mp->m_dev,
+ libxfs_device_zero(mp->m_ddev_targp,
XFS_FSB_TO_DADDR(mp, ep->br_startblock),
XFS_FSB_TO_BB(mp, ep->br_blockcount));
bno += ep->br_blockcount;
error);
}
for (i = 0, ep = map; i < nmap; i++, ep++) {
- libxfs_device_zero(mp->m_dev,
+ libxfs_device_zero(mp->m_ddev_targp,
XFS_FSB_TO_DADDR(mp, ep->br_startblock),
XFS_FSB_TO_BB(mp, ep->br_blockcount));
bno += ep->br_blockcount;
struct xfs_dir2_leaf_entry *ents;
da_bno = mp->m_dirleafblk;
- if (libxfs_da_read_buf(NULL, ip, da_bno, -1, &bp, XFS_DATA_FORK, NULL)) {
+ if (libxfs_da_read_buf(NULL, ip, da_bno, -1, &bp, XFS_DATA_FORK,
+ &xfs_dir3_leaf1_buf_ops)) {
do_error(
_("can't read block %u for directory inode %" PRIu64 "\n"),
da_bno, ip->i_ino);
if (bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK))
break;
if (libxfs_da_read_buf(NULL, ip, da_bno, -1, &bp,
- XFS_DATA_FORK, NULL)) {
+ XFS_DATA_FORK, &xfs_dir3_leafn_buf_ops)) {
do_warn(
_("can't read leaf block %u for directory inode %" PRIu64 "\n"),
da_bno, ip->i_ino);
if (bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK))
break;
if (libxfs_da_read_buf(NULL, ip, da_bno, -1, &bp,
- XFS_DATA_FORK, NULL)) {
+ XFS_DATA_FORK, &xfs_dir3_free_buf_ops)) {
do_warn(
_("can't read freespace block %u for directory inode %" PRIu64 "\n"),
da_bno, ip->i_ino);
num_bps * sizeof(struct xfs_buf*));
}
if (libxfs_da_read_buf(NULL, ip, da_bno, -1, &bplist[db],
- XFS_DATA_FORK, NULL)) {
+ XFS_DATA_FORK, &xfs_dir3_data_buf_ops)) {
do_warn(
_("can't read data block %u for directory inode %" PRIu64 "\n"),
da_bno, ino);
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;
xfs_mount_t *pmp)
{
mp = pmp;
- mp_fd = libxfs_device_to_fd(mp->m_dev);
+ mp_fd = libxfs_device_to_fd(mp->m_ddev_targp->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;
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);
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);
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;
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),
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;
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;
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);
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);
}
memset(agcnts, 0, mp->m_sb.sb_agcount * sizeof(*agcnts));
- create_work_queue(&wq, mp, scan_threads);
+ create_work_queue(&wq, mp, 1);
+ //create_work_queue(&wq, mp, scan_threads);
for (i = 0; i < mp->m_sb.sb_agcount; i++)
queue_work(&wq, scan_ag, i, &agcnts[i]);
}
/* 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));
+ libxfs_buftarg_init(&xfs_m, x.ddev, x.logdev, x.rtdev);
+ sbp = libxfs_readbuf(xfs_m.m_ddev_targp, 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));
/*