From: Barry Naujok Date: Mon, 26 May 2008 04:03:56 +0000 (+0000) Subject: ASCII case-insensitive support for xfsprogs X-Git-Tag: v2.10.0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=51ca7008bcbb2af9407a612490b86a97f3eb7494;p=thirdparty%2Fxfsprogs-dev.git ASCII case-insensitive support for xfsprogs Merge of master-melb:xfs-cmds:31229a by kenmcd. Bump to 2.10.0 --- diff --git a/VERSION b/VERSION index d01da0f56..6d487e229 100644 --- a/VERSION +++ b/VERSION @@ -2,6 +2,6 @@ # This file is used by configure to get version information # PKG_MAJOR=2 -PKG_MINOR=9 -PKG_REVISION=8 +PKG_MINOR=10 +PKG_REVISION=0 PKG_BUILD=1 diff --git a/db/check.c b/db/check.c index bd6d8a9aa..a151c0678 100644 --- a/db/check.c +++ b/db/check.c @@ -2317,7 +2317,7 @@ process_data_dir_v2( tag_err += INT_GET(*tagp, ARCH_CONVERT) != (char *)dep - (char *)data; addr = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, db, (char *)dep - (char *)data); - hash = libxfs_da_hashname((uchar_t *)dep->name, dep->namelen); + hash = mp->m_dirnameops->hashname((uchar_t *)dep->name, dep->namelen); dir_hash_add(hash, addr); ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen); count++; diff --git a/db/sb.c b/db/sb.c index 03a639e3d..643f482d1 100644 --- a/db/sb.c +++ b/db/sb.c @@ -605,6 +605,8 @@ version_string( strcat(s, ",EXTFLG"); if (XFS_SB_VERSION_HASSECTOR(sbp)) strcat(s, ",SECTOR"); + if (xfs_sb_version_hasasciici(sbp)) + strcat(s, ",ASCII_CI"); if (XFS_SB_VERSION_HASMOREBITS(sbp)) strcat(s, ",MOREBITS"); if (XFS_SB_VERSION_HASATTR2(sbp)) diff --git a/doc/CHANGES b/doc/CHANGES index 72a28015d..48640ceaf 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -1,3 +1,6 @@ +xfsprogs-2.10.0 (26 May 2008) + - Add ASCII case-insensitive support to xfsprogs. + xfsprogs-2.9.8 (21 April 2008) - Add support for sb_features2 in wrong location in mkfs.xfs, xfs_repair and xfs_db. diff --git a/growfs/xfs_growfs.c b/growfs/xfs_growfs.c index e865b1f72..8e53ff5fc 100644 --- a/growfs/xfs_growfs.c +++ b/growfs/xfs_growfs.c @@ -61,14 +61,15 @@ report_info( int lazycount, int dirversion, int logversion, - int attrversion) + int attrversion, + int cimode) { printf(_( "meta-data=%-22s isize=%-6u agcount=%u, agsize=%u blks\n" " =%-22s sectsz=%-5u attr=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" - "naming =version %-14u bsize=%-6u\n" + "naming =version %-14u bsize=%-6u mixed-case=%c\n" "log =%-22s bsize=%-6u blocks=%u, version=%u\n" " =%-22s sectsz=%-5u sunit=%u blks, lazy-count=%u\n" "realtime =%-22s extsz=%-6u blocks=%llu, rtextents=%llu\n"), @@ -78,7 +79,7 @@ report_info( "", geo.blocksize, (unsigned long long)geo.datablocks, geo.imaxpct, "", geo.sunit, geo.swidth, - dirversion, geo.dirblocksize, + dirversion, geo.dirblocksize, cimode ? 'N' : 'Y', isint ? _("internal") : logname ? logname : _("external"), geo.blocksize, geo.logblocks, logversion, "", geo.logsectsize, geo.logsunit / geo.blocksize, lazycount, @@ -114,6 +115,7 @@ main(int argc, char **argv) xfs_fsop_geom_t ngeo; /* new fs geometry */ int rflag; /* -r flag */ long long rsize; /* new rt size in fs blocks */ + int ci; /* ASCII case-insensitive fs */ int lazycount; /* lazy superblock counters */ int xflag; /* -x flag */ char *fname; /* mount point name */ @@ -131,6 +133,7 @@ main(int argc, char **argv) maxpct = esize = 0; dsize = lsize = rsize = 0LL; aflag = dflag = iflag = lflag = mflag = nflag = rflag = xflag = 0; + ci = 0; while ((c = getopt(argc, argv, "dD:e:ilL:m:np:rR:t:xV")) != EOF) { switch (c) { @@ -239,11 +242,11 @@ main(int argc, char **argv) logversion = geo.flags & XFS_FSOP_GEOM_FLAGS_LOGV2 ? 2 : 1; attrversion = geo.flags & XFS_FSOP_GEOM_FLAGS_ATTR2 ? 2 : \ (geo.flags & XFS_FSOP_GEOM_FLAGS_ATTR ? 1 : 0); - + ci = geo.flags & XFS_FSOP_GEOM_FLAGS_DIRV2CI ? 1 : 0; if (nflag) { report_info(geo, datadev, isint, logdev, rtdev, lazycount, dirversion, logversion, - attrversion); + attrversion, ci); exit(0); } @@ -280,7 +283,7 @@ main(int argc, char **argv) report_info(geo, datadev, isint, logdev, rtdev, lazycount, dirversion, logversion, - attrversion); + attrversion, ci); ddsize = xi.dsize; dlsize = ( xi.logBBsize? xi.logBBsize : diff --git a/include/libxfs.h b/include/libxfs.h index 1c0a62ed6..84d6ec6fb 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -175,6 +175,7 @@ typedef struct xfs_mount { int m_attr_magicpct;/* 37% of the blocksize */ int m_dir_magicpct; /* 37% of the dir blocksize */ __uint8_t m_dirversion; /* 1 or 2 */ + const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */ int m_dirblksize; /* directory block sz--bytes */ int m_dirblkfsbs; /* directory block sz--fsbs */ xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ diff --git a/include/xfs_da_btree.h b/include/xfs_da_btree.h index 413521137..49e38167e 100644 --- a/include/xfs_da_btree.h +++ b/include/xfs_da_btree.h @@ -102,6 +102,15 @@ typedef struct xfs_da_node_entry xfs_da_node_entry_t; * Btree searching and modification structure definitions. *========================================================================*/ +/* + * Search comparison results + */ +enum xfs_dacmp { + XFS_CMP_DIFFERENT, /* names are completely different */ + XFS_CMP_EXACT, /* names are exactly the same */ + XFS_CMP_CASE /* names are same but differ in case */ +}; + /* * Structure to ease passing around component names. */ @@ -131,6 +140,7 @@ typedef struct xfs_da_args { unsigned char rename; /* T/F: this is an atomic rename op */ unsigned char addname; /* T/F: this is an add operation */ unsigned char oknoent; /* T/F: ok to return ENOENT, else die */ + enum xfs_dacmp cmpresult; /* name compare result for lookups */ } xfs_da_args_t; /* @@ -205,6 +215,14 @@ typedef struct xfs_da_state { (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)(const uchar_t *, int); + enum xfs_dacmp (*compname)(const uchar_t *, int, const uchar_t *, int); +}; + #ifdef __KERNEL__ /*======================================================================== @@ -253,6 +271,9 @@ int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, xfs_dabuf_t *dead_buf); uint xfs_da_hashname(const uchar_t *name_string, int name_length); +enum xfs_dacmp xfs_da_compname(const uchar_t *name1, int len1, + const uchar_t *name2, int len2); + uint xfs_da_log2_roundup(uint i); xfs_da_state_t *xfs_da_state_alloc(void); void xfs_da_state_free(xfs_da_state_t *state); diff --git a/include/xfs_fs.h b/include/xfs_fs.h index 4ee0ab88a..7d22bbd72 100644 --- a/include/xfs_fs.h +++ b/include/xfs_fs.h @@ -241,6 +241,7 @@ typedef struct xfs_fsop_resblks { #define XFS_FSOP_GEOM_FLAGS_LOGV2 0x0100 /* log format version 2 */ #define XFS_FSOP_GEOM_FLAGS_SECTOR 0x0200 /* sector sizes >1BB */ #define XFS_FSOP_GEOM_FLAGS_ATTR2 0x0400 /* inline attributes rework */ +#define XFS_FSOP_GEOM_FLAGS_DIRV2CI 0x1000 /* ASCII only CI names */ #define XFS_FSOP_GEOM_FLAGS_LAZYSB 0x4000 /* lazy superblock counters */ diff --git a/include/xfs_sb.h b/include/xfs_sb.h index 309834420..41c6e3fbf 100644 --- a/include/xfs_sb.h +++ b/include/xfs_sb.h @@ -46,10 +46,12 @@ struct xfs_mount; #define XFS_SB_VERSION_SECTORBIT 0x0800 #define XFS_SB_VERSION_EXTFLGBIT 0x1000 #define XFS_SB_VERSION_DIRV2BIT 0x2000 +#define XFS_SB_VERSION_BORGBIT 0x4000 #define XFS_SB_VERSION_MOREBITSBIT 0x8000 #define XFS_SB_VERSION_OKSASHFBITS \ (XFS_SB_VERSION_EXTFLGBIT | \ - XFS_SB_VERSION_DIRV2BIT) + XFS_SB_VERSION_DIRV2BIT | \ + XFS_SB_VERSION_BORGBIT) #define XFS_SB_VERSION_OKREALFBITS \ (XFS_SB_VERSION_ATTRBIT | \ XFS_SB_VERSION_NLINKBIT | \ @@ -416,6 +418,12 @@ static inline int xfs_sb_version_hassector(xfs_sb_t *sbp) ((sbp)->sb_versionnum & XFS_SB_VERSION_SECTORBIT); } +static inline int xfs_sb_version_hasasciici(xfs_sb_t *sbp) +{ + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ + (sbp->sb_versionnum & XFS_SB_VERSION_BORGBIT); +} + #define XFS_SB_VERSION_HASMOREBITS(sbp) xfs_sb_version_hasmorebits(sbp) static inline int xfs_sb_version_hasmorebits(xfs_sb_t *sbp) { diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c index 3121e2f74..c7777049e 100644 --- a/libxfs/xfs_da_btree.c +++ b/libxfs/xfs_da_btree.c @@ -1540,6 +1540,18 @@ xfs_da_hashname(const uchar_t *name, int namelen) } } +enum xfs_dacmp +xfs_da_compname(const uchar_t *name1, int len1, const uchar_t *name2, int len2) +{ + return (len1 == len2 && memcmp(name1, name2, len1) == 0) ? + XFS_CMP_EXACT : XFS_CMP_DIFFERENT; +} + +const struct xfs_nameops xfs_default_nameops = { + .hashname = xfs_da_hashname, + .compname = xfs_da_compname +}; + /* * Add a block to the btree ahead of the file. * Return the new block number to the caller. diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index 76b0b7ee2..a436e4f8b 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -23,6 +23,57 @@ #include +extern const struct xfs_nameops xfs_default_nameops; + +/* + * V1/OLDCI case-insensitive support for directories that was used in IRIX. + * + * This is ASCII only case support, ie. A-Z. + */ +static xfs_dahash_t +xfs_ascii_ci_hashname( + const uchar_t *name, + int len) +{ + xfs_dahash_t hash; + int i; + + for (i = 0, hash = 0; i < len; i++) + hash = tolower(name[i]) ^ rol32(hash, 7); + + return hash; +} + +static enum xfs_dacmp +xfs_ascii_ci_compname( + const uchar_t *name1, + int len1, + const uchar_t *name2, + int len2) +{ + enum xfs_dacmp result; + int i; + + if (len1 != len2) + return XFS_CMP_DIFFERENT; + + result = XFS_CMP_EXACT; + for (i = 0; i < len1; i++) { + if (name1[i] == name2[i]) + continue; + if (tolower(name1[i]) != tolower(name2[i])) + return XFS_CMP_DIFFERENT; + result = XFS_CMP_CASE; + } + + return result; +} + +static const struct xfs_nameops xfs_ascii_ci_nameops = { + .hashname = xfs_ascii_ci_hashname, + .compname = xfs_ascii_ci_compname, +}; + /* * Initialize directory-related fields in the mount structure. @@ -46,6 +97,10 @@ xfs_dir2_mount( (mp->m_dirblksize - (uint)sizeof(xfs_da_node_hdr_t)) / (uint)sizeof(xfs_da_node_entry_t); mp->m_dir_magicpct = (mp->m_dirblksize * 37) / 100; + if (xfs_sb_version_hasasciici(&mp->m_sb)) + mp->m_dirnameops = &xfs_ascii_ci_nameops; + else + mp->m_dirnameops = &xfs_default_nameops; } /* @@ -98,7 +153,7 @@ xfs_dir2_createname( */ args.name = name; args.namelen = namelen; - args.hashval = xfs_da_hashname(name, namelen); + args.hashval = dp->i_mount->m_dirnameops->hashname(name, namelen); args.inumber = inum; args.dp = dp; args.firstblock = first; @@ -149,7 +204,7 @@ xfs_dir2_lookup( */ args.name = name; args.namelen = namelen; - args.hashval = xfs_da_hashname(name, namelen); + args.hashval = dp->i_mount->m_dirnameops->hashname(name, namelen); args.inumber = 0; args.dp = dp; args.firstblock = NULL; @@ -206,7 +261,7 @@ xfs_dir2_removename( */ args.name = name; args.namelen = namelen; - args.hashval = xfs_da_hashname(name, namelen); + args.hashval = dp->i_mount->m_dirnameops->hashname(name, namelen); args.inumber = ino; args.dp = dp; args.firstblock = first; @@ -261,7 +316,7 @@ xfs_dir2_replace( */ args.name = name; args.namelen = namelen; - args.hashval = xfs_da_hashname(name, namelen); + args.hashval = dp->i_mount->m_dirnameops->hashname(name, namelen); args.inumber = inum; args.dp = dp; args.firstblock = first; diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c index 08d79100e..f7259cd7c 100644 --- a/libxfs/xfs_dir2_block.c +++ b/libxfs/xfs_dir2_block.c @@ -1046,8 +1046,9 @@ xfs_dir2_sf_to_block( tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block)); xfs_dir2_data_log_entry(tp, bp, dep); - INT_SET(blp[2 + i].hashval, ARCH_CONVERT, xfs_da_hashname((const uchar_t *)sfep->name, sfep->namelen)); - INT_SET(blp[2 + i].address, ARCH_CONVERT, XFS_DIR2_BYTE_TO_DATAPTR(mp, + blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops->hashname( + sfep->name, sfep->namelen)); + blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, (char *)dep - (char *)block)); offset = (int)((char *)(tagp + 1) - (char *)block); if (++i == INT_GET(sfp->hdr.count, ARCH_CONVERT)) diff --git a/libxfs/xfs_dir2_data.c b/libxfs/xfs_dir2_data.c index 1f2488241..bd3e8f150 100644 --- a/libxfs/xfs_dir2_data.c +++ b/libxfs/xfs_dir2_data.c @@ -126,7 +126,7 @@ xfs_dir2_data_check( addr = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, (xfs_dir2_data_aoff_t) ((char *)dep - (char *)d)); - hash = xfs_da_hashname((char *)dep->name, dep->namelen); + hash = mp->m_dirnameops->hashname(dep->name, dep->namelen); for (i = 0; i < INT_GET(btp->count, ARCH_CONVERT); i++) { if (INT_GET(lep[i].address, ARCH_CONVERT) == addr && INT_GET(lep[i].hashval, ARCH_CONVERT) == hash) diff --git a/man/man8/mkfs.xfs.8 b/man/man8/mkfs.xfs.8 index 9b7f8bea1..242f28784 100644 --- a/man/man8/mkfs.xfs.8 +++ b/man/man8/mkfs.xfs.8 @@ -302,8 +302,8 @@ bits. .TP .BI maxpct= value This specifies the maximum percentage of space in the filesystem that -can be allocated to inodes. The default -.I value +can be allocated to inodes. The default +.I value is 25% for filesystems under 1TB, 5% for filesystems under 50TB and 1% for filesystems over 50TB. .IP @@ -314,14 +314,14 @@ allocator will avoid these low blocks to accommodate the specified maxpct, so a high value may result in a filesystem with nothing but inodes in a significant portion of the lower blocks of the filesystem. (This restriction is not present when the filesystem is mounted with -the -.I "inode64" +the +.I "inode64" option on 64-bit platforms). .IP Setting the value to 0 means that essentially all of the filesystem can become inode blocks, subject to inode32 restrictions. .IP -This value can be modified with +This value can be modified with .Ixfs_growfs(8) . .TP @@ -340,7 +340,7 @@ filesystem needs to be mountable by a version of IRIX that does not have the inode alignment feature (any release of IRIX before 6.2, and IRIX 6.2 without XFS patches). .TP -.BI attr= value +.BI attr= value This is used to specify the version of extended attribute inline allocation policy to be used. By default, this is 2, which uses an efficient algorithm for managing the available inline inode space @@ -489,10 +489,17 @@ filesystem block size. .BI version= value The naming (directory) version .I value -can be either 1 or 2, defaulting to 2 if unspecified. -With version 2 directories, -the directory block size can be any power of 2 size -from the filesystem block size up to 65536. +can be either 2 or 'ci', defaulting to 2 if unspecified. +With version 2 directories, the directory block size can be +any power of 2 size from the filesystem block size up to 65536. +.IP +The +.B version=ci +option enables ASCII only case-insensitive filename lookup and version +2 directories. Filenames are case-preserving, that is, the names +are stored in directories using the case they were created with. +.IP +Note: Version 1 directories are not supported. .RE .TP .BI \-p " protofile" diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index c07ae1499..ff0d9d010 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -678,6 +678,7 @@ main( xfs_alloc_rec_t *nrec; int nsflag; int nvflag; + int nci; int Nflag; char *p; char *protofile; @@ -720,8 +721,9 @@ main( loginternal = 1; logversion = 2; logagno = logblocks = rtblocks = rtextblocks = 0; - Nflag = nlflag = nsflag = nvflag = 0; - dirblocklog = dirblocksize = dirversion = 0; + Nflag = nlflag = nsflag = nvflag = nci = 0; + dirblocklog = dirblocksize = 0; + dirversion = XFS_DFL_DIR_VERSION; qflag = 0; imaxpct = inodelog = inopblock = isize = 0; iaflag = XFS_IFLAG_ALIGN; @@ -1236,9 +1238,14 @@ main( reqval('n', nopts, N_VERSION); if (nvflag) respec('n', nopts, N_VERSION); - dirversion = atoi(value); - if (dirversion < 1 || dirversion > 2) - illegal(value, "n version"); + if (!strcasecmp(value, "ci")) { + nci = 1; /* ASCII CI mode */ + } else { + dirversion = atoi(value); + if (dirversion != 2) + illegal(value, + "n version"); + } nvflag = 1; break; default: @@ -1412,33 +1419,19 @@ main( logversion = 2; } - if (!nvflag) - dirversion = (nsflag || nlflag) ? 2 : XFS_DFL_DIR_VERSION; - switch (dirversion) { - case 1: - if ((nsflag || nlflag) && dirblocklog != blocklog) { + if (nsflag || nlflag) { + if (dirblocksize < blocksize || + dirblocksize > XFS_MAX_BLOCKSIZE) { fprintf(stderr, _("illegal directory block size %d\n"), dirblocksize); usage(); } - break; - case 2: - if (nsflag || nlflag) { - if (dirblocksize < blocksize || - dirblocksize > XFS_MAX_BLOCKSIZE) { - fprintf(stderr, - _("illegal directory block size %d\n"), - dirblocksize); - usage(); - } - } else { - if (blocksize < (1 << XFS_MIN_REC_DIRSIZE)) - dirblocklog = XFS_MIN_REC_DIRSIZE; - else - dirblocklog = blocklog; - dirblocksize = 1 << dirblocklog; - } - break; + } else { + if (blocksize < (1 << XFS_MIN_REC_DIRSIZE)) + dirblocklog = XFS_MIN_REC_DIRSIZE; + else + dirblocklog = blocklog; + dirblocksize = 1 << dirblocklog; } if (daflag && dasize) { @@ -2024,7 +2017,7 @@ an AG size that is one stripe unit smaller, for example %llu.\n"), " =%-22s sectsz=%-5u attr=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" - "naming =version %-14u bsize=%-6u\n" + "naming =version %-14u bsize=%-6u mixed-case=%c\n" "log =%-22s bsize=%-6d blocks=%lld, version=%d\n" " =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n" "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"), @@ -2033,7 +2026,7 @@ an AG size that is one stripe unit smaller, for example %llu.\n"), "", blocksize, (long long)dblocks, calc_default_imaxpct(blocklog, dblocks), "", dsunit, dswidth, - dirversion, dirversion == 1 ? blocksize : dirblocksize, + dirversion, dirblocksize, nci ? 'N' : 'Y', logfile, 1 << blocklog, (long long)logblocks, logversion, "", lsectorsize, lsunit, lazy_sb_counters, rtfile, rtextblocks << blocklog, @@ -2078,8 +2071,7 @@ an AG size that is one stripe unit smaller, for example %llu.\n"), sbp->sb_qflags = 0; sbp->sb_unit = dsunit; sbp->sb_width = dswidth; - if (dirversion == 2) - sbp->sb_dirblklog = dirblocklog - blocklog; + sbp->sb_dirblklog = dirblocklog - blocklog; if (logversion == 2) { /* This is stored in bytes */ lsunit = (lsunit == 0) ? 1 : XFS_FSB_TO_B(mp, lsunit); sbp->sb_logsunit = lsunit; @@ -2097,12 +2089,13 @@ an AG size that is one stripe unit smaller, for example %llu.\n"), sbp->sb_logsectlog = 0; sbp->sb_logsectsize = 0; } - sbp->sb_features2 = XFS_SB_VERSION2_MKFS(lazy_sb_counters, attrversion == 2, 0); - sbp->sb_versionnum = XFS_SB_VERSION_MKFS( - iaflag, dsunit != 0, - dirversion == 2, logversion == 2, attrversion == 1, - (sectorsize != BBSIZE || lsectorsize != BBSIZE), - sbp->sb_features2 != 0); + sbp->sb_features2 = XFS_SB_VERSION2_MKFS(lazy_sb_counters, + attrversion == 2, 0); + sbp->sb_versionnum = XFS_SB_VERSION_MKFS(iaflag, dsunit != 0, + logversion == 2, attrversion == 1, + (sectorsize != BBSIZE || + lsectorsize != BBSIZE), + nci, sbp->sb_features2 != 0); /* * Due to a structure alignment issue, sb_features2 ended up in one * of two locations, the second "incorrect" location represented by diff --git a/mkfs/xfs_mkfs.h b/mkfs/xfs_mkfs.h index 5cc841cf0..296da9e9d 100644 --- a/mkfs/xfs_mkfs.h +++ b/mkfs/xfs_mkfs.h @@ -20,17 +20,18 @@ #define XFS_DFL_SB_VERSION_BITS \ (XFS_SB_VERSION_NLINKBIT | \ - XFS_SB_VERSION_EXTFLGBIT) + XFS_SB_VERSION_EXTFLGBIT | \ + XFS_SB_VERSION_DIRV2BIT) -#define XFS_SB_VERSION_MKFS(ia,dia,dir2,log2,attr1,sflag,more) (\ - ((ia)||(dia)||(dir2)||(log2)||(attr1)||(sflag)||(more)) ? \ +#define XFS_SB_VERSION_MKFS(ia,dia,log2,attr1,sflag,ci,more) (\ + ((ia)||(dia)||(log2)||(attr1)||(sflag)||(ci)||(more)) ? \ ( XFS_SB_VERSION_4 | \ ((ia) ? XFS_SB_VERSION_ALIGNBIT : 0) | \ ((dia) ? XFS_SB_VERSION_DALIGNBIT : 0) | \ - ((dir2) ? XFS_SB_VERSION_DIRV2BIT : 0) | \ ((log2) ? XFS_SB_VERSION_LOGV2BIT : 0) | \ ((attr1) ? XFS_SB_VERSION_ATTRBIT : 0) | \ ((sflag) ? XFS_SB_VERSION_SECTORBIT : 0) | \ + ((ci) ? XFS_SB_VERSION_BORGBIT : 0) | \ ((more) ? XFS_SB_VERSION_MOREBITSBIT : 0) | \ XFS_DFL_SB_VERSION_BITS | \ 0 ) : XFS_SB_VERSION_1 ) diff --git a/repair/phase6.c b/repair/phase6.c index 36bb8eef7..0495e8598 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -93,6 +93,7 @@ typedef struct freetab { */ static int dir_hash_add( + xfs_mount_t *mp, dir_hash_tab_t *hashtab, __uint32_t addr, xfs_ino_t inum, @@ -113,7 +114,7 @@ dir_hash_add( dup = 0; if (!junk) { - hash = libxfs_da_hashname(name, namelen); + hash = mp->m_dirnameops->hashname(name, namelen); byhash = DIR_HASH_FUNC(hashtab, hash); /* @@ -1589,7 +1590,7 @@ lf_block_dir_entry_check(xfs_mount_t *mp, /* * check for duplicate names in directory. */ - if (!dir_hash_add(hashtab, (da_bno << mp->m_sb.sb_blocklog) + + if (!dir_hash_add(mp, hashtab, (da_bno << mp->m_sb.sb_blocklog) + entry->nameidx, lino, entry->namelen, namest->name)) { nbad++; @@ -2260,7 +2261,7 @@ longform_dir2_entry_check_data( /* * check for duplicate names in directory. */ - if (!dir_hash_add(hashtab, addr, inum, dep->namelen, + if (!dir_hash_add(mp, hashtab, addr, inum, dep->namelen, dep->name)) { nbad++; if (entry_junked(_("entry \"%s\" (ino %llu) in dir " @@ -2870,7 +2871,7 @@ shortform_dir_entry_check(xfs_mount_t *mp, /* * check for duplicate names in directory. */ - if (!dir_hash_add(hashtab, + if (!dir_hash_add(mp, hashtab, (xfs_dir2_dataptr_t)(sf_entry - &sf->list[0]), lino, sf_entry->namelen, sf_entry->name)) { do_warn(_("entry \"%s\" (ino %llu) in dir %llu is a " @@ -3275,7 +3276,7 @@ shortform_dir2_entry_check(xfs_mount_t *mp, /* * check for duplicate names in directory. */ - if (!dir_hash_add(hashtab, (xfs_dir2_dataptr_t) + if (!dir_hash_add(mp, hashtab, (xfs_dir2_dataptr_t) (sfep - XFS_DIR2_SF_FIRSTENTRY(sfp)), lino, sfep->namelen, sfep->name)) { do_warn(_("entry \"%s\" (ino %llu) in dir %llu is a "