xfs: add support for large btree blocks
Add support for larger btree blocks that contains a CRC32C checksum, a filesystem uuid and block number for detecting filesystem consistency and out of place writes. [dchinner@redhat.com] Also include an owner field to allow reverse mappings to be implemented for improved repairability and a LSN field to so that log recovery can easily determine the last modification that made it to disk for each buffer. [dchinner@redhat.com] Add buffer log format flags to indicate the type of buffer to recovery so that we don't have to do blind magic number tests to determine what the buffer is. [dchinner@redhat.com] Modified to fit into the verifier structure. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Ben Myers <bpm@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
This commit is contained in:

committed by
Ben Myers

parent
a2050646f6
commit
ee1a47ab0e
@@ -439,11 +439,15 @@ xfs_bmap_sanity_check(
|
||||
{
|
||||
struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
|
||||
|
||||
if (block->bb_magic != cpu_to_be32(XFS_BMAP_MAGIC) ||
|
||||
be16_to_cpu(block->bb_level) != level ||
|
||||
if (block->bb_magic != cpu_to_be32(XFS_BMAP_CRC_MAGIC) &&
|
||||
block->bb_magic != cpu_to_be32(XFS_BMAP_MAGIC))
|
||||
return 0;
|
||||
|
||||
if (be16_to_cpu(block->bb_level) != level ||
|
||||
be16_to_cpu(block->bb_numrecs) == 0 ||
|
||||
be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[level != 0])
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1031,6 +1035,7 @@ xfs_bmap_extents_to_btree(
|
||||
xfs_extnum_t nextents; /* number of file extents */
|
||||
xfs_bmbt_ptr_t *pp; /* root block address pointer */
|
||||
|
||||
mp = ip->i_mount;
|
||||
ifp = XFS_IFORK_PTR(ip, whichfork);
|
||||
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS);
|
||||
|
||||
@@ -1044,16 +1049,18 @@ xfs_bmap_extents_to_btree(
|
||||
* Fill in the root.
|
||||
*/
|
||||
block = ifp->if_broot;
|
||||
block->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
|
||||
block->bb_level = cpu_to_be16(1);
|
||||
block->bb_numrecs = cpu_to_be16(1);
|
||||
block->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO);
|
||||
block->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO);
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb))
|
||||
xfs_btree_init_block_int(mp, block, XFS_BUF_DADDR_NULL,
|
||||
XFS_BMAP_CRC_MAGIC, 1, 1, ip->i_ino,
|
||||
XFS_BTREE_LONG_PTRS | XFS_BTREE_CRC_BLOCKS);
|
||||
else
|
||||
xfs_btree_init_block_int(mp, block, XFS_BUF_DADDR_NULL,
|
||||
XFS_BMAP_MAGIC, 1, 1, ip->i_ino,
|
||||
XFS_BTREE_LONG_PTRS);
|
||||
|
||||
/*
|
||||
* Need a cursor. Can't allocate until bb_level is filled in.
|
||||
*/
|
||||
mp = ip->i_mount;
|
||||
cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
|
||||
cur->bc_private.b.firstblock = *firstblock;
|
||||
cur->bc_private.b.flist = flist;
|
||||
@@ -1102,10 +1109,15 @@ xfs_bmap_extents_to_btree(
|
||||
*/
|
||||
abp->b_ops = &xfs_bmbt_buf_ops;
|
||||
ablock = XFS_BUF_TO_BLOCK(abp);
|
||||
ablock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
|
||||
ablock->bb_level = 0;
|
||||
ablock->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO);
|
||||
ablock->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO);
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb))
|
||||
xfs_btree_init_block_int(mp, ablock, abp->b_bn,
|
||||
XFS_BMAP_CRC_MAGIC, 0, 0, ip->i_ino,
|
||||
XFS_BTREE_LONG_PTRS | XFS_BTREE_CRC_BLOCKS);
|
||||
else
|
||||
xfs_btree_init_block_int(mp, ablock, abp->b_bn,
|
||||
XFS_BMAP_MAGIC, 0, 0, ip->i_ino,
|
||||
XFS_BTREE_LONG_PTRS);
|
||||
|
||||
arp = XFS_BMBT_REC_ADDR(mp, ablock, 1);
|
||||
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
|
||||
for (cnt = i = 0; i < nextents; i++) {
|
||||
@@ -1155,7 +1167,8 @@ xfs_bmap_local_to_extents(
|
||||
xfs_extlen_t total, /* total blocks needed by transaction */
|
||||
int *logflagsp, /* inode logging flags */
|
||||
int whichfork,
|
||||
void (*init_fn)(struct xfs_buf *bp,
|
||||
void (*init_fn)(struct xfs_trans *tp,
|
||||
struct xfs_buf *bp,
|
||||
struct xfs_inode *ip,
|
||||
struct xfs_ifork *ifp))
|
||||
{
|
||||
@@ -1207,7 +1220,7 @@ xfs_bmap_local_to_extents(
|
||||
bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0);
|
||||
|
||||
/* initialise the block and copy the data */
|
||||
init_fn(bp, ip, ifp);
|
||||
init_fn(tp, bp, ip, ifp);
|
||||
|
||||
/* account for the change in fork size and log everything */
|
||||
xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
|
||||
@@ -1314,16 +1327,19 @@ xfs_bmap_add_attrfork_extents(
|
||||
*/
|
||||
STATIC void
|
||||
xfs_bmap_local_to_extents_init_fn(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_buf *bp,
|
||||
struct xfs_inode *ip,
|
||||
struct xfs_ifork *ifp)
|
||||
{
|
||||
bp->b_ops = &xfs_bmbt_buf_ops;
|
||||
memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);
|
||||
xfs_trans_buf_set_type(tp, bp, XFS_BLF_BTREE_BUF);
|
||||
}
|
||||
|
||||
STATIC void
|
||||
xfs_symlink_local_to_remote(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_buf *bp,
|
||||
struct xfs_inode *ip,
|
||||
struct xfs_ifork *ifp)
|
||||
@@ -1342,8 +1358,7 @@ xfs_symlink_local_to_remote(
|
||||
*
|
||||
* XXX (dgc): investigate whether directory conversion can use the generic
|
||||
* formatting callout. It should be possible - it's just a very complex
|
||||
* formatter. it would also require passing the transaction through to the init
|
||||
* function.
|
||||
* formatter.
|
||||
*/
|
||||
STATIC int /* error */
|
||||
xfs_bmap_add_attrfork_local(
|
||||
|
Reference in New Issue
Block a user