From a5155b870d687de1a5f07e774b49b1e8ef0f6f50 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Sat, 2 Nov 2019 09:40:53 -0700 Subject: xfs: always log corruption errors Make sure we log something to dmesg whenever we return -EFSCORRUPTED up the call stack. Signed-off-by: Darrick J. Wong Reviewed-by: Carlos Maiolino Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_dir2_node.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 705c4f562758..72d7ed17eef5 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -373,8 +373,10 @@ xfs_dir2_leaf_to_node( leaf = lbp->b_addr; ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); if (be32_to_cpu(ltp->bestcount) > - (uint)dp->i_d.di_size / args->geo->blksize) + (uint)dp->i_d.di_size / args->geo->blksize) { + xfs_buf_corruption_error(lbp); return -EFSCORRUPTED; + } /* * Copy freespace entries from the leaf block to the new block. @@ -445,8 +447,10 @@ xfs_dir2_leafn_add( * Quick check just to make sure we are not going to index * into other peoples memory */ - if (index < 0) + if (index < 0) { + xfs_buf_corruption_error(bp); return -EFSCORRUPTED; + } /* * If there are already the maximum number of leaf entries in @@ -739,8 +743,10 @@ xfs_dir2_leafn_lookup_for_entry( ents = dp->d_ops->leaf_ents_p(leaf); xfs_dir3_leaf_check(dp, bp); - if (leafhdr.count <= 0) + if (leafhdr.count <= 0) { + xfs_buf_corruption_error(bp); return -EFSCORRUPTED; + } /* * Look up the hash value in the leaf entries. -- cgit v1.2.3-70-g09d2 From 518425560a8b6ec7516505846c1b79623b467148 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 14:57:49 -0800 Subject: xfs: devirtualize ->leaf_hdr_from_disk Replace the ->leaf_hdr_from_disk dir ops method with a directly called xfs_dir2_leaf_hdr_from_disk helper that takes care of the differences between the v4 and v5 on-disk format. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_btree.c | 5 +++-- fs/xfs/libxfs/xfs_da_format.c | 35 -------------------------------- fs/xfs/libxfs/xfs_dir2.h | 2 -- fs/xfs/libxfs/xfs_dir2_block.c | 2 +- fs/xfs/libxfs/xfs_dir2_leaf.c | 45 ++++++++++++++++++++++++++++++++++-------- fs/xfs/libxfs/xfs_dir2_node.c | 28 +++++++++++++------------- fs/xfs/libxfs/xfs_dir2_priv.h | 2 ++ fs/xfs/scrub/dir.c | 2 +- 8 files changed, 58 insertions(+), 63 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 34928c96ea5f..1742e8293574 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -643,7 +643,7 @@ xfs_da3_root_split( struct xfs_dir2_leaf_entry *ents; leaf = (xfs_dir2_leaf_t *)oldroot; - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); ents = dp->d_ops->leaf_ents_p(leaf); ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || @@ -2295,7 +2295,8 @@ xfs_da3_swap_lastblock( struct xfs_dir2_leaf_entry *ents; dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; - dp->d_ops->leaf_hdr_from_disk(&leafhdr, dead_leaf2); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, + dead_leaf2); ents = dp->d_ops->leaf_ents_p(dead_leaf2); dead_level = 0; dead_hash = be32_to_cpu(ents[leafhdr.count - 1].hashval); diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index 68dff1de61e9..c848cab41be5 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -430,21 +430,6 @@ xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp) return ((struct xfs_dir3_leaf *)lp)->__ents; } -static void -xfs_dir2_leaf_hdr_from_disk( - struct xfs_dir3_icleaf_hdr *to, - struct xfs_dir2_leaf *from) -{ - to->forw = be32_to_cpu(from->hdr.info.forw); - to->back = be32_to_cpu(from->hdr.info.back); - to->magic = be16_to_cpu(from->hdr.info.magic); - to->count = be16_to_cpu(from->hdr.count); - to->stale = be16_to_cpu(from->hdr.stale); - - ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC || - to->magic == XFS_DIR2_LEAFN_MAGIC); -} - static void xfs_dir2_leaf_hdr_to_disk( struct xfs_dir2_leaf *to, @@ -460,23 +445,6 @@ xfs_dir2_leaf_hdr_to_disk( to->hdr.stale = cpu_to_be16(from->stale); } -static void -xfs_dir3_leaf_hdr_from_disk( - struct xfs_dir3_icleaf_hdr *to, - struct xfs_dir2_leaf *from) -{ - struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)from; - - to->forw = be32_to_cpu(hdr3->info.hdr.forw); - to->back = be32_to_cpu(hdr3->info.hdr.back); - to->magic = be16_to_cpu(hdr3->info.hdr.magic); - to->count = be16_to_cpu(hdr3->count); - to->stale = be16_to_cpu(hdr3->stale); - - ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC || - to->magic == XFS_DIR3_LEAFN_MAGIC); -} - static void xfs_dir3_leaf_hdr_to_disk( struct xfs_dir2_leaf *to, @@ -648,7 +616,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr), .leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk, - .leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk, .leaf_max_ents = xfs_dir2_max_leaf_ents, .leaf_ents_p = xfs_dir2_leaf_ents_p, @@ -693,7 +660,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr), .leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk, - .leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk, .leaf_max_ents = xfs_dir2_max_leaf_ents, .leaf_ents_p = xfs_dir2_leaf_ents_p, @@ -738,7 +704,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = { .leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr), .leaf_hdr_to_disk = xfs_dir3_leaf_hdr_to_disk, - .leaf_hdr_from_disk = xfs_dir3_leaf_hdr_from_disk, .leaf_max_ents = xfs_dir3_max_leaf_ents, .leaf_ents_p = xfs_dir3_leaf_ents_p, diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index 87fe876e90ed..74c592496bf0 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -75,8 +75,6 @@ struct xfs_dir_ops { int leaf_hdr_size; void (*leaf_hdr_to_disk)(struct xfs_dir2_leaf *to, struct xfs_dir3_icleaf_hdr *from); - void (*leaf_hdr_from_disk)(struct xfs_dir3_icleaf_hdr *to, - struct xfs_dir2_leaf *from); int (*leaf_max_ents)(struct xfs_da_geometry *geo); struct xfs_dir2_leaf_entry * (*leaf_ents_p)(struct xfs_dir2_leaf *lp); diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index e1afa35141c5..d9ad89f6fd79 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -923,7 +923,7 @@ xfs_dir2_leaf_to_block( tp = args->trans; mp = dp->i_mount; leaf = lbp->b_addr; - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); ents = dp->d_ops->leaf_ents_p(leaf); ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index 388b5da12228..b27609c852c5 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -30,6 +30,35 @@ static void xfs_dir3_leaf_log_bests(struct xfs_da_args *args, static void xfs_dir3_leaf_log_tail(struct xfs_da_args *args, struct xfs_buf *bp); +void +xfs_dir2_leaf_hdr_from_disk( + struct xfs_mount *mp, + struct xfs_dir3_icleaf_hdr *to, + struct xfs_dir2_leaf *from) +{ + if (xfs_sb_version_hascrc(&mp->m_sb)) { + struct xfs_dir3_leaf *from3 = (struct xfs_dir3_leaf *)from; + + to->forw = be32_to_cpu(from3->hdr.info.hdr.forw); + to->back = be32_to_cpu(from3->hdr.info.hdr.back); + to->magic = be16_to_cpu(from3->hdr.info.hdr.magic); + to->count = be16_to_cpu(from3->hdr.count); + to->stale = be16_to_cpu(from3->hdr.stale); + + ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC || + to->magic == XFS_DIR3_LEAFN_MAGIC); + } else { + to->forw = be32_to_cpu(from->hdr.info.forw); + to->back = be32_to_cpu(from->hdr.info.back); + to->magic = be16_to_cpu(from->hdr.info.magic); + to->count = be16_to_cpu(from->hdr.count); + to->stale = be16_to_cpu(from->hdr.stale); + + ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC || + to->magic == XFS_DIR2_LEAFN_MAGIC); + } +} + /* * Check the internal consistency of a leaf1 block. * Pop an assert if something is wrong. @@ -43,7 +72,7 @@ xfs_dir3_leaf1_check( struct xfs_dir2_leaf *leaf = bp->b_addr; struct xfs_dir3_icleaf_hdr leafhdr; - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); if (leafhdr.magic == XFS_DIR3_LEAF1_MAGIC) { struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr; @@ -96,7 +125,7 @@ xfs_dir3_leaf_check_int( ops = xfs_dir_get_ops(mp, dp); if (!hdr) { - ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); hdr = &leafhdr; } @@ -381,7 +410,7 @@ xfs_dir2_block_to_leaf( /* * Set the counts in the leaf header. */ - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); leafhdr.count = be32_to_cpu(btp->count); leafhdr.stale = be32_to_cpu(btp->stale); dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); @@ -608,7 +637,7 @@ xfs_dir2_leaf_addname( leaf = lbp->b_addr; ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); ents = dp->d_ops->leaf_ents_p(leaf); - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); bestsp = xfs_dir2_leaf_bests_p(ltp); length = dp->d_ops->data_entsize(args->namelen); @@ -1197,7 +1226,7 @@ xfs_dir2_leaf_lookup_int( leaf = lbp->b_addr; xfs_dir3_leaf_check(dp, lbp); ents = dp->d_ops->leaf_ents_p(leaf); - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); /* * Look for the first leaf entry with our hash value. @@ -1330,7 +1359,7 @@ xfs_dir2_leaf_removename( hdr = dbp->b_addr; xfs_dir3_data_check(dp, dbp); bf = dp->d_ops->data_bestfree_p(hdr); - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); ents = dp->d_ops->leaf_ents_p(leaf); /* * Point to the leaf entry, use that to point to the data entry. @@ -1511,7 +1540,7 @@ xfs_dir2_leaf_search_hash( leaf = lbp->b_addr; ents = args->dp->d_ops->leaf_ents_p(leaf); - args->dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(args->dp->i_mount, &leafhdr, leaf); /* * Note, the table cannot be empty, so we have to go through the loop. @@ -1699,7 +1728,7 @@ xfs_dir2_node_to_leaf( return 0; lbp = state->path.blk[0].bp; leaf = lbp->b_addr; - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || leafhdr.magic == XFS_DIR3_LEAFN_MAGIC); diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 72d7ed17eef5..d4402b491a41 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -45,7 +45,7 @@ xfs_dir3_leafn_check( struct xfs_dir2_leaf *leaf = bp->b_addr; struct xfs_dir3_icleaf_hdr leafhdr; - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); if (leafhdr.magic == XFS_DIR3_LEAFN_MAGIC) { struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr; @@ -440,7 +440,7 @@ xfs_dir2_leafn_add( trace_xfs_dir2_leafn_add(args, index); - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); ents = dp->d_ops->leaf_ents_p(leaf); /* @@ -538,7 +538,7 @@ xfs_dir2_leaf_lasthash( struct xfs_dir2_leaf_entry *ents; struct xfs_dir3_icleaf_hdr leafhdr; - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || leafhdr.magic == XFS_DIR3_LEAFN_MAGIC || @@ -587,7 +587,7 @@ xfs_dir2_leafn_lookup_for_addname( tp = args->trans; mp = dp->i_mount; leaf = bp->b_addr; - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); ents = dp->d_ops->leaf_ents_p(leaf); xfs_dir3_leaf_check(dp, bp); @@ -739,7 +739,7 @@ xfs_dir2_leafn_lookup_for_entry( tp = args->trans; mp = dp->i_mount; leaf = bp->b_addr; - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); ents = dp->d_ops->leaf_ents_p(leaf); xfs_dir3_leaf_check(dp, bp); @@ -977,8 +977,8 @@ xfs_dir2_leafn_order( struct xfs_dir3_icleaf_hdr hdr1; struct xfs_dir3_icleaf_hdr hdr2; - dp->d_ops->leaf_hdr_from_disk(&hdr1, leaf1); - dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf2); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr1, leaf1); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf2); ents1 = dp->d_ops->leaf_ents_p(leaf1); ents2 = dp->d_ops->leaf_ents_p(leaf2); @@ -1030,8 +1030,8 @@ xfs_dir2_leafn_rebalance( leaf1 = blk1->bp->b_addr; leaf2 = blk2->bp->b_addr; - dp->d_ops->leaf_hdr_from_disk(&hdr1, leaf1); - dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf2); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr1, leaf1); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf2); ents1 = dp->d_ops->leaf_ents_p(leaf1); ents2 = dp->d_ops->leaf_ents_p(leaf2); @@ -1228,7 +1228,7 @@ xfs_dir2_leafn_remove( dp = args->dp; tp = args->trans; leaf = bp->b_addr; - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); ents = dp->d_ops->leaf_ents_p(leaf); /* @@ -1450,7 +1450,7 @@ xfs_dir2_leafn_toosmall( */ blk = &state->path.blk[state->path.active - 1]; leaf = blk->bp->b_addr; - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); ents = dp->d_ops->leaf_ents_p(leaf); xfs_dir3_leaf_check(dp, blk->bp); @@ -1513,7 +1513,7 @@ xfs_dir2_leafn_toosmall( (state->args->geo->blksize >> 2); leaf = bp->b_addr; - dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf); ents = dp->d_ops->leaf_ents_p(leaf); count += hdr2.count - hdr2.stale; bytes -= count * sizeof(ents[0]); @@ -1576,8 +1576,8 @@ xfs_dir2_leafn_unbalance( drop_leaf = drop_blk->bp->b_addr; save_leaf = save_blk->bp->b_addr; - dp->d_ops->leaf_hdr_from_disk(&savehdr, save_leaf); - dp->d_ops->leaf_hdr_from_disk(&drophdr, drop_leaf); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &savehdr, save_leaf); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &drophdr, drop_leaf); sents = dp->d_ops->leaf_ents_p(save_leaf); dents = dp->d_ops->leaf_ents_p(drop_leaf); diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index d2eaea663e7f..5f42f2c81869 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h @@ -66,6 +66,8 @@ extern int xfs_dir3_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno, struct xfs_buf **bpp); /* xfs_dir2_leaf.c */ +void xfs_dir2_leaf_hdr_from_disk(struct xfs_mount *mp, + struct xfs_dir3_icleaf_hdr *to, struct xfs_dir2_leaf *from); extern int xfs_dir3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, xfs_dablk_t fbno, xfs_daddr_t mappedbno, struct xfs_buf **bpp); extern int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp, diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index 19e1aae92a75..580927df287b 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -507,7 +507,7 @@ xchk_directory_leaf1_bestfree( xchk_buffer_recheck(sc, bp); leaf = bp->b_addr; - d_ops->leaf_hdr_from_disk(&leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(sc->ip->i_mount, &leafhdr, leaf); ents = d_ops->leaf_ents_p(leaf); ltp = xfs_dir2_leaf_tail_p(geo, leaf); bestcount = be32_to_cpu(ltp->bestcount); -- cgit v1.2.3-70-g09d2 From 163fbbb3568b6acf762449b8aa7713c764cf860a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 14:57:50 -0800 Subject: xfs: devirtualize ->leaf_hdr_to_disk Replace the ->leaf_hdr_to_disk dir ops method with a directly called xfs_dir_leaf_hdr_to_disk helper that takes care of the differences between the v4 and v5 on-disk format. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_format.c | 35 ----------------------------------- fs/xfs/libxfs/xfs_dir2.h | 2 -- fs/xfs/libxfs/xfs_dir2_leaf.c | 39 ++++++++++++++++++++++++++++++++++----- fs/xfs/libxfs/xfs_dir2_node.c | 12 ++++++------ fs/xfs/libxfs/xfs_dir2_priv.h | 2 ++ 5 files changed, 42 insertions(+), 48 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index c848cab41be5..193708d12459 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -430,38 +430,6 @@ xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp) return ((struct xfs_dir3_leaf *)lp)->__ents; } -static void -xfs_dir2_leaf_hdr_to_disk( - struct xfs_dir2_leaf *to, - struct xfs_dir3_icleaf_hdr *from) -{ - ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC || - from->magic == XFS_DIR2_LEAFN_MAGIC); - - to->hdr.info.forw = cpu_to_be32(from->forw); - to->hdr.info.back = cpu_to_be32(from->back); - to->hdr.info.magic = cpu_to_be16(from->magic); - to->hdr.count = cpu_to_be16(from->count); - to->hdr.stale = cpu_to_be16(from->stale); -} - -static void -xfs_dir3_leaf_hdr_to_disk( - struct xfs_dir2_leaf *to, - struct xfs_dir3_icleaf_hdr *from) -{ - struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)to; - - ASSERT(from->magic == XFS_DIR3_LEAF1_MAGIC || - from->magic == XFS_DIR3_LEAFN_MAGIC); - - hdr3->info.hdr.forw = cpu_to_be32(from->forw); - hdr3->info.hdr.back = cpu_to_be32(from->back); - hdr3->info.hdr.magic = cpu_to_be16(from->magic); - hdr3->count = cpu_to_be16(from->count); - hdr3->stale = cpu_to_be16(from->stale); -} - /* * Directory free space block operations */ @@ -615,7 +583,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { .data_unused_p = xfs_dir2_data_unused_p, .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr), - .leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk, .leaf_max_ents = xfs_dir2_max_leaf_ents, .leaf_ents_p = xfs_dir2_leaf_ents_p, @@ -659,7 +626,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .data_unused_p = xfs_dir2_data_unused_p, .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr), - .leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk, .leaf_max_ents = xfs_dir2_max_leaf_ents, .leaf_ents_p = xfs_dir2_leaf_ents_p, @@ -703,7 +669,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = { .data_unused_p = xfs_dir3_data_unused_p, .leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr), - .leaf_hdr_to_disk = xfs_dir3_leaf_hdr_to_disk, .leaf_max_ents = xfs_dir3_max_leaf_ents, .leaf_ents_p = xfs_dir3_leaf_ents_p, diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index 74c592496bf0..15a1a72dc126 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -73,8 +73,6 @@ struct xfs_dir_ops { (*data_unused_p)(struct xfs_dir2_data_hdr *hdr); int leaf_hdr_size; - void (*leaf_hdr_to_disk)(struct xfs_dir2_leaf *to, - struct xfs_dir3_icleaf_hdr *from); int (*leaf_max_ents)(struct xfs_da_geometry *geo); struct xfs_dir2_leaf_entry * (*leaf_ents_p)(struct xfs_dir2_leaf *lp); diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index b27609c852c5..07734c0fe8a7 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -59,6 +59,35 @@ xfs_dir2_leaf_hdr_from_disk( } } +void +xfs_dir2_leaf_hdr_to_disk( + struct xfs_mount *mp, + struct xfs_dir2_leaf *to, + struct xfs_dir3_icleaf_hdr *from) +{ + if (xfs_sb_version_hascrc(&mp->m_sb)) { + struct xfs_dir3_leaf *to3 = (struct xfs_dir3_leaf *)to; + + ASSERT(from->magic == XFS_DIR3_LEAF1_MAGIC || + from->magic == XFS_DIR3_LEAFN_MAGIC); + + to3->hdr.info.hdr.forw = cpu_to_be32(from->forw); + to3->hdr.info.hdr.back = cpu_to_be32(from->back); + to3->hdr.info.hdr.magic = cpu_to_be16(from->magic); + to3->hdr.count = cpu_to_be16(from->count); + to3->hdr.stale = cpu_to_be16(from->stale); + } else { + ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC || + from->magic == XFS_DIR2_LEAFN_MAGIC); + + to->hdr.info.forw = cpu_to_be32(from->forw); + to->hdr.info.back = cpu_to_be32(from->back); + to->hdr.info.magic = cpu_to_be16(from->magic); + to->hdr.count = cpu_to_be16(from->count); + to->hdr.stale = cpu_to_be16(from->stale); + } +} + /* * Check the internal consistency of a leaf1 block. * Pop an assert if something is wrong. @@ -413,7 +442,7 @@ xfs_dir2_block_to_leaf( xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); leafhdr.count = be32_to_cpu(btp->count); leafhdr.stale = be32_to_cpu(btp->stale); - dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); xfs_dir3_leaf_log_header(args, lbp); /* @@ -881,7 +910,7 @@ xfs_dir2_leaf_addname( /* * Log the leaf fields and give up the buffers. */ - dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); xfs_dir3_leaf_log_header(args, lbp); xfs_dir3_leaf_log_ents(args, lbp, lfloglow, lfloghigh); xfs_dir3_leaf_check(dp, lbp); @@ -934,7 +963,7 @@ xfs_dir3_leaf_compact( leafhdr->count -= leafhdr->stale; leafhdr->stale = 0; - dp->d_ops->leaf_hdr_to_disk(leaf, leafhdr); + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, leafhdr); xfs_dir3_leaf_log_header(args, bp); if (loglow != -1) xfs_dir3_leaf_log_ents(args, bp, loglow, to - 1); @@ -1386,7 +1415,7 @@ xfs_dir2_leaf_removename( * We just mark the leaf entry stale by putting a null in it. */ leafhdr.stale++; - dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); xfs_dir3_leaf_log_header(args, lbp); lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); @@ -1777,7 +1806,7 @@ xfs_dir2_node_to_leaf( memcpy(xfs_dir2_leaf_bests_p(ltp), dp->d_ops->free_bests_p(free), freehdr.nvalid * sizeof(xfs_dir2_data_off_t)); - dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); + xfs_dir2_leaf_hdr_to_disk(mp, leaf, &leafhdr); xfs_dir3_leaf_log_header(args, lbp); xfs_dir3_leaf_log_bests(args, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); xfs_dir3_leaf_log_tail(args, lbp); diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index d4402b491a41..98cd645a8c99 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -497,7 +497,7 @@ xfs_dir2_leafn_add( lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(args->geo, args->blkno, args->index)); - dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); xfs_dir3_leaf_log_header(args, bp); xfs_dir3_leaf_log_ents(args, bp, lfloglow, lfloghigh); xfs_dir3_leaf_check(dp, bp); @@ -1079,8 +1079,8 @@ xfs_dir2_leafn_rebalance( ASSERT(hdr1.stale + hdr2.stale == oldstale); /* log the changes made when moving the entries */ - dp->d_ops->leaf_hdr_to_disk(leaf1, &hdr1); - dp->d_ops->leaf_hdr_to_disk(leaf2, &hdr2); + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf1, &hdr1); + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf2, &hdr2); xfs_dir3_leaf_log_header(args, blk1->bp); xfs_dir3_leaf_log_header(args, blk2->bp); @@ -1249,7 +1249,7 @@ xfs_dir2_leafn_remove( * Log the leaf block changes. */ leafhdr.stale++; - dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); xfs_dir3_leaf_log_header(args, bp); lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); @@ -1605,8 +1605,8 @@ xfs_dir2_leafn_unbalance( save_blk->hashval = be32_to_cpu(sents[savehdr.count - 1].hashval); /* log the changes made when moving the entries */ - dp->d_ops->leaf_hdr_to_disk(save_leaf, &savehdr); - dp->d_ops->leaf_hdr_to_disk(drop_leaf, &drophdr); + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, save_leaf, &savehdr); + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, drop_leaf, &drophdr); xfs_dir3_leaf_log_header(args, save_blk->bp); xfs_dir3_leaf_log_header(args, drop_blk->bp); diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index 5f42f2c81869..af96e3faefaf 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h @@ -68,6 +68,8 @@ extern int xfs_dir3_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno, /* xfs_dir2_leaf.c */ void xfs_dir2_leaf_hdr_from_disk(struct xfs_mount *mp, struct xfs_dir3_icleaf_hdr *to, struct xfs_dir2_leaf *from); +void xfs_dir2_leaf_hdr_to_disk(struct xfs_mount *mp, struct xfs_dir2_leaf *to, + struct xfs_dir3_icleaf_hdr *from); extern int xfs_dir3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, xfs_dablk_t fbno, xfs_daddr_t mappedbno, struct xfs_buf **bpp); extern int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp, -- cgit v1.2.3-70-g09d2 From 787b0893ad1e315ea014dc3f0e01a5bc9236c623 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 14:57:50 -0800 Subject: xfs: add an entries pointer to struct xfs_dir3_icleaf_hdr All callers of the ->node_tree_p dir operation already have a struct xfs_dir3_icleaf_hdr from a previous call to xfs_da_leaf_hdr_from_disk at hand, or just need slight changes to the calling conventions to do so. Add a pointer to the entries to struct xfs_dir3_icleaf_hdr to clean up this pattern. To make this possible the xfs_dir3_leaf_log_ents function grow a new argument to pass the xfs_dir3_icleaf_hdr that call callers already have, and xfs_dir2_leaf_lookup_int returns the xfs_dir3_icleaf_hdr to the callers so that they can later use it. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_btree.c | 7 ++- fs/xfs/libxfs/xfs_da_format.c | 15 ------ fs/xfs/libxfs/xfs_dir2.h | 2 - fs/xfs/libxfs/xfs_dir2_block.c | 7 ++- fs/xfs/libxfs/xfs_dir2_leaf.c | 101 ++++++++++++++++++----------------------- fs/xfs/libxfs/xfs_dir2_node.c | 64 +++++++++++--------------- fs/xfs/libxfs/xfs_dir2_priv.h | 9 +++- fs/xfs/scrub/dir.c | 14 +++--- 8 files changed, 93 insertions(+), 126 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 1742e8293574..46b1c3fb305c 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -640,15 +640,14 @@ xfs_da3_root_split( xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DA_NODE_BUF); } else { struct xfs_dir3_icleaf_hdr leafhdr; - struct xfs_dir2_leaf_entry *ents; leaf = (xfs_dir2_leaf_t *)oldroot; xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); - ents = dp->d_ops->leaf_ents_p(leaf); ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || leafhdr.magic == XFS_DIR3_LEAFN_MAGIC); - size = (int)((char *)&ents[leafhdr.count] - (char *)leaf); + size = (int)((char *)&leafhdr.ents[leafhdr.count] - + (char *)leaf); level = 0; /* @@ -2297,7 +2296,7 @@ xfs_da3_swap_lastblock( dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, dead_leaf2); - ents = dp->d_ops->leaf_ents_p(dead_leaf2); + ents = leafhdr.ents; dead_level = 0; dead_hash = be32_to_cpu(ents[leafhdr.count - 1].hashval); } else { diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index 193708d12459..ed21ce01502f 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -411,12 +411,6 @@ xfs_dir2_max_leaf_ents(struct xfs_da_geometry *geo) (uint)sizeof(struct xfs_dir2_leaf_entry); } -static struct xfs_dir2_leaf_entry * -xfs_dir2_leaf_ents_p(struct xfs_dir2_leaf *lp) -{ - return lp->__ents; -} - static int xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo) { @@ -424,12 +418,6 @@ xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo) (uint)sizeof(struct xfs_dir2_leaf_entry); } -static struct xfs_dir2_leaf_entry * -xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp) -{ - return ((struct xfs_dir3_leaf *)lp)->__ents; -} - /* * Directory free space block operations */ @@ -584,7 +572,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr), .leaf_max_ents = xfs_dir2_max_leaf_ents, - .leaf_ents_p = xfs_dir2_leaf_ents_p, .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk, @@ -627,7 +614,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr), .leaf_max_ents = xfs_dir2_max_leaf_ents, - .leaf_ents_p = xfs_dir2_leaf_ents_p, .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk, @@ -670,7 +656,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = { .leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr), .leaf_max_ents = xfs_dir3_max_leaf_ents, - .leaf_ents_p = xfs_dir3_leaf_ents_p, .free_hdr_size = sizeof(struct xfs_dir3_free_hdr), .free_hdr_to_disk = xfs_dir3_free_hdr_to_disk, diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index 15a1a72dc126..b46657974134 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -74,8 +74,6 @@ struct xfs_dir_ops { int leaf_hdr_size; int (*leaf_max_ents)(struct xfs_da_geometry *geo); - struct xfs_dir2_leaf_entry * - (*leaf_ents_p)(struct xfs_dir2_leaf *lp); int free_hdr_size; void (*free_hdr_to_disk)(struct xfs_dir2_free *to, diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index d9ad89f6fd79..065fe10a842b 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -914,7 +914,6 @@ xfs_dir2_leaf_to_block( __be16 *tagp; /* end of entry (tag) */ int to; /* block/leaf to index */ xfs_trans_t *tp; /* transaction pointer */ - struct xfs_dir2_leaf_entry *ents; struct xfs_dir3_icleaf_hdr leafhdr; trace_xfs_dir2_leaf_to_block(args); @@ -924,7 +923,6 @@ xfs_dir2_leaf_to_block( mp = dp->i_mount; leaf = lbp->b_addr; xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); - ents = dp->d_ops->leaf_ents_p(leaf); ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); ASSERT(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC || @@ -1004,9 +1002,10 @@ xfs_dir2_leaf_to_block( */ lep = xfs_dir2_block_leaf_p(btp); for (from = to = 0; from < leafhdr.count; from++) { - if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) + if (leafhdr.ents[from].address == + cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) continue; - lep[to++] = ents[from]; + lep[to++] = leafhdr.ents[from]; } ASSERT(to == be32_to_cpu(btp->count)); xfs_dir2_block_log_leaf(tp, dbp, 0, be32_to_cpu(btp->count) - 1); diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index 07734c0fe8a7..5e3e96efdaca 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -24,7 +24,8 @@ * Local function declarations. */ static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, struct xfs_buf **lbpp, - int *indexp, struct xfs_buf **dbpp); + int *indexp, struct xfs_buf **dbpp, + struct xfs_dir3_icleaf_hdr *leafhdr); static void xfs_dir3_leaf_log_bests(struct xfs_da_args *args, struct xfs_buf *bp, int first, int last); static void xfs_dir3_leaf_log_tail(struct xfs_da_args *args, @@ -44,6 +45,7 @@ xfs_dir2_leaf_hdr_from_disk( to->magic = be16_to_cpu(from3->hdr.info.hdr.magic); to->count = be16_to_cpu(from3->hdr.count); to->stale = be16_to_cpu(from3->hdr.stale); + to->ents = from3->__ents; ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC || to->magic == XFS_DIR3_LEAFN_MAGIC); @@ -53,6 +55,7 @@ xfs_dir2_leaf_hdr_from_disk( to->magic = be16_to_cpu(from->hdr.info.magic); to->count = be16_to_cpu(from->hdr.count); to->stale = be16_to_cpu(from->hdr.stale); + to->ents = from->__ents; ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC || to->magic == XFS_DIR2_LEAFN_MAGIC); @@ -139,7 +142,6 @@ xfs_dir3_leaf_check_int( struct xfs_dir3_icleaf_hdr *hdr, struct xfs_dir2_leaf *leaf) { - struct xfs_dir2_leaf_entry *ents; xfs_dir2_leaf_tail_t *ltp; int stale; int i; @@ -158,7 +160,6 @@ xfs_dir3_leaf_check_int( hdr = &leafhdr; } - ents = ops->leaf_ents_p(leaf); ltp = xfs_dir2_leaf_tail_p(geo, leaf); /* @@ -172,17 +173,17 @@ xfs_dir3_leaf_check_int( /* Leaves and bests don't overlap in leaf format. */ if ((hdr->magic == XFS_DIR2_LEAF1_MAGIC || hdr->magic == XFS_DIR3_LEAF1_MAGIC) && - (char *)&ents[hdr->count] > (char *)xfs_dir2_leaf_bests_p(ltp)) + (char *)&hdr->ents[hdr->count] > (char *)xfs_dir2_leaf_bests_p(ltp)) return __this_address; /* Check hash value order, count stale entries. */ for (i = stale = 0; i < hdr->count; i++) { if (i + 1 < hdr->count) { - if (be32_to_cpu(ents[i].hashval) > - be32_to_cpu(ents[i + 1].hashval)) + if (be32_to_cpu(hdr->ents[i].hashval) > + be32_to_cpu(hdr->ents[i + 1].hashval)) return __this_address; } - if (ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) + if (hdr->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) stale++; } if (hdr->stale != stale) @@ -404,7 +405,6 @@ xfs_dir2_block_to_leaf( int needscan; /* need to rescan bestfree */ xfs_trans_t *tp; /* transaction pointer */ struct xfs_dir2_data_free *bf; - struct xfs_dir2_leaf_entry *ents; struct xfs_dir3_icleaf_hdr leafhdr; trace_xfs_dir2_block_to_leaf(args); @@ -434,7 +434,6 @@ xfs_dir2_block_to_leaf( btp = xfs_dir2_block_tail_p(args->geo, hdr); blp = xfs_dir2_block_leaf_p(btp); bf = dp->d_ops->data_bestfree_p(hdr); - ents = dp->d_ops->leaf_ents_p(leaf); /* * Set the counts in the leaf header. @@ -449,8 +448,9 @@ xfs_dir2_block_to_leaf( * Could compact these but I think we always do the conversion * after squeezing out stale entries. */ - memcpy(ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t)); - xfs_dir3_leaf_log_ents(args, lbp, 0, leafhdr.count - 1); + memcpy(leafhdr.ents, blp, + be32_to_cpu(btp->count) * sizeof(struct xfs_dir2_leaf_entry)); + xfs_dir3_leaf_log_ents(args, &leafhdr, lbp, 0, leafhdr.count - 1); needscan = 0; needlog = 1; /* @@ -665,8 +665,8 @@ xfs_dir2_leaf_addname( index = xfs_dir2_leaf_search_hash(args, lbp); leaf = lbp->b_addr; ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); - ents = dp->d_ops->leaf_ents_p(leaf); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); + ents = leafhdr.ents; bestsp = xfs_dir2_leaf_bests_p(ltp); length = dp->d_ops->data_entsize(args->namelen); @@ -912,7 +912,7 @@ xfs_dir2_leaf_addname( */ xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); xfs_dir3_leaf_log_header(args, lbp); - xfs_dir3_leaf_log_ents(args, lbp, lfloglow, lfloghigh); + xfs_dir3_leaf_log_ents(args, &leafhdr, lbp, lfloglow, lfloghigh); xfs_dir3_leaf_check(dp, lbp); xfs_dir3_data_check(dp, dbp); return 0; @@ -932,7 +932,6 @@ xfs_dir3_leaf_compact( xfs_dir2_leaf_t *leaf; /* leaf structure */ int loglow; /* first leaf entry to log */ int to; /* target leaf index */ - struct xfs_dir2_leaf_entry *ents; struct xfs_inode *dp = args->dp; leaf = bp->b_addr; @@ -942,9 +941,9 @@ xfs_dir3_leaf_compact( /* * Compress out the stale entries in place. */ - ents = dp->d_ops->leaf_ents_p(leaf); for (from = to = 0, loglow = -1; from < leafhdr->count; from++) { - if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) + if (leafhdr->ents[from].address == + cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) continue; /* * Only actually copy the entries that are different. @@ -952,7 +951,7 @@ xfs_dir3_leaf_compact( if (from > to) { if (loglow == -1) loglow = to; - ents[to] = ents[from]; + leafhdr->ents[to] = leafhdr->ents[from]; } to++; } @@ -966,7 +965,7 @@ xfs_dir3_leaf_compact( xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, leafhdr); xfs_dir3_leaf_log_header(args, bp); if (loglow != -1) - xfs_dir3_leaf_log_ents(args, bp, loglow, to - 1); + xfs_dir3_leaf_log_ents(args, leafhdr, bp, loglow, to - 1); } /* @@ -1095,6 +1094,7 @@ xfs_dir3_leaf_log_bests( void xfs_dir3_leaf_log_ents( struct xfs_da_args *args, + struct xfs_dir3_icleaf_hdr *hdr, struct xfs_buf *bp, int first, int last) @@ -1102,16 +1102,14 @@ xfs_dir3_leaf_log_ents( xfs_dir2_leaf_entry_t *firstlep; /* pointer to first entry */ xfs_dir2_leaf_entry_t *lastlep; /* pointer to last entry */ struct xfs_dir2_leaf *leaf = bp->b_addr; - struct xfs_dir2_leaf_entry *ents; ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) || leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)); - ents = args->dp->d_ops->leaf_ents_p(leaf); - firstlep = &ents[first]; - lastlep = &ents[last]; + firstlep = &hdr->ents[first]; + lastlep = &hdr->ents[last]; xfs_trans_log_buf(args->trans, bp, (uint)((char *)firstlep - (char *)leaf), (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1)); @@ -1173,28 +1171,27 @@ xfs_dir2_leaf_lookup( int error; /* error return code */ int index; /* found entry index */ struct xfs_buf *lbp; /* leaf buffer */ - xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_trans_t *tp; /* transaction pointer */ - struct xfs_dir2_leaf_entry *ents; + struct xfs_dir3_icleaf_hdr leafhdr; trace_xfs_dir2_leaf_lookup(args); /* * Look up name in the leaf block, returning both buffers and index. */ - if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { + error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp, &leafhdr); + if (error) return error; - } + tp = args->trans; dp = args->dp; xfs_dir3_leaf_check(dp, lbp); - leaf = lbp->b_addr; - ents = dp->d_ops->leaf_ents_p(leaf); + /* * Get to the leaf entry and contained data entry address. */ - lep = &ents[index]; + lep = &leafhdr.ents[index]; /* * Point to the data entry. @@ -1224,7 +1221,8 @@ xfs_dir2_leaf_lookup_int( xfs_da_args_t *args, /* operation arguments */ struct xfs_buf **lbpp, /* out: leaf buffer */ int *indexp, /* out: index in leaf block */ - struct xfs_buf **dbpp) /* out: data buffer */ + struct xfs_buf **dbpp, /* out: data buffer */ + struct xfs_dir3_icleaf_hdr *leafhdr) { xfs_dir2_db_t curdb = -1; /* current data block number */ struct xfs_buf *dbp = NULL; /* data buffer */ @@ -1240,8 +1238,6 @@ xfs_dir2_leaf_lookup_int( xfs_trans_t *tp; /* transaction pointer */ xfs_dir2_db_t cidb = -1; /* case match data block no. */ enum xfs_dacmp cmp; /* name compare result */ - struct xfs_dir2_leaf_entry *ents; - struct xfs_dir3_icleaf_hdr leafhdr; dp = args->dp; tp = args->trans; @@ -1254,8 +1250,7 @@ xfs_dir2_leaf_lookup_int( *lbpp = lbp; leaf = lbp->b_addr; xfs_dir3_leaf_check(dp, lbp); - ents = dp->d_ops->leaf_ents_p(leaf); - xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(mp, leafhdr, leaf); /* * Look for the first leaf entry with our hash value. @@ -1265,8 +1260,9 @@ xfs_dir2_leaf_lookup_int( * Loop over all the entries with the right hash value * looking to match the name. */ - for (lep = &ents[index]; - index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; + for (lep = &leafhdr->ents[index]; + index < leafhdr->count && + be32_to_cpu(lep->hashval) == args->hashval; lep++, index++) { /* * Skip over stale leaf entries. @@ -1372,7 +1368,6 @@ xfs_dir2_leaf_removename( int needscan; /* need to rescan data frees */ xfs_dir2_data_off_t oldbest; /* old value of best free */ struct xfs_dir2_data_free *bf; /* bestfree table */ - struct xfs_dir2_leaf_entry *ents; struct xfs_dir3_icleaf_hdr leafhdr; trace_xfs_dir2_leaf_removename(args); @@ -1380,20 +1375,20 @@ xfs_dir2_leaf_removename( /* * Lookup the leaf entry, get the leaf and data blocks read in. */ - if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { + error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp, &leafhdr); + if (error) return error; - } + dp = args->dp; leaf = lbp->b_addr; hdr = dbp->b_addr; xfs_dir3_data_check(dp, dbp); bf = dp->d_ops->data_bestfree_p(hdr); - xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); - ents = dp->d_ops->leaf_ents_p(leaf); + /* * Point to the leaf entry, use that to point to the data entry. */ - lep = &ents[index]; + lep = &leafhdr.ents[index]; db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address)); dep = (xfs_dir2_data_entry_t *)((char *)hdr + xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address))); @@ -1419,7 +1414,7 @@ xfs_dir2_leaf_removename( xfs_dir3_leaf_log_header(args, lbp); lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); - xfs_dir3_leaf_log_ents(args, lbp, index, index); + xfs_dir3_leaf_log_ents(args, &leafhdr, lbp, index, index); /* * Scan the freespace in the data block again if necessary, @@ -1508,26 +1503,24 @@ xfs_dir2_leaf_replace( int error; /* error return code */ int index; /* index of leaf entry */ struct xfs_buf *lbp; /* leaf buffer */ - xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_trans_t *tp; /* transaction pointer */ - struct xfs_dir2_leaf_entry *ents; + struct xfs_dir3_icleaf_hdr leafhdr; trace_xfs_dir2_leaf_replace(args); /* * Look up the entry. */ - if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { + error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp, &leafhdr); + if (error) return error; - } + dp = args->dp; - leaf = lbp->b_addr; - ents = dp->d_ops->leaf_ents_p(leaf); /* * Point to the leaf entry, get data address from it. */ - lep = &ents[index]; + lep = &leafhdr.ents[index]; /* * Point to the data entry. */ @@ -1561,21 +1554,17 @@ xfs_dir2_leaf_search_hash( xfs_dahash_t hashwant; /* hash value looking for */ int high; /* high leaf index */ int low; /* low leaf index */ - xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ int mid=0; /* current leaf index */ - struct xfs_dir2_leaf_entry *ents; struct xfs_dir3_icleaf_hdr leafhdr; - leaf = lbp->b_addr; - ents = args->dp->d_ops->leaf_ents_p(leaf); - xfs_dir2_leaf_hdr_from_disk(args->dp->i_mount, &leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(args->dp->i_mount, &leafhdr, lbp->b_addr); /* * Note, the table cannot be empty, so we have to go through the loop. * Binary search the leaf entries looking for our hash value. */ - for (lep = ents, low = 0, high = leafhdr.count - 1, + for (lep = leafhdr.ents, low = 0, high = leafhdr.count - 1, hashwant = args->hashval; low <= high; ) { mid = (low + high) >> 1; diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 98cd645a8c99..721dd2dcba8d 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -441,7 +441,7 @@ xfs_dir2_leafn_add( trace_xfs_dir2_leafn_add(args, index); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); - ents = dp->d_ops->leaf_ents_p(leaf); + ents = leafhdr.ents; /* * Quick check just to make sure we are not going to index @@ -499,7 +499,7 @@ xfs_dir2_leafn_add( xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); xfs_dir3_leaf_log_header(args, bp); - xfs_dir3_leaf_log_ents(args, bp, lfloglow, lfloghigh); + xfs_dir3_leaf_log_ents(args, &leafhdr, bp, lfloglow, lfloghigh); xfs_dir3_leaf_check(dp, bp); return 0; } @@ -534,11 +534,9 @@ xfs_dir2_leaf_lasthash( struct xfs_buf *bp, /* leaf buffer */ int *count) /* count of entries in leaf */ { - struct xfs_dir2_leaf *leaf = bp->b_addr; - struct xfs_dir2_leaf_entry *ents; struct xfs_dir3_icleaf_hdr leafhdr; - xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, bp->b_addr); ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || leafhdr.magic == XFS_DIR3_LEAFN_MAGIC || @@ -549,9 +547,7 @@ xfs_dir2_leaf_lasthash( *count = leafhdr.count; if (!leafhdr.count) return 0; - - ents = dp->d_ops->leaf_ents_p(leaf); - return be32_to_cpu(ents[leafhdr.count - 1].hashval); + return be32_to_cpu(leafhdr.ents[leafhdr.count - 1].hashval); } /* @@ -580,7 +576,6 @@ xfs_dir2_leafn_lookup_for_addname( xfs_dir2_db_t newdb; /* new data block number */ xfs_dir2_db_t newfdb; /* new free block number */ xfs_trans_t *tp; /* transaction pointer */ - struct xfs_dir2_leaf_entry *ents; struct xfs_dir3_icleaf_hdr leafhdr; dp = args->dp; @@ -588,7 +583,6 @@ xfs_dir2_leafn_lookup_for_addname( mp = dp->i_mount; leaf = bp->b_addr; xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); - ents = dp->d_ops->leaf_ents_p(leaf); xfs_dir3_leaf_check(dp, bp); ASSERT(leafhdr.count > 0); @@ -612,7 +606,7 @@ xfs_dir2_leafn_lookup_for_addname( /* * Loop over leaf entries with the right hash value. */ - for (lep = &ents[index]; + for (lep = &leafhdr.ents[index]; index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; lep++, index++) { /* @@ -732,7 +726,6 @@ xfs_dir2_leafn_lookup_for_entry( xfs_dir2_db_t newdb; /* new data block number */ xfs_trans_t *tp; /* transaction pointer */ enum xfs_dacmp cmp; /* comparison result */ - struct xfs_dir2_leaf_entry *ents; struct xfs_dir3_icleaf_hdr leafhdr; dp = args->dp; @@ -740,7 +733,6 @@ xfs_dir2_leafn_lookup_for_entry( mp = dp->i_mount; leaf = bp->b_addr; xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); - ents = dp->d_ops->leaf_ents_p(leaf); xfs_dir3_leaf_check(dp, bp); if (leafhdr.count <= 0) { @@ -762,7 +754,7 @@ xfs_dir2_leafn_lookup_for_entry( /* * Loop over leaf entries with the right hash value. */ - for (lep = &ents[index]; + for (lep = &leafhdr.ents[index]; index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; lep++, index++) { /* @@ -917,7 +909,7 @@ xfs_dir3_leafn_moveents( if (start_d < dhdr->count) { memmove(&dents[start_d + count], &dents[start_d], (dhdr->count - start_d) * sizeof(xfs_dir2_leaf_entry_t)); - xfs_dir3_leaf_log_ents(args, bp_d, start_d + count, + xfs_dir3_leaf_log_ents(args, dhdr, bp_d, start_d + count, count + dhdr->count - 1); } /* @@ -939,7 +931,7 @@ xfs_dir3_leafn_moveents( */ memcpy(&dents[start_d], &sents[start_s], count * sizeof(xfs_dir2_leaf_entry_t)); - xfs_dir3_leaf_log_ents(args, bp_d, start_d, start_d + count - 1); + xfs_dir3_leaf_log_ents(args, dhdr, bp_d, start_d, start_d + count - 1); /* * If there are source entries after the ones we copied, @@ -948,7 +940,8 @@ xfs_dir3_leafn_moveents( if (start_s + count < shdr->count) { memmove(&sents[start_s], &sents[start_s + count], count * sizeof(xfs_dir2_leaf_entry_t)); - xfs_dir3_leaf_log_ents(args, bp_s, start_s, start_s + count - 1); + xfs_dir3_leaf_log_ents(args, shdr, bp_s, start_s, + start_s + count - 1); } /* @@ -979,8 +972,8 @@ xfs_dir2_leafn_order( xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr1, leaf1); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf2); - ents1 = dp->d_ops->leaf_ents_p(leaf1); - ents2 = dp->d_ops->leaf_ents_p(leaf2); + ents1 = hdr1.ents; + ents2 = hdr2.ents; if (hdr1.count > 0 && hdr2.count > 0 && (be32_to_cpu(ents2[0].hashval) < be32_to_cpu(ents1[0].hashval) || @@ -1032,8 +1025,8 @@ xfs_dir2_leafn_rebalance( leaf2 = blk2->bp->b_addr; xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr1, leaf1); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf2); - ents1 = dp->d_ops->leaf_ents_p(leaf1); - ents2 = dp->d_ops->leaf_ents_p(leaf2); + ents1 = hdr1.ents; + ents2 = hdr2.ents; oldsum = hdr1.count + hdr2.count; #if defined(DEBUG) || defined(XFS_WARN) @@ -1221,7 +1214,6 @@ xfs_dir2_leafn_remove( xfs_trans_t *tp; /* transaction pointer */ struct xfs_dir2_data_free *bf; /* bestfree table */ struct xfs_dir3_icleaf_hdr leafhdr; - struct xfs_dir2_leaf_entry *ents; trace_xfs_dir2_leafn_remove(args, index); @@ -1229,12 +1221,11 @@ xfs_dir2_leafn_remove( tp = args->trans; leaf = bp->b_addr; xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); - ents = dp->d_ops->leaf_ents_p(leaf); /* * Point to the entry we're removing. */ - lep = &ents[index]; + lep = &leafhdr.ents[index]; /* * Extract the data block and offset from the entry. @@ -1253,7 +1244,7 @@ xfs_dir2_leafn_remove( xfs_dir3_leaf_log_header(args, bp); lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); - xfs_dir3_leaf_log_ents(args, bp, index, index); + xfs_dir3_leaf_log_ents(args, &leafhdr, bp, index, index); /* * Make the data entry free. Keep track of the longest freespace @@ -1350,7 +1341,7 @@ xfs_dir2_leafn_remove( * to justify trying to join it with a neighbor. */ *rval = (dp->d_ops->leaf_hdr_size + - (uint)sizeof(ents[0]) * (leafhdr.count - leafhdr.stale)) < + (uint)sizeof(leafhdr.ents) * (leafhdr.count - leafhdr.stale)) < args->geo->magicpct; return 0; } @@ -1451,7 +1442,7 @@ xfs_dir2_leafn_toosmall( blk = &state->path.blk[state->path.active - 1]; leaf = blk->bp->b_addr; xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); - ents = dp->d_ops->leaf_ents_p(leaf); + ents = leafhdr.ents; xfs_dir3_leaf_check(dp, blk->bp); count = leafhdr.count - leafhdr.stale; @@ -1514,7 +1505,7 @@ xfs_dir2_leafn_toosmall( leaf = bp->b_addr; xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf); - ents = dp->d_ops->leaf_ents_p(leaf); + ents = hdr2.ents; count += hdr2.count - hdr2.stale; bytes -= count * sizeof(ents[0]); @@ -1578,8 +1569,8 @@ xfs_dir2_leafn_unbalance( xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &savehdr, save_leaf); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &drophdr, drop_leaf); - sents = dp->d_ops->leaf_ents_p(save_leaf); - dents = dp->d_ops->leaf_ents_p(drop_leaf); + sents = savehdr.ents; + dents = drophdr.ents; /* * If there are any stale leaf entries, take this opportunity @@ -2161,8 +2152,6 @@ xfs_dir2_node_replace( int i; /* btree level */ xfs_ino_t inum; /* new inode number */ int ftype; /* new file type */ - xfs_dir2_leaf_t *leaf; /* leaf structure */ - xfs_dir2_leaf_entry_t *lep; /* leaf entry being changed */ int rval; /* internal return value */ xfs_da_state_t *state; /* btree cursor */ @@ -2194,16 +2183,17 @@ xfs_dir2_node_replace( * and locked it. But paranoia is good. */ if (rval == -EEXIST) { - struct xfs_dir2_leaf_entry *ents; + struct xfs_dir3_icleaf_hdr leafhdr; + /* * Find the leaf entry. */ blk = &state->path.blk[state->path.active - 1]; ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); - leaf = blk->bp->b_addr; - ents = args->dp->d_ops->leaf_ents_p(leaf); - lep = &ents[blk->index]; ASSERT(state->extravalid); + + xfs_dir2_leaf_hdr_from_disk(state->mp, &leafhdr, + blk->bp->b_addr); /* * Point to the data entry. */ @@ -2213,7 +2203,7 @@ xfs_dir2_node_replace( dep = (xfs_dir2_data_entry_t *) ((char *)hdr + xfs_dir2_dataptr_to_off(args->geo, - be32_to_cpu(lep->address))); + be32_to_cpu(leafhdr.ents[blk->index].address))); ASSERT(inum != be64_to_cpu(dep->inumber)); /* * Fill in the new inode number and log the entry. diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index af96e3faefaf..1f068812c453 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h @@ -18,6 +18,12 @@ struct xfs_dir3_icleaf_hdr { uint16_t magic; uint16_t count; uint16_t stale; + + /* + * Pointer to the on-disk format entries, which are behind the + * variable size (v4 vs v5) header in the on-disk block. + */ + struct xfs_dir2_leaf_entry *ents; }; struct xfs_dir3_icfree_hdr { @@ -85,7 +91,8 @@ extern void xfs_dir3_leaf_compact_x1(struct xfs_dir3_icleaf_hdr *leafhdr, extern int xfs_dir3_leaf_get_buf(struct xfs_da_args *args, xfs_dir2_db_t bno, struct xfs_buf **bpp, uint16_t magic); extern void xfs_dir3_leaf_log_ents(struct xfs_da_args *args, - struct xfs_buf *bp, int first, int last); + struct xfs_dir3_icleaf_hdr *hdr, struct xfs_buf *bp, int first, + int last); extern void xfs_dir3_leaf_log_header(struct xfs_da_args *args, struct xfs_buf *bp); extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args); diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index 580927df287b..d8bb1ae4c5e3 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -198,14 +198,15 @@ xchk_dir_rec( xfs_dir2_dataptr_t ptr; xfs_dahash_t calc_hash; xfs_dahash_t hash; + struct xfs_dir3_icleaf_hdr hdr; unsigned int tag; int error; ASSERT(blk->magic == XFS_DIR2_LEAF1_MAGIC || blk->magic == XFS_DIR2_LEAFN_MAGIC); - ent = (void *)ds->dargs.dp->d_ops->leaf_ents_p(blk->bp->b_addr) + - (blk->index * sizeof(struct xfs_dir2_leaf_entry)); + xfs_dir2_leaf_hdr_from_disk(mp, &hdr, blk->bp->b_addr); + ent = hdr.ents + blk->index; /* Check the hash of the entry. */ error = xchk_da_btree_hash(ds, level, &ent->hashval); @@ -484,7 +485,6 @@ xchk_directory_leaf1_bestfree( xfs_dablk_t lblk) { struct xfs_dir3_icleaf_hdr leafhdr; - struct xfs_dir2_leaf_entry *ents; struct xfs_dir2_leaf_tail *ltp; struct xfs_dir2_leaf *leaf; struct xfs_buf *dbp; @@ -508,7 +508,6 @@ xchk_directory_leaf1_bestfree( leaf = bp->b_addr; xfs_dir2_leaf_hdr_from_disk(sc->ip->i_mount, &leafhdr, leaf); - ents = d_ops->leaf_ents_p(leaf); ltp = xfs_dir2_leaf_tail_p(geo, leaf); bestcount = be32_to_cpu(ltp->bestcount); bestp = xfs_dir2_leaf_bests_p(ltp); @@ -536,18 +535,19 @@ xchk_directory_leaf1_bestfree( } /* Leaves and bests don't overlap in leaf format. */ - if ((char *)&ents[leafhdr.count] > (char *)bestp) { + if ((char *)&leafhdr.ents[leafhdr.count] > (char *)bestp) { xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); goto out; } /* Check hash value order, count stale entries. */ for (i = 0; i < leafhdr.count; i++) { - hash = be32_to_cpu(ents[i].hashval); + hash = be32_to_cpu(leafhdr.ents[i].hashval); if (i > 0 && lasthash > hash) xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); lasthash = hash; - if (ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) + if (leafhdr.ents[i].address == + cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) stale++; } if (leafhdr.stale != stale) -- cgit v1.2.3-70-g09d2 From 545910bcc875377160b7b669e790865602a006f3 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 14:57:51 -0800 Subject: xfs: move the dir2 leaf header size to struct xfs_da_geometry Move the leaf header size towards our structure for dir/attr geometry parameters. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_btree.h | 1 + fs/xfs/libxfs/xfs_da_format.c | 3 --- fs/xfs/libxfs/xfs_dir2.c | 7 +++++-- fs/xfs/libxfs/xfs_dir2.h | 1 - fs/xfs/libxfs/xfs_dir2_leaf.c | 2 +- fs/xfs/libxfs/xfs_dir2_node.c | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index 396b76ac02d6..b262ec403bba 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -26,6 +26,7 @@ struct xfs_da_geometry { unsigned int node_ents; /* # of entries in a danode */ unsigned int magicpct; /* 37% of block size in bytes */ xfs_dablk_t datablk; /* blockno of dir data v2 */ + unsigned int leaf_hdr_size; /* dir2 leaf header size */ xfs_dablk_t leafblk; /* blockno of leaf data v2 */ xfs_dablk_t freeblk; /* blockno of free data v2 */ }; diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index ed21ce01502f..a3e87f4788e0 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -570,7 +570,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { .data_entry_p = xfs_dir2_data_entry_p, .data_unused_p = xfs_dir2_data_unused_p, - .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr), .leaf_max_ents = xfs_dir2_max_leaf_ents, .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), @@ -612,7 +611,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .data_entry_p = xfs_dir2_data_entry_p, .data_unused_p = xfs_dir2_data_unused_p, - .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr), .leaf_max_ents = xfs_dir2_max_leaf_ents, .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), @@ -654,7 +652,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = { .data_entry_p = xfs_dir3_data_entry_p, .data_unused_p = xfs_dir3_data_unused_p, - .leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr), .leaf_max_ents = xfs_dir3_max_leaf_ents, .free_hdr_size = sizeof(struct xfs_dir3_free_hdr), diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 98cc0631e7d5..6e7a4e9ced5e 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -122,10 +122,13 @@ xfs_da_mount( dageo->fsblog = mp->m_sb.sb_blocklog; dageo->blksize = xfs_dir2_dirblock_bytes(&mp->m_sb); dageo->fsbcount = 1 << mp->m_sb.sb_dirblklog; - if (xfs_sb_version_hascrc(&mp->m_sb)) + if (xfs_sb_version_hascrc(&mp->m_sb)) { dageo->node_hdr_size = sizeof(struct xfs_da3_node_hdr); - else + dageo->leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr); + } else { dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr); + dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr); + } /* * Now we've set up the block conversion variables, we can calculate the diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index b46657974134..544adee5dd12 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -72,7 +72,6 @@ struct xfs_dir_ops { struct xfs_dir2_data_unused * (*data_unused_p)(struct xfs_dir2_data_hdr *hdr); - int leaf_hdr_size; int (*leaf_max_ents)(struct xfs_da_geometry *geo); int free_hdr_size; diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index 5e3e96efdaca..888d4b0acab8 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -1132,7 +1132,7 @@ xfs_dir3_leaf_log_header( xfs_trans_log_buf(args->trans, bp, (uint)((char *)&leaf->hdr - (char *)leaf), - args->dp->d_ops->leaf_hdr_size - 1); + args->geo->leaf_hdr_size - 1); } /* diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 721dd2dcba8d..f7ba4d22165c 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -1340,7 +1340,7 @@ xfs_dir2_leafn_remove( * Return indication of whether this leaf block is empty enough * to justify trying to join it with a neighbor. */ - *rval = (dp->d_ops->leaf_hdr_size + + *rval = (args->geo->leaf_hdr_size + (uint)sizeof(leafhdr.ents) * (leafhdr.count - leafhdr.stale)) < args->geo->magicpct; return 0; @@ -1446,7 +1446,7 @@ xfs_dir2_leafn_toosmall( xfs_dir3_leaf_check(dp, blk->bp); count = leafhdr.count - leafhdr.stale; - bytes = dp->d_ops->leaf_hdr_size + count * sizeof(ents[0]); + bytes = state->args->geo->leaf_hdr_size + count * sizeof(ents[0]); if (bytes > (state->args->geo->blksize >> 1)) { /* * Blk over 50%, don't try to join. -- cgit v1.2.3-70-g09d2 From 478c7835cb8ee28e73e732642866995f8555df7e Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 14:57:51 -0800 Subject: xfs: move the max dir2 leaf entries count to struct xfs_da_geometry Move the max leaf entries count towards our structure for dir/attr geometry parameters. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_btree.h | 1 + fs/xfs/libxfs/xfs_da_format.c | 23 ----------------------- fs/xfs/libxfs/xfs_dir2.c | 2 ++ fs/xfs/libxfs/xfs_dir2.h | 2 -- fs/xfs/libxfs/xfs_dir2_leaf.c | 2 +- fs/xfs/libxfs/xfs_dir2_node.c | 2 +- fs/xfs/scrub/dir.c | 3 +-- 7 files changed, 6 insertions(+), 29 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index b262ec403bba..c6ff5329e92b 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -27,6 +27,7 @@ struct xfs_da_geometry { unsigned int magicpct; /* 37% of block size in bytes */ xfs_dablk_t datablk; /* blockno of dir data v2 */ unsigned int leaf_hdr_size; /* dir2 leaf header size */ + unsigned int leaf_max_ents; /* # of entries in dir2 leaf */ xfs_dablk_t leafblk; /* blockno of leaf data v2 */ xfs_dablk_t freeblk; /* blockno of free data v2 */ }; diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index a3e87f4788e0..fe9e20698719 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -401,23 +401,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr) } -/* - * Directory Leaf block operations - */ -static int -xfs_dir2_max_leaf_ents(struct xfs_da_geometry *geo) -{ - return (geo->blksize - sizeof(struct xfs_dir2_leaf_hdr)) / - (uint)sizeof(struct xfs_dir2_leaf_entry); -} - -static int -xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo) -{ - return (geo->blksize - sizeof(struct xfs_dir3_leaf_hdr)) / - (uint)sizeof(struct xfs_dir2_leaf_entry); -} - /* * Directory free space block operations */ @@ -570,8 +553,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { .data_entry_p = xfs_dir2_data_entry_p, .data_unused_p = xfs_dir2_data_unused_p, - .leaf_max_ents = xfs_dir2_max_leaf_ents, - .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk, .free_hdr_from_disk = xfs_dir2_free_hdr_from_disk, @@ -611,8 +592,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .data_entry_p = xfs_dir2_data_entry_p, .data_unused_p = xfs_dir2_data_unused_p, - .leaf_max_ents = xfs_dir2_max_leaf_ents, - .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk, .free_hdr_from_disk = xfs_dir2_free_hdr_from_disk, @@ -652,8 +631,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = { .data_entry_p = xfs_dir3_data_entry_p, .data_unused_p = xfs_dir3_data_unused_p, - .leaf_max_ents = xfs_dir3_max_leaf_ents, - .free_hdr_size = sizeof(struct xfs_dir3_free_hdr), .free_hdr_to_disk = xfs_dir3_free_hdr_to_disk, .free_hdr_from_disk = xfs_dir3_free_hdr_from_disk, diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 6e7a4e9ced5e..8093afb389a1 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -129,6 +129,8 @@ xfs_da_mount( dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr); dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr); } + dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) / + sizeof(struct xfs_dir2_leaf_entry); /* * Now we've set up the block conversion variables, we can calculate the diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index 544adee5dd12..ee18fc56a6a1 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -72,8 +72,6 @@ struct xfs_dir_ops { struct xfs_dir2_data_unused * (*data_unused_p)(struct xfs_dir2_data_hdr *hdr); - int (*leaf_max_ents)(struct xfs_da_geometry *geo); - int free_hdr_size; void (*free_hdr_to_disk)(struct xfs_dir2_free *to, struct xfs_dir3_icfree_hdr *from); diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index 888d4b0acab8..7e4e77f2f5b5 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -167,7 +167,7 @@ xfs_dir3_leaf_check_int( * Should factor in the size of the bests table as well. * We can deduce a value for that from di_size. */ - if (hdr->count > ops->leaf_max_ents(geo)) + if (hdr->count > geo->leaf_max_ents) return __this_address; /* Leaves and bests don't overlap in leaf format. */ diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index f7ba4d22165c..2c44248b7b4a 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -459,7 +459,7 @@ xfs_dir2_leafn_add( * a compact. */ - if (leafhdr.count == dp->d_ops->leaf_max_ents(args->geo)) { + if (leafhdr.count == args->geo->leaf_max_ents) { if (!leafhdr.stale) return -ENOSPC; compact = leafhdr.stale > 1; diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index d8bb1ae4c5e3..9aa90ff45c3e 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -489,7 +489,6 @@ xchk_directory_leaf1_bestfree( struct xfs_dir2_leaf *leaf; struct xfs_buf *dbp; struct xfs_buf *bp; - const struct xfs_dir_ops *d_ops = sc->ip->d_ops; struct xfs_da_geometry *geo = sc->mp->m_dir_geo; __be16 *bestp; __u16 best; @@ -529,7 +528,7 @@ xchk_directory_leaf1_bestfree( } /* Is the leaf count even remotely sane? */ - if (leafhdr.count > d_ops->leaf_max_ents(geo)) { + if (leafhdr.count > geo->leaf_max_ents) { xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); goto out; } -- cgit v1.2.3-70-g09d2 From 5ba30919a6fcf0d3d52507082ea67fab32c8bb29 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 14:57:52 -0800 Subject: xfs: devirtualize ->free_hdr_from_disk Replace the ->free_hdr_from_disk dir ops method with a directly called xfs_dir_free_hdr_from_disk helper that takes care of the differences between the v4 and v5 on-disk format. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_format.c | 30 ---------------------------- fs/xfs/libxfs/xfs_dir2.h | 2 -- fs/xfs/libxfs/xfs_dir2_leaf.c | 14 +++---------- fs/xfs/libxfs/xfs_dir2_node.c | 46 +++++++++++++++++++++++++++++++++---------- fs/xfs/libxfs/xfs_dir2_priv.h | 5 +++-- fs/xfs/scrub/dir.c | 2 +- 6 files changed, 43 insertions(+), 56 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index fe9e20698719..d0e541d9d335 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -468,18 +468,6 @@ xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db) return db % xfs_dir3_free_max_bests(geo); } -static void -xfs_dir2_free_hdr_from_disk( - struct xfs_dir3_icfree_hdr *to, - struct xfs_dir2_free *from) -{ - to->magic = be32_to_cpu(from->hdr.magic); - to->firstdb = be32_to_cpu(from->hdr.firstdb); - to->nvalid = be32_to_cpu(from->hdr.nvalid); - to->nused = be32_to_cpu(from->hdr.nused); - ASSERT(to->magic == XFS_DIR2_FREE_MAGIC); -} - static void xfs_dir2_free_hdr_to_disk( struct xfs_dir2_free *to, @@ -493,21 +481,6 @@ xfs_dir2_free_hdr_to_disk( to->hdr.nused = cpu_to_be32(from->nused); } -static void -xfs_dir3_free_hdr_from_disk( - struct xfs_dir3_icfree_hdr *to, - struct xfs_dir2_free *from) -{ - struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)from; - - to->magic = be32_to_cpu(hdr3->hdr.magic); - to->firstdb = be32_to_cpu(hdr3->firstdb); - to->nvalid = be32_to_cpu(hdr3->nvalid); - to->nused = be32_to_cpu(hdr3->nused); - - ASSERT(to->magic == XFS_DIR3_FREE_MAGIC); -} - static void xfs_dir3_free_hdr_to_disk( struct xfs_dir2_free *to, @@ -555,7 +528,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk, - .free_hdr_from_disk = xfs_dir2_free_hdr_from_disk, .free_max_bests = xfs_dir2_free_max_bests, .free_bests_p = xfs_dir2_free_bests_p, .db_to_fdb = xfs_dir2_db_to_fdb, @@ -594,7 +566,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk, - .free_hdr_from_disk = xfs_dir2_free_hdr_from_disk, .free_max_bests = xfs_dir2_free_max_bests, .free_bests_p = xfs_dir2_free_bests_p, .db_to_fdb = xfs_dir2_db_to_fdb, @@ -633,7 +604,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = { .free_hdr_size = sizeof(struct xfs_dir3_free_hdr), .free_hdr_to_disk = xfs_dir3_free_hdr_to_disk, - .free_hdr_from_disk = xfs_dir3_free_hdr_from_disk, .free_max_bests = xfs_dir3_free_max_bests, .free_bests_p = xfs_dir3_free_bests_p, .db_to_fdb = xfs_dir3_db_to_fdb, diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index ee18fc56a6a1..c3e6a6fb7e37 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -75,8 +75,6 @@ struct xfs_dir_ops { int free_hdr_size; void (*free_hdr_to_disk)(struct xfs_dir2_free *to, struct xfs_dir3_icfree_hdr *from); - void (*free_hdr_from_disk)(struct xfs_dir3_icfree_hdr *to, - struct xfs_dir2_free *from); int (*free_max_bests)(struct xfs_da_geometry *geo); __be16 * (*free_bests_p)(struct xfs_dir2_free *free); xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo, diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index 7e4e77f2f5b5..b435379ddaa2 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -113,7 +113,7 @@ xfs_dir3_leaf1_check( } else if (leafhdr.magic != XFS_DIR2_LEAF1_MAGIC) return __this_address; - return xfs_dir3_leaf_check_int(dp->i_mount, dp, &leafhdr, leaf); + return xfs_dir3_leaf_check_int(dp->i_mount, &leafhdr, leaf); } static inline void @@ -138,23 +138,15 @@ xfs_dir3_leaf_check( xfs_failaddr_t xfs_dir3_leaf_check_int( struct xfs_mount *mp, - struct xfs_inode *dp, struct xfs_dir3_icleaf_hdr *hdr, struct xfs_dir2_leaf *leaf) { xfs_dir2_leaf_tail_t *ltp; int stale; int i; - const struct xfs_dir_ops *ops; struct xfs_dir3_icleaf_hdr leafhdr; struct xfs_da_geometry *geo = mp->m_dir_geo; - /* - * we can be passed a null dp here from a verifier, so we need to go the - * hard way to get them. - */ - ops = xfs_dir_get_ops(mp, dp); - if (!hdr) { xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); hdr = &leafhdr; @@ -208,7 +200,7 @@ xfs_dir3_leaf_verify( if (fa) return fa; - return xfs_dir3_leaf_check_int(mp, NULL, NULL, leaf); + return xfs_dir3_leaf_check_int(mp, NULL, leaf); } static void @@ -1758,7 +1750,7 @@ xfs_dir2_node_to_leaf( if (error) return error; free = fbp->b_addr; - dp->d_ops->free_hdr_from_disk(&freehdr, free); + xfs_dir2_free_hdr_from_disk(mp, &freehdr, free); ASSERT(!freehdr.firstdb); diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 2c44248b7b4a..d337ecd4e3be 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -54,7 +54,7 @@ xfs_dir3_leafn_check( } else if (leafhdr.magic != XFS_DIR2_LEAFN_MAGIC) return __this_address; - return xfs_dir3_leaf_check_int(dp->i_mount, dp, &leafhdr, leaf); + return xfs_dir3_leaf_check_int(dp->i_mount, &leafhdr, leaf); } static inline void @@ -220,6 +220,30 @@ __xfs_dir3_free_read( return 0; } +void +xfs_dir2_free_hdr_from_disk( + struct xfs_mount *mp, + struct xfs_dir3_icfree_hdr *to, + struct xfs_dir2_free *from) +{ + if (xfs_sb_version_hascrc(&mp->m_sb)) { + struct xfs_dir3_free *from3 = (struct xfs_dir3_free *)from; + + to->magic = be32_to_cpu(from3->hdr.hdr.magic); + to->firstdb = be32_to_cpu(from3->hdr.firstdb); + to->nvalid = be32_to_cpu(from3->hdr.nvalid); + to->nused = be32_to_cpu(from3->hdr.nused); + + ASSERT(to->magic == XFS_DIR3_FREE_MAGIC); + } else { + to->magic = be32_to_cpu(from->hdr.magic); + to->firstdb = be32_to_cpu(from->hdr.firstdb); + to->nvalid = be32_to_cpu(from->hdr.nvalid); + to->nused = be32_to_cpu(from->hdr.nused); + ASSERT(to->magic == XFS_DIR2_FREE_MAGIC); + } +} + int xfs_dir2_free_read( struct xfs_trans *tp, @@ -369,7 +393,7 @@ xfs_dir2_leaf_to_node( return error; free = fbp->b_addr; - dp->d_ops->free_hdr_from_disk(&freehdr, free); + xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free); leaf = lbp->b_addr; ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); if (be32_to_cpu(ltp->bestcount) > @@ -513,7 +537,7 @@ xfs_dir2_free_hdr_check( { struct xfs_dir3_icfree_hdr hdr; - dp->d_ops->free_hdr_from_disk(&hdr, bp->b_addr); + xfs_dir2_free_hdr_from_disk(dp->i_mount, &hdr, bp->b_addr); ASSERT((hdr.firstdb % dp->d_ops->free_max_bests(dp->i_mount->m_dir_geo)) == 0); @@ -1123,7 +1147,7 @@ xfs_dir3_data_block_free( struct xfs_dir3_icfree_hdr freehdr; struct xfs_inode *dp = args->dp; - dp->d_ops->free_hdr_from_disk(&freehdr, free); + xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free); bests = dp->d_ops->free_bests_p(free); if (hdr) { /* @@ -1292,7 +1316,8 @@ xfs_dir2_leafn_remove( #ifdef DEBUG { struct xfs_dir3_icfree_hdr freehdr; - dp->d_ops->free_hdr_from_disk(&freehdr, free); + + xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free); ASSERT(freehdr.firstdb == dp->d_ops->free_max_bests(args->geo) * (fdb - xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET))); @@ -1686,7 +1711,7 @@ xfs_dir2_node_add_datablk( return error; free = fbp->b_addr; bests = dp->d_ops->free_bests_p(free); - dp->d_ops->free_hdr_from_disk(&freehdr, free); + xfs_dir2_free_hdr_from_disk(mp, &freehdr, free); /* Remember the first slot as our empty slot. */ freehdr.firstdb = (fbno - xfs_dir2_byte_to_db(args->geo, @@ -1695,7 +1720,7 @@ xfs_dir2_node_add_datablk( } else { free = fbp->b_addr; bests = dp->d_ops->free_bests_p(free); - dp->d_ops->free_hdr_from_disk(&freehdr, free); + xfs_dir2_free_hdr_from_disk(mp, &freehdr, free); } /* Set the freespace block index from the data block number. */ @@ -1764,7 +1789,8 @@ xfs_dir2_node_find_freeblk( if (findex >= 0) { /* caller already found the freespace for us. */ bests = dp->d_ops->free_bests_p(free); - dp->d_ops->free_hdr_from_disk(&freehdr, free); + xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, + free); ASSERT(findex < freehdr.nvalid); ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF); @@ -1813,7 +1839,7 @@ xfs_dir2_node_find_freeblk( free = fbp->b_addr; bests = dp->d_ops->free_bests_p(free); - dp->d_ops->free_hdr_from_disk(&freehdr, free); + xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free); /* Scan the free entry array for a large enough free space. */ for (findex = freehdr.nvalid - 1; findex >= 0; findex--) { @@ -2266,7 +2292,7 @@ xfs_dir2_node_trim_free( if (!bp) return 0; free = bp->b_addr; - dp->d_ops->free_hdr_from_disk(&freehdr, free); + xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free); /* * If there are used entries, there's nothing to do. diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index 1f068812c453..2c3370a3c010 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h @@ -109,10 +109,11 @@ xfs_dir3_leaf_find_entry(struct xfs_dir3_icleaf_hdr *leafhdr, extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state); extern xfs_failaddr_t xfs_dir3_leaf_check_int(struct xfs_mount *mp, - struct xfs_inode *dp, struct xfs_dir3_icleaf_hdr *hdr, - struct xfs_dir2_leaf *leaf); + struct xfs_dir3_icleaf_hdr *hdr, struct xfs_dir2_leaf *leaf); /* xfs_dir2_node.c */ +void xfs_dir2_free_hdr_from_disk(struct xfs_mount *mp, + struct xfs_dir3_icfree_hdr *to, struct xfs_dir2_free *from); extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args, struct xfs_buf *lbp); extern xfs_dahash_t xfs_dir2_leaf_lasthash(struct xfs_inode *dp, diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index 9aa90ff45c3e..1314a9159156 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -603,7 +603,7 @@ xchk_directory_free_bestfree( } /* Check all the entries. */ - sc->ip->d_ops->free_hdr_from_disk(&freehdr, bp->b_addr); + xfs_dir2_free_hdr_from_disk(sc->ip->i_mount, &freehdr, bp->b_addr); bestp = sc->ip->d_ops->free_bests_p(bp->b_addr); for (i = 0; i < freehdr.nvalid; i++, bestp++) { best = be16_to_cpu(*bestp); -- cgit v1.2.3-70-g09d2 From 200dada70008a1204ddd3d95250d23d6477e20e6 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 14:57:52 -0800 Subject: xfs: devirtualize ->free_hdr_to_disk Replace the ->free_hdr_to_disk dir ops method with a directly called xfs_dir2_free_hdr_to_disk helper that takes care of the differences between the v4 and v5 on-disk format. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_format.c | 31 ------------------------------- fs/xfs/libxfs/xfs_dir2.h | 2 -- fs/xfs/libxfs/xfs_dir2_node.c | 33 +++++++++++++++++++++++++++++---- 3 files changed, 29 insertions(+), 37 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index d0e541d9d335..b943d9443d55 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -468,34 +468,6 @@ xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db) return db % xfs_dir3_free_max_bests(geo); } -static void -xfs_dir2_free_hdr_to_disk( - struct xfs_dir2_free *to, - struct xfs_dir3_icfree_hdr *from) -{ - ASSERT(from->magic == XFS_DIR2_FREE_MAGIC); - - to->hdr.magic = cpu_to_be32(from->magic); - to->hdr.firstdb = cpu_to_be32(from->firstdb); - to->hdr.nvalid = cpu_to_be32(from->nvalid); - to->hdr.nused = cpu_to_be32(from->nused); -} - -static void -xfs_dir3_free_hdr_to_disk( - struct xfs_dir2_free *to, - struct xfs_dir3_icfree_hdr *from) -{ - struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)to; - - ASSERT(from->magic == XFS_DIR3_FREE_MAGIC); - - hdr3->hdr.magic = cpu_to_be32(from->magic); - hdr3->firstdb = cpu_to_be32(from->firstdb); - hdr3->nvalid = cpu_to_be32(from->nvalid); - hdr3->nused = cpu_to_be32(from->nused); -} - static const struct xfs_dir_ops xfs_dir2_ops = { .sf_entsize = xfs_dir2_sf_entsize, .sf_nextentry = xfs_dir2_sf_nextentry, @@ -527,7 +499,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { .data_unused_p = xfs_dir2_data_unused_p, .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), - .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk, .free_max_bests = xfs_dir2_free_max_bests, .free_bests_p = xfs_dir2_free_bests_p, .db_to_fdb = xfs_dir2_db_to_fdb, @@ -565,7 +536,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .data_unused_p = xfs_dir2_data_unused_p, .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), - .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk, .free_max_bests = xfs_dir2_free_max_bests, .free_bests_p = xfs_dir2_free_bests_p, .db_to_fdb = xfs_dir2_db_to_fdb, @@ -603,7 +573,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = { .data_unused_p = xfs_dir3_data_unused_p, .free_hdr_size = sizeof(struct xfs_dir3_free_hdr), - .free_hdr_to_disk = xfs_dir3_free_hdr_to_disk, .free_max_bests = xfs_dir3_free_max_bests, .free_bests_p = xfs_dir3_free_bests_p, .db_to_fdb = xfs_dir3_db_to_fdb, diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index c3e6a6fb7e37..613a78281d03 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -73,8 +73,6 @@ struct xfs_dir_ops { (*data_unused_p)(struct xfs_dir2_data_hdr *hdr); int free_hdr_size; - void (*free_hdr_to_disk)(struct xfs_dir2_free *to, - struct xfs_dir3_icfree_hdr *from); int (*free_max_bests)(struct xfs_da_geometry *geo); __be16 * (*free_bests_p)(struct xfs_dir2_free *free); xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo, diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index d337ecd4e3be..4e49ac64a2ff 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -244,6 +244,31 @@ xfs_dir2_free_hdr_from_disk( } } +static void +xfs_dir2_free_hdr_to_disk( + struct xfs_mount *mp, + struct xfs_dir2_free *to, + struct xfs_dir3_icfree_hdr *from) +{ + if (xfs_sb_version_hascrc(&mp->m_sb)) { + struct xfs_dir3_free *to3 = (struct xfs_dir3_free *)to; + + ASSERT(from->magic == XFS_DIR3_FREE_MAGIC); + + to3->hdr.hdr.magic = cpu_to_be32(from->magic); + to3->hdr.firstdb = cpu_to_be32(from->firstdb); + to3->hdr.nvalid = cpu_to_be32(from->nvalid); + to3->hdr.nused = cpu_to_be32(from->nused); + } else { + ASSERT(from->magic == XFS_DIR2_FREE_MAGIC); + + to->hdr.magic = cpu_to_be32(from->magic); + to->hdr.firstdb = cpu_to_be32(from->firstdb); + to->hdr.nvalid = cpu_to_be32(from->nvalid); + to->hdr.nused = cpu_to_be32(from->nused); + } +} + int xfs_dir2_free_read( struct xfs_trans *tp, @@ -302,7 +327,7 @@ xfs_dir3_free_get_buf( uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_meta_uuid); } else hdr.magic = XFS_DIR2_FREE_MAGIC; - dp->d_ops->free_hdr_to_disk(bp->b_addr, &hdr); + xfs_dir2_free_hdr_to_disk(mp, bp->b_addr, &hdr); *bpp = bp; return 0; } @@ -420,7 +445,7 @@ xfs_dir2_leaf_to_node( freehdr.nused = n; freehdr.nvalid = be32_to_cpu(ltp->bestcount); - dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr); + xfs_dir2_free_hdr_to_disk(dp->i_mount, fbp->b_addr, &freehdr); xfs_dir2_free_log_bests(args, fbp, 0, freehdr.nvalid - 1); xfs_dir2_free_log_header(args, fbp); @@ -1182,7 +1207,7 @@ xfs_dir3_data_block_free( logfree = 1; } - dp->d_ops->free_hdr_to_disk(free, &freehdr); + xfs_dir2_free_hdr_to_disk(dp->i_mount, free, &freehdr); xfs_dir2_free_log_header(args, fbp); /* @@ -1739,7 +1764,7 @@ xfs_dir2_node_add_datablk( */ if (bests[*findex] == cpu_to_be16(NULLDATAOFF)) { freehdr.nused++; - dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr); + xfs_dir2_free_hdr_to_disk(mp, fbp->b_addr, &freehdr); xfs_dir2_free_log_header(args, fbp); } -- cgit v1.2.3-70-g09d2 From 195b0a44ab73f0275683e7a0b1985751ea2ef6ae Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 14:57:53 -0800 Subject: xfs: make the xfs_dir3_icfree_hdr available to xfs_dir2_node_addname_int Return the xfs_dir3_icfree_hdr used by the helpers called from xfs_dir2_node_addname_int to the main function to prepare for the next round of changes where we'll use the ichdr in xfs_dir3_icfree_hdr to avoid extra operations to find the bests pointers. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_dir2_node.c | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 4e49ac64a2ff..6d67ceac48b7 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -1666,14 +1666,13 @@ xfs_dir2_node_add_datablk( xfs_dir2_db_t *dbno, struct xfs_buf **dbpp, struct xfs_buf **fbpp, + struct xfs_dir3_icfree_hdr *hdr, int *findex) { struct xfs_inode *dp = args->dp; struct xfs_trans *tp = args->trans; struct xfs_mount *mp = dp->i_mount; - struct xfs_dir3_icfree_hdr freehdr; struct xfs_dir2_data_free *bf; - struct xfs_dir2_data_hdr *hdr; struct xfs_dir2_free *free = NULL; xfs_dir2_db_t fbno; struct xfs_buf *fbp; @@ -1736,25 +1735,25 @@ xfs_dir2_node_add_datablk( return error; free = fbp->b_addr; bests = dp->d_ops->free_bests_p(free); - xfs_dir2_free_hdr_from_disk(mp, &freehdr, free); + xfs_dir2_free_hdr_from_disk(mp, hdr, free); /* Remember the first slot as our empty slot. */ - freehdr.firstdb = (fbno - xfs_dir2_byte_to_db(args->geo, + hdr->firstdb = (fbno - xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET)) * dp->d_ops->free_max_bests(args->geo); } else { free = fbp->b_addr; bests = dp->d_ops->free_bests_p(free); - xfs_dir2_free_hdr_from_disk(mp, &freehdr, free); + xfs_dir2_free_hdr_from_disk(mp, hdr, free); } /* Set the freespace block index from the data block number. */ *findex = dp->d_ops->db_to_fdindex(args->geo, *dbno); /* Extend the freespace table if the new data block is off the end. */ - if (*findex >= freehdr.nvalid) { + if (*findex >= hdr->nvalid) { ASSERT(*findex < dp->d_ops->free_max_bests(args->geo)); - freehdr.nvalid = *findex + 1; + hdr->nvalid = *findex + 1; bests[*findex] = cpu_to_be16(NULLDATAOFF); } @@ -1763,14 +1762,13 @@ xfs_dir2_node_add_datablk( * true) then update the header. */ if (bests[*findex] == cpu_to_be16(NULLDATAOFF)) { - freehdr.nused++; - xfs_dir2_free_hdr_to_disk(mp, fbp->b_addr, &freehdr); + hdr->nused++; + xfs_dir2_free_hdr_to_disk(mp, fbp->b_addr, hdr); xfs_dir2_free_log_header(args, fbp); } /* Update the freespace value for the new block in the table. */ - hdr = dbp->b_addr; - bf = dp->d_ops->data_bestfree_p(hdr); + bf = dp->d_ops->data_bestfree_p(dbp->b_addr); bests[*findex] = bf[0].length; *dbpp = dbp; @@ -1784,10 +1782,10 @@ xfs_dir2_node_find_freeblk( struct xfs_da_state_blk *fblk, xfs_dir2_db_t *dbnop, struct xfs_buf **fbpp, + struct xfs_dir3_icfree_hdr *hdr, int *findexp, int length) { - struct xfs_dir3_icfree_hdr freehdr; struct xfs_dir2_free *free = NULL; struct xfs_inode *dp = args->dp; struct xfs_trans *tp = args->trans; @@ -1814,13 +1812,12 @@ xfs_dir2_node_find_freeblk( if (findex >= 0) { /* caller already found the freespace for us. */ bests = dp->d_ops->free_bests_p(free); - xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, - free); + xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, free); - ASSERT(findex < freehdr.nvalid); + ASSERT(findex < hdr->nvalid); ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF); ASSERT(be16_to_cpu(bests[findex]) >= length); - dbno = freehdr.firstdb + findex; + dbno = hdr->firstdb + findex; goto found_block; } @@ -1864,13 +1861,13 @@ xfs_dir2_node_find_freeblk( free = fbp->b_addr; bests = dp->d_ops->free_bests_p(free); - xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free); + xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, free); /* Scan the free entry array for a large enough free space. */ - for (findex = freehdr.nvalid - 1; findex >= 0; findex--) { + for (findex = hdr->nvalid - 1; findex >= 0; findex--) { if (be16_to_cpu(bests[findex]) != NULLDATAOFF && be16_to_cpu(bests[findex]) >= length) { - dbno = freehdr.firstdb + findex; + dbno = hdr->firstdb + findex; goto found_block; } } @@ -1904,6 +1901,7 @@ xfs_dir2_node_addname_int( struct xfs_dir2_free *free = NULL; /* freespace block structure */ struct xfs_trans *tp = args->trans; struct xfs_inode *dp = args->dp; + struct xfs_dir3_icfree_hdr freehdr; struct xfs_buf *dbp; /* data block buffer */ struct xfs_buf *fbp; /* freespace buffer */ xfs_dir2_data_aoff_t aoff; @@ -1918,8 +1916,8 @@ xfs_dir2_node_addname_int( __be16 *bests; length = dp->d_ops->data_entsize(args->namelen); - error = xfs_dir2_node_find_freeblk(args, fblk, &dbno, &fbp, &findex, - length); + error = xfs_dir2_node_find_freeblk(args, fblk, &dbno, &fbp, &freehdr, + &findex, length); if (error) return error; @@ -1941,7 +1939,7 @@ xfs_dir2_node_addname_int( /* we're going to have to log the free block index later */ logfree = 1; error = xfs_dir2_node_add_datablk(args, fblk, &dbno, &dbp, &fbp, - &findex); + &freehdr, &findex); } else { /* Read the data block in. */ error = xfs_dir3_data_read(tp, dp, -- cgit v1.2.3-70-g09d2 From a84f3d5cb04f7dff1bf6904f0a05bc8df16137fb Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 14:58:05 -0800 Subject: xfs: add a bests pointer to struct xfs_dir3_icfree_hdr All but two callers of the ->free_bests_p dir operation already have a struct xfs_dir3_icfree_hdr from a previous call to xfs_dir2_free_hdr_from_disk at hand. Add a pointer to the bests to struct xfs_dir3_icfree_hdr to clean up this pattern. To optimize this pattern, pass the struct xfs_dir3_icfree_hdr to xfs_dir2_free_log_bests instead of recalculating the pointer there. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_format.c | 15 ------- fs/xfs/libxfs/xfs_dir2.h | 1 - fs/xfs/libxfs/xfs_dir2_leaf.c | 6 +-- fs/xfs/libxfs/xfs_dir2_node.c | 97 +++++++++++++++++-------------------------- fs/xfs/libxfs/xfs_dir2_priv.h | 6 +++ fs/xfs/scrub/dir.c | 6 +-- 6 files changed, 48 insertions(+), 83 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index b943d9443d55..7263b6d6a135 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -411,12 +411,6 @@ xfs_dir2_free_max_bests(struct xfs_da_geometry *geo) sizeof(xfs_dir2_data_off_t); } -static __be16 * -xfs_dir2_free_bests_p(struct xfs_dir2_free *free) -{ - return (__be16 *)((char *)free + sizeof(struct xfs_dir2_free_hdr)); -} - /* * Convert data space db to the corresponding free db. */ @@ -443,12 +437,6 @@ xfs_dir3_free_max_bests(struct xfs_da_geometry *geo) sizeof(xfs_dir2_data_off_t); } -static __be16 * -xfs_dir3_free_bests_p(struct xfs_dir2_free *free) -{ - return (__be16 *)((char *)free + sizeof(struct xfs_dir3_free_hdr)); -} - /* * Convert data space db to the corresponding free db. */ @@ -500,7 +488,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), .free_max_bests = xfs_dir2_free_max_bests, - .free_bests_p = xfs_dir2_free_bests_p, .db_to_fdb = xfs_dir2_db_to_fdb, .db_to_fdindex = xfs_dir2_db_to_fdindex, }; @@ -537,7 +524,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), .free_max_bests = xfs_dir2_free_max_bests, - .free_bests_p = xfs_dir2_free_bests_p, .db_to_fdb = xfs_dir2_db_to_fdb, .db_to_fdindex = xfs_dir2_db_to_fdindex, }; @@ -574,7 +560,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = { .free_hdr_size = sizeof(struct xfs_dir3_free_hdr), .free_max_bests = xfs_dir3_free_max_bests, - .free_bests_p = xfs_dir3_free_bests_p, .db_to_fdb = xfs_dir3_db_to_fdb, .db_to_fdindex = xfs_dir3_db_to_fdindex, }; diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index 613a78281d03..402f00326b64 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -74,7 +74,6 @@ struct xfs_dir_ops { int free_hdr_size; int (*free_max_bests)(struct xfs_da_geometry *geo); - __be16 * (*free_bests_p)(struct xfs_dir2_free *free); xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo, xfs_dir2_db_t db); int (*db_to_fdindex)(struct xfs_da_geometry *geo, diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index b435379ddaa2..bbbd7b96678a 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -1680,7 +1680,6 @@ xfs_dir2_node_to_leaf( int error; /* error return code */ struct xfs_buf *fbp; /* buffer for freespace block */ xfs_fileoff_t fo; /* freespace file offset */ - xfs_dir2_free_t *free; /* freespace structure */ struct xfs_buf *lbp; /* buffer for leaf block */ xfs_dir2_leaf_tail_t *ltp; /* tail of leaf structure */ xfs_dir2_leaf_t *leaf; /* leaf structure */ @@ -1749,8 +1748,7 @@ xfs_dir2_node_to_leaf( error = xfs_dir2_free_read(tp, dp, args->geo->freeblk, &fbp); if (error) return error; - free = fbp->b_addr; - xfs_dir2_free_hdr_from_disk(mp, &freehdr, free); + xfs_dir2_free_hdr_from_disk(mp, &freehdr, fbp->b_addr); ASSERT(!freehdr.firstdb); @@ -1784,7 +1782,7 @@ xfs_dir2_node_to_leaf( /* * Set up the leaf bests table. */ - memcpy(xfs_dir2_leaf_bests_p(ltp), dp->d_ops->free_bests_p(free), + memcpy(xfs_dir2_leaf_bests_p(ltp), freehdr.bests, freehdr.nvalid * sizeof(xfs_dir2_data_off_t)); xfs_dir2_leaf_hdr_to_disk(mp, leaf, &leafhdr); diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 6d67ceac48b7..78900ba3db71 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -233,6 +233,7 @@ xfs_dir2_free_hdr_from_disk( to->firstdb = be32_to_cpu(from3->hdr.firstdb); to->nvalid = be32_to_cpu(from3->hdr.nvalid); to->nused = be32_to_cpu(from3->hdr.nused); + to->bests = from3->bests; ASSERT(to->magic == XFS_DIR3_FREE_MAGIC); } else { @@ -240,6 +241,8 @@ xfs_dir2_free_hdr_from_disk( to->firstdb = be32_to_cpu(from->hdr.firstdb); to->nvalid = be32_to_cpu(from->hdr.nvalid); to->nused = be32_to_cpu(from->hdr.nused); + to->bests = from->bests; + ASSERT(to->magic == XFS_DIR2_FREE_MAGIC); } } @@ -338,21 +341,19 @@ xfs_dir3_free_get_buf( STATIC void xfs_dir2_free_log_bests( struct xfs_da_args *args, + struct xfs_dir3_icfree_hdr *hdr, struct xfs_buf *bp, int first, /* first entry to log */ int last) /* last entry to log */ { - xfs_dir2_free_t *free; /* freespace structure */ - __be16 *bests; + struct xfs_dir2_free *free = bp->b_addr; - free = bp->b_addr; - bests = args->dp->d_ops->free_bests_p(free); ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) || free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); xfs_trans_log_buf(args->trans, bp, - (uint)((char *)&bests[first] - (char *)free), - (uint)((char *)&bests[last] - (char *)free + - sizeof(bests[0]) - 1)); + (char *)&hdr->bests[first] - (char *)free, + (char *)&hdr->bests[last] - (char *)free + + sizeof(hdr->bests[0]) - 1); } /* @@ -388,14 +389,12 @@ xfs_dir2_leaf_to_node( int error; /* error return value */ struct xfs_buf *fbp; /* freespace buffer */ xfs_dir2_db_t fdb; /* freespace block number */ - xfs_dir2_free_t *free; /* freespace structure */ __be16 *from; /* pointer to freespace entry */ int i; /* leaf freespace index */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ int n; /* count of live freespc ents */ xfs_dir2_data_off_t off; /* freespace entry value */ - __be16 *to; /* pointer to freespace entry */ xfs_trans_t *tp; /* transaction pointer */ struct xfs_dir3_icfree_hdr freehdr; @@ -417,8 +416,7 @@ xfs_dir2_leaf_to_node( if (error) return error; - free = fbp->b_addr; - xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free); + xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, fbp->b_addr); leaf = lbp->b_addr; ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); if (be32_to_cpu(ltp->bestcount) > @@ -432,11 +430,11 @@ xfs_dir2_leaf_to_node( * Count active entries. */ from = xfs_dir2_leaf_bests_p(ltp); - to = dp->d_ops->free_bests_p(free); - for (i = n = 0; i < be32_to_cpu(ltp->bestcount); i++, from++, to++) { - if ((off = be16_to_cpu(*from)) != NULLDATAOFF) + for (i = n = 0; i < be32_to_cpu(ltp->bestcount); i++, from++) { + off = be16_to_cpu(*from); + if (off != NULLDATAOFF) n++; - *to = cpu_to_be16(off); + freehdr.bests[i] = cpu_to_be16(off); } /* @@ -446,7 +444,7 @@ xfs_dir2_leaf_to_node( freehdr.nvalid = be32_to_cpu(ltp->bestcount); xfs_dir2_free_hdr_to_disk(dp->i_mount, fbp->b_addr, &freehdr); - xfs_dir2_free_log_bests(args, fbp, 0, freehdr.nvalid - 1); + xfs_dir2_free_log_bests(args, &freehdr, fbp, 0, freehdr.nvalid - 1); xfs_dir2_free_log_header(args, fbp); /* @@ -677,7 +675,7 @@ xfs_dir2_leafn_lookup_for_addname( * in hand, take a look at it. */ if (newdb != curdb) { - __be16 *bests; + struct xfs_dir3_icfree_hdr freehdr; curdb = newdb; /* @@ -712,8 +710,9 @@ xfs_dir2_leafn_lookup_for_addname( /* * If it has room, return it. */ - bests = dp->d_ops->free_bests_p(free); - if (unlikely(bests[fi] == cpu_to_be16(NULLDATAOFF))) { + xfs_dir2_free_hdr_from_disk(mp, &freehdr, free); + if (unlikely( + freehdr.bests[fi] == cpu_to_be16(NULLDATAOFF))) { XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", XFS_ERRLEVEL_LOW, mp); if (curfdb != newfdb) @@ -721,7 +720,7 @@ xfs_dir2_leafn_lookup_for_addname( return -EFSCORRUPTED; } curfdb = newfdb; - if (be16_to_cpu(bests[fi]) >= length) + if (be16_to_cpu(freehdr.bests[fi]) >= length) goto out; } } @@ -1168,19 +1167,17 @@ xfs_dir3_data_block_free( int longest) { int logfree = 0; - __be16 *bests; struct xfs_dir3_icfree_hdr freehdr; struct xfs_inode *dp = args->dp; xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free); - bests = dp->d_ops->free_bests_p(free); if (hdr) { /* * Data block is not empty, just set the free entry to the new * value. */ - bests[findex] = cpu_to_be16(longest); - xfs_dir2_free_log_bests(args, fbp, findex, findex); + freehdr.bests[findex] = cpu_to_be16(longest); + xfs_dir2_free_log_bests(args, &freehdr, fbp, findex, findex); return 0; } @@ -1196,14 +1193,14 @@ xfs_dir3_data_block_free( int i; /* free entry index */ for (i = findex - 1; i >= 0; i--) { - if (bests[i] != cpu_to_be16(NULLDATAOFF)) + if (freehdr.bests[i] != cpu_to_be16(NULLDATAOFF)) break; } freehdr.nvalid = i + 1; logfree = 0; } else { /* Not the last entry, just punch it out. */ - bests[findex] = cpu_to_be16(NULLDATAOFF); + freehdr.bests[findex] = cpu_to_be16(NULLDATAOFF); logfree = 1; } @@ -1232,7 +1229,7 @@ xfs_dir3_data_block_free( /* Log the free entry that changed, unless we got rid of it. */ if (logfree) - xfs_dir2_free_log_bests(args, fbp, findex, findex); + xfs_dir2_free_log_bests(args, &freehdr, fbp, findex, findex); return 0; } @@ -1673,11 +1670,9 @@ xfs_dir2_node_add_datablk( struct xfs_trans *tp = args->trans; struct xfs_mount *mp = dp->i_mount; struct xfs_dir2_data_free *bf; - struct xfs_dir2_free *free = NULL; xfs_dir2_db_t fbno; struct xfs_buf *fbp; struct xfs_buf *dbp; - __be16 *bests = NULL; int error; /* Not allowed to allocate, return failure. */ @@ -1733,18 +1728,14 @@ xfs_dir2_node_add_datablk( error = xfs_dir3_free_get_buf(args, fbno, &fbp); if (error) return error; - free = fbp->b_addr; - bests = dp->d_ops->free_bests_p(free); - xfs_dir2_free_hdr_from_disk(mp, hdr, free); + xfs_dir2_free_hdr_from_disk(mp, hdr, fbp->b_addr); /* Remember the first slot as our empty slot. */ hdr->firstdb = (fbno - xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET)) * dp->d_ops->free_max_bests(args->geo); } else { - free = fbp->b_addr; - bests = dp->d_ops->free_bests_p(free); - xfs_dir2_free_hdr_from_disk(mp, hdr, free); + xfs_dir2_free_hdr_from_disk(mp, hdr, fbp->b_addr); } /* Set the freespace block index from the data block number. */ @@ -1754,14 +1745,14 @@ xfs_dir2_node_add_datablk( if (*findex >= hdr->nvalid) { ASSERT(*findex < dp->d_ops->free_max_bests(args->geo)); hdr->nvalid = *findex + 1; - bests[*findex] = cpu_to_be16(NULLDATAOFF); + hdr->bests[*findex] = cpu_to_be16(NULLDATAOFF); } /* * If this entry was for an empty data block (this should always be * true) then update the header. */ - if (bests[*findex] == cpu_to_be16(NULLDATAOFF)) { + if (hdr->bests[*findex] == cpu_to_be16(NULLDATAOFF)) { hdr->nused++; xfs_dir2_free_hdr_to_disk(mp, fbp->b_addr, hdr); xfs_dir2_free_log_header(args, fbp); @@ -1769,7 +1760,7 @@ xfs_dir2_node_add_datablk( /* Update the freespace value for the new block in the table. */ bf = dp->d_ops->data_bestfree_p(dbp->b_addr); - bests[*findex] = bf[0].length; + hdr->bests[*findex] = bf[0].length; *dbpp = dbp; *fbpp = fbp; @@ -1786,7 +1777,6 @@ xfs_dir2_node_find_freeblk( int *findexp, int length) { - struct xfs_dir2_free *free = NULL; struct xfs_inode *dp = args->dp; struct xfs_trans *tp = args->trans; struct xfs_buf *fbp = NULL; @@ -1796,7 +1786,6 @@ xfs_dir2_node_find_freeblk( xfs_dir2_db_t dbno = -1; xfs_dir2_db_t fbno; xfs_fileoff_t fo; - __be16 *bests = NULL; int findex = 0; int error; @@ -1807,16 +1796,13 @@ xfs_dir2_node_find_freeblk( */ if (fblk) { fbp = fblk->bp; - free = fbp->b_addr; findex = fblk->index; + xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, fbp->b_addr); if (findex >= 0) { /* caller already found the freespace for us. */ - bests = dp->d_ops->free_bests_p(free); - xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, free); - ASSERT(findex < hdr->nvalid); - ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF); - ASSERT(be16_to_cpu(bests[findex]) >= length); + ASSERT(be16_to_cpu(hdr->bests[findex]) != NULLDATAOFF); + ASSERT(be16_to_cpu(hdr->bests[findex]) >= length); dbno = hdr->firstdb + findex; goto found_block; } @@ -1859,14 +1845,12 @@ xfs_dir2_node_find_freeblk( if (!fbp) continue; - free = fbp->b_addr; - bests = dp->d_ops->free_bests_p(free); - xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, free); + xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, fbp->b_addr); /* Scan the free entry array for a large enough free space. */ for (findex = hdr->nvalid - 1; findex >= 0; findex--) { - if (be16_to_cpu(bests[findex]) != NULLDATAOFF && - be16_to_cpu(bests[findex]) >= length) { + if (be16_to_cpu(hdr->bests[findex]) != NULLDATAOFF && + be16_to_cpu(hdr->bests[findex]) >= length) { dbno = hdr->firstdb + findex; goto found_block; } @@ -1883,7 +1867,6 @@ found_block: return 0; } - /* * Add the data entry for a node-format directory name addition. * The leaf entry is added in xfs_dir2_leafn_add. @@ -1898,7 +1881,6 @@ xfs_dir2_node_addname_int( struct xfs_dir2_data_entry *dep; /* data entry pointer */ struct xfs_dir2_data_hdr *hdr; /* data block header */ struct xfs_dir2_data_free *bf; - struct xfs_dir2_free *free = NULL; /* freespace block structure */ struct xfs_trans *tp = args->trans; struct xfs_inode *dp = args->dp; struct xfs_dir3_icfree_hdr freehdr; @@ -1913,7 +1895,6 @@ xfs_dir2_node_addname_int( int needlog = 0; /* need to log data header */ int needscan = 0; /* need to rescan data frees */ __be16 *tagp; /* data entry tag pointer */ - __be16 *bests; length = dp->d_ops->data_entsize(args->namelen); error = xfs_dir2_node_find_freeblk(args, fblk, &dbno, &fbp, &freehdr, @@ -1984,16 +1965,14 @@ xfs_dir2_node_addname_int( xfs_dir2_data_log_header(args, dbp); /* If the freespace block entry is now wrong, update it. */ - free = fbp->b_addr; - bests = dp->d_ops->free_bests_p(free); - if (bests[findex] != bf[0].length) { - bests[findex] = bf[0].length; + if (freehdr.bests[findex] != bf[0].length) { + freehdr.bests[findex] = bf[0].length; logfree = 1; } /* Log the freespace entry if needed. */ if (logfree) - xfs_dir2_free_log_bests(args, fbp, findex, findex); + xfs_dir2_free_log_bests(args, &freehdr, fbp, findex, findex); /* Return the data block and offset in args. */ args->blkno = (xfs_dablk_t)dbno; diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index 2c3370a3c010..9128f7aae0be 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h @@ -31,6 +31,12 @@ struct xfs_dir3_icfree_hdr { uint32_t firstdb; uint32_t nvalid; uint32_t nused; + + /* + * Pointer to the on-disk format entries, which are behind the + * variable size (v4 vs v5) header in the on-disk block. + */ + __be16 *bests; }; /* xfs_dir2.c */ diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index 1314a9159156..b474c6f1926f 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -583,7 +583,6 @@ xchk_directory_free_bestfree( struct xfs_dir3_icfree_hdr freehdr; struct xfs_buf *dbp; struct xfs_buf *bp; - __be16 *bestp; __u16 best; unsigned int stale = 0; int i; @@ -604,9 +603,8 @@ xchk_directory_free_bestfree( /* Check all the entries. */ xfs_dir2_free_hdr_from_disk(sc->ip->i_mount, &freehdr, bp->b_addr); - bestp = sc->ip->d_ops->free_bests_p(bp->b_addr); - for (i = 0; i < freehdr.nvalid; i++, bestp++) { - best = be16_to_cpu(*bestp); + for (i = 0; i < freehdr.nvalid; i++) { + best = be16_to_cpu(freehdr.bests[i]); if (best == NULLDATAOFF) { stale++; continue; -- cgit v1.2.3-70-g09d2 From ed1d612fbe6ba95a4d16b56bbfb1f90d48a42149 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 15:01:29 -0800 Subject: xfs: move the dir2 free header size to struct xfs_da_geometry Move the free header size towards our structure for dir/attr geometry parameters. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_btree.h | 1 + fs/xfs/libxfs/xfs_da_format.c | 3 --- fs/xfs/libxfs/xfs_dir2.c | 2 ++ fs/xfs/libxfs/xfs_dir2.h | 1 - fs/xfs/libxfs/xfs_dir2_node.c | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index c6ff5329e92b..e8f0b7ac051c 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -29,6 +29,7 @@ struct xfs_da_geometry { unsigned int leaf_hdr_size; /* dir2 leaf header size */ unsigned int leaf_max_ents; /* # of entries in dir2 leaf */ xfs_dablk_t leafblk; /* blockno of leaf data v2 */ + unsigned int free_hdr_size; /* dir2 free header size */ xfs_dablk_t freeblk; /* blockno of free data v2 */ }; diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index 7263b6d6a135..1fc8982c830f 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -486,7 +486,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { .data_entry_p = xfs_dir2_data_entry_p, .data_unused_p = xfs_dir2_data_unused_p, - .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), .free_max_bests = xfs_dir2_free_max_bests, .db_to_fdb = xfs_dir2_db_to_fdb, .db_to_fdindex = xfs_dir2_db_to_fdindex, @@ -522,7 +521,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .data_entry_p = xfs_dir2_data_entry_p, .data_unused_p = xfs_dir2_data_unused_p, - .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), .free_max_bests = xfs_dir2_free_max_bests, .db_to_fdb = xfs_dir2_db_to_fdb, .db_to_fdindex = xfs_dir2_db_to_fdindex, @@ -558,7 +556,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = { .data_entry_p = xfs_dir3_data_entry_p, .data_unused_p = xfs_dir3_data_unused_p, - .free_hdr_size = sizeof(struct xfs_dir3_free_hdr), .free_max_bests = xfs_dir3_free_max_bests, .db_to_fdb = xfs_dir3_db_to_fdb, .db_to_fdindex = xfs_dir3_db_to_fdindex, diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 8093afb389a1..eee75ec9707f 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -125,9 +125,11 @@ xfs_da_mount( if (xfs_sb_version_hascrc(&mp->m_sb)) { dageo->node_hdr_size = sizeof(struct xfs_da3_node_hdr); dageo->leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr); + dageo->free_hdr_size = sizeof(struct xfs_dir3_free_hdr); } else { dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr); dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr); + dageo->free_hdr_size = sizeof(struct xfs_dir2_free_hdr); } dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) / sizeof(struct xfs_dir2_leaf_entry); diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index 402f00326b64..d87cd71e3cf1 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -72,7 +72,6 @@ struct xfs_dir_ops { struct xfs_dir2_data_unused * (*data_unused_p)(struct xfs_dir2_data_hdr *hdr); - int free_hdr_size; int (*free_max_bests)(struct xfs_da_geometry *geo); xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo, xfs_dir2_db_t db); diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 78900ba3db71..b9d5f4ae9a8d 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -372,7 +372,7 @@ xfs_dir2_free_log_header( free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); #endif xfs_trans_log_buf(args->trans, bp, 0, - args->dp->d_ops->free_hdr_size - 1); + args->geo->free_hdr_size - 1); } /* -- cgit v1.2.3-70-g09d2 From 5893e4feb0eac11aab7b93ff9fe7e6e58bcec5ec Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 15:01:30 -0800 Subject: xfs: move the max dir2 free bests count to struct xfs_da_geometry Move the max free bests count towards our structure for dir/attr geometry parameters. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_btree.h | 1 + fs/xfs/libxfs/xfs_da_format.c | 29 ++++------------------------- fs/xfs/libxfs/xfs_dir2.c | 2 ++ fs/xfs/libxfs/xfs_dir2.h | 1 - fs/xfs/libxfs/xfs_dir2_node.c | 12 +++++------- 5 files changed, 12 insertions(+), 33 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index e8f0b7ac051c..40110acf9f8a 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -30,6 +30,7 @@ struct xfs_da_geometry { unsigned int leaf_max_ents; /* # of entries in dir2 leaf */ xfs_dablk_t leafblk; /* blockno of leaf data v2 */ unsigned int free_hdr_size; /* dir2 free header size */ + unsigned int free_max_bests; /* # of bests entries in dir2 free */ xfs_dablk_t freeblk; /* blockno of free data v2 */ }; diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index 1fc8982c830f..d2d3144c1598 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -400,17 +400,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr) ((char *)hdr + sizeof(struct xfs_dir3_data_hdr)); } - -/* - * Directory free space block operations - */ -static int -xfs_dir2_free_max_bests(struct xfs_da_geometry *geo) -{ - return (geo->blksize - sizeof(struct xfs_dir2_free_hdr)) / - sizeof(xfs_dir2_data_off_t); -} - /* * Convert data space db to the corresponding free db. */ @@ -418,7 +407,7 @@ static xfs_dir2_db_t xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db) { return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) + - (db / xfs_dir2_free_max_bests(geo)); + (db / geo->free_max_bests); } /* @@ -427,14 +416,7 @@ xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db) static int xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db) { - return db % xfs_dir2_free_max_bests(geo); -} - -static int -xfs_dir3_free_max_bests(struct xfs_da_geometry *geo) -{ - return (geo->blksize - sizeof(struct xfs_dir3_free_hdr)) / - sizeof(xfs_dir2_data_off_t); + return db % geo->free_max_bests; } /* @@ -444,7 +426,7 @@ static xfs_dir2_db_t xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db) { return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) + - (db / xfs_dir3_free_max_bests(geo)); + (db / geo->free_max_bests); } /* @@ -453,7 +435,7 @@ xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db) static int xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db) { - return db % xfs_dir3_free_max_bests(geo); + return db % geo->free_max_bests; } static const struct xfs_dir_ops xfs_dir2_ops = { @@ -486,7 +468,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { .data_entry_p = xfs_dir2_data_entry_p, .data_unused_p = xfs_dir2_data_unused_p, - .free_max_bests = xfs_dir2_free_max_bests, .db_to_fdb = xfs_dir2_db_to_fdb, .db_to_fdindex = xfs_dir2_db_to_fdindex, }; @@ -521,7 +502,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .data_entry_p = xfs_dir2_data_entry_p, .data_unused_p = xfs_dir2_data_unused_p, - .free_max_bests = xfs_dir2_free_max_bests, .db_to_fdb = xfs_dir2_db_to_fdb, .db_to_fdindex = xfs_dir2_db_to_fdindex, }; @@ -556,7 +536,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = { .data_entry_p = xfs_dir3_data_entry_p, .data_unused_p = xfs_dir3_data_unused_p, - .free_max_bests = xfs_dir3_free_max_bests, .db_to_fdb = xfs_dir3_db_to_fdb, .db_to_fdindex = xfs_dir3_db_to_fdindex, }; diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index eee75ec9707f..77a297e7d91c 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -133,6 +133,8 @@ xfs_da_mount( } dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) / sizeof(struct xfs_dir2_leaf_entry); + dageo->free_max_bests = (dageo->blksize - dageo->free_hdr_size) / + sizeof(xfs_dir2_data_off_t); /* * Now we've set up the block conversion variables, we can calculate the diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index d87cd71e3cf1..e3c1385d1522 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -72,7 +72,6 @@ struct xfs_dir_ops { struct xfs_dir2_data_unused * (*data_unused_p)(struct xfs_dir2_data_hdr *hdr); - int (*free_max_bests)(struct xfs_da_geometry *geo); xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo, xfs_dir2_db_t db); int (*db_to_fdindex)(struct xfs_da_geometry *geo, diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index b9d5f4ae9a8d..5d35a6d77b56 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -160,10 +160,9 @@ xfs_dir3_free_header_check( struct xfs_buf *bp) { struct xfs_mount *mp = dp->i_mount; + int maxbests = mp->m_dir_geo->free_max_bests; unsigned int firstdb; - int maxbests; - maxbests = dp->d_ops->free_max_bests(mp->m_dir_geo); firstdb = (xfs_dir2_da_to_db(mp->m_dir_geo, fbno) - xfs_dir2_byte_to_db(mp->m_dir_geo, XFS_DIR2_FREE_OFFSET)) * maxbests; @@ -562,8 +561,7 @@ xfs_dir2_free_hdr_check( xfs_dir2_free_hdr_from_disk(dp->i_mount, &hdr, bp->b_addr); - ASSERT((hdr.firstdb % - dp->d_ops->free_max_bests(dp->i_mount->m_dir_geo)) == 0); + ASSERT((hdr.firstdb % dp->i_mount->m_dir_geo->free_max_bests) == 0); ASSERT(hdr.firstdb <= db); ASSERT(db < hdr.firstdb + hdr.nvalid); } @@ -1340,7 +1338,7 @@ xfs_dir2_leafn_remove( struct xfs_dir3_icfree_hdr freehdr; xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free); - ASSERT(freehdr.firstdb == dp->d_ops->free_max_bests(args->geo) * + ASSERT(freehdr.firstdb == args->geo->free_max_bests * (fdb - xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET))); } @@ -1733,7 +1731,7 @@ xfs_dir2_node_add_datablk( /* Remember the first slot as our empty slot. */ hdr->firstdb = (fbno - xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET)) * - dp->d_ops->free_max_bests(args->geo); + args->geo->free_max_bests; } else { xfs_dir2_free_hdr_from_disk(mp, hdr, fbp->b_addr); } @@ -1743,7 +1741,7 @@ xfs_dir2_node_add_datablk( /* Extend the freespace table if the new data block is off the end. */ if (*findex >= hdr->nvalid) { - ASSERT(*findex < dp->d_ops->free_max_bests(args->geo)); + ASSERT(*findex < args->geo->free_max_bests); hdr->nvalid = *findex + 1; hdr->bests[*findex] = cpu_to_be16(NULLDATAOFF); } -- cgit v1.2.3-70-g09d2 From 3d92c93b7065be28eda33f92681d2f1121fbf8bf Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 15:01:39 -0800 Subject: xfs: devirtualize ->db_to_fdb and ->db_to_fdindex Now that the max bests value is in struct xfs_da_geometry both instances of ->db_to_fdb and ->db_to_fdindex are identical. Replace them with local xfs_dir2_db_to_fdb and xfs_dir2_db_to_fdindex functions in xfs_dir2_node.c. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_format.c | 47 ------------------------------------------- fs/xfs/libxfs/xfs_dir2.h | 5 ----- fs/xfs/libxfs/xfs_dir2_node.c | 35 ++++++++++++++++++++++++-------- 3 files changed, 27 insertions(+), 60 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index d2d3144c1598..2b708b9fae1a 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -400,44 +400,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr) ((char *)hdr + sizeof(struct xfs_dir3_data_hdr)); } -/* - * Convert data space db to the corresponding free db. - */ -static xfs_dir2_db_t -xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db) -{ - return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) + - (db / geo->free_max_bests); -} - -/* - * Convert data space db to the corresponding index in a free db. - */ -static int -xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db) -{ - return db % geo->free_max_bests; -} - -/* - * Convert data space db to the corresponding free db. - */ -static xfs_dir2_db_t -xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db) -{ - return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) + - (db / geo->free_max_bests); -} - -/* - * Convert data space db to the corresponding index in a free db. - */ -static int -xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db) -{ - return db % geo->free_max_bests; -} - static const struct xfs_dir_ops xfs_dir2_ops = { .sf_entsize = xfs_dir2_sf_entsize, .sf_nextentry = xfs_dir2_sf_nextentry, @@ -467,9 +429,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { .data_first_entry_p = xfs_dir2_data_first_entry_p, .data_entry_p = xfs_dir2_data_entry_p, .data_unused_p = xfs_dir2_data_unused_p, - - .db_to_fdb = xfs_dir2_db_to_fdb, - .db_to_fdindex = xfs_dir2_db_to_fdindex, }; static const struct xfs_dir_ops xfs_dir2_ftype_ops = { @@ -501,9 +460,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .data_first_entry_p = xfs_dir2_ftype_data_first_entry_p, .data_entry_p = xfs_dir2_data_entry_p, .data_unused_p = xfs_dir2_data_unused_p, - - .db_to_fdb = xfs_dir2_db_to_fdb, - .db_to_fdindex = xfs_dir2_db_to_fdindex, }; static const struct xfs_dir_ops xfs_dir3_ops = { @@ -535,9 +491,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = { .data_first_entry_p = xfs_dir3_data_first_entry_p, .data_entry_p = xfs_dir3_data_entry_p, .data_unused_p = xfs_dir3_data_unused_p, - - .db_to_fdb = xfs_dir3_db_to_fdb, - .db_to_fdindex = xfs_dir3_db_to_fdindex, }; /* diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index e3c1385d1522..e302679d8c80 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -71,11 +71,6 @@ struct xfs_dir_ops { (*data_entry_p)(struct xfs_dir2_data_hdr *hdr); struct xfs_dir2_data_unused * (*data_unused_p)(struct xfs_dir2_data_hdr *hdr); - - xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo, - xfs_dir2_db_t db); - int (*db_to_fdindex)(struct xfs_da_geometry *geo, - xfs_dir2_db_t db); }; extern const struct xfs_dir_ops * diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 5d35a6d77b56..daa9dc7a7762 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -33,6 +33,25 @@ static int xfs_dir2_leafn_remove(xfs_da_args_t *args, struct xfs_buf *bp, int index, xfs_da_state_blk_t *dblk, int *rval); +/* + * Convert data space db to the corresponding free db. + */ +static xfs_dir2_db_t +xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db) +{ + return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) + + (db / geo->free_max_bests); +} + +/* + * Convert data space db to the corresponding index in a free db. + */ +static int +xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db) +{ + return db % geo->free_max_bests; +} + /* * Check internal consistency of a leafn block. */ @@ -680,7 +699,7 @@ xfs_dir2_leafn_lookup_for_addname( * Convert the data block to the free block * holding its freespace information. */ - newfdb = dp->d_ops->db_to_fdb(args->geo, newdb); + newfdb = xfs_dir2_db_to_fdb(args->geo, newdb); /* * If it's not the one we have in hand, read it in. */ @@ -704,7 +723,7 @@ xfs_dir2_leafn_lookup_for_addname( /* * Get the index for our entry. */ - fi = dp->d_ops->db_to_fdindex(args->geo, curdb); + fi = xfs_dir2_db_to_fdindex(args->geo, curdb); /* * If it has room, return it. */ @@ -1326,7 +1345,7 @@ xfs_dir2_leafn_remove( * Convert the data block number to a free block, * read in the free block. */ - fdb = dp->d_ops->db_to_fdb(args->geo, db); + fdb = xfs_dir2_db_to_fdb(args->geo, db); error = xfs_dir2_free_read(tp, dp, xfs_dir2_db_to_da(args->geo, fdb), &fbp); @@ -1346,7 +1365,7 @@ xfs_dir2_leafn_remove( /* * Calculate which entry we need to fix. */ - findex = dp->d_ops->db_to_fdindex(args->geo, db); + findex = xfs_dir2_db_to_fdindex(args->geo, db); longest = be16_to_cpu(bf[0].length); /* * If the data block is now empty we can get rid of it @@ -1689,7 +1708,7 @@ xfs_dir2_node_add_datablk( * Get the freespace block corresponding to the data block * that was just allocated. */ - fbno = dp->d_ops->db_to_fdb(args->geo, *dbno); + fbno = xfs_dir2_db_to_fdb(args->geo, *dbno); error = xfs_dir2_free_try_read(tp, dp, xfs_dir2_db_to_da(args->geo, fbno), &fbp); if (error) @@ -1704,11 +1723,11 @@ xfs_dir2_node_add_datablk( if (error) return error; - if (dp->d_ops->db_to_fdb(args->geo, *dbno) != fbno) { + if (xfs_dir2_db_to_fdb(args->geo, *dbno) != fbno) { xfs_alert(mp, "%s: dir ino %llu needed freesp block %lld for data block %lld, got %lld", __func__, (unsigned long long)dp->i_ino, - (long long)dp->d_ops->db_to_fdb(args->geo, *dbno), + (long long)xfs_dir2_db_to_fdb(args->geo, *dbno), (long long)*dbno, (long long)fbno); if (fblk) { xfs_alert(mp, @@ -1737,7 +1756,7 @@ xfs_dir2_node_add_datablk( } /* Set the freespace block index from the data block number. */ - *findex = dp->d_ops->db_to_fdindex(args->geo, *dbno); + *findex = xfs_dir2_db_to_fdindex(args->geo, *dbno); /* Extend the freespace table if the new data block is off the end. */ if (*findex >= hdr->nvalid) { -- cgit v1.2.3-70-g09d2 From fdbb8c5b805c19bc2764aa1b91952e75e4c1c086 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 15:05:37 -0800 Subject: xfs: devirtualize ->data_entsize Replace the ->data_entsize dir ops method with a directly called xfs_dir2_data_entsize helper that takes care of the differences between the directory format with and without the file type field. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_format.c | 22 ++++++++-------------- fs/xfs/libxfs/xfs_dir2.h | 3 +-- fs/xfs/libxfs/xfs_dir2_block.c | 9 +++++---- fs/xfs/libxfs/xfs_dir2_data.c | 14 +++++++------- fs/xfs/libxfs/xfs_dir2_leaf.c | 5 +++-- fs/xfs/libxfs/xfs_dir2_node.c | 7 ++++--- fs/xfs/libxfs/xfs_dir2_priv.h | 2 ++ fs/xfs/libxfs/xfs_dir2_sf.c | 14 +++++++------- fs/xfs/scrub/dir.c | 4 ++-- fs/xfs/xfs_dir2_readdir.c | 11 ++++++----- 10 files changed, 45 insertions(+), 46 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index e70cc54d99e1..e4498bd0d6c0 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -41,18 +41,15 @@ sizeof(xfs_dir2_data_off_t) + sizeof(uint8_t)), \ XFS_DIR2_DATA_ALIGN) -static int +int xfs_dir2_data_entsize( + struct xfs_mount *mp, int n) { - return XFS_DIR2_DATA_ENTSIZE(n); -} - -static int -xfs_dir3_data_entsize( - int n) -{ - return XFS_DIR3_DATA_ENTSIZE(n); + if (xfs_sb_version_hasftype(&mp->m_sb)) + return XFS_DIR3_DATA_ENTSIZE(n); + else + return XFS_DIR2_DATA_ENTSIZE(n); } static uint8_t @@ -100,7 +97,7 @@ xfs_dir2_data_entry_tag_p( struct xfs_dir2_data_entry *dep) { return (__be16 *)((char *)dep + - xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16)); + XFS_DIR2_DATA_ENTSIZE(dep->namelen) - sizeof(__be16)); } static __be16 * @@ -108,7 +105,7 @@ xfs_dir3_data_entry_tag_p( struct xfs_dir2_data_entry *dep) { return (__be16 *)((char *)dep + - xfs_dir3_data_entsize(dep->namelen) - sizeof(__be16)); + XFS_DIR3_DATA_ENTSIZE(dep->namelen) - sizeof(__be16)); } static struct xfs_dir2_data_free * @@ -124,7 +121,6 @@ xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr) } static const struct xfs_dir_ops xfs_dir2_ops = { - .data_entsize = xfs_dir2_data_entsize, .data_get_ftype = xfs_dir2_data_get_ftype, .data_put_ftype = xfs_dir2_data_put_ftype, .data_entry_tag_p = xfs_dir2_data_entry_tag_p, @@ -137,7 +133,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { }; static const struct xfs_dir_ops xfs_dir2_ftype_ops = { - .data_entsize = xfs_dir3_data_entsize, .data_get_ftype = xfs_dir3_data_get_ftype, .data_put_ftype = xfs_dir3_data_put_ftype, .data_entry_tag_p = xfs_dir3_data_entry_tag_p, @@ -150,7 +145,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { }; static const struct xfs_dir_ops xfs_dir3_ops = { - .data_entsize = xfs_dir3_data_entsize, .data_get_ftype = xfs_dir3_data_get_ftype, .data_put_ftype = xfs_dir3_data_put_ftype, .data_entry_tag_p = xfs_dir3_data_entry_tag_p, diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index 3a4b98d4973d..f717b1cdb208 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -32,7 +32,6 @@ extern unsigned char xfs_mode_to_ftype(int mode); * directory operations vector for encode/decode routines */ struct xfs_dir_ops { - int (*data_entsize)(int len); uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep); void (*data_put_ftype)(struct xfs_dir2_data_entry *dep, uint8_t ftype); @@ -85,7 +84,7 @@ extern int xfs_dir2_isleaf(struct xfs_da_args *args, int *r); extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, struct xfs_buf *bp); -extern void xfs_dir2_data_freescan_int(struct xfs_da_geometry *geo, +extern void xfs_dir2_data_freescan_int(struct xfs_mount *mp, const struct xfs_dir_ops *ops, struct xfs_dir2_data_hdr *hdr, int *loghead); extern void xfs_dir2_data_freescan(struct xfs_inode *dp, diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 9061f378d52a..a83fcf4ac35c 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -355,7 +355,7 @@ xfs_dir2_block_addname( if (error) return error; - len = dp->d_ops->data_entsize(args->namelen); + len = xfs_dir2_data_entsize(dp->i_mount, args->namelen); /* * Set up pointers to parts of the block. @@ -791,7 +791,8 @@ xfs_dir2_block_removename( needlog = needscan = 0; xfs_dir2_data_make_free(args, bp, (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr), - dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan); + xfs_dir2_data_entsize(dp->i_mount, dep->namelen), &needlog, + &needscan); /* * Fix up the block tail. */ @@ -1149,7 +1150,7 @@ xfs_dir2_sf_to_block( xfs_dir2_data_log_entry(args, bp, dep); blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot); blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(offset)); - offset += dp->d_ops->data_entsize(dep->namelen); + offset += xfs_dir2_data_entsize(mp, dep->namelen); /* * Create entry for .. @@ -1164,7 +1165,7 @@ xfs_dir2_sf_to_block( xfs_dir2_data_log_entry(args, bp, dep); blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(offset)); - offset += dp->d_ops->data_entsize(dep->namelen); + offset += xfs_dir2_data_entsize(mp, dep->namelen); /* * Loop over existing entries, stuff them in. diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index f5fa8b9187b0..830dfd9edfda 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -13,6 +13,7 @@ #include "xfs_mount.h" #include "xfs_inode.h" #include "xfs_dir2.h" +#include "xfs_dir2_priv.h" #include "xfs_error.h" #include "xfs_trans.h" #include "xfs_buf_item.h" @@ -179,7 +180,7 @@ __xfs_dir3_data_check( return __this_address; if (xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber))) return __this_address; - if (offset + ops->data_entsize(dep->namelen) > end) + if (offset + xfs_dir2_data_entsize(mp, dep->namelen) > end) return __this_address; if (be16_to_cpu(*ops->data_entry_tag_p(dep)) != offset) return __this_address; @@ -203,7 +204,7 @@ __xfs_dir3_data_check( if (i >= be32_to_cpu(btp->count)) return __this_address; } - offset += ops->data_entsize(dep->namelen); + offset += xfs_dir2_data_entsize(mp, dep->namelen); } /* * Need to have seen all the entries and all the bestfree slots. @@ -567,7 +568,7 @@ xfs_dir2_data_freeremove( */ void xfs_dir2_data_freescan_int( - struct xfs_da_geometry *geo, + struct xfs_mount *mp, const struct xfs_dir_ops *ops, struct xfs_dir2_data_hdr *hdr, int *loghead) @@ -588,7 +589,7 @@ xfs_dir2_data_freescan_int( memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT); *loghead = 1; - end = xfs_dir3_data_end_offset(geo, addr); + end = xfs_dir3_data_end_offset(mp->m_dir_geo, addr); while (offset < end) { struct xfs_dir2_data_unused *dup = addr + offset; struct xfs_dir2_data_entry *dep = addr + offset; @@ -608,7 +609,7 @@ xfs_dir2_data_freescan_int( * For active entries, check their tags and skip them. */ ASSERT(offset == be16_to_cpu(*ops->data_entry_tag_p(dep))); - offset += ops->data_entsize(dep->namelen); + offset += xfs_dir2_data_entsize(mp, dep->namelen); } } @@ -618,8 +619,7 @@ xfs_dir2_data_freescan( struct xfs_dir2_data_hdr *hdr, int *loghead) { - return xfs_dir2_data_freescan_int(dp->i_mount->m_dir_geo, dp->d_ops, - hdr, loghead); + return xfs_dir2_data_freescan_int(dp->i_mount, dp->d_ops, hdr, loghead); } /* diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index bbbd7b96678a..dd7b4bd8ed61 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -660,7 +660,7 @@ xfs_dir2_leaf_addname( xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); ents = leafhdr.ents; bestsp = xfs_dir2_leaf_bests_p(ltp); - length = dp->d_ops->data_entsize(args->namelen); + length = xfs_dir2_data_entsize(dp->i_mount, args->namelen); /* * See if there are any entries with the same hash value @@ -1397,7 +1397,8 @@ xfs_dir2_leaf_removename( */ xfs_dir2_data_make_free(args, dbp, (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr), - dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan); + xfs_dir2_data_entsize(dp->i_mount, dep->namelen), &needlog, + &needscan); /* * We just mark the leaf entry stale by putting a null in it. */ diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index daa9dc7a7762..ca346c9cc7c8 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -666,7 +666,7 @@ xfs_dir2_leafn_lookup_for_addname( ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) || free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); } - length = dp->d_ops->data_entsize(args->namelen); + length = xfs_dir2_data_entsize(mp, args->namelen); /* * Loop over leaf entries with the right hash value. */ @@ -1320,7 +1320,8 @@ xfs_dir2_leafn_remove( longest = be16_to_cpu(bf[0].length); needlog = needscan = 0; xfs_dir2_data_make_free(args, dbp, off, - dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan); + xfs_dir2_data_entsize(dp->i_mount, dep->namelen), &needlog, + &needscan); /* * Rescan the data block freespaces for bestfree. * Log the data block header if needed. @@ -1913,7 +1914,7 @@ xfs_dir2_node_addname_int( int needscan = 0; /* need to rescan data frees */ __be16 *tagp; /* data entry tag pointer */ - length = dp->d_ops->data_entsize(args->namelen); + length = xfs_dir2_data_entsize(dp->i_mount, args->namelen); error = xfs_dir2_node_find_freeblk(args, fblk, &dbno, &fbp, &freehdr, &findex, length); if (error) diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index b49f745f1bc3..c60b8663f754 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h @@ -57,6 +57,8 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args, struct xfs_buf *lbp, struct xfs_buf *dbp); /* xfs_dir2_data.c */ +int xfs_dir2_data_entsize(struct xfs_mount *mp, int n); + #ifdef DEBUG extern void xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp); #else diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c index bb6491a3c473..a41715c9b061 100644 --- a/fs/xfs/libxfs/xfs_dir2_sf.c +++ b/fs/xfs/libxfs/xfs_dir2_sf.c @@ -323,7 +323,7 @@ xfs_dir2_block_to_sf( sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); } - offset += dp->d_ops->data_entsize(dep->namelen); + offset += xfs_dir2_data_entsize(mp, dep->namelen); } ASSERT((char *)sfep - (char *)sfp == size); @@ -540,10 +540,10 @@ xfs_dir2_sf_addname_hard( */ for (offset = dp->d_ops->data_first_offset, oldsfep = xfs_dir2_sf_firstentry(oldsfp), - add_datasize = dp->d_ops->data_entsize(args->namelen), + add_datasize = xfs_dir2_data_entsize(mp, args->namelen), eof = (char *)oldsfep == &buf[old_isize]; !eof; - offset = new_offset + dp->d_ops->data_entsize(oldsfep->namelen), + offset = new_offset + xfs_dir2_data_entsize(mp, oldsfep->namelen), oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep), eof = (char *)oldsfep == &buf[old_isize]) { new_offset = xfs_dir2_sf_get_offset(oldsfep); @@ -615,7 +615,7 @@ xfs_dir2_sf_addname_pick( int used; /* data bytes used */ sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; - size = dp->d_ops->data_entsize(args->namelen); + size = xfs_dir2_data_entsize(mp, args->namelen); offset = dp->d_ops->data_first_offset; sfep = xfs_dir2_sf_firstentry(sfp); holefit = 0; @@ -628,7 +628,7 @@ xfs_dir2_sf_addname_pick( if (!holefit) holefit = offset + size <= xfs_dir2_sf_get_offset(sfep); offset = xfs_dir2_sf_get_offset(sfep) + - dp->d_ops->data_entsize(sfep->namelen); + xfs_dir2_data_entsize(mp, sfep->namelen); sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); } /* @@ -693,7 +693,7 @@ xfs_dir2_sf_check( i8count += ino > XFS_DIR2_MAX_SHORT_INUM; offset = xfs_dir2_sf_get_offset(sfep) + - dp->d_ops->data_entsize(sfep->namelen); + xfs_dir2_data_entsize(mp, sfep->namelen); ASSERT(xfs_dir2_sf_get_ftype(mp, sfep) < XFS_DIR3_FT_MAX); } ASSERT(i8count == sfp->i8count); @@ -793,7 +793,7 @@ xfs_dir2_sf_verify( return __this_address; offset = xfs_dir2_sf_get_offset(sfep) + - dops->data_entsize(sfep->namelen); + xfs_dir2_data_entsize(mp, sfep->namelen); sfep = next_sfep; } diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index 71967ca67302..5347c18745d3 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -265,7 +265,7 @@ xchk_dir_rec( } if (dep == dent) break; - iter_off += mp->m_dir_inode_ops->data_entsize(dep->namelen); + iter_off += xfs_dir2_data_entsize(mp, dep->namelen); } /* Retrieve the entry, sanity check it, and compare hashes. */ @@ -403,7 +403,7 @@ xchk_directory_data_bestfree( if (dup->freetag != cpu_to_be16(XFS_DIR2_DATA_FREE_TAG)) { struct xfs_dir2_data_entry *dep = bp->b_addr + offset; - newlen = d_ops->data_entsize(dep->namelen); + newlen = xfs_dir2_data_entsize(mp, dep->namelen); if (newlen <= 0) { xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index bf3a98967153..edc57bed0f1f 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -78,7 +78,7 @@ xfs_dir2_sf_getdents( dp->d_ops->data_entry_offset); dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, dp->d_ops->data_entry_offset + - dp->d_ops->data_entsize(sizeof(".") - 1)); + xfs_dir2_data_entsize(mp, sizeof(".") - 1)); /* * Put . entry unless we're starting past it. @@ -192,7 +192,7 @@ xfs_dir2_block_getdents( /* * Bump pointer for the next iteration. */ - offset += dp->d_ops->data_entsize(dep->namelen); + offset += xfs_dir2_data_entsize(dp->i_mount, dep->namelen); /* * The entry is before the desired starting point, skip it. @@ -347,6 +347,7 @@ xfs_dir2_leaf_getdents( size_t bufsize) { struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; struct xfs_buf *bp = NULL; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data entry */ xfs_dir2_data_unused_t *dup; /* unused entry */ @@ -422,8 +423,8 @@ xfs_dir2_leaf_getdents( continue; } dep = bp->b_addr + offset; - length = - dp->d_ops->data_entsize(dep->namelen); + length = xfs_dir2_data_entsize(mp, + dep->namelen); offset += length; } /* @@ -454,7 +455,7 @@ xfs_dir2_leaf_getdents( } dep = bp->b_addr + offset; - length = dp->d_ops->data_entsize(dep->namelen); + length = xfs_dir2_data_entsize(mp, dep->namelen); filetype = dp->d_ops->data_get_ftype(dep); ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff; -- cgit v1.2.3-70-g09d2 From 7e8ae7bd1c5d806316e6b6403ac2dd0be7a1f82b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 15:05:37 -0800 Subject: xfs: devirtualize ->data_entry_tag_p Replace the ->data_entry_tag_p dir ops method with a directly called xfs_dir2_data_entry_tag_p helper that takes care of the differences between the directory format with and without the file type field. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_format.c | 22 ---------------------- fs/xfs/libxfs/xfs_dir2.h | 1 - fs/xfs/libxfs/xfs_dir2_block.c | 8 ++++---- fs/xfs/libxfs/xfs_dir2_data.c | 21 ++++++++++++++++++--- fs/xfs/libxfs/xfs_dir2_leaf.c | 2 +- fs/xfs/libxfs/xfs_dir2_node.c | 2 +- fs/xfs/libxfs/xfs_dir2_priv.h | 2 ++ fs/xfs/scrub/dir.c | 2 +- 8 files changed, 27 insertions(+), 33 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index e4498bd0d6c0..483f4ab6abb8 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -89,25 +89,6 @@ xfs_dir3_data_put_ftype( dep->name[dep->namelen] = type; } -/* - * Pointer to an entry's tag word. - */ -static __be16 * -xfs_dir2_data_entry_tag_p( - struct xfs_dir2_data_entry *dep) -{ - return (__be16 *)((char *)dep + - XFS_DIR2_DATA_ENTSIZE(dep->namelen) - sizeof(__be16)); -} - -static __be16 * -xfs_dir3_data_entry_tag_p( - struct xfs_dir2_data_entry *dep) -{ - return (__be16 *)((char *)dep + - XFS_DIR3_DATA_ENTSIZE(dep->namelen) - sizeof(__be16)); -} - static struct xfs_dir2_data_free * xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr) { @@ -123,7 +104,6 @@ xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr) static const struct xfs_dir_ops xfs_dir2_ops = { .data_get_ftype = xfs_dir2_data_get_ftype, .data_put_ftype = xfs_dir2_data_put_ftype, - .data_entry_tag_p = xfs_dir2_data_entry_tag_p, .data_bestfree_p = xfs_dir2_data_bestfree_p, .data_first_offset = sizeof(struct xfs_dir2_data_hdr) + @@ -135,7 +115,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .data_get_ftype = xfs_dir3_data_get_ftype, .data_put_ftype = xfs_dir3_data_put_ftype, - .data_entry_tag_p = xfs_dir3_data_entry_tag_p, .data_bestfree_p = xfs_dir2_data_bestfree_p, .data_first_offset = sizeof(struct xfs_dir2_data_hdr) + @@ -147,7 +126,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { static const struct xfs_dir_ops xfs_dir3_ops = { .data_get_ftype = xfs_dir3_data_get_ftype, .data_put_ftype = xfs_dir3_data_put_ftype, - .data_entry_tag_p = xfs_dir3_data_entry_tag_p, .data_bestfree_p = xfs_dir3_data_bestfree_p, .data_first_offset = sizeof(struct xfs_dir3_data_hdr) + diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index f717b1cdb208..3f46954e9370 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -35,7 +35,6 @@ struct xfs_dir_ops { uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep); void (*data_put_ftype)(struct xfs_dir2_data_entry *dep, uint8_t ftype); - __be16 * (*data_entry_tag_p)(struct xfs_dir2_data_entry *dep); struct xfs_dir2_data_free * (*data_bestfree_p)(struct xfs_dir2_data_hdr *hdr); diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index a83fcf4ac35c..35eda4d18cd8 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -542,7 +542,7 @@ xfs_dir2_block_addname( dep->namelen = args->namelen; memcpy(dep->name, args->name, args->namelen); dp->d_ops->data_put_ftype(dep, args->filetype); - tagp = dp->d_ops->data_entry_tag_p(dep); + tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep); *tagp = cpu_to_be16((char *)dep - (char *)hdr); /* * Clean up the bestfree array and log the header, tail, and entry. @@ -1145,7 +1145,7 @@ xfs_dir2_sf_to_block( dep->namelen = 1; dep->name[0] = '.'; dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR); - tagp = dp->d_ops->data_entry_tag_p(dep); + tagp = xfs_dir2_data_entry_tag_p(mp, dep); *tagp = cpu_to_be16(offset); xfs_dir2_data_log_entry(args, bp, dep); blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot); @@ -1160,7 +1160,7 @@ xfs_dir2_sf_to_block( dep->namelen = 2; dep->name[0] = dep->name[1] = '.'; dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR); - tagp = dp->d_ops->data_entry_tag_p(dep); + tagp = xfs_dir2_data_entry_tag_p(mp, dep); *tagp = cpu_to_be16(offset); xfs_dir2_data_log_entry(args, bp, dep); blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); @@ -1211,7 +1211,7 @@ xfs_dir2_sf_to_block( dep->namelen = sfep->namelen; dp->d_ops->data_put_ftype(dep, xfs_dir2_sf_get_ftype(mp, sfep)); memcpy(dep->name, sfep->name, dep->namelen); - tagp = dp->d_ops->data_entry_tag_p(dep); + tagp = xfs_dir2_data_entry_tag_p(mp, dep); *tagp = cpu_to_be16(newoffset); xfs_dir2_data_log_entry(args, bp, dep); name.name = sfep->name; diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index 830dfd9edfda..3504b230ba1d 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -18,12 +18,25 @@ #include "xfs_trans.h" #include "xfs_buf_item.h" #include "xfs_log.h" +#include "xfs_dir2_priv.h" static xfs_failaddr_t xfs_dir2_data_freefind_verify( struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_free *bf, struct xfs_dir2_data_unused *dup, struct xfs_dir2_data_free **bf_ent); +/* + * Pointer to an entry's tag word. + */ +__be16 * +xfs_dir2_data_entry_tag_p( + struct xfs_mount *mp, + struct xfs_dir2_data_entry *dep) +{ + return (__be16 *)((char *)dep + + xfs_dir2_data_entsize(mp, dep->namelen) - sizeof(__be16)); +} + /* * The number of leaf entries is limited by the size of the block and the amount * of space used by the data entries. We don't know how much space is used by @@ -182,7 +195,7 @@ __xfs_dir3_data_check( return __this_address; if (offset + xfs_dir2_data_entsize(mp, dep->namelen) > end) return __this_address; - if (be16_to_cpu(*ops->data_entry_tag_p(dep)) != offset) + if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)) != offset) return __this_address; if (ops->data_get_ftype(dep) >= XFS_DIR3_FT_MAX) return __this_address; @@ -608,7 +621,8 @@ xfs_dir2_data_freescan_int( /* * For active entries, check their tags and skip them. */ - ASSERT(offset == be16_to_cpu(*ops->data_entry_tag_p(dep))); + ASSERT(offset == + be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep))); offset += xfs_dir2_data_entsize(mp, dep->namelen); } } @@ -703,6 +717,7 @@ xfs_dir2_data_log_entry( struct xfs_buf *bp, xfs_dir2_data_entry_t *dep) /* data entry pointer */ { + struct xfs_mount *mp = bp->b_mount; struct xfs_dir2_data_hdr *hdr = bp->b_addr; ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || @@ -711,7 +726,7 @@ xfs_dir2_data_log_entry( hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); xfs_trans_log_buf(args->trans, bp, (uint)((char *)dep - (char *)hdr), - (uint)((char *)(args->dp->d_ops->data_entry_tag_p(dep) + 1) - + (uint)((char *)(xfs_dir2_data_entry_tag_p(mp, dep) + 1) - (char *)hdr - 1)); } diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index dd7b4bd8ed61..4b6d590c5856 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -866,7 +866,7 @@ xfs_dir2_leaf_addname( dep->namelen = args->namelen; memcpy(dep->name, args->name, dep->namelen); dp->d_ops->data_put_ftype(dep, args->filetype); - tagp = dp->d_ops->data_entry_tag_p(dep); + tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep); *tagp = cpu_to_be16((char *)dep - (char *)hdr); /* * Need to scan fix up the bestfree table. diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index ca346c9cc7c8..b758da14cc7b 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -1972,7 +1972,7 @@ xfs_dir2_node_addname_int( dep->namelen = args->namelen; memcpy(dep->name, args->name, dep->namelen); dp->d_ops->data_put_ftype(dep, args->filetype); - tagp = dp->d_ops->data_entry_tag_p(dep); + tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep); *tagp = cpu_to_be16((char *)dep - (char *)hdr); xfs_dir2_data_log_entry(args, dbp, dep); diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index c60b8663f754..a6c3fb3a2f7b 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h @@ -58,6 +58,8 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args, /* xfs_dir2_data.c */ int xfs_dir2_data_entsize(struct xfs_mount *mp, int n); +__be16 *xfs_dir2_data_entry_tag_p(struct xfs_mount *mp, + struct xfs_dir2_data_entry *dep); #ifdef DEBUG extern void xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp); diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index 5347c18745d3..82e3ed366524 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -271,7 +271,7 @@ xchk_dir_rec( /* Retrieve the entry, sanity check it, and compare hashes. */ ino = be64_to_cpu(dent->inumber); hash = be32_to_cpu(ent->hashval); - tag = be16_to_cpup(dp->d_ops->data_entry_tag_p(dent)); + tag = be16_to_cpup(xfs_dir2_data_entry_tag_p(mp, dent)); if (!xfs_verify_dir_ino(mp, ino) || tag != off) xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); if (dent->namelen == 0) { -- cgit v1.2.3-70-g09d2 From d73e1cee8add0d18d5401b81db2351b9e8af899a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 15:05:38 -0800 Subject: xfs: move the dir2 data block fixed offsets to struct xfs_da_geometry Move the data block fixed offsets towards our structure for dir/attr geometry parameters. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_btree.h | 3 +++ fs/xfs/libxfs/xfs_da_format.c | 15 --------------- fs/xfs/libxfs/xfs_dir2.c | 8 ++++++++ fs/xfs/libxfs/xfs_dir2.h | 3 --- fs/xfs/libxfs/xfs_dir2_block.c | 5 +++-- fs/xfs/libxfs/xfs_dir2_data.c | 25 ++++++++++++------------- fs/xfs/libxfs/xfs_dir2_leaf.c | 22 ++++++++++++---------- fs/xfs/libxfs/xfs_dir2_node.c | 24 +++++++++++------------- fs/xfs/libxfs/xfs_dir2_sf.c | 16 +++++----------- fs/xfs/scrub/dir.c | 15 ++++++++------- fs/xfs/xfs_dir2_readdir.c | 10 +++++----- 11 files changed, 67 insertions(+), 79 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index 40110acf9f8a..4ac2cc87c28f 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -32,6 +32,9 @@ struct xfs_da_geometry { unsigned int free_hdr_size; /* dir2 free header size */ unsigned int free_max_bests; /* # of bests entries in dir2 free */ xfs_dablk_t freeblk; /* blockno of free data v2 */ + + xfs_dir2_data_aoff_t data_first_offset; + size_t data_entry_offset; }; /*======================================================================== diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index 483f4ab6abb8..0e35e613fbf3 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -105,33 +105,18 @@ static const struct xfs_dir_ops xfs_dir2_ops = { .data_get_ftype = xfs_dir2_data_get_ftype, .data_put_ftype = xfs_dir2_data_put_ftype, .data_bestfree_p = xfs_dir2_data_bestfree_p, - - .data_first_offset = sizeof(struct xfs_dir2_data_hdr) + - XFS_DIR2_DATA_ENTSIZE(1) + - XFS_DIR2_DATA_ENTSIZE(2), - .data_entry_offset = sizeof(struct xfs_dir2_data_hdr), }; static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .data_get_ftype = xfs_dir3_data_get_ftype, .data_put_ftype = xfs_dir3_data_put_ftype, .data_bestfree_p = xfs_dir2_data_bestfree_p, - - .data_first_offset = sizeof(struct xfs_dir2_data_hdr) + - XFS_DIR3_DATA_ENTSIZE(1) + - XFS_DIR3_DATA_ENTSIZE(2), - .data_entry_offset = sizeof(struct xfs_dir2_data_hdr), }; static const struct xfs_dir_ops xfs_dir3_ops = { .data_get_ftype = xfs_dir3_data_get_ftype, .data_put_ftype = xfs_dir3_data_put_ftype, .data_bestfree_p = xfs_dir3_data_bestfree_p, - - .data_first_offset = sizeof(struct xfs_dir3_data_hdr) + - XFS_DIR3_DATA_ENTSIZE(1) + - XFS_DIR3_DATA_ENTSIZE(2), - .data_entry_offset = sizeof(struct xfs_dir3_data_hdr), }; /* diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 77a297e7d91c..eccffe7a5ae0 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -126,16 +126,24 @@ xfs_da_mount( dageo->node_hdr_size = sizeof(struct xfs_da3_node_hdr); dageo->leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr); dageo->free_hdr_size = sizeof(struct xfs_dir3_free_hdr); + dageo->data_entry_offset = + sizeof(struct xfs_dir3_data_hdr); } else { dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr); dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr); dageo->free_hdr_size = sizeof(struct xfs_dir2_free_hdr); + dageo->data_entry_offset = + sizeof(struct xfs_dir2_data_hdr); } dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) / sizeof(struct xfs_dir2_leaf_entry); dageo->free_max_bests = (dageo->blksize - dageo->free_hdr_size) / sizeof(xfs_dir2_data_off_t); + dageo->data_first_offset = dageo->data_entry_offset + + xfs_dir2_data_entsize(mp, 1) + + xfs_dir2_data_entsize(mp, 2); + /* * Now we've set up the block conversion variables, we can calculate the * segment block constants using the geometry structure. diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index 3f46954e9370..830c70a20761 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -37,9 +37,6 @@ struct xfs_dir_ops { uint8_t ftype); struct xfs_dir2_data_free * (*data_bestfree_p)(struct xfs_dir2_data_hdr *hdr); - - xfs_dir2_data_aoff_t data_first_offset; - size_t data_entry_offset; }; extern const struct xfs_dir_ops * diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 35eda4d18cd8..9529a000838f 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -937,7 +937,7 @@ xfs_dir2_leaf_to_block( while (dp->i_d.di_size > args->geo->blksize) { int hdrsz; - hdrsz = dp->d_ops->data_entry_offset; + hdrsz = args->geo->data_entry_offset; bestsp = xfs_dir2_leaf_bests_p(ltp); if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) == args->geo->blksize - hdrsz) { @@ -1045,6 +1045,7 @@ xfs_dir2_sf_to_block( struct xfs_inode *dp = args->dp; struct xfs_mount *mp = dp->i_mount; struct xfs_ifork *ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK); + struct xfs_da_geometry *geo = args->geo; xfs_dir2_db_t blkno; /* dir-relative block # (0) */ xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ @@ -1059,7 +1060,7 @@ xfs_dir2_sf_to_block( int needlog; /* need to log block header */ int needscan; /* need to scan block freespc */ int newoffset; /* offset from current entry */ - unsigned int offset = dp->d_ops->data_entry_offset; + unsigned int offset = geo->data_entry_offset; xfs_dir2_sf_entry_t *sfep; /* sf entry pointer */ xfs_dir2_sf_hdr_t *oldsfp; /* old shortform header */ xfs_dir2_sf_hdr_t *sfp; /* shortform header */ diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index 3504b230ba1d..c1a843f6a8da 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -45,11 +45,10 @@ xfs_dir2_data_entry_tag_p( */ static inline unsigned int xfs_dir2_data_max_leaf_entries( - const struct xfs_dir_ops *ops, struct xfs_da_geometry *geo) { return (geo->blksize - sizeof(struct xfs_dir2_block_tail) - - ops->data_entry_offset) / + geo->data_entry_offset) / sizeof(struct xfs_dir2_leaf_entry); } @@ -97,7 +96,7 @@ __xfs_dir3_data_check( return __this_address; hdr = bp->b_addr; - offset = ops->data_entry_offset; + offset = geo->data_entry_offset; switch (hdr->magic) { case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC): @@ -106,7 +105,7 @@ __xfs_dir3_data_check( lep = xfs_dir2_block_leaf_p(btp); if (be32_to_cpu(btp->count) >= - xfs_dir2_data_max_leaf_entries(ops, geo)) + xfs_dir2_data_max_leaf_entries(geo)) return __this_address; break; case cpu_to_be32(XFS_DIR3_DATA_MAGIC): @@ -586,9 +585,10 @@ xfs_dir2_data_freescan_int( struct xfs_dir2_data_hdr *hdr, int *loghead) { + struct xfs_da_geometry *geo = mp->m_dir_geo; struct xfs_dir2_data_free *bf = ops->data_bestfree_p(hdr); void *addr = hdr; - unsigned int offset = ops->data_entry_offset; + unsigned int offset = geo->data_entry_offset; unsigned int end; ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || @@ -602,7 +602,7 @@ xfs_dir2_data_freescan_int( memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT); *loghead = 1; - end = xfs_dir3_data_end_offset(mp->m_dir_geo, addr); + end = xfs_dir3_data_end_offset(geo, addr); while (offset < end) { struct xfs_dir2_data_unused *dup = addr + offset; struct xfs_dir2_data_entry *dep = addr + offset; @@ -649,6 +649,7 @@ xfs_dir3_data_init( struct xfs_trans *tp = args->trans; struct xfs_inode *dp = args->dp; struct xfs_mount *mp = dp->i_mount; + struct xfs_da_geometry *geo = args->geo; struct xfs_buf *bp; struct xfs_dir2_data_hdr *hdr; struct xfs_dir2_data_unused *dup; @@ -683,9 +684,8 @@ xfs_dir3_data_init( hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); bf = dp->d_ops->data_bestfree_p(hdr); - bf[0].offset = cpu_to_be16(dp->d_ops->data_entry_offset); - bf[0].length = - cpu_to_be16(args->geo->blksize - dp->d_ops->data_entry_offset); + bf[0].offset = cpu_to_be16(geo->data_entry_offset); + bf[0].length = cpu_to_be16(geo->blksize - geo->data_entry_offset); for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) { bf[i].length = 0; bf[i].offset = 0; @@ -694,7 +694,7 @@ xfs_dir3_data_init( /* * Set up an unused entry for the block's body. */ - dup = bp->b_addr + dp->d_ops->data_entry_offset; + dup = bp->b_addr + geo->data_entry_offset; dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); dup->length = bf[0].length; *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr); @@ -747,8 +747,7 @@ xfs_dir2_data_log_header( hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); #endif - xfs_trans_log_buf(args->trans, bp, 0, - args->dp->d_ops->data_entry_offset - 1); + xfs_trans_log_buf(args->trans, bp, 0, args->geo->data_entry_offset - 1); } /* @@ -816,7 +815,7 @@ xfs_dir2_data_make_free( * If this isn't the start of the block, then back up to * the previous entry and see if it's free. */ - if (offset > args->dp->d_ops->data_entry_offset) { + if (offset > args->geo->data_entry_offset) { __be16 *tagp; /* tag just before us */ tagp = (__be16 *)((char *)hdr + offset) - 1; diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index 4b6d590c5856..2b327d1937f4 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -1343,6 +1343,7 @@ int /* error */ xfs_dir2_leaf_removename( xfs_da_args_t *args) /* operation arguments */ { + struct xfs_da_geometry *geo = args->geo; __be16 *bestsp; /* leaf block best freespace */ xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_db_t db; /* data block number */ @@ -1381,12 +1382,12 @@ xfs_dir2_leaf_removename( * Point to the leaf entry, use that to point to the data entry. */ lep = &leafhdr.ents[index]; - db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address)); + db = xfs_dir2_dataptr_to_db(geo, be32_to_cpu(lep->address)); dep = (xfs_dir2_data_entry_t *)((char *)hdr + - xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address))); + xfs_dir2_dataptr_to_off(geo, be32_to_cpu(lep->address))); needscan = needlog = 0; oldbest = be16_to_cpu(bf[0].length); - ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); + ltp = xfs_dir2_leaf_tail_p(geo, leaf); bestsp = xfs_dir2_leaf_bests_p(ltp); if (be16_to_cpu(bestsp[db]) != oldbest) { xfs_buf_corruption_error(lbp); @@ -1430,8 +1431,8 @@ xfs_dir2_leaf_removename( * If the data block is now empty then get rid of the data block. */ if (be16_to_cpu(bf[0].length) == - args->geo->blksize - dp->d_ops->data_entry_offset) { - ASSERT(db != args->geo->datablk); + geo->blksize - geo->data_entry_offset) { + ASSERT(db != geo->datablk); if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { /* * Nope, can't get rid of it because it caused @@ -1473,7 +1474,7 @@ xfs_dir2_leaf_removename( /* * If the data block was not the first one, drop it. */ - else if (db != args->geo->datablk) + else if (db != geo->datablk) dbp = NULL; xfs_dir3_leaf_check(dp, lbp); @@ -1594,6 +1595,7 @@ xfs_dir2_leaf_trim_data( struct xfs_buf *lbp, /* leaf buffer */ xfs_dir2_db_t db) /* data block number */ { + struct xfs_da_geometry *geo = args->geo; __be16 *bestsp; /* leaf bests table */ struct xfs_buf *dbp; /* data block buffer */ xfs_inode_t *dp; /* incore directory inode */ @@ -1607,13 +1609,13 @@ xfs_dir2_leaf_trim_data( /* * Read the offending data block. We need its buffer. */ - error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(args->geo, db), - -1, &dbp); + error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(geo, db), -1, + &dbp); if (error) return error; leaf = lbp->b_addr; - ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); + ltp = xfs_dir2_leaf_tail_p(geo, leaf); #ifdef DEBUG { @@ -1623,7 +1625,7 @@ xfs_dir2_leaf_trim_data( ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)); ASSERT(be16_to_cpu(bf[0].length) == - args->geo->blksize - dp->d_ops->data_entry_offset); + geo->blksize - geo->data_entry_offset); ASSERT(db == be32_to_cpu(ltp->bestcount) - 1); } #endif diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index b758da14cc7b..80659d009cba 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -1263,6 +1263,7 @@ xfs_dir2_leafn_remove( xfs_da_state_blk_t *dblk, /* data block */ int *rval) /* resulting block needs join */ { + struct xfs_da_geometry *geo = args->geo; xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_db_t db; /* data block number */ struct xfs_buf *dbp; /* data block buffer */ @@ -1293,9 +1294,9 @@ xfs_dir2_leafn_remove( /* * Extract the data block and offset from the entry. */ - db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address)); + db = xfs_dir2_dataptr_to_db(geo, be32_to_cpu(lep->address)); ASSERT(dblk->blkno == db); - off = xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address)); + off = xfs_dir2_dataptr_to_off(geo, be32_to_cpu(lep->address)); ASSERT(dblk->index == off); /* @@ -1346,9 +1347,8 @@ xfs_dir2_leafn_remove( * Convert the data block number to a free block, * read in the free block. */ - fdb = xfs_dir2_db_to_fdb(args->geo, db); - error = xfs_dir2_free_read(tp, dp, - xfs_dir2_db_to_da(args->geo, fdb), + fdb = xfs_dir2_db_to_fdb(geo, db); + error = xfs_dir2_free_read(tp, dp, xfs_dir2_db_to_da(geo, fdb), &fbp); if (error) return error; @@ -1358,22 +1358,20 @@ xfs_dir2_leafn_remove( struct xfs_dir3_icfree_hdr freehdr; xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free); - ASSERT(freehdr.firstdb == args->geo->free_max_bests * - (fdb - xfs_dir2_byte_to_db(args->geo, - XFS_DIR2_FREE_OFFSET))); + ASSERT(freehdr.firstdb == geo->free_max_bests * + (fdb - xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET))); } #endif /* * Calculate which entry we need to fix. */ - findex = xfs_dir2_db_to_fdindex(args->geo, db); + findex = xfs_dir2_db_to_fdindex(geo, db); longest = be16_to_cpu(bf[0].length); /* * If the data block is now empty we can get rid of it * (usually). */ - if (longest == args->geo->blksize - - dp->d_ops->data_entry_offset) { + if (longest == geo->blksize - geo->data_entry_offset) { /* * Try to punch out the data block. */ @@ -1405,9 +1403,9 @@ xfs_dir2_leafn_remove( * Return indication of whether this leaf block is empty enough * to justify trying to join it with a neighbor. */ - *rval = (args->geo->leaf_hdr_size + + *rval = (geo->leaf_hdr_size + (uint)sizeof(leafhdr.ents) * (leafhdr.count - leafhdr.stale)) < - args->geo->magicpct; + geo->magicpct; return 0; } diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c index a41715c9b061..b5ac27442f9a 100644 --- a/fs/xfs/libxfs/xfs_dir2_sf.c +++ b/fs/xfs/libxfs/xfs_dir2_sf.c @@ -266,7 +266,7 @@ xfs_dir2_block_to_sf( int logflags; /* inode logging flags */ struct xfs_dir2_sf_entry *sfep; /* shortform entry */ struct xfs_dir2_sf_hdr *sfp; /* shortform directory header */ - unsigned int offset = dp->d_ops->data_entry_offset; + unsigned int offset = args->geo->data_entry_offset; unsigned int end; trace_xfs_dir2_block_to_sf(args); @@ -538,7 +538,7 @@ xfs_dir2_sf_addname_hard( * to insert the new entry. * If it's going to end up at the end then oldsfep will point there. */ - for (offset = dp->d_ops->data_first_offset, + for (offset = args->geo->data_first_offset, oldsfep = xfs_dir2_sf_firstentry(oldsfp), add_datasize = xfs_dir2_data_entsize(mp, args->namelen), eof = (char *)oldsfep == &buf[old_isize]; @@ -616,7 +616,7 @@ xfs_dir2_sf_addname_pick( sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; size = xfs_dir2_data_entsize(mp, args->namelen); - offset = dp->d_ops->data_first_offset; + offset = args->geo->data_first_offset; sfep = xfs_dir2_sf_firstentry(sfp); holefit = 0; /* @@ -681,7 +681,7 @@ xfs_dir2_sf_check( xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; - offset = dp->d_ops->data_first_offset; + offset = args->geo->data_first_offset; ino = xfs_dir2_sf_get_parent_ino(sfp); i8count = ino > XFS_DIR2_MAX_SHORT_INUM; @@ -714,7 +714,6 @@ xfs_dir2_sf_verify( struct xfs_dir2_sf_entry *sfep; struct xfs_dir2_sf_entry *next_sfep; char *endp; - const struct xfs_dir_ops *dops; struct xfs_ifork *ifp; xfs_ino_t ino; int i; @@ -725,11 +724,6 @@ xfs_dir2_sf_verify( uint8_t filetype; ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_LOCAL); - /* - * xfs_iread calls us before xfs_setup_inode sets up ip->d_ops, - * so we can only trust the mountpoint to have the right pointer. - */ - dops = xfs_dir_get_ops(mp, NULL); ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); sfp = (struct xfs_dir2_sf_hdr *)ifp->if_u1.if_data; @@ -750,7 +744,7 @@ xfs_dir2_sf_verify( error = xfs_dir_ino_validate(mp, ino); if (error) return __this_address; - offset = dops->data_first_offset; + offset = mp->m_dir_geo->data_first_offset; /* Check all reported entries */ sfep = xfs_dir2_sf_firstentry(sfp); diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index 82e3ed366524..132659bccb4f 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -187,6 +187,7 @@ xchk_dir_rec( struct xfs_da_state_blk *blk = &ds->state->path.blk[level]; struct xfs_mount *mp = ds->state->mp; struct xfs_inode *dp = ds->dargs.dp; + struct xfs_da_geometry *geo = mp->m_dir_geo; struct xfs_dir2_data_entry *dent; struct xfs_buf *bp; struct xfs_dir2_leaf_entry *ent; @@ -220,11 +221,11 @@ xchk_dir_rec( return 0; /* Find the directory entry's location. */ - db = xfs_dir2_dataptr_to_db(mp->m_dir_geo, ptr); - off = xfs_dir2_dataptr_to_off(mp->m_dir_geo, ptr); - rec_bno = xfs_dir2_db_to_da(mp->m_dir_geo, db); + db = xfs_dir2_dataptr_to_db(geo, ptr); + off = xfs_dir2_dataptr_to_off(geo, ptr); + rec_bno = xfs_dir2_db_to_da(geo, db); - if (rec_bno >= mp->m_dir_geo->leafblk) { + if (rec_bno >= geo->leafblk) { xchk_da_set_corrupt(ds, level); goto out; } @@ -244,8 +245,8 @@ xchk_dir_rec( dent = bp->b_addr + off; /* Make sure we got a real directory entry. */ - iter_off = mp->m_dir_inode_ops->data_entry_offset; - end = xfs_dir3_data_end_offset(mp->m_dir_geo, bp->b_addr); + iter_off = geo->data_entry_offset; + end = xfs_dir3_data_end_offset(geo, bp->b_addr); if (!end) { xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); goto out_relse; @@ -392,7 +393,7 @@ xchk_directory_data_bestfree( } /* Make sure the bestfrees are actually the best free spaces. */ - offset = d_ops->data_entry_offset; + offset = mp->m_dir_geo->data_entry_offset; end = xfs_dir3_data_end_offset(mp->m_dir_geo, bp->b_addr); /* Iterate the entries, stopping when we hit or go past the end. */ diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index edc57bed0f1f..a893d2d09620 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -75,9 +75,9 @@ xfs_dir2_sf_getdents( * entries for "." and "..". */ dot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, - dp->d_ops->data_entry_offset); + geo->data_entry_offset); dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, - dp->d_ops->data_entry_offset + + geo->data_entry_offset + xfs_dir2_data_entsize(mp, sizeof(".") - 1)); /* @@ -174,7 +174,7 @@ xfs_dir2_block_getdents( * Loop over the data portion of the block. * Each object is a real entry (dep) or an unused one (dup). */ - offset = dp->d_ops->data_entry_offset; + offset = geo->data_entry_offset; end = xfs_dir3_data_end_offset(geo, bp->b_addr); while (offset < end) { struct xfs_dir2_data_unused *dup = bp->b_addr + offset; @@ -401,13 +401,13 @@ xfs_dir2_leaf_getdents( /* * Find our position in the block. */ - offset = dp->d_ops->data_entry_offset; + offset = geo->data_entry_offset; byteoff = xfs_dir2_byte_to_off(geo, curoff); /* * Skip past the header. */ if (byteoff == 0) - curoff += dp->d_ops->data_entry_offset; + curoff += geo->data_entry_offset; /* * Skip past entries until we reach our offset. */ -- cgit v1.2.3-70-g09d2 From 1848b607a9ad084db0180118304b9af2be68384e Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 15:05:39 -0800 Subject: xfs: devirtualize ->data_bestfree_p Replace the ->data_bestfree_p dir ops method with a directly called xfs_dir2_data_bestfree_p helper that takes care of the differences between the v4 and v5 on-disk format. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_format.c | 15 --------------- fs/xfs/libxfs/xfs_dir2.h | 3 --- fs/xfs/libxfs/xfs_dir2_block.c | 6 +++--- fs/xfs/libxfs/xfs_dir2_data.c | 23 ++++++++++++++++------- fs/xfs/libxfs/xfs_dir2_leaf.c | 11 ++++++----- fs/xfs/libxfs/xfs_dir2_node.c | 6 +++--- fs/xfs/libxfs/xfs_dir2_priv.h | 2 ++ fs/xfs/scrub/dir.c | 7 ++----- 8 files changed, 32 insertions(+), 41 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index dd2389748672..b9f9fbf7eee2 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -56,34 +56,19 @@ xfs_dir3_data_put_ftype( dep->name[dep->namelen] = type; } -static struct xfs_dir2_data_free * -xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr) -{ - return hdr->bestfree; -} - -static struct xfs_dir2_data_free * -xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr) -{ - return ((struct xfs_dir3_data_hdr *)hdr)->best_free; -} - static const struct xfs_dir_ops xfs_dir2_ops = { .data_get_ftype = xfs_dir2_data_get_ftype, .data_put_ftype = xfs_dir2_data_put_ftype, - .data_bestfree_p = xfs_dir2_data_bestfree_p, }; static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .data_get_ftype = xfs_dir3_data_get_ftype, .data_put_ftype = xfs_dir3_data_put_ftype, - .data_bestfree_p = xfs_dir2_data_bestfree_p, }; static const struct xfs_dir_ops xfs_dir3_ops = { .data_get_ftype = xfs_dir3_data_get_ftype, .data_put_ftype = xfs_dir3_data_put_ftype, - .data_bestfree_p = xfs_dir3_data_bestfree_p, }; /* diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index 830c70a20761..b50273b2d970 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -35,8 +35,6 @@ struct xfs_dir_ops { uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep); void (*data_put_ftype)(struct xfs_dir2_data_entry *dep, uint8_t ftype); - struct xfs_dir2_data_free * - (*data_bestfree_p)(struct xfs_dir2_data_hdr *hdr); }; extern const struct xfs_dir_ops * @@ -81,7 +79,6 @@ extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, struct xfs_buf *bp); extern void xfs_dir2_data_freescan_int(struct xfs_mount *mp, - const struct xfs_dir_ops *ops, struct xfs_dir2_data_hdr *hdr, int *loghead); extern void xfs_dir2_data_freescan(struct xfs_inode *dp, struct xfs_dir2_data_hdr *hdr, int *loghead); diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 9529a000838f..62b3adb01210 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -172,7 +172,7 @@ xfs_dir2_block_need_space( struct xfs_dir2_data_unused *enddup = NULL; *compact = 0; - bf = dp->d_ops->data_bestfree_p(hdr); + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); /* * If there are stale entries we'll use one for the leaf. @@ -1199,8 +1199,8 @@ xfs_dir2_sf_to_block( *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16(offset); xfs_dir2_data_log_unused(args, bp, dup); xfs_dir2_data_freeinsert(hdr, - dp->d_ops->data_bestfree_p(hdr), - dup, &dummy); + xfs_dir2_data_bestfree_p(mp, hdr), + dup, &dummy); offset += be16_to_cpu(dup->length); continue; } diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index c1a843f6a8da..6ed9396225e3 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -25,6 +25,16 @@ static xfs_failaddr_t xfs_dir2_data_freefind_verify( struct xfs_dir2_data_unused *dup, struct xfs_dir2_data_free **bf_ent); +struct xfs_dir2_data_free * +xfs_dir2_data_bestfree_p( + struct xfs_mount *mp, + struct xfs_dir2_data_hdr *hdr) +{ + if (xfs_sb_version_hascrc(&mp->m_sb)) + return ((struct xfs_dir3_data_hdr *)hdr)->best_free; + return hdr->bestfree; +} + /* * Pointer to an entry's tag word. */ @@ -121,7 +131,7 @@ __xfs_dir3_data_check( /* * Account for zero bestfree entries. */ - bf = ops->data_bestfree_p(hdr); + bf = xfs_dir2_data_bestfree_p(mp, hdr); count = lastfree = freeseen = 0; if (!bf[0].length) { if (bf[0].offset) @@ -581,12 +591,11 @@ xfs_dir2_data_freeremove( void xfs_dir2_data_freescan_int( struct xfs_mount *mp, - const struct xfs_dir_ops *ops, struct xfs_dir2_data_hdr *hdr, int *loghead) { struct xfs_da_geometry *geo = mp->m_dir_geo; - struct xfs_dir2_data_free *bf = ops->data_bestfree_p(hdr); + struct xfs_dir2_data_free *bf = xfs_dir2_data_bestfree_p(mp, hdr); void *addr = hdr; unsigned int offset = geo->data_entry_offset; unsigned int end; @@ -633,7 +642,7 @@ xfs_dir2_data_freescan( struct xfs_dir2_data_hdr *hdr, int *loghead) { - return xfs_dir2_data_freescan_int(dp->i_mount, dp->d_ops, hdr, loghead); + return xfs_dir2_data_freescan_int(dp->i_mount, hdr, loghead); } /* @@ -683,7 +692,7 @@ xfs_dir3_data_init( } else hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); - bf = dp->d_ops->data_bestfree_p(hdr); + bf = xfs_dir2_data_bestfree_p(mp, hdr); bf[0].offset = cpu_to_be16(geo->data_entry_offset); bf[0].length = cpu_to_be16(geo->blksize - geo->data_entry_offset); for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) { @@ -841,7 +850,7 @@ xfs_dir2_data_make_free( * Previous and following entries are both free, * merge everything into a single free entry. */ - bf = args->dp->d_ops->data_bestfree_p(hdr); + bf = xfs_dir2_data_bestfree_p(args->dp->i_mount, hdr); if (prevdup && postdup) { xfs_dir2_data_free_t *dfp2; /* another bestfree pointer */ @@ -1032,7 +1041,7 @@ xfs_dir2_data_use_free( * Look up the entry in the bestfree table. */ oldlen = be16_to_cpu(dup->length); - bf = args->dp->d_ops->data_bestfree_p(hdr); + bf = xfs_dir2_data_bestfree_p(args->dp->i_mount, hdr); dfp = xfs_dir2_data_freefind(hdr, bf, dup); ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length)); /* diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index 2b327d1937f4..7fa485cd0158 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -425,7 +425,7 @@ xfs_dir2_block_to_leaf( xfs_dir3_data_check(dp, dbp); btp = xfs_dir2_block_tail_p(args->geo, hdr); blp = xfs_dir2_block_leaf_p(btp); - bf = dp->d_ops->data_bestfree_p(hdr); + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); /* * Set the counts in the leaf header. @@ -823,7 +823,7 @@ xfs_dir2_leaf_addname( else xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block); hdr = dbp->b_addr; - bf = dp->d_ops->data_bestfree_p(hdr); + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); bestsp[use_block] = bf[0].length; grown = 1; } else { @@ -839,7 +839,7 @@ xfs_dir2_leaf_addname( return error; } hdr = dbp->b_addr; - bf = dp->d_ops->data_bestfree_p(hdr); + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); grown = 0; } /* @@ -1376,7 +1376,7 @@ xfs_dir2_leaf_removename( leaf = lbp->b_addr; hdr = dbp->b_addr; xfs_dir3_data_check(dp, dbp); - bf = dp->d_ops->data_bestfree_p(hdr); + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); /* * Point to the leaf entry, use that to point to the data entry. @@ -1620,7 +1620,8 @@ xfs_dir2_leaf_trim_data( #ifdef DEBUG { struct xfs_dir2_data_hdr *hdr = dbp->b_addr; - struct xfs_dir2_data_free *bf = dp->d_ops->data_bestfree_p(hdr); + struct xfs_dir2_data_free *bf = + xfs_dir2_data_bestfree_p(dp->i_mount, hdr); ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)); diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 80659d009cba..76d19b522e92 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -1317,7 +1317,7 @@ xfs_dir2_leafn_remove( dbp = dblk->bp; hdr = dbp->b_addr; dep = (xfs_dir2_data_entry_t *)((char *)hdr + off); - bf = dp->d_ops->data_bestfree_p(hdr); + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); longest = be16_to_cpu(bf[0].length); needlog = needscan = 0; xfs_dir2_data_make_free(args, dbp, off, @@ -1775,7 +1775,7 @@ xfs_dir2_node_add_datablk( } /* Update the freespace value for the new block in the table. */ - bf = dp->d_ops->data_bestfree_p(dbp->b_addr); + bf = xfs_dir2_data_bestfree_p(mp, dbp->b_addr); hdr->bests[*findex] = bf[0].length; *dbpp = dbp; @@ -1948,7 +1948,7 @@ xfs_dir2_node_addname_int( /* setup for data block up now */ hdr = dbp->b_addr; - bf = dp->d_ops->data_bestfree_p(hdr); + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); ASSERT(be16_to_cpu(bf[0].length) >= length); /* Point to the existing unused space. */ diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index d8f10be77b46..0a18cf7023a0 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h @@ -57,6 +57,8 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args, struct xfs_buf *lbp, struct xfs_buf *dbp); /* xfs_dir2_data.c */ +struct xfs_dir2_data_free *xfs_dir2_data_bestfree_p(struct xfs_mount *mp, + struct xfs_dir2_data_hdr *hdr); __be16 *xfs_dir2_data_entry_tag_p(struct xfs_mount *mp, struct xfs_dir2_data_entry *dep); diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index 132659bccb4f..7983ea40668a 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -330,7 +330,6 @@ xchk_directory_data_bestfree( struct xfs_buf *bp; struct xfs_dir2_data_free *bf; struct xfs_mount *mp = sc->mp; - const struct xfs_dir_ops *d_ops; u16 tag; unsigned int nr_bestfrees = 0; unsigned int nr_frees = 0; @@ -340,8 +339,6 @@ xchk_directory_data_bestfree( unsigned int end; int error; - d_ops = sc->ip->d_ops; - if (is_block) { /* dir block format */ if (lblk != XFS_B_TO_FSBT(mp, XFS_DIR2_DATA_OFFSET)) @@ -361,7 +358,7 @@ xchk_directory_data_bestfree( goto out_buf; /* Do the bestfrees correspond to actual free space? */ - bf = d_ops->data_bestfree_p(bp->b_addr); + bf = xfs_dir2_data_bestfree_p(mp, bp->b_addr); smallest_bestfree = UINT_MAX; for (dfp = &bf[0]; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) { offset = be16_to_cpu(dfp->offset); @@ -468,7 +465,7 @@ xchk_directory_check_freesp( { struct xfs_dir2_data_free *dfp; - dfp = sc->ip->d_ops->data_bestfree_p(dbp->b_addr); + dfp = xfs_dir2_data_bestfree_p(sc->mp, dbp->b_addr); if (len != be16_to_cpu(dfp->length)) xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); -- cgit v1.2.3-70-g09d2 From 59b8b465058ec203493c0436f243263051e08f5a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 15:05:48 -0800 Subject: xfs: devirtualize ->data_get_ftype and ->data_put_ftype Replace the ->data_get_ftype and ->data_put_ftype dir ops methods with directly called xfs_dir2_data_get_ftype and xfs_dir2_data_put_ftype helpers that takes care of the differences between the directory format with and without the file type field. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_format.c | 47 ------------------------------------------ fs/xfs/libxfs/xfs_dir2.h | 3 --- fs/xfs/libxfs/xfs_dir2_block.c | 13 ++++++------ fs/xfs/libxfs/xfs_dir2_data.c | 43 +++++++++++++++++++++++++++----------- fs/xfs/libxfs/xfs_dir2_leaf.c | 6 +++--- fs/xfs/libxfs/xfs_dir2_node.c | 6 +++--- fs/xfs/libxfs/xfs_dir2_priv.h | 4 ++++ fs/xfs/libxfs/xfs_dir2_sf.c | 2 +- fs/xfs/xfs_dir2_readdir.c | 4 ++-- 9 files changed, 51 insertions(+), 77 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index b9f9fbf7eee2..498363ac193d 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -15,60 +15,13 @@ #include "xfs_dir2.h" #include "xfs_dir2_priv.h" -/* - * Directory data block operations - */ - -static uint8_t -xfs_dir2_data_get_ftype( - struct xfs_dir2_data_entry *dep) -{ - return XFS_DIR3_FT_UNKNOWN; -} - -static void -xfs_dir2_data_put_ftype( - struct xfs_dir2_data_entry *dep, - uint8_t ftype) -{ - ASSERT(ftype < XFS_DIR3_FT_MAX); -} - -static uint8_t -xfs_dir3_data_get_ftype( - struct xfs_dir2_data_entry *dep) -{ - uint8_t ftype = dep->name[dep->namelen]; - - if (ftype >= XFS_DIR3_FT_MAX) - return XFS_DIR3_FT_UNKNOWN; - return ftype; -} - -static void -xfs_dir3_data_put_ftype( - struct xfs_dir2_data_entry *dep, - uint8_t type) -{ - ASSERT(type < XFS_DIR3_FT_MAX); - ASSERT(dep->namelen != 0); - - dep->name[dep->namelen] = type; -} - static const struct xfs_dir_ops xfs_dir2_ops = { - .data_get_ftype = xfs_dir2_data_get_ftype, - .data_put_ftype = xfs_dir2_data_put_ftype, }; static const struct xfs_dir_ops xfs_dir2_ftype_ops = { - .data_get_ftype = xfs_dir3_data_get_ftype, - .data_put_ftype = xfs_dir3_data_put_ftype, }; static const struct xfs_dir_ops xfs_dir3_ops = { - .data_get_ftype = xfs_dir3_data_get_ftype, - .data_put_ftype = xfs_dir3_data_put_ftype, }; /* diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index b50273b2d970..b44c64a20f67 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -32,9 +32,6 @@ extern unsigned char xfs_mode_to_ftype(int mode); * directory operations vector for encode/decode routines */ struct xfs_dir_ops { - uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep); - void (*data_put_ftype)(struct xfs_dir2_data_entry *dep, - uint8_t ftype); }; extern const struct xfs_dir_ops * diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 62b3adb01210..0c481e55c981 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -541,7 +541,7 @@ xfs_dir2_block_addname( dep->inumber = cpu_to_be64(args->inumber); dep->namelen = args->namelen; memcpy(dep->name, args->name, args->namelen); - dp->d_ops->data_put_ftype(dep, args->filetype); + xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep); *tagp = cpu_to_be16((char *)dep - (char *)hdr); /* @@ -633,7 +633,7 @@ xfs_dir2_block_lookup( * Fill in inode number, CI name if appropriate, release the block. */ args->inumber = be64_to_cpu(dep->inumber); - args->filetype = dp->d_ops->data_get_ftype(dep); + args->filetype = xfs_dir2_data_get_ftype(dp->i_mount, dep); error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); xfs_trans_brelse(args->trans, bp); return error; @@ -865,7 +865,7 @@ xfs_dir2_block_replace( * Change the inode number to the new value. */ dep->inumber = cpu_to_be64(args->inumber); - dp->d_ops->data_put_ftype(dep, args->filetype); + xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); xfs_dir2_data_log_entry(args, bp, dep); xfs_dir3_data_check(dp, bp); return 0; @@ -1145,7 +1145,7 @@ xfs_dir2_sf_to_block( dep->inumber = cpu_to_be64(dp->i_ino); dep->namelen = 1; dep->name[0] = '.'; - dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR); + xfs_dir2_data_put_ftype(mp, dep, XFS_DIR3_FT_DIR); tagp = xfs_dir2_data_entry_tag_p(mp, dep); *tagp = cpu_to_be16(offset); xfs_dir2_data_log_entry(args, bp, dep); @@ -1160,7 +1160,7 @@ xfs_dir2_sf_to_block( dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp)); dep->namelen = 2; dep->name[0] = dep->name[1] = '.'; - dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR); + xfs_dir2_data_put_ftype(mp, dep, XFS_DIR3_FT_DIR); tagp = xfs_dir2_data_entry_tag_p(mp, dep); *tagp = cpu_to_be16(offset); xfs_dir2_data_log_entry(args, bp, dep); @@ -1210,7 +1210,8 @@ xfs_dir2_sf_to_block( dep = bp->b_addr + newoffset; dep->inumber = cpu_to_be64(xfs_dir2_sf_get_ino(mp, sfp, sfep)); dep->namelen = sfep->namelen; - dp->d_ops->data_put_ftype(dep, xfs_dir2_sf_get_ftype(mp, sfep)); + xfs_dir2_data_put_ftype(mp, dep, + xfs_dir2_sf_get_ftype(mp, sfep)); memcpy(dep->name, sfep->name, dep->namelen); tagp = xfs_dir2_data_entry_tag_p(mp, dep); *tagp = cpu_to_be16(newoffset); diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index 6ed9396225e3..0aa1d165c964 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -47,6 +47,34 @@ xfs_dir2_data_entry_tag_p( xfs_dir2_data_entsize(mp, dep->namelen) - sizeof(__be16)); } +uint8_t +xfs_dir2_data_get_ftype( + struct xfs_mount *mp, + struct xfs_dir2_data_entry *dep) +{ + if (xfs_sb_version_hasftype(&mp->m_sb)) { + uint8_t ftype = dep->name[dep->namelen]; + + if (likely(ftype < XFS_DIR3_FT_MAX)) + return ftype; + } + + return XFS_DIR3_FT_UNKNOWN; +} + +void +xfs_dir2_data_put_ftype( + struct xfs_mount *mp, + struct xfs_dir2_data_entry *dep, + uint8_t ftype) +{ + ASSERT(ftype < XFS_DIR3_FT_MAX); + ASSERT(dep->namelen != 0); + + if (xfs_sb_version_hasftype(&mp->m_sb)) + dep->name[dep->namelen] = ftype; +} + /* * The number of leaf entries is limited by the size of the block and the amount * of space used by the data entries. We don't know how much space is used by @@ -88,21 +116,12 @@ __xfs_dir3_data_check( struct xfs_name name; unsigned int offset; unsigned int end; - const struct xfs_dir_ops *ops; struct xfs_da_geometry *geo = mp->m_dir_geo; /* - * We can be passed a null dp here from a verifier, so we need to go the - * hard way to get them. - */ - ops = xfs_dir_get_ops(mp, dp); - - /* - * If this isn't a directory, or we don't get handed the dir ops, - * something is seriously wrong. Bail out. + * If this isn't a directory, something is seriously wrong. Bail out. */ - if ((dp && !S_ISDIR(VFS_I(dp)->i_mode)) || - ops != xfs_dir_get_ops(mp, NULL)) + if (dp && !S_ISDIR(VFS_I(dp)->i_mode)) return __this_address; hdr = bp->b_addr; @@ -206,7 +225,7 @@ __xfs_dir3_data_check( return __this_address; if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)) != offset) return __this_address; - if (ops->data_get_ftype(dep) >= XFS_DIR3_FT_MAX) + if (xfs_dir2_data_get_ftype(mp, dep) >= XFS_DIR3_FT_MAX) return __this_address; count++; lastfree = 0; diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index 7fa485cd0158..bc301c973450 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -865,7 +865,7 @@ xfs_dir2_leaf_addname( dep->inumber = cpu_to_be64(args->inumber); dep->namelen = args->namelen; memcpy(dep->name, args->name, dep->namelen); - dp->d_ops->data_put_ftype(dep, args->filetype); + xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep); *tagp = cpu_to_be16((char *)dep - (char *)hdr); /* @@ -1195,7 +1195,7 @@ xfs_dir2_leaf_lookup( * Return the found inode number & CI name if appropriate */ args->inumber = be64_to_cpu(dep->inumber); - args->filetype = dp->d_ops->data_get_ftype(dep); + args->filetype = xfs_dir2_data_get_ftype(dp->i_mount, dep); error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); xfs_trans_brelse(tp, dbp); xfs_trans_brelse(tp, lbp); @@ -1526,7 +1526,7 @@ xfs_dir2_leaf_replace( * Put the new inode number in, log it. */ dep->inumber = cpu_to_be64(args->inumber); - dp->d_ops->data_put_ftype(dep, args->filetype); + xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); tp = args->trans; xfs_dir2_data_log_entry(args, dbp, dep); xfs_dir3_leaf_check(dp, lbp); diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 76d19b522e92..4ac7518b667d 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -884,7 +884,7 @@ xfs_dir2_leafn_lookup_for_entry( xfs_trans_brelse(tp, state->extrablk.bp); args->cmpresult = cmp; args->inumber = be64_to_cpu(dep->inumber); - args->filetype = dp->d_ops->data_get_ftype(dep); + args->filetype = xfs_dir2_data_get_ftype(mp, dep); *indexp = index; state->extravalid = 1; state->extrablk.bp = curbp; @@ -1969,7 +1969,7 @@ xfs_dir2_node_addname_int( dep->inumber = cpu_to_be64(args->inumber); dep->namelen = args->namelen; memcpy(dep->name, args->name, dep->namelen); - dp->d_ops->data_put_ftype(dep, args->filetype); + xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep); *tagp = cpu_to_be16((char *)dep - (char *)hdr); xfs_dir2_data_log_entry(args, dbp, dep); @@ -2253,7 +2253,7 @@ xfs_dir2_node_replace( * Fill in the new inode number and log the entry. */ dep->inumber = cpu_to_be64(inum); - args->dp->d_ops->data_put_ftype(dep, ftype); + xfs_dir2_data_put_ftype(state->mp, dep, ftype); xfs_dir2_data_log_entry(args, state->extrablk.bp, dep); rval = 0; } diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index 0a18cf7023a0..a22222df4bf2 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h @@ -61,6 +61,10 @@ struct xfs_dir2_data_free *xfs_dir2_data_bestfree_p(struct xfs_mount *mp, struct xfs_dir2_data_hdr *hdr); __be16 *xfs_dir2_data_entry_tag_p(struct xfs_mount *mp, struct xfs_dir2_data_entry *dep); +uint8_t xfs_dir2_data_get_ftype(struct xfs_mount *mp, + struct xfs_dir2_data_entry *dep); +void xfs_dir2_data_put_ftype(struct xfs_mount *mp, + struct xfs_dir2_data_entry *dep, uint8_t ftype); #ifdef DEBUG extern void xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp); diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c index b5ac27442f9a..db1a82972d9e 100644 --- a/fs/xfs/libxfs/xfs_dir2_sf.c +++ b/fs/xfs/libxfs/xfs_dir2_sf.c @@ -319,7 +319,7 @@ xfs_dir2_block_to_sf( xfs_dir2_sf_put_ino(mp, sfp, sfep, be64_to_cpu(dep->inumber)); xfs_dir2_sf_put_ftype(mp, sfep, - dp->d_ops->data_get_ftype(dep)); + xfs_dir2_data_get_ftype(mp, dep)); sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); } diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index a893d2d09620..b149cb4a4d86 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -203,7 +203,7 @@ xfs_dir2_block_getdents( cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, offset); ctx->pos = cook & 0x7fffffff; - filetype = dp->d_ops->data_get_ftype(dep); + filetype = xfs_dir2_data_get_ftype(dp->i_mount, dep); /* * If it didn't fit, set the final offset to here & return. */ @@ -456,7 +456,7 @@ xfs_dir2_leaf_getdents( dep = bp->b_addr + offset; length = xfs_dir2_data_entsize(mp, dep->namelen); - filetype = dp->d_ops->data_get_ftype(dep); + filetype = xfs_dir2_data_get_ftype(mp, dep); ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff; if (!xfs_dir2_namecheck(dep->name, dep->namelen)) { -- cgit v1.2.3-70-g09d2 From ae42976de7f1022e6d83f5560debc072929921a9 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 15:06:02 -0800 Subject: xfs: merge xfs_dir2_data_freescan and xfs_dir2_data_freescan_int There is no real need for xfs_dir2_data_freescan wrapper, so rename xfs_dir2_data_freescan_int to xfs_dir2_data_freescan and let the callers dereference the mount pointer from the inode. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_dir2.h | 4 +--- fs/xfs/libxfs/xfs_dir2_block.c | 10 +++++----- fs/xfs/libxfs/xfs_dir2_data.c | 11 +---------- fs/xfs/libxfs/xfs_dir2_leaf.c | 6 +++--- fs/xfs/libxfs/xfs_dir2_node.c | 4 ++-- 5 files changed, 12 insertions(+), 23 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index a0cd423c79dd..34e7a0b64205 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -66,9 +66,7 @@ extern int xfs_dir2_isleaf(struct xfs_da_args *args, int *r); extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, struct xfs_buf *bp); -extern void xfs_dir2_data_freescan_int(struct xfs_mount *mp, - struct xfs_dir2_data_hdr *hdr, int *loghead); -extern void xfs_dir2_data_freescan(struct xfs_inode *dp, +extern void xfs_dir2_data_freescan(struct xfs_mount *mp, struct xfs_dir2_data_hdr *hdr, int *loghead); extern void xfs_dir2_data_log_entry(struct xfs_da_args *args, struct xfs_buf *bp, struct xfs_dir2_data_entry *dep); diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 0c481e55c981..358151ddfa75 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -311,7 +311,7 @@ xfs_dir2_block_compact( * This needs to happen before the next call to use_free. */ if (needscan) - xfs_dir2_data_freescan(args->dp, hdr, needlog); + xfs_dir2_data_freescan(args->dp->i_mount, hdr, needlog); } /* @@ -458,7 +458,7 @@ xfs_dir2_block_addname( * This needs to happen before the next call to use_free. */ if (needscan) { - xfs_dir2_data_freescan(dp, hdr, &needlog); + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); needscan = 0; } /* @@ -548,7 +548,7 @@ xfs_dir2_block_addname( * Clean up the bestfree array and log the header, tail, and entry. */ if (needscan) - xfs_dir2_data_freescan(dp, hdr, &needlog); + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); if (needlog) xfs_dir2_data_log_header(args, bp); xfs_dir2_block_log_tail(tp, bp); @@ -807,7 +807,7 @@ xfs_dir2_block_removename( * Fix up bestfree, log the header if necessary. */ if (needscan) - xfs_dir2_data_freescan(dp, hdr, &needlog); + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); if (needlog) xfs_dir2_data_log_header(args, bp); xfs_dir3_data_check(dp, bp); @@ -1014,7 +1014,7 @@ xfs_dir2_leaf_to_block( * Scan the bestfree if we need it and log the data block header. */ if (needscan) - xfs_dir2_data_freescan(dp, hdr, &needlog); + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); if (needlog) xfs_dir2_data_log_header(args, dbp); /* diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index 0aa1d165c964..9e471a28b6c6 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -608,7 +608,7 @@ xfs_dir2_data_freeremove( * Given a data block, reconstruct its bestfree map. */ void -xfs_dir2_data_freescan_int( +xfs_dir2_data_freescan( struct xfs_mount *mp, struct xfs_dir2_data_hdr *hdr, int *loghead) @@ -655,15 +655,6 @@ xfs_dir2_data_freescan_int( } } -void -xfs_dir2_data_freescan( - struct xfs_inode *dp, - struct xfs_dir2_data_hdr *hdr, - int *loghead) -{ - return xfs_dir2_data_freescan_int(dp->i_mount, hdr, loghead); -} - /* * Initialize a data block at the given block number in the directory. * Give back the buffer for the created block. diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index bc301c973450..2c67a9e24bd0 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -465,7 +465,7 @@ xfs_dir2_block_to_leaf( hdr->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC); if (needscan) - xfs_dir2_data_freescan(dp, hdr, &needlog); + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); /* * Set up leaf tail and bests table. */ @@ -872,7 +872,7 @@ xfs_dir2_leaf_addname( * Need to scan fix up the bestfree table. */ if (needscan) - xfs_dir2_data_freescan(dp, hdr, &needlog); + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); /* * Need to log the data block's header. */ @@ -1415,7 +1415,7 @@ xfs_dir2_leaf_removename( * log the data block header if necessary. */ if (needscan) - xfs_dir2_data_freescan(dp, hdr, &needlog); + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); if (needlog) xfs_dir2_data_log_header(args, dbp); /* diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 4ac7518b667d..5f30a1953a52 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -1328,7 +1328,7 @@ xfs_dir2_leafn_remove( * Log the data block header if needed. */ if (needscan) - xfs_dir2_data_freescan(dp, hdr, &needlog); + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); if (needlog) xfs_dir2_data_log_header(args, dbp); xfs_dir3_data_check(dp, dbp); @@ -1976,7 +1976,7 @@ xfs_dir2_node_addname_int( /* Rescan the freespace and log the data block if needed. */ if (needscan) - xfs_dir2_data_freescan(dp, hdr, &needlog); + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); if (needlog) xfs_dir2_data_log_header(args, dbp); -- cgit v1.2.3-70-g09d2 From a71895c5dad1ab8cf30622e208d148298ab602e5 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 11 Nov 2019 12:53:22 -0800 Subject: xfs: convert open coded corruption check to use XFS_IS_CORRUPT Convert the last of the open coded corruption check and report idioms to use the XFS_IS_CORRUPT macro. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_alloc.c | 7 ++--- fs/xfs/libxfs/xfs_bmap.c | 68 +++++++++++++++-------------------------- fs/xfs/libxfs/xfs_btree.c | 14 +++------ fs/xfs/libxfs/xfs_da_btree.c | 50 +++++++++--------------------- fs/xfs/libxfs/xfs_dir2.c | 10 +++--- fs/xfs/libxfs/xfs_dir2_node.c | 12 ++++---- fs/xfs/libxfs/xfs_refcount.c | 9 +++--- fs/xfs/libxfs/xfs_rmap.c | 2 +- fs/xfs/libxfs/xfs_rtbitmap.c | 4 +-- fs/xfs/xfs_attr_list.c | 23 ++++++-------- fs/xfs/xfs_dir2_readdir.c | 19 ++++++------ fs/xfs/xfs_iomap.c | 6 ++-- fs/xfs/xfs_iops.c | 4 +-- fs/xfs/xfs_log_recover.c | 71 ++++++++++++++++--------------------------- fs/xfs/xfs_mount.c | 7 ++--- fs/xfs/xfs_qm.c | 12 +++----- 16 files changed, 116 insertions(+), 202 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index fcee5e8f1a5b..c284e10af491 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -1071,8 +1071,7 @@ xfs_alloc_ag_vextent_small( struct xfs_buf *bp; bp = xfs_btree_get_bufs(args->mp, args->tp, args->agno, fbno); - if (!bp) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, args->mp); + if (XFS_IS_CORRUPT(args->mp, !bp)) { error = -EFSCORRUPTED; goto error; } @@ -2341,10 +2340,8 @@ xfs_free_agfl_block( return error; bp = xfs_btree_get_bufs(tp->t_mountp, tp, agno, agbno); - if (!bp) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, tp->t_mountp); + if (XFS_IS_CORRUPT(tp->t_mountp, !bp)) return -EFSCORRUPTED; - } xfs_trans_binval(tp, bp); return 0; diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 97b6a1fd3246..4acc6e37c31d 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -731,8 +731,7 @@ xfs_bmap_extents_to_btree( ip->i_d.di_nblocks++; xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); abp = xfs_btree_get_bufl(mp, tp, args.fsbno); - if (!abp) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, !abp)) { error = -EFSCORRUPTED; goto out_unreserve_dquot; } @@ -1090,8 +1089,7 @@ xfs_bmap_add_attrfork( goto trans_cancel; if (XFS_IFORK_Q(ip)) goto trans_cancel; - if (ip->i_d.di_anextents != 0) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, ip->i_d.di_anextents != 0)) { error = -EFSCORRUPTED; goto trans_cancel; } @@ -1238,8 +1236,9 @@ xfs_iread_extents( ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); - if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, + XFS_IFORK_FORMAT(ip, whichfork) != + XFS_DINODE_FMT_BTREE)) { error = -EFSCORRUPTED; goto out; } @@ -1253,8 +1252,8 @@ xfs_iread_extents( if (error) goto out; - if (ir.loaded != XFS_IFORK_NEXTENTS(ip, whichfork)) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, + ir.loaded != XFS_IFORK_NEXTENTS(ip, whichfork))) { error = -EFSCORRUPTED; goto out; } @@ -1444,10 +1443,8 @@ xfs_bmap_last_offset( if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) return 0; - if (!xfs_ifork_has_extents(ip, whichfork)) { - ASSERT(0); + if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ip, whichfork))) return -EFSCORRUPTED; - } error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty); if (error || is_empty) @@ -3906,10 +3903,8 @@ xfs_bmapi_read( XFS_BMAPI_COWFORK))); ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)); - if (unlikely(XFS_TEST_ERROR( - !xfs_ifork_has_extents(ip, whichfork), - mp, XFS_ERRTAG_BMAPIFORMAT))) { - XFS_ERROR_REPORT("xfs_bmapi_read", XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { return -EFSCORRUPTED; } @@ -4417,10 +4412,8 @@ xfs_bmapi_write( ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) != (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)); - if (unlikely(XFS_TEST_ERROR( - !xfs_ifork_has_extents(ip, whichfork), - mp, XFS_ERRTAG_BMAPIFORMAT))) { - XFS_ERROR_REPORT("xfs_bmapi_write", XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { return -EFSCORRUPTED; } @@ -4686,10 +4679,8 @@ xfs_bmapi_remap( ASSERT((flags & (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC)) != (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC)); - if (unlikely(XFS_TEST_ERROR( - !xfs_ifork_has_extents(ip, whichfork), - mp, XFS_ERRTAG_BMAPIFORMAT))) { - XFS_ERROR_REPORT("xfs_bmapi_remap", XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { return -EFSCORRUPTED; } @@ -5311,7 +5302,7 @@ __xfs_bunmapi( int isrt; /* freeing in rt area */ int logflags; /* transaction logging flags */ xfs_extlen_t mod; /* rt extent offset */ - struct xfs_mount *mp; /* mount structure */ + struct xfs_mount *mp = ip->i_mount; int tmp_logflags; /* partial logging flags */ int wasdel; /* was a delayed alloc extent */ int whichfork; /* data or attribute fork */ @@ -5328,12 +5319,8 @@ __xfs_bunmapi( whichfork = xfs_bmapi_whichfork(flags); ASSERT(whichfork != XFS_COW_FORK); ifp = XFS_IFORK_PTR(ip, whichfork); - if (unlikely(!xfs_ifork_has_extents(ip, whichfork))) { - XFS_ERROR_REPORT("xfs_bunmapi", XFS_ERRLEVEL_LOW, - ip->i_mount); + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork))) return -EFSCORRUPTED; - } - mp = ip->i_mount; if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; @@ -5826,10 +5813,8 @@ xfs_bmap_collapse_extents( int error = 0; int logflags = 0; - if (unlikely(XFS_TEST_ERROR( - !xfs_ifork_has_extents(ip, whichfork), - mp, XFS_ERRTAG_BMAPIFORMAT))) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { return -EFSCORRUPTED; } @@ -5945,10 +5930,8 @@ xfs_bmap_insert_extents( int error = 0; int logflags = 0; - if (unlikely(XFS_TEST_ERROR( - !xfs_ifork_has_extents(ip, whichfork), - mp, XFS_ERRTAG_BMAPIFORMAT))) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { return -EFSCORRUPTED; } @@ -5986,8 +5969,8 @@ xfs_bmap_insert_extents( goto del_cursor; } - if (stop_fsb >= got.br_startoff + got.br_blockcount) { - ASSERT(0); + if (XFS_IS_CORRUPT(mp, + stop_fsb >= got.br_startoff + got.br_blockcount)) { error = -EFSCORRUPTED; goto del_cursor; } @@ -6053,11 +6036,8 @@ xfs_bmap_split_extent_at( int logflags = 0; int i = 0; - if (unlikely(XFS_TEST_ERROR( - !xfs_ifork_has_extents(ip, whichfork), - mp, XFS_ERRTAG_BMAPIFORMAT))) { - XFS_ERROR_REPORT("xfs_bmap_split_extent_at", - XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { return -EFSCORRUPTED; } diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 897dfb9e4682..8f0e3a368f38 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -105,11 +105,10 @@ xfs_btree_check_lblock( xfs_failaddr_t fa; fa = __xfs_btree_check_lblock(cur, block, level, bp); - if (unlikely(XFS_TEST_ERROR(fa != NULL, mp, - XFS_ERRTAG_BTREE_CHECK_LBLOCK))) { + if (XFS_IS_CORRUPT(mp, fa != NULL) || + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK)) { if (bp) trace_xfs_btree_corrupt(bp, _RET_IP_); - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); return -EFSCORRUPTED; } return 0; @@ -169,11 +168,10 @@ xfs_btree_check_sblock( xfs_failaddr_t fa; fa = __xfs_btree_check_sblock(cur, block, level, bp); - if (unlikely(XFS_TEST_ERROR(fa != NULL, mp, - XFS_ERRTAG_BTREE_CHECK_SBLOCK))) { + if (XFS_IS_CORRUPT(mp, fa != NULL) || + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_SBLOCK)) { if (bp) trace_xfs_btree_corrupt(bp, _RET_IP_); - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); return -EFSCORRUPTED; } return 0; @@ -1849,10 +1847,8 @@ xfs_btree_lookup( XFS_BTREE_STATS_INC(cur, lookup); /* No such thing as a zero-level tree. */ - if (cur->bc_nlevels == 0) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, cur->bc_mp); + if (XFS_IS_CORRUPT(cur->bc_mp, cur->bc_nlevels == 0)) return -EFSCORRUPTED; - } block = NULL; keyno = 0; diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 46b1c3fb305c..418189498234 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -1663,17 +1663,12 @@ xfs_da3_node_lookup_int( } /* We can't point back to the root. */ - if (blkno == args->geo->leafblk) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, - dp->i_mount); + if (XFS_IS_CORRUPT(dp->i_mount, blkno == args->geo->leafblk)) return -EFSCORRUPTED; - } } - if (expected_level != 0) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, dp->i_mount); + if (XFS_IS_CORRUPT(dp->i_mount, expected_level != 0)) return -EFSCORRUPTED; - } /* * A leaf block that ends in the hashval that we are interested in @@ -2267,11 +2262,8 @@ xfs_da3_swap_lastblock( error = xfs_bmap_last_before(tp, dp, &lastoff, w); if (error) return error; - if (unlikely(lastoff == 0)) { - XFS_ERROR_REPORT("xfs_da_swap_lastblock(1)", XFS_ERRLEVEL_LOW, - mp); + if (XFS_IS_CORRUPT(mp, lastoff == 0)) return -EFSCORRUPTED; - } /* * Read the last block in the btree space. */ @@ -2317,11 +2309,9 @@ xfs_da3_swap_lastblock( if (error) goto done; sib_info = sib_buf->b_addr; - if (unlikely( - be32_to_cpu(sib_info->forw) != last_blkno || - sib_info->magic != dead_info->magic)) { - XFS_ERROR_REPORT("xfs_da_swap_lastblock(2)", - XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, + be32_to_cpu(sib_info->forw) != last_blkno || + sib_info->magic != dead_info->magic)) { error = -EFSCORRUPTED; goto done; } @@ -2339,11 +2329,9 @@ xfs_da3_swap_lastblock( if (error) goto done; sib_info = sib_buf->b_addr; - if (unlikely( - be32_to_cpu(sib_info->back) != last_blkno || - sib_info->magic != dead_info->magic)) { - XFS_ERROR_REPORT("xfs_da_swap_lastblock(3)", - XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, + be32_to_cpu(sib_info->back) != last_blkno || + sib_info->magic != dead_info->magic)) { error = -EFSCORRUPTED; goto done; } @@ -2364,9 +2352,8 @@ xfs_da3_swap_lastblock( goto done; par_node = par_buf->b_addr; xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node); - if (level >= 0 && level != par_hdr.level + 1) { - XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)", - XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, + level >= 0 && level != par_hdr.level + 1)) { error = -EFSCORRUPTED; goto done; } @@ -2377,9 +2364,7 @@ xfs_da3_swap_lastblock( be32_to_cpu(btree[entno].hashval) < dead_hash; entno++) continue; - if (entno == par_hdr.count) { - XFS_ERROR_REPORT("xfs_da_swap_lastblock(5)", - XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, entno == par_hdr.count)) { error = -EFSCORRUPTED; goto done; } @@ -2404,9 +2389,7 @@ xfs_da3_swap_lastblock( par_blkno = par_hdr.forw; xfs_trans_brelse(tp, par_buf); par_buf = NULL; - if (unlikely(par_blkno == 0)) { - XFS_ERROR_REPORT("xfs_da_swap_lastblock(6)", - XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, par_blkno == 0)) { error = -EFSCORRUPTED; goto done; } @@ -2415,9 +2398,7 @@ xfs_da3_swap_lastblock( goto done; par_node = par_buf->b_addr; xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node); - if (par_hdr.level != level) { - XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)", - XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, par_hdr.level != level)) { error = -EFSCORRUPTED; goto done; } @@ -2611,7 +2592,7 @@ xfs_dabuf_map( if (!xfs_da_map_covers_blocks(nirecs, irecs, bno, nfsb)) { /* Caller ok with no mapping. */ - if (mappedbno == -2) { + if (!XFS_IS_CORRUPT(mp, mappedbno != -2)) { error = -1; goto out; } @@ -2632,7 +2613,6 @@ xfs_dabuf_map( irecs[i].br_state); } } - XFS_ERROR_REPORT("xfs_da_do_buf(1)", XFS_ERRLEVEL_LOW, mp); error = -EFSCORRUPTED; goto out; } diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 624c05e77ab4..83cc8770f0ca 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -208,10 +208,10 @@ xfs_dir_ino_validate( { bool ino_ok = xfs_verify_dir_ino(mp, ino); - if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE))) { + if (XFS_IS_CORRUPT(mp, !ino_ok) || + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_DIR_INO_VALIDATE)) { xfs_warn(mp, "Invalid inode number 0x%Lx", (unsigned long long) ino); - XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp); return -EFSCORRUPTED; } return 0; @@ -617,10 +617,10 @@ xfs_dir2_isblock( if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK))) return rval; rval = XFS_FSB_TO_B(args->dp->i_mount, last) == args->geo->blksize; - if (rval != 0 && args->dp->i_d.di_size != args->geo->blksize) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, args->dp->i_mount); + if (XFS_IS_CORRUPT(args->dp->i_mount, + rval != 0 && + args->dp->i_d.di_size != args->geo->blksize)) return -EFSCORRUPTED; - } *vp = rval; return 0; } diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 5f30a1953a52..560b7e9d210d 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -728,10 +728,9 @@ xfs_dir2_leafn_lookup_for_addname( * If it has room, return it. */ xfs_dir2_free_hdr_from_disk(mp, &freehdr, free); - if (unlikely( - freehdr.bests[fi] == cpu_to_be16(NULLDATAOFF))) { - XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", - XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, + freehdr.bests[fi] == + cpu_to_be16(NULLDATAOFF))) { if (curfdb != newfdb) xfs_trans_brelse(tp, curbp); return -EFSCORRUPTED; @@ -1722,7 +1721,9 @@ xfs_dir2_node_add_datablk( if (error) return error; - if (xfs_dir2_db_to_fdb(args->geo, *dbno) != fbno) { + if (XFS_IS_CORRUPT(mp, + xfs_dir2_db_to_fdb(args->geo, *dbno) != + fbno)) { xfs_alert(mp, "%s: dir ino %llu needed freesp block %lld for data block %lld, got %lld", __func__, (unsigned long long)dp->i_ino, @@ -1736,7 +1737,6 @@ xfs_dir2_node_add_datablk( } else { xfs_alert(mp, " ... fblk is NULL"); } - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); return -EFSCORRUPTED; } diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index af7fc4f6f62b..d7d702ee4d1a 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -1177,7 +1177,7 @@ xfs_refcount_finish_one( XFS_ALLOC_FLAG_FREEING, &agbp); if (error) return error; - if (!agbp) + if (XFS_IS_CORRUPT(tp->t_mountp, !agbp)) return -EFSCORRUPTED; rcur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno); @@ -1661,17 +1661,16 @@ struct xfs_refcount_recovery { /* Stuff an extent on the recovery list. */ STATIC int xfs_refcount_recover_extent( - struct xfs_btree_cur *cur, + struct xfs_btree_cur *cur, union xfs_btree_rec *rec, void *priv) { struct list_head *debris = priv; struct xfs_refcount_recovery *rr; - if (be32_to_cpu(rec->refc.rc_refcount) != 1) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, cur->bc_mp); + if (XFS_IS_CORRUPT(cur->bc_mp, + be32_to_cpu(rec->refc.rc_refcount) != 1)) return -EFSCORRUPTED; - } rr = kmem_alloc(sizeof(struct xfs_refcount_recovery), 0); xfs_refcount_btrec_to_irec(rec, &rr->rr_rrec); diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index 9488cbe5a80f..ff9412f113c4 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -2400,7 +2400,7 @@ xfs_rmap_finish_one( error = xfs_free_extent_fix_freelist(tp, agno, &agbp); if (error) return error; - if (!agbp) + if (XFS_IS_CORRUPT(tp->t_mountp, !agbp)) return -EFSCORRUPTED; rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index d8aaa1de921c..f42c74cb8be5 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -70,10 +70,8 @@ xfs_rtbuf_get( if (error) return error; - if (nmap == 0 || !xfs_bmap_is_real_extent(&map)) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, nmap == 0 || !xfs_bmap_is_real_extent(&map))) return -EFSCORRUPTED; - } ASSERT(map.br_startblock != NULLFSBLOCK); error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index 0ec6606149a2..7a099df88a0c 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c @@ -86,11 +86,10 @@ xfs_attr_shortform_list( (XFS_ISRESET_CURSOR(cursor) && (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) { for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { - if (!xfs_attr_namecheck(sfe->nameval, sfe->namelen)) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, - context->dp->i_mount); + if (XFS_IS_CORRUPT(context->dp->i_mount, + !xfs_attr_namecheck(sfe->nameval, + sfe->namelen))) return -EFSCORRUPTED; - } context->put_listent(context, sfe->flags, sfe->nameval, @@ -179,9 +178,9 @@ xfs_attr_shortform_list( cursor->hashval = sbp->hash; cursor->offset = 0; } - if (!xfs_attr_namecheck(sbp->name, sbp->namelen)) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, - context->dp->i_mount); + if (XFS_IS_CORRUPT(context->dp->i_mount, + !xfs_attr_namecheck(sbp->name, + sbp->namelen))) { error = -EFSCORRUPTED; goto out; } @@ -269,10 +268,8 @@ xfs_attr_node_list_lookup( return 0; /* We can't point back to the root. */ - if (cursor->blkno == 0) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, cursor->blkno == 0)) return -EFSCORRUPTED; - } } if (expected_level != 0) @@ -473,11 +470,9 @@ xfs_attr3_leaf_list_int( valuelen = be32_to_cpu(name_rmt->valuelen); } - if (!xfs_attr_namecheck(name, namelen)) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, - context->dp->i_mount); + if (XFS_IS_CORRUPT(context->dp->i_mount, + !xfs_attr_namecheck(name, namelen))) return -EFSCORRUPTED; - } context->put_listent(context, entry->flags, name, namelen, valuelen); if (context->seen_enough) diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index b149cb4a4d86..95bc9ef8f5f9 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -117,11 +117,10 @@ xfs_dir2_sf_getdents( ino = xfs_dir2_sf_get_ino(mp, sfp, sfep); filetype = xfs_dir2_sf_get_ftype(mp, sfep); ctx->pos = off & 0x7fffffff; - if (!xfs_dir2_namecheck(sfep->name, sfep->namelen)) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, - dp->i_mount); + if (XFS_IS_CORRUPT(dp->i_mount, + !xfs_dir2_namecheck(sfep->name, + sfep->namelen))) return -EFSCORRUPTED; - } if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino, xfs_dir3_get_dtype(mp, filetype))) return 0; @@ -207,9 +206,9 @@ xfs_dir2_block_getdents( /* * If it didn't fit, set the final offset to here & return. */ - if (!xfs_dir2_namecheck(dep->name, dep->namelen)) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, - dp->i_mount); + if (XFS_IS_CORRUPT(dp->i_mount, + !xfs_dir2_namecheck(dep->name, + dep->namelen))) { error = -EFSCORRUPTED; goto out_rele; } @@ -459,9 +458,9 @@ xfs_dir2_leaf_getdents( filetype = xfs_dir2_data_get_ftype(mp, dep); ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff; - if (!xfs_dir2_namecheck(dep->name, dep->namelen)) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, - dp->i_mount); + if (XFS_IS_CORRUPT(dp->i_mount, + !xfs_dir2_namecheck(dep->name, + dep->namelen))) { error = -EFSCORRUPTED; break; } diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index d1960ff0a396..28e2d1f37267 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -856,10 +856,8 @@ xfs_buffered_write_iomap_begin( xfs_ilock(ip, XFS_ILOCK_EXCL); - if (unlikely(XFS_TEST_ERROR( - !xfs_ifork_has_extents(ip, XFS_DATA_FORK), - mp, XFS_ERRTAG_BMAPIFORMAT))) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, XFS_DATA_FORK)) || + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { error = -EFSCORRUPTED; goto out_unlock; } diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 57e6e44123a9..b129e077a5fa 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -481,10 +481,8 @@ xfs_vn_get_link_inline( * if_data is junk. */ link = ip->i_df.if_u1.if_data; - if (!link) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, ip->i_mount); + if (XFS_IS_CORRUPT(ip->i_mount, !link)) return ERR_PTR(-EFSCORRUPTED); - } return link; } diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 02f2147952b3..a008e3349483 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -103,10 +103,9 @@ xlog_alloc_buffer( * Pass log block 0 since we don't have an addr yet, buffer will be * verified on read. */ - if (!xlog_verify_bno(log, 0, nbblks)) { + if (XFS_IS_CORRUPT(log->l_mp, !xlog_verify_bno(log, 0, nbblks))) { xfs_warn(log->l_mp, "Invalid block length (0x%x) for buffer", nbblks); - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp); return NULL; } @@ -152,11 +151,10 @@ xlog_do_io( { int error; - if (!xlog_verify_bno(log, blk_no, nbblks)) { + if (XFS_IS_CORRUPT(log->l_mp, !xlog_verify_bno(log, blk_no, nbblks))) { xfs_warn(log->l_mp, "Invalid log block/length (0x%llx, 0x%x) for buffer", blk_no, nbblks); - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp); return -EFSCORRUPTED; } @@ -244,19 +242,17 @@ xlog_header_check_recover( * (XLOG_FMT_UNKNOWN). This stops us from trying to recover * a dirty log created in IRIX. */ - if (unlikely(head->h_fmt != cpu_to_be32(XLOG_FMT))) { + if (XFS_IS_CORRUPT(mp, head->h_fmt != cpu_to_be32(XLOG_FMT))) { xfs_warn(mp, "dirty log written in incompatible format - can't recover"); xlog_header_check_dump(mp, head); - XFS_ERROR_REPORT("xlog_header_check_recover(1)", - XFS_ERRLEVEL_HIGH, mp); return -EFSCORRUPTED; - } else if (unlikely(!uuid_equal(&mp->m_sb.sb_uuid, &head->h_fs_uuid))) { + } + if (XFS_IS_CORRUPT(mp, !uuid_equal(&mp->m_sb.sb_uuid, + &head->h_fs_uuid))) { xfs_warn(mp, "dirty log entry has mismatched uuid - can't recover"); xlog_header_check_dump(mp, head); - XFS_ERROR_REPORT("xlog_header_check_recover(2)", - XFS_ERRLEVEL_HIGH, mp); return -EFSCORRUPTED; } return 0; @@ -279,11 +275,10 @@ xlog_header_check_mount( * by IRIX and continue. */ xfs_warn(mp, "null uuid in log - IRIX style log"); - } else if (unlikely(!uuid_equal(&mp->m_sb.sb_uuid, &head->h_fs_uuid))) { + } else if (XFS_IS_CORRUPT(mp, !uuid_equal(&mp->m_sb.sb_uuid, + &head->h_fs_uuid))) { xfs_warn(mp, "log has mismatched uuid - can't recover"); xlog_header_check_dump(mp, head); - XFS_ERROR_REPORT("xlog_header_check_mount", - XFS_ERRLEVEL_HIGH, mp); return -EFSCORRUPTED; } return 0; @@ -1699,11 +1694,10 @@ xlog_clear_stale_blocks( * the distance from the beginning of the log to the * tail. */ - if (unlikely(head_block < tail_block || head_block >= log->l_logBBsize)) { - XFS_ERROR_REPORT("xlog_clear_stale_blocks(1)", - XFS_ERRLEVEL_LOW, log->l_mp); + if (XFS_IS_CORRUPT(log->l_mp, + head_block < tail_block || + head_block >= log->l_logBBsize)) return -EFSCORRUPTED; - } tail_distance = tail_block + (log->l_logBBsize - head_block); } else { /* @@ -1711,11 +1705,10 @@ xlog_clear_stale_blocks( * so the distance from the head to the tail is just * the tail block minus the head block. */ - if (unlikely(head_block >= tail_block || head_cycle != (tail_cycle + 1))){ - XFS_ERROR_REPORT("xlog_clear_stale_blocks(2)", - XFS_ERRLEVEL_LOW, log->l_mp); + if (XFS_IS_CORRUPT(log->l_mp, + head_block >= tail_block || + head_cycle != tail_cycle + 1)) return -EFSCORRUPTED; - } tail_distance = tail_block - head_block; } @@ -2135,13 +2128,11 @@ xlog_recover_do_inode_buffer( */ logged_nextp = item->ri_buf[item_index].i_addr + next_unlinked_offset - reg_buf_offset; - if (unlikely(*logged_nextp == 0)) { + if (XFS_IS_CORRUPT(mp, *logged_nextp == 0)) { xfs_alert(mp, "Bad inode buffer log record (ptr = "PTR_FMT", bp = "PTR_FMT"). " "Trying to replay bad (0) inode di_next_unlinked field.", item, bp); - XFS_ERROR_REPORT("xlog_recover_do_inode_buf", - XFS_ERRLEVEL_LOW, mp); return -EFSCORRUPTED; } @@ -2969,22 +2960,18 @@ xlog_recover_inode_pass2( * Make sure the place we're flushing out to really looks * like an inode! */ - if (unlikely(!xfs_verify_magic16(bp, dip->di_magic))) { + if (XFS_IS_CORRUPT(mp, !xfs_verify_magic16(bp, dip->di_magic))) { xfs_alert(mp, "%s: Bad inode magic number, dip = "PTR_FMT", dino bp = "PTR_FMT", ino = %Ld", __func__, dip, bp, in_f->ilf_ino); - XFS_ERROR_REPORT("xlog_recover_inode_pass2(1)", - XFS_ERRLEVEL_LOW, mp); error = -EFSCORRUPTED; goto out_release; } ldip = item->ri_buf[1].i_addr; - if (unlikely(ldip->di_magic != XFS_DINODE_MAGIC)) { + if (XFS_IS_CORRUPT(mp, ldip->di_magic != XFS_DINODE_MAGIC)) { xfs_alert(mp, "%s: Bad inode log record, rec ptr "PTR_FMT", ino %Ld", __func__, item, in_f->ilf_ino); - XFS_ERROR_REPORT("xlog_recover_inode_pass2(2)", - XFS_ERRLEVEL_LOW, mp); error = -EFSCORRUPTED; goto out_release; } @@ -5209,14 +5196,13 @@ xlog_valid_rec_header( { int hlen; - if (unlikely(rhead->h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM))) { - XFS_ERROR_REPORT("xlog_valid_rec_header(1)", - XFS_ERRLEVEL_LOW, log->l_mp); + if (XFS_IS_CORRUPT(log->l_mp, + rhead->h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM))) return -EFSCORRUPTED; - } - if (unlikely( - (!rhead->h_version || - (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) { + if (XFS_IS_CORRUPT(log->l_mp, + (!rhead->h_version || + (be32_to_cpu(rhead->h_version) & + (~XLOG_VERSION_OKBITS))))) { xfs_warn(log->l_mp, "%s: unrecognised log version (%d).", __func__, be32_to_cpu(rhead->h_version)); return -EFSCORRUPTED; @@ -5224,16 +5210,11 @@ xlog_valid_rec_header( /* LR body must have data or it wouldn't have been written */ hlen = be32_to_cpu(rhead->h_len); - if (unlikely( hlen <= 0 || hlen > INT_MAX )) { - XFS_ERROR_REPORT("xlog_valid_rec_header(2)", - XFS_ERRLEVEL_LOW, log->l_mp); + if (XFS_IS_CORRUPT(log->l_mp, hlen <= 0 || hlen > INT_MAX)) return -EFSCORRUPTED; - } - if (unlikely( blkno > log->l_logBBsize || blkno > INT_MAX )) { - XFS_ERROR_REPORT("xlog_valid_rec_header(3)", - XFS_ERRLEVEL_LOW, log->l_mp); + if (XFS_IS_CORRUPT(log->l_mp, + blkno > log->l_logBBsize || blkno > INT_MAX)) return -EFSCORRUPTED; - } return 0; } diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 5ea95247a37f..fca65109cf24 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -761,9 +761,8 @@ xfs_mountfs( goto out_free_dir; } - if (!sbp->sb_logblocks) { + if (XFS_IS_CORRUPT(mp, !sbp->sb_logblocks)) { xfs_warn(mp, "no log defined"); - XFS_ERROR_REPORT("xfs_mountfs", XFS_ERRLEVEL_LOW, mp); error = -EFSCORRUPTED; goto out_free_perag; } @@ -801,12 +800,10 @@ xfs_mountfs( ASSERT(rip != NULL); - if (unlikely(!S_ISDIR(VFS_I(rip)->i_mode))) { + if (XFS_IS_CORRUPT(mp, !S_ISDIR(VFS_I(rip)->i_mode))) { xfs_warn(mp, "corrupted root inode %llu: not a directory", (unsigned long long)rip->i_ino); xfs_iunlock(rip, XFS_ILOCK_EXCL); - XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW, - mp); error = -EFSCORRUPTED; goto out_rele_rip; } diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 66ea8e4fca86..7e264cbd15b9 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -755,19 +755,15 @@ xfs_qm_qino_alloc( if ((flags & XFS_QMOPT_PQUOTA) && (mp->m_sb.sb_gquotino != NULLFSINO)) { ino = mp->m_sb.sb_gquotino; - if (mp->m_sb.sb_pquotino != NULLFSINO) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, - mp); + if (XFS_IS_CORRUPT(mp, + mp->m_sb.sb_pquotino != NULLFSINO)) return -EFSCORRUPTED; - } } else if ((flags & XFS_QMOPT_GQUOTA) && (mp->m_sb.sb_pquotino != NULLFSINO)) { ino = mp->m_sb.sb_pquotino; - if (mp->m_sb.sb_gquotino != NULLFSINO) { - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, - mp); + if (XFS_IS_CORRUPT(mp, + mp->m_sb.sb_gquotino != NULLFSINO)) return -EFSCORRUPTED; - } } if (ino != NULLFSINO) { error = xfs_iget(mp, NULL, ino, 0, 0, ip); -- cgit v1.2.3-70-g09d2 From d8d11fc703a22bbe3939e08b08396fa6b816719a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 11 Nov 2019 12:59:26 -0800 Subject: xfs: devirtualize ->m_dirnameops Instead of causing a relatively expensive indirect call for each hashing and comparism of a file name in a directory just use an inline function and a simple branch on the ASCII CI bit. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong [darrick: fix unused variable warning] Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_btree.c | 14 +------------- fs/xfs/libxfs/xfs_da_btree.h | 11 ----------- fs/xfs/libxfs/xfs_dir2.c | 33 +++++++++++---------------------- fs/xfs/libxfs/xfs_dir2_block.c | 7 ++----- fs/xfs/libxfs/xfs_dir2_data.c | 2 +- fs/xfs/libxfs/xfs_dir2_leaf.c | 2 +- fs/xfs/libxfs/xfs_dir2_node.c | 2 +- fs/xfs/libxfs/xfs_dir2_priv.h | 24 ++++++++++++++++++++++++ fs/xfs/libxfs/xfs_dir2_sf.c | 3 +-- fs/xfs/xfs_mount.h | 2 -- 10 files changed, 42 insertions(+), 58 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 418189498234..e424b004e3cb 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -12,9 +12,9 @@ #include "xfs_trans_resv.h" #include "xfs_bit.h" #include "xfs_mount.h" +#include "xfs_inode.h" #include "xfs_dir2.h" #include "xfs_dir2_priv.h" -#include "xfs_inode.h" #include "xfs_trans.h" #include "xfs_bmap.h" #include "xfs_attr_leaf.h" @@ -2093,18 +2093,6 @@ xfs_da_compname( XFS_CMP_EXACT : XFS_CMP_DIFFERENT; } -static xfs_dahash_t -xfs_default_hashname( - struct xfs_name *name) -{ - return xfs_da_hashname(name->name, name->len); -} - -const struct xfs_nameops xfs_default_nameops = { - .hashname = xfs_default_hashname, - .compname = xfs_da_compname -}; - int xfs_da_grow_inode_int( struct xfs_da_args *args, diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index 5af4df71e92b..ed3b558a9c1a 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -158,16 +158,6 @@ struct xfs_da3_icnode_hdr { (uint)(XFS_DA_LOGOFF(BASE, ADDR)), \ (uint)(XFS_DA_LOGOFF(BASE, ADDR)+(SIZE)-1) -/* - * Name ops for directory and/or attr name operations - */ -struct xfs_nameops { - xfs_dahash_t (*hashname)(struct xfs_name *); - enum xfs_dacmp (*compname)(struct xfs_da_args *, - const unsigned char *, int); -}; - - /*======================================================================== * Function prototypes. *========================================================================*/ @@ -234,6 +224,5 @@ void xfs_da3_node_hdr_to_disk(struct xfs_mount *mp, struct xfs_da_intnode *to, struct xfs_da3_icnode_hdr *from); extern struct kmem_zone *xfs_da_state_zone; -extern const struct xfs_nameops xfs_default_nameops; #endif /* __XFS_DA_BTREE_H__ */ diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 83cc8770f0ca..0aa87cbde49e 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -52,7 +52,7 @@ xfs_mode_to_ftype( * ASCII case-insensitive (ie. A-Z) support for directories that was * used in IRIX. */ -STATIC xfs_dahash_t +xfs_dahash_t xfs_ascii_ci_hashname( struct xfs_name *name) { @@ -65,14 +65,14 @@ xfs_ascii_ci_hashname( return hash; } -STATIC enum xfs_dacmp +enum xfs_dacmp xfs_ascii_ci_compname( - struct xfs_da_args *args, - const unsigned char *name, - int len) + struct xfs_da_args *args, + const unsigned char *name, + int len) { - enum xfs_dacmp result; - int i; + enum xfs_dacmp result; + int i; if (args->namelen != len) return XFS_CMP_DIFFERENT; @@ -89,11 +89,6 @@ xfs_ascii_ci_compname( return result; } -static const struct xfs_nameops xfs_ascii_ci_nameops = { - .hashname = xfs_ascii_ci_hashname, - .compname = xfs_ascii_ci_compname, -}; - int xfs_da_mount( struct xfs_mount *mp) @@ -163,12 +158,6 @@ xfs_da_mount( dageo->node_ents = (dageo->blksize - dageo->node_hdr_size) / (uint)sizeof(xfs_da_node_entry_t); dageo->magicpct = (dageo->blksize * 37) / 100; - - if (xfs_sb_version_hasasciici(&mp->m_sb)) - mp->m_dirnameops = &xfs_ascii_ci_nameops; - else - mp->m_dirnameops = &xfs_default_nameops; - return 0; } @@ -279,7 +268,7 @@ xfs_dir_createname( args->name = name->name; args->namelen = name->len; args->filetype = name->type; - args->hashval = dp->i_mount->m_dirnameops->hashname(name); + args->hashval = xfs_dir2_hashname(dp->i_mount, name); args->inumber = inum; args->dp = dp; args->total = total; @@ -375,7 +364,7 @@ xfs_dir_lookup( args->name = name->name; args->namelen = name->len; args->filetype = name->type; - args->hashval = dp->i_mount->m_dirnameops->hashname(name); + args->hashval = xfs_dir2_hashname(dp->i_mount, name); args->dp = dp; args->whichfork = XFS_DATA_FORK; args->trans = tp; @@ -447,7 +436,7 @@ xfs_dir_removename( args->name = name->name; args->namelen = name->len; args->filetype = name->type; - args->hashval = dp->i_mount->m_dirnameops->hashname(name); + args->hashval = xfs_dir2_hashname(dp->i_mount, name); args->inumber = ino; args->dp = dp; args->total = total; @@ -508,7 +497,7 @@ xfs_dir_replace( args->name = name->name; args->namelen = name->len; args->filetype = name->type; - args->hashval = dp->i_mount->m_dirnameops->hashname(name); + args->hashval = xfs_dir2_hashname(dp->i_mount, name); args->inumber = inum; args->dp = dp; args->total = total; diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 358151ddfa75..328a8dd53a22 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -660,13 +660,11 @@ xfs_dir2_block_lookup_int( int high; /* binary search high index */ int low; /* binary search low index */ int mid; /* binary search current idx */ - xfs_mount_t *mp; /* filesystem mount point */ xfs_trans_t *tp; /* transaction pointer */ enum xfs_dacmp cmp; /* comparison result */ dp = args->dp; tp = args->trans; - mp = dp->i_mount; error = xfs_dir3_block_read(tp, dp, &bp); if (error) @@ -718,7 +716,7 @@ xfs_dir2_block_lookup_int( * and buffer. If it's the first case-insensitive match, store * the index and buffer and continue looking for an exact match. */ - cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); + cmp = xfs_dir2_compname(args, dep->name, dep->namelen); if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { args->cmpresult = cmp; *bpp = bp; @@ -1218,8 +1216,7 @@ xfs_dir2_sf_to_block( xfs_dir2_data_log_entry(args, bp, dep); name.name = sfep->name; name.len = sfep->namelen; - blp[2 + i].hashval = - cpu_to_be32(mp->m_dirnameops->hashname(&name)); + blp[2 + i].hashval = cpu_to_be32(xfs_dir2_hashname(mp, &name)); blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(newoffset)); offset = (int)((char *)(tagp + 1) - (char *)hdr); diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index 9e471a28b6c6..11b1f3021e66 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -236,7 +236,7 @@ __xfs_dir3_data_check( ((char *)dep - (char *)hdr)); name.name = dep->name; name.len = dep->namelen; - hash = mp->m_dirnameops->hashname(&name); + hash = xfs_dir2_hashname(mp, &name); for (i = 0; i < be32_to_cpu(btp->count); i++) { if (be32_to_cpu(lep[i].address) == addr && be32_to_cpu(lep[i].hashval) == hash) diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index e2e4b2c6d6c2..73edd96ce0ac 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -1288,7 +1288,7 @@ xfs_dir2_leaf_lookup_int( * and buffer. If it's the first case-insensitive match, store * the index and buffer and continue looking for an exact match. */ - cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); + cmp = xfs_dir2_compname(args, dep->name, dep->namelen); if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { args->cmpresult = cmp; *indexp = index; diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 560b7e9d210d..3a8b0625a08b 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -875,7 +875,7 @@ xfs_dir2_leafn_lookup_for_entry( * EEXIST immediately. If it's the first case-insensitive * match, store the block & inode number and continue looking. */ - cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); + cmp = xfs_dir2_compname(args, dep->name, dep->namelen); if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { /* If there is a CI match block, drop it */ if (args->cmpresult != XFS_CMP_DIFFERENT && diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index a22222df4bf2..eb6af7daf803 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h @@ -40,6 +40,9 @@ struct xfs_dir3_icfree_hdr { }; /* xfs_dir2.c */ +xfs_dahash_t xfs_ascii_ci_hashname(struct xfs_name *name); +enum xfs_dacmp xfs_ascii_ci_compname(struct xfs_da_args *args, + const unsigned char *name, int len); extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, xfs_dir2_db_t *dbp); extern int xfs_dir_cilookup_result(struct xfs_da_args *args, @@ -191,4 +194,25 @@ xfs_dir2_data_entsize( return round_up(len, XFS_DIR2_DATA_ALIGN); } +static inline xfs_dahash_t +xfs_dir2_hashname( + struct xfs_mount *mp, + struct xfs_name *name) +{ + if (unlikely(xfs_sb_version_hasasciici(&mp->m_sb))) + return xfs_ascii_ci_hashname(name); + return xfs_da_hashname(name->name, name->len); +} + +static inline enum xfs_dacmp +xfs_dir2_compname( + struct xfs_da_args *args, + const unsigned char *name, + int len) +{ + if (unlikely(xfs_sb_version_hasasciici(&args->dp->i_mount->m_sb))) + return xfs_ascii_ci_compname(args, name, len); + return xfs_da_compname(args, name, len); +} + #endif /* __XFS_DIR2_PRIV_H__ */ diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c index db1a82972d9e..41eb8a676bf3 100644 --- a/fs/xfs/libxfs/xfs_dir2_sf.c +++ b/fs/xfs/libxfs/xfs_dir2_sf.c @@ -914,8 +914,7 @@ xfs_dir2_sf_lookup( * number. If it's the first case-insensitive match, store the * inode number and continue looking for an exact match. */ - cmp = dp->i_mount->m_dirnameops->compname(args, sfep->name, - sfep->namelen); + cmp = xfs_dir2_compname(args, sfep->name, sfep->namelen); if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { args->cmpresult = cmp; args->inumber = xfs_dir2_sf_get_ino(mp, sfp, sfep); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 43145a4ab690..247c2b15a22c 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -9,7 +9,6 @@ struct xlog; struct xfs_inode; struct xfs_mru_cache; -struct xfs_nameops; struct xfs_ail; struct xfs_quotainfo; struct xfs_da_geometry; @@ -154,7 +153,6 @@ typedef struct xfs_mount { int m_dalign; /* stripe unit */ int m_swidth; /* stripe width */ uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ - const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */ atomic_t m_active_trans; /* number trans frozen */ struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ struct delayed_work m_reclaim_work; /* background inode reclaim */ -- cgit v1.2.3-70-g09d2 From f3fcb314d16cdcffb6c521564b86b453869300da Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 20 Nov 2019 09:46:03 -0800 Subject: xfs: remove the mappedbno argument to xfs_dir3_leafn_read This argument is always hard coded to -1, so remove it. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_dir2_leaf.c | 5 ++--- fs/xfs/libxfs/xfs_dir2_node.c | 3 +-- fs/xfs/libxfs/xfs_dir2_priv.h | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index 41df4322f260..482a974d6361 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -278,13 +278,12 @@ xfs_dir3_leafn_read( struct xfs_trans *tp, struct xfs_inode *dp, xfs_dablk_t fbno, - xfs_daddr_t mappedbno, struct xfs_buf **bpp) { int err; - err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, - XFS_DATA_FORK, &xfs_dir3_leafn_buf_ops); + err = xfs_da_read_buf(tp, dp, fbno, -1, bpp, XFS_DATA_FORK, + &xfs_dir3_leafn_buf_ops); if (!err && tp && *bpp) xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_LEAFN_BUF); return err; diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 3a8b0625a08b..2e2129fdb6a9 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -1553,8 +1553,7 @@ xfs_dir2_leafn_toosmall( /* * Read the sibling leaf block. */ - error = xfs_dir3_leafn_read(state->args->trans, dp, - blkno, -1, &bp); + error = xfs_dir3_leafn_read(state->args->trans, dp, blkno, &bp); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index 4d5e17a81cd4..15353b61051b 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h @@ -96,8 +96,8 @@ void xfs_dir2_leaf_hdr_to_disk(struct xfs_mount *mp, struct xfs_dir2_leaf *to, struct xfs_dir3_icleaf_hdr *from); int xfs_dir3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, xfs_dablk_t fbno, struct xfs_buf **bpp); -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); +int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp, + xfs_dablk_t fbno, struct xfs_buf **bpp); extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args, struct xfs_buf *dbp); extern int xfs_dir2_leaf_addname(struct xfs_da_args *args); -- cgit v1.2.3-70-g09d2 From cd2c9f1b544b8f5e1ca1874032fd669d74946a6d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 20 Nov 2019 09:46:04 -0800 Subject: xfs: remove the mappedbno argument to xfs_da_read_buf Move the code for reading an already mapped block into xfs_da3_node_read_mapped, which is the only caller ever passing a block number in the mappedbno argument and replace the mappedbno argument with the simple xfs_dabuf_get flags. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr_leaf.c | 2 +- fs/xfs/libxfs/xfs_da_btree.c | 34 ++++++++++++++++------------------ fs/xfs/libxfs/xfs_da_btree.h | 5 ++--- fs/xfs/libxfs/xfs_dir2_block.c | 4 ++-- fs/xfs/libxfs/xfs_dir2_data.c | 6 +++--- fs/xfs/libxfs/xfs_dir2_leaf.c | 13 ++++++------- fs/xfs/libxfs/xfs_dir2_node.c | 14 +++++++------- fs/xfs/libxfs/xfs_dir2_priv.h | 4 ++-- fs/xfs/scrub/dabtree.c | 4 ++-- fs/xfs/scrub/dir.c | 9 +++++---- fs/xfs/xfs_dir2_readdir.c | 2 +- 11 files changed, 47 insertions(+), 50 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 2d17ed342a96..b0742c856de2 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -434,7 +434,7 @@ xfs_attr3_leaf_read( { int err; - err = xfs_da_read_buf(tp, dp, bno, -1, bpp, XFS_ATTR_FORK, + err = xfs_da_read_buf(tp, dp, bno, 0, bpp, XFS_ATTR_FORK, &xfs_attr3_leaf_buf_ops); if (!err && tp && *bpp) xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_ATTR_LEAF_BUF); diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index ee509bb787ff..c00983034c78 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -369,7 +369,7 @@ xfs_da3_node_read( { int error; - error = xfs_da_read_buf(tp, dp, bno, -1, bpp, whichfork, + error = xfs_da_read_buf(tp, dp, bno, 0, bpp, whichfork, &xfs_da3_node_buf_ops); if (error || !*bpp || !tp) return error; @@ -384,12 +384,22 @@ xfs_da3_node_read_mapped( struct xfs_buf **bpp, int whichfork) { + struct xfs_mount *mp = dp->i_mount; int error; - error = xfs_da_read_buf(tp, dp, 0, mappedbno, bpp, whichfork, - &xfs_da3_node_buf_ops); - if (error || !*bpp || !tp) + error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, mappedbno, + XFS_FSB_TO_BB(mp, xfs_dabuf_nfsb(mp, whichfork)), 0, + bpp, &xfs_da3_node_buf_ops); + if (error || !*bpp) return error; + + if (whichfork == XFS_ATTR_FORK) + xfs_buf_set_ref(*bpp, XFS_ATTR_BTREE_REF); + else + xfs_buf_set_ref(*bpp, XFS_DIR_BTREE_REF); + + if (!tp) + return 0; return xfs_da3_node_set_type(tp, *bpp); } @@ -2618,7 +2628,7 @@ xfs_da_read_buf( struct xfs_trans *tp, struct xfs_inode *dp, xfs_dablk_t bno, - xfs_daddr_t mappedbno, + unsigned int flags, struct xfs_buf **bpp, int whichfork, const struct xfs_buf_ops *ops) @@ -2630,24 +2640,12 @@ xfs_da_read_buf( int error; *bpp = NULL; - - if (mappedbno >= 0) { - error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, - mappedbno, XFS_FSB_TO_BB(mp, - xfs_dabuf_nfsb(mp, whichfork)), - 0, &bp, ops); - goto done; - } - - error = xfs_dabuf_map(dp, bno, - mappedbno == -1 ? XFS_DABUF_MAP_HOLE_OK : 0, - whichfork, &mapp, &nmap); + error = xfs_dabuf_map(dp, bno, flags, whichfork, &mapp, &nmap); if (error || !nmap) goto out_free; error = xfs_trans_read_buf_map(mp, tp, mp->m_ddev_targp, mapp, nmap, 0, &bp, ops); -done: if (error) goto out_free; diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index 25bcbfa9016f..f83d18a5d5f1 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -206,9 +206,8 @@ int xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp, xfs_dablk_t bno, xfs_daddr_t mappedbno, struct xfs_buf **bp, int whichfork); int xfs_da_read_buf(struct xfs_trans *trans, struct xfs_inode *dp, - xfs_dablk_t bno, xfs_daddr_t mappedbno, - struct xfs_buf **bpp, int whichfork, - const struct xfs_buf_ops *ops); + xfs_dablk_t bno, unsigned int flags, struct xfs_buf **bpp, + int whichfork, const struct xfs_buf_ops *ops); int xfs_da_reada_buf(struct xfs_inode *dp, xfs_dablk_t bno, unsigned int flags, int whichfork, const struct xfs_buf_ops *ops); diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 328a8dd53a22..d6ced59b9567 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -123,7 +123,7 @@ xfs_dir3_block_read( struct xfs_mount *mp = dp->i_mount; int err; - err = xfs_da_read_buf(tp, dp, mp->m_dir_geo->datablk, -1, bpp, + err = xfs_da_read_buf(tp, dp, mp->m_dir_geo->datablk, 0, bpp, XFS_DATA_FORK, &xfs_dir3_block_buf_ops); if (!err && tp && *bpp) xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_BLOCK_BUF); @@ -950,7 +950,7 @@ xfs_dir2_leaf_to_block( * Read the data block if we don't already have it, give up if it fails. */ if (!dbp) { - error = xfs_dir3_data_read(tp, dp, args->geo->datablk, -1, &dbp); + error = xfs_dir3_data_read(tp, dp, args->geo->datablk, 0, &dbp); if (error) return error; } diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index 2ab0c78aac3f..34f87a12b09e 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -400,13 +400,13 @@ xfs_dir3_data_read( struct xfs_trans *tp, struct xfs_inode *dp, xfs_dablk_t bno, - xfs_daddr_t mapped_bno, + unsigned int flags, struct xfs_buf **bpp) { int err; - err = xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp, - XFS_DATA_FORK, &xfs_dir3_data_buf_ops); + err = xfs_da_read_buf(tp, dp, bno, flags, bpp, XFS_DATA_FORK, + &xfs_dir3_data_buf_ops); if (!err && tp && *bpp) xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_DATA_BUF); return err; diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index 482a974d6361..8c6faf086ff9 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -266,7 +266,7 @@ xfs_dir3_leaf_read( { int err; - err = xfs_da_read_buf(tp, dp, fbno, -1, bpp, XFS_DATA_FORK, + err = xfs_da_read_buf(tp, dp, fbno, 0, bpp, XFS_DATA_FORK, &xfs_dir3_leaf1_buf_ops); if (!err && tp && *bpp) xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_LEAF1_BUF); @@ -282,7 +282,7 @@ xfs_dir3_leafn_read( { int err; - err = xfs_da_read_buf(tp, dp, fbno, -1, bpp, XFS_DATA_FORK, + err = xfs_da_read_buf(tp, dp, fbno, 0, bpp, XFS_DATA_FORK, &xfs_dir3_leafn_buf_ops); if (!err && tp && *bpp) xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_LEAFN_BUF); @@ -826,7 +826,7 @@ xfs_dir2_leaf_addname( */ error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(args->geo, use_block), - -1, &dbp); + 0, &dbp); if (error) { xfs_trans_brelse(tp, lbp); return error; @@ -1268,7 +1268,7 @@ xfs_dir2_leaf_lookup_int( xfs_trans_brelse(tp, dbp); error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(args->geo, newdb), - -1, &dbp); + 0, &dbp); if (error) { xfs_trans_brelse(tp, lbp); return error; @@ -1310,7 +1310,7 @@ xfs_dir2_leaf_lookup_int( xfs_trans_brelse(tp, dbp); error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(args->geo, cidb), - -1, &dbp); + 0, &dbp); if (error) { xfs_trans_brelse(tp, lbp); return error; @@ -1602,8 +1602,7 @@ xfs_dir2_leaf_trim_data( /* * Read the offending data block. We need its buffer. */ - error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(geo, db), -1, - &dbp); + error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(geo, db), 0, &dbp); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 2e2129fdb6a9..cc871345a141 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -212,14 +212,14 @@ __xfs_dir3_free_read( struct xfs_trans *tp, struct xfs_inode *dp, xfs_dablk_t fbno, - xfs_daddr_t mappedbno, + unsigned int flags, struct xfs_buf **bpp) { xfs_failaddr_t fa; int err; - err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, - XFS_DATA_FORK, &xfs_dir3_free_buf_ops); + err = xfs_da_read_buf(tp, dp, fbno, flags, bpp, XFS_DATA_FORK, + &xfs_dir3_free_buf_ops); if (err || !*bpp) return err; @@ -297,7 +297,7 @@ xfs_dir2_free_read( xfs_dablk_t fbno, struct xfs_buf **bpp) { - return __xfs_dir3_free_read(tp, dp, fbno, -1, bpp); + return __xfs_dir3_free_read(tp, dp, fbno, 0, bpp); } static int @@ -307,7 +307,7 @@ xfs_dir2_free_try_read( xfs_dablk_t fbno, struct xfs_buf **bpp) { - return __xfs_dir3_free_read(tp, dp, fbno, -2, bpp); + return __xfs_dir3_free_read(tp, dp, fbno, XFS_DABUF_MAP_HOLE_OK, bpp); } static int @@ -857,7 +857,7 @@ xfs_dir2_leafn_lookup_for_entry( error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(args->geo, newdb), - -1, &curbp); + 0, &curbp); if (error) return error; } @@ -1940,7 +1940,7 @@ xfs_dir2_node_addname_int( /* Read the data block in. */ error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(args->geo, dbno), - -1, &dbp); + 0, &dbp); } if (error) return error; diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index 15353b61051b..c031c53d0f0d 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h @@ -77,8 +77,8 @@ extern void xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp); extern xfs_failaddr_t __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); +int xfs_dir3_data_read(struct xfs_trans *tp, struct xfs_inode *dp, + xfs_dablk_t bno, unsigned int flags, struct xfs_buf **bpp); int xfs_dir3_data_readahead(struct xfs_inode *dp, xfs_dablk_t bno, unsigned int flags); diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c index 85b9207359ec..97a15b6f2865 100644 --- a/fs/xfs/scrub/dabtree.c +++ b/fs/xfs/scrub/dabtree.c @@ -331,8 +331,8 @@ xchk_da_btree_block( goto out_nobuf; /* Read the buffer. */ - error = xfs_da_read_buf(dargs->trans, dargs->dp, blk->blkno, -2, - &blk->bp, dargs->whichfork, + error = xfs_da_read_buf(dargs->trans, dargs->dp, blk->blkno, + XFS_DABUF_MAP_HOLE_OK, &blk->bp, dargs->whichfork, &xchk_da_btree_buf_ops); if (!xchk_da_process_error(ds, level, &error)) goto out_nobuf; diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index 910e0bf85bd7..266da4e4bde6 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -229,7 +229,8 @@ xchk_dir_rec( xchk_da_set_corrupt(ds, level); goto out; } - error = xfs_dir3_data_read(ds->dargs.trans, dp, rec_bno, -2, &bp); + error = xfs_dir3_data_read(ds->dargs.trans, dp, rec_bno, + XFS_DABUF_MAP_HOLE_OK, &bp); if (!xchk_fblock_process_error(ds->sc, XFS_DATA_FORK, rec_bno, &error)) goto out; @@ -346,7 +347,7 @@ xchk_directory_data_bestfree( error = xfs_dir3_block_read(sc->tp, sc->ip, &bp); } else { /* dir data format */ - error = xfs_dir3_data_read(sc->tp, sc->ip, lblk, -1, &bp); + error = xfs_dir3_data_read(sc->tp, sc->ip, lblk, 0, &bp); } if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) goto out; @@ -557,7 +558,7 @@ xchk_directory_leaf1_bestfree( if (best == NULLDATAOFF) continue; error = xfs_dir3_data_read(sc->tp, sc->ip, - i * args->geo->fsbcount, -1, &dbp); + i * args->geo->fsbcount, 0, &dbp); if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) break; @@ -608,7 +609,7 @@ xchk_directory_free_bestfree( } error = xfs_dir3_data_read(sc->tp, sc->ip, (freehdr.firstdb + i) * args->geo->fsbcount, - -1, &dbp); + 0, &dbp); if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) break; diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index 5df3d1e2b17f..0d3b640cf1cc 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -279,7 +279,7 @@ xfs_dir2_leaf_readbuf( new_off = xfs_dir2_da_to_byte(geo, map.br_startoff); if (new_off > *cur_off) *cur_off = new_off; - error = xfs_dir3_data_read(args->trans, dp, map.br_startoff, -1, &bp); + error = xfs_dir3_data_read(args->trans, dp, map.br_startoff, 0, &bp); if (error) goto out; -- cgit v1.2.3-70-g09d2 From 2911edb653b9c64e0aad461f308cae8ce030eb7b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 20 Nov 2019 09:46:05 -0800 Subject: xfs: remove the mappedbno argument to xfs_da_get_buf Use the xfs_da_get_buf_daddr function directly for the two callers that pass a mapped disk address, and then remove the mappedbno argument. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr_leaf.c | 4 ++-- fs/xfs/libxfs/xfs_da_btree.c | 18 +++--------------- fs/xfs/libxfs/xfs_da_btree.h | 3 +-- fs/xfs/libxfs/xfs_dir2_data.c | 2 +- fs/xfs/libxfs/xfs_dir2_leaf.c | 2 +- fs/xfs/libxfs/xfs_dir2_node.c | 2 +- fs/xfs/xfs_attr_inactive.c | 24 +++++++++++++++++++----- 7 files changed, 28 insertions(+), 27 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_node.c') diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index b0742c856de2..08d4b10ae2d5 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -1162,7 +1162,7 @@ xfs_attr3_leaf_to_node( if (error) goto out; - error = xfs_da_get_buf(args->trans, dp, blkno, -1, &bp2, XFS_ATTR_FORK); + error = xfs_da_get_buf(args->trans, dp, blkno, &bp2, XFS_ATTR_FORK); if (error) goto out; @@ -1223,7 +1223,7 @@ xfs_attr3_leaf_create( trace_xfs_attr_leaf_create(args); - error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp, + error = xfs_da_get_buf(args->trans, args->dp, blkno, &bp, XFS_ATTR_FORK); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index c00983034c78..8c3eafe280ed 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -429,7 +429,7 @@ xfs_da3_node_create( trace_xfs_da_node_create(args); ASSERT(level <= XFS_DA_NODE_MAXDEPTH); - error = xfs_da_get_buf(tp, dp, blkno, -1, &bp, whichfork); + error = xfs_da_get_buf(tp, dp, blkno, &bp, whichfork); if (error) return error; bp->b_ops = &xfs_da3_node_buf_ops; @@ -656,7 +656,7 @@ xfs_da3_root_split( dp = args->dp; tp = args->trans; - error = xfs_da_get_buf(tp, dp, blkno, -1, &bp, args->whichfork); + error = xfs_da_get_buf(tp, dp, blkno, &bp, args->whichfork); if (error) return error; node = bp->b_addr; @@ -2577,7 +2577,6 @@ xfs_da_get_buf( struct xfs_trans *tp, struct xfs_inode *dp, xfs_dablk_t bno, - xfs_daddr_t mappedbno, struct xfs_buf **bpp, int whichfork) { @@ -2588,22 +2587,11 @@ xfs_da_get_buf( int error; *bpp = NULL; - - if (mappedbno >= 0) { - bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, mappedbno, - XFS_FSB_TO_BB(mp, - xfs_dabuf_nfsb(mp, whichfork)), 0); - goto done; - } - - error = xfs_dabuf_map(dp, bno, - mappedbno == -1 ? XFS_DABUF_MAP_HOLE_OK : 0, - whichfork, &mapp, &nmap); + error = xfs_dabuf_map(dp, bno, 0, whichfork, &mapp, &nmap); if (error || nmap == 0) goto out_free; bp = xfs_trans_get_buf_map(tp, mp->m_ddev_targp, mapp, nmap, 0); -done: error = bp ? bp->b_error : -EIO; if (error) { if (bp) diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index f83d18a5d5f1..e16610d1c14f 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -203,8 +203,7 @@ int xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno); int xfs_da_grow_inode_int(struct xfs_da_args *args, xfs_fileoff_t *bno, int count); int xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp, - xfs_dablk_t bno, xfs_daddr_t mappedbno, - struct xfs_buf **bp, int whichfork); + xfs_dablk_t bno, struct xfs_buf **bp, int whichfork); int xfs_da_read_buf(struct xfs_trans *trans, struct xfs_inode *dp, xfs_dablk_t bno, unsigned int flags, struct xfs_buf **bpp, int whichfork, const struct xfs_buf_ops *ops); diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index 34f87a12b09e..b9eba8213180 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -679,7 +679,7 @@ xfs_dir3_data_init( * Get the buffer set up for the block. */ error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, blkno), - -1, &bp, XFS_DATA_FORK); + &bp, XFS_DATA_FORK); if (error) return error; bp->b_ops = &xfs_dir3_data_buf_ops; diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index 8c6faf086ff9..a131b520aac7 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -355,7 +355,7 @@ xfs_dir3_leaf_get_buf( bno < xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET)); error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, bno), - -1, &bp, XFS_DATA_FORK); + &bp, XFS_DATA_FORK); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index cc871345a141..a0cc5e240306 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -324,7 +324,7 @@ xfs_dir3_free_get_buf( struct xfs_dir3_icfree_hdr hdr; error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, fbno), - -1, &bp, XFS_DATA_FORK); + &bp, XFS_DATA_FORK); if (error) return error; diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c index f1cafd82ec75..5ff49523d8ea 100644 --- a/fs/xfs/xfs_attr_inactive.c +++ b/fs/xfs/xfs_attr_inactive.c @@ -196,6 +196,7 @@ xfs_attr3_node_inactive( struct xfs_buf *bp, int level) { + struct xfs_mount *mp = dp->i_mount; struct xfs_da_blkinfo *info; xfs_dablk_t child_fsb; xfs_daddr_t parent_blkno, child_blkno; @@ -267,10 +268,16 @@ xfs_attr3_node_inactive( /* * Remove the subsidiary block from the cache and from the log. */ - error = xfs_da_get_buf(*trans, dp, 0, child_blkno, &child_bp, - XFS_ATTR_FORK); - if (error) + child_bp = xfs_trans_get_buf(*trans, mp->m_ddev_targp, + child_blkno, + XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0); + if (!child_bp) + return -EIO; + error = bp->b_error; + if (error) { + xfs_trans_brelse(*trans, child_bp); return error; + } xfs_trans_binval(*trans, child_bp); /* @@ -311,6 +318,7 @@ xfs_attr3_root_inactive( struct xfs_trans **trans, struct xfs_inode *dp) { + struct xfs_mount *mp = dp->i_mount; struct xfs_da_blkinfo *info; struct xfs_buf *bp; xfs_daddr_t blkno; @@ -353,9 +361,15 @@ xfs_attr3_root_inactive( /* * Invalidate the incore copy of the root block. */ - error = xfs_da_get_buf(*trans, dp, 0, blkno, &bp, XFS_ATTR_FORK); - if (error) + bp = xfs_trans_get_buf(*trans, mp->m_ddev_targp, blkno, + XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0); + if (!bp) + return -EIO; + error = bp->b_error; + if (error) { + xfs_trans_brelse(*trans, bp); return error; + } xfs_trans_binval(*trans, bp); /* remove from cache */ /* * Commit the invalidate and start the next transaction. -- cgit v1.2.3-70-g09d2