From e91ec882af21c0e845bf962b35f3c13482f74b2f Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Sat, 2 Nov 2019 09:38:08 -0700 Subject: xfs: relax shortform directory size checks Each of the four functions that operate on shortform directories checks that the directory's di_size is at least as large as the shortform directory header. This is now checked by the inode fork verifiers (di_size is used to allocate if_bytes, and if_bytes is checked against the header structure size) so we can turn these checks into ASSERTions. Signed-off-by: Darrick J. Wong Reviewed-by: Carlos Maiolino Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_dir2_block.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_block.c') diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 49e4bc39e7bb..e1afa35141c5 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -1073,13 +1073,7 @@ xfs_dir2_sf_to_block( mp = dp->i_mount; ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK); ASSERT(ifp->if_flags & XFS_IFINLINE); - /* - * Bomb out if the shortform directory is way too short. - */ - if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { - ASSERT(XFS_FORCED_SHUTDOWN(mp)); - return -EIO; - } + ASSERT(dp->i_d.di_size >= offsetof(struct xfs_dir2_sf_hdr, parent)); oldsfp = (xfs_dir2_sf_hdr_t *)ifp->if_u1.if_data; -- cgit v1.2.3 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_block.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 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_block.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 From 84915e1bdddf9de3edf79a2813982b886e76658f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 15:02:31 -0800 Subject: xfs: devirtualize ->sf_get_parent_ino and ->sf_put_parent_ino The parent inode handling is the same for all directory format variants, just use direct calls instead of going through a pointless indirect call. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_format.c | 10 ++-------- fs/xfs/libxfs/xfs_dir2.h | 3 --- fs/xfs/libxfs/xfs_dir2_block.c | 2 +- fs/xfs/libxfs/xfs_dir2_priv.h | 2 ++ fs/xfs/libxfs/xfs_dir2_sf.c | 20 ++++++++++---------- fs/xfs/xfs_dir2_readdir.c | 2 +- 6 files changed, 16 insertions(+), 23 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_block.c') diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index 2b708b9fae1a..7858469c09e4 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -132,14 +132,14 @@ xfs_dir2_sf_put_ino( put_unaligned_be32(ino, to); } -static xfs_ino_t +xfs_ino_t xfs_dir2_sf_get_parent_ino( struct xfs_dir2_sf_hdr *hdr) { return xfs_dir2_sf_get_ino(hdr, hdr->parent); } -static void +void xfs_dir2_sf_put_parent_ino( struct xfs_dir2_sf_hdr *hdr, xfs_ino_t ino) @@ -407,8 +407,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { .sf_put_ftype = xfs_dir2_sfe_put_ftype, .sf_get_ino = xfs_dir2_sfe_get_ino, .sf_put_ino = xfs_dir2_sfe_put_ino, - .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino, - .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino, .data_entsize = xfs_dir2_data_entsize, .data_get_ftype = xfs_dir2_data_get_ftype, @@ -438,8 +436,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .sf_put_ftype = xfs_dir3_sfe_put_ftype, .sf_get_ino = xfs_dir3_sfe_get_ino, .sf_put_ino = xfs_dir3_sfe_put_ino, - .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino, - .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino, .data_entsize = xfs_dir3_data_entsize, .data_get_ftype = xfs_dir3_data_get_ftype, @@ -469,8 +465,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = { .sf_put_ftype = xfs_dir3_sfe_put_ftype, .sf_get_ino = xfs_dir3_sfe_get_ino, .sf_put_ino = xfs_dir3_sfe_put_ino, - .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino, - .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino, .data_entsize = xfs_dir3_data_entsize, .data_get_ftype = xfs_dir3_data_get_ftype, diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index e302679d8c80..d3a0b8daab5f 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -44,9 +44,6 @@ struct xfs_dir_ops { void (*sf_put_ino)(struct xfs_dir2_sf_hdr *hdr, struct xfs_dir2_sf_entry *sfep, xfs_ino_t ino); - xfs_ino_t (*sf_get_parent_ino)(struct xfs_dir2_sf_hdr *hdr); - void (*sf_put_parent_ino)(struct xfs_dir2_sf_hdr *hdr, - xfs_ino_t ino); int (*data_entsize)(int len); uint8_t (*data_get_ftype)(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 065fe10a842b..bc47113b78e5 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -1157,7 +1157,7 @@ xfs_dir2_sf_to_block( * Create entry for .. */ dep = dp->d_ops->data_dotdot_entry_p(hdr); - dep->inumber = cpu_to_be64(dp->d_ops->sf_get_parent_ino(sfp)); + 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); diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index 9128f7aae0be..bb50853d0988 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h @@ -145,6 +145,8 @@ extern int xfs_dir2_free_read(struct xfs_trans *tp, struct xfs_inode *dp, xfs_dablk_t fbno, struct xfs_buf **bpp); /* xfs_dir2_sf.c */ +xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *hdr); +void xfs_dir2_sf_put_parent_ino(struct xfs_dir2_sf_hdr *hdr, xfs_ino_t ino); extern int xfs_dir2_block_sfsize(struct xfs_inode *dp, struct xfs_dir2_data_hdr *block, struct xfs_dir2_sf_hdr *sfhp); extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_buf *bp, diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c index d6b164a2fe57..c7ca25acdb18 100644 --- a/fs/xfs/libxfs/xfs_dir2_sf.c +++ b/fs/xfs/libxfs/xfs_dir2_sf.c @@ -125,7 +125,7 @@ xfs_dir2_block_sfsize( */ sfhp->count = count; sfhp->i8count = i8count; - dp->d_ops->sf_put_parent_ino(sfhp, parent); + xfs_dir2_sf_put_parent_ino(sfhp, parent); return size; } @@ -204,7 +204,7 @@ xfs_dir2_block_to_sf( else if (dep->namelen == 2 && dep->name[0] == '.' && dep->name[1] == '.') ASSERT(be64_to_cpu(dep->inumber) == - dp->d_ops->sf_get_parent_ino(sfp)); + xfs_dir2_sf_get_parent_ino(sfp)); /* * Normal entry, copy it into shortform. */ @@ -584,7 +584,7 @@ xfs_dir2_sf_check( sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; offset = dp->d_ops->data_first_offset; - ino = dp->d_ops->sf_get_parent_ino(sfp); + ino = xfs_dir2_sf_get_parent_ino(sfp); i8count = ino > XFS_DIR2_MAX_SHORT_INUM; for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); @@ -647,7 +647,7 @@ xfs_dir2_sf_verify( endp = (char *)sfp + size; /* Check .. entry */ - ino = dops->sf_get_parent_ino(sfp); + ino = xfs_dir2_sf_get_parent_ino(sfp); i8count = ino > XFS_DIR2_MAX_SHORT_INUM; error = xfs_dir_ino_validate(mp, ino); if (error) @@ -757,7 +757,7 @@ xfs_dir2_sf_create( /* * Now can put in the inode number, since i8count is set. */ - dp->d_ops->sf_put_parent_ino(sfp, pino); + xfs_dir2_sf_put_parent_ino(sfp, pino); sfp->count = 0; dp->i_d.di_size = size; xfs_dir2_sf_check(args); @@ -806,7 +806,7 @@ xfs_dir2_sf_lookup( */ if (args->namelen == 2 && args->name[0] == '.' && args->name[1] == '.') { - args->inumber = dp->d_ops->sf_get_parent_ino(sfp); + args->inumber = xfs_dir2_sf_get_parent_ino(sfp); args->cmpresult = XFS_CMP_EXACT; args->filetype = XFS_DIR3_FT_DIR; return -EEXIST; @@ -984,9 +984,9 @@ xfs_dir2_sf_replace( */ if (args->namelen == 2 && args->name[0] == '.' && args->name[1] == '.') { - ino = dp->d_ops->sf_get_parent_ino(sfp); + ino = xfs_dir2_sf_get_parent_ino(sfp); ASSERT(args->inumber != ino); - dp->d_ops->sf_put_parent_ino(sfp, args->inumber); + xfs_dir2_sf_put_parent_ino(sfp, args->inumber); } /* * Normal entry, look for the name. @@ -1092,7 +1092,7 @@ xfs_dir2_sf_toino4( */ sfp->count = oldsfp->count; sfp->i8count = 0; - dp->d_ops->sf_put_parent_ino(sfp, dp->d_ops->sf_get_parent_ino(oldsfp)); + xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp)); /* * Copy the entries field by field. */ @@ -1165,7 +1165,7 @@ xfs_dir2_sf_toino8( */ sfp->count = oldsfp->count; sfp->i8count = 1; - dp->d_ops->sf_put_parent_ino(sfp, dp->d_ops->sf_get_parent_ino(oldsfp)); + xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp)); /* * Copy the entries field by field. */ diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index a0bec0931f3b..6f94d2a45174 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -92,7 +92,7 @@ xfs_dir2_sf_getdents( * Put .. entry unless we're starting past it. */ if (ctx->pos <= dotdot_offset) { - ino = dp->d_ops->sf_get_parent_ino(sfp); + ino = xfs_dir2_sf_get_parent_ino(sfp); ctx->pos = dotdot_offset & 0x7fffffff; if (!dir_emit(ctx, "..", 2, ino, DT_DIR)) return 0; -- cgit v1.2.3 From 50f6bb6b7aea8177110e55355c455f18912a7a73 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 15:02:38 -0800 Subject: xfs: devirtualize ->sf_entsize and ->sf_nextentry Just check for file-type enabled directories directly. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_format.c | 48 --------------------- fs/xfs/libxfs/xfs_dir2.h | 4 -- fs/xfs/libxfs/xfs_dir2_block.c | 2 +- fs/xfs/libxfs/xfs_dir2_priv.h | 2 + fs/xfs/libxfs/xfs_dir2_sf.c | 96 +++++++++++++++++++++++++----------------- fs/xfs/xfs_dir2_readdir.c | 7 +-- 6 files changed, 64 insertions(+), 95 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_block.c') diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index 7858469c09e4..f80495a38a76 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -15,48 +15,6 @@ #include "xfs_dir2.h" #include "xfs_dir2_priv.h" -/* - * Shortform directory ops - */ -static int -xfs_dir2_sf_entsize( - struct xfs_dir2_sf_hdr *hdr, - int len) -{ - int count = sizeof(struct xfs_dir2_sf_entry); /* namelen + offset */ - - count += len; /* name */ - count += hdr->i8count ? XFS_INO64_SIZE : XFS_INO32_SIZE; /* ino # */ - return count; -} - -static int -xfs_dir3_sf_entsize( - struct xfs_dir2_sf_hdr *hdr, - int len) -{ - return xfs_dir2_sf_entsize(hdr, len) + sizeof(uint8_t); -} - -static struct xfs_dir2_sf_entry * -xfs_dir2_sf_nextentry( - struct xfs_dir2_sf_hdr *hdr, - struct xfs_dir2_sf_entry *sfep) -{ - return (struct xfs_dir2_sf_entry *) - ((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen)); -} - -static struct xfs_dir2_sf_entry * -xfs_dir3_sf_nextentry( - struct xfs_dir2_sf_hdr *hdr, - struct xfs_dir2_sf_entry *sfep) -{ - return (struct xfs_dir2_sf_entry *) - ((char *)sfep + xfs_dir3_sf_entsize(hdr, sfep->namelen)); -} - - /* * For filetype enabled shortform directories, the file type field is stored at * the end of the name. Because it's only a single byte, endian conversion is @@ -401,8 +359,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr) } static const struct xfs_dir_ops xfs_dir2_ops = { - .sf_entsize = xfs_dir2_sf_entsize, - .sf_nextentry = xfs_dir2_sf_nextentry, .sf_get_ftype = xfs_dir2_sfe_get_ftype, .sf_put_ftype = xfs_dir2_sfe_put_ftype, .sf_get_ino = xfs_dir2_sfe_get_ino, @@ -430,8 +386,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { }; static const struct xfs_dir_ops xfs_dir2_ftype_ops = { - .sf_entsize = xfs_dir3_sf_entsize, - .sf_nextentry = xfs_dir3_sf_nextentry, .sf_get_ftype = xfs_dir3_sfe_get_ftype, .sf_put_ftype = xfs_dir3_sfe_put_ftype, .sf_get_ino = xfs_dir3_sfe_get_ino, @@ -459,8 +413,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { }; static const struct xfs_dir_ops xfs_dir3_ops = { - .sf_entsize = xfs_dir3_sf_entsize, - .sf_nextentry = xfs_dir3_sf_nextentry, .sf_get_ftype = xfs_dir3_sfe_get_ftype, .sf_put_ftype = xfs_dir3_sfe_put_ftype, .sf_get_ino = xfs_dir3_sfe_get_ino, diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index d3a0b8daab5f..c99f0ad6607a 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -32,10 +32,6 @@ extern unsigned char xfs_mode_to_ftype(int mode); * directory operations vector for encode/decode routines */ struct xfs_dir_ops { - int (*sf_entsize)(struct xfs_dir2_sf_hdr *hdr, int len); - struct xfs_dir2_sf_entry * - (*sf_nextentry)(struct xfs_dir2_sf_hdr *hdr, - struct xfs_dir2_sf_entry *sfep); uint8_t (*sf_get_ftype)(struct xfs_dir2_sf_entry *sfep); void (*sf_put_ftype)(struct xfs_dir2_sf_entry *sfep, uint8_t ftype); diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index bc47113b78e5..a6decb4c079a 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -1225,7 +1225,7 @@ xfs_dir2_sf_to_block( if (++i == sfp->count) sfep = NULL; else - sfep = dp->d_ops->sf_nextentry(sfp, sfep); + sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); } /* Done with the temporary buffer */ kmem_free(sfp); diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index bb50853d0988..357b388a5be0 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h @@ -147,6 +147,8 @@ extern int xfs_dir2_free_read(struct xfs_trans *tp, struct xfs_inode *dp, /* xfs_dir2_sf.c */ xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *hdr); void xfs_dir2_sf_put_parent_ino(struct xfs_dir2_sf_hdr *hdr, xfs_ino_t ino); +struct xfs_dir2_sf_entry *xfs_dir2_sf_nextentry(struct xfs_mount *mp, + struct xfs_dir2_sf_hdr *hdr, struct xfs_dir2_sf_entry *sfep); extern int xfs_dir2_block_sfsize(struct xfs_inode *dp, struct xfs_dir2_data_hdr *block, struct xfs_dir2_sf_hdr *sfhp); extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_buf *bp, diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c index c7ca25acdb18..36d79ec57d55 100644 --- a/fs/xfs/libxfs/xfs_dir2_sf.c +++ b/fs/xfs/libxfs/xfs_dir2_sf.c @@ -37,6 +37,31 @@ static void xfs_dir2_sf_check(xfs_da_args_t *args); static void xfs_dir2_sf_toino4(xfs_da_args_t *args); static void xfs_dir2_sf_toino8(xfs_da_args_t *args); +static int +xfs_dir2_sf_entsize( + struct xfs_mount *mp, + struct xfs_dir2_sf_hdr *hdr, + int len) +{ + int count = len; + + count += sizeof(struct xfs_dir2_sf_entry); /* namelen + offset */ + count += hdr->i8count ? XFS_INO64_SIZE : XFS_INO32_SIZE; /* ino # */ + + if (xfs_sb_version_hasftype(&mp->m_sb)) + count += sizeof(uint8_t); + return count; +} + +struct xfs_dir2_sf_entry * +xfs_dir2_sf_nextentry( + struct xfs_mount *mp, + struct xfs_dir2_sf_hdr *hdr, + struct xfs_dir2_sf_entry *sfep) +{ + return (void *)sfep + xfs_dir2_sf_entsize(mp, hdr, sfep->namelen); +} + /* * Given a block directory (dp/block), calculate its size as a shortform (sf) * directory and a header for the sf directory, if it will fit it the @@ -219,7 +244,7 @@ xfs_dir2_block_to_sf( dp->d_ops->sf_put_ftype(sfep, dp->d_ops->data_get_ftype(dep)); - sfep = dp->d_ops->sf_nextentry(sfp, sfep); + sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); } ptr += dp->d_ops->data_entsize(dep->namelen); } @@ -285,7 +310,7 @@ xfs_dir2_sf_addname( /* * Compute entry (and change in) size. */ - incr_isize = dp->d_ops->sf_entsize(sfp, args->namelen); + incr_isize = xfs_dir2_sf_entsize(dp->i_mount, sfp, args->namelen); objchange = 0; /* @@ -358,18 +383,17 @@ xfs_dir2_sf_addname_easy( xfs_dir2_data_aoff_t offset, /* offset to use for new ent */ int new_isize) /* new directory size */ { + struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; int byteoff; /* byte offset in sf dir */ - xfs_inode_t *dp; /* incore directory inode */ xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ - dp = args->dp; - sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; byteoff = (int)((char *)sfep - (char *)sfp); /* * Grow the in-inode space. */ - xfs_idata_realloc(dp, dp->d_ops->sf_entsize(sfp, args->namelen), + xfs_idata_realloc(dp, xfs_dir2_sf_entsize(mp, sfp, args->namelen), XFS_DATA_FORK); /* * Need to set up again due to realloc of the inode data. @@ -410,9 +434,10 @@ xfs_dir2_sf_addname_hard( int objchange, /* changing inode number size */ int new_isize) /* new directory size */ { + struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; int add_datasize; /* data size need for new ent */ char *buf; /* buffer for old */ - xfs_inode_t *dp; /* incore directory inode */ int eof; /* reached end of old dir */ int nbytes; /* temp for byte copies */ xfs_dir2_data_aoff_t new_offset; /* next offset value */ @@ -426,8 +451,6 @@ xfs_dir2_sf_addname_hard( /* * Copy the old directory to the stack buffer. */ - dp = args->dp; - sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; old_isize = (int)dp->i_d.di_size; buf = kmem_alloc(old_isize, 0); @@ -444,7 +467,7 @@ xfs_dir2_sf_addname_hard( eof = (char *)oldsfep == &buf[old_isize]; !eof; offset = new_offset + dp->d_ops->data_entsize(oldsfep->namelen), - oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep), + oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep), eof = (char *)oldsfep == &buf[old_isize]) { new_offset = xfs_dir2_sf_get_offset(oldsfep); if (offset + add_datasize <= new_offset) @@ -482,7 +505,7 @@ xfs_dir2_sf_addname_hard( * If there's more left to copy, do that. */ if (!eof) { - sfep = dp->d_ops->sf_nextentry(sfp, sfep); + sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); memcpy(sfep, oldsfep, old_isize - nbytes); } kmem_free(buf); @@ -504,7 +527,8 @@ xfs_dir2_sf_addname_pick( xfs_dir2_sf_entry_t **sfepp, /* out(1): new entry ptr */ xfs_dir2_data_aoff_t *offsetp) /* out(1): new offset */ { - xfs_inode_t *dp; /* incore directory inode */ + struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; int holefit; /* found hole it will fit in */ int i; /* entry number */ xfs_dir2_data_aoff_t offset; /* data block offset */ @@ -513,8 +537,6 @@ xfs_dir2_sf_addname_pick( int size; /* entry's data size */ int used; /* data bytes used */ - dp = args->dp; - sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; size = dp->d_ops->data_entsize(args->namelen); offset = dp->d_ops->data_first_offset; @@ -530,7 +552,7 @@ xfs_dir2_sf_addname_pick( holefit = offset + size <= xfs_dir2_sf_get_offset(sfep); offset = xfs_dir2_sf_get_offset(sfep) + dp->d_ops->data_entsize(sfep->namelen); - sfep = dp->d_ops->sf_nextentry(sfp, sfep); + sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); } /* * Calculate data bytes used excluding the new entry, if this @@ -589,7 +611,7 @@ xfs_dir2_sf_check( for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { + i++, sfep = xfs_dir2_sf_nextentry(dp->i_mount, sfp, sfep)) { ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset); ino = dp->d_ops->sf_get_ino(sfp, sfep); i8count += ino > XFS_DIR2_MAX_SHORT_INUM; @@ -674,7 +696,7 @@ xfs_dir2_sf_verify( * within the data buffer. The next entry starts after the * name component, so nextentry is an acceptable test. */ - next_sfep = dops->sf_nextentry(sfp, sfep); + next_sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); if (endp < (char *)next_sfep) return __this_address; @@ -773,7 +795,8 @@ int /* error */ xfs_dir2_sf_lookup( xfs_da_args_t *args) /* operation arguments */ { - xfs_inode_t *dp; /* incore directory inode */ + struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; int i; /* entry index */ int error; xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ @@ -784,7 +807,6 @@ xfs_dir2_sf_lookup( trace_xfs_dir2_sf_lookup(args); xfs_dir2_sf_check(args); - dp = args->dp; ASSERT(dp->i_df.if_flags & XFS_IFINLINE); ASSERT(dp->i_d.di_size >= offsetof(struct xfs_dir2_sf_hdr, parent)); @@ -816,7 +838,7 @@ xfs_dir2_sf_lookup( */ ci_sfep = NULL; for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) { /* * Compare name and if it's an exact match, return the inode * number. If it's the first case-insensitive match, store the @@ -852,8 +874,9 @@ int /* error */ xfs_dir2_sf_removename( xfs_da_args_t *args) { + struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; int byteoff; /* offset of removed entry */ - xfs_inode_t *dp; /* incore directory inode */ int entsize; /* this entry's size */ int i; /* shortform entry index */ int newsize; /* new inode size */ @@ -863,8 +886,6 @@ xfs_dir2_sf_removename( trace_xfs_dir2_sf_removename(args); - dp = args->dp; - ASSERT(dp->i_df.if_flags & XFS_IFINLINE); oldsize = (int)dp->i_d.di_size; ASSERT(oldsize >= offsetof(struct xfs_dir2_sf_hdr, parent)); @@ -877,7 +898,7 @@ xfs_dir2_sf_removename( * Find the one we're deleting. */ for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) { if (xfs_da_compname(args, sfep->name, sfep->namelen) == XFS_CMP_EXACT) { ASSERT(dp->d_ops->sf_get_ino(sfp, sfep) == @@ -894,7 +915,7 @@ xfs_dir2_sf_removename( * Calculate sizes. */ byteoff = (int)((char *)sfep - (char *)sfp); - entsize = dp->d_ops->sf_entsize(sfp, args->namelen); + entsize = xfs_dir2_sf_entsize(mp, sfp, args->namelen); newsize = oldsize - entsize; /* * Copy the part if any after the removed entry, sliding it down. @@ -933,7 +954,8 @@ int /* error */ xfs_dir2_sf_replace( xfs_da_args_t *args) /* operation arguments */ { - xfs_inode_t *dp; /* incore directory inode */ + struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; int i; /* entry index */ xfs_ino_t ino=0; /* entry old inode number */ int i8elevated; /* sf_toino8 set i8count=1 */ @@ -942,8 +964,6 @@ xfs_dir2_sf_replace( trace_xfs_dir2_sf_replace(args); - dp = args->dp; - ASSERT(dp->i_df.if_flags & XFS_IFINLINE); ASSERT(dp->i_d.di_size >= offsetof(struct xfs_dir2_sf_hdr, parent)); ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); @@ -993,7 +1013,7 @@ xfs_dir2_sf_replace( */ else { for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) { if (xfs_da_compname(args, sfep->name, sfep->namelen) == XFS_CMP_EXACT) { ino = dp->d_ops->sf_get_ino(sfp, sfep); @@ -1052,8 +1072,9 @@ static void xfs_dir2_sf_toino4( xfs_da_args_t *args) /* operation arguments */ { + struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; char *buf; /* old dir's buffer */ - xfs_inode_t *dp; /* incore directory inode */ int i; /* entry index */ int newsize; /* new inode size */ xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ @@ -1064,8 +1085,6 @@ xfs_dir2_sf_toino4( trace_xfs_dir2_sf_toino4(args); - dp = args->dp; - /* * Copy the old directory to the buffer. * Then nuke it from the inode, and add the new buffer to the inode. @@ -1099,8 +1118,8 @@ xfs_dir2_sf_toino4( for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), oldsfep = xfs_dir2_sf_firstentry(oldsfp); i < sfp->count; - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep), - oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep)) { + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep), + oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep)) { sfep->namelen = oldsfep->namelen; memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset)); memcpy(sfep->name, oldsfep->name, sfep->namelen); @@ -1125,8 +1144,9 @@ static void xfs_dir2_sf_toino8( xfs_da_args_t *args) /* operation arguments */ { + struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; char *buf; /* old dir's buffer */ - xfs_inode_t *dp; /* incore directory inode */ int i; /* entry index */ int newsize; /* new inode size */ xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ @@ -1137,8 +1157,6 @@ xfs_dir2_sf_toino8( trace_xfs_dir2_sf_toino8(args); - dp = args->dp; - /* * Copy the old directory to the buffer. * Then nuke it from the inode, and add the new buffer to the inode. @@ -1172,8 +1190,8 @@ xfs_dir2_sf_toino8( for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), oldsfep = xfs_dir2_sf_firstentry(oldsfp); i < sfp->count; - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep), - oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep)) { + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep), + oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep)) { sfep->namelen = oldsfep->namelen; memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset)); memcpy(sfep->name, oldsfep->name, sfep->namelen); diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index 6f94d2a45174..7d150e914d00 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -48,6 +48,7 @@ xfs_dir2_sf_getdents( { int i; /* shortform entry number */ struct xfs_inode *dp = args->dp; /* incore directory inode */ + struct xfs_mount *mp = dp->i_mount; xfs_dir2_dataptr_t off; /* current entry's offset */ xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ @@ -109,7 +110,7 @@ xfs_dir2_sf_getdents( xfs_dir2_sf_get_offset(sfep)); if (ctx->pos > off) { - sfep = dp->d_ops->sf_nextentry(sfp, sfep); + sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); continue; } @@ -122,9 +123,9 @@ xfs_dir2_sf_getdents( return -EFSCORRUPTED; } if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino, - xfs_dir3_get_dtype(dp->i_mount, filetype))) + xfs_dir3_get_dtype(mp, filetype))) return 0; - sfep = dp->d_ops->sf_nextentry(sfp, sfep); + sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); } ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) & -- cgit v1.2.3 From 93b1e96a42006813e58e5052718f7b24a9312258 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 15:02:59 -0800 Subject: xfs: devirtualize ->sf_get_ino and ->sf_put_ino Replace the ->sf_get_ino and ->sf_put_ino dir ops methods with directly called xfs_dir2_sf_get_ino and xfs_dir2_sf_put_ino helpers that take care of the difference between the directory format with and without the file type field. Also move xfs_dir2_sf_get_parent_ino and xfs_dir2_sf_put_parent_ino to xfs_dir2_sf.c with the rest of the low-level short form entry handling and use XFS_MAXINUMBER istead of opencoded constants. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_format.c | 94 ------------------------------------------ fs/xfs/libxfs/xfs_dir2.h | 5 --- fs/xfs/libxfs/xfs_dir2_block.c | 2 +- fs/xfs/libxfs/xfs_dir2_priv.h | 2 + fs/xfs/libxfs/xfs_dir2_sf.c | 91 ++++++++++++++++++++++++++++++++++------ fs/xfs/xfs_dir2_readdir.c | 2 +- 6 files changed, 82 insertions(+), 114 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_block.c') diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index f80495a38a76..f427f141d001 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -58,94 +58,6 @@ xfs_dir3_sfe_put_ftype( sfep->name[sfep->namelen] = ftype; } -/* - * Inode numbers in short-form directories can come in two versions, - * either 4 bytes or 8 bytes wide. These helpers deal with the - * two forms transparently by looking at the headers i8count field. - * - * For 64-bit inode number the most significant byte must be zero. - */ -static xfs_ino_t -xfs_dir2_sf_get_ino( - struct xfs_dir2_sf_hdr *hdr, - uint8_t *from) -{ - if (hdr->i8count) - return get_unaligned_be64(from) & 0x00ffffffffffffffULL; - else - return get_unaligned_be32(from); -} - -static void -xfs_dir2_sf_put_ino( - struct xfs_dir2_sf_hdr *hdr, - uint8_t *to, - xfs_ino_t ino) -{ - ASSERT((ino & 0xff00000000000000ULL) == 0); - - if (hdr->i8count) - put_unaligned_be64(ino, to); - else - put_unaligned_be32(ino, to); -} - -xfs_ino_t -xfs_dir2_sf_get_parent_ino( - struct xfs_dir2_sf_hdr *hdr) -{ - return xfs_dir2_sf_get_ino(hdr, hdr->parent); -} - -void -xfs_dir2_sf_put_parent_ino( - struct xfs_dir2_sf_hdr *hdr, - xfs_ino_t ino) -{ - xfs_dir2_sf_put_ino(hdr, hdr->parent, ino); -} - -/* - * In short-form directory entries the inode numbers are stored at variable - * offset behind the entry name. If the entry stores a filetype value, then it - * sits between the name and the inode number. Hence the inode numbers may only - * be accessed through the helpers below. - */ -static xfs_ino_t -xfs_dir2_sfe_get_ino( - struct xfs_dir2_sf_hdr *hdr, - struct xfs_dir2_sf_entry *sfep) -{ - return xfs_dir2_sf_get_ino(hdr, &sfep->name[sfep->namelen]); -} - -static void -xfs_dir2_sfe_put_ino( - struct xfs_dir2_sf_hdr *hdr, - struct xfs_dir2_sf_entry *sfep, - xfs_ino_t ino) -{ - xfs_dir2_sf_put_ino(hdr, &sfep->name[sfep->namelen], ino); -} - -static xfs_ino_t -xfs_dir3_sfe_get_ino( - struct xfs_dir2_sf_hdr *hdr, - struct xfs_dir2_sf_entry *sfep) -{ - return xfs_dir2_sf_get_ino(hdr, &sfep->name[sfep->namelen + 1]); -} - -static void -xfs_dir3_sfe_put_ino( - struct xfs_dir2_sf_hdr *hdr, - struct xfs_dir2_sf_entry *sfep, - xfs_ino_t ino) -{ - xfs_dir2_sf_put_ino(hdr, &sfep->name[sfep->namelen + 1], ino); -} - - /* * Directory data block operations */ @@ -361,8 +273,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr) static const struct xfs_dir_ops xfs_dir2_ops = { .sf_get_ftype = xfs_dir2_sfe_get_ftype, .sf_put_ftype = xfs_dir2_sfe_put_ftype, - .sf_get_ino = xfs_dir2_sfe_get_ino, - .sf_put_ino = xfs_dir2_sfe_put_ino, .data_entsize = xfs_dir2_data_entsize, .data_get_ftype = xfs_dir2_data_get_ftype, @@ -388,8 +298,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .sf_get_ftype = xfs_dir3_sfe_get_ftype, .sf_put_ftype = xfs_dir3_sfe_put_ftype, - .sf_get_ino = xfs_dir3_sfe_get_ino, - .sf_put_ino = xfs_dir3_sfe_put_ino, .data_entsize = xfs_dir3_data_entsize, .data_get_ftype = xfs_dir3_data_get_ftype, @@ -415,8 +323,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { static const struct xfs_dir_ops xfs_dir3_ops = { .sf_get_ftype = xfs_dir3_sfe_get_ftype, .sf_put_ftype = xfs_dir3_sfe_put_ftype, - .sf_get_ino = xfs_dir3_sfe_get_ino, - .sf_put_ino = xfs_dir3_sfe_put_ino, .data_entsize = xfs_dir3_data_entsize, .data_get_ftype = xfs_dir3_data_get_ftype, diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index c99f0ad6607a..049d844d6a18 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -35,11 +35,6 @@ struct xfs_dir_ops { uint8_t (*sf_get_ftype)(struct xfs_dir2_sf_entry *sfep); void (*sf_put_ftype)(struct xfs_dir2_sf_entry *sfep, uint8_t ftype); - xfs_ino_t (*sf_get_ino)(struct xfs_dir2_sf_hdr *hdr, - struct xfs_dir2_sf_entry *sfep); - void (*sf_put_ino)(struct xfs_dir2_sf_hdr *hdr, - struct xfs_dir2_sf_entry *sfep, - xfs_ino_t ino); int (*data_entsize)(int len); uint8_t (*data_get_ftype)(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 a6decb4c079a..02b0344508e0 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -1208,7 +1208,7 @@ xfs_dir2_sf_to_block( * Copy a real entry. */ dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset); - dep->inumber = cpu_to_be64(dp->d_ops->sf_get_ino(sfp, sfep)); + dep->inumber = cpu_to_be64(xfs_dir2_sf_get_ino(mp, sfp, sfep)); dep->namelen = sfep->namelen; dp->d_ops->data_put_ftype(dep, dp->d_ops->sf_get_ftype(sfep)); memcpy(dep->name, sfep->name, dep->namelen); diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index 357b388a5be0..a194a7b57277 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h @@ -145,6 +145,8 @@ extern int xfs_dir2_free_read(struct xfs_trans *tp, struct xfs_inode *dp, xfs_dablk_t fbno, struct xfs_buf **bpp); /* xfs_dir2_sf.c */ +xfs_ino_t xfs_dir2_sf_get_ino(struct xfs_mount *mp, struct xfs_dir2_sf_hdr *hdr, + struct xfs_dir2_sf_entry *sfep); xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *hdr); void xfs_dir2_sf_put_parent_ino(struct xfs_dir2_sf_hdr *hdr, xfs_ino_t ino); struct xfs_dir2_sf_entry *xfs_dir2_sf_nextentry(struct xfs_mount *mp, diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c index 36d79ec57d55..f63fb044bd15 100644 --- a/fs/xfs/libxfs/xfs_dir2_sf.c +++ b/fs/xfs/libxfs/xfs_dir2_sf.c @@ -62,6 +62,70 @@ xfs_dir2_sf_nextentry( return (void *)sfep + xfs_dir2_sf_entsize(mp, hdr, sfep->namelen); } +/* + * In short-form directory entries the inode numbers are stored at variable + * offset behind the entry name. If the entry stores a filetype value, then it + * sits between the name and the inode number. The actual inode numbers can + * come in two formats as well, either 4 bytes or 8 bytes wide. + */ +xfs_ino_t +xfs_dir2_sf_get_ino( + struct xfs_mount *mp, + struct xfs_dir2_sf_hdr *hdr, + struct xfs_dir2_sf_entry *sfep) +{ + uint8_t *from = sfep->name + sfep->namelen; + + if (xfs_sb_version_hasftype(&mp->m_sb)) + from++; + + if (!hdr->i8count) + return get_unaligned_be32(from); + return get_unaligned_be64(from) & XFS_MAXINUMBER; +} + +static void +xfs_dir2_sf_put_ino( + struct xfs_mount *mp, + struct xfs_dir2_sf_hdr *hdr, + struct xfs_dir2_sf_entry *sfep, + xfs_ino_t ino) +{ + uint8_t *to = sfep->name + sfep->namelen; + + ASSERT(ino <= XFS_MAXINUMBER); + + if (xfs_sb_version_hasftype(&mp->m_sb)) + to++; + + if (hdr->i8count) + put_unaligned_be64(ino, to); + else + put_unaligned_be32(ino, to); +} + +xfs_ino_t +xfs_dir2_sf_get_parent_ino( + struct xfs_dir2_sf_hdr *hdr) +{ + if (!hdr->i8count) + return get_unaligned_be32(hdr->parent); + return get_unaligned_be64(hdr->parent) & XFS_MAXINUMBER; +} + +void +xfs_dir2_sf_put_parent_ino( + struct xfs_dir2_sf_hdr *hdr, + xfs_ino_t ino) +{ + ASSERT(ino <= XFS_MAXINUMBER); + + if (hdr->i8count) + put_unaligned_be64(ino, hdr->parent); + else + put_unaligned_be32(ino, hdr->parent); +} + /* * Given a block directory (dp/block), calculate its size as a shortform (sf) * directory and a header for the sf directory, if it will fit it the @@ -239,7 +303,7 @@ xfs_dir2_block_to_sf( (xfs_dir2_data_aoff_t) ((char *)dep - (char *)hdr)); memcpy(sfep->name, dep->name, dep->namelen); - dp->d_ops->sf_put_ino(sfp, sfep, + xfs_dir2_sf_put_ino(mp, sfp, sfep, be64_to_cpu(dep->inumber)); dp->d_ops->sf_put_ftype(sfep, dp->d_ops->data_get_ftype(dep)); @@ -406,7 +470,7 @@ xfs_dir2_sf_addname_easy( sfep->namelen = args->namelen; xfs_dir2_sf_put_offset(sfep, offset); memcpy(sfep->name, args->name, sfep->namelen); - dp->d_ops->sf_put_ino(sfp, sfep, args->inumber); + xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber); dp->d_ops->sf_put_ftype(sfep, args->filetype); /* @@ -496,7 +560,7 @@ xfs_dir2_sf_addname_hard( sfep->namelen = args->namelen; xfs_dir2_sf_put_offset(sfep, offset); memcpy(sfep->name, args->name, sfep->namelen); - dp->d_ops->sf_put_ino(sfp, sfep, args->inumber); + xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber); dp->d_ops->sf_put_ftype(sfep, args->filetype); sfp->count++; if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange) @@ -613,7 +677,7 @@ xfs_dir2_sf_check( i < sfp->count; i++, sfep = xfs_dir2_sf_nextentry(dp->i_mount, sfp, sfep)) { ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset); - ino = dp->d_ops->sf_get_ino(sfp, sfep); + ino = xfs_dir2_sf_get_ino(dp->i_mount, sfp, sfep); i8count += ino > XFS_DIR2_MAX_SHORT_INUM; offset = xfs_dir2_sf_get_offset(sfep) + @@ -705,7 +769,7 @@ xfs_dir2_sf_verify( return __this_address; /* Check the inode number. */ - ino = dops->sf_get_ino(sfp, sfep); + ino = xfs_dir2_sf_get_ino(mp, sfp, sfep); i8count += ino > XFS_DIR2_MAX_SHORT_INUM; error = xfs_dir_ino_validate(mp, ino); if (error) @@ -848,7 +912,7 @@ xfs_dir2_sf_lookup( sfep->namelen); if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { args->cmpresult = cmp; - args->inumber = dp->d_ops->sf_get_ino(sfp, sfep); + args->inumber = xfs_dir2_sf_get_ino(mp, sfp, sfep); args->filetype = dp->d_ops->sf_get_ftype(sfep); if (cmp == XFS_CMP_EXACT) return -EEXIST; @@ -901,7 +965,7 @@ xfs_dir2_sf_removename( i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) { if (xfs_da_compname(args, sfep->name, sfep->namelen) == XFS_CMP_EXACT) { - ASSERT(dp->d_ops->sf_get_ino(sfp, sfep) == + ASSERT(xfs_dir2_sf_get_ino(mp, sfp, sfep) == args->inumber); break; } @@ -1016,9 +1080,10 @@ xfs_dir2_sf_replace( i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) { if (xfs_da_compname(args, sfep->name, sfep->namelen) == XFS_CMP_EXACT) { - ino = dp->d_ops->sf_get_ino(sfp, sfep); + ino = xfs_dir2_sf_get_ino(mp, sfp, sfep); ASSERT(args->inumber != ino); - dp->d_ops->sf_put_ino(sfp, sfep, args->inumber); + xfs_dir2_sf_put_ino(mp, sfp, sfep, + args->inumber); dp->d_ops->sf_put_ftype(sfep, args->filetype); break; } @@ -1123,8 +1188,8 @@ xfs_dir2_sf_toino4( sfep->namelen = oldsfep->namelen; memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset)); memcpy(sfep->name, oldsfep->name, sfep->namelen); - dp->d_ops->sf_put_ino(sfp, sfep, - dp->d_ops->sf_get_ino(oldsfp, oldsfep)); + xfs_dir2_sf_put_ino(mp, sfp, sfep, + xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep)); dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep)); } /* @@ -1195,8 +1260,8 @@ xfs_dir2_sf_toino8( sfep->namelen = oldsfep->namelen; memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset)); memcpy(sfep->name, oldsfep->name, sfep->namelen); - dp->d_ops->sf_put_ino(sfp, sfep, - dp->d_ops->sf_get_ino(oldsfp, oldsfep)); + xfs_dir2_sf_put_ino(mp, sfp, sfep, + xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep)); dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep)); } /* diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index 7d150e914d00..9d318f091a73 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -114,7 +114,7 @@ xfs_dir2_sf_getdents( continue; } - ino = dp->d_ops->sf_get_ino(sfp, sfep); + ino = xfs_dir2_sf_get_ino(mp, sfp, sfep); filetype = dp->d_ops->sf_get_ftype(sfep); ctx->pos = off & 0x7fffffff; if (!xfs_dir2_namecheck(sfep->name, sfep->namelen)) { -- cgit v1.2.3 From 4501ed2a3a863ae5d43629b98f6a4d7f6147c4df Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 15:03:30 -0800 Subject: xfs: devirtualize ->sf_get_ftype and ->sf_put_ftype Replace the ->sf_get_ftype and ->sf_put_ftype dir ops methods with directly called xfs_dir2_sf_get_ftype and xfs_dir2_sf_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 | 52 ------------------------------------ fs/xfs/libxfs/xfs_dir2.h | 4 --- fs/xfs/libxfs/xfs_dir2_block.c | 2 +- fs/xfs/libxfs/xfs_dir2_priv.h | 2 ++ fs/xfs/libxfs/xfs_dir2_sf.c | 60 ++++++++++++++++++++++++++++++++---------- fs/xfs/xfs_dir2_readdir.c | 2 +- 6 files changed, 50 insertions(+), 72 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_block.c') diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index f427f141d001..1c72b46344d6 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -15,49 +15,6 @@ #include "xfs_dir2.h" #include "xfs_dir2_priv.h" -/* - * For filetype enabled shortform directories, the file type field is stored at - * the end of the name. Because it's only a single byte, endian conversion is - * not necessary. For non-filetype enable directories, the type is always - * unknown and we never store the value. - */ -static uint8_t -xfs_dir2_sfe_get_ftype( - struct xfs_dir2_sf_entry *sfep) -{ - return XFS_DIR3_FT_UNKNOWN; -} - -static void -xfs_dir2_sfe_put_ftype( - struct xfs_dir2_sf_entry *sfep, - uint8_t ftype) -{ - ASSERT(ftype < XFS_DIR3_FT_MAX); -} - -static uint8_t -xfs_dir3_sfe_get_ftype( - struct xfs_dir2_sf_entry *sfep) -{ - uint8_t ftype; - - ftype = sfep->name[sfep->namelen]; - if (ftype >= XFS_DIR3_FT_MAX) - return XFS_DIR3_FT_UNKNOWN; - return ftype; -} - -static void -xfs_dir3_sfe_put_ftype( - struct xfs_dir2_sf_entry *sfep, - uint8_t ftype) -{ - ASSERT(ftype < XFS_DIR3_FT_MAX); - - sfep->name[sfep->namelen] = ftype; -} - /* * Directory data block operations */ @@ -271,9 +228,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr) } static const struct xfs_dir_ops xfs_dir2_ops = { - .sf_get_ftype = xfs_dir2_sfe_get_ftype, - .sf_put_ftype = xfs_dir2_sfe_put_ftype, - .data_entsize = xfs_dir2_data_entsize, .data_get_ftype = xfs_dir2_data_get_ftype, .data_put_ftype = xfs_dir2_data_put_ftype, @@ -296,9 +250,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { }; static const struct xfs_dir_ops xfs_dir2_ftype_ops = { - .sf_get_ftype = xfs_dir3_sfe_get_ftype, - .sf_put_ftype = xfs_dir3_sfe_put_ftype, - .data_entsize = xfs_dir3_data_entsize, .data_get_ftype = xfs_dir3_data_get_ftype, .data_put_ftype = xfs_dir3_data_put_ftype, @@ -321,9 +272,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { }; static const struct xfs_dir_ops xfs_dir3_ops = { - .sf_get_ftype = xfs_dir3_sfe_get_ftype, - .sf_put_ftype = xfs_dir3_sfe_put_ftype, - .data_entsize = xfs_dir3_data_entsize, .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 049d844d6a18..61cc9ae837d5 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -32,10 +32,6 @@ extern unsigned char xfs_mode_to_ftype(int mode); * directory operations vector for encode/decode routines */ struct xfs_dir_ops { - uint8_t (*sf_get_ftype)(struct xfs_dir2_sf_entry *sfep); - void (*sf_put_ftype)(struct xfs_dir2_sf_entry *sfep, - uint8_t ftype); - 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, diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 02b0344508e0..6bc82a02b228 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -1210,7 +1210,7 @@ xfs_dir2_sf_to_block( dep = (xfs_dir2_data_entry_t *)((char *)hdr + 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, dp->d_ops->sf_get_ftype(sfep)); + 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 = cpu_to_be16((char *)dep - (char *)hdr); diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index a194a7b57277..b49f745f1bc3 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h @@ -149,6 +149,8 @@ xfs_ino_t xfs_dir2_sf_get_ino(struct xfs_mount *mp, struct xfs_dir2_sf_hdr *hdr, struct xfs_dir2_sf_entry *sfep); xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *hdr); void xfs_dir2_sf_put_parent_ino(struct xfs_dir2_sf_hdr *hdr, xfs_ino_t ino); +uint8_t xfs_dir2_sf_get_ftype(struct xfs_mount *mp, + struct xfs_dir2_sf_entry *sfep); struct xfs_dir2_sf_entry *xfs_dir2_sf_nextentry(struct xfs_mount *mp, struct xfs_dir2_sf_hdr *hdr, struct xfs_dir2_sf_entry *sfep); extern int xfs_dir2_block_sfsize(struct xfs_inode *dp, diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c index f63fb044bd15..39a537c61b04 100644 --- a/fs/xfs/libxfs/xfs_dir2_sf.c +++ b/fs/xfs/libxfs/xfs_dir2_sf.c @@ -126,6 +126,37 @@ xfs_dir2_sf_put_parent_ino( put_unaligned_be32(ino, hdr->parent); } +/* + * The file type field is stored at the end of the name for filetype enabled + * shortform directories, or not at all otherwise. + */ +uint8_t +xfs_dir2_sf_get_ftype( + struct xfs_mount *mp, + struct xfs_dir2_sf_entry *sfep) +{ + if (xfs_sb_version_hasftype(&mp->m_sb)) { + uint8_t ftype = sfep->name[sfep->namelen]; + + if (ftype < XFS_DIR3_FT_MAX) + return ftype; + } + + return XFS_DIR3_FT_UNKNOWN; +} + +static void +xfs_dir2_sf_put_ftype( + struct xfs_mount *mp, + struct xfs_dir2_sf_entry *sfep, + uint8_t ftype) +{ + ASSERT(ftype < XFS_DIR3_FT_MAX); + + if (xfs_sb_version_hasftype(&mp->m_sb)) + sfep->name[sfep->namelen] = ftype; +} + /* * Given a block directory (dp/block), calculate its size as a shortform (sf) * directory and a header for the sf directory, if it will fit it the @@ -305,7 +336,7 @@ xfs_dir2_block_to_sf( memcpy(sfep->name, dep->name, dep->namelen); xfs_dir2_sf_put_ino(mp, sfp, sfep, be64_to_cpu(dep->inumber)); - dp->d_ops->sf_put_ftype(sfep, + xfs_dir2_sf_put_ftype(mp, sfep, dp->d_ops->data_get_ftype(dep)); sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); @@ -471,7 +502,7 @@ xfs_dir2_sf_addname_easy( xfs_dir2_sf_put_offset(sfep, offset); memcpy(sfep->name, args->name, sfep->namelen); xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber); - dp->d_ops->sf_put_ftype(sfep, args->filetype); + xfs_dir2_sf_put_ftype(mp, sfep, args->filetype); /* * Update the header and inode. @@ -561,7 +592,7 @@ xfs_dir2_sf_addname_hard( xfs_dir2_sf_put_offset(sfep, offset); memcpy(sfep->name, args->name, sfep->namelen); xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber); - dp->d_ops->sf_put_ftype(sfep, args->filetype); + xfs_dir2_sf_put_ftype(mp, sfep, args->filetype); sfp->count++; if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange) sfp->i8count++; @@ -658,7 +689,8 @@ static void xfs_dir2_sf_check( xfs_da_args_t *args) /* operation arguments */ { - xfs_inode_t *dp; /* incore directory inode */ + struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; int i; /* entry number */ int i8count; /* number of big inode#s */ xfs_ino_t ino; /* entry inode number */ @@ -666,8 +698,6 @@ xfs_dir2_sf_check( xfs_dir2_sf_entry_t *sfep; /* shortform dir entry */ xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ - dp = args->dp; - sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; offset = dp->d_ops->data_first_offset; ino = xfs_dir2_sf_get_parent_ino(sfp); @@ -675,14 +705,14 @@ xfs_dir2_sf_check( for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; - i++, sfep = xfs_dir2_sf_nextentry(dp->i_mount, sfp, sfep)) { + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) { ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset); - ino = xfs_dir2_sf_get_ino(dp->i_mount, sfp, sfep); + ino = xfs_dir2_sf_get_ino(mp, sfp, sfep); i8count += ino > XFS_DIR2_MAX_SHORT_INUM; offset = xfs_dir2_sf_get_offset(sfep) + dp->d_ops->data_entsize(sfep->namelen); - ASSERT(dp->d_ops->sf_get_ftype(sfep) < XFS_DIR3_FT_MAX); + ASSERT(xfs_dir2_sf_get_ftype(mp, sfep) < XFS_DIR3_FT_MAX); } ASSERT(i8count == sfp->i8count); ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size); @@ -776,7 +806,7 @@ xfs_dir2_sf_verify( return __this_address; /* Check the file type. */ - filetype = dops->sf_get_ftype(sfep); + filetype = xfs_dir2_sf_get_ftype(mp, sfep); if (filetype >= XFS_DIR3_FT_MAX) return __this_address; @@ -913,7 +943,7 @@ xfs_dir2_sf_lookup( if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { args->cmpresult = cmp; args->inumber = xfs_dir2_sf_get_ino(mp, sfp, sfep); - args->filetype = dp->d_ops->sf_get_ftype(sfep); + args->filetype = xfs_dir2_sf_get_ftype(mp, sfep); if (cmp == XFS_CMP_EXACT) return -EEXIST; ci_sfep = sfep; @@ -1084,7 +1114,7 @@ xfs_dir2_sf_replace( ASSERT(args->inumber != ino); xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber); - dp->d_ops->sf_put_ftype(sfep, args->filetype); + xfs_dir2_sf_put_ftype(mp, sfep, args->filetype); break; } } @@ -1190,7 +1220,8 @@ xfs_dir2_sf_toino4( memcpy(sfep->name, oldsfep->name, sfep->namelen); xfs_dir2_sf_put_ino(mp, sfp, sfep, xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep)); - dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep)); + xfs_dir2_sf_put_ftype(mp, sfep, + xfs_dir2_sf_get_ftype(mp, oldsfep)); } /* * Clean up the inode. @@ -1262,7 +1293,8 @@ xfs_dir2_sf_toino8( memcpy(sfep->name, oldsfep->name, sfep->namelen); xfs_dir2_sf_put_ino(mp, sfp, sfep, xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep)); - dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep)); + xfs_dir2_sf_put_ftype(mp, sfep, + xfs_dir2_sf_get_ftype(mp, oldsfep)); } /* * Clean up the inode. diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index 9d318f091a73..e18045465455 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -115,7 +115,7 @@ xfs_dir2_sf_getdents( } ino = xfs_dir2_sf_get_ino(mp, sfp, sfep); - filetype = dp->d_ops->sf_get_ftype(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, -- cgit v1.2.3 From da3ca0df8bd146bf1c83db1b9763189976175e87 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 15:05:31 -0800 Subject: xfs: remove the ->data_dot_entry_p and ->data_dotdot_entry_p methods The only user of the ->data_dot_entry_p and ->data_dotdot_entry_p methods is the xfs_dir2_sf_to_block function that builds block format directorys from a short form directory. It already uses pointer arithmetics with a offset variable to do so for the real entries in the directory, so switch the generation of the . and .. entries to the same scheme, and clean up some of the later pointer arithmetics to use bp->b_addr directly as well and avoid some casts. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_format.c | 52 ---------------------------------------- fs/xfs/libxfs/xfs_dir2.h | 4 ---- fs/xfs/libxfs/xfs_dir2_block.c | 54 ++++++++++++++++++++---------------------- 3 files changed, 26 insertions(+), 84 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_block.c') diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index 7b783b11790d..711faff4aea2 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -111,52 +111,6 @@ xfs_dir3_data_entry_tag_p( xfs_dir3_data_entsize(dep->namelen) - sizeof(__be16)); } -/* - * location of . and .. in data space (always block 0) - */ -static struct xfs_dir2_data_entry * -xfs_dir2_data_dot_entry_p( - struct xfs_dir2_data_hdr *hdr) -{ - return (struct xfs_dir2_data_entry *) - ((char *)hdr + sizeof(struct xfs_dir2_data_hdr)); -} - -static struct xfs_dir2_data_entry * -xfs_dir2_data_dotdot_entry_p( - struct xfs_dir2_data_hdr *hdr) -{ - return (struct xfs_dir2_data_entry *) - ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) + - XFS_DIR2_DATA_ENTSIZE(1)); -} - -static struct xfs_dir2_data_entry * -xfs_dir2_ftype_data_dotdot_entry_p( - struct xfs_dir2_data_hdr *hdr) -{ - return (struct xfs_dir2_data_entry *) - ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) + - XFS_DIR3_DATA_ENTSIZE(1)); -} - -static struct xfs_dir2_data_entry * -xfs_dir3_data_dot_entry_p( - struct xfs_dir2_data_hdr *hdr) -{ - return (struct xfs_dir2_data_entry *) - ((char *)hdr + sizeof(struct xfs_dir3_data_hdr)); -} - -static struct xfs_dir2_data_entry * -xfs_dir3_data_dotdot_entry_p( - struct xfs_dir2_data_hdr *hdr) -{ - return (struct xfs_dir2_data_entry *) - ((char *)hdr + sizeof(struct xfs_dir3_data_hdr) + - XFS_DIR3_DATA_ENTSIZE(1)); -} - static struct xfs_dir2_data_free * xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr) { @@ -209,8 +163,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { XFS_DIR2_DATA_ENTSIZE(2), .data_entry_offset = sizeof(struct xfs_dir2_data_hdr), - .data_dot_entry_p = xfs_dir2_data_dot_entry_p, - .data_dotdot_entry_p = xfs_dir2_data_dotdot_entry_p, .data_entry_p = xfs_dir2_data_entry_p, .data_unused_p = xfs_dir2_data_unused_p, }; @@ -227,8 +179,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { XFS_DIR3_DATA_ENTSIZE(2), .data_entry_offset = sizeof(struct xfs_dir2_data_hdr), - .data_dot_entry_p = xfs_dir2_data_dot_entry_p, - .data_dotdot_entry_p = xfs_dir2_ftype_data_dotdot_entry_p, .data_entry_p = xfs_dir2_data_entry_p, .data_unused_p = xfs_dir2_data_unused_p, }; @@ -245,8 +195,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = { XFS_DIR3_DATA_ENTSIZE(2), .data_entry_offset = sizeof(struct xfs_dir3_data_hdr), - .data_dot_entry_p = xfs_dir3_data_dot_entry_p, - .data_dotdot_entry_p = xfs_dir3_data_dotdot_entry_p, .data_entry_p = xfs_dir3_data_entry_p, .data_unused_p = xfs_dir3_data_unused_p, }; diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index 8b937993263d..8bfcf4c1b9c4 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -43,10 +43,6 @@ struct xfs_dir_ops { xfs_dir2_data_aoff_t data_first_offset; size_t data_entry_offset; - struct xfs_dir2_data_entry * - (*data_dot_entry_p)(struct xfs_dir2_data_hdr *hdr); - struct xfs_dir2_data_entry * - (*data_dotdot_entry_p)(struct xfs_dir2_data_hdr *hdr); struct xfs_dir2_data_entry * (*data_entry_p)(struct xfs_dir2_data_hdr *hdr); struct xfs_dir2_data_unused * diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 6bc82a02b228..e7719356829d 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -1038,39 +1038,35 @@ xfs_dir2_leaf_to_block( */ int /* error */ xfs_dir2_sf_to_block( - xfs_da_args_t *args) /* operation arguments */ + struct xfs_da_args *args) { + struct xfs_trans *tp = args->trans; + struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; + struct xfs_ifork *ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK); 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 */ struct xfs_buf *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail pointer */ xfs_dir2_data_entry_t *dep; /* data entry pointer */ - xfs_inode_t *dp; /* incore directory inode */ int dummy; /* trash */ xfs_dir2_data_unused_t *dup; /* unused entry pointer */ int endoffset; /* end of data objects */ int error; /* error return value */ int i; /* index */ - xfs_mount_t *mp; /* filesystem mount point */ int needlog; /* need to log block header */ int needscan; /* need to scan block freespc */ int newoffset; /* offset from current entry */ - int offset; /* target block offset */ + unsigned int offset = dp->d_ops->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 */ __be16 *tagp; /* end of data entry */ - xfs_trans_t *tp; /* transaction pointer */ struct xfs_name name; - struct xfs_ifork *ifp; trace_xfs_dir2_sf_to_block(args); - dp = args->dp; - tp = args->trans; - mp = dp->i_mount; - ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK); ASSERT(ifp->if_flags & XFS_IFINLINE); ASSERT(dp->i_d.di_size >= offsetof(struct xfs_dir2_sf_hdr, parent)); @@ -1139,35 +1135,37 @@ xfs_dir2_sf_to_block( be16_to_cpu(dup->length), &needlog, &needscan); if (error) goto out_free; + /* * Create entry for . */ - dep = dp->d_ops->data_dot_entry_p(hdr); + dep = bp->b_addr + offset; 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); tagp = dp->d_ops->data_entry_tag_p(dep); - *tagp = cpu_to_be16((char *)dep - (char *)hdr); + *tagp = cpu_to_be16(offset); 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( - (char *)dep - (char *)hdr)); + blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(offset)); + offset += dp->d_ops->data_entsize(dep->namelen); + /* * Create entry for .. */ - dep = dp->d_ops->data_dotdot_entry_p(hdr); + dep = bp->b_addr + offset; 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); tagp = dp->d_ops->data_entry_tag_p(dep); - *tagp = cpu_to_be16((char *)dep - (char *)hdr); + *tagp = cpu_to_be16(offset); 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( - (char *)dep - (char *)hdr)); - offset = dp->d_ops->data_first_offset; + blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(offset)); + offset += dp->d_ops->data_entsize(dep->namelen); + /* * Loop over existing entries, stuff them in. */ @@ -1176,6 +1174,7 @@ xfs_dir2_sf_to_block( sfep = NULL; else sfep = xfs_dir2_sf_firstentry(sfp); + /* * Need to preserve the existing offset values in the sf directory. * Insert holes (unused entries) where necessary. @@ -1192,11 +1191,10 @@ xfs_dir2_sf_to_block( * There should be a hole here, make one. */ if (offset < newoffset) { - dup = (xfs_dir2_data_unused_t *)((char *)hdr + offset); + dup = bp->b_addr + offset; dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); dup->length = cpu_to_be16(newoffset - offset); - *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16( - ((char *)dup - (char *)hdr)); + *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), @@ -1207,20 +1205,20 @@ xfs_dir2_sf_to_block( /* * Copy a real entry. */ - dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset); + 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)); memcpy(dep->name, sfep->name, dep->namelen); tagp = dp->d_ops->data_entry_tag_p(dep); - *tagp = cpu_to_be16((char *)dep - (char *)hdr); + *tagp = cpu_to_be16(newoffset); 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].address = cpu_to_be32(xfs_dir2_byte_to_dataptr( - (char *)dep - (char *)hdr)); + blp[2 + i].hashval = + cpu_to_be32(mp->m_dirnameops->hashname(&name)); + blp[2 + i].address = + cpu_to_be32(xfs_dir2_byte_to_dataptr(newoffset)); offset = (int)((char *)(tagp + 1) - (char *)hdr); if (++i == sfp->count) sfep = NULL; -- cgit v1.2.3 From ee641d5af5e638d53d9bcde459836b1cb90f12e2 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Nov 2019 15:05:31 -0800 Subject: xfs: remove the ->data_unused_p method Replace the two users of the ->data_unused_p dir ops method with a direct calculation using ->data_entry_offset, and clean them up a bit. xfs_dir2_sf_to_block already had an offset variable containing the value of ->data_entry_offset, which we are now reusing to make it clear that the initial freespace entry is at the same place that we later fill in the 1 entry, and in xfs_dir3_data_init the function is cleaned up a bit to keep the initialization of fields of a given structure close to each other, and to avoid a local variable. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_da_format.c | 17 ----------------- fs/xfs/libxfs/xfs_dir2.h | 2 -- fs/xfs/libxfs/xfs_dir2_block.c | 2 +- fs/xfs/libxfs/xfs_dir2_data.c | 40 ++++++++++++++++++---------------------- 4 files changed, 19 insertions(+), 42 deletions(-) (limited to 'fs/xfs/libxfs/xfs_dir2_block.c') diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index 711faff4aea2..347092ec28ab 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -130,13 +130,6 @@ xfs_dir2_data_entry_p(struct xfs_dir2_data_hdr *hdr) ((char *)hdr + sizeof(struct xfs_dir2_data_hdr)); } -static struct xfs_dir2_data_unused * -xfs_dir2_data_unused_p(struct xfs_dir2_data_hdr *hdr) -{ - return (struct xfs_dir2_data_unused *) - ((char *)hdr + sizeof(struct xfs_dir2_data_hdr)); -} - static struct xfs_dir2_data_entry * xfs_dir3_data_entry_p(struct xfs_dir2_data_hdr *hdr) { @@ -144,13 +137,6 @@ xfs_dir3_data_entry_p(struct xfs_dir2_data_hdr *hdr) ((char *)hdr + sizeof(struct xfs_dir3_data_hdr)); } -static struct xfs_dir2_data_unused * -xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr) -{ - return (struct xfs_dir2_data_unused *) - ((char *)hdr + sizeof(struct xfs_dir3_data_hdr)); -} - static const struct xfs_dir_ops xfs_dir2_ops = { .data_entsize = xfs_dir2_data_entsize, .data_get_ftype = xfs_dir2_data_get_ftype, @@ -164,7 +150,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { .data_entry_offset = sizeof(struct xfs_dir2_data_hdr), .data_entry_p = xfs_dir2_data_entry_p, - .data_unused_p = xfs_dir2_data_unused_p, }; static const struct xfs_dir_ops xfs_dir2_ftype_ops = { @@ -180,7 +165,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { .data_entry_offset = sizeof(struct xfs_dir2_data_hdr), .data_entry_p = xfs_dir2_data_entry_p, - .data_unused_p = xfs_dir2_data_unused_p, }; static const struct xfs_dir_ops xfs_dir3_ops = { @@ -196,7 +180,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = { .data_entry_offset = sizeof(struct xfs_dir3_data_hdr), .data_entry_p = xfs_dir3_data_entry_p, - .data_unused_p = xfs_dir3_data_unused_p, }; /* diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index 8bfcf4c1b9c4..75aec05aae10 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -45,8 +45,6 @@ struct xfs_dir_ops { struct xfs_dir2_data_entry * (*data_entry_p)(struct xfs_dir2_data_hdr *hdr); - struct xfs_dir2_data_unused * - (*data_unused_p)(struct xfs_dir2_data_hdr *hdr); }; 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 e7719356829d..9061f378d52a 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -1112,7 +1112,7 @@ xfs_dir2_sf_to_block( * The whole thing is initialized to free by the init routine. * Say we're using the leaf and tail area. */ - dup = dp->d_ops->data_unused_p(hdr); + dup = bp->b_addr + offset; needlog = needscan = 0; error = xfs_dir2_data_use_free(args, bp, dup, args->geo->blksize - i, i, &needlog, &needscan); diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index 2c79be4c3153..3ecec8e1c5f6 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -631,24 +631,20 @@ xfs_dir2_data_freescan( */ int /* error */ xfs_dir3_data_init( - xfs_da_args_t *args, /* directory operation args */ - xfs_dir2_db_t blkno, /* logical dir block number */ - struct xfs_buf **bpp) /* output block buffer */ + struct xfs_da_args *args, /* directory operation args */ + xfs_dir2_db_t blkno, /* logical dir block number */ + struct xfs_buf **bpp) /* output block buffer */ { - struct xfs_buf *bp; /* block buffer */ - xfs_dir2_data_hdr_t *hdr; /* data block header */ - xfs_inode_t *dp; /* incore directory inode */ - xfs_dir2_data_unused_t *dup; /* unused entry pointer */ - struct xfs_dir2_data_free *bf; - int error; /* error return value */ - int i; /* bestfree index */ - xfs_mount_t *mp; /* filesystem mount point */ - xfs_trans_t *tp; /* transaction pointer */ - int t; /* temp */ - - dp = args->dp; - mp = dp->i_mount; - tp = args->trans; + struct xfs_trans *tp = args->trans; + struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; + struct xfs_buf *bp; + struct xfs_dir2_data_hdr *hdr; + struct xfs_dir2_data_unused *dup; + struct xfs_dir2_data_free *bf; + int error; + int i; + /* * Get the buffer set up for the block. */ @@ -677,6 +673,8 @@ xfs_dir3_data_init( 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); for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) { bf[i].length = 0; bf[i].offset = 0; @@ -685,13 +683,11 @@ xfs_dir3_data_init( /* * Set up an unused entry for the block's body. */ - dup = dp->d_ops->data_unused_p(hdr); + dup = bp->b_addr + dp->d_ops->data_entry_offset; dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); - - t = args->geo->blksize - (uint)dp->d_ops->data_entry_offset; - bf[0].length = cpu_to_be16(t); - dup->length = cpu_to_be16(t); + dup->length = bf[0].length; *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr); + /* * Log it and return it. */ -- cgit v1.2.3 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_block.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 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_block.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 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_block.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 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_block.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 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_block.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 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_block.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 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_block.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 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_block.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