From: Christoph Hellwig Date: Wed, 22 Jan 2020 16:29:43 +0000 (-0500) Subject: xfs: devirtualize ->data_entsize X-Git-Tag: v5.5.0-rc0~43 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=271a654f404d6621730c144b9b5281222814784f;p=thirdparty%2Fxfsprogs-dev.git xfs: devirtualize ->data_entsize Source kernel commit: fdbb8c5b805c19bc2764aa1b91952e75e4c1c086 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 Signed-off-by: Eric Sandeen --- diff --git a/db/check.c b/db/check.c index cb55d3a6d..c0665abe1 100644 --- a/db/check.c +++ b/db/check.c @@ -2416,7 +2416,7 @@ process_data_dir_v2( xname.name = dep->name; xname.len = dep->namelen; dir_hash_add(mp->m_dirnameops->hashname(&xname), addr); - ptr += M_DIROPS(mp)->data_entsize(dep->namelen); + ptr += libxfs_dir2_data_entsize(mp, dep->namelen); count++; lastfree = 0; lino = be64_to_cpu(dep->inumber); diff --git a/db/dir2.c b/db/dir2.c index bd1a3edbf..58f75b395 100644 --- a/db/dir2.c +++ b/db/dir2.c @@ -211,7 +211,7 @@ __dir2_data_entries_count( ptr += be16_to_cpu(dup->length); else { dep = (xfs_dir2_data_entry_t *)ptr; - ptr += M_DIROPS(mp)->data_entsize(dep->namelen); + ptr += libxfs_dir2_data_entsize(mp, dep->namelen); } } return i; @@ -235,7 +235,7 @@ __dir2_data_entry_offset( ptr += be16_to_cpu(dup->length); else { dep = (xfs_dir2_data_entry_t *)ptr; - ptr += M_DIROPS(mp)->data_entsize(dep->namelen); + ptr += libxfs_dir2_data_entsize(mp, dep->namelen); } } return ptr; @@ -585,7 +585,7 @@ dir2_data_union_size( return bitize(be16_to_cpu(dup->length)); else { dep = (xfs_dir2_data_entry_t *)dup; - return bitize(M_DIROPS(mp)->data_entsize(dep->namelen)); + return bitize(libxfs_dir2_data_entsize(mp, dep->namelen)); } } diff --git a/db/metadump.c b/db/metadump.c index 43f7ee94f..77e3b4ba4 100644 --- a/db/metadump.c +++ b/db/metadump.c @@ -1602,7 +1602,7 @@ process_dir_data_block( } dep = (xfs_dir2_data_entry_t *)ptr; - length = M_DIROPS(mp)->data_entsize(dep->namelen); + length = libxfs_dir2_data_entsize(mp, dep->namelen); if (dir_offset + length > end_of_data || ptr + length > endptr) { diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index 09d618e22..208db077a 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -84,6 +84,7 @@ #define xfs_dir2_data_log_header libxfs_dir2_data_log_header #define xfs_dir2_data_make_free libxfs_dir2_data_make_free #define xfs_dir2_data_use_free libxfs_dir2_data_use_free +#define xfs_dir2_data_entsize libxfs_dir2_data_entsize #define xfs_dir2_shrink_inode libxfs_dir2_shrink_inode #define xfs_dir2_sf_get_parent_ino libxfs_dir2_sf_get_parent_ino #define xfs_dir2_sf_put_parent_ino libxfs_dir2_sf_put_parent_ino diff --git a/libxfs/xfs_da_format.c b/libxfs/xfs_da_format.c index 2847bc4cd..d54d6e288 100644 --- a/libxfs/xfs_da_format.c +++ b/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/libxfs/xfs_dir2.h b/libxfs/xfs_dir2.h index 3a4b98d49..f717b1cdb 100644 --- a/libxfs/xfs_dir2.h +++ b/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/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c index aa8142c5c..8d2354ead 100644 --- a/libxfs/xfs_dir2_block.c +++ b/libxfs/xfs_dir2_block.c @@ -352,7 +352,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. @@ -788,7 +788,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. */ @@ -1146,7 +1147,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 .. @@ -1161,7 +1162,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/libxfs/xfs_dir2_data.c b/libxfs/xfs_dir2_data.c index d6e0c8787..b18b73670 100644 --- a/libxfs/xfs_dir2_data.c +++ b/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_trans.h" static xfs_failaddr_t xfs_dir2_data_freefind_verify( @@ -176,7 +177,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; @@ -200,7 +201,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. @@ -564,7 +565,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) @@ -585,7 +586,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; @@ -605,7 +606,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); } } @@ -615,8 +616,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/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c index 15ed7c6f8..a0cd60f3e 100644 --- a/libxfs/xfs_dir2_leaf.c +++ b/libxfs/xfs_dir2_leaf.c @@ -658,7 +658,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 @@ -1395,7 +1395,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/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c index a6733e1d9..b446bed7c 100644 --- a/libxfs/xfs_dir2_node.c +++ b/libxfs/xfs_dir2_node.c @@ -663,7 +663,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. */ @@ -1317,7 +1317,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. @@ -1910,7 +1911,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/libxfs/xfs_dir2_priv.h b/libxfs/xfs_dir2_priv.h index d6b58aa7e..b97718eef 100644 --- a/libxfs/xfs_dir2_priv.h +++ b/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/libxfs/xfs_dir2_sf.c b/libxfs/xfs_dir2_sf.c index a707180ad..e4df15bc0 100644 --- a/libxfs/xfs_dir2_sf.c +++ b/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/repair/dir2.c b/repair/dir2.c index f5f2d7bf7..c15e8754c 100644 --- a/repair/dir2.c +++ b/repair/dir2.c @@ -121,7 +121,7 @@ process_sf_dir2_fixoff( for (i = 0; i < sfp->count; i++) { xfs_dir2_sf_put_offset(sfep, offset); - offset += M_DIROPS(mp)->data_entsize(sfep->namelen); + offset += libxfs_dir2_data_entsize(mp, sfep->namelen); sfep = libxfs_dir2_sf_nextentry(mp, sfp, sfep); } } @@ -327,7 +327,7 @@ _("entry contains offset out of order in shortform dir %" PRIu64 "\n"), bad_offset = 1; } offset = xfs_dir2_sf_get_offset(sfep) + - M_DIROPS(mp)->data_entsize(namelen); + libxfs_dir2_data_entsize(mp, namelen); /* * junk the entry by copying up the rest of the @@ -625,12 +625,12 @@ process_dir2_data( continue; } dep = (xfs_dir2_data_entry_t *)ptr; - if (ptr + M_DIROPS(mp)->data_entsize(dep->namelen) > endptr) + if (ptr + libxfs_dir2_data_entsize(mp, dep->namelen) > endptr) break; if (be16_to_cpu(*M_DIROPS(mp)->data_entry_tag_p(dep)) != (char *)dep - (char *)d) break; - ptr += M_DIROPS(mp)->data_entsize(dep->namelen); + ptr += libxfs_dir2_data_entsize(mp, dep->namelen); lastfree = 0; } /* @@ -917,7 +917,7 @@ _("entry \"%*.*s\" in directory inode %" PRIu64 " points to self: "), /* * Advance to the next entry. */ - ptr += M_DIROPS(mp)->data_entsize(dep->namelen); + ptr += libxfs_dir2_data_entsize(mp, dep->namelen); } /* * Check the bestfree table. @@ -928,8 +928,7 @@ _("bad bestfree table in block %u in directory inode %" PRIu64 ": "), da_bno, ino); if (!no_modify) { do_warn(_("repairing table\n")); - libxfs_dir2_data_freescan_int(mp->m_dir_geo, - M_DIROPS(mp), d, &i); + libxfs_dir2_data_freescan_int(mp, M_DIROPS(mp), d, &i); *dirty = 1; } else { do_warn(_("would repair table\n")); diff --git a/repair/phase6.c b/repair/phase6.c index e7d227ae3..4c74d6f2d 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -1602,12 +1602,12 @@ longform_dir2_entry_check_data( /* validate data entry size */ dep = (xfs_dir2_data_entry_t *)ptr; - if (ptr + M_DIROPS(mp)->data_entsize(dep->namelen) > endptr) + if (ptr + libxfs_dir2_data_entsize(mp, dep->namelen) > endptr) break; if (be16_to_cpu(*M_DIROPS(mp)->data_entry_tag_p(dep)) != (char *)dep - (char *)d) break; - ptr += M_DIROPS(mp)->data_entsize(dep->namelen); + ptr += libxfs_dir2_data_entsize(mp, dep->namelen); } /* did we find an empty or corrupt block? */ @@ -1696,7 +1696,7 @@ longform_dir2_entry_check_data( addr = xfs_dir2_db_off_to_dataptr(mp->m_dir_geo, db, ptr - (char *)d); dep = (xfs_dir2_data_entry_t *)ptr; - ptr += M_DIROPS(mp)->data_entsize(dep->namelen); + ptr += libxfs_dir2_data_entsize(mp, dep->namelen); inum = be64_to_cpu(dep->inumber); lastfree = 0; /* @@ -1940,8 +1940,7 @@ _("entry \"%s\" in dir inode %" PRIu64 " inconsistent with .. value (%" PRIu64 " } *num_illegal += nbad; if (needscan) - libxfs_dir2_data_freescan_int(mp->m_dir_geo, M_DIROPS(mp), - d, &i); + libxfs_dir2_data_freescan_int(mp, M_DIROPS(mp), d, &i); if (needlog) libxfs_dir2_data_log_header(&da, bp); error = -libxfs_trans_commit(tp);