From: Barry Naujok Date: Mon, 8 Sep 2008 06:18:43 +0000 (+0000) Subject: Update xfsprogs to latest kernel headers and functions X-Git-Tag: v3.0.0~56 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5e656dbb84af1f96564b93ea03249772825520f2;p=thirdparty%2Fxfsprogs-dev.git Update xfsprogs to latest kernel headers and functions Merge of master-melb:xfs-cmds:32070a by kenmcd. --- diff --git a/Makefile b/Makefile index 7882ee2c7..f2a38764a 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ LDIRT = config.log .dep config.status config.cache confdefs.h conftest* \ Logs/* built .census install.* install-dev.* *.gz SUBDIRS = include libxfs libxlog libxcmd libhandle libdisk \ - copy db fsck growfs io logprint mkfs quota mdrestore repair rtcp \ + copy db estimate fsck growfs io logprint mkfs quota mdrestore repair rtcp \ m4 man doc po debian build default: $(CONFIGURE) @@ -59,6 +59,9 @@ install: default install-dev: default $(SUBDIRS_MAKERULE) +install-qa: install + $(SUBDIRS_MAKERULE) + realclean distclean: clean rm -f $(LDIRT) $(CONFIGURE) rm -rf autom4te.cache Logs diff --git a/VERSION b/VERSION index 4cb760756..665924b18 100644 --- a/VERSION +++ b/VERSION @@ -1,7 +1,7 @@ # # This file is used by configure to get version information # -PKG_MAJOR=2 -PKG_MINOR=10 -PKG_REVISION=1 +PKG_MAJOR=3 +PKG_MINOR=0 +PKG_REVISION=0 PKG_BUILD=1 diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c index 4e3f2aa8c..0fbf71019 100644 --- a/copy/xfs_copy.c +++ b/copy/xfs_copy.c @@ -236,7 +236,7 @@ killall(void) } void -handler() +handler(int sig) { pid_t pid = getpid(); int status, i; @@ -453,13 +453,13 @@ read_ag_header(int fd, xfs_agnumber_t agno, wbuf *buf, ag_header_t *ag, read_wbuf(fd, buf, mp); ASSERT(buf->length >= length); - ag->xfs_sb = (xfs_sb_t *) (buf->data + diff); - ASSERT(INT_GET(ag->xfs_sb->sb_magicnum, ARCH_CONVERT)==XFS_SB_MAGIC); + ag->xfs_sb = (xfs_dsb_t *) (buf->data + diff); + ASSERT(be32_to_cpu(ag->xfs_sb->sb_magicnum) == XFS_SB_MAGIC); ag->xfs_agf = (xfs_agf_t *) (buf->data + diff + sectorsize); - ASSERT(INT_GET(ag->xfs_agf->agf_magicnum, ARCH_CONVERT)==XFS_AGF_MAGIC); - ag->xfs_agi = (xfs_agi_t *) (buf->data + diff + 2*sectorsize); - ASSERT(INT_GET(ag->xfs_agi->agi_magicnum, ARCH_CONVERT)==XFS_AGI_MAGIC); - ag->xfs_agfl = (xfs_agfl_t *) (buf->data + diff + 3*sectorsize); + ASSERT(be32_to_cpu(ag->xfs_agf->agf_magicnum) == XFS_AGF_MAGIC); + ag->xfs_agi = (xfs_agi_t *) (buf->data + diff + 2 * sectorsize); + ASSERT(be32_to_cpu(ag->xfs_agi->agi_magicnum) == XFS_AGI_MAGIC); + ag->xfs_agfl = (xfs_agfl_t *) (buf->data + diff + 3 * sectorsize); } @@ -677,7 +677,7 @@ main(int argc, char **argv) sbp = libxfs_readbuf(xargs.ddev, XFS_SB_DADDR, 1, 0); memset(&mbuf, 0, sizeof(xfs_mount_t)); sb = &mbuf.m_sb; - libxfs_xlate_sb(XFS_BUF_PTR(sbp), sb, 1, XFS_SB_ALL_BITS); + libxfs_sb_from_disk(sb, XFS_BUF_TO_SBP(sbp)); mp = libxfs_mount(&mbuf, sb, xargs.ddev, xargs.logdev, xargs.rtdev, 1); if (mp == NULL) { @@ -797,7 +797,7 @@ main(int argc, char **argv) } } } else { - char *lb[XFS_MAX_SECTORSIZE] = { 0 }; + char *lb[XFS_MAX_SECTORSIZE] = { NULL }; off64_t off; /* ensure device files are sufficiently large */ @@ -908,7 +908,7 @@ main(int argc, char **argv) /* set the in_progress bit for the first AG */ if (agno == 0) - INT_SET(ag_hdr.xfs_sb->sb_inprogress, ARCH_CONVERT, 1); + ag_hdr.xfs_sb->sb_inprogress = 1; /* save what we need (agf) in the btree buffer */ @@ -922,16 +922,14 @@ main(int argc, char **argv) /* traverse btree until we get to the leftmost leaf node */ - bno = INT_GET(ag_hdr.xfs_agf->agf_roots[XFS_BTNUM_BNOi], - ARCH_CONVERT); + bno = be32_to_cpu(ag_hdr.xfs_agf->agf_roots[XFS_BTNUM_BNOi]); current_level = 0; - btree_levels = INT_GET( - ag_hdr.xfs_agf->agf_levels[XFS_BTNUM_BNOi], - ARCH_CONVERT); + btree_levels = be32_to_cpu(ag_hdr.xfs_agf-> + agf_levels[XFS_BTNUM_BNOi]); ag_end = XFS_AGB_TO_DADDR(mp, agno, - INT_GET(ag_hdr.xfs_agf->agf_length,ARCH_CONVERT) - 1) - + source_blocksize/BBSIZE; + be32_to_cpu(ag_hdr.xfs_agf->agf_length) - 1) + + source_blocksize / BBSIZE; for (;;) { /* none of this touches the w_buf buffer */ @@ -948,16 +946,14 @@ main(int argc, char **argv) block = (xfs_alloc_block_t *) ((char *) btree_buf.data + pos - btree_buf.position); - ASSERT(INT_GET(block->bb_magic,ARCH_CONVERT) == - XFS_ABTB_MAGIC); + ASSERT(be32_to_cpu(block->bb_magic) == XFS_ABTB_MAGIC); - if (INT_GET(block->bb_level,ARCH_CONVERT) == 0) + if (be16_to_cpu(block->bb_level) == 0) break; - ptr = XFS_BTREE_PTR_ADDR(sourceb_blocksize, xfs_alloc, - block, 1, mp->m_alloc_mxr[1]), - - bno = INT_GET(ptr[0], ARCH_CONVERT); + ptr = XFS_BTREE_PTR_ADDR(xfs_alloc, block, 1, + mp->m_alloc_mxr[1]); + bno = be32_to_cpu(ptr[0]); } /* align first data copy but don't overwrite ag header */ @@ -972,7 +968,7 @@ main(int argc, char **argv) /* handle the rest of the ag */ for (;;) { - if (INT_GET(block->bb_level,ARCH_CONVERT) != 0) { + if (be16_to_cpu(block->bb_level) != 0) { do_log( _("WARNING: source filesystem inconsistent.\n")); do_log( @@ -980,12 +976,9 @@ main(int argc, char **argv) exit(1); } - rec_ptr = XFS_BTREE_REC_ADDR(source_blocksize, - xfs_alloc, block, 1, mp->m_alloc_mxr[0]); - - for (i = 0; - i < INT_GET(block->bb_numrecs,ARCH_CONVERT); - i++, rec_ptr++) { + rec_ptr = XFS_BTREE_REC_ADDR(xfs_alloc, block, 1); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); + i++, rec_ptr++) { /* calculate in daddr's */ begin = next_begin; @@ -1004,9 +997,9 @@ main(int argc, char **argv) * range bigger than required */ - sizeb = XFS_AGB_TO_DADDR(mp, agno, - INT_GET(rec_ptr->ar_startblock, - ARCH_CONVERT)) - begin; + sizeb = XFS_AGB_TO_DADDR(mp, agno, + be32_to_cpu(rec_ptr->ar_startblock)) - + begin; size = roundup(sizeb < 0) { /* copy extent */ @@ -1042,24 +1035,20 @@ main(int argc, char **argv) /* round next starting point down */ new_begin = XFS_AGB_TO_DADDR(mp, agno, - INT_GET(rec_ptr->ar_startblock, - ARCH_CONVERT) + - INT_GET(rec_ptr->ar_blockcount, - ARCH_CONVERT)); + be32_to_cpu(rec_ptr->ar_startblock) + + be32_to_cpu(rec_ptr->ar_blockcount)); next_begin = rounddown(new_begin, w_buf.min_io_size >> BBSHIFT); } - if (INT_GET(block->bb_rightsib,ARCH_CONVERT) == - NULLAGBLOCK) + if (be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK) break; /* read in next btree record block */ btree_buf.position = pos = (xfs_off_t) - XFS_AGB_TO_DADDR(mp, agno, - INT_GET(block->bb_rightsib, - ARCH_CONVERT)) << BBSHIFT; + XFS_AGB_TO_DADDR(mp, agno, be32_to_cpu( + block->bb_rightsib)) << BBSHIFT; btree_buf.length = source_blocksize; /* let read_wbuf handle alignment */ @@ -1069,8 +1058,7 @@ main(int argc, char **argv) block = (xfs_alloc_block_t *) ((char *) btree_buf.data + pos - btree_buf.position); - ASSERT(INT_GET(block->bb_magic,ARCH_CONVERT) == - XFS_ABTB_MAGIC); + ASSERT(be32_to_cpu(block->bb_magic) == XFS_ABTB_MAGIC); } /* @@ -1208,7 +1196,7 @@ write_log_header(int fd, wbuf *buf, xfs_mount_t *mp) } offset = libxfs_log_header(p, &buf->owner->uuid, - XFS_SB_VERSION_HASLOGV2(&mp->m_sb) ? 2 : 1, + xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, mp->m_sb.sb_logsunit, XLOG_FMT, next_log_chunk, buf); do_write(buf->owner); diff --git a/copy/xfs_copy.h b/copy/xfs_copy.h index f23927daa..e76b937a3 100644 --- a/copy/xfs_copy.h +++ b/copy/xfs_copy.h @@ -30,7 +30,7 @@ * each of which is an AG and has an ag_header at the beginning. */ typedef struct ag_header { - xfs_sb_t *xfs_sb; /* superblock for filesystem or AG */ + xfs_dsb_t *xfs_sb; /* superblock for filesystem or AG */ xfs_agf_t *xfs_agf; /* free space info */ xfs_agi_t *xfs_agi; /* free inode info */ xfs_agfl_t *xfs_agfl; /* AG freelist */ diff --git a/db/attr.c b/db/attr.c index bc2f65c3e..f15d40817 100644 --- a/db/attr.c +++ b/db/attr.c @@ -158,12 +158,9 @@ attr_leaf_entries_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->hdr.info.magic, ARCH_CONVERT) - != XFS_ATTR_LEAF_MAGIC) { + if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; - } - - return INT_GET(block->hdr.count, ARCH_CONVERT); + return be16_to_cpu(block->hdr.count); } /*ARGSUSED*/ @@ -176,8 +173,7 @@ attr_leaf_hdr_count( ASSERT(startoff == 0); block = obj; - return INT_GET(block->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC; + return be16_to_cpu(block->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC; } static int @@ -193,14 +189,12 @@ attr_leaf_name_local_count( ASSERT(bitoffs(startoff) == 0); off = byteize(startoff); block = obj; - if (INT_GET(block->hdr.info.magic, ARCH_CONVERT) - != XFS_ATTR_LEAF_MAGIC) + if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; - for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) { + for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { e = &block->entries[i]; - if (INT_GET(e->nameidx, ARCH_CONVERT) == off) - return (INT_GET(e->flags, ARCH_CONVERT) - & XFS_ATTR_LOCAL) != 0; + if (be16_to_cpu(e->nameidx) == off) + return (e->flags & XFS_ATTR_LOCAL) != 0; } return 0; } @@ -219,15 +213,14 @@ attr_leaf_name_local_name_count( ASSERT(bitoffs(startoff) == 0); off = byteize(startoff); block = obj; - if (INT_GET(block->hdr.info.magic, ARCH_CONVERT) - != XFS_ATTR_LEAF_MAGIC) + if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; - for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) { + for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { e = &block->entries[i]; - if (INT_GET(e->nameidx, ARCH_CONVERT) == off) { - if (INT_GET(e->flags, ARCH_CONVERT) & XFS_ATTR_LOCAL) { + if (be16_to_cpu(e->nameidx) == off) { + if (e->flags & XFS_ATTR_LOCAL) { l = XFS_ATTR_LEAF_NAME_LOCAL(block, i); - return INT_GET(l->namelen, ARCH_CONVERT); + return l->namelen; } else return 0; } @@ -249,15 +242,14 @@ attr_leaf_name_local_value_count( ASSERT(bitoffs(startoff) == 0); off = byteize(startoff); block = obj; - if (INT_GET(block->hdr.info.magic, ARCH_CONVERT) - != XFS_ATTR_LEAF_MAGIC) + if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; - for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) { + for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { e = &block->entries[i]; - if (INT_GET(e->nameidx, ARCH_CONVERT) == off) { - if (INT_GET(e->flags, ARCH_CONVERT) & XFS_ATTR_LOCAL) { + if (be16_to_cpu(e->nameidx) == off) { + if (e->flags & XFS_ATTR_LOCAL) { l = XFS_ATTR_LEAF_NAME_LOCAL(block, i); - return INT_GET(l->valuelen, ARCH_CONVERT); + return be16_to_cpu(l->valuelen); } else return 0; } @@ -282,16 +274,16 @@ attr_leaf_name_local_value_offset( ASSERT(bitoffs(startoff) == 0); off = byteize(startoff); block = obj; - if (INT_GET(block->hdr.info.magic, ARCH_CONVERT) - != XFS_ATTR_LEAF_MAGIC) + if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; - for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) { + for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { e = &block->entries[i]; - if (INT_GET(e->nameidx, ARCH_CONVERT) == off) - break; + if (be16_to_cpu(e->nameidx) == off) + break; } - if (i>=INT_GET(block->hdr.count, ARCH_CONVERT)) return 0; + if (i >= be16_to_cpu(block->hdr.count)) + return 0; l = XFS_ATTR_LEAF_NAME_LOCAL(block, i); vp = (char *)&l->nameval[l->namelen]; @@ -311,13 +303,12 @@ attr_leaf_name_remote_count( ASSERT(bitoffs(startoff) == 0); off = byteize(startoff); block = obj; - if (INT_GET(block->hdr.info.magic, ARCH_CONVERT) - != XFS_ATTR_LEAF_MAGIC) + if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; - for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) { + for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { e = &block->entries[i]; - if (INT_GET(e->nameidx, ARCH_CONVERT) == off) - return (INT_GET(e->flags, ARCH_CONVERT) & XFS_ATTR_LOCAL) == 0; + if (be16_to_cpu(e->nameidx) == off) + return (e->flags & XFS_ATTR_LOCAL) == 0; } return 0; } @@ -336,15 +327,14 @@ attr_leaf_name_remote_name_count( ASSERT(bitoffs(startoff) == 0); off = byteize(startoff); block = obj; - if (INT_GET(block->hdr.info.magic, ARCH_CONVERT) - != XFS_ATTR_LEAF_MAGIC) + if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; - for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) { + for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { e = &block->entries[i]; - if (INT_GET(e->nameidx, ARCH_CONVERT) == off) { - if (!(INT_GET(e->flags, ARCH_CONVERT) & XFS_ATTR_LOCAL)) { + if (be16_to_cpu(e->nameidx) == off) { + if (!(e->flags & XFS_ATTR_LOCAL)) { r = XFS_ATTR_LEAF_NAME_REMOTE(block, i); - return INT_GET(r->namelen, ARCH_CONVERT); + return r->namelen; } else return 0; } @@ -366,17 +356,16 @@ attr_leaf_name_size( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->hdr.info.magic, ARCH_CONVERT) - != XFS_ATTR_LEAF_MAGIC) + if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; e = &block->entries[idx]; - if (INT_GET(e->flags, ARCH_CONVERT) & XFS_ATTR_LOCAL) { + if (e->flags & XFS_ATTR_LOCAL) { l = XFS_ATTR_LEAF_NAME_LOCAL(block, idx); - return (int)bitize(XFS_ATTR_LEAF_ENTSIZE_LOCAL(INT_GET(l->namelen, ARCH_CONVERT), - INT_GET(l->valuelen, ARCH_CONVERT))); + return (int)bitize(XFS_ATTR_LEAF_ENTSIZE_LOCAL(l->namelen, + be16_to_cpu(l->valuelen))); } else { r = XFS_ATTR_LEAF_NAME_REMOTE(block, idx); - return (int)bitize(XFS_ATTR_LEAF_ENTSIZE_REMOTE(INT_GET(r->namelen, ARCH_CONVERT))); + return (int)bitize(XFS_ATTR_LEAF_ENTSIZE_REMOTE(r->namelen)); } } @@ -390,10 +379,9 @@ attr_leaf_nvlist_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->hdr.info.magic, ARCH_CONVERT) - != XFS_ATTR_LEAF_MAGIC) + if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; - return INT_GET(block->hdr.count, ARCH_CONVERT); + return be16_to_cpu(block->hdr.count); } /*ARGSUSED*/ @@ -409,7 +397,7 @@ attr_leaf_nvlist_offset( ASSERT(startoff == 0); block = obj; e = &block->entries[idx]; - return bitize(INT_GET(e->nameidx, ARCH_CONVERT)); + return bitize(be16_to_cpu(e->nameidx)); } /*ARGSUSED*/ @@ -422,10 +410,9 @@ attr_node_btree_count( ASSERT(startoff == 0); /* this is a base structure */ block = obj; - if (INT_GET(block->hdr.info.magic, ARCH_CONVERT) - != XFS_DA_NODE_MAGIC) + if (be16_to_cpu(block->hdr.info.magic) != XFS_DA_NODE_MAGIC) return 0; - return INT_GET(block->hdr.count, ARCH_CONVERT); + return be16_to_cpu(block->hdr.count); } /*ARGSUSED*/ @@ -438,8 +425,7 @@ attr_node_hdr_count( ASSERT(startoff == 0); block = obj; - return INT_GET(block->hdr.info.magic, ARCH_CONVERT) - == XFS_DA_NODE_MAGIC; + return be16_to_cpu(block->hdr.info.magic) == XFS_DA_NODE_MAGIC; } /*ARGSUSED*/ diff --git a/db/attrset.c b/db/attrset.c index c96ea3eb8..1936a5cb2 100644 --- a/db/attrset.c +++ b/db/attrset.c @@ -158,7 +158,7 @@ attr_set_f( goto out; } - if (libxfs_attr_set_int(ip, name, namelen, value, valuelen, flags)) { + if (libxfs_attr_set(ip, name, value, valuelen, flags)) { dbprintf(_("failed to set attr %s on inode %llu\n"), name, (unsigned long long)iocur_top->ino); goto out; @@ -233,7 +233,7 @@ attr_remove_f( goto out; } - if (libxfs_attr_remove_int(ip, name, namelen, flags)) { + if (libxfs_attr_remove(ip, name, flags)) { dbprintf(_("failed to remove attr %s from inode %llu\n"), name, (unsigned long long)iocur_top->ino); goto out; diff --git a/db/bit.c b/db/bit.c index dd1a3c9a2..ca57d3156 100644 --- a/db/bit.c +++ b/db/bit.c @@ -80,32 +80,28 @@ getbitval( bit = bitoffs(bitoff); signext = (flags & BVSIGNED) != 0; z4 = ((__psint_t)p & 0xf) == 0 && bit == 0; - if (nbits == 64 && z4) { - if (signext) - return (__int64_t)INT_GET(*(__int64_t *)p, ARCH_CONVERT); - else - return (__int64_t)INT_GET(*(__uint64_t *)p, ARCH_CONVERT); - } + if (nbits == 64 && z4) + return be64_to_cpu(*(__be64 *)p); z3 = ((__psint_t)p & 0x7) == 0 && bit == 0; if (nbits == 32 && z3) { if (signext) - return (__int64_t)INT_GET(*(__int32_t *)p, ARCH_CONVERT); + return (__s32)be32_to_cpu(*(__be32 *)p); else - return (__int64_t)INT_GET(*(__uint32_t *)p, ARCH_CONVERT); + return (__u32)be32_to_cpu(*(__be32 *)p); } z2 = ((__psint_t)p & 0x3) == 0 && bit == 0; if (nbits == 16 && z2) { if (signext) - return (__int64_t)INT_GET(*(__int16_t *)p, ARCH_CONVERT); + return (__s16)be16_to_cpu(*(__be16 *)p); else - return (__int64_t)INT_GET(*(__uint16_t *)p, ARCH_CONVERT); + return (__u16)be16_to_cpu(*(__be16 *)p); } z1 = ((__psint_t)p & 0x1) == 0 && bit == 0; if (nbits == 8 && z1) { if (signext) - return (__int64_t)INT_GET(*(__int8_t *)p, ARCH_CONVERT); + return *(__s8 *)p; else - return (__int64_t)INT_GET(*(__uint8_t *)p, ARCH_CONVERT); + return *(__u8 *)p; } diff --git a/db/bmap.c b/db/bmap.c index 934b42c87..2fc81a32d 100644 --- a/db/bmap.c +++ b/db/bmap.c @@ -91,35 +91,29 @@ bmap( bno = NULLFSBLOCK; rblock = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); fsize = XFS_DFORK_SIZE(dip, mp, whichfork); - pp = XFS_BTREE_PTR_ADDR(fsize, xfs_bmdr, rblock, 1, + pp = XFS_BTREE_PTR_ADDR(xfs_bmdr, rblock, 1, XFS_BTREE_BLOCK_MAXRECS(fsize, xfs_bmdr, 0)); - kp = XFS_BTREE_KEY_ADDR(fsize, xfs_bmdr, rblock, 1, - XFS_BTREE_BLOCK_MAXRECS(fsize, xfs_bmdr, 0)); - bno = select_child(curoffset, kp, pp, INT_GET(rblock->bb_numrecs, ARCH_CONVERT)); + kp = XFS_BTREE_KEY_ADDR(xfs_bmdr, rblock, 1); + bno = select_child(curoffset, kp, pp, + be16_to_cpu(rblock->bb_numrecs)); for (;;) { set_cur(&typtab[typ], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_IGN, NULL); block = (xfs_bmbt_block_t *)iocur_top->data; - if (INT_GET(block->bb_level, ARCH_CONVERT) == 0) + if (be16_to_cpu(block->bb_level) == 0) break; - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, - block, 1, - XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, - xfs_bmbt, 0)); - kp = XFS_BTREE_KEY_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, - block, 1, + pp = XFS_BTREE_PTR_ADDR(xfs_bmbt, block, 1, XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, xfs_bmbt, 0)); + kp = XFS_BTREE_KEY_ADDR(xfs_bmbt, block, 1); bno = select_child(curoffset, kp, pp, - INT_GET(block->bb_numrecs, ARCH_CONVERT)); + be16_to_cpu(block->bb_numrecs)); } for (;;) { - nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT); - nextents = INT_GET(block->bb_numrecs, ARCH_CONVERT); - xp = (xfs_bmbt_rec_64_t *)XFS_BTREE_REC_ADDR( - mp->m_sb.sb_blocksize, xfs_bmbt, block, 1, - XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, - xfs_bmbt, 1)); + nextbno = be64_to_cpu(block->bb_rightsib); + nextents = be16_to_cpu(block->bb_numrecs); + xp = (xfs_bmbt_rec_64_t *)XFS_BTREE_REC_ADDR(xfs_bmbt, + block, 1); for (ep = xp; ep < &xp[nextents] && n < nex; ep++) { if (!bmap_one_extent(ep, &curoffset, eoffset, &n, bep)) { @@ -179,9 +173,9 @@ bmap_f( push_cur(); set_cur_inode(iocur_top->ino); dip = iocur_top->data; - if (INT_GET(dip->di_core.di_nextents, ARCH_CONVERT)) + if (be32_to_cpu(dip->di_core.di_nextents)) dfork = 1; - if (INT_GET(dip->di_core.di_anextents, ARCH_CONVERT)) + if (be16_to_cpu(dip->di_core.di_anextents)) afork = 1; pop_cur(); } @@ -334,14 +328,14 @@ select_child( int i; for (i = 0; i < nrecs; i++) { - if (INT_GET(kp[i].br_startoff, ARCH_CONVERT) == off) - return INT_GET(pp[i], ARCH_CONVERT); - if (INT_GET(kp[i].br_startoff, ARCH_CONVERT) > off) { + if (be64_to_cpu(kp[i].br_startoff) == off) + return be64_to_cpu(pp[i]); + if (be64_to_cpu(kp[i].br_startoff) > off) { if (i == 0) - return INT_GET(pp[i], ARCH_CONVERT); + return be64_to_cpu(pp[i]); else - return INT_GET(pp[i - 1], ARCH_CONVERT); + return be64_to_cpu(pp[i - 1]); } } - return INT_GET(pp[nrecs - 1], ARCH_CONVERT); + return be64_to_cpu(pp[nrecs - 1]); } diff --git a/db/bmapbt.c b/db/bmapbt.c index 8c491b94a..44ecabdb4 100644 --- a/db/bmapbt.c +++ b/db/bmapbt.c @@ -88,6 +88,23 @@ const field_t bmapbtd_key_flds[] = { { NULL } }; +#ifndef XFS_NATIVE_HOST + +#define BMBT_EXNTFLAG_BITOFF 0 +#define BMBT_STARTOFF_BITOFF (BMBT_EXNTFLAG_BITOFF + BMBT_EXNTFLAG_BITLEN) +#define BMBT_STARTBLOCK_BITOFF (BMBT_STARTOFF_BITOFF + BMBT_STARTOFF_BITLEN) +#define BMBT_BLOCKCOUNT_BITOFF \ + (BMBT_STARTBLOCK_BITOFF + BMBT_STARTBLOCK_BITLEN) + +#else + +#define BMBT_EXNTFLAG_BITOFF 63 +#define BMBT_STARTOFF_BITOFF (BMBT_EXNTFLAG_BITOFF - BMBT_STARTOFF_BITLEN) +#define BMBT_STARTBLOCK_BITOFF 85 /* 128 - 43 (other 9 is in first word) */ +#define BMBT_BLOCKCOUNT_BITOFF 64 /* Start of second 64 bit container */ + +#endif /* XFS_NATIVE_HOST */ + const field_t bmapbta_rec_flds[] = { { "startoff", FLDT_CFILEOFFA, OI(BMBT_STARTOFF_BITOFF), C1, 0, TYP_ATTR }, @@ -120,9 +137,9 @@ bmapbta_key_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->bb_level, ARCH_CONVERT) == 0) + if (be16_to_cpu(block->bb_level) == 0) return 0; - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + return be16_to_cpu(block->bb_numrecs); } static int @@ -136,9 +153,8 @@ bmapbta_key_offset( ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - kp = XFS_BTREE_KEY_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, idx, - XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, xfs_bmbt, 0)); + ASSERT(be16_to_cpu(block->bb_level) > 0); + kp = XFS_BTREE_KEY_ADDR(xfs_bmbt, block, idx); return bitize((int)((char *)kp - (char *)block)); } @@ -151,9 +167,9 @@ bmapbta_ptr_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->bb_level, ARCH_CONVERT) == 0) + if (be16_to_cpu(block->bb_level) == 0) return 0; - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + return be16_to_cpu(block->bb_numrecs); } static int @@ -167,8 +183,8 @@ bmapbta_ptr_offset( ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, idx, + ASSERT(be16_to_cpu(block->bb_level) > 0); + pp = XFS_BTREE_PTR_ADDR(xfs_bmbt, block, idx, XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, xfs_bmbt, 0)); return bitize((int)((char *)pp - (char *)block)); } @@ -182,9 +198,9 @@ bmapbta_rec_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->bb_level, ARCH_CONVERT) > 0) + if (be16_to_cpu(block->bb_level) > 0) return 0; - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + return be16_to_cpu(block->bb_numrecs); } static int @@ -198,9 +214,8 @@ bmapbta_rec_offset( ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) == 0); - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, idx, - XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, xfs_bmbt, 1)); + ASSERT(be16_to_cpu(block->bb_level) == 0); + rp = XFS_BTREE_REC_ADDR(xfs_bmbt, block, idx); return bitize((int)((char *)rp - (char *)block)); } @@ -222,9 +237,9 @@ bmapbtd_key_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->bb_level, ARCH_CONVERT) == 0) + if (be16_to_cpu(block->bb_level) == 0) return 0; - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + return be16_to_cpu(block->bb_numrecs); } static int @@ -238,9 +253,8 @@ bmapbtd_key_offset( ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - kp = XFS_BTREE_KEY_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, idx, - XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, xfs_bmbt, 0)); + ASSERT(be16_to_cpu(block->bb_level) > 0); + kp = XFS_BTREE_KEY_ADDR(xfs_bmbt, block, idx); return bitize((int)((char *)kp - (char *)block)); } @@ -253,9 +267,9 @@ bmapbtd_ptr_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->bb_level, ARCH_CONVERT) == 0) + if (be16_to_cpu(block->bb_level) == 0) return 0; - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + return be16_to_cpu(block->bb_numrecs); } static int @@ -269,8 +283,8 @@ bmapbtd_ptr_offset( ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, idx, + ASSERT(be16_to_cpu(block->bb_level) > 0); + pp = XFS_BTREE_PTR_ADDR(xfs_bmbt, block, idx, XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, xfs_bmbt, 0)); return bitize((int)((char *)pp - (char *)block)); } @@ -284,9 +298,9 @@ bmapbtd_rec_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->bb_level, ARCH_CONVERT) > 0) + if (be16_to_cpu(block->bb_level) > 0) return 0; - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + return be16_to_cpu(block->bb_numrecs); } static int @@ -300,9 +314,8 @@ bmapbtd_rec_offset( ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) == 0); - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, idx, - XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, xfs_bmbt, 1)); + ASSERT(be16_to_cpu(block->bb_level) == 0); + rp = XFS_BTREE_REC_ADDR(xfs_bmbt, block, idx); return bitize((int)((char *)rp - (char *)block)); } diff --git a/db/bmroot.c b/db/bmroot.c index a08bd717d..d4b7e2cc0 100644 --- a/db/bmroot.c +++ b/db/bmroot.c @@ -80,8 +80,8 @@ bmroota_key_count( ASSERT(obj == iocur_top->data); block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); ASSERT(XFS_DFORK_Q(dip) && (char *)block == XFS_DFORK_APTR(dip)); - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + ASSERT(be16_to_cpu(block->bb_level) > 0); + return be16_to_cpu(block->bb_numrecs); } static int @@ -100,9 +100,8 @@ bmroota_key_offset( dip = obj; block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); ASSERT(XFS_DFORK_Q(dip) && (char *)block == XFS_DFORK_APTR(dip)); - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - kp = XFS_BTREE_KEY_ADDR(iocur_top->len, xfs_bmdr, block, idx, - XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_ASIZE(dip, mp), xfs_bmdr, 0)); + ASSERT(be16_to_cpu(block->bb_level) > 0); + kp = XFS_BTREE_KEY_ADDR(xfs_bmdr, block, idx); return bitize((int)((char *)kp - (char *)block)); } @@ -120,8 +119,8 @@ bmroota_ptr_count( ASSERT(obj == iocur_top->data); block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); ASSERT(XFS_DFORK_Q(dip) && (char *)block == XFS_DFORK_APTR(dip)); - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + ASSERT(be16_to_cpu(block->bb_level) > 0); + return be16_to_cpu(block->bb_numrecs); } static int @@ -139,8 +138,8 @@ bmroota_ptr_offset( dip = obj; block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); ASSERT(XFS_DFORK_Q(dip) && (char *)block == XFS_DFORK_APTR(dip)); - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - pp = XFS_BTREE_PTR_ADDR(iocur_top->len, xfs_bmdr, block, idx, + ASSERT(be16_to_cpu(block->bb_level) > 0); + pp = XFS_BTREE_PTR_ADDR(xfs_bmdr, block, idx, XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_ASIZE(dip, mp), xfs_bmdr, 0)); return bitize((int)((char *)pp - (char *)block)); } @@ -181,8 +180,8 @@ bmrootd_key_count( ASSERT(obj == iocur_top->data); block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); ASSERT((char *)block == XFS_DFORK_DPTR(dip)); - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + ASSERT(be16_to_cpu(block->bb_level) > 0); + return be16_to_cpu(block->bb_numrecs); } static int @@ -199,9 +198,8 @@ bmrootd_key_offset( ASSERT(obj == iocur_top->data); dip = obj; block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - kp = XFS_BTREE_KEY_ADDR(iocur_top->len, xfs_bmdr, block, idx, - XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_DSIZE(dip, mp), xfs_bmdr, 0)); + ASSERT(be16_to_cpu(block->bb_level) > 0); + kp = XFS_BTREE_KEY_ADDR(xfs_bmdr, block, idx); return bitize((int)((char *)kp - (char *)block)); } @@ -219,8 +217,8 @@ bmrootd_ptr_count( ASSERT(obj == iocur_top->data); block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); ASSERT((char *)block == XFS_DFORK_DPTR(dip)); - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + ASSERT(be16_to_cpu(block->bb_level) > 0); + return be16_to_cpu(block->bb_numrecs); } static int @@ -237,8 +235,8 @@ bmrootd_ptr_offset( ASSERT(obj == iocur_top->data); dip = obj; block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - pp = XFS_BTREE_PTR_ADDR(iocur_top->len, xfs_bmdr, block, idx, + ASSERT(be16_to_cpu(block->bb_level) > 0); + pp = XFS_BTREE_PTR_ADDR(xfs_bmdr, block, idx, XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_DSIZE(dip, mp), xfs_bmdr, 0)); return bitize((int)((char *)pp - (char *)block)); } diff --git a/db/bnobt.c b/db/bnobt.c index 142ada623..e1d664c68 100644 --- a/db/bnobt.c +++ b/db/bnobt.c @@ -78,9 +78,9 @@ bnobt_key_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->bb_level, ARCH_CONVERT) == 0) + if (be16_to_cpu(block->bb_level) == 0) return 0; - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + return be16_to_cpu(block->bb_numrecs); } static int @@ -94,9 +94,8 @@ bnobt_key_offset( ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - kp = XFS_BTREE_KEY_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, idx, - XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, xfs_alloc, 0)); + ASSERT(be16_to_cpu(block->bb_level) > 0); + kp = XFS_BTREE_KEY_ADDR(xfs_alloc, block, idx); return bitize((int)((char *)kp - (char *)block)); } @@ -109,9 +108,9 @@ bnobt_ptr_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->bb_level, ARCH_CONVERT) == 0) + if (be16_to_cpu(block->bb_level) == 0) return 0; - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + return be16_to_cpu(block->bb_numrecs); } static int @@ -125,8 +124,8 @@ bnobt_ptr_offset( ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, idx, + ASSERT(be16_to_cpu(block->bb_level) > 0); + pp = XFS_BTREE_PTR_ADDR(xfs_alloc, block, idx, XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, xfs_alloc, 0)); return bitize((int)((char *)pp - (char *)block)); } @@ -140,9 +139,9 @@ bnobt_rec_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->bb_level, ARCH_CONVERT) > 0) + if (be16_to_cpu(block->bb_level) > 0) return 0; - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + return be16_to_cpu(block->bb_numrecs); } static int @@ -156,9 +155,8 @@ bnobt_rec_offset( ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) == 0); - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, idx, - XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, xfs_alloc, 1)); + ASSERT(be16_to_cpu(block->bb_level) == 0); + rp = XFS_BTREE_REC_ADDR(xfs_alloc, block, idx); return bitize((int)((char *)rp - (char *)block)); } diff --git a/db/check.c b/db/check.c index f18dbf82c..74147e644 100644 --- a/db/check.c +++ b/db/check.c @@ -102,7 +102,8 @@ typedef struct freetab { typedef struct dirhash { struct dirhash *next; - xfs_dir2_leaf_entry_t entry; + __u32 hashval; + __u32 address; int seen; } dirhash_t; #define DIR_HASH_SIZE 1024 @@ -879,28 +880,28 @@ blockget_f( error++; } if ((sbversion & XFS_SB_VERSION_ATTRBIT) && - !XFS_SB_VERSION_HASATTR(&mp->m_sb)) { + !xfs_sb_version_hasattr(&mp->m_sb)) { if (!sflag) dbprintf("sb versionnum missing attr bit %x\n", XFS_SB_VERSION_ATTRBIT); error++; } if ((sbversion & XFS_SB_VERSION_NLINKBIT) && - !XFS_SB_VERSION_HASNLINK(&mp->m_sb)) { + !xfs_sb_version_hasnlink(&mp->m_sb)) { if (!sflag) dbprintf("sb versionnum missing nlink bit %x\n", XFS_SB_VERSION_NLINKBIT); error++; } if ((sbversion & XFS_SB_VERSION_QUOTABIT) && - !XFS_SB_VERSION_HASQUOTA(&mp->m_sb)) { + !xfs_sb_version_hasquota(&mp->m_sb)) { if (!sflag) dbprintf("sb versionnum missing quota bit %x\n", XFS_SB_VERSION_QUOTABIT); error++; } if (!(sbversion & XFS_SB_VERSION_ALIGNBIT) && - XFS_SB_VERSION_HASALIGN(&mp->m_sb)) { + xfs_sb_version_hasalign(&mp->m_sb)) { if (!sflag) dbprintf("sb versionnum extra align bit %x\n", XFS_SB_VERSION_ALIGNBIT); @@ -1624,8 +1625,8 @@ dir_hash_add( p = malloc(sizeof(*p)); p->next = dirhash[i]; dirhash[i] = p; - p->entry.hashval = hash; - p->entry.address = addr; + p->hashval = hash; + p->address = addr; p->seen = 0; } @@ -1644,8 +1645,7 @@ dir_hash_check( if (!sflag || id->ilist || v) dbprintf("dir ino %lld missing leaf entry for " "%x/%x\n", - id->ino, p->entry.hashval, - p->entry.address); + id->ino, p->hashval, p->address); error++; } } @@ -1684,7 +1684,7 @@ dir_hash_see( i = DIR_HASH_FUNC(hash, addr); for (p = dirhash[i]; p; p = p->next) { - if (p->entry.hashval == hash && p->entry.address == addr) { + if (p->hashval == hash && p->address == addr) { if (p->seen) return 1; p->seen = 1; @@ -2116,54 +2116,48 @@ process_btinode( xfs_bmbt_rec_32_t *rp; dib = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); - if (INT_GET(dib->bb_level, ARCH_CONVERT) >= XFS_BM_MAXLEVELS(mp, whichfork)) { + if (be16_to_cpu(dib->bb_level) >= XFS_BM_MAXLEVELS(mp, whichfork)) { if (!sflag || id->ilist) dbprintf("level for ino %lld %s fork bmap root too " "large (%u)\n", id->ino, whichfork == XFS_DATA_FORK ? "data" : "attr", - INT_GET(dib->bb_level, ARCH_CONVERT)); + be16_to_cpu(dib->bb_level)); error++; return; } - if (INT_GET(dib->bb_numrecs, ARCH_CONVERT) > - XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_SIZE_HOST(dip, mp, whichfork), - xfs_bmdr, INT_GET(dib->bb_level, ARCH_CONVERT) == 0)) { + if (be16_to_cpu(dib->bb_numrecs) > XFS_BTREE_BLOCK_MAXRECS( + XFS_DFORK_SIZE(dip, mp, whichfork), xfs_bmdr, + be16_to_cpu(dib->bb_level) == 0)) { if (!sflag || id->ilist) dbprintf("numrecs for ino %lld %s fork bmap root too " "large (%u)\n", id->ino, whichfork == XFS_DATA_FORK ? "data" : "attr", - INT_GET(dib->bb_numrecs, ARCH_CONVERT)); + be16_to_cpu(dib->bb_numrecs)); error++; return; } - if (INT_GET(dib->bb_level, ARCH_CONVERT) == 0) { - rp = (xfs_bmbt_rec_32_t *)XFS_BTREE_REC_ADDR( - XFS_DFORK_SIZE_HOST(dip, mp, whichfork), - xfs_bmdr, dib, 1, - XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_SIZE(dip, mp, - whichfork), - xfs_bmdr, 1)); - process_bmbt_reclist(rp, INT_GET(dib->bb_numrecs, ARCH_CONVERT), type, id, totd, - blkmapp); - *nex += INT_GET(dib->bb_numrecs, ARCH_CONVERT); + if (be16_to_cpu(dib->bb_level) == 0) { + rp = (xfs_bmbt_rec_32_t *)XFS_BTREE_REC_ADDR(xfs_bmdr, dib, 1); + process_bmbt_reclist(rp, be16_to_cpu(dib->bb_numrecs), type, + id, totd, blkmapp); + *nex += be16_to_cpu(dib->bb_numrecs); return; } else { - pp = XFS_BTREE_PTR_ADDR(XFS_DFORK_SIZE_HOST(dip, mp, whichfork), - xfs_bmdr, dib, 1, + pp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dib, 1, XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_SIZE(dip, mp, whichfork), xfs_bmdr, 0)); - for (i = 0; i < INT_GET(dib->bb_numrecs, ARCH_CONVERT); i++) - scan_lbtree((xfs_fsblock_t)INT_GET(pp[i], ARCH_CONVERT), INT_GET(dib->bb_level, ARCH_CONVERT), - scanfunc_bmap, type, id, totd, toti, nex, - blkmapp, 1, - whichfork == XFS_DATA_FORK ? - TYP_BMAPBTD : TYP_BMAPBTA); - } - if (*nex <= - XFS_DFORK_SIZE_HOST(dip, mp, whichfork) / sizeof(xfs_bmbt_rec_t)) { + for (i = 0; i < be16_to_cpu(dib->bb_numrecs); i++) + scan_lbtree(be64_to_cpu(pp[i]), + be16_to_cpu(dib->bb_level), + scanfunc_bmap, type, id, totd, toti, + nex, blkmapp, 1, + whichfork == XFS_DATA_FORK ? + TYP_BMAPBTD : TYP_BMAPBTA); + } + if (*nex <= XFS_DFORK_SIZE(dip, mp, whichfork) / sizeof(xfs_bmbt_rec_t)) { if (!sflag || id->ilist) dbprintf("extent count for ino %lld %s fork too low " "(%d) for file format\n", @@ -2198,7 +2192,6 @@ process_data_dir_v2( char *endptr; int freeseen; freetab_t *freetab; - xfs_dahash_t hash; int i; int lastfree; int lastfree_err; @@ -2208,25 +2201,26 @@ process_data_dir_v2( char *ptr; int stale = 0; int tag_err; - xfs_dir2_data_off_t *tagp; + __be16 *tagp; + struct xfs_name xname; data = iocur_top->data; block = iocur_top->data; - if (INT_GET(block->hdr.magic, ARCH_CONVERT) != XFS_DIR2_BLOCK_MAGIC && - INT_GET(data->hdr.magic, ARCH_CONVERT) != XFS_DIR2_DATA_MAGIC) { + if (be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC && + be32_to_cpu(data->hdr.magic) != XFS_DIR2_DATA_MAGIC) { if (!sflag || v) dbprintf("bad directory data magic # %#x for dir ino " "%lld block %d\n", - INT_GET(data->hdr.magic, ARCH_CONVERT), id->ino, dabno); + be32_to_cpu(data->hdr.magic), id->ino, dabno); error++; return NULLFSINO; } - db = XFS_DIR2_DA_TO_DB(mp, dabno); + db = xfs_dir2_da_to_db(mp, dabno); bf = data->hdr.bestfree; ptr = (char *)data->u; - if (INT_GET(block->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) { - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); - lep = XFS_DIR2_BLOCK_LEAF_P(btp); + if (be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { + btp = xfs_dir2_block_tail_p(mp, block); + lep = xfs_dir2_block_leaf_p(btp); endptr = (char *)lep; if (endptr <= ptr || endptr > (char *)btp) { endptr = (char *)data + mp->m_dirblksize; @@ -2241,20 +2235,20 @@ process_data_dir_v2( endptr = (char *)data + mp->m_dirblksize; bf_err = lastfree_err = tag_err = 0; count = lastfree = freeseen = 0; - if (INT_GET(bf[0].length, ARCH_CONVERT) == 0) { - bf_err += INT_GET(bf[0].offset, ARCH_CONVERT) != 0; + if (be16_to_cpu(bf[0].length) == 0) { + bf_err += be16_to_cpu(bf[0].offset) != 0; freeseen |= 1 << 0; } - if (INT_GET(bf[1].length, ARCH_CONVERT) == 0) { - bf_err += INT_GET(bf[1].offset, ARCH_CONVERT) != 0; + if (be16_to_cpu(bf[1].length) == 0) { + bf_err += be16_to_cpu(bf[1].offset) != 0; freeseen |= 1 << 1; } - if (INT_GET(bf[2].length, ARCH_CONVERT) == 0) { - bf_err += INT_GET(bf[2].offset, ARCH_CONVERT) != 0; + if (be16_to_cpu(bf[2].length) == 0) { + bf_err += be16_to_cpu(bf[2].offset) != 0; freeseen |= 1 << 2; } - bf_err += INT_GET(bf[0].length, ARCH_CONVERT) < INT_GET(bf[1].length, ARCH_CONVERT); - bf_err += INT_GET(bf[1].length, ARCH_CONVERT) < INT_GET(bf[2].length, ARCH_CONVERT); + bf_err += be16_to_cpu(bf[0].length) < be16_to_cpu(bf[1].length); + bf_err += be16_to_cpu(bf[1].length) < be16_to_cpu(bf[2].length); if (freetabp) { freetab = *freetabp; if (freetab->naents <= db) { @@ -2266,16 +2260,16 @@ process_data_dir_v2( } if (freetab->nents < db + 1) freetab->nents = db + 1; - freetab->ents[db] = INT_GET(bf[0].length, ARCH_CONVERT); + freetab->ents[db] = be16_to_cpu(bf[0].length); } while (ptr < endptr) { dup = (xfs_dir2_data_unused_t *)ptr; - if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) { + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { lastfree_err += lastfree != 0; - if ((INT_GET(dup->length, ARCH_CONVERT) & (XFS_DIR2_DATA_ALIGN - 1)) || - INT_GET(dup->length, ARCH_CONVERT) == 0 || - (char *)(tagp = XFS_DIR2_DATA_UNUSED_TAG_P(dup)) >= - endptr) { + tagp = xfs_dir2_data_unused_tag_p(dup); + if ((be16_to_cpu(dup->length) & (XFS_DIR2_DATA_ALIGN - 1)) || + be16_to_cpu(dup->length) == 0 || + (char *)tagp >= endptr) { if (!sflag || v) dbprintf("dir %lld block %d bad free " "entry at %d\n", @@ -2285,15 +2279,16 @@ process_data_dir_v2( error++; break; } - tag_err += INT_GET(*tagp, ARCH_CONVERT) != (char *)dup - (char *)data; + tag_err += be16_to_cpu(*tagp) != (char *)dup - (char *)data; dfp = process_data_dir_v2_freefind(data, dup); if (dfp) { i = (int)(dfp - bf); bf_err += (freeseen & (1 << i)) != 0; freeseen |= 1 << i; } else - bf_err += INT_GET(dup->length, ARCH_CONVERT) > INT_GET(bf[2].length, ARCH_CONVERT); - ptr += INT_GET(dup->length, ARCH_CONVERT); + bf_err += be16_to_cpu(dup->length) > + be16_to_cpu(bf[2].length); + ptr += be16_to_cpu(dup->length); lastfree = 1; continue; } @@ -2306,7 +2301,7 @@ process_data_dir_v2( (int)((char *)dep - (char *)data)); error++; } - tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); + tagp = xfs_dir2_data_entry_tag_p(dep); if ((char *)tagp >= endptr) { if (!sflag || v) dbprintf("dir %lld block %d bad entry at %d\n", @@ -2315,15 +2310,16 @@ process_data_dir_v2( error++; break; } - tag_err += INT_GET(*tagp, ARCH_CONVERT) != (char *)dep - (char *)data; - addr = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, db, + tag_err += be16_to_cpu(*tagp) != (char *)dep - (char *)data; + addr = xfs_dir2_db_off_to_dataptr(mp, db, (char *)dep - (char *)data); - hash = mp->m_dirnameops->hashname((uchar_t *)dep->name, dep->namelen); - dir_hash_add(hash, addr); - ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen); + xname.name = (char *)dep->name; + xname.len = dep->namelen; + dir_hash_add(mp->m_dirnameops->hashname(&xname), addr); + ptr += xfs_dir2_data_entsize(dep->namelen); count++; lastfree = 0; - lino = INT_GET(dep->inumber, ARCH_CONVERT); + lino = be64_to_cpu(dep->inumber); cid = find_inode(lino, 1); if (v) dbprintf("dir %lld block %d entry %*.*s %lld\n", @@ -2368,25 +2364,27 @@ process_data_dir_v2( (*dot)++; } } - if (INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) { + if (be32_to_cpu(data->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { endptr = (char *)data + mp->m_dirblksize; - for (i = stale = 0; lep && i < INT_GET(btp->count, ARCH_CONVERT); i++) { + for (i = stale = 0; lep && i < be32_to_cpu(btp->count); i++) { if ((char *)&lep[i] >= endptr) { if (!sflag || v) dbprintf("dir %lld block %d bad count " - "%u\n", - id->ino, dabno, INT_GET(btp->count, ARCH_CONVERT)); + "%u\n", id->ino, dabno, + be32_to_cpu(btp->count)); error++; break; } - if (INT_GET(lep[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) + if (be32_to_cpu(lep[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; - else if (dir_hash_see(INT_GET(lep[i].hashval, ARCH_CONVERT), INT_GET(lep[i].address, ARCH_CONVERT))) { + else if (dir_hash_see(be32_to_cpu(lep[i].hashval), + be32_to_cpu(lep[i].address))) { if (!sflag || v) dbprintf("dir %lld block %d extra leaf " - "entry %x %x\n", - id->ino, dabno, INT_GET(lep[i].hashval, ARCH_CONVERT), - INT_GET(lep[i].address, ARCH_CONVERT)); + "entry %x %x\n", + id->ino, dabno, + be32_to_cpu(lep[i].hashval), + be32_to_cpu(lep[i].address)); error++; } } @@ -2398,18 +2396,21 @@ process_data_dir_v2( id->ino, dabno); error++; } - if (INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC && - count != INT_GET(btp->count, ARCH_CONVERT) - INT_GET(btp->stale, ARCH_CONVERT)) { + if (be32_to_cpu(data->hdr.magic) == XFS_DIR2_BLOCK_MAGIC && + count != be32_to_cpu(btp->count) - + be32_to_cpu(btp->stale)) { if (!sflag || v) dbprintf("dir %lld block %d bad block tail count %d " - "(stale %d)\n", - id->ino, dabno, INT_GET(btp->count, ARCH_CONVERT), INT_GET(btp->stale, ARCH_CONVERT)); + "(stale %d)\n", + id->ino, dabno, be32_to_cpu(btp->count), + be32_to_cpu(btp->stale)); error++; } - if (INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC && stale != INT_GET(btp->stale, ARCH_CONVERT)) { + if (be32_to_cpu(data->hdr.magic) == XFS_DIR2_BLOCK_MAGIC && + stale != be32_to_cpu(btp->stale)) { if (!sflag || v) dbprintf("dir %lld block %d bad stale tail count %d\n", - id->ino, dabno, INT_GET(btp->stale, ARCH_CONVERT)); + id->ino, dabno, be32_to_cpu(btp->stale)); error++; } if (lastfree_err) { @@ -2437,14 +2438,14 @@ process_data_dir_v2_freefind( xfs_dir2_data_aoff_t off; off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)data); - if (INT_GET(dup->length, ARCH_CONVERT) < INT_GET(data->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length, ARCH_CONVERT)) + if (be16_to_cpu(dup->length) < be16_to_cpu(data->hdr. + bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length)) return NULL; - for (dfp = &data->hdr.bestfree[0]; - dfp < &data->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT]; - dfp++) { - if (INT_GET(dfp->offset, ARCH_CONVERT) == 0) + for (dfp = &data->hdr.bestfree[0]; dfp < &data->hdr. + bestfree[XFS_DIR2_DATA_FD_COUNT]; dfp++) { + if (be16_to_cpu(dfp->offset) == 0) return NULL; - if (INT_GET(dfp->offset, ARCH_CONVERT) == off) + if (be16_to_cpu(dfp->offset) == off) return dfp; } return NULL; @@ -2462,7 +2463,7 @@ process_dir( xfs_ino_t parent; dot = dotdot = 0; - if (XFS_DIR_IS_V2(mp)) { + if (xfs_sb_version_hasdirv2(&mp->m_sb)) { if (process_dir_v2(dip, blkmap, &dot, &dotdot, id, &parent)) return; } else @@ -2503,23 +2504,23 @@ process_dir_v1( inodata_t *id, xfs_ino_t *parent) { - if (dip->di_core.di_size <= XFS_DFORK_DSIZE_HOST(dip, mp) && - dip->di_core.di_format == XFS_DINODE_FMT_LOCAL) - *parent = - process_shortform_dir_v1(dip, dot, dotdot, id); - else if (dip->di_core.di_size == XFS_LBSIZE(mp) && - (dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS || - dip->di_core.di_format == XFS_DINODE_FMT_BTREE)) + xfs_fsize_t size = be64_to_cpu(dip->di_core.di_size); + + if (size <= XFS_DFORK_DSIZE(dip, mp) && + dip->di_core.di_format == XFS_DINODE_FMT_LOCAL) + *parent = process_shortform_dir_v1(dip, dot, dotdot, id); + else if (size == XFS_LBSIZE(mp) && + (dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS || + dip->di_core.di_format == XFS_DINODE_FMT_BTREE)) *parent = process_leaf_dir_v1(blkmap, dot, dotdot, id); - else if (dip->di_core.di_size >= XFS_LBSIZE(mp) && - (dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS || - dip->di_core.di_format == XFS_DINODE_FMT_BTREE)) + else if (size >= XFS_LBSIZE(mp) && + (dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS || + dip->di_core.di_format == XFS_DINODE_FMT_BTREE)) *parent = process_node_dir_v1(blkmap, dot, dotdot, id); else { dbprintf("bad size (%lld) or format (%d) for directory inode " "%lld\n", - dip->di_core.di_size, (int)dip->di_core.di_format, - id->ino); + size, dip->di_core.di_format, id->ino); error++; return 1; } @@ -2536,26 +2537,25 @@ process_dir_v2( xfs_ino_t *parent) { xfs_fileoff_t last = 0; + xfs_fsize_t size = be64_to_cpu(dip->di_core.di_size); if (blkmap) last = blkmap_last_off(blkmap); - if (dip->di_core.di_size <= XFS_DFORK_DSIZE_HOST(dip, mp) && - dip->di_core.di_format == XFS_DINODE_FMT_LOCAL) + if (size <= XFS_DFORK_DSIZE(dip, mp) && + dip->di_core.di_format == XFS_DINODE_FMT_LOCAL) *parent = process_sf_dir_v2(dip, dot, dotdot, id); else if (last == mp->m_dirblkfsbs && - (dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS || - dip->di_core.di_format == XFS_DINODE_FMT_BTREE)) + (dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS || + dip->di_core.di_format == XFS_DINODE_FMT_BTREE)) *parent = process_block_dir_v2(blkmap, dot, dotdot, id); else if (last >= mp->m_dirleafblk + mp->m_dirblkfsbs && - (dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS || - dip->di_core.di_format == XFS_DINODE_FMT_BTREE)) - *parent = process_leaf_node_dir_v2(blkmap, dot, dotdot, id, - dip->di_core.di_size); + (dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS || + dip->di_core.di_format == XFS_DINODE_FMT_BTREE)) + *parent = process_leaf_node_dir_v2(blkmap, dot, dotdot, id, size); else { dbprintf("bad size (%lld) or format (%d) for directory inode " "%lld\n", - dip->di_core.di_size, (int)dip->di_core.di_format, - id->ino); + size, dip->di_core.di_format, id->ino); error++; return 1; } @@ -2577,10 +2577,9 @@ process_exinode( xfs_bmbt_rec_32_t *rp; rp = (xfs_bmbt_rec_32_t *)XFS_DFORK_PTR(dip, whichfork); - *nex = XFS_DFORK_NEXTENTS_HOST(dip, whichfork); - if (*nex < 0 || - *nex > - XFS_DFORK_SIZE_HOST(dip, mp, whichfork) / sizeof(xfs_bmbt_rec_32_t)) { + *nex = XFS_DFORK_NEXTENTS(dip, whichfork); + if (*nex < 0 || *nex > XFS_DFORK_SIZE(dip, mp, whichfork) / + sizeof(xfs_bmbt_rec_32_t)) { if (!sflag || id->ilist) dbprintf("bad number of extents %d for inode %lld\n", *nex, id->ino); @@ -2599,8 +2598,7 @@ process_inode( { blkmap_t *blkmap; xfs_fsblock_t bno = 0; - xfs_dinode_core_t tdic; - xfs_dinode_core_t *dic; + xfs_icdinode_t idic; inodata_t *id = NULL; xfs_ino_t ino; xfs_extnum_t nextents = 0; @@ -2643,53 +2641,50 @@ process_inode( "dev", "local", "extents", "btree", "uuid" }; - /* convert the core, then copy it back into the inode */ - libxfs_xlate_dinode_core((xfs_caddr_t)&dip->di_core, &tdic, 1); - memcpy(&dip->di_core, &tdic, sizeof(xfs_dinode_core_t)); - dic=&dip->di_core; + libxfs_dinode_from_disk(&idic, &dip->di_core); - ino = XFS_AGINO_TO_INO(mp, INT_GET(agf->agf_seqno, ARCH_CONVERT), agino); + ino = XFS_AGINO_TO_INO(mp, be32_to_cpu(agf->agf_seqno), agino); if (!isfree) { id = find_inode(ino, 1); bno = XFS_INO_TO_FSB(mp, ino); blkmap = NULL; } - if (dic->di_magic != XFS_DINODE_MAGIC) { + if (idic.di_magic != XFS_DINODE_MAGIC) { if (!sflag || isfree || id->ilist || CHECK_BLIST(bno)) dbprintf("bad magic number %#x for inode %lld\n", - dic->di_magic, ino); + idic.di_magic, ino); error++; return; } - if (!XFS_DINODE_GOOD_VERSION(dic->di_version)) { + if (!XFS_DINODE_GOOD_VERSION(idic.di_version)) { if (!sflag || isfree || id->ilist || CHECK_BLIST(bno)) dbprintf("bad version number %#x for inode %lld\n", - dic->di_version, ino); + idic.di_version, ino); error++; return; } if (isfree) { - if (dic->di_nblocks != 0) { + if (idic.di_nblocks != 0) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf("bad nblocks %lld for free inode " "%lld\n", - dic->di_nblocks, ino); + idic.di_nblocks, ino); error++; } - if (dic->di_version == XFS_DINODE_VERSION_1) - nlink = dic->di_onlink; + if (idic.di_version == XFS_DINODE_VERSION_1) + nlink = idic.di_onlink; else - nlink = dic->di_nlink; + nlink = idic.di_nlink; if (nlink != 0) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf("bad nlink %d for free inode %lld\n", nlink, ino); error++; } - if (dic->di_mode != 0) { + if (idic.di_mode != 0) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf("bad mode %#o for free inode %lld\n", - dic->di_mode, ino); + idic.di_mode, ino); error++; } return; @@ -2697,25 +2692,25 @@ process_inode( /* * di_mode is a 16-bit uint so no need to check the < 0 case */ - if ((((dic->di_mode & S_IFMT) >> 12) > 15) || - (!(okfmts[(dic->di_mode & S_IFMT) >> 12] & (1 << dic->di_format)))) { + if ((((idic.di_mode & S_IFMT) >> 12) > 15) || + (!(okfmts[(idic.di_mode & S_IFMT) >> 12] & (1 << idic.di_format)))) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf("bad format %d for inode %lld type %#o\n", - dic->di_format, id->ino, dic->di_mode & S_IFMT); + idic.di_format, id->ino, idic.di_mode & S_IFMT); error++; return; } - if ((unsigned int)XFS_DFORK_ASIZE_HOST(dip, mp) >= XFS_LITINO(mp)) { + if ((unsigned int)XFS_DFORK_ASIZE(dip, mp) >= XFS_LITINO(mp)) { if (!sflag || id->ilist) dbprintf("bad fork offset %d for inode %lld\n", - dic->di_forkoff, id->ino); + idic.di_forkoff, id->ino); error++; return; } - if ((unsigned int)dic->di_aformat > XFS_DINODE_FMT_BTREE) { + if ((unsigned int)idic.di_aformat > XFS_DINODE_FMT_BTREE) { if (!sflag || id->ilist) dbprintf("bad attribute format %d for inode %lld\n", - dic->di_aformat, id->ino); + idic.di_aformat, id->ino); error++; return; } @@ -2723,47 +2718,47 @@ process_inode( dbprintf("inode %lld mode %#o fmt %s " "afmt %s " "nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n", - id->ino, dic->di_mode, fmtnames[(int)dic->di_format], - fmtnames[(int)dic->di_aformat], - dic->di_nextents, - dic->di_anextents, - dic->di_nblocks, dic->di_size, - dic->di_flags & XFS_DIFLAG_REALTIME ? " rt" : "", - dic->di_flags & XFS_DIFLAG_PREALLOC ? " pre" : "", - dic->di_flags & XFS_DIFLAG_IMMUTABLE? " imm" : "", - dic->di_flags & XFS_DIFLAG_APPEND ? " app" : "", - dic->di_flags & XFS_DIFLAG_SYNC ? " syn" : "", - dic->di_flags & XFS_DIFLAG_NOATIME ? " noa" : "", - dic->di_flags & XFS_DIFLAG_NODUMP ? " nod" : ""); + id->ino, idic.di_mode, fmtnames[(int)idic.di_format], + fmtnames[(int)idic.di_aformat], + idic.di_nextents, + idic.di_anextents, + idic.di_nblocks, idic.di_size, + idic.di_flags & XFS_DIFLAG_REALTIME ? " rt" : "", + idic.di_flags & XFS_DIFLAG_PREALLOC ? " pre" : "", + idic.di_flags & XFS_DIFLAG_IMMUTABLE? " imm" : "", + idic.di_flags & XFS_DIFLAG_APPEND ? " app" : "", + idic.di_flags & XFS_DIFLAG_SYNC ? " syn" : "", + idic.di_flags & XFS_DIFLAG_NOATIME ? " noa" : "", + idic.di_flags & XFS_DIFLAG_NODUMP ? " nod" : ""); security = 0; - switch (dic->di_mode & S_IFMT) { + switch (idic.di_mode & S_IFMT) { case S_IFDIR: type = DBM_DIR; - if (dic->di_format == XFS_DINODE_FMT_LOCAL) + if (idic.di_format == XFS_DINODE_FMT_LOCAL) break; - blkmap = blkmap_alloc(dic->di_nextents); + blkmap = blkmap_alloc(idic.di_nextents); break; case S_IFREG: - if (dic->di_flags & XFS_DIFLAG_REALTIME) + if (idic.di_flags & XFS_DIFLAG_REALTIME) type = DBM_RTDATA; else if (id->ino == mp->m_sb.sb_rbmino) { type = DBM_RTBITMAP; - blkmap = blkmap_alloc(dic->di_nextents); + blkmap = blkmap_alloc(idic.di_nextents); addlink_inode(id); } else if (id->ino == mp->m_sb.sb_rsumino) { type = DBM_RTSUM; - blkmap = blkmap_alloc(dic->di_nextents); + blkmap = blkmap_alloc(idic.di_nextents); addlink_inode(id); } else if (id->ino == mp->m_sb.sb_uquotino || id->ino == mp->m_sb.sb_gquotino) { type = DBM_QUOTA; - blkmap = blkmap_alloc(dic->di_nextents); + blkmap = blkmap_alloc(idic.di_nextents); addlink_inode(id); } else type = DBM_DATA; - if (dic->di_mode & (S_ISUID | S_ISGID)) + if (idic.di_mode & (S_ISUID | S_ISGID)) security = 1; break; case S_IFLNK: @@ -2774,13 +2769,13 @@ process_inode( type = DBM_UNKNOWN; break; } - if (dic->di_version == XFS_DINODE_VERSION_1) - setlink_inode(id, dic->di_onlink, type == DBM_DIR, security); + if (idic.di_version == XFS_DINODE_VERSION_1) + setlink_inode(id, idic.di_onlink, type == DBM_DIR, security); else { sbversion |= XFS_SB_VERSION_NLINKBIT; - setlink_inode(id, dic->di_nlink, type == DBM_DIR, security); + setlink_inode(id, idic.di_nlink, type == DBM_DIR, security); } - switch (dic->di_format) { + switch (idic.di_format) { case XFS_DINODE_FMT_LOCAL: process_lclinode(id, dip, type, &totdblocks, &totiblocks, &nextents, &blkmap, XFS_DATA_FORK); @@ -2796,7 +2791,7 @@ process_inode( } if (XFS_DFORK_Q(dip)) { sbversion |= XFS_SB_VERSION_ATTRBIT; - switch (dic->di_aformat) { + switch (idic.di_aformat) { case XFS_DINODE_FMT_LOCAL: process_lclinode(id, dip, DBM_ATTR, &atotdblocks, &atotiblocks, &anextents, NULL, XFS_ATTR_FORK); @@ -2832,30 +2827,30 @@ process_inode( break; } if (ic) { - dqprid = dic->di_projid; /* dquot ID is u32 */ - quota_add(&dqprid, &dic->di_gid, &dic->di_uid, + dqprid = idic.di_projid; /* dquot ID is u32 */ + quota_add(&dqprid, &idic.di_gid, &idic.di_uid, 0, bc, ic, rc); } } totblocks = totdblocks + totiblocks + atotdblocks + atotiblocks; - if (totblocks != dic->di_nblocks) { + if (totblocks != idic.di_nblocks) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf("bad nblocks %lld for inode %lld, counted " "%lld\n", - dic->di_nblocks, id->ino, totblocks); + idic.di_nblocks, id->ino, totblocks); error++; } - if (nextents != dic->di_nextents) { + if (nextents != idic.di_nextents) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf("bad nextents %d for inode %lld, counted %d\n", - dic->di_nextents, id->ino, nextents); + idic.di_nextents, id->ino, nextents); error++; } - if (anextents != dic->di_anextents) { + if (anextents != idic.di_anextents) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf("bad anextents %d for inode %lld, counted " "%d\n", - dic->di_anextents, id->ino, anextents); + idic.di_anextents, id->ino, anextents); error++; } if (type == DBM_DIR) @@ -2900,25 +2895,23 @@ process_lclinode( { xfs_attr_shortform_t *asf; xfs_fsblock_t bno; - xfs_dinode_core_t *dic; - dic = &dip->di_core; bno = XFS_INO_TO_FSB(mp, id->ino); - if (whichfork == XFS_DATA_FORK && - dic->di_size > XFS_DFORK_DSIZE_HOST(dip, mp)) { + if (whichfork == XFS_DATA_FORK && be64_to_cpu(dip->di_core.di_size) > + XFS_DFORK_DSIZE(dip, mp)) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf("local inode %lld data is too large (size " "%lld)\n", - id->ino, dic->di_size); + id->ino, be64_to_cpu(dip->di_core.di_size)); error++; } else if (whichfork == XFS_ATTR_FORK) { - asf = (xfs_attr_shortform_t *)XFS_DFORK_PTR(dip, whichfork); - if (INT_GET(asf->hdr.totsize, ARCH_CONVERT) > XFS_DFORK_ASIZE_HOST(dip, mp)) { + asf = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); + if (be16_to_cpu(asf->hdr.totsize) > XFS_DFORK_ASIZE(dip, mp)) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf("local inode %lld attr is too large " "(size %d)\n", - id->ino, INT_GET(asf->hdr.totsize, ARCH_CONVERT)); + id->ino, be16_to_cpu(asf->hdr.totsize)); error++; } } @@ -2979,17 +2972,18 @@ process_leaf_dir_v1_int( bno = XFS_DADDR_TO_FSB(mp, iocur_top->bb); v = verbose || id->ilist || CHECK_BLIST(bno); leaf = iocur_top->data; - if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR_LEAF_MAGIC) { + if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf("bad directory leaf magic # %#x for dir ino " "%lld\n", - INT_GET(leaf->hdr.info.magic, ARCH_CONVERT), id->ino); + be16_to_cpu(leaf->hdr.info.magic), id->ino); error++; return NULLFSINO; } entry = &leaf->entries[0]; - for (i = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); entry++, i++) { - namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); + for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { + namest = xfs_dir_leaf_namestruct(leaf, + be16_to_cpu(entry->nameidx)); lino = XFS_GET_DIR_INO8(namest->inumber); cid = find_inode(lino, 1); if (v) @@ -3129,7 +3123,7 @@ process_leaf_node_dir_v2( if (!sflag || v) dbprintf("missing free index for data block %d " "in dir ino %lld\n", - XFS_DIR2_DB_TO_DA(mp, i), id->ino); + xfs_dir2_db_to_da(mp, i), id->ino); error++; } } @@ -3151,57 +3145,63 @@ process_leaf_node_dir_v2_free( int used; free = iocur_top->data; - if (INT_GET(free->hdr.magic, ARCH_CONVERT) != XFS_DIR2_FREE_MAGIC) { + if (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC) { if (!sflag || v) dbprintf("bad free block magic # %#x for dir ino %lld " "block %d\n", - INT_GET(free->hdr.magic, ARCH_CONVERT), id->ino, dabno); + be32_to_cpu(free->hdr.magic), id->ino, dabno); error++; return; } maxent = XFS_DIR2_MAX_FREE_BESTS(mp); - if (INT_GET(free->hdr.firstdb, ARCH_CONVERT) != - XFS_DIR2_DA_TO_DB(mp, dabno - mp->m_dirfreeblk) * maxent) { + if (be32_to_cpu(free->hdr.firstdb) != xfs_dir2_da_to_db(mp, + dabno - mp->m_dirfreeblk) * maxent) { if (!sflag || v) dbprintf("bad free block firstdb %d for dir ino %lld " "block %d\n", - INT_GET(free->hdr.firstdb, ARCH_CONVERT), id->ino, dabno); + be32_to_cpu(free->hdr.firstdb), id->ino, dabno); error++; return; } - if (INT_GET(free->hdr.nvalid, ARCH_CONVERT) > maxent || INT_GET(free->hdr.nvalid, ARCH_CONVERT) < 0 || - INT_GET(free->hdr.nused, ARCH_CONVERT) > maxent || INT_GET(free->hdr.nused, ARCH_CONVERT) < 0 || - INT_GET(free->hdr.nused, ARCH_CONVERT) > INT_GET(free->hdr.nvalid, ARCH_CONVERT)) { + if (be32_to_cpu(free->hdr.nvalid) > maxent || + be32_to_cpu(free->hdr.nvalid) < 0 || + be32_to_cpu(free->hdr.nused) > maxent || + be32_to_cpu(free->hdr.nused) < 0 || + be32_to_cpu(free->hdr.nused) > + be32_to_cpu(free->hdr.nvalid)) { if (!sflag || v) dbprintf("bad free block nvalid/nused %d/%d for dir " "ino %lld block %d\n", - INT_GET(free->hdr.nvalid, ARCH_CONVERT), INT_GET(free->hdr.nused, ARCH_CONVERT), id->ino, - dabno); + be32_to_cpu(free->hdr.nvalid), + be32_to_cpu(free->hdr.nused), id->ino, dabno); error++; return; } - for (used = i = 0; i < INT_GET(free->hdr.nvalid, ARCH_CONVERT); i++) { - if (freetab->nents <= INT_GET(free->hdr.firstdb, ARCH_CONVERT) + i) + for (used = i = 0; i < be32_to_cpu(free->hdr.nvalid); i++) { + if (freetab->nents <= be32_to_cpu(free->hdr.firstdb) + i) ent = NULLDATAOFF; else - ent = freetab->ents[INT_GET(free->hdr.firstdb, ARCH_CONVERT) + i]; - if (ent != INT_GET(free->bests[i], ARCH_CONVERT)) { + ent = freetab->ents[be32_to_cpu(free->hdr.firstdb) + i]; + if (ent != be16_to_cpu(free->bests[i])) { if (!sflag || v) dbprintf("bad free block ent %d is %d should " "be %d for dir ino %lld block %d\n", - i, INT_GET(free->bests[i], ARCH_CONVERT), ent, id->ino, dabno); + i, be16_to_cpu(free->bests[i]), ent, + id->ino, dabno); error++; } - if (INT_GET(free->bests[i], ARCH_CONVERT) != NULLDATAOFF) + if (be16_to_cpu(free->bests[i]) != NULLDATAOFF) used++; if (ent != NULLDATAOFF) - freetab->ents[INT_GET(free->hdr.firstdb, ARCH_CONVERT) + i] = NULLDATAOFF; + freetab->ents[be32_to_cpu(free->hdr.firstdb) + i] = + NULLDATAOFF; } - if (used != INT_GET(free->hdr.nused, ARCH_CONVERT)) { + if (used != be32_to_cpu(free->hdr.nused)) { if (!sflag || v) dbprintf("bad free block nused %d should be %d for dir " "ino %lld block %d\n", - INT_GET(free->hdr.nused, ARCH_CONVERT), used, id->ino, dabno); + be32_to_cpu(free->hdr.nused), used, id->ino, + dabno); error++; } } @@ -3214,7 +3214,7 @@ process_leaf_node_dir_v2_int( freetab_t *freetab) { int i; - xfs_dir2_data_off_t *lbp; + __be16 *lbp; xfs_dir2_leaf_t *leaf; xfs_dir2_leaf_entry_t *lep; xfs_dir2_leaf_tail_t *ltp; @@ -3222,14 +3222,16 @@ process_leaf_node_dir_v2_int( int stale; leaf = iocur_top->data; - switch (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT)) { + switch (be16_to_cpu(leaf->hdr.info.magic)) { case XFS_DIR2_LEAF1_MAGIC: - if (INT_GET(leaf->hdr.info.forw, ARCH_CONVERT) || INT_GET(leaf->hdr.info.back, ARCH_CONVERT)) { + if (be32_to_cpu(leaf->hdr.info.forw) || + be32_to_cpu(leaf->hdr.info.back)) { if (!sflag || v) dbprintf("bad leaf block forw/back pointers " "%d/%d for dir ino %lld block %d\n", - INT_GET(leaf->hdr.info.forw, ARCH_CONVERT), - INT_GET(leaf->hdr.info.back, ARCH_CONVERT), id->ino, dabno); + be32_to_cpu(leaf->hdr.info.forw), + be32_to_cpu(leaf->hdr.info.back), + id->ino, dabno); error++; } if (dabno != mp->m_dirleafblk) { @@ -3240,10 +3242,11 @@ process_leaf_node_dir_v2_int( (xfs_dablk_t)mp->m_dirleafblk); error++; } - ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); - lbp = XFS_DIR2_LEAF_BESTS_P(ltp); - for (i = 0; i < INT_GET(ltp->bestcount, ARCH_CONVERT); i++) { - if (freetab->nents <= i || freetab->ents[i] != INT_GET(lbp[i], ARCH_CONVERT)) { + ltp = xfs_dir2_leaf_tail_p(mp, leaf); + lbp = xfs_dir2_leaf_bests_p(ltp); + for (i = 0; i < be32_to_cpu(ltp->bestcount); i++) { + if (freetab->nents <= i || freetab->ents[i] != + be16_to_cpu(lbp[i])) { if (!sflag || v) dbprintf("bestfree %d for dir ino %lld " "block %d doesn't match table " @@ -3252,8 +3255,8 @@ process_leaf_node_dir_v2_int( NULLDATAOFF : freetab->ents[i], id->ino, - XFS_DIR2_DB_TO_DA(mp, i), - INT_GET(lbp[i], ARCH_CONVERT)); + xfs_dir2_db_to_da(mp, i), + be16_to_cpu(lbp[i])); } if (freetab->nents > i) freetab->ents[i] = NULLDATAOFF; @@ -3265,12 +3268,14 @@ process_leaf_node_dir_v2_int( break; case XFS_DA_NODE_MAGIC: node = iocur_top->data; - if (INT_GET(node->hdr.level, ARCH_CONVERT) < 1 || - INT_GET(node->hdr.level, ARCH_CONVERT) > XFS_DA_NODE_MAXDEPTH) { + if (be16_to_cpu(node->hdr.level) < 1 || + be16_to_cpu(node->hdr.level) > + XFS_DA_NODE_MAXDEPTH) { if (!sflag || v) dbprintf("bad node block level %d for dir ino " "%lld block %d\n", - INT_GET(node->hdr.level, ARCH_CONVERT), id->ino, dabno); + be16_to_cpu(node->hdr.level), id->ino, + dabno); error++; } return; @@ -3278,29 +3283,31 @@ process_leaf_node_dir_v2_int( if (!sflag || v) dbprintf("bad directory data magic # %#x for dir ino " "%lld block %d\n", - INT_GET(leaf->hdr.info.magic, ARCH_CONVERT), id->ino, dabno); + be16_to_cpu(leaf->hdr.info.magic), id->ino, + dabno); error++; return; } lep = leaf->ents; - for (i = stale = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); i++) { - if (INT_GET(lep[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) + for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { + if (be32_to_cpu(lep[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; - else if (dir_hash_see(INT_GET(lep[i].hashval, ARCH_CONVERT), INT_GET(lep[i].address, ARCH_CONVERT))) { + else if (dir_hash_see(be32_to_cpu(lep[i].hashval), + be32_to_cpu(lep[i].address))) { if (!sflag || v) dbprintf("dir %lld block %d extra leaf entry " - "%x %x\n", - id->ino, dabno, INT_GET(lep[i].hashval, ARCH_CONVERT), - INT_GET(lep[i].address, ARCH_CONVERT)); + "%x %x\n", id->ino, dabno, + be32_to_cpu(lep[i].hashval), + be32_to_cpu(lep[i].address)); error++; } } - if (stale != INT_GET(leaf->hdr.stale, ARCH_CONVERT)) { + if (stale != be16_to_cpu(leaf->hdr.stale)) { if (!sflag || v) dbprintf("dir %lld block %d stale mismatch " "%d/%d\n", id->ino, dabno, stale, - INT_GET(leaf->hdr.stale, ARCH_CONVERT)); + be16_to_cpu(leaf->hdr.stale)); error++; } } @@ -3315,7 +3322,6 @@ process_node_dir_v1( xfs_fsblock_t bno; xfs_fileoff_t dbno; xfs_ino_t lino; - xfs_da_intnode_t *node; xfs_ino_t parent; int t; int v; @@ -3344,7 +3350,7 @@ process_node_dir_v1( push_cur(); set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_IGN, NULL); - if ((node = iocur_top->data) == NULL) { + if (iocur_top->data == NULL) { if (!sflag || v || v2) dbprintf("can't read block %u for directory " "inode %lld\n", @@ -3352,11 +3358,8 @@ process_node_dir_v1( error++; continue; } -#if VERS >= V_62 - if (INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) -#else - if (INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_NODE_MAGIC) -#endif + if (be16_to_cpu(((xfs_da_intnode_t *)iocur_top->data)-> + hdr.info.magic) == XFS_DA_NODE_MAGIC) continue; lino = process_leaf_dir_v1_int(dot, dotdot, id); if (lino) { @@ -3435,42 +3438,42 @@ process_quota( dbprintf("%s dqblk %lld entry %d id %u bc " "%lld ic %lld rc %lld\n", s, (xfs_dfiloff_t)qbno, i, dqid, - INT_GET(dqb->dd_diskdq.d_bcount, ARCH_CONVERT), - INT_GET(dqb->dd_diskdq.d_icount, ARCH_CONVERT), - INT_GET(dqb->dd_diskdq.d_rtbcount, ARCH_CONVERT)); - if (INT_GET(dqb->dd_diskdq.d_magic, ARCH_CONVERT) != XFS_DQUOT_MAGIC) { + be64_to_cpu(dqb->dd_diskdq.d_bcount), + be64_to_cpu(dqb->dd_diskdq.d_icount), + be64_to_cpu(dqb->dd_diskdq.d_rtbcount)); + if (be16_to_cpu(dqb->dd_diskdq.d_magic) != XFS_DQUOT_MAGIC) { if (scicb) dbprintf("bad magic number %#x for %s " "dqblk %lld entry %d id %u\n", - INT_GET(dqb->dd_diskdq.d_magic, ARCH_CONVERT), s, + be16_to_cpu(dqb->dd_diskdq.d_magic), s, (xfs_dfiloff_t)qbno, i, dqid); error++; continue; } - if (INT_GET(dqb->dd_diskdq.d_version, ARCH_CONVERT) != XFS_DQUOT_VERSION) { + if (dqb->dd_diskdq.d_version != XFS_DQUOT_VERSION) { if (scicb) dbprintf("bad version number %#x for " "%s dqblk %lld entry %d id " "%u\n", - INT_GET(dqb->dd_diskdq.d_version, ARCH_CONVERT), s, + dqb->dd_diskdq.d_version, s, (xfs_dfiloff_t)qbno, i, dqid); error++; continue; } - if (INT_GET(dqb->dd_diskdq.d_flags, ARCH_CONVERT) != exp_flags) { + if (dqb->dd_diskdq.d_flags != exp_flags) { if (scicb) dbprintf("bad flags %#x for %s dqblk " "%lld entry %d id %u\n", - INT_GET(dqb->dd_diskdq.d_flags, ARCH_CONVERT), s, + dqb->dd_diskdq.d_flags, s, (xfs_dfiloff_t)qbno, i, dqid); error++; continue; } - if (INT_GET(dqb->dd_diskdq.d_id, ARCH_CONVERT) != dqid) { + if (be32_to_cpu(dqb->dd_diskdq.d_id) != dqid) { if (scicb) dbprintf("bad id %u for %s dqblk %lld " "entry %d id %u\n", - INT_GET(dqb->dd_diskdq.d_id, ARCH_CONVERT), s, + be32_to_cpu(dqb->dd_diskdq.d_id), s, (xfs_dfiloff_t)qbno, i, dqid); error++; continue; @@ -3479,9 +3482,9 @@ process_quota( (qtype == IS_GROUP_QUOTA) ? &dqid : NULL, (qtype == IS_USER_QUOTA) ? &dqid : NULL, 1, - INT_GET(dqb->dd_diskdq.d_bcount, ARCH_CONVERT), - INT_GET(dqb->dd_diskdq.d_icount, ARCH_CONVERT), - INT_GET(dqb->dd_diskdq.d_rtbcount, ARCH_CONVERT)); + be64_to_cpu(dqb->dd_diskdq.d_bcount), + be64_to_cpu(dqb->dd_diskdq.d_icount), + be64_to_cpu(dqb->dd_diskdq.d_rtbcount)); } pop_cur(); } @@ -3491,7 +3494,6 @@ static void process_rtbitmap( blkmap_t *blkmap) { -#define xfs_highbit64 libxfs_highbit64 /* for XFS_RTBLOCKLOG macro */ int bit; int bitsperblock; xfs_fileoff_t bmbno; @@ -3622,17 +3624,17 @@ process_sf_dir_v2( xfs_dir2_sf_entry_t *sfe; int v; - sf = &dip->di_u.di_dir2sf; + sf = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(dip); addlink_inode(id); v = verbose || id->ilist; if (v) dbprintf("dir %lld entry . %lld\n", id->ino, id->ino); (*dot)++; - sfe = XFS_DIR2_SF_FIRSTENTRY(sf); + sfe = xfs_dir2_sf_firstentry(sf); offset = XFS_DIR2_DATA_FIRST_OFFSET; - for (i = INT_GET(sf->hdr.count, ARCH_CONVERT) - 1, i8 = 0; i >= 0; i--) { - if ((__psint_t)sfe + XFS_DIR2_SF_ENTSIZE_BYENTRY(sf, sfe) - - (__psint_t)sf > dip->di_core.di_size) { + for (i = sf->hdr.count - 1, i8 = 0; i >= 0; i--) { + if ((__psint_t)sfe + xfs_dir2_sf_entsize_byentry(sf, sfe) - + (__psint_t)sf > be64_to_cpu(dip->di_core.di_size)) { if (!sflag) dbprintf("dir %llu bad size in entry at %d\n", id->ino, @@ -3640,7 +3642,7 @@ process_sf_dir_v2( error++; break; } - lino = XFS_DIR2_SF_GET_INUMBER(sf, XFS_DIR2_SF_INUMBERP(sfe)); + lino = xfs_dir2_sf_get_inumber(sf, xfs_dir2_sf_inumberp(sfe)); if (lino > XFS_DIR2_MAX_SHORT_INUM) i8++; cid = find_inode(lino, 1); @@ -3660,33 +3662,34 @@ process_sf_dir_v2( if (v) dbprintf("dir %lld entry %*.*s offset %d %lld\n", id->ino, sfe->namelen, sfe->namelen, sfe->name, - XFS_DIR2_SF_GET_OFFSET(sfe), lino); - if (XFS_DIR2_SF_GET_OFFSET(sfe) < offset) { + xfs_dir2_sf_get_offset(sfe), lino); + if (xfs_dir2_sf_get_offset(sfe) < offset) { if (!sflag) dbprintf("dir %lld entry %*.*s bad offset %d\n", id->ino, sfe->namelen, sfe->namelen, - sfe->name, XFS_DIR2_SF_GET_OFFSET(sfe)); + sfe->name, xfs_dir2_sf_get_offset(sfe)); error++; } offset = - XFS_DIR2_SF_GET_OFFSET(sfe) + - XFS_DIR2_DATA_ENTSIZE(sfe->namelen); - sfe = XFS_DIR2_SF_NEXTENTRY(sf, sfe); + xfs_dir2_sf_get_offset(sfe) + + xfs_dir2_data_entsize(sfe->namelen); + sfe = xfs_dir2_sf_nextentry(sf, sfe); } - if (i < 0 && (__psint_t)sfe - (__psint_t)sf != dip->di_core.di_size) { + if (i < 0 && (__psint_t)sfe - (__psint_t)sf != + be64_to_cpu(dip->di_core.di_size)) { if (!sflag) dbprintf("dir %llu size is %lld, should be %u\n", - id->ino, dip->di_core.di_size, + id->ino, be64_to_cpu(dip->di_core.di_size), (uint)((char *)sfe - (char *)sf)); error++; } - if (offset + (INT_GET(sf->hdr.count, ARCH_CONVERT) + 2) * sizeof(xfs_dir2_leaf_entry_t) + + if (offset + (sf->hdr.count + 2) * sizeof(xfs_dir2_leaf_entry_t) + sizeof(xfs_dir2_block_tail_t) > mp->m_dirblksize) { if (!sflag) dbprintf("dir %llu offsets too high\n", id->ino); error++; } - lino = XFS_DIR2_SF_GET_INUMBER(sf, &sf->hdr.parent); + lino = xfs_dir2_sf_get_inumber(sf, &sf->hdr.parent); if (lino > XFS_DIR2_MAX_SHORT_INUM) i8++; cid = find_inode(lino, 1); @@ -3725,14 +3728,14 @@ process_shortform_dir_v1( xfs_dir_sf_entry_t *sfe; int v; - sf = &dip->di_u.di_dirsf; + sf = (xfs_dir_shortform_t *)XFS_DFORK_DPTR(dip); addlink_inode(id); v = verbose || id->ilist; if (v) dbprintf("dir %lld entry . %lld\n", id->ino, id->ino); (*dot)++; sfe = &sf->list[0]; - for (i = INT_GET(sf->hdr.count, ARCH_CONVERT) - 1; i >= 0; i--) { + for (i = sf->hdr.count - 1; i >= 0; i--) { lino = XFS_GET_DIR_INO8(sfe->inumber); cid = find_inode(lino, 1); if (cid == NULL) { @@ -3751,11 +3754,11 @@ process_shortform_dir_v1( if (v) dbprintf("dir %lld entry %*.*s %lld\n", id->ino, sfe->namelen, sfe->namelen, sfe->name, lino); - sfe = XFS_DIR_SF_NEXTENTRY(sfe); + sfe = xfs_dir_sf_nextentry(sfe); } - if ((__psint_t)sfe - (__psint_t)sf != dip->di_core.di_size) + if ((__psint_t)sfe - (__psint_t)sf != be64_to_cpu(dip->di_core.di_size)) dbprintf("dir %llu size is %lld, should be %d\n", - id->ino, dip->di_core.di_size, + id->ino, be64_to_cpu(dip->di_core.di_size), (int)((char *)sfe - (char *)sf)); lino = XFS_GET_DIR_INO8(sf->hdr.parent); cid = find_inode(lino, 1); @@ -3901,7 +3904,7 @@ scan_ag( xfs_agi_t *agi; int i; xfs_sb_t tsb; - xfs_sb_t *sb=&tsb; + xfs_sb_t *sb = &tsb; agffreeblks = agflongest = 0; agfbtreeblks = -2; @@ -3917,7 +3920,7 @@ scan_ag( goto pop1_out; } - libxfs_xlate_sb(iocur_top->data, sb, 1, XFS_SB_ALL_BITS); + libxfs_sb_from_disk(sb, iocur_top->data); if (sb->sb_magicnum != XFS_SB_MAGIC) { if (!sflag) @@ -3925,14 +3928,14 @@ scan_ag( sb->sb_magicnum, agno); error++; } - if (!XFS_SB_GOOD_VERSION(sb)) { + if (!xfs_sb_good_version(sb)) { if (!sflag) dbprintf("bad sb version # %#x in ag %u\n", sb->sb_versionnum, agno); error++; sbver_err++; } - if (!lazycount && XFS_SB_VERSION_LAZYSBCOUNT(sb)) { + if (!lazycount && xfs_sb_version_haslazysbcount(sb)) { lazycount = 1; } if (agno == 0 && sb->sb_inprogress != 0) { @@ -3953,24 +3956,24 @@ scan_ag( serious_error++; goto pop2_out; } - if (INT_GET(agf->agf_magicnum, ARCH_CONVERT) != XFS_AGF_MAGIC) { + if (be32_to_cpu(agf->agf_magicnum) != XFS_AGF_MAGIC) { if (!sflag) dbprintf("bad agf magic # %#x in ag %u\n", - INT_GET(agf->agf_magicnum, ARCH_CONVERT), agno); + be32_to_cpu(agf->agf_magicnum), agno); error++; } - if (!XFS_AGF_GOOD_VERSION(INT_GET(agf->agf_versionnum, ARCH_CONVERT))) { + if (!XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum))) { if (!sflag) dbprintf("bad agf version # %#x in ag %u\n", - INT_GET(agf->agf_versionnum, ARCH_CONVERT), agno); + be32_to_cpu(agf->agf_versionnum), agno); error++; } if (XFS_SB_BLOCK(mp) != XFS_AGF_BLOCK(mp)) set_dbmap(agno, XFS_AGF_BLOCK(mp), 1, DBM_AGF, agno, XFS_SB_BLOCK(mp)); - if (sb->sb_agblocks > INT_GET(agf->agf_length, ARCH_CONVERT)) - set_dbmap(agno, INT_GET(agf->agf_length, ARCH_CONVERT), - sb->sb_agblocks - INT_GET(agf->agf_length, ARCH_CONVERT), + if (sb->sb_agblocks > be32_to_cpu(agf->agf_length)) + set_dbmap(agno, be32_to_cpu(agf->agf_length), + sb->sb_agblocks - be32_to_cpu(agf->agf_length), DBM_MISSING, agno, XFS_SB_BLOCK(mp)); push_cur(); /* 3 pushed */ set_cur(&typtab[TYP_AGI], @@ -3981,16 +3984,16 @@ scan_ag( serious_error++; goto pop3_out; } - if (INT_GET(agi->agi_magicnum, ARCH_CONVERT) != XFS_AGI_MAGIC) { + if (be32_to_cpu(agi->agi_magicnum) != XFS_AGI_MAGIC) { if (!sflag) dbprintf("bad agi magic # %#x in ag %u\n", - INT_GET(agi->agi_magicnum, ARCH_CONVERT), agno); + be32_to_cpu(agi->agi_magicnum), agno); error++; } - if (!XFS_AGI_GOOD_VERSION(INT_GET(agi->agi_versionnum, ARCH_CONVERT))) { + if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum))) { if (!sflag) dbprintf("bad agi version # %#x in ag %u\n", - INT_GET(agi->agi_versionnum, ARCH_CONVERT), agno); + be32_to_cpu(agi->agi_versionnum), agno); error++; } if (XFS_SB_BLOCK(mp) != XFS_AGI_BLOCK(mp) && @@ -4000,59 +4003,59 @@ scan_ag( scan_freelist(agf); fdblocks--; scan_sbtree(agf, - INT_GET(agf->agf_roots[XFS_BTNUM_BNO], ARCH_CONVERT), - INT_GET(agf->agf_levels[XFS_BTNUM_BNO], ARCH_CONVERT), + be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]), + be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]), 1, scanfunc_bno, TYP_BNOBT); fdblocks--; scan_sbtree(agf, - INT_GET(agf->agf_roots[XFS_BTNUM_CNT], ARCH_CONVERT), - INT_GET(agf->agf_levels[XFS_BTNUM_CNT], ARCH_CONVERT), + be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]), + be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]), 1, scanfunc_cnt, TYP_CNTBT); scan_sbtree(agf, - INT_GET(agi->agi_root, ARCH_CONVERT), - INT_GET(agi->agi_level, ARCH_CONVERT), + be32_to_cpu(agi->agi_root), + be32_to_cpu(agi->agi_level), 1, scanfunc_ino, TYP_INOBT); - if (INT_GET(agf->agf_freeblks, ARCH_CONVERT) != agffreeblks) { + if (be32_to_cpu(agf->agf_freeblks) != agffreeblks) { if (!sflag) dbprintf("agf_freeblks %u, counted %u in ag %u\n", - INT_GET(agf->agf_freeblks, ARCH_CONVERT), + be32_to_cpu(agf->agf_freeblks), agffreeblks, agno); error++; } - if (INT_GET(agf->agf_longest, ARCH_CONVERT) != agflongest) { + if (be32_to_cpu(agf->agf_longest) != agflongest) { if (!sflag) dbprintf("agf_longest %u, counted %u in ag %u\n", - INT_GET(agf->agf_longest, ARCH_CONVERT), + be32_to_cpu(agf->agf_longest), agflongest, agno); error++; } if (lazycount && - INT_GET(agf->agf_btreeblks, ARCH_CONVERT) != agfbtreeblks) { + be32_to_cpu(agf->agf_btreeblks) != agfbtreeblks) { if (!sflag) dbprintf("agf_btreeblks %u, counted %u in ag %u\n", - INT_GET(agf->agf_btreeblks, ARCH_CONVERT), + be32_to_cpu(agf->agf_btreeblks), agfbtreeblks, agno); error++; } agf_aggr_freeblks += agffreeblks + agfbtreeblks; - if (INT_GET(agi->agi_count, ARCH_CONVERT) != agicount) { + if (be32_to_cpu(agi->agi_count) != agicount) { if (!sflag) dbprintf("agi_count %u, counted %u in ag %u\n", - INT_GET(agi->agi_count, ARCH_CONVERT), + be32_to_cpu(agi->agi_count), agicount, agno); error++; } - if (INT_GET(agi->agi_freecount, ARCH_CONVERT) != agifreecount) { + if (be32_to_cpu(agi->agi_freecount) != agifreecount) { if (!sflag) dbprintf("agi_freecount %u, counted %u in ag %u\n", - INT_GET(agi->agi_freecount, ARCH_CONVERT), + be32_to_cpu(agi->agi_freecount), agifreecount, agno); error++; } for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) { - if (INT_GET(agi->agi_unlinked[i], ARCH_CONVERT) != NULLAGINO) { + if (be32_to_cpu(agi->agi_unlinked[i]) != NULLAGINO) { if (!sflag) { - xfs_agino_t agino=INT_GET(agi->agi_unlinked[i], ARCH_CONVERT); + xfs_agino_t agino=be32_to_cpu(agi->agi_unlinked[i]); dbprintf("agi unlinked bucket %d is %u in ag " "%u (inode=%lld)\n", i, agino, agno, XFS_AGINO_TO_INO(mp, agno, agino)); @@ -4072,7 +4075,7 @@ static void scan_freelist( xfs_agf_t *agf) { - xfs_agnumber_t seqno = INT_GET(agf->agf_seqno, ARCH_CONVERT); + xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); xfs_agfl_t *agfl; xfs_agblock_t bno; uint count; @@ -4083,7 +4086,7 @@ scan_freelist( XFS_AGI_BLOCK(mp) != XFS_AGFL_BLOCK(mp)) set_dbmap(seqno, XFS_AGFL_BLOCK(mp), 1, DBM_AGFL, seqno, XFS_SB_BLOCK(mp)); - if (INT_GET(agf->agf_flcount, ARCH_CONVERT) == 0) + if (be32_to_cpu(agf->agf_flcount) == 0) return; push_cur(); set_cur(&typtab[TYP_AGFL], @@ -4095,22 +4098,22 @@ scan_freelist( pop_cur(); return; } - i = INT_GET(agf->agf_flfirst, ARCH_CONVERT); + i = be32_to_cpu(agf->agf_flfirst); count = 0; for (;;) { - bno = INT_GET(agfl->agfl_bno[i], ARCH_CONVERT); + bno = be32_to_cpu(agfl->agfl_bno[i]); set_dbmap(seqno, bno, 1, DBM_FREELIST, seqno, XFS_AGFL_BLOCK(mp)); count++; - if (i == INT_GET(agf->agf_fllast, ARCH_CONVERT)) + if (i == be32_to_cpu(agf->agf_fllast)) break; if (++i == XFS_AGFL_SIZE(mp)) i = 0; } - if (count != INT_GET(agf->agf_flcount, ARCH_CONVERT)) { + if (count != be32_to_cpu(agf->agf_flcount)) { if (!sflag) dbprintf("freeblk count %u != flcount %u in ag %u\n", - count, INT_GET(agf->agf_flcount, ARCH_CONVERT), + count, be32_to_cpu(agf->agf_flcount), seqno); error++; } @@ -4159,7 +4162,7 @@ scan_sbtree( scan_sbtree_f_t func, typnm_t btype) { - xfs_agnumber_t seqno = INT_GET(agf->agf_seqno, ARCH_CONVERT); + xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); push_cur(); set_cur(&typtab[btype], @@ -4198,58 +4201,55 @@ scanfunc_bmap( agno = XFS_FSB_TO_AGNO(mp, bno); agbno = XFS_FSB_TO_AGBNO(mp, bno); - if (INT_GET(block->bb_magic, ARCH_CONVERT) != XFS_BMAP_MAGIC) { + if (be32_to_cpu(block->bb_magic) != XFS_BMAP_MAGIC) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf("bad magic # %#x in inode %lld bmbt block " "%u/%u\n", - INT_GET(block->bb_magic, ARCH_CONVERT), id->ino, agno, agbno); + be32_to_cpu(block->bb_magic), id->ino, agno, agbno); error++; } - if (INT_GET(block->bb_level, ARCH_CONVERT) != level) { + if (be16_to_cpu(block->bb_level) != level) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf("expected level %d got %d in inode %lld bmbt " "block %u/%u\n", - level, INT_GET(block->bb_level, ARCH_CONVERT), id->ino, agno, agbno); + level, be16_to_cpu(block->bb_level), id->ino, agno, agbno); error++; } set_dbmap(agno, agbno, 1, type, agno, agbno); set_inomap(agno, agbno, 1, id); (*toti)++; if (level == 0) { - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_bmap_dmxr[0] || - (isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_bmap_dmnr[0])) { + if (be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[0] || + (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_bmap_dmnr[0])) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf("bad btree nrecs (%u, min=%u, max=%u) " "in inode %lld bmap block %lld\n", - INT_GET(block->bb_numrecs, ARCH_CONVERT), mp->m_bmap_dmnr[0], + be16_to_cpu(block->bb_numrecs), mp->m_bmap_dmnr[0], mp->m_bmap_dmxr[0], id->ino, (xfs_dfsbno_t)bno); error++; return; } - rp = (xfs_bmbt_rec_32_t *) - XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, - block, 1, mp->m_bmap_dmxr[0]); - *nex += INT_GET(block->bb_numrecs, ARCH_CONVERT); - process_bmbt_reclist(rp, INT_GET(block->bb_numrecs, ARCH_CONVERT), type, id, totd, + rp = (xfs_bmbt_rec_32_t *)XFS_BTREE_REC_ADDR(xfs_bmbt, block, 1); + *nex += be16_to_cpu(block->bb_numrecs); + process_bmbt_reclist(rp, be16_to_cpu(block->bb_numrecs), type, id, totd, blkmapp); return; } - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_bmap_dmxr[1] || - (isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_bmap_dmnr[1])) { + if (be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[1] || + (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_bmap_dmnr[1])) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf("bad btree nrecs (%u, min=%u, max=%u) in " "inode %lld bmap block %lld\n", - INT_GET(block->bb_numrecs, ARCH_CONVERT), mp->m_bmap_dmnr[1], + be16_to_cpu(block->bb_numrecs), mp->m_bmap_dmnr[1], mp->m_bmap_dmxr[1], id->ino, (xfs_dfsbno_t)bno); error++; return; } - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, 1, - mp->m_bmap_dmxr[0]); - for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) - scan_lbtree(INT_GET(pp[i], ARCH_CONVERT), level, scanfunc_bmap, type, id, totd, toti, - nex, blkmapp, 0, btype); + pp = XFS_BTREE_PTR_ADDR(xfs_bmbt, block, 1, mp->m_bmap_dmxr[0]); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) + scan_lbtree(be64_to_cpu(pp[i]), level, scanfunc_bmap, type, id, + totd, toti, nex, blkmapp, 0, btype); } static void @@ -4264,68 +4264,66 @@ scanfunc_bno( int i; xfs_alloc_ptr_t *pp; xfs_alloc_rec_t *rp; - xfs_agnumber_t seqno = INT_GET(agf->agf_seqno, ARCH_CONVERT); + xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); xfs_agblock_t lastblock; - if (INT_GET(block->bb_magic, ARCH_CONVERT) != XFS_ABTB_MAGIC) { + if (be32_to_cpu(block->bb_magic) != XFS_ABTB_MAGIC) { dbprintf("bad magic # %#x in btbno block %u/%u\n", - INT_GET(block->bb_magic, ARCH_CONVERT), seqno, bno); + be32_to_cpu(block->bb_magic), seqno, bno); serious_error++; return; } fdblocks++; agfbtreeblks++; - if (INT_GET(block->bb_level, ARCH_CONVERT) != level) { + if (be16_to_cpu(block->bb_level) != level) { if (!sflag) dbprintf("expected level %d got %d in btbno block " "%u/%u\n", - level, INT_GET(block->bb_level, ARCH_CONVERT), seqno, bno); + level, be16_to_cpu(block->bb_level), seqno, bno); error++; } set_dbmap(seqno, bno, 1, DBM_BTBNO, seqno, bno); if (level == 0) { - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_alloc_mxr[0] || - (isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_alloc_mnr[0])) { + if (be16_to_cpu(block->bb_numrecs) > mp->m_alloc_mxr[0] || + (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_alloc_mnr[0])) { dbprintf("bad btree nrecs (%u, min=%u, max=%u) in " "btbno block %u/%u\n", - INT_GET(block->bb_numrecs, ARCH_CONVERT), mp->m_alloc_mnr[0], + be16_to_cpu(block->bb_numrecs), mp->m_alloc_mnr[0], mp->m_alloc_mxr[0], seqno, bno); serious_error++; return; } - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, - 1, mp->m_alloc_mxr[0]); + rp = XFS_BTREE_REC_ADDR(xfs_alloc, block, 1); lastblock = 0; - for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) { - set_dbmap(seqno, INT_GET(rp[i].ar_startblock, ARCH_CONVERT), - INT_GET(rp[i].ar_blockcount, ARCH_CONVERT), DBM_FREE1, + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) { + set_dbmap(seqno, be32_to_cpu(rp[i].ar_startblock), + be32_to_cpu(rp[i].ar_blockcount), DBM_FREE1, seqno, bno); - if (INT_GET(rp[i].ar_startblock, ARCH_CONVERT) <= lastblock) { + if (be32_to_cpu(rp[i].ar_startblock) <= lastblock) { dbprintf( "out-of-order bno btree record %d (%u %u) block %u/%u\n", - i, INT_GET(rp[i].ar_startblock, ARCH_CONVERT), - INT_GET(rp[i].ar_blockcount, ARCH_CONVERT), - INT_GET(agf->agf_seqno, ARCH_CONVERT), bno); + i, be32_to_cpu(rp[i].ar_startblock), + be32_to_cpu(rp[i].ar_blockcount), + be32_to_cpu(agf->agf_seqno), bno); serious_error++; } else { - lastblock = INT_GET(rp[i].ar_startblock, ARCH_CONVERT); + lastblock = be32_to_cpu(rp[i].ar_startblock); } } return; } - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_alloc_mxr[1] || - (isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_alloc_mnr[1])) { + if (be16_to_cpu(block->bb_numrecs) > mp->m_alloc_mxr[1] || + (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_alloc_mnr[1])) { dbprintf("bad btree nrecs (%u, min=%u, max=%u) in btbno block " "%u/%u\n", - INT_GET(block->bb_numrecs, ARCH_CONVERT), mp->m_alloc_mnr[1], + be16_to_cpu(block->bb_numrecs), mp->m_alloc_mnr[1], mp->m_alloc_mxr[1], seqno, bno); serious_error++; return; } - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, 1, - mp->m_alloc_mxr[1]); - for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) - scan_sbtree(agf, INT_GET(pp[i], ARCH_CONVERT), level, 0, scanfunc_bno, TYP_BNOBT); + pp = XFS_BTREE_PTR_ADDR(xfs_alloc, block, 1, mp->m_alloc_mxr[1]); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) + scan_sbtree(agf, be32_to_cpu(pp[i]), level, 0, scanfunc_bno, TYP_BNOBT); } static void @@ -4337,74 +4335,72 @@ scanfunc_cnt( int isroot) { xfs_alloc_block_t *block = (xfs_alloc_block_t *)ablock; - xfs_agnumber_t seqno = INT_GET(agf->agf_seqno, ARCH_CONVERT); + xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); int i; xfs_alloc_ptr_t *pp; xfs_alloc_rec_t *rp; xfs_extlen_t lastcount; - if (INT_GET(block->bb_magic, ARCH_CONVERT) != XFS_ABTC_MAGIC) { + if (be32_to_cpu(block->bb_magic) != XFS_ABTC_MAGIC) { dbprintf("bad magic # %#x in btcnt block %u/%u\n", - INT_GET(block->bb_magic, ARCH_CONVERT), seqno, bno); + be32_to_cpu(block->bb_magic), seqno, bno); serious_error++; return; } fdblocks++; agfbtreeblks++; - if (INT_GET(block->bb_level, ARCH_CONVERT) != level) { + if (be16_to_cpu(block->bb_level) != level) { if (!sflag) dbprintf("expected level %d got %d in btcnt block " "%u/%u\n", - level, INT_GET(block->bb_level, ARCH_CONVERT), seqno, bno); + level, be16_to_cpu(block->bb_level), seqno, bno); error++; } set_dbmap(seqno, bno, 1, DBM_BTCNT, seqno, bno); if (level == 0) { - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_alloc_mxr[0] || - (isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_alloc_mnr[0])) { + if (be16_to_cpu(block->bb_numrecs) > mp->m_alloc_mxr[0] || + (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_alloc_mnr[0])) { dbprintf("bad btree nrecs (%u, min=%u, max=%u) in " "btbno block %u/%u\n", - INT_GET(block->bb_numrecs, ARCH_CONVERT), mp->m_alloc_mnr[0], + be16_to_cpu(block->bb_numrecs), mp->m_alloc_mnr[0], mp->m_alloc_mxr[0], seqno, bno); serious_error++; return; } - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, - 1, mp->m_alloc_mxr[0]); + rp = XFS_BTREE_REC_ADDR(xfs_alloc, block, 1); lastcount = 0; - for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) { - check_set_dbmap(seqno, INT_GET(rp[i].ar_startblock, ARCH_CONVERT), - INT_GET(rp[i].ar_blockcount, ARCH_CONVERT), DBM_FREE1, DBM_FREE2, + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) { + check_set_dbmap(seqno, be32_to_cpu(rp[i].ar_startblock), + be32_to_cpu(rp[i].ar_blockcount), DBM_FREE1, DBM_FREE2, seqno, bno); - fdblocks += INT_GET(rp[i].ar_blockcount, ARCH_CONVERT); - agffreeblks += INT_GET(rp[i].ar_blockcount, ARCH_CONVERT); - if (INT_GET(rp[i].ar_blockcount, ARCH_CONVERT) > agflongest) - agflongest = INT_GET(rp[i].ar_blockcount, ARCH_CONVERT); - if (INT_GET(rp[i].ar_blockcount, ARCH_CONVERT) < lastcount) { + fdblocks += be32_to_cpu(rp[i].ar_blockcount); + agffreeblks += be32_to_cpu(rp[i].ar_blockcount); + if (be32_to_cpu(rp[i].ar_blockcount) > agflongest) + agflongest = be32_to_cpu(rp[i].ar_blockcount); + if (be32_to_cpu(rp[i].ar_blockcount) < lastcount) { dbprintf( "out-of-order cnt btree record %d (%u %u) block %u/%u\n", - i, INT_GET(rp[i].ar_startblock, ARCH_CONVERT), - INT_GET(rp[i].ar_blockcount, ARCH_CONVERT), - INT_GET(agf->agf_seqno, ARCH_CONVERT), bno); + i, be32_to_cpu(rp[i].ar_startblock), + be32_to_cpu(rp[i].ar_blockcount), + be32_to_cpu(agf->agf_seqno), bno); } else { - lastcount = INT_GET(rp[i].ar_blockcount, ARCH_CONVERT); + lastcount = be32_to_cpu(rp[i].ar_blockcount); } } return; } - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_alloc_mxr[1] || - (isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_alloc_mnr[1])) { + if (be16_to_cpu(block->bb_numrecs) > mp->m_alloc_mxr[1] || + (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_alloc_mnr[1])) { dbprintf("bad btree nrecs (%u, min=%u, max=%u) in btbno block " "%u/%u\n", - INT_GET(block->bb_numrecs, ARCH_CONVERT), mp->m_alloc_mnr[1], + be16_to_cpu(block->bb_numrecs), mp->m_alloc_mnr[1], mp->m_alloc_mxr[1], seqno, bno); serious_error++; return; } - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, 1, - mp->m_alloc_mxr[1]); - for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) - scan_sbtree(agf, INT_GET(pp[i], ARCH_CONVERT), level, 0, scanfunc_cnt, TYP_CNTBT); + pp = XFS_BTREE_PTR_ADDR(xfs_alloc, block, 1, mp->m_alloc_mxr[1]); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) + scan_sbtree(agf, be32_to_cpu(pp[i]), level, 0, scanfunc_cnt, TYP_CNTBT); } static void @@ -4417,7 +4413,7 @@ scanfunc_ino( { xfs_agino_t agino; xfs_inobt_block_t *block = (xfs_inobt_block_t *)ablock; - xfs_agnumber_t seqno = INT_GET(agf->agf_seqno, ARCH_CONVERT); + xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); int i; int isfree; int j; @@ -4426,34 +4422,33 @@ scanfunc_ino( xfs_inobt_ptr_t *pp; xfs_inobt_rec_t *rp; - if (INT_GET(block->bb_magic, ARCH_CONVERT) != XFS_IBT_MAGIC) { + if (be32_to_cpu(block->bb_magic) != XFS_IBT_MAGIC) { dbprintf("bad magic # %#x in inobt block %u/%u\n", - INT_GET(block->bb_magic, ARCH_CONVERT), seqno, bno); + be32_to_cpu(block->bb_magic), seqno, bno); serious_error++; return; } - if (INT_GET(block->bb_level, ARCH_CONVERT) != level) { + if (be16_to_cpu(block->bb_level) != level) { if (!sflag) dbprintf("expected level %d got %d in inobt block " "%u/%u\n", - level, INT_GET(block->bb_level, ARCH_CONVERT), seqno, bno); + level, be16_to_cpu(block->bb_level), seqno, bno); error++; } set_dbmap(seqno, bno, 1, DBM_BTINO, seqno, bno); if (level == 0) { - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_inobt_mxr[0] || - (isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_inobt_mnr[0])) { + if (be16_to_cpu(block->bb_numrecs) > mp->m_inobt_mxr[0] || + (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_inobt_mnr[0])) { dbprintf("bad btree nrecs (%u, min=%u, max=%u) in " "inobt block %u/%u\n", - INT_GET(block->bb_numrecs, ARCH_CONVERT), mp->m_inobt_mnr[0], + be16_to_cpu(block->bb_numrecs), mp->m_inobt_mnr[0], mp->m_inobt_mxr[0], seqno, bno); serious_error++; return; } - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_inobt, block, - 1, mp->m_inobt_mxr[0]); - for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) { - agino = INT_GET(rp[i].ir_startino, ARCH_CONVERT); + rp = XFS_BTREE_REC_ADDR(xfs_inobt, block, 1); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) { + agino = be32_to_cpu(rp[i].ir_startino); off = XFS_INO_TO_OFFSET(mp, agino); if (off == 0) { if ((sbversion & XFS_SB_VERSION_ALIGNBIT) && @@ -4469,8 +4464,8 @@ scanfunc_ino( } icount += XFS_INODES_PER_CHUNK; agicount += XFS_INODES_PER_CHUNK; - ifree += INT_GET(rp[i].ir_freecount, ARCH_CONVERT); - agifreecount += INT_GET(rp[i].ir_freecount, ARCH_CONVERT); + ifree += be32_to_cpu(rp[i].ir_freecount); + agifreecount += be32_to_cpu(rp[i].ir_freecount); push_cur(); set_cur(&typtab[TYP_INODE], XFS_AGB_TO_DADDR(mp, seqno, @@ -4488,38 +4483,38 @@ scanfunc_ino( continue; } for (j = 0, nfree = 0; j < XFS_INODES_PER_CHUNK; j++) { - if ((isfree = XFS_INOBT_IS_FREE_DISK(&rp[i], j))) + isfree = XFS_INOBT_IS_FREE_DISK(&rp[i], j); + if (isfree) nfree++; process_inode(agf, agino + j, (xfs_dinode_t *)((char *)iocur_top->data + ((off + j) << mp->m_sb.sb_inodelog)), isfree); } - if (nfree != INT_GET(rp[i].ir_freecount, ARCH_CONVERT)) { + if (nfree != be32_to_cpu(rp[i].ir_freecount)) { if (!sflag) dbprintf("ir_freecount/free mismatch, " "inode chunk %u/%u, freecount " "%d nfree %d\n", seqno, agino, - INT_GET(rp[i].ir_freecount, ARCH_CONVERT), nfree); + be32_to_cpu(rp[i].ir_freecount), nfree); error++; } pop_cur(); } return; } - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_inobt_mxr[1] || - (isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_inobt_mnr[1])) { + if (be16_to_cpu(block->bb_numrecs) > mp->m_inobt_mxr[1] || + (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_inobt_mnr[1])) { dbprintf("bad btree nrecs (%u, min=%u, max=%u) in inobt block " "%u/%u\n", - INT_GET(block->bb_numrecs, ARCH_CONVERT), mp->m_inobt_mnr[1], + be16_to_cpu(block->bb_numrecs), mp->m_inobt_mnr[1], mp->m_inobt_mxr[1], seqno, bno); serious_error++; return; } - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_inobt, block, 1, - mp->m_inobt_mxr[1]); - for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) - scan_sbtree(agf, INT_GET(pp[i], ARCH_CONVERT), level, 0, scanfunc_ino, TYP_INOBT); + pp = XFS_BTREE_PTR_ADDR(xfs_inobt, block, 1, mp->m_inobt_mxr[1]); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) + scan_sbtree(agf, be32_to_cpu(pp[i]), level, 0, scanfunc_ino, TYP_INOBT); } static void diff --git a/db/cntbt.c b/db/cntbt.c index 43f66578f..aa21428d1 100644 --- a/db/cntbt.c +++ b/db/cntbt.c @@ -78,9 +78,9 @@ cntbt_key_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->bb_level, ARCH_CONVERT) == 0) + if (be16_to_cpu(block->bb_level) == 0) return 0; - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + return be16_to_cpu(block->bb_numrecs); } /*ARGSUSED*/ @@ -95,9 +95,8 @@ cntbt_key_offset( ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - kp = XFS_BTREE_KEY_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, idx, - XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, xfs_alloc, 0)); + ASSERT(be16_to_cpu(block->bb_level) > 0); + kp = XFS_BTREE_KEY_ADDR(xfs_alloc, block, idx); return bitize((int)((char *)kp - (char *)block)); } @@ -111,9 +110,9 @@ cntbt_ptr_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->bb_level, ARCH_CONVERT) == 0) + if (be16_to_cpu(block->bb_level) == 0) return 0; - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + return be16_to_cpu(block->bb_numrecs); } /*ARGSUSED*/ @@ -128,8 +127,8 @@ cntbt_ptr_offset( ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, idx, + ASSERT(be16_to_cpu(block->bb_level) > 0); + pp = XFS_BTREE_PTR_ADDR(xfs_alloc, block, idx, XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, xfs_alloc, 0)); return bitize((int)((char *)pp - (char *)block)); } @@ -144,9 +143,9 @@ cntbt_rec_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->bb_level, ARCH_CONVERT) > 0) + if (be16_to_cpu(block->bb_level) > 0) return 0; - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + return be16_to_cpu(block->bb_numrecs); } /*ARGSUSED*/ @@ -161,9 +160,8 @@ cntbt_rec_offset( ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) == 0); - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, idx, - XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, xfs_alloc, 1)); + ASSERT(be16_to_cpu(block->bb_level) == 0); + rp = XFS_BTREE_REC_ADDR(xfs_alloc, block, idx); return bitize((int)((char *)rp - (char *)block)); } diff --git a/db/dir.c b/db/dir.c index 633fc2d1b..4b7e9dce5 100644 --- a/db/dir.c +++ b/db/dir.c @@ -126,9 +126,9 @@ dir_leaf_entries_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->hdr.info.magic, ARCH_CONVERT) != XFS_DIR_LEAF_MAGIC) + if (be16_to_cpu(block->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) return 0; - return INT_GET(block->hdr.count, ARCH_CONVERT); + return be16_to_cpu(block->hdr.count); } /*ARGSUSED*/ @@ -141,7 +141,7 @@ dir_leaf_hdr_count( ASSERT(startoff == 0); block = obj; - return INT_GET(block->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC; + return be16_to_cpu(block->hdr.info.magic) == XFS_DIR_LEAF_MAGIC; } static int @@ -157,11 +157,11 @@ dir_leaf_name_count( ASSERT(bitoffs(startoff) == 0); off = byteize(startoff); block = obj; - if (INT_GET(block->hdr.info.magic, ARCH_CONVERT) != XFS_DIR_LEAF_MAGIC) + if (be16_to_cpu(block->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) return 0; - for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) { + for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { e = &block->entries[i]; - if (INT_GET(e->nameidx, ARCH_CONVERT) == off) + if (be16_to_cpu(e->nameidx) == off) return e->namelen; } return 0; @@ -179,10 +179,10 @@ dir_leaf_name_size( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->hdr.info.magic, ARCH_CONVERT) != XFS_DIR_LEAF_MAGIC) + if (be16_to_cpu(block->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) return 0; e = &block->entries[idx]; - return bitize((int)XFS_DIR_LEAF_ENTSIZE_BYENTRY(e)); + return bitize((int)xfs_dir_leaf_entsize_byentry(e)); } /*ARGSUSED*/ @@ -195,9 +195,9 @@ dir_leaf_namelist_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->hdr.info.magic, ARCH_CONVERT) != XFS_DIR_LEAF_MAGIC) + if (be16_to_cpu(block->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) return 0; - return INT_GET(block->hdr.count, ARCH_CONVERT); + return be16_to_cpu(block->hdr.count); } /*ARGSUSED*/ @@ -213,7 +213,7 @@ dir_leaf_namelist_offset( ASSERT(startoff == 0); block = obj; e = &block->entries[idx]; - return bitize(INT_GET(e->nameidx, ARCH_CONVERT)); + return bitize(be16_to_cpu(e->nameidx)); } /*ARGSUSED*/ @@ -226,9 +226,9 @@ dir_node_btree_count( ASSERT(startoff == 0); /* this is a base structure */ block = obj; - if (INT_GET(block->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC) + if (be16_to_cpu(block->hdr.info.magic) != XFS_DA_NODE_MAGIC) return 0; - return INT_GET(block->hdr.count, ARCH_CONVERT); + return be16_to_cpu(block->hdr.count); } /*ARGSUSED*/ @@ -241,7 +241,7 @@ dir_node_hdr_count( ASSERT(startoff == 0); block = obj; - return INT_GET(block->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC; + return be16_to_cpu(block->hdr.info.magic) == XFS_DA_NODE_MAGIC; } /*ARGSUSED*/ diff --git a/db/dir2.c b/db/dir2.c index cb6770df7..51c598b32 100644 --- a/db/dir2.c +++ b/db/dir2.c @@ -176,7 +176,7 @@ dir2_block_hdr_count( ASSERT(startoff == 0); block = obj; - return INT_GET(block->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC; + return be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC; } /*ARGSUSED*/ @@ -190,10 +190,10 @@ dir2_block_leaf_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->hdr.magic, ARCH_CONVERT) != XFS_DIR2_BLOCK_MAGIC) + if (be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC) return 0; - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); - return INT_GET(btp->count, ARCH_CONVERT); + btp = xfs_dir2_block_tail_p(mp, block); + return be32_to_cpu(btp->count); } /*ARGSUSED*/ @@ -209,9 +209,9 @@ dir2_block_leaf_offset( ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); - lep = XFS_DIR2_BLOCK_LEAF_P(btp) + idx; + ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); + btp = xfs_dir2_block_tail_p(mp, block); + lep = xfs_dir2_block_leaf_p(btp) + idx; return bitize((int)((char *)lep - (char *)block)); } @@ -225,7 +225,7 @@ dir2_block_tail_count( ASSERT(startoff == 0); block = obj; - return INT_GET(block->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC; + return be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC; } /*ARGSUSED*/ @@ -241,8 +241,8 @@ dir2_block_tail_offset( ASSERT(startoff == 0); ASSERT(idx == 0); block = obj; - ASSERT(INT_GET(block->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); + ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); + btp = xfs_dir2_block_tail_p(mp, block); return bitize((int)((char *)btp - (char *)block)); } @@ -262,18 +262,18 @@ dir2_block_u_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->hdr.magic, ARCH_CONVERT) != XFS_DIR2_BLOCK_MAGIC) + if (be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC) return 0; - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); + btp = xfs_dir2_block_tail_p(mp, block); ptr = (char *)block->u; - endptr = (char *)XFS_DIR2_BLOCK_LEAF_P(btp); + endptr = (char *)xfs_dir2_block_leaf_p(btp); for (i = 0; ptr < endptr; i++) { dup = (xfs_dir2_data_unused_t *)ptr; - if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) - ptr += INT_GET(dup->length, ARCH_CONVERT); + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) + ptr += be16_to_cpu(dup->length); else { dep = (xfs_dir2_data_entry_t *)ptr; - ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen); + ptr += xfs_dir2_data_entsize(dep->namelen); } } return i; @@ -290,25 +290,24 @@ dir2_block_u_offset( xfs_dir2_block_tail_t *btp; xfs_dir2_data_entry_t *dep; xfs_dir2_data_unused_t *dup; - /*REFERENCED*/ char *endptr; int i; char *ptr; ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); + ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); + btp = xfs_dir2_block_tail_p(mp, block); ptr = (char *)block->u; - endptr = (char *)XFS_DIR2_BLOCK_LEAF_P(btp); + endptr = (char *)xfs_dir2_block_leaf_p(btp); for (i = 0; i < idx; i++) { ASSERT(ptr < endptr); dup = (xfs_dir2_data_unused_t *)ptr; - if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) - ptr += INT_GET(dup->length, ARCH_CONVERT); + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) + ptr += be16_to_cpu(dup->length); else { dep = (xfs_dir2_data_entry_t *)ptr; - ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen); + ptr += xfs_dir2_data_entsize(dep->namelen); } } return bitize((int)(ptr - (char *)block)); @@ -326,7 +325,7 @@ dir2_data_union_freetag_count( dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff)); end = (char *)&dup->freetag + sizeof(dup->freetag); return end <= (char *)obj + mp->m_dirblksize && - INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG; + be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG; } static int @@ -343,7 +342,7 @@ dir2_data_union_inumber_count( dep = (xfs_dir2_data_entry_t *)dup; end = (char *)&dep->inumber + sizeof(dep->inumber); return end <= (char *)obj + mp->m_dirblksize && - INT_GET(dup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG; + be16_to_cpu(dup->freetag) != XFS_DIR2_DATA_FREE_TAG; } static int @@ -358,7 +357,7 @@ dir2_data_union_length_count( dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff)); end = (char *)&dup->length + sizeof(dup->length); return end <= (char *)obj + mp->m_dirblksize && - INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG; + be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG; } static int @@ -375,7 +374,7 @@ dir2_data_union_name_count( dep = (xfs_dir2_data_entry_t *)dup; end = (char *)&dep->namelen + sizeof(dep->namelen); if (end >= (char *)obj + mp->m_dirblksize || - INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) + be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) return 0; end = (char *)&dep->name[0] + dep->namelen; return end <= (char *)obj + mp->m_dirblksize ? dep->namelen : 0; @@ -395,7 +394,7 @@ dir2_data_union_namelen_count( dep = (xfs_dir2_data_entry_t *)dup; end = (char *)&dep->namelen + sizeof(dep->namelen); return end <= (char *)obj + mp->m_dirblksize && - INT_GET(dup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG; + be16_to_cpu(dup->freetag) != XFS_DIR2_DATA_FREE_TAG; } static int @@ -406,7 +405,7 @@ dir2_data_union_tag_count( xfs_dir2_data_entry_t *dep; xfs_dir2_data_unused_t *dup; char *end; - xfs_dir2_data_off_t *tagp; + __be16 *tagp; ASSERT(bitoffs(startoff) == 0); dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff)); @@ -414,16 +413,16 @@ dir2_data_union_tag_count( end = (char *)&dup->freetag + sizeof(dup->freetag); if (end > (char *)obj + mp->m_dirblksize) return 0; - if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) { + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { end = (char *)&dup->length + sizeof(dup->length); if (end > (char *)obj + mp->m_dirblksize) return 0; - tagp = XFS_DIR2_DATA_UNUSED_TAG_P(dup); + tagp = xfs_dir2_data_unused_tag_p(dup); } else { end = (char *)&dep->namelen + sizeof(dep->namelen); if (end > (char *)obj + mp->m_dirblksize) return 0; - tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); + tagp = xfs_dir2_data_entry_tag_p(dep); } end = (char *)tagp + sizeof(*tagp); return end <= (char *)obj + mp->m_dirblksize; @@ -442,11 +441,11 @@ dir2_data_union_tag_offset( ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff)); - if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) - return bitize((int)((char *)XFS_DIR2_DATA_UNUSED_TAG_P(dup) - + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) + return bitize((int)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)dup)); dep = (xfs_dir2_data_entry_t *)dup; - return bitize((int)((char *)XFS_DIR2_DATA_ENTRY_TAG_P(dep) - + return bitize((int)((char *)xfs_dir2_data_entry_tag_p(dep) - (char *)dep)); } @@ -460,7 +459,7 @@ dir2_data_hdr_count( ASSERT(startoff == 0); data = obj; - return INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC; + return be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC; } /*ARGSUSED*/ @@ -478,17 +477,17 @@ dir2_data_u_count( ASSERT(startoff == 0); data = obj; - if (INT_GET(data->hdr.magic, ARCH_CONVERT) != XFS_DIR2_DATA_MAGIC) + if (be32_to_cpu(data->hdr.magic) != XFS_DIR2_DATA_MAGIC) return 0; ptr = (char *)data->u; endptr = (char *)data + mp->m_dirblksize; for (i = 0; ptr < endptr; i++) { dup = (xfs_dir2_data_unused_t *)ptr; - if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) - ptr += INT_GET(dup->length, ARCH_CONVERT); + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) + ptr += be16_to_cpu(dup->length); else { dep = (xfs_dir2_data_entry_t *)ptr; - ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen); + ptr += xfs_dir2_data_entsize(dep->namelen); } } return i; @@ -511,17 +510,17 @@ dir2_data_u_offset( ASSERT(startoff == 0); data = obj; - ASSERT(INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC); + ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC); ptr = (char *)data->u; endptr = (char *)data + mp->m_dirblksize; for (i = 0; i < idx; i++) { ASSERT(ptr < endptr); dup = (xfs_dir2_data_unused_t *)ptr; - if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) - ptr += INT_GET(dup->length, ARCH_CONVERT); + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) + ptr += be16_to_cpu(dup->length); else { dep = (xfs_dir2_data_entry_t *)ptr; - ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen); + ptr += xfs_dir2_data_entsize(dep->namelen); } } return bitize((int)(ptr - (char *)data)); @@ -540,11 +539,11 @@ dir2_data_union_size( ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff)); - if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) - return bitize(INT_GET(dup->length, ARCH_CONVERT)); + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) + return bitize(be16_to_cpu(dup->length)); else { dep = (xfs_dir2_data_entry_t *)dup; - return bitize(XFS_DIR2_DATA_ENTSIZE(dep->namelen)); + return bitize(xfs_dir2_data_entsize(dep->namelen)); } } @@ -558,9 +557,9 @@ dir2_free_bests_count( ASSERT(startoff == 0); free = obj; - if (INT_GET(free->hdr.magic, ARCH_CONVERT) != XFS_DIR2_FREE_MAGIC) + if (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC) return 0; - return INT_GET(free->hdr.nvalid, ARCH_CONVERT); + return be32_to_cpu(free->hdr.nvalid); } /*ARGSUSED*/ @@ -573,7 +572,7 @@ dir2_free_hdr_count( ASSERT(startoff == 0); free = obj; - return INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC; + return be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC; } /*ARGSUSED*/ @@ -587,10 +586,10 @@ dir2_leaf_bests_count( ASSERT(startoff == 0); leaf = obj; - if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR2_LEAF1_MAGIC) + if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAF1_MAGIC) return 0; - ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); - return INT_GET(ltp->bestcount, ARCH_CONVERT); + ltp = xfs_dir2_leaf_tail_p(mp, leaf); + return be32_to_cpu(ltp->bestcount); } /*ARGSUSED*/ @@ -600,15 +599,15 @@ dir2_leaf_bests_offset( int startoff, int idx) { - xfs_dir2_data_off_t *lbp; + __be16 *lbp; xfs_dir2_leaf_t *leaf; xfs_dir2_leaf_tail_t *ltp; ASSERT(startoff == 0); leaf = obj; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC); - ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); - lbp = XFS_DIR2_LEAF_BESTS_P(ltp) + idx; + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); + ltp = xfs_dir2_leaf_tail_p(mp, leaf); + lbp = xfs_dir2_leaf_bests_p(ltp) + idx; return bitize((int)((char *)lbp - (char *)leaf)); } @@ -622,10 +621,10 @@ dir2_leaf_ents_count( ASSERT(startoff == 0); leaf = obj; - if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR2_LEAF1_MAGIC && - INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR2_LEAFN_MAGIC) + if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAF1_MAGIC && + be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAFN_MAGIC) return 0; - return INT_GET(leaf->hdr.count, ARCH_CONVERT); + return be16_to_cpu(leaf->hdr.count); } /*ARGSUSED*/ @@ -638,8 +637,8 @@ dir2_leaf_hdr_count( ASSERT(startoff == 0); leaf = obj; - return INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC || - INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC; + return be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC || + be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC; } /*ARGSUSED*/ @@ -652,7 +651,7 @@ dir2_leaf_tail_count( ASSERT(startoff == 0); leaf = obj; - return INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC; + return be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC; } /*ARGSUSED*/ @@ -668,8 +667,8 @@ dir2_leaf_tail_offset( ASSERT(startoff == 0); ASSERT(idx == 0); leaf = obj; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC); - ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); + ltp = xfs_dir2_leaf_tail_p(mp, leaf); return bitize((int)((char *)ltp - (char *)leaf)); } @@ -683,9 +682,9 @@ dir2_node_btree_count( ASSERT(startoff == 0); node = obj; - if (INT_GET(node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC) + if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) return 0; - return INT_GET(node->hdr.count, ARCH_CONVERT); + return be16_to_cpu(node->hdr.count); } /*ARGSUSED*/ @@ -698,7 +697,7 @@ dir2_node_hdr_count( ASSERT(startoff == 0); node = obj; - return INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC; + return be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC; } /*ARGSUSED*/ diff --git a/db/dir2sf.c b/db/dir2sf.c index 459bcedb7..426ad1667 100644 --- a/db/dir2sf.c +++ b/db/dir2sf.c @@ -134,7 +134,7 @@ dir2_sf_entry_inumber_offset( ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); e = (xfs_dir2_sf_entry_t *)((char *)obj + byteize(startoff)); - return bitize((int)((char *)XFS_DIR2_SF_INUMBERP(e) - (char *)e)); + return bitize((int)((char *)xfs_dir2_sf_inumberp(e) - (char *)e)); } int @@ -149,10 +149,10 @@ dir2_sf_entry_size( ASSERT(bitoffs(startoff) == 0); sf = (xfs_dir2_sf_t *)((char *)obj + byteize(startoff)); - e = XFS_DIR2_SF_FIRSTENTRY(sf); + e = xfs_dir2_sf_firstentry(sf); for (i = 0; i < idx; i++) - e = XFS_DIR2_SF_NEXTENTRY(sf, e); - return bitize((int)XFS_DIR2_SF_ENTSIZE_BYENTRY(sf, e)); + e = xfs_dir2_sf_nextentry(sf, e); + return bitize((int)xfs_dir2_sf_entsize_byentry(sf, e)); } /*ARGSUSED*/ @@ -167,7 +167,7 @@ dir2_sf_hdr_size( ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); sf = (xfs_dir2_sf_t *)((char *)obj + byteize(startoff)); - return bitize(XFS_DIR2_SF_HDR_SIZE(sf->hdr.i8count)); + return bitize(xfs_dir2_sf_hdr_size(sf->hdr.i8count)); } static int @@ -194,9 +194,9 @@ dir2_sf_list_offset( ASSERT(bitoffs(startoff) == 0); sf = (xfs_dir2_sf_t *)((char *)obj + byteize(startoff)); - e = XFS_DIR2_SF_FIRSTENTRY(sf); + e = xfs_dir2_sf_firstentry(sf); for (i = 0; i < idx; i++) - e = XFS_DIR2_SF_NEXTENTRY(sf, e); + e = xfs_dir2_sf_nextentry(sf, e); return bitize((int)((char *)e - (char *)sf)); } @@ -214,8 +214,8 @@ dir2sf_size( ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); sf = (xfs_dir2_sf_t *)((char *)obj + byteize(startoff)); - e = XFS_DIR2_SF_FIRSTENTRY(sf); + e = xfs_dir2_sf_firstentry(sf); for (i = 0; i < sf->hdr.count; i++) - e = XFS_DIR2_SF_NEXTENTRY(sf, e); + e = xfs_dir2_sf_nextentry(sf, e); return bitize((int)((char *)e - (char *)sf)); } diff --git a/db/dirshort.c b/db/dirshort.c index 8cc590ca7..b0d3b6bf9 100644 --- a/db/dirshort.c +++ b/db/dirshort.c @@ -78,8 +78,8 @@ dir_sf_entry_size( sf = (xfs_dir_shortform_t *)((char *)obj + byteize(startoff)); e = &sf->list[0]; for (i = 0; i < idx; i++) - e = XFS_DIR_SF_NEXTENTRY(e); - return bitize((int)XFS_DIR_SF_ENTSIZE_BYENTRY(e)); + e = xfs_dir_sf_nextentry(e); + return bitize((int)xfs_dir_sf_entsize_byentry(e)); } static int @@ -108,7 +108,7 @@ dir_shortform_list_offset( sf = (xfs_dir_shortform_t *)((char *)obj + byteize(startoff)); e = &sf->list[0]; for (i = 0; i < idx; i++) - e = XFS_DIR_SF_NEXTENTRY(e); + e = xfs_dir_sf_nextentry(e); return bitize((int)((char *)e - (char *)sf)); } @@ -127,6 +127,6 @@ dirshort_size( sf = (xfs_dir_shortform_t *)((char *)obj + byteize(startoff)); e = &sf->list[0]; for (i = 0; i < sf->hdr.count; i++) - e = XFS_DIR_SF_NEXTENTRY(e); + e = xfs_dir_sf_nextentry(e); return bitize((int)((char *)e - (char *)sf)); } diff --git a/db/frag.c b/db/frag.c index 35f3f37db..f877c0159 100644 --- a/db/frag.c +++ b/db/frag.c @@ -251,23 +251,17 @@ process_btinode( xfs_bmbt_rec_32_t *rp; dib = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); - if (INT_GET(dib->bb_level, ARCH_CONVERT) == 0) { - rp = (xfs_bmbt_rec_32_t *)XFS_BTREE_REC_ADDR( - XFS_DFORK_SIZE(dip, mp, whichfork), - xfs_bmdr, dib, 1, - XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_SIZE(dip, mp, - whichfork), - xfs_bmdr, 1)); - process_bmbt_reclist(rp, INT_GET(dib->bb_numrecs, ARCH_CONVERT), extmapp); + if (be16_to_cpu(dib->bb_level) == 0) { + rp = (xfs_bmbt_rec_32_t *)XFS_BTREE_REC_ADDR(xfs_bmdr, dib, 1); + process_bmbt_reclist(rp, be16_to_cpu(dib->bb_numrecs), extmapp); return; } - pp = XFS_BTREE_PTR_ADDR(XFS_DFORK_SIZE(dip, mp, whichfork), - xfs_bmdr, dib, 1, + pp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dib, 1, XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_SIZE(dip, mp, whichfork), xfs_bmdr, 0)); - for (i = 0; i < INT_GET(dib->bb_numrecs, ARCH_CONVERT); i++) - scan_lbtree((xfs_fsblock_t)INT_GET(pp[i], ARCH_CONVERT), INT_GET(dib->bb_level, ARCH_CONVERT), scanfunc_bmap, - extmapp, + for (i = 0; i < be16_to_cpu(dib->bb_numrecs); i++) + scan_lbtree(be64_to_cpu(pp[i]), be16_to_cpu(dib->bb_level), + scanfunc_bmap, extmapp, whichfork == XFS_DATA_FORK ? TYP_BMAPBTD : TYP_BMAPBTA); } @@ -280,7 +274,7 @@ process_exinode( xfs_bmbt_rec_32_t *rp; rp = (xfs_bmbt_rec_32_t *)XFS_DFORK_PTR(dip, whichfork); - process_bmbt_reclist(rp, XFS_DFORK_NEXTENTS_HOST(dip, whichfork), extmapp); + process_bmbt_reclist(rp, XFS_DFORK_NEXTENTS(dip, whichfork), extmapp); } static void @@ -291,7 +285,7 @@ process_fork( extmap_t *extmap; int nex; - nex = XFS_DFORK_NEXTENTS_HOST(dip, whichfork); + nex = XFS_DFORK_NEXTENTS(dip, whichfork); if (!nex) return; extmap = extmap_alloc(nex); @@ -322,13 +316,13 @@ process_inode( int skipd; dic = &dip->di_core; - ino = XFS_AGINO_TO_INO(mp, INT_GET(agf->agf_seqno, ARCH_CONVERT), agino); - switch (dic->di_mode & S_IFMT) { + ino = XFS_AGINO_TO_INO(mp, be32_to_cpu(agf->agf_seqno), agino); + switch (be16_to_cpu(dic->di_mode) & S_IFMT) { case S_IFDIR: skipd = !dflag; break; case S_IFREG: - if (!rflag && (dic->di_flags & XFS_DIFLAG_REALTIME)) + if (!rflag && (be16_to_cpu(dic->di_flags) & XFS_DIFLAG_REALTIME)) skipd = 1; else if (!Rflag && (ino == mp->m_sb.sb_rbmino || @@ -386,10 +380,8 @@ scan_ag( pop_cur(); return; } - scan_sbtree(agf, - INT_GET(agi->agi_root, ARCH_CONVERT), - INT_GET(agi->agi_level, ARCH_CONVERT), - scanfunc_ino, TYP_INOBT); + scan_sbtree(agf, be32_to_cpu(agi->agi_root), + be32_to_cpu(agi->agi_level), scanfunc_ino, TYP_INOBT); pop_cur(); pop_cur(); } @@ -423,7 +415,7 @@ scan_sbtree( scan_sbtree_f_t func, typnm_t btype) { - xfs_agnumber_t seqno = INT_GET(agf->agf_seqno, ARCH_CONVERT); + xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); push_cur(); set_cur(&typtab[btype], XFS_AGB_TO_DADDR(mp, seqno, root), @@ -446,19 +438,18 @@ scanfunc_bmap( xfs_bmbt_block_t *block = (xfs_bmbt_block_t *)ablock; int i; xfs_bmbt_ptr_t *pp; - xfs_bmbt_rec_32_t *rp; + xfs_bmbt_rec_t *rp; if (level == 0) { - rp = (xfs_bmbt_rec_32_t *) - XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, - block, 1, mp->m_bmap_dmxr[0]); - process_bmbt_reclist(rp, INT_GET(block->bb_numrecs, ARCH_CONVERT), extmapp); + rp = XFS_BTREE_REC_ADDR(xfs_bmbt, block, 1); + process_bmbt_reclist((xfs_bmbt_rec_32_t *)rp, + be16_to_cpu(block->bb_numrecs), extmapp); return; } - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, 1, - mp->m_bmap_dmxr[0]); - for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) - scan_lbtree(INT_GET(pp[i], ARCH_CONVERT), level, scanfunc_bmap, extmapp, btype); + pp = XFS_BTREE_PTR_ADDR(xfs_bmbt, block, 1, mp->m_bmap_dmxr[0]); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) + scan_lbtree(be64_to_cpu(pp[i]), level, scanfunc_bmap, extmapp, + btype); } static void @@ -469,7 +460,7 @@ scanfunc_ino( { xfs_agino_t agino; xfs_inobt_block_t *block = (xfs_inobt_block_t *)ablock; - xfs_agnumber_t seqno = INT_GET(agf->agf_seqno, ARCH_CONVERT); + xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); int i; int j; int off; @@ -477,10 +468,9 @@ scanfunc_ino( xfs_inobt_rec_t *rp; if (level == 0) { - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_inobt, block, - 1, mp->m_inobt_mxr[0]); - for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) { - agino = INT_GET(rp[i].ir_startino, ARCH_CONVERT); + rp = XFS_BTREE_REC_ADDR(xfs_inobt, block, 1); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) { + agino = be32_to_cpu(rp[i].ir_startino); off = XFS_INO_TO_OFFSET(mp, agino); push_cur(); set_cur(&typtab[TYP_INODE], @@ -494,27 +484,18 @@ scanfunc_ino( continue; } for (j = 0; j < XFS_INODES_PER_CHUNK; j++) { - xfs_dinode_t *dip; - xfs_dinode_core_t tdic; - - dip=(xfs_dinode_t *)((char *)iocur_top->data + ((off + j) << mp->m_sb.sb_inodelog)); - - /* convert the core, then copy it back into the inode */ - libxfs_xlate_dinode_core( (xfs_caddr_t) - &dip->di_core, &tdic, 1); - memcpy(&dip->di_core, &tdic, sizeof(xfs_dinode_core_t)); - if (XFS_INOBT_IS_FREE_DISK(&rp[i], j)) continue; - process_inode(agf, agino + j, - (xfs_dinode_t *)((char *)iocur_top->data + ((off + j) << mp->m_sb.sb_inodelog))); + process_inode(agf, agino + j, (xfs_dinode_t *) + ((char *)iocur_top->data + + ((off + j) << mp->m_sb.sb_inodelog))); } pop_cur(); } return; } - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_inobt, block, 1, - mp->m_inobt_mxr[1]); - for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) - scan_sbtree(agf, INT_GET(pp[i], ARCH_CONVERT), level, scanfunc_ino, TYP_INOBT); + pp = XFS_BTREE_PTR_ADDR(xfs_inobt, block, 1, mp->m_inobt_mxr[1]); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) + scan_sbtree(agf, be32_to_cpu(pp[i]), level, scanfunc_ino, + TYP_INOBT); } diff --git a/db/freesp.c b/db/freesp.c index 336432a65..e72fc2d8e 100644 --- a/db/freesp.c +++ b/db/freesp.c @@ -208,22 +208,17 @@ scan_ag( xfs_agf_t *agf; push_cur(); - set_cur(&typtab[TYP_AGF], - XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), - XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); + set_cur(&typtab[TYP_AGF], XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), + XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); agf = iocur_top->data; scan_freelist(agf); if (countflag) - scan_sbtree(agf, - INT_GET(agf->agf_roots[XFS_BTNUM_CNT], ARCH_CONVERT), - TYP_CNTBT, - INT_GET(agf->agf_levels[XFS_BTNUM_CNT], ARCH_CONVERT), + scan_sbtree(agf, be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]), + TYP_CNTBT, be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]), scanfunc_cnt); else - scan_sbtree(agf, - INT_GET(agf->agf_roots[XFS_BTNUM_BNO], ARCH_CONVERT), - TYP_BNOBT, - INT_GET(agf->agf_levels[XFS_BTNUM_BNO], ARCH_CONVERT), + scan_sbtree(agf, be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]), + TYP_BNOBT, be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]), scanfunc_bno); pop_cur(); } @@ -232,23 +227,22 @@ static void scan_freelist( xfs_agf_t *agf) { - xfs_agnumber_t seqno = INT_GET(agf->agf_seqno, ARCH_CONVERT); + xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); xfs_agfl_t *agfl; xfs_agblock_t bno; int i; - if (INT_GET(agf->agf_flcount, ARCH_CONVERT) == 0) + if (be32_to_cpu(agf->agf_flcount) == 0) return; push_cur(); - set_cur(&typtab[TYP_AGFL], - XFS_AG_DADDR(mp, seqno, XFS_AGFL_DADDR(mp)), - XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); + set_cur(&typtab[TYP_AGFL], XFS_AG_DADDR(mp, seqno, XFS_AGFL_DADDR(mp)), + XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); agfl = iocur_top->data; - i = INT_GET(agf->agf_flfirst, ARCH_CONVERT); + i = be32_to_cpu(agf->agf_flfirst); for (;;) { - bno = INT_GET(agfl->agfl_bno[i], ARCH_CONVERT); + bno = be32_to_cpu(agfl->agfl_bno[i]); addtohist(seqno, bno, 1); - if (i == INT_GET(agf->agf_fllast, ARCH_CONVERT)) + if (i == be32_to_cpu(agf->agf_fllast)) break; if (++i == XFS_AGFL_SIZE(mp)) i = 0; @@ -267,7 +261,7 @@ scan_sbtree( int level, xfs_agf_t *agf)) { - xfs_agnumber_t seqno = INT_GET(agf->agf_seqno, ARCH_CONVERT); + xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); push_cur(); set_cur(&typtab[typ], XFS_AGB_TO_DADDR(mp, seqno, root), @@ -294,19 +288,16 @@ scanfunc_bno( xfs_alloc_rec_t *rp; if (level == 0) { - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, - 1, mp->m_alloc_mxr[0]); - for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) - addtohist(INT_GET(agf->agf_seqno, ARCH_CONVERT), - INT_GET(rp[i].ar_startblock, ARCH_CONVERT), - INT_GET(rp[i].ar_blockcount, ARCH_CONVERT)); + rp = XFS_BTREE_REC_ADDR(xfs_alloc, block, 1); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) + addtohist(be32_to_cpu(agf->agf_seqno), + be32_to_cpu(rp[i].ar_startblock), + be32_to_cpu(rp[i].ar_blockcount)); return; } - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, 1, - mp->m_alloc_mxr[1]); - for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) - scan_sbtree(agf, INT_GET(pp[i], ARCH_CONVERT), typ, level, - scanfunc_bno); + pp = XFS_BTREE_PTR_ADDR(xfs_alloc, block, 1, mp->m_alloc_mxr[1]); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) + scan_sbtree(agf, be32_to_cpu(pp[i]), typ, level, scanfunc_bno); } static void @@ -322,19 +313,16 @@ scanfunc_cnt( xfs_alloc_rec_t *rp; if (level == 0) { - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, - 1, mp->m_alloc_mxr[0]); - for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) - addtohist(INT_GET(agf->agf_seqno, ARCH_CONVERT), - INT_GET(rp[i].ar_startblock, ARCH_CONVERT), - INT_GET(rp[i].ar_blockcount, ARCH_CONVERT)); + rp = XFS_BTREE_REC_ADDR(xfs_alloc, block, 1); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) + addtohist(be32_to_cpu(agf->agf_seqno), + be32_to_cpu(rp[i].ar_startblock), + be32_to_cpu(rp[i].ar_blockcount)); return; } - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, 1, - mp->m_alloc_mxr[1]); - for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) - scan_sbtree(agf, INT_GET(pp[i], ARCH_CONVERT), typ, level, - scanfunc_cnt); + pp = XFS_BTREE_PTR_ADDR(xfs_alloc, block, 1, mp->m_alloc_mxr[1]); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) + scan_sbtree(agf, be32_to_cpu(pp[i]), typ, level, scanfunc_cnt); } static void diff --git a/db/init.c b/db/init.c index 27be16818..af5a850fc 100644 --- a/db/init.c +++ b/db/init.c @@ -113,7 +113,7 @@ init( } /* copy SB from buffer to in-core, converting architecture as we go */ - libxfs_xlate_sb(bufp, &xmount.m_sb, 1, XFS_SB_ALL_BITS); + libxfs_sb_from_disk(&xmount.m_sb, bufp); xfree(bufp); sbp = &xmount.m_sb; diff --git a/db/inobt.c b/db/inobt.c index bb1dfdb52..ef2cd7086 100644 --- a/db/inobt.c +++ b/db/inobt.c @@ -78,9 +78,9 @@ inobt_key_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->bb_level, ARCH_CONVERT) == 0) + if (be16_to_cpu(block->bb_level) == 0) return 0; - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + return be16_to_cpu(block->bb_numrecs); } /*ARGSUSED*/ @@ -95,9 +95,8 @@ inobt_key_offset( ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - kp = XFS_BTREE_KEY_ADDR(mp->m_sb.sb_blocksize, xfs_inobt, block, idx, - XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, xfs_inobt, 0)); + ASSERT(be16_to_cpu(block->bb_level) > 0); + kp = XFS_BTREE_KEY_ADDR(xfs_inobt, block, idx); return bitize((int)((char *)kp - (char *)block)); } @@ -111,9 +110,9 @@ inobt_ptr_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->bb_level, ARCH_CONVERT) == 0) + if (be16_to_cpu(block->bb_level) == 0) return 0; - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + return be16_to_cpu(block->bb_numrecs); } /*ARGSUSED*/ @@ -128,8 +127,8 @@ inobt_ptr_offset( ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_inobt, block, idx, + ASSERT(be16_to_cpu(block->bb_level) > 0); + pp = XFS_BTREE_PTR_ADDR(xfs_inobt, block, idx, XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, xfs_inobt, 0)); return bitize((int)((char *)pp - (char *)block)); } @@ -144,9 +143,9 @@ inobt_rec_count( ASSERT(startoff == 0); block = obj; - if (INT_GET(block->bb_level, ARCH_CONVERT) > 0) + if (be16_to_cpu(block->bb_level) > 0) return 0; - return INT_GET(block->bb_numrecs, ARCH_CONVERT); + return be16_to_cpu(block->bb_numrecs); } /*ARGSUSED*/ @@ -161,9 +160,8 @@ inobt_rec_offset( ASSERT(startoff == 0); block = obj; - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) == 0); - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_inobt, block, idx, - XFS_BTREE_BLOCK_MAXRECS(mp->m_sb.sb_blocksize, xfs_inobt, 1)); + ASSERT(be16_to_cpu(block->bb_level) == 0); + rp = XFS_BTREE_REC_ADDR(xfs_inobt, block, idx); return bitize((int)((char *)rp - (char *)block)); } diff --git a/db/inode.c b/db/inode.c index 39e70f05a..6b93eff91 100644 --- a/db/inode.c +++ b/db/inode.c @@ -156,24 +156,24 @@ const field_t timestamp_flds[] = { }; const field_t inode_u_flds[] = { - { "bmbt", FLDT_BMROOTD, 0, inode_u_bmbt_count, FLD_COUNT, TYP_NONE }, - { "bmx", FLDT_BMAPBTDREC, 0, inode_u_bmx_count, FLD_ARRAY|FLD_COUNT, + { "bmbt", FLDT_BMROOTD, NULL, inode_u_bmbt_count, FLD_COUNT, TYP_NONE }, + { "bmx", FLDT_BMAPBTDREC, NULL, inode_u_bmx_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, - { "c", FLDT_CHARNS, 0, inode_u_c_count, FLD_COUNT, TYP_NONE }, - { "dev", FLDT_DEV, 0, inode_u_dev_count, FLD_COUNT, TYP_NONE }, - { "muuid", FLDT_UUID, 0, inode_u_muuid_count, FLD_COUNT, TYP_NONE }, - { "sfdir", FLDT_DIRSHORT, 0, inode_u_sfdir_count, FLD_COUNT, TYP_NONE }, - { "sfdir2", FLDT_DIR2SF, 0, inode_u_sfdir2_count, FLD_COUNT, TYP_NONE }, - { "symlink", FLDT_CHARNS, 0, inode_u_symlink_count, FLD_COUNT, + { "c", FLDT_CHARNS, NULL, inode_u_c_count, FLD_COUNT, TYP_NONE }, + { "dev", FLDT_DEV, NULL, inode_u_dev_count, FLD_COUNT, TYP_NONE }, + { "muuid", FLDT_UUID, NULL, inode_u_muuid_count, FLD_COUNT, TYP_NONE }, + { "sfdir", FLDT_DIRSHORT, NULL, inode_u_sfdir_count, FLD_COUNT, TYP_NONE }, + { "sfdir2", FLDT_DIR2SF, NULL, inode_u_sfdir2_count, FLD_COUNT, TYP_NONE }, + { "symlink", FLDT_CHARNS, NULL, inode_u_symlink_count, FLD_COUNT, TYP_NONE }, { NULL } }; const field_t inode_a_flds[] = { - { "bmbt", FLDT_BMROOTA, 0, inode_a_bmbt_count, FLD_COUNT, TYP_NONE }, - { "bmx", FLDT_BMAPBTAREC, 0, inode_a_bmx_count, FLD_ARRAY|FLD_COUNT, + { "bmbt", FLDT_BMROOTA, NULL, inode_a_bmbt_count, FLD_COUNT, TYP_NONE }, + { "bmx", FLDT_BMAPBTAREC, NULL, inode_a_bmx_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, - { "sfattr", FLDT_ATTRSHORT, 0, inode_a_sfattr_count, FLD_COUNT, + { "sfattr", FLDT_ATTRSHORT, NULL, inode_a_sfattr_count, FLD_COUNT, TYP_NONE }, { NULL } }; @@ -226,7 +226,7 @@ inode_a_bmbt_count( if (!XFS_DFORK_Q(dip)) return 0; ASSERT((char *)XFS_DFORK_APTR(dip) - (char *)dip == byteize(startoff)); - return INT_GET(dip->di_core.di_aformat, ARCH_CONVERT) == XFS_DINODE_FMT_BTREE; + return dip->di_core.di_aformat == XFS_DINODE_FMT_BTREE; } static int @@ -242,8 +242,8 @@ inode_a_bmx_count( if (!XFS_DFORK_Q(dip)) return 0; ASSERT((char *)XFS_DFORK_APTR(dip) - (char *)dip == byteize(startoff)); - return INT_GET(dip->di_core.di_aformat, ARCH_CONVERT) == XFS_DINODE_FMT_EXTENTS ? - INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) : 0; + return dip->di_core.di_aformat == XFS_DINODE_FMT_EXTENTS ? + be16_to_cpu(dip->di_core.di_anextents) : 0; } static int @@ -286,7 +286,7 @@ inode_a_sfattr_count( if (!XFS_DFORK_Q(dip)) return 0; ASSERT((char *)XFS_DFORK_APTR(dip) - (char *)dip == byteize(startoff)); - return INT_GET(dip->di_core.di_aformat, ARCH_CONVERT) == XFS_DINODE_FMT_LOCAL; + return dip->di_core.di_aformat == XFS_DINODE_FMT_LOCAL; } int @@ -301,12 +301,13 @@ inode_a_size( ASSERT(startoff == 0); ASSERT(idx == 0); dip = obj; - switch (INT_GET(dip->di_core.di_aformat, ARCH_CONVERT)) { + switch (dip->di_core.di_aformat) { case XFS_DINODE_FMT_LOCAL: asf = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); - return bitize((int)asf->hdr.totsize); + return bitize(be16_to_cpu(asf->hdr.totsize)); case XFS_DINODE_FMT_EXTENTS: - return (int)(INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) * bitsz(xfs_bmbt_rec_t)); + return (int)be16_to_cpu(dip->di_core.di_anextents) * + bitsz(xfs_bmbt_rec_t); case XFS_DINODE_FMT_BTREE: return bitize((int)XFS_DFORK_ASIZE(dip, mp)); default: @@ -399,7 +400,7 @@ inode_next_type(void) { switch (iocur_top->mode & S_IFMT) { case S_IFDIR: - return XFS_DIR_IS_V2(mp) ? TYP_DIR2 : TYP_DIR; + return xfs_sb_version_hasdirv2(&mp->m_sb) ? TYP_DIR2 : TYP_DIR; case S_IFLNK: return TYP_SYMLINK; case S_IFREG: @@ -437,7 +438,7 @@ inode_u_bmbt_count( ASSERT(obj == iocur_top->data); dip = obj; ASSERT((char *)&dip->di_u - (char *)dip == byteize(startoff)); - return INT_GET(dip->di_core.di_format, ARCH_CONVERT) == XFS_DINODE_FMT_BTREE; + return dip->di_core.di_format == XFS_DINODE_FMT_BTREE; } static int @@ -451,8 +452,8 @@ inode_u_bmx_count( ASSERT(obj == iocur_top->data); dip = obj; ASSERT((char *)&dip->di_u - (char *)dip == byteize(startoff)); - return INT_GET(dip->di_core.di_format, ARCH_CONVERT) == XFS_DINODE_FMT_EXTENTS ? - INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) : 0; + return dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS ? + be32_to_cpu(dip->di_core.di_nextents) : 0; } static int @@ -466,9 +467,9 @@ inode_u_c_count( ASSERT(obj == iocur_top->data); dip = obj; ASSERT((char *)&dip->di_u - (char *)dip == byteize(startoff)); - return INT_GET(dip->di_core.di_format, ARCH_CONVERT) == XFS_DINODE_FMT_LOCAL && - (INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & S_IFMT) == S_IFREG ? - (int)INT_GET(dip->di_core.di_size, ARCH_CONVERT) : 0; + return dip->di_core.di_format == XFS_DINODE_FMT_LOCAL && + (be16_to_cpu(dip->di_core.di_mode) & S_IFMT) == S_IFREG ? + (int)be64_to_cpu(dip->di_core.di_size) : 0; } static int @@ -482,7 +483,7 @@ inode_u_dev_count( ASSERT(obj == iocur_top->data); dip = obj; ASSERT((char *)&dip->di_u - (char *)dip == byteize(startoff)); - return INT_GET(dip->di_core.di_format, ARCH_CONVERT) == XFS_DINODE_FMT_DEV; + return dip->di_core.di_format == XFS_DINODE_FMT_DEV; } static int @@ -496,7 +497,7 @@ inode_u_muuid_count( ASSERT(obj == iocur_top->data); dip = obj; ASSERT((char *)&dip->di_u - (char *)dip == byteize(startoff)); - return INT_GET(dip->di_core.di_format, ARCH_CONVERT) == XFS_DINODE_FMT_UUID; + return dip->di_core.di_format == XFS_DINODE_FMT_UUID; } static int @@ -510,9 +511,9 @@ inode_u_sfdir_count( ASSERT(obj == iocur_top->data); dip = obj; ASSERT((char *)&dip->di_u - (char *)dip == byteize(startoff)); - return INT_GET(dip->di_core.di_format, ARCH_CONVERT) == XFS_DINODE_FMT_LOCAL && - (INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & S_IFMT) == S_IFDIR - && XFS_DIR_IS_V1(mp); + return dip->di_core.di_format == XFS_DINODE_FMT_LOCAL && + (be16_to_cpu(dip->di_core.di_mode) & S_IFMT) == S_IFDIR + && !xfs_sb_version_hasdirv2(&mp->m_sb); } static int @@ -526,9 +527,9 @@ inode_u_sfdir2_count( ASSERT(obj == iocur_top->data); dip = obj; ASSERT((char *)&dip->di_u - (char *)dip == byteize(startoff)); - return INT_GET(dip->di_core.di_format, ARCH_CONVERT) == XFS_DINODE_FMT_LOCAL && - (INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & S_IFMT) == S_IFDIR && - XFS_DIR_IS_V2(mp); + return dip->di_core.di_format == XFS_DINODE_FMT_LOCAL && + (be16_to_cpu(dip->di_core.di_mode) & S_IFMT) == S_IFDIR && + xfs_sb_version_hasdirv2(&mp->m_sb); } int @@ -542,13 +543,14 @@ inode_u_size( ASSERT(startoff == 0); ASSERT(idx == 0); dip = obj; - switch (INT_GET(dip->di_core.di_format, ARCH_CONVERT)) { + switch (dip->di_core.di_format) { case XFS_DINODE_FMT_DEV: return bitsz(xfs_dev_t); case XFS_DINODE_FMT_LOCAL: - return bitize((int)INT_GET(dip->di_core.di_size, ARCH_CONVERT)); + return bitize((int)be64_to_cpu(dip->di_core.di_size)); case XFS_DINODE_FMT_EXTENTS: - return (int)(INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) * bitsz(xfs_bmbt_rec_t)); + return (int)be32_to_cpu(dip->di_core.di_nextents) * + bitsz(xfs_bmbt_rec_t); case XFS_DINODE_FMT_BTREE: return bitize((int)XFS_DFORK_DSIZE(dip, mp)); case XFS_DINODE_FMT_UUID: @@ -569,9 +571,9 @@ inode_u_symlink_count( ASSERT(obj == iocur_top->data); dip = obj; ASSERT((char *)&dip->di_u - (char *)dip == byteize(startoff)); - return INT_GET(dip->di_core.di_format, ARCH_CONVERT) == XFS_DINODE_FMT_LOCAL && - (INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & S_IFMT) == S_IFLNK ? - (int)INT_GET(dip->di_core.di_size, ARCH_CONVERT) : 0; + return dip->di_core.di_format == XFS_DINODE_FMT_LOCAL && + (be16_to_cpu(dip->di_core.di_mode) & S_IFMT) == S_IFLNK ? + (int)be64_to_cpu(dip->di_core.di_size) : 0; } void @@ -607,7 +609,7 @@ set_cur_inode( off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize); dip = iocur_top->data; iocur_top->ino = ino; - iocur_top->mode = INT_GET(dip->di_core.di_mode, ARCH_CONVERT); + iocur_top->mode = be16_to_cpu(dip->di_core.di_mode); if ((iocur_top->mode & S_IFMT) == S_IFDIR) iocur_top->dirino = ino; diff --git a/db/metadump.c b/db/metadump.c index 9342d0c08..e6115ac5f 100644 --- a/db/metadump.c +++ b/db/metadump.c @@ -253,8 +253,7 @@ scanfunc_freesp( return 1; } - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, bthdr, 1, - mp->m_alloc_mxr[1]); + pp = XFS_BTREE_PTR_ADDR(xfs_alloc, bthdr, 1, mp->m_alloc_mxr[1]); for (i = 0; i < numrecs; i++) { if (!valid_bno(agno, be32_to_cpu(pp[i]))) { if (show_warnings) @@ -424,7 +423,7 @@ generate_obfuscated_name( int i; int dup; xfs_dahash_t newhash; - uchar_t newname[namelen]; + uchar_t newname[NAME_MAX]; if (is_special_dirent(ino, namelen, name)) return; @@ -499,11 +498,11 @@ obfuscate_sf_dir( { xfs_dir2_sf_t *sfp; xfs_dir2_sf_entry_t *sfep; - int ino_dir_size; + __uint64_t ino_dir_size; int i; sfp = &dip->di_u.di_dir2sf; - ino_dir_size = dip->di_core.di_size; + ino_dir_size = be64_to_cpu(dip->di_core.di_size); if (ino_dir_size > XFS_DFORK_DSIZE(dip, mp)) { ino_dir_size = XFS_DFORK_DSIZE(dip, mp); if (show_warnings) @@ -511,7 +510,7 @@ obfuscate_sf_dir( (long long)cur_ino); } - sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); + sfep = xfs_dir2_sf_firstentry(sfp); for (i = 0; (i < sfp->hdr.count) && ((char *)sfep - (char *)sfp < ino_dir_size); i++) { @@ -530,7 +529,7 @@ obfuscate_sf_dir( namelen = ino_dir_size - ((char *)&sfep->name[0] - (char *)sfp); } else if ((char *)sfep - (char *)sfp + - XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp, sfep) > + xfs_dir2_sf_entsize_byentry(sfp, sfep) > ino_dir_size) { if (show_warnings) print_warning("entry length in dir inode %llu " @@ -541,12 +540,12 @@ obfuscate_sf_dir( (char *)sfp); } - generate_obfuscated_name(XFS_DIR2_SF_GET_INUMBER(sfp, - XFS_DIR2_SF_INUMBERP(sfep)), namelen, + generate_obfuscated_name(xfs_dir2_sf_get_inumber(sfp, + xfs_dir2_sf_inumberp(sfep)), namelen, &sfep->name[0]); sfep = (xfs_dir2_sf_entry_t *)((char *)sfep + - XFS_DIR2_SF_ENTSIZE_BYNAME(sfp, namelen)); + xfs_dir2_sf_entsize_byname(sfp, namelen)); } } @@ -554,9 +553,9 @@ static void obfuscate_sf_symlink( xfs_dinode_t *dip) { - int len; + __uint64_t len; - len = dip->di_core.di_size; + len = be64_to_cpu(dip->di_core.di_size); if (len > XFS_DFORK_DSIZE(dip, mp)) { if (show_warnings) print_warning("invalid size (%d) in symlink inode %llu", @@ -668,9 +667,9 @@ obfuscate_dir_data_blocks( xfs_dir2_leaf_entry_t *blp; xfs_dir2_block_tail_t *btp; - btp = XFS_DIR2_BLOCK_TAIL_P(mp, + btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)block); - blp = XFS_DIR2_BLOCK_LEAF_P(btp); + blp = xfs_dir2_block_leaf_p(btp); if ((char *)blp > (char *)btp) blp = (xfs_dir2_leaf_entry_t *)btp; @@ -726,7 +725,7 @@ obfuscate_dir_data_blocks( dir_data.bad_block = 1; break; } - if (be16_to_cpu(*XFS_DIR2_DATA_UNUSED_TAG_P(dup)) != + if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) != dir_offset) { dir_data.bad_block = 1; break; @@ -739,7 +738,7 @@ obfuscate_dir_data_blocks( } dep = (xfs_dir2_data_entry_t *)ptr; - length = XFS_DIR2_DATA_ENTSIZE(dep->namelen); + length = xfs_dir2_data_entsize(dep->namelen); if (dir_offset + length > dir_data.end_of_data || ptr + length > endptr) { @@ -749,7 +748,7 @@ obfuscate_dir_data_blocks( (long long)cur_ino); break; } - if (be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep)) != + if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) != dir_offset) { dir_data.bad_block = 1; break; @@ -1003,7 +1002,6 @@ scanfunc_bmap( { int i; xfs_bmbt_ptr_t *pp; - xfs_bmbt_rec_t *rp; int nrecs; nrecs = be16_to_cpu(bthdr->bb_numrecs); @@ -1016,10 +1014,8 @@ scanfunc_bmap( typtab[btype].name, agno, agbno); return 1; } - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sqb_blocksize, xfs_bmbt, bthdr, - 1, mp->m_bmap_dmxr[0]); - - return process_bmbt_reclist(rp, nrecs, *(typnm_t*)arg); + return process_bmbt_reclist(XFS_BTREE_REC_ADDR(xfs_bmbt, + bthdr, 1), nrecs, *(typnm_t*)arg); } if (nrecs > mp->m_bmap_dmxr[1]) { @@ -1028,8 +1024,7 @@ scanfunc_bmap( nrecs, typtab[btype].name, agno, agbno); return 1; } - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, bthdr, 1, - mp->m_bmap_dmxr[1]); + pp = XFS_BTREE_PTR_ADDR(xfs_bmbt, bthdr, 1, mp->m_bmap_dmxr[1]); for (i = 0; i < nrecs; i++) { xfs_agnumber_t ag; xfs_agblock_t bno; @@ -1060,7 +1055,6 @@ process_btinode( xfs_bmdr_block_t *dib; int i; xfs_bmbt_ptr_t *pp; - xfs_bmbt_rec_t *rp; int level; int nrecs; int maxrecs; @@ -1082,14 +1076,9 @@ process_btinode( return 1; } - if (level == 0) { - rp = XFS_BTREE_REC_ADDR(XFS_DFORK_SIZE(dip, mp, whichfork), - xfs_bmdr, dib, 1, XFS_BTREE_BLOCK_MAXRECS( - XFS_DFORK_SIZE(dip, mp, whichfork), - xfs_bmdr, 1)); - - return process_bmbt_reclist(rp, nrecs, itype); - } + if (level == 0) + return process_bmbt_reclist(XFS_BTREE_REC_ADDR(xfs_bmdr, + dib, 1), nrecs, itype); maxrecs = XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_SIZE(dip, mp, whichfork), xfs_bmdr, 0); @@ -1101,8 +1090,7 @@ process_btinode( return 1; } - pp = XFS_BTREE_PTR_ADDR(XFS_DFORK_SIZE(dip, mp, whichfork), xfs_bmdr, - dib, 1, maxrecs); + pp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dib, 1, maxrecs); for (i = 0; i < nrecs; i++) { xfs_agnumber_t ag; xfs_agblock_t bno; @@ -1136,9 +1124,9 @@ process_exinode( whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK; - nex = XFS_DFORK_NEXTENTS_HOST(dip, whichfork); - if (nex < 0 || nex > XFS_DFORK_SIZE_HOST(dip, mp, whichfork) / - sizeof(xfs_bmbt_rec_t)) { + nex = XFS_DFORK_NEXTENTS(dip, whichfork); + if (nex < 0 || nex > XFS_DFORK_SIZE(dip, mp, whichfork) / + sizeof(xfs_bmbt_rec_t)) { if (show_warnings) print_warning("bad number of extents %d in inode %lld", nex, (long long)cur_ino); @@ -1185,18 +1173,13 @@ process_inode( xfs_agino_t agino, xfs_dinode_t *dip) { - xfs_dinode_core_t odic; int success; - /* convert the core */ - memcpy(&odic, &dip->di_core, sizeof(xfs_dinode_core_t)); - libxfs_xlate_dinode_core((xfs_caddr_t)&odic, &dip->di_core, 1); - success = 1; cur_ino = XFS_AGINO_TO_INO(mp, agno, agino); /* copy appropriate data fork metadata */ - switch (dip->di_core.di_mode & S_IFMT) { + switch (be16_to_cpu(dip->di_core.di_mode) & S_IFMT) { case S_IFDIR: memset(&dir_data, 0, sizeof(dir_data)); success = process_inode_data(dip, TYP_DIR2); @@ -1212,7 +1195,7 @@ process_inode( clear_nametable(); /* copy extended attributes if they exist and forkoff is valid */ - if (success && XFS_CFORK_DSIZE(&dip->di_core, mp) < XFS_LITINO(mp)) { + if (success && XFS_DFORK_DSIZE(dip, mp) < XFS_LITINO(mp)) { attr_data.remote_val_count = 0; switch (dip->di_core.di_aformat) { case XFS_DINODE_FMT_LOCAL: @@ -1230,10 +1213,6 @@ process_inode( } clear_nametable(); } - - /* restore the core back to it's original endianess */ - memcpy(&dip->di_core, &odic, sizeof(xfs_dinode_core_t)); - return success; } @@ -1281,7 +1260,7 @@ copy_inode_chunk( if ((mp->m_sb.sb_inopblock <= XFS_INODES_PER_CHUNK && off != 0) || (mp->m_sb.sb_inopblock > XFS_INODES_PER_CHUNK && off % XFS_INODES_PER_CHUNK != 0) || - (XFS_SB_VERSION_HASALIGN(&mp->m_sb) && + (xfs_sb_version_hasalign(&mp->m_sb) && agbno % mp->m_sb.sb_inoalignmt != 0)) { if (show_warnings) print_warning("badly aligned inode (start = %llu)", @@ -1345,8 +1324,7 @@ scanfunc_ino( typtab[btype].name, agno, agbno); numrecs = mp->m_inobt_mxr[0]; } - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_inobt, - bthdr, 1, mp->m_inobt_mxr[0]); + rp = XFS_BTREE_REC_ADDR(xfs_inobt, bthdr, 1); for (i = 0; i < numrecs; i++, rp++) { if (!copy_inode_chunk(agno, rp)) return 0; @@ -1361,8 +1339,7 @@ scanfunc_ino( numrecs = mp->m_inobt_mxr[1]; } - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_inobt, - bthdr, 1, mp->m_inobt_mxr[1]); + pp = XFS_BTREE_PTR_ADDR(xfs_inobt, bthdr, 1, mp->m_inobt_mxr[1]); for (i = 0; i < numrecs; i++) { if (!valid_bno(agno, be32_to_cpu(pp[i]))) { if (show_warnings) @@ -1505,8 +1482,6 @@ copy_ino( xfs_agnumber_t agno; xfs_agblock_t agbno; xfs_agino_t agino; - xfs_dinode_t *dip; - xfs_dinode_core_t tdic; int offset; int rval = 0; @@ -1537,12 +1512,8 @@ copy_ino( } off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize); - dip = iocur_top->data; - libxfs_xlate_dinode_core((xfs_caddr_t)&dip->di_core, &tdic, 1); - memcpy(&dip->di_core, &tdic, sizeof(xfs_dinode_core_t)); - cur_ino = ino; - rval = process_inode_data(dip, itype); + rval = process_inode_data(iocur_top->data, itype); pop_out: pop_cur(); return rval; diff --git a/db/sb.c b/db/sb.c index 643f482d1..d47b9012a 100644 --- a/db/sb.c +++ b/db/sb.c @@ -185,14 +185,14 @@ get_sb(xfs_agnumber_t agno, xfs_sb_t *sb) return 0; } - libxfs_xlate_sb(iocur_top->data, sb, 1, XFS_SB_ALL_BITS); + libxfs_sb_from_disk(sb, iocur_top->data); if (sb->sb_magicnum != XFS_SB_MAGIC) { dbprintf("bad sb magic # %#x in AG %u\n", sb->sb_magicnum, agno); return 0; } - if (!XFS_SB_GOOD_VERSION(sb)) { + if (!xfs_sb_good_version(sb)) { dbprintf("bad sb version # %#x in AG %u\n", sb->sb_versionnum, agno); return 0; @@ -238,7 +238,7 @@ sb_logcheck(void) log.l_logBBstart = x.logBBstart; log.l_mp = mp; - if (xlog_find_tail(&log, &head_blk, &tail_blk, 0)) { + if (xlog_find_tail(&log, &head_blk, &tail_blk)) { dbprintf("ERROR: cannot find log head/tail, run xfs_repair\n"); return 0; } @@ -268,7 +268,7 @@ sb_logzero(uuid_t *uuidp) XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), uuidp, - XFS_SB_VERSION_HASLOGV2(&mp->m_sb) ? 2 : 1, + xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, mp->m_sb.sb_logsunit, XLOG_FMT)) { dbprintf("ERROR: cannot clear the log\n"); return 0; @@ -317,7 +317,7 @@ do_uuid(xfs_agnumber_t agno, uuid_t *uuid) } /* set uuid */ memcpy(&tsb.sb_uuid, uuid, sizeof(uuid_t)); - libxfs_xlate_sb(iocur_top->data, &tsb, -1, XFS_SB_UUID); + libxfs_sb_to_disk(iocur_top->data, &tsb, XFS_SB_UUID); write_cur(); return uuid; } @@ -470,7 +470,7 @@ do_label(xfs_agnumber_t agno, char *label) memset(&tsb.sb_fname, 0, sizeof(tsb.sb_fname)); memcpy(&tsb.sb_fname, label, len); memcpy(&lbl[0], &tsb.sb_fname, sizeof(tsb.sb_fname)); - libxfs_xlate_sb(iocur_top->data, &tsb, -1, XFS_SB_FNAME); + libxfs_sb_to_disk(iocur_top->data, &tsb, XFS_SB_FNAME); write_cur(); return &lbl[0]; } @@ -557,7 +557,7 @@ do_version(xfs_agnumber_t agno, __uint16_t version, __uint32_t features) return 0; if ((version & XFS_SB_VERSION_LOGV2BIT) && - !XFS_SB_VERSION_HASLOGV2(&tsb)) { + !xfs_sb_version_haslogv2(&tsb)) { tsb.sb_logsunit = 1; fields |= (1LL << XFS_SBS_LOGSUNIT); } @@ -565,7 +565,7 @@ do_version(xfs_agnumber_t agno, __uint16_t version, __uint32_t features) tsb.sb_versionnum = version; tsb.sb_features2 = features; fields |= XFS_SB_VERSIONNUM | XFS_SB_FEATURES2; - libxfs_xlate_sb(iocur_top->data, &tsb, -1, fields); + libxfs_sb_to_disk(iocur_top->data, &tsb, fields); write_cur(); return 1; } @@ -585,33 +585,33 @@ version_string( else if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) strcpy(s, "V4"); - if (XFS_SB_VERSION_HASATTR(sbp)) + if (xfs_sb_version_hasattr(sbp)) strcat(s, ",ATTR"); - if (XFS_SB_VERSION_HASNLINK(sbp)) + if (xfs_sb_version_hasnlink(sbp)) strcat(s, ",NLINK"); - if (XFS_SB_VERSION_HASQUOTA(sbp)) + if (xfs_sb_version_hasquota(sbp)) strcat(s, ",QUOTA"); - if (XFS_SB_VERSION_HASALIGN(sbp)) + if (xfs_sb_version_hasalign(sbp)) strcat(s, ",ALIGN"); - if (XFS_SB_VERSION_HASDALIGN(sbp)) + if (xfs_sb_version_hasdalign(sbp)) strcat(s, ",DALIGN"); - if (XFS_SB_VERSION_HASSHARED(sbp)) + if (xfs_sb_version_hasshared(sbp)) strcat(s, ",SHARED"); - if (XFS_SB_VERSION_HASDIRV2(sbp)) + if (xfs_sb_version_hasdirv2(sbp)) strcat(s, ",DIRV2"); - if (XFS_SB_VERSION_HASLOGV2(sbp)) + if (xfs_sb_version_haslogv2(sbp)) strcat(s, ",LOGV2"); - if (XFS_SB_VERSION_HASEXTFLGBIT(sbp)) + if (xfs_sb_version_hasextflgbit(sbp)) strcat(s, ",EXTFLG"); - if (XFS_SB_VERSION_HASSECTOR(sbp)) + 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)) + if (xfs_sb_version_hasmorebits(sbp)) strcat(s, ",MOREBITS"); - if (XFS_SB_VERSION_HASATTR2(sbp)) + if (xfs_sb_version_hasattr2(sbp)) strcat(s, ",ATTR2"); - if (XFS_SB_VERSION_LAZYSBCOUNT(sbp)) + if (xfs_sb_version_haslazysbcount(sbp)) strcat(s, ",LAZYSBCOUNT"); return s; } @@ -646,7 +646,7 @@ version_f( version = 0x0034 | XFS_SB_VERSION_EXTFLGBIT; break; case XFS_SB_VERSION_4: - if (XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) + if (xfs_sb_version_hasextflgbit(&mp->m_sb)) dbprintf("unwritten extents flag" " is already enabled\n"); else @@ -666,7 +666,7 @@ version_f( version = 0x0034 | XFS_SB_VERSION_LOGV2BIT; break; case XFS_SB_VERSION_4: - if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) + if (xfs_sb_version_haslogv2(&mp->m_sb)) dbprintf("version 2 log format" " is already in use\n"); else @@ -675,18 +675,18 @@ version_f( break; } } else if (!strcasecmp(argv[1], "attr1")) { - if (XFS_SB_VERSION_HASATTR2(&mp->m_sb)) { + if (xfs_sb_version_hasattr2(&mp->m_sb)) { if (!(mp->m_sb.sb_features2 &= ~XFS_SB_VERSION2_ATTR2BIT)) mp->m_sb.sb_versionnum &= ~XFS_SB_VERSION_MOREBITSBIT; } - XFS_SB_VERSION_ADDATTR(&mp->m_sb); + xfs_sb_version_addattr(&mp->m_sb); version = mp->m_sb.sb_versionnum; features = mp->m_sb.sb_features2; } else if (!strcasecmp(argv[1], "attr2")) { - XFS_SB_VERSION_ADDATTR(&mp->m_sb); - XFS_SB_VERSION_ADDATTR2(&mp->m_sb); + xfs_sb_version_addattr(&mp->m_sb); + xfs_sb_version_addattr2(&mp->m_sb); version = mp->m_sb.sb_versionnum; features = mp->m_sb.sb_features2; } else { diff --git a/doc/CHANGES b/doc/CHANGES index 9fd09f313..252e5db9f 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -1,3 +1,10 @@ +xfsprogs-3.0.0 + - Resync libxfs to latest kernel implemenation + - Update all of xfsprogs to latest kernel interfaces + - Add sparse support to xfsprogs build (thanks to Christoph Hellwig) + - Cleanup devel package for xfsctl, libhandle and libdisk only + (remove libxfs interfaces). + xfsprogs-2.10.1 (5 September 2008) - Improve xfs_repair -P option to disable xfs_buf_t locking. - Fix inode cluster I/O size for > 8KB block size filesystems. diff --git a/doc/sparse.txt b/doc/sparse.txt new file mode 100644 index 000000000..36a34a0bb --- /dev/null +++ b/doc/sparse.txt @@ -0,0 +1,24 @@ +This document describes how to use the sparse source code checking tool +to check the source code of the open source XFS commands and utilites +("xfsprogs"). + +First you need to install sparse, either from your distribution or from +source as provided at http://www.kernel.org/pub/software/devel/sparse/. + +To simply build the xfsprogs source code while checking the source using +sparse just set the compiler to cgcc, which is a wrapper that calls both +sparse and gcc using: + + CC=cgcc ./configure + +Now that default warnings from sparse are a little bit verbose checking +for various not that important things and also complaining about the +glibc system headers. It does however not check for bitwise annotation +which are very important for xfsprogs to verify the endianess handling +of the on-disk structures is correct. To get a more reasonable set +of warnings build xfsprogs using: + + LCFLAGS="-Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-decl" make + +You are of course free to experiment with the warnings flags documented +in the sparse manpage to check xfsprogs for other issues. diff --git a/estimate/Makefile b/estimate/Makefile new file mode 100644 index 000000000..192aa3931 --- /dev/null +++ b/estimate/Makefile @@ -0,0 +1,18 @@ +# +# Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. +# + +TOPDIR = .. +include $(TOPDIR)/include/builddefs + +LTCOMMAND = xfs_estimate +CFILES = xfs_estimate.c + +default: $(LTCOMMAND) + +include $(BUILDRULES) + +install: default + $(INSTALL) -m 755 -d $(PKG_BIN_DIR) + $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_BIN_DIR) +install-dev: diff --git a/estimate/xfs_estimate.c b/estimate/xfs_estimate.c new file mode 100644 index 000000000..54a72e9b4 --- /dev/null +++ b/estimate/xfs_estimate.c @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2000-2002 Silicon Graphics, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * Estimate space of an XFS filesystem + */ +#include +#include +#include + +unsigned long long +cvtnum(char *s) +{ + unsigned long long i; + char *sp; + + i = strtoll(s, &sp, 0); + if (i == 0 && sp == s) + return 0LL; + if (*sp == '\0') + return i; + if (*sp =='k' && sp[1] == '\0') + return 1024LL * i; + if (*sp =='m' && sp[1] == '\0') + return 1024LL * 1024LL * i; + if (*sp =='g' && sp[1] == '\0') + return 1024LL * 1024LL * 1024LL * i; + return 0LL; +} + +int ffn(const char *, const struct stat64 *, int, struct FTW *); + +#define BLOCKSIZE 4096 +#define INODESIZE 256 +#define PERDIRENTRY \ + (sizeof(xfs_dir_leaf_entry_t) + sizeof(xfs_dir_leaf_name_t)) +#define LOGSIZE 1000 + +#define FBLOCKS(n) ((n)/blocksize) +#define RFBYTES(n) ((n) - (FBLOCKS(n) * blocksize)) + +unsigned long long dirsize=0; /* bytes */ +unsigned long long logsize=LOGSIZE*BLOCKSIZE; /* bytes */ +unsigned long long fullblocks=0; /* FS blocks */ +unsigned long long isize=0; /* inodes bytes */ +unsigned long long blocksize=BLOCKSIZE; +unsigned long long nslinks=0; /* number of symbolic links */ +unsigned long long nfiles=0; /* number of regular files */ +unsigned long long ndirs=0; /* number of directories */ +unsigned long long nspecial=0; /* number of special files */ +unsigned long long verbose=0; /* verbose mode TRUE/FALSE */ + +int __debug = 0; +int ilog = 0; +int elog = 0; + +void +usage(char *progname) +{ + fprintf(stderr, + _("Usage: %s [opts] directory [directory ...]\n" + "\t-b blocksize (fundamental filesystem blocksize)\n" + "\t-i logsize (internal log size)\n" + "\t-e logsize (external log size)\n" + "\t-v prints more verbose messages\n" + "\t-h prints this usage message\n\n" + "Note:\tblocksize may have 'k' appended to indicate x1024\n" + "\tlogsize may also have 'm' appended to indicate (1024 x 1024)\n"), + basename(progname)); + exit(1); +} + +int +main(int argc, char **argv) +{ + unsigned long long est; + extern int optind; + extern char *optarg; + char dname[40]; + int c; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + while ((c = getopt (argc, argv, "b:hdve:i:V")) != EOF) { + switch (c) { + case 'b': + blocksize=cvtnum(optarg); + if (blocksize <= 0LL) { + fprintf(stderr, _("blocksize %llu too small\n"), + blocksize); + usage(argv[0]); + } + else if (blocksize > 64LL * 1024LL) { + fprintf(stderr, _("blocksize %llu too large\n"), + blocksize); + usage(argv[0]); + } + break; + case 'i': + if (elog) { + fprintf(stderr, _("already have external log " + "noted, can't have both\n")); + usage(argv[0]); + } + logsize=cvtnum(optarg); + ilog++; + break; + case 'e': + if (ilog) { + fprintf(stderr, _("already have internal log " + "noted, can't have both\n")); + usage(argv[0]); + } + logsize=cvtnum(optarg); + elog++; + break; + case 'v': + verbose = 1; + break; + case 'd': + __debug++; + break; + case 'V': + printf(_("%s version %s\n"), basename(argv[0]), VERSION); + exit(0); + default: + case 'h': + usage(argv[0]); + } + } + + if (optind == argc) + usage(argv[0]); + + if (!elog && !ilog) { + ilog=1; + logsize=LOGSIZE * blocksize; + } + if (verbose) + printf(_("directory bsize blocks megabytes logsize\n")); + + for ( ; optind < argc; optind++) { + dirsize=0LL; /* bytes */ + fullblocks=0LL; /* FS blocks */ + isize=0LL; /* inodes bytes */ + nslinks=0LL; /* number of symbolic links */ + nfiles=0LL; /* number of regular files */ + ndirs=0LL; /* number of directories */ + nspecial=0LL; /* number of special files */ + + nftw64(argv[optind], ffn, 40, FTW_PHYS | FTW_MOUNT); + + if (__debug) { + printf(_("dirsize=%llu\n"), dirsize); + printf(_("fullblocks=%llu\n"), fullblocks); + printf(_("isize=%llu\n"), isize); + + printf(_("%llu regular files\n"), nfiles); + printf(_("%llu symbolic links\n"), nslinks); + printf(_("%llu directories\n"), ndirs); + printf(_("%llu special files\n"), nspecial); + } + + est = FBLOCKS(isize) + 8 /* blocks for inodes */ + + FBLOCKS(dirsize) + 1 /* blocks for directories */ + + fullblocks /* blocks for file contents */ + + (8 * 16) /* fudge for overhead blks (per ag) */ + + FBLOCKS(isize / INODESIZE); /* 1 byte/inode for map */ + + if (ilog) + est += (logsize / blocksize); + + if (!verbose) { + printf(_("%s will take about %.1f megabytes\n"), + argv[optind], + (double)est*(double)blocksize/(1024.0*1024.0)); + } else { + /* avoid running over 39 characters in field */ + strncpy(dname, argv[optind], 40); + dname[39] = '\0'; + printf(_("%-39s %5llu %8llu %10.1fMB %10llu\n"), + dname, blocksize, est, + (double)est*(double)blocksize/(1024.0*1024.0), logsize); + } + + if (!verbose && elog) { + printf(_("\twith the external log using %llu blocks "), + logsize/blocksize); + printf(_("or about %.1f megabytes\n"), + (double)logsize/(1024.0*1024.0)); + } + } + return 0; +} + +int +ffn(const char *path, const struct stat64 *stb, int flags, struct FTW *f) +{ + /* cases are in most-encountered to least-encountered order */ + dirsize+=PERDIRENTRY+strlen(path); + isize+=INODESIZE; + switch (S_IFMT & stb->st_mode) { + case S_IFREG: /* regular files */ + fullblocks+=FBLOCKS(stb->st_blocks * 512 + blocksize-1); + if (stb->st_blocks * 512 < stb->st_size) + fullblocks++; /* add one bmap block here */ + nfiles++; + break; + case S_IFLNK: /* symbolic links */ + if (stb->st_size >= (INODESIZE - (sizeof(xfs_dinode_t)+4))) + fullblocks+=FBLOCKS(stb->st_size + blocksize-1); + nslinks++; + break; + case S_IFDIR: /* directories */ + dirsize+=blocksize; /* fudge upwards */ + if (stb->st_size >= blocksize) + dirsize+=blocksize; + ndirs++; + break; + case S_IFIFO: /* named pipes */ + case S_IFCHR: /* Character Special device */ + case S_IFBLK: /* Block Special device */ + case S_IFSOCK: /* socket */ + nspecial++; + break; + } + return 0; +} diff --git a/include/Makefile b/include/Makefile index 8aca6bde3..70c366be7 100644 --- a/include/Makefile +++ b/include/Makefile @@ -18,19 +18,21 @@ TOPDIR = .. include $(TOPDIR)/include/builddefs -HFILES = cache.h handle.h jdm.h libxfs.h libxlog.h list.h parent.h xfs.h xqm.h \ +QAHFILES = libxfs.h libxlog.h \ + bitops.h cache.h kmem.h list.h parent.h swab.h xqm.h \ xfs_ag.h xfs_alloc.h xfs_alloc_btree.h xfs_arch.h xfs_attr_leaf.h \ xfs_attr_sf.h xfs_bit.h xfs_bmap.h xfs_bmap_btree.h xfs_btree.h \ - xfs_buf_item.h xfs_da_btree.h xfs_dfrag.h xfs_dinode.h \ + xfs_buf_item.h xfs_da_btree.h xfs_dinode.h \ xfs_dir2.h xfs_dir2_block.h xfs_dir2_data.h xfs_dir2_leaf.h \ xfs_dir2_node.h xfs_dir2_sf.h xfs_dir_leaf.h xfs_dir_sf.h \ - xfs_extfree_item.h xfs_fs.h xfs_ialloc.h xfs_ialloc_btree.h \ + xfs_extfree_item.h xfs_ialloc.h xfs_ialloc_btree.h \ xfs_imap.h xfs_inode.h xfs_inode_item.h xfs_inum.h \ xfs_log.h xfs_log_priv.h xfs_log_recover.h xfs_metadump.h \ xfs_mount.h xfs_quota.h xfs_rtalloc.h xfs_sb.h \ xfs_trans.h xfs_trans_space.h xfs_types.h -HFILES += $(PKG_PLATFORM).h swab.h +HFILES = handle.h jdm.h xqm.h xfs.h xfs_dfrag.h xfs_fs.h +HFILES += $(PKG_PLATFORM).h PHFILES = darwin.h freebsd.h irix.h linux.h DKHFILES = volume.h fstyp.h dvh.h LSRCFILES = $(shell echo $(PHFILES) | sed -e "s/$(PKG_PLATFORM).h//g") @@ -51,3 +53,6 @@ install-dev: default $(INSTALL) -m 644 platform_defs.h $(PKG_INC_DIR) $(INSTALL) -m 755 -d $(DK_INC_DIR) $(INSTALL) -m 644 $(DKHFILES) $(DK_INC_DIR) + +install-qa: install-dev + $(INSTALL) -m 644 $(QAHFILES) $(PKG_INC_DIR) diff --git a/include/bitops.h b/include/bitops.h new file mode 100644 index 000000000..276e9a708 --- /dev/null +++ b/include/bitops.h @@ -0,0 +1,52 @@ +#ifndef __BITOPS_H__ +#define __BITOPS_H__ + +/* + * fls: find last bit set. + */ + +static inline int fls(int x) +{ + int r = 32; + + if (!x) + return 0; + if (!(x & 0xffff0000u)) { + x <<= 16; + r -= 16; + } + if (!(x & 0xff000000u)) { + x <<= 8; + r -= 8; + } + if (!(x & 0xf0000000u)) { + x <<= 4; + r -= 4; + } + if (!(x & 0xc0000000u)) { + x <<= 2; + r -= 2; + } + if (!(x & 0x80000000u)) { + x <<= 1; + r -= 1; + } + return r; +} + +static inline int fls64(__u64 x) +{ + __u32 h = x >> 32; + if (h) + return fls(h) + 32; + return fls(x); +} + +static inline unsigned fls_long(unsigned long l) +{ + if (sizeof(l) == 4) + return fls(l); + return fls64(l); +} + +#endif diff --git a/include/builddefs.in b/include/builddefs.in index 10911a11b..f1b4340be 100644 --- a/include/builddefs.in +++ b/include/builddefs.in @@ -93,7 +93,8 @@ HAVE_SENDFILE = @have_sendfile@ HAVE_GETMNTENT = @have_getmntent@ HAVE_GETMNTINFO = @have_getmntinfo@ -GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall +GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall +# -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-decl ifeq ($(PKG_PLATFORM),linux) PCFLAGS = -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 $(GCCFLAGS) diff --git a/include/buildmacros b/include/buildmacros index 00da8a972..0da451bfc 100644 --- a/include/buildmacros +++ b/include/buildmacros @@ -42,10 +42,10 @@ LIBNAME = $(basename $(LTLIBRARY)) LTOBJECTS = $(OBJECTS:.o=.lo) LTVERSION = $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) -LTLINK = $(LIBTOOL) --mode=link $(CC) +LTLINK = $(LIBTOOL) --tag=CC --mode=link $(CC) LTEXEC = $(LIBTOOL) --mode=execute LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL) -LTCOMPILE = $(LIBTOOL) --mode=compile $(CCF) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CCF) ifeq ($(ENABLE_SHARED),yes) LTLDFLAGS += -rpath $(PKG_LIB_DIR) diff --git a/include/buildrules b/include/buildrules index 4d4f189d0..1bc5cf86b 100644 --- a/include/buildrules +++ b/include/buildrules @@ -56,7 +56,7 @@ endif # _BUILDRULES_INCLUDED_ $(_FORCE): -.PHONY : depend +.PHONY : depend install-qa DEPENDSCRIPT := $(MAKEDEPEND) $(DEPENDFLAGS) -f - -- $(CFLAGS) -- $(CFILES) | \ $(SED) \ diff --git a/include/darwin.h b/include/darwin.h index 87eec1b22..25cd61841 100644 --- a/include/darwin.h +++ b/include/darwin.h @@ -29,7 +29,6 @@ #define __BYTE_ORDER BYTE_ORDER #define __BIG_ENDIAN BIG_ENDIAN #define __LITTLE_ENDIAN LITTLE_ENDIAN -#include #include # ifndef SYS_fsctl diff --git a/include/freebsd.h b/include/freebsd.h index 19d85d55f..967ca25f2 100644 --- a/include/freebsd.h +++ b/include/freebsd.h @@ -31,9 +31,6 @@ #define __BYTE_ORDER BYTE_ORDER #define __BIG_ENDIAN BIG_ENDIAN #define __LITTLE_ENDIAN LITTLE_ENDIAN -#define __swab16(x) __bswap16(x) -#define __swab32(x) __bswap32(x) -#define __swab64(x) __bswap64(x) /* FreeBSD file API is 64-bit aware */ #define fstat64 fstat diff --git a/include/irix.h b/include/irix.h index 28904e5c1..a7debd3e9 100644 --- a/include/irix.h +++ b/include/irix.h @@ -164,16 +164,9 @@ typedef struct xfs_efd_log_format_32 { #define __BYTE_ORDER BYTE_ORDER #define __BIG_ENDIAN BIG_ENDIAN #define __LITTLE_ENDIAN LITTLE_ENDIAN -#define __swab16(x) (x) -#define __swab32(x) (x) -#define __swab64(x) (x) /* Map some gcc macros for the MipsPRO compiler */ #ifndef __GNUC__ -#define INT_SWAP16(type,var) (var) -#define INT_SWAP32(type,var) (var) -#define INT_SWAP64(type,var) (var) -#define HAVE_SWABMACROS 1 /* no typeof available */ #define __builtin_constant_p(x) (0) #define __FUNCTION__ "XFS" #define __sgi__ __sgi diff --git a/include/kmem.h b/include/kmem.h new file mode 100644 index 000000000..1893b6909 --- /dev/null +++ b/include/kmem.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2008 Silicon Graphics, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __KMEM_H__ +#define __KMEM_H__ + +#define KM_SLEEP 0x0001u +#define KM_NOSLEEP 0x0002u +#define KM_NOFS 0x0004u +#define KM_MAYFAIL 0x0008u +#define KM_LARGE 0x0010u + +typedef struct kmem_zone { + int zone_unitsize; /* Size in bytes of zone unit */ + char *zone_name; /* tag name */ + int allocated; /* debug: How many currently allocated */ +} kmem_zone_t; + +extern kmem_zone_t *kmem_zone_init(int, char *); +extern void *kmem_zone_alloc(kmem_zone_t *, int); +extern void *kmem_zone_zalloc(kmem_zone_t *, int); + +static inline void +kmem_zone_free(kmem_zone_t *zone, void *ptr) +{ + zone->allocated--; + free(ptr); +} + +extern void *kmem_alloc(size_t, int); +extern void *kmem_zalloc(size_t, int); + +static inline void +kmem_free(void *ptr) { + free(ptr); +} + +extern void *kmem_realloc(void *, size_t, size_t, int); + +#endif diff --git a/include/libxfs.h b/include/libxfs.h index f4286847c..0356f2660 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -15,6 +15,7 @@ * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + #ifndef __LIBXFS_H__ #define __LIBXFS_H__ @@ -23,9 +24,11 @@ #include -#include #include #include +#include +#include +#include #include #include @@ -125,7 +128,6 @@ extern int libxfs_log_header (xfs_caddr_t, uuid_t *, int, int, int, * Define a user-level mount structure with all we need * in order to make use of the numerous XFS_* macros. */ -struct xfs_inode; typedef struct xfs_mount { xfs_sb_t m_sb; /* copy of fs superblock */ char *m_fsname; /* filesystem name */ @@ -177,7 +179,6 @@ typedef struct xfs_mount { int m_sinoalign; /* stripe unit inode alignmnt */ 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 */ @@ -185,30 +186,21 @@ typedef struct xfs_mount { xfs_dablk_t m_dirleafblk; /* blockno of dir non-data v2 */ xfs_dablk_t m_dirfreeblk; /* blockno of dirfreeindex v2 */ } xfs_mount_t; -#define XFS_DIR_IS_V1(mp) ((mp)->m_dirversion == 1) -#define XFS_DIR_IS_V2(mp) ((mp)->m_dirversion == 2) #define LIBXFS_MOUNT_ROOTINOS 0x0001 #define LIBXFS_MOUNT_DEBUGGER 0x0002 #define LIBXFS_MOUNT_32BITINODES 0x0004 #define LIBXFS_MOUNT_32BITINOOPT 0x0008 #define LIBXFS_MOUNT_COMPAT_ATTR 0x0010 +#define LIBXFS_MOUNT_ATTR2 0x0020 #define LIBXFS_IHASHSIZE(sbp) (1<<10) #define LIBXFS_BHASHSIZE(sbp) (1<<10) extern xfs_mount_t *libxfs_mount (xfs_mount_t *, xfs_sb_t *, dev_t, dev_t, dev_t, int); -extern void libxfs_mount_common (xfs_mount_t *, xfs_sb_t *); -extern xfs_agnumber_t libxfs_initialize_perag (xfs_mount_t *, xfs_agnumber_t); -extern int libxfs_initialize_perag_data (xfs_mount_t *, xfs_agnumber_t); extern void libxfs_umount (xfs_mount_t *); -extern int libxfs_rtmount_init (xfs_mount_t *); extern void libxfs_rtmount_destroy (xfs_mount_t *); -extern void libxfs_alloc_compute_maxlevels (xfs_mount_t *); -extern void libxfs_bmap_compute_maxlevels (xfs_mount_t *, int); -extern void libxfs_ialloc_compute_maxlevels (xfs_mount_t *); -extern void libxfs_trans_init (xfs_mount_t *); /* @@ -364,7 +356,7 @@ typedef struct xfs_trans { extern xfs_trans_t *libxfs_trans_alloc (xfs_mount_t *, int); extern xfs_trans_t *libxfs_trans_dup (xfs_trans_t *); extern int libxfs_trans_reserve (xfs_trans_t *, uint,uint,uint,uint,uint); -extern int libxfs_trans_commit (xfs_trans_t *, uint, xfs_lsn_t *); +extern int libxfs_trans_commit (xfs_trans_t *, uint); extern void libxfs_trans_cancel (xfs_trans_t *, int); extern void libxfs_mod_sb (xfs_trans_t *, __int64_t); extern xfs_buf_t *libxfs_trans_getsb (xfs_trans_t *, xfs_mount_t *, int); @@ -389,23 +381,6 @@ extern int libxfs_trans_read_buf (xfs_mount_t *, xfs_trans_t *, dev_t, xfs_daddr_t, int, uint, struct xfs_buf **); -/* - * Simple memory interface - */ -typedef struct xfs_zone { - int zone_unitsize; /* Size in bytes of zone unit */ - char *zone_name; /* tag name */ - int allocated; /* debug: How many currently allocated */ -} xfs_zone_t; - -extern xfs_zone_t *libxfs_zone_init (int, char *); -extern void *libxfs_zone_zalloc (xfs_zone_t *); -extern void libxfs_zone_free (xfs_zone_t *, void *); -extern void *libxfs_malloc (size_t); -extern void libxfs_free (void *); -extern void *libxfs_realloc (void *, size_t); - - /* * Inode interface */ @@ -422,7 +397,8 @@ typedef struct xfs_inode { xfs_trans_t *i_transp; /* ptr to owning transaction */ xfs_inode_log_item_t *i_itemp; /* logging information */ unsigned int i_delayed_blks; /* count of delay alloc blks */ - xfs_dinode_core_t i_d; /* most of ondisk inode */ + xfs_icdinode_t i_d; /* most of ondisk inode */ + xfs_fsize_t i_size; /* in-memory size */ } xfs_inode_t; #define LIBXFS_ATTR_ROOT 0x0002 /* use attrs in root namespace */ @@ -440,13 +416,8 @@ extern int libxfs_inode_alloc (xfs_trans_t **, xfs_inode_t *, mode_t, struct fsxattr *, xfs_inode_t **); extern void libxfs_trans_inode_alloc_buf (xfs_trans_t *, xfs_buf_t *); -extern void libxfs_idata_realloc (xfs_inode_t *, int, int); -extern void libxfs_idestroy_fork (xfs_inode_t *, int); -extern int libxfs_iformat (xfs_inode_t *, xfs_dinode_t *); extern void libxfs_ichgtime (xfs_inode_t *, int); extern int libxfs_iflush_int (xfs_inode_t *, xfs_buf_t *); -extern int libxfs_itobp (xfs_mount_t *, xfs_trans_t *, xfs_inode_t *, - xfs_dinode_t **, xfs_buf_t **, xfs_daddr_t); extern int libxfs_iread (xfs_mount_t *, xfs_trans_t *, xfs_ino_t, xfs_inode_t *, xfs_daddr_t); @@ -458,142 +429,26 @@ extern int libxfs_iget (xfs_mount_t *, xfs_trans_t *, xfs_ino_t, uint, xfs_inode_t **, xfs_daddr_t); extern void libxfs_iput (xfs_inode_t *, uint); - -/* - * Directory interface - */ -#include +#include /* dirv1 support in db & repair */ #include #include #include #include -extern void libxfs_dir_mount (xfs_mount_t *); -extern void libxfs_dir2_mount (xfs_mount_t *); -extern int libxfs_dir_init (xfs_trans_t *, xfs_inode_t *, xfs_inode_t *); -extern int libxfs_dir2_init (xfs_trans_t *, xfs_inode_t *, xfs_inode_t *); -extern int libxfs_dir_createname (xfs_trans_t *, xfs_inode_t *, uchar_t *, - int, xfs_ino_t, xfs_fsblock_t *, - xfs_bmap_free_t *, xfs_extlen_t); -extern int libxfs_dir2_createname (xfs_trans_t *, xfs_inode_t *, uchar_t *, - int, xfs_ino_t, xfs_fsblock_t *, - xfs_bmap_free_t *, xfs_extlen_t); -extern int libxfs_dir_lookup (xfs_trans_t *, xfs_inode_t *, - uchar_t *, int, xfs_ino_t *); -extern int libxfs_dir2_lookup (xfs_trans_t *, xfs_inode_t *, - uchar_t *, int, xfs_ino_t *); -extern int libxfs_dir_replace (xfs_trans_t *, xfs_inode_t *, - uchar_t *, int, xfs_ino_t, xfs_fsblock_t *, - xfs_bmap_free_t *, xfs_extlen_t); -extern int libxfs_dir2_replace (xfs_trans_t *, xfs_inode_t *, - uchar_t *, int, xfs_ino_t, xfs_fsblock_t *, - xfs_bmap_free_t *, xfs_extlen_t); -extern int libxfs_dir_removename (xfs_trans_t *, xfs_inode_t *, - uchar_t *, int, xfs_ino_t, xfs_fsblock_t *, - xfs_bmap_free_t *, xfs_extlen_t); -extern int libxfs_dir2_removename (xfs_trans_t *, xfs_inode_t *, - uchar_t *, int, xfs_ino_t, xfs_fsblock_t *, - xfs_bmap_free_t *, xfs_extlen_t); -extern int libxfs_dir_bogus_removename (xfs_trans_t *, xfs_inode_t *, - uchar_t *, xfs_fsblock_t *, xfs_bmap_free_t *, - xfs_extlen_t, xfs_dahash_t, int); -extern int libxfs_dir2_bogus_removename (xfs_trans_t *, xfs_inode_t *, - uchar_t *, xfs_fsblock_t *, xfs_bmap_free_t *, - xfs_extlen_t, xfs_dahash_t, int); - - -/* - * Block map interface - */ -extern int libxfs_bmapi (xfs_trans_t *, xfs_inode_t *, xfs_fileoff_t, - xfs_filblks_t, int, xfs_fsblock_t *, - xfs_extlen_t, xfs_bmbt_irec_t *, int *, - xfs_bmap_free_t *); -extern int libxfs_bmapi_single(xfs_trans_t *, xfs_inode_t *, int, - xfs_fsblock_t *, xfs_fileoff_t); -extern int libxfs_bmap_finish (xfs_trans_t **, xfs_bmap_free_t *, - xfs_fsblock_t, int *); -extern void libxfs_bmap_cancel(xfs_bmap_free_t *); -extern int libxfs_bmap_next_offset (xfs_trans_t *, xfs_inode_t *, - xfs_fileoff_t *, int); -extern int libxfs_bmap_last_offset(xfs_trans_t *, xfs_inode_t *, - xfs_fileoff_t *, int); -extern int libxfs_bunmapi (xfs_trans_t *, xfs_inode_t *, xfs_fileoff_t, - xfs_filblks_t, int, xfs_extnum_t, - xfs_fsblock_t *, xfs_bmap_free_t *, int *); -extern void libxfs_bmap_del_free (xfs_bmap_free_t *, - xfs_bmap_free_item_t *, xfs_bmap_free_item_t *); - - -/* - * All other routines we want to keep common... - */ - -extern int libxfs_highbit32 (__uint32_t); -extern int libxfs_highbit64 (__uint64_t); -extern uint libxfs_da_log2_roundup (uint); - -extern void libxfs_xlate_sb (void *, xfs_sb_t *, int, __int64_t); -extern void libxfs_xlate_dinode_core (xfs_caddr_t buf, - xfs_dinode_core_t *, int); +/* Shared utility routines */ +extern unsigned int libxfs_log2_roundup(unsigned int i); -extern int libxfs_alloc_fix_freelist (xfs_alloc_arg_t *, int); extern int libxfs_alloc_file_space (xfs_inode_t *, xfs_off_t, xfs_off_t, int, int); +extern int libxfs_bmap_finish(xfs_trans_t **, xfs_bmap_free_t *, int *); -extern xfs_dahash_t libxfs_da_hashname (const uchar_t *, int); -extern int libxfs_attr_leaf_newentsize (int, int, int, int *); -extern int libxfs_attr_set_int (xfs_inode_t*, const char *, int, char *, - int, int); -extern int libxfs_attr_remove_int (xfs_inode_t *, const char *, int, int); - - -extern void libxfs_bmbt_get_all (xfs_bmbt_rec_t *, xfs_bmbt_irec_t *); -#if __BYTE_ORDER != __BIG_ENDIAN -extern void libxfs_bmbt_disk_get_all (xfs_bmbt_rec_t *, xfs_bmbt_irec_t *); -#else -# define libxfs_bmbt_disk_get_all(r,s) libxfs_bmbt_get_all(r,s) -#endif - -extern int libxfs_free_extent (xfs_trans_t *, xfs_fsblock_t, xfs_extlen_t); -extern int libxfs_rtfree_extent (xfs_trans_t *, xfs_rtblock_t, - xfs_extlen_t); - -/* Directory/Attribute routines used by xfs_repair */ extern void libxfs_da_bjoin (xfs_trans_t *, xfs_dabuf_t *); -extern int libxfs_da_shrink_inode (xfs_da_args_t *, xfs_dablk_t, - xfs_dabuf_t *); -extern int libxfs_da_grow_inode (xfs_da_args_t *, xfs_dablk_t *); extern void libxfs_da_bhold (xfs_trans_t *, xfs_dabuf_t *); -extern void libxfs_da_brelse (xfs_trans_t *, xfs_dabuf_t *); -extern int libxfs_da_read_bufr (xfs_trans_t *, xfs_inode_t *, xfs_dablk_t, +extern int libxfs_da_read_bufr(xfs_trans_t *, xfs_inode_t *, xfs_dablk_t, xfs_daddr_t, xfs_dabuf_t **, int); -extern int libxfs_da_read_buf (xfs_trans_t *, xfs_inode_t *, - xfs_dablk_t, xfs_daddr_t, xfs_dabuf_t **, int); -extern int libxfs_da_get_buf (xfs_trans_t *, xfs_inode_t *, - xfs_dablk_t, xfs_daddr_t, xfs_dabuf_t **, int); -extern void libxfs_da_log_buf (xfs_trans_t *, xfs_dabuf_t *, uint, uint); -extern int libxfs_dir2_shrink_inode (xfs_da_args_t *, xfs_dir2_db_t, - xfs_dabuf_t *); -extern int libxfs_dir2_grow_inode (xfs_da_args_t *, int, xfs_dir2_db_t *); -extern int libxfs_dir2_isleaf (xfs_trans_t *, xfs_inode_t *, int *); -extern int libxfs_dir2_isblock (xfs_trans_t *, xfs_inode_t *, int *); -extern void libxfs_dir2_data_use_free (xfs_trans_t *, xfs_dabuf_t *, - xfs_dir2_data_unused_t *, xfs_dir2_data_aoff_t, - xfs_dir2_data_aoff_t, int *, int *); -extern void libxfs_dir2_data_make_free (xfs_trans_t *, xfs_dabuf_t *, - xfs_dir2_data_aoff_t, xfs_dir2_data_aoff_t, - int *, int *); -extern void libxfs_dir2_data_log_entry (xfs_trans_t *, xfs_dabuf_t *, - xfs_dir2_data_entry_t *); -extern void libxfs_dir2_data_log_header (xfs_trans_t *, xfs_dabuf_t *); -extern void libxfs_dir2_data_freescan (xfs_mount_t *, xfs_dir2_data_t *, - int *, char *); -extern void libxfs_dir2_free_log_bests (xfs_trans_t *, xfs_dabuf_t *, - int, int); -/* Shared utility routines */ -extern unsigned int libxfs_log2_roundup(unsigned int i); +extern void libxfs_fs_repair_cmn_err(int, struct xfs_mount *, char *, ...); +extern void libxfs_fs_cmn_err(int, struct xfs_mount *, char *, ...); extern void cmn_err(int, char *, ...); enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC }; @@ -613,4 +468,74 @@ extern unsigned long libxfs_physmem(void); /* in kilobytes */ #include #include +#define XFS_INOBT_IS_FREE_DISK(rp,i) \ + ((be64_to_cpu((rp)->ir_free) & XFS_INOBT_MASK(i)) != 0) +/* + * public xfs kernel routines to be called as libxfs_* + */ + +/* xfs_alloc.c */ +int libxfs_alloc_fix_freelist(xfs_alloc_arg_t *, int); + +/* xfs_attr.c */ +int libxfs_attr_get(struct xfs_inode *, const char *, char *, int *, int); +int libxfs_attr_set(struct xfs_inode *, const char *, char *, int, int); +int libxfs_attr_remove(struct xfs_inode *, const char *, int); + +/* xfs_bmap.c */ +xfs_bmbt_rec_host_t *xfs_bmap_search_extents(xfs_inode_t *, xfs_fileoff_t, + int, int *, xfs_extnum_t *, xfs_bmbt_irec_t *, + xfs_bmbt_irec_t *); + +/* xfs_attr_leaf.h */ +#define libxfs_attr_leaf_newentsize xfs_attr_leaf_newentsize + +/* xfs_bit.h */ +#define libxfs_highbit32 xfs_highbit32 +#define libxfs_highbit64 xfs_highbit64 + +/* xfs_bmap.h */ +#define libxfs_bmap_cancel xfs_bmap_cancel +#define libxfs_bmap_last_offset xfs_bmap_last_offset +#define libxfs_bmapi xfs_bmapi +#define libxfs_bunmapi xfs_bunmapi + +/* xfs_bmap_btree.h */ +#define libxfs_bmbt_disk_get_all xfs_bmbt_disk_get_all + +/* xfs_da_btree.h */ +#define libxfs_da_brelse xfs_da_brelse +#define libxfs_da_hashname xfs_da_hashname +#define libxfs_da_shrink_inode xfs_da_shrink_inode + +/* xfs_dir2.h */ +#define libxfs_dir_createname xfs_dir_createname +#define libxfs_dir_init xfs_dir_init +#define libxfs_dir_lookup xfs_dir_lookup +#define libxfs_dir_replace xfs_dir_replace +#define libxfs_dir2_isblock xfs_dir2_isblock +#define libxfs_dir2_isleaf xfs_dir2_isleaf + +/* xfs_dir2_data.h */ +#define libxfs_dir2_data_freescan xfs_dir2_data_freescan +#define libxfs_dir2_data_log_entry xfs_dir2_data_log_entry +#define libxfs_dir2_data_log_header xfs_dir2_data_log_header +#define libxfs_dir2_data_make_free xfs_dir2_data_make_free +#define libxfs_dir2_data_use_free xfs_dir2_data_use_free +#define libxfs_dir2_shrink_inode xfs_dir2_shrink_inode + +/* xfs_inode.h */ +#define libxfs_dinode_from_disk xfs_dinode_from_disk +#define libxfs_dinode_to_disk xfs_dinode_to_disk +#define libxfs_idata_realloc xfs_idata_realloc +#define libxfs_idestroy_fork xfs_idestroy_fork + +/* xfs_mount.h */ +#define libxfs_mod_sb xfs_mod_sb +#define libxfs_sb_from_disk xfs_sb_from_disk +#define libxfs_sb_to_disk xfs_sb_to_disk + +/* xfs_rtalloc.c */ +int libxfs_rtfree_extent(struct xfs_trans *, xfs_rtblock_t, xfs_extlen_t); + #endif /* __LIBXFS_H__ */ diff --git a/include/libxlog.h b/include/libxlog.h index f7f14f997..2a8a25111 100644 --- a/include/libxlog.h +++ b/include/libxlog.h @@ -81,11 +81,6 @@ extern void xlog_warn(char *fmt,...); extern void xlog_exit(char *fmt,...); extern void xlog_panic(char *fmt,...); -#define kmem_zalloc(size, foo) calloc(size,1) -#define kmem_alloc(size, foo) calloc(size,1) -#define kmem_free(ptr, foo) free(ptr) -#define kmem_realloc(ptr, len, old, foo) realloc(ptr, len) - /* exports */ extern int print_exit; extern int print_skip_uuid; @@ -95,39 +90,34 @@ extern int print_record_header; extern libxfs_init_t x; extern struct xfs_buf *xlog_get_bp(xlog_t *, int); -extern void xlog_put_bp(struct xfs_buf *); -extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *); - -extern int xlog_find_zeroed(xlog_t *log, xfs_daddr_t *blk_no); -extern int xlog_find_cycle_start(xlog_t *log, xfs_buf_t *bp, - xfs_daddr_t first_blk, xfs_daddr_t *last_blk, uint cycle); -extern int xlog_find_tail(xlog_t *log, xfs_daddr_t *head_blk, - xfs_daddr_t *tail_blk, int readonly); - -extern int xlog_test_footer(xlog_t *log); -extern int xlog_recover(xlog_t *log, int readonly); -extern void xlog_recover_print_data(xfs_caddr_t p, int len); -extern void xlog_recover_print_logitem(xlog_recover_item_t *item); -extern void xlog_recover_print_trans_head(xlog_recover_t *tr); -extern int xlog_print_find_oldest(xlog_t *log, xfs_daddr_t *last_blk); +extern void xlog_put_bp(struct xfs_buf *); +extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *); + +extern int xlog_find_zeroed(xlog_t *log, xfs_daddr_t *blk_no); +extern int xlog_find_cycle_start(xlog_t *log, xfs_buf_t *bp, + xfs_daddr_t first_blk, xfs_daddr_t *last_blk, + uint cycle); +extern int xlog_find_tail(xlog_t *log, xfs_daddr_t *head_blk, + xfs_daddr_t *tail_blk); + +extern int xlog_test_footer(xlog_t *log); +extern int xlog_recover(xlog_t *log, int readonly); +extern void xlog_recover_print_data(xfs_caddr_t p, int len); +extern void xlog_recover_print_logitem(xlog_recover_item_t *item); +extern void xlog_recover_print_trans_head(xlog_recover_t *tr); +extern int xlog_print_find_oldest(xlog_t *log, xfs_daddr_t *last_blk); /* for transactional view */ -extern void xlog_recover_print_trans_head(xlog_recover_t *tr); - -extern void xlog_recover_print_trans( xlog_recover_t *trans, - xlog_recover_item_t *itemq, - int print); - -extern int xlog_do_recovery_pass( xlog_t *log, - xfs_daddr_t head_blk, - xfs_daddr_t tail_blk, - int pass); -extern int xlog_recover_do_trans( xlog_t *log, - xlog_recover_t *trans, - int pass); -extern int xlog_header_check_recover( xfs_mount_t *mp, - xlog_rec_header_t *head); -extern int xlog_header_check_mount( xfs_mount_t *mp, - xlog_rec_header_t *head); +extern void xlog_recover_print_trans_head(xlog_recover_t *tr); +extern void xlog_recover_print_trans(xlog_recover_t *trans, + xlog_recover_item_t *itemq, int print); +extern int xlog_do_recovery_pass(xlog_t *log, xfs_daddr_t head_blk, + xfs_daddr_t tail_blk, int pass); +extern int xlog_recover_do_trans(xlog_t *log, xlog_recover_t *trans, + int pass); +extern int xlog_header_check_recover(xfs_mount_t *mp, + xlog_rec_header_t *head); +extern int xlog_header_check_mount(xfs_mount_t *mp, + xlog_rec_header_t *head); #endif /* LIBXLOG_H */ diff --git a/include/linux.h b/include/linux.h index 440f29bea..1bb5866d6 100644 --- a/include/linux.h +++ b/include/linux.h @@ -25,7 +25,6 @@ #include #include #include -#include static __inline__ int xfsctl(const char *path, int fd, int cmd, void *p) { diff --git a/include/platform_defs.h.in b/include/platform_defs.h.in index d2d96060f..6682ef6d8 100644 --- a/include/platform_defs.h.in +++ b/include/platform_defs.h.in @@ -28,7 +28,10 @@ #include #include #include +#include #include +#include +#include #include #undef HAVE___U32 @@ -45,9 +48,19 @@ typedef unsigned long long int __u64; typedef signed long long int __s64; #endif -typedef __u16 __be16; -typedef __u32 __be32; -typedef __u64 __be64; +#ifdef __CHECKER__ +#define __bitwise __attribute__((bitwise)) +#define __force __attribute__((force)) +#else +#define __bitwise +#define __force +#endif + +typedef __u16 __bitwise __be16; +typedef __u32 __bitwise __be32; +typedef __u64 __bitwise __be64; + +typedef struct filldir filldir_t; #if defined(__linux__) #include @@ -124,7 +137,7 @@ typedef unsigned long long __psunsigned_t; #include #ifdef DEBUG -# define ASSERT assert +# define ASSERT(EX) assert(EX) #else # define ASSERT(EX) ((void) 0) #endif diff --git a/include/unaligned.h b/include/unaligned.h new file mode 100644 index 000000000..7f75981ff --- /dev/null +++ b/include/unaligned.h @@ -0,0 +1,120 @@ +#ifndef _UNALIGNED_H_ +#define _UNALIGNED_H_ + +/* + * For the benefit of those who are trying to port Linux to another + * architecture, here are some C-language equivalents. + * + * This is based almost entirely upon Richard Henderson's + * asm-alpha/unaligned.h implementation. Some comments were + * taken from David Mosberger's asm-ia64/unaligned.h header. + */ + +/* + * The main single-value unaligned transfer routines. + */ +#define get_unaligned(ptr) \ + __get_unaligned((ptr), sizeof(*(ptr))) +#define put_unaligned(x,ptr) \ + __put_unaligned((__u64)(x), (ptr), sizeof(*(ptr))) + +/* + * This function doesn't actually exist. The idea is that when + * someone uses the macros below with an unsupported size (datatype), + * the linker will alert us to the problem via an unresolved reference + * error. + */ +extern void bad_unaligned_access_length(void) __attribute__((noreturn)); + +struct __una_u64 { __u64 x __attribute__((packed)); }; +struct __una_u32 { __u32 x __attribute__((packed)); }; +struct __una_u16 { __u16 x __attribute__((packed)); }; + +/* + * Elemental unaligned loads + */ + +static inline __u64 __uldq(const __u64 *addr) +{ + const struct __una_u64 *ptr = (const struct __una_u64 *) addr; + return ptr->x; +} + +static inline __u32 __uldl(const __u32 *addr) +{ + const struct __una_u32 *ptr = (const struct __una_u32 *) addr; + return ptr->x; +} + +static inline __u16 __uldw(const __u16 *addr) +{ + const struct __una_u16 *ptr = (const struct __una_u16 *) addr; + return ptr->x; +} + +/* + * Elemental unaligned stores + */ + +static inline void __ustq(__u64 val, __u64 *addr) +{ + struct __una_u64 *ptr = (struct __una_u64 *) addr; + ptr->x = val; +} + +static inline void __ustl(__u32 val, __u32 *addr) +{ + struct __una_u32 *ptr = (struct __una_u32 *) addr; + ptr->x = val; +} + +static inline void __ustw(__u16 val, __u16 *addr) +{ + struct __una_u16 *ptr = (struct __una_u16 *) addr; + ptr->x = val; +} + +#define __get_unaligned(ptr, size) ({ \ + const void *__gu_p = ptr; \ + __u64 val; \ + switch (size) { \ + case 1: \ + val = *(const __u8 *)__gu_p; \ + break; \ + case 2: \ + val = __uldw(__gu_p); \ + break; \ + case 4: \ + val = __uldl(__gu_p); \ + break; \ + case 8: \ + val = __uldq(__gu_p); \ + break; \ + default: \ + bad_unaligned_access_length(); \ + }; \ + (__typeof__(*(ptr)))val; \ +}) + +#define __put_unaligned(val, ptr, size) \ +do { \ + void *__gu_p = ptr; \ + switch (size) { \ + case 1: \ + *(__u8 *)__gu_p = val; \ + break; \ + case 2: \ + __ustw(val, __gu_p); \ + break; \ + case 4: \ + __ustl(val, __gu_p); \ + break; \ + case 8: \ + __ustq(val, __gu_p); \ + break; \ + default: \ + bad_unaligned_access_length(); \ + }; \ +} while(0) + +#endif /* _UNALIGNED_H */ diff --git a/include/xfs_ag.h b/include/xfs_ag.h index f3eed100b..729ee3eb3 100644 --- a/include/xfs_ag.h +++ b/include/xfs_ag.h @@ -152,7 +152,7 @@ typedef struct xfs_agi { #define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)XFS_BUF_PTR(bp)) typedef struct xfs_agfl { - xfs_agblock_t agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */ + __be32 agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */ } xfs_agfl_t; /* @@ -181,7 +181,7 @@ typedef struct xfs_perag { char pagf_init; /* this agf's entry is initialized */ char pagi_init; /* this agi's entry is initialized */ - char pagf_metadata; /* the agf is prefered to be metadata */ + char pagf_metadata; /* the agf is preferred to be metadata */ char pagi_inodeok; /* The agi is ok for inodes */ __uint8_t pagf_levels[XFS_BTNUM_AGF]; /* # of levels in bno & cnt btree */ @@ -192,10 +192,16 @@ typedef struct xfs_perag xfs_agino_t pagi_freecount; /* number of free inodes */ xfs_agino_t pagi_count; /* number of allocated inodes */ int pagb_count; /* pagb slots in use */ + xfs_perag_busy_t *pagb_list; /* unstable blocks */ #ifdef __KERNEL__ - lock_t pagb_lock; /* lock for pagb_list */ + spinlock_t pagb_lock; /* lock for pagb_list */ + + atomic_t pagf_fstrms; /* # of filestreams active in this AG */ + + int pag_ici_init; /* incore inode cache initialised */ + rwlock_t pag_ici_lock; /* incore inode lock */ + struct radix_tree_root pag_ici_root; /* incore inode cache root */ #endif - xfs_perag_busy_t *pagb_list; /* unstable blocks */ } xfs_perag_t; #define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels) diff --git a/include/xfs_alloc.h b/include/xfs_alloc.h index 32651b75f..588172796 100644 --- a/include/xfs_alloc.h +++ b/include/xfs_alloc.h @@ -41,6 +41,27 @@ typedef enum xfs_alloctype * Flags for xfs_alloc_fix_freelist. */ #define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */ +#define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/ + +/* + * In order to avoid ENOSPC-related deadlock caused by + * out-of-order locking of AGF buffer (PV 947395), we place + * constraints on the relationship among actual allocations for + * data blocks, freelist blocks, and potential file data bmap + * btree blocks. However, these restrictions may result in no + * actual space allocated for a delayed extent, for example, a data + * block in a certain AG is allocated but there is no additional + * block for the additional bmap btree block due to a split of the + * bmap btree of the file. The result of this may lead to an + * infinite loop in xfssyncd when the file gets flushed to disk and + * all delayed extents need to be actually allocated. To get around + * this, we explicitly set aside a few blocks which will not be + * reserved in delayed allocation. Considering the minimum number of + * needed freelist blocks is 4 fsbs _per AG_, a potential split of file's bmap + * btree requires 1 fsb, so we set the number of set-aside blocks + * to 4 + 4*agcount. + */ +#define XFS_ALLOC_SET_ASIDE(mp) (4 + ((mp)->m_sb.sb_agcount * 4)) /* * Argument structure for xfs_alloc routines. @@ -68,8 +89,9 @@ typedef struct xfs_alloc_arg { xfs_alloctype_t otype; /* original allocation type */ char wasdel; /* set if allocation was prev delayed */ char wasfromfl; /* set if allocation is from freelist */ - char isfl; /* set if is freelist blocks - !actg */ + char isfl; /* set if is freelist blocks - !acctg */ char userdata; /* set if this is user data */ + xfs_fsblock_t firstblock; /* io first block allocated */ } xfs_alloc_arg_t; /* @@ -99,6 +121,19 @@ extern ktrace_t *xfs_alloc_trace_buf; #define XFS_ALLOC_KTRACE_BUSYSEARCH 6 #endif +void +xfs_alloc_mark_busy(xfs_trans_t *tp, + xfs_agnumber_t agno, + xfs_agblock_t bno, + xfs_extlen_t len); + +void +xfs_alloc_clear_busy(xfs_trans_t *tp, + xfs_agnumber_t ag, + int idx); + +#endif /* __KERNEL__ */ + /* * Compute and fill in value of m_ag_maxlevels. */ @@ -174,18 +209,4 @@ xfs_free_extent( xfs_fsblock_t bno, /* starting block number of extent */ xfs_extlen_t len); /* length of extent */ -void -xfs_alloc_mark_busy(xfs_trans_t *tp, - xfs_agnumber_t agno, - xfs_agblock_t bno, - xfs_extlen_t len); - -void -xfs_alloc_clear_busy(xfs_trans_t *tp, - xfs_agnumber_t ag, - int idx); - - -#endif /* __KERNEL__ */ - #endif /* __XFS_ALLOC_H__ */ diff --git a/include/xfs_alloc_btree.h b/include/xfs_alloc_btree.h index bce81c7a4..5bd1a2c8b 100644 --- a/include/xfs_alloc_btree.h +++ b/include/xfs_alloc_btree.h @@ -58,7 +58,6 @@ typedef struct xfs_btree_sblock xfs_alloc_block_t; /* * Real block structures have a size equal to the disk block size. */ -#define XFS_ALLOC_BLOCK_SIZE(lev,cur) (1 << (cur)->bc_blocklog) #define XFS_ALLOC_BLOCK_MAXRECS(lev,cur) ((cur)->bc_mp->m_alloc_mxr[lev != 0]) #define XFS_ALLOC_BLOCK_MINRECS(lev,cur) ((cur)->bc_mp->m_alloc_mnr[lev != 0]) @@ -87,16 +86,13 @@ typedef struct xfs_btree_sblock xfs_alloc_block_t; * Record, key, and pointer address macros for btree blocks. */ #define XFS_ALLOC_REC_ADDR(bb,i,cur) \ - XFS_BTREE_REC_ADDR(XFS_ALLOC_BLOCK_SIZE(0,cur), xfs_alloc, \ - bb, i, XFS_ALLOC_BLOCK_MAXRECS(0, cur)) + XFS_BTREE_REC_ADDR(xfs_alloc, bb, i) #define XFS_ALLOC_KEY_ADDR(bb,i,cur) \ - XFS_BTREE_KEY_ADDR(XFS_ALLOC_BLOCK_SIZE(1,cur), xfs_alloc, \ - bb, i, XFS_ALLOC_BLOCK_MAXRECS(1, cur)) + XFS_BTREE_KEY_ADDR(xfs_alloc, bb, i) #define XFS_ALLOC_PTR_ADDR(bb,i,cur) \ - XFS_BTREE_PTR_ADDR(XFS_ALLOC_BLOCK_SIZE(1,cur), xfs_alloc, \ - bb, i, XFS_ALLOC_BLOCK_MAXRECS(1, cur)) + XFS_BTREE_PTR_ADDR(xfs_alloc, bb, i, XFS_ALLOC_BLOCK_MAXRECS(1, cur)) /* * Decrement cursor by one record at the level. diff --git a/include/xfs_arch.h b/include/xfs_arch.h index 7be1fb68f..53d5e70d1 100644 --- a/include/xfs_arch.h +++ b/include/xfs_arch.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002,2005-2006 Silicon Graphics, Inc. + * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -41,21 +41,36 @@ #endif #ifdef XFS_NATIVE_HOST -#define cpu_to_be16(val) ((__be16)(val)) -#define cpu_to_be32(val) ((__be32)(val)) -#define cpu_to_be64(val) ((__be64)(val)) -#define be16_to_cpu(val) ((__uint16_t)(val)) -#define be32_to_cpu(val) ((__uint32_t)(val)) -#define be64_to_cpu(val) ((__uint64_t)(val)) +#define cpu_to_be16(val) ((__force __be16)(__u16)(val)) +#define cpu_to_be32(val) ((__force __be32)(__u32)(val)) +#define cpu_to_be64(val) ((__force __be64)(__u64)(val)) +#define be16_to_cpu(val) ((__force __u16)(__be16)(val)) +#define be32_to_cpu(val) ((__force __u32)(__be32)(val)) +#define be64_to_cpu(val) ((__force __u64)(__be64)(val)) #else -#define cpu_to_be16(val) (__swab16((__uint16_t)(val))) -#define cpu_to_be32(val) (__swab32((__uint32_t)(val))) -#define cpu_to_be64(val) (__swab64((__uint64_t)(val))) -#define be16_to_cpu(val) (__swab16((__be16)(val))) -#define be32_to_cpu(val) (__swab32((__be32)(val))) -#define be64_to_cpu(val) (__swab64((__be64)(val))) +#define cpu_to_be16(val) ((__force __be16)__swab16((__u16)(val))) +#define cpu_to_be32(val) ((__force __be32)__swab32((__u32)(val))) +#define cpu_to_be64(val) ((__force __be64)__swab64((__u64)(val))) +#define be16_to_cpu(val) (__swab16((__force __u16)(__be16)(val))) +#define be32_to_cpu(val) (__swab32((__force __u32)(__be32)(val))) +#define be64_to_cpu(val) (__swab64((__force __u64)(__be64)(val))) #endif +static inline void be16_add_cpu(__be16 *a, __s16 b) +{ + *a = cpu_to_be16(be16_to_cpu(*a) + b); +} + +static inline void be32_add_cpu(__be32 *a, __s32 b) +{ + *a = cpu_to_be32(be32_to_cpu(*a) + b); +} + +static inline void be64_add_cpu(__be64 *a, __s64 b) +{ + *a = cpu_to_be64(be64_to_cpu(*a) + b); +} + #endif /* __KERNEL__ */ /* do we need conversion? */ @@ -92,16 +107,6 @@ ((__u8*)(pointer))[1] = (((value) ) & 0xff); \ } -/* define generic INT_ macros */ - -#define INT_GET(reference,arch) \ - (((arch) == ARCH_NOCONVERT) \ - ? \ - (reference) \ - : \ - INT_SWAP((reference),(reference)) \ - ) - /* does not return a value */ #define INT_SET(reference,arch,valueref) \ (__builtin_constant_p(valueref) ? \ @@ -112,79 +117,6 @@ ) \ ) -/* does not return a value */ -#define INT_MOD_EXPR(reference,arch,code) \ - (((arch) == ARCH_NOCONVERT) \ - ? \ - (void)((reference) code) \ - : \ - (void)( \ - (reference) = INT_GET((reference),arch) , \ - ((reference) code), \ - INT_SET(reference, arch, reference) \ - ) \ - ) - -/* does not return a value */ -#define INT_MOD(reference,arch,delta) \ - (void)( \ - INT_MOD_EXPR(reference,arch,+=(delta)) \ - ) - -/* - * INT_COPY - copy a value between two locations with the - * _same architecture_ but _potentially different sizes_ - * - * if the types of the two parameters are equal or they are - * in native architecture, a simple copy is done - * - * otherwise, architecture conversions are done - * - */ - -/* does not return a value */ -#define INT_COPY(dst,src,arch) \ - ( \ - ((sizeof(dst) == sizeof(src)) || ((arch) == ARCH_NOCONVERT)) \ - ? \ - (void)((dst) = (src)) \ - : \ - INT_SET(dst, arch, INT_GET(src, arch)) \ - ) - -/* - * INT_XLATE - copy a value in either direction between two locations - * with different architectures - * - * dir < 0 - copy from memory to buffer (native to arch) - * dir > 0 - copy from buffer to memory (arch to native) - */ - -/* does not return a value */ -#define INT_XLATE(buf,mem,dir,arch) {\ - ASSERT(dir); \ - if (dir>0) { \ - (mem)=INT_GET(buf, arch); \ - } else { \ - INT_SET(buf, arch, mem); \ - } \ -} - -static inline void be16_add(__be16 *a, __s16 b) -{ - *a = cpu_to_be16(be16_to_cpu(*a) + b); -} - -static inline void be32_add(__be32 *a, __s32 b) -{ - *a = cpu_to_be32(be32_to_cpu(*a) + b); -} - -static inline void be64_add(__be64 *a, __s64 b) -{ - *a = cpu_to_be64(be64_to_cpu(*a) + b); -} - /* * In directories inode numbers are stored as unaligned arrays of unsigned * 8bit integers on disk. @@ -199,7 +131,7 @@ static inline void be64_add(__be64 *a, __s64 b) * into 32bits a four-member array is used: * * |24-31|16-23| 8-15| 0- 7| - */ + */ #define XFS_GET_DIR_INO4(di) \ (((__u32)(di).i[0] << 24) | ((di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3])) @@ -232,5 +164,5 @@ do { \ (di).i[6] = (((from) & 0x000000000000ff00ULL) >> 8); \ (di).i[7] = ((from) & 0x00000000000000ffULL); \ } while (0) - + #endif /* __XFS_ARCH_H__ */ diff --git a/include/xfs_attr_leaf.h b/include/xfs_attr_leaf.h index 541e34109..83e9af417 100644 --- a/include/xfs_attr_leaf.h +++ b/include/xfs_attr_leaf.h @@ -30,7 +30,7 @@ struct attrlist; struct attrlist_cursor_kern; -struct attrnames; +struct xfs_attr_list_context; struct xfs_dabuf; struct xfs_da_args; struct xfs_da_state; @@ -73,39 +73,39 @@ struct xfs_trans; #define XFS_ATTR_LEAF_MAPSIZE 3 /* how many freespace slots */ typedef struct xfs_attr_leaf_map { /* RLE map of free bytes */ - __uint16_t base; /* base of free region */ - __uint16_t size; /* length of free region */ + __be16 base; /* base of free region */ + __be16 size; /* length of free region */ } xfs_attr_leaf_map_t; typedef struct xfs_attr_leaf_hdr { /* constant-structure header block */ xfs_da_blkinfo_t info; /* block type, links, etc. */ - __uint16_t count; /* count of active leaf_entry's */ - __uint16_t usedbytes; /* num bytes of names/values stored */ - __uint16_t firstused; /* first used byte in name area */ - __uint8_t holes; /* != 0 if blk needs compaction */ - __uint8_t pad1; + __be16 count; /* count of active leaf_entry's */ + __be16 usedbytes; /* num bytes of names/values stored */ + __be16 firstused; /* first used byte in name area */ + __u8 holes; /* != 0 if blk needs compaction */ + __u8 pad1; xfs_attr_leaf_map_t freemap[XFS_ATTR_LEAF_MAPSIZE]; /* N largest free regions */ } xfs_attr_leaf_hdr_t; typedef struct xfs_attr_leaf_entry { /* sorted on key, not name */ - xfs_dahash_t hashval; /* hash value of name */ - __uint16_t nameidx; /* index into buffer of name/value */ - __uint8_t flags; /* LOCAL/ROOT/SECURE/INCOMPLETE flag */ - __uint8_t pad2; /* unused pad byte */ + __be32 hashval; /* hash value of name */ + __be16 nameidx; /* index into buffer of name/value */ + __u8 flags; /* LOCAL/ROOT/SECURE/INCOMPLETE flag */ + __u8 pad2; /* unused pad byte */ } xfs_attr_leaf_entry_t; typedef struct xfs_attr_leaf_name_local { - __uint16_t valuelen; /* number of bytes in value */ - __uint8_t namelen; /* length of name bytes */ - __uint8_t nameval[1]; /* name/value bytes */ + __be16 valuelen; /* number of bytes in value */ + __u8 namelen; /* length of name bytes */ + __u8 nameval[1]; /* name/value bytes */ } xfs_attr_leaf_name_local_t; typedef struct xfs_attr_leaf_name_remote { - xfs_dablk_t valueblk; /* block number of value bytes */ - __uint32_t valuelen; /* number of bytes in value */ - __uint8_t namelen; /* length of name bytes */ - __uint8_t name[1]; /* name bytes */ + __be32 valueblk; /* block number of value bytes */ + __be32 valuelen; /* number of bytes in value */ + __u8 namelen; /* length of name bytes */ + __u8 name[1]; /* name bytes */ } xfs_attr_leaf_name_remote_t; typedef struct xfs_attr_leafblock { @@ -129,6 +129,19 @@ typedef struct xfs_attr_leafblock { #define XFS_ATTR_SECURE (1 << XFS_ATTR_SECURE_BIT) #define XFS_ATTR_INCOMPLETE (1 << XFS_ATTR_INCOMPLETE_BIT) +/* + * Conversion macros for converting namespace bits from argument flags + * to ondisk flags. + */ +#define XFS_ATTR_NSP_ARGS_MASK (ATTR_ROOT | ATTR_SECURE) +#define XFS_ATTR_NSP_ONDISK_MASK (XFS_ATTR_ROOT | XFS_ATTR_SECURE) +#define XFS_ATTR_NSP_ONDISK(flags) ((flags) & XFS_ATTR_NSP_ONDISK_MASK) +#define XFS_ATTR_NSP_ARGS(flags) ((flags) & XFS_ATTR_NSP_ARGS_MASK) +#define XFS_ATTR_NSP_ARGS_TO_ONDISK(x) (((x) & ATTR_ROOT ? XFS_ATTR_ROOT : 0) |\ + ((x) & ATTR_SECURE ? XFS_ATTR_SECURE : 0)) +#define XFS_ATTR_NSP_ONDISK_TO_ARGS(x) (((x) & XFS_ATTR_ROOT ? ATTR_ROOT : 0) |\ + ((x) & XFS_ATTR_SECURE ? ATTR_SECURE : 0)) + /* * Alignment for namelist and valuelist entries (since they are mixed * there can be only one alignment value) @@ -143,8 +156,8 @@ typedef struct xfs_attr_leafblock { static inline xfs_attr_leaf_name_remote_t * xfs_attr_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx) { - return (xfs_attr_leaf_name_remote_t *) &((char *) - (leafp))[INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT)]; + return (xfs_attr_leaf_name_remote_t *) + &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)]; } #define XFS_ATTR_LEAF_NAME_LOCAL(leafp,idx) \ @@ -152,16 +165,15 @@ xfs_attr_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx) static inline xfs_attr_leaf_name_local_t * xfs_attr_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx) { - return (xfs_attr_leaf_name_local_t *) &((char *) - (leafp))[INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT)]; + return (xfs_attr_leaf_name_local_t *) + &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)]; } #define XFS_ATTR_LEAF_NAME(leafp,idx) \ xfs_attr_leaf_name(leafp,idx) static inline char *xfs_attr_leaf_name(xfs_attr_leafblock_t *leafp, int idx) { - return (&((char *) - (leafp))[INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT)]); + return &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)]; } /* @@ -192,23 +204,6 @@ static inline int xfs_attr_leaf_entsize_local_max(int bsize) return (((bsize) >> 1) + ((bsize) >> 2)); } - -/*======================================================================== - * Structure used to pass context around among the routines. - *========================================================================*/ - -typedef struct xfs_attr_list_context { - struct xfs_inode *dp; /* inode */ - struct attrlist_cursor_kern *cursor;/* position in list */ - struct attrlist *alist; /* output buffer */ - int count; /* num used entries */ - int dupcnt; /* count dup hashvals seen */ - int bufsize;/* total buffer size */ - int firstu; /* first used byte in buffer */ - int flags; /* from VOP call */ - int resynch;/* T/F: resynch with cursor */ -} xfs_attr_list_context_t; - /* * Used to keep a list of "remote value" extents when unlinking an inode. */ @@ -279,6 +274,4 @@ int xfs_attr_leaf_order(struct xfs_dabuf *leaf1_bp, struct xfs_dabuf *leaf2_bp); int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local); -int xfs_attr_rolltrans(struct xfs_trans **transp, struct xfs_inode *dp); - #endif /* __XFS_ATTR_LEAF_H__ */ diff --git a/include/xfs_attr_sf.h b/include/xfs_attr_sf.h index ffed6ca81..ea22839ca 100644 --- a/include/xfs_attr_sf.h +++ b/include/xfs_attr_sf.h @@ -32,8 +32,8 @@ struct xfs_inode; */ typedef struct xfs_attr_shortform { struct xfs_attr_sf_hdr { /* constant-structure header block */ - __uint16_t totsize; /* total bytes in shortform list */ - __uint8_t count; /* count of active entries */ + __be16 totsize; /* total bytes in shortform list */ + __u8 count; /* count of active entries */ } hdr; struct xfs_attr_sf_entry { __uint8_t namelen; /* actual length of name (no NULL) */ @@ -66,8 +66,8 @@ typedef struct xfs_attr_sf_sort { #define XFS_ATTR_SF_NEXTENTRY(sfep) /* next entry in struct */ \ ((xfs_attr_sf_entry_t *)((char *)(sfep) + XFS_ATTR_SF_ENTSIZE(sfep))) #define XFS_ATTR_SF_TOTSIZE(dp) /* total space in use */ \ - (INT_GET(((xfs_attr_shortform_t *) \ - ((dp)->i_afp->if_u1.if_data))->hdr.totsize, ARCH_CONVERT)) + (be16_to_cpu(((xfs_attr_shortform_t *) \ + ((dp)->i_afp->if_u1.if_data))->hdr.totsize)) #if defined(XFS_ATTR_TRACE) /* @@ -97,13 +97,9 @@ void xfs_attr_trace_l_cb(char *where, struct xfs_attr_list_context *context, void xfs_attr_trace_l_cl(char *where, struct xfs_attr_list_context *context, struct xfs_attr_leafblock *leaf); void xfs_attr_trace_enter(int type, char *where, - __psunsigned_t a2, __psunsigned_t a3, - __psunsigned_t a4, __psunsigned_t a5, - __psunsigned_t a6, __psunsigned_t a7, - __psunsigned_t a8, __psunsigned_t a9, - __psunsigned_t a10, __psunsigned_t a11, - __psunsigned_t a12, __psunsigned_t a13, - __psunsigned_t a14, __psunsigned_t a15); + struct xfs_attr_list_context *context, + __psunsigned_t a13, __psunsigned_t a14, + __psunsigned_t a15); #else #define xfs_attr_trace_l_c(w,c) #define xfs_attr_trace_l_cn(w,c,n) diff --git a/include/xfs_bit.h b/include/xfs_bit.h index 0bbe56817..bca7b243c 100644 --- a/include/xfs_bit.h +++ b/include/xfs_bit.h @@ -47,16 +47,41 @@ static inline __uint64_t xfs_mask64lo(int n) } /* Get high bit set out of 32-bit argument, -1 if none set */ -extern int xfs_highbit32(__uint32_t v); +static inline int xfs_highbit32(__uint32_t v) +{ + return fls(v) - 1; +} + +/* Get high bit set out of 64-bit argument, -1 if none set */ +static inline int xfs_highbit64(__uint64_t v) +{ + return fls64(v) - 1; +} + +/* Get low bit set out of 32-bit argument, -1 if none set */ +static inline int xfs_lowbit32(__uint32_t v) +{ + return ffs(v) - 1; +} /* Get low bit set out of 64-bit argument, -1 if none set */ -extern int xfs_lowbit64(__uint64_t v); +static inline int xfs_lowbit64(__uint64_t v) +{ + __uint32_t w = (__uint32_t)v; + int n = 0; -/* Get high bit set out of 64-bit argument, -1 if none set */ -extern int xfs_highbit64(__uint64_t); + if (w) { /* lower bits */ + n = ffs(w); + } else { /* upper bits */ + w = (__uint32_t)(v >> 32); + if (w && (n = ffs(w))) + n += 32; + } + return n - 1; +} -/* Count set bits in map starting with start_bit */ -extern int xfs_count_bits(uint *map, uint size, uint start_bit); +/* Return whether bitmap is empty (1 == empty) */ +extern int xfs_bitmap_empty(uint *map, uint size); /* Count continuous one bits in map starting with start_bit */ extern int xfs_contig_bits(uint *map, uint size, uint start_bit); diff --git a/include/xfs_bmap.h b/include/xfs_bmap.h index 12cc63dfc..7c9d12cd7 100644 --- a/include/xfs_bmap.h +++ b/include/xfs_bmap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -20,10 +20,27 @@ struct getbmap; struct xfs_bmbt_irec; +struct xfs_ifork; struct xfs_inode; struct xfs_mount; struct xfs_trans; +extern kmem_zone_t *xfs_bmap_free_item_zone; + +/* + * DELTA: describe a change to the in-core extent list. + * + * Internally the use of xed_blockount is somewhat funky. + * xed_blockcount contains an offset much of the time because this + * makes merging changes easier. (xfs_fileoff_t and xfs_filblks_t are + * the same underlying type). + */ +typedef struct xfs_extdelta +{ + xfs_fileoff_t xed_startoff; /* offset of range */ + xfs_filblks_t xed_blockcount; /* blocks in range */ +} xfs_extdelta_t; + /* * List of extents to be free "later". * The list is kept sorted on xbf_startblock. @@ -37,12 +54,23 @@ typedef struct xfs_bmap_free_item /* * Header for free extent list. + * + * xbf_low is used by the allocator to activate the lowspace algorithm - + * when free space is running low the extent allocator may choose to + * allocate an extent from an AG without leaving sufficient space for + * a btree split when inserting the new extent. In this case the allocator + * will enable the lowspace algorithm which is supposed to allow further + * allocations (such as btree splits and newroots) to allocate from + * sequential AGs. In order to avoid locking AGs out of order the lowspace + * algorithm will start searching for free space from AG 0. If the correct + * transaction reservations have been made then this algorithm will eventually + * find all the space it needs. */ typedef struct xfs_bmap_free { xfs_bmap_free_item_t *xbf_first; /* list of to-be-free extents */ int xbf_count; /* count of items on list */ - int xbf_low; /* kludge: alloc in low mode */ + int xbf_low; /* alloc in low mode */ } xfs_bmap_free_t; #define XFS_BMAP_MAX_NMAP 4 @@ -109,9 +137,7 @@ typedef struct xfs_bmalloca { char conv; /* overwriting unwritten extents */ } xfs_bmalloca_t; -#ifdef __KERNEL__ - -#if defined(XFS_BMAP_TRACE) +#if defined(__KERNEL__) && defined(XFS_BMAP_TRACE) /* * Trace operations for bmap extent tracing */ @@ -129,13 +155,18 @@ extern ktrace_t *xfs_bmap_trace_buf; */ void xfs_bmap_trace_exlist( - char *fname, /* function name */ + const char *fname, /* function name */ struct xfs_inode *ip, /* incore inode pointer */ xfs_extnum_t cnt, /* count of entries in list */ int whichfork); /* data or attr fork */ -#else -#define xfs_bmap_trace_exlist(f,ip,c,w) -#endif +#define XFS_BMAP_TRACE_EXLIST(ip,c,w) \ + xfs_bmap_trace_exlist(__func__,ip,c,w) + +#else /* __KERNEL__ && XFS_BMAP_TRACE */ + +#define XFS_BMAP_TRACE_EXLIST(ip,c,w) + +#endif /* __KERNEL__ && XFS_BMAP_TRACE */ /* * Convert inode from non-attributed to attributed. @@ -175,21 +206,6 @@ xfs_bmap_compute_maxlevels( struct xfs_mount *mp, /* file system mount structure */ int whichfork); /* data or attr fork */ -/* - * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi - * caller. Frees all the extents that need freeing, which must be done - * last due to locking considerations. - * - * Return 1 if the given transaction was committed and a new one allocated, - * and 0 otherwise. - */ -int /* error */ -xfs_bmap_finish( - struct xfs_trans **tp, /* transaction pointer addr */ - xfs_bmap_free_t *flist, /* i/o: list extents to free */ - xfs_fsblock_t firstblock, /* controlled a.g. for allocs */ - int *committed); /* xact committed or not */ - /* * Returns the file-relative block number of the first unused block in the file. * This is the lowest-address hole if the file has holes, else the first block @@ -274,7 +290,9 @@ xfs_bmapi( xfs_extlen_t total, /* total blocks needed */ struct xfs_bmbt_irec *mval, /* output: map values */ int *nmap, /* i/o: mval size/count */ - xfs_bmap_free_t *flist); /* i/o: list extents to free */ + xfs_bmap_free_t *flist, /* i/o: list extents to free */ + xfs_extdelta_t *delta); /* o: change made to incore + extents */ /* * Map file blocks to filesystem blocks, simple version. @@ -308,14 +326,42 @@ xfs_bunmapi( xfs_fsblock_t *firstblock, /* first allocated block controls a.g. for allocs */ xfs_bmap_free_t *flist, /* i/o: list extents to free */ + xfs_extdelta_t *delta, /* o: change made to incore + extents */ int *done); /* set if not done yet */ +/* + * Check an extent list, which has just been read, for + * any bit in the extent flag field. + */ +int +xfs_check_nostate_extents( + struct xfs_ifork *ifp, + xfs_extnum_t idx, + xfs_extnum_t num); + +#ifdef __KERNEL__ + +/* + * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi + * caller. Frees all the extents that need freeing, which must be done + * last due to locking considerations. + * + * Return 1 if the given transaction was committed and a new one allocated, + * and 0 otherwise. + */ +int /* error */ +xfs_bmap_finish( + struct xfs_trans **tp, /* transaction pointer addr */ + xfs_bmap_free_t *flist, /* i/o: list extents to free */ + int *committed); /* xact committed or not */ + /* * Fcntl interface to xfs_bmapi. */ int /* error code */ xfs_getbmap( - bhv_desc_t *bdp, /* XFS behavior descriptor*/ + xfs_inode_t *ip, struct getbmap *bmv, /* user bmap structure */ void __user *ap, /* pointer to user's array */ int iflags); /* interface flags */ @@ -342,13 +388,15 @@ xfs_bmap_count_blocks( int *count); /* - * Check an extent list, which has just been read, for - * any bit in the extent flag field. + * Search the extent records for the entry containing block bno. + * If bno lies in a hole, point to the next entry. If bno lies + * past eof, *eofp will be set, and *prevp will contain the last + * entry (null if none). Else, *lastxp will be set to the index + * of the found entry; *gotp will contain the entry. */ -int -xfs_check_nostate_extents( - xfs_bmbt_rec_t *ep, - xfs_extnum_t num); +xfs_bmbt_rec_host_t * +xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *, + xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *); #endif /* __KERNEL__ */ diff --git a/include/xfs_bmap_btree.h b/include/xfs_bmap_btree.h index e095a2d34..afad34cf7 100644 --- a/include/xfs_bmap_btree.h +++ b/include/xfs_bmap_btree.h @@ -35,45 +35,16 @@ typedef struct xfs_bmdr_block { /* * Bmap btree record and extent descriptor. - * For 32-bit kernels, - * l0:31 is an extent flag (value 1 indicates non-normal). - * l0:0-30 and l1:9-31 are startoff. - * l1:0-8, l2:0-31, and l3:21-31 are startblock. - * l3:0-20 are blockcount. - * For 64-bit kernels, * l0:63 is an extent flag (value 1 indicates non-normal). * l0:9-62 are startoff. * l0:0-8 and l1:21-63 are startblock. * l1:0-20 are blockcount. */ - -#ifndef XFS_NATIVE_HOST - -#define BMBT_TOTAL_BITLEN 128 /* 128 bits, 16 bytes */ -#define BMBT_EXNTFLAG_BITOFF 0 -#define BMBT_EXNTFLAG_BITLEN 1 -#define BMBT_STARTOFF_BITOFF (BMBT_EXNTFLAG_BITOFF + BMBT_EXNTFLAG_BITLEN) -#define BMBT_STARTOFF_BITLEN 54 -#define BMBT_STARTBLOCK_BITOFF (BMBT_STARTOFF_BITOFF + BMBT_STARTOFF_BITLEN) -#define BMBT_STARTBLOCK_BITLEN 52 -#define BMBT_BLOCKCOUNT_BITOFF \ - (BMBT_STARTBLOCK_BITOFF + BMBT_STARTBLOCK_BITLEN) -#define BMBT_BLOCKCOUNT_BITLEN (BMBT_TOTAL_BITLEN - BMBT_BLOCKCOUNT_BITOFF) - -#else - -#define BMBT_TOTAL_BITLEN 128 /* 128 bits, 16 bytes */ -#define BMBT_EXNTFLAG_BITOFF 63 #define BMBT_EXNTFLAG_BITLEN 1 -#define BMBT_STARTOFF_BITOFF (BMBT_EXNTFLAG_BITOFF - BMBT_STARTOFF_BITLEN) #define BMBT_STARTOFF_BITLEN 54 -#define BMBT_STARTBLOCK_BITOFF 85 /* 128 - 43 (other 9 is in first word) */ #define BMBT_STARTBLOCK_BITLEN 52 -#define BMBT_BLOCKCOUNT_BITOFF 64 /* Start of second 64 bit container */ #define BMBT_BLOCKCOUNT_BITLEN 21 -#endif /* XFS_NATIVE_HOST */ - #define BMBT_USE_64 1 @@ -83,12 +54,16 @@ typedef struct xfs_bmbt_rec_32 } xfs_bmbt_rec_32_t; typedef struct xfs_bmbt_rec_64 { - __uint64_t l0, l1; + __be64 l0, l1; } xfs_bmbt_rec_64_t; typedef __uint64_t xfs_bmbt_rec_base_t; /* use this for casts */ typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t; +typedef struct xfs_bmbt_rec_host { + __uint64_t l0, l1; +} xfs_bmbt_rec_host_t; + /* * Values and macros for delayed-allocation startblock fields. */ @@ -145,7 +120,7 @@ typedef enum { * Extent state and extent format macros. */ #define XFS_EXTFMT_INODE(x) \ - (XFS_SB_VERSION_HASEXTFLGBIT(&((x)->i_mount->m_sb)) ? \ + (xfs_sb_version_hasextflgbit(&((x)->i_mount->m_sb)) ? \ XFS_EXTFMT_HASSTATE : XFS_EXTFMT_NOSTATE) #define ISUNWRITTEN(x) ((x)->br_state == XFS_EXT_UNWRITTEN) @@ -163,30 +138,23 @@ typedef struct xfs_bmbt_irec /* * Key structure for non-leaf levels of the tree. */ -typedef struct xfs_bmbt_key -{ - xfs_dfiloff_t br_startoff; /* starting file offset */ +typedef struct xfs_bmbt_key { + __be64 br_startoff; /* starting file offset */ } xfs_bmbt_key_t, xfs_bmdr_key_t; -typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; /* btree pointer type */ - /* btree block header type */ +/* btree pointer type */ +typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; + +/* btree block header type */ typedef struct xfs_btree_lblock xfs_bmbt_block_t; #define XFS_BUF_TO_BMBT_BLOCK(bp) ((xfs_bmbt_block_t *)XFS_BUF_PTR(bp)) -#define XFS_BMAP_IBLOCK_SIZE(lev,cur) (1 << (cur)->bc_blocklog) #define XFS_BMAP_RBLOCK_DSIZE(lev,cur) ((cur)->bc_private.b.forksize) #define XFS_BMAP_RBLOCK_ISIZE(lev,cur) \ ((int)XFS_IFORK_PTR((cur)->bc_private.b.ip, \ (cur)->bc_private.b.whichfork)->if_broot_bytes) -#define XFS_BMAP_BLOCK_DSIZE(lev,cur) \ - (((lev) == (cur)->bc_nlevels - 1 ? \ - XFS_BMAP_RBLOCK_DSIZE(lev,cur) : XFS_BMAP_IBLOCK_SIZE(lev,cur))) -#define XFS_BMAP_BLOCK_ISIZE(lev,cur) \ - (((lev) == (cur)->bc_nlevels - 1 ? \ - XFS_BMAP_RBLOCK_ISIZE(lev,cur) : XFS_BMAP_IBLOCK_SIZE(lev,cur))) - #define XFS_BMAP_BLOCK_DMAXRECS(lev,cur) \ (((lev) == (cur)->bc_nlevels - 1 ? \ XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur), \ @@ -209,37 +177,21 @@ typedef struct xfs_btree_lblock xfs_bmbt_block_t; xfs_bmbt, (lev) == 0) : \ ((cur)->bc_mp->m_bmap_dmnr[(lev) != 0]))) -#define XFS_BMAP_REC_DADDR(bb,i,cur) \ - (XFS_BTREE_REC_ADDR(XFS_BMAP_BLOCK_DSIZE( \ - be16_to_cpu((bb)->bb_level), cur), \ - xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS( \ - be16_to_cpu((bb)->bb_level), cur))) -#define XFS_BMAP_REC_IADDR(bb,i,cur) \ - (XFS_BTREE_REC_ADDR(XFS_BMAP_BLOCK_ISIZE( \ - be16_to_cpu((bb)->bb_level), cur), \ - xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS( \ - be16_to_cpu((bb)->bb_level), cur))) +#define XFS_BMAP_REC_DADDR(bb,i,cur) (XFS_BTREE_REC_ADDR(xfs_bmbt, bb, i)) + +#define XFS_BMAP_REC_IADDR(bb,i,cur) (XFS_BTREE_REC_ADDR(xfs_bmbt, bb, i)) #define XFS_BMAP_KEY_DADDR(bb,i,cur) \ - (XFS_BTREE_KEY_ADDR(XFS_BMAP_BLOCK_DSIZE( \ - be16_to_cpu((bb)->bb_level), cur), \ - xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS( \ - be16_to_cpu((bb)->bb_level), cur))) + (XFS_BTREE_KEY_ADDR(xfs_bmbt, bb, i)) + #define XFS_BMAP_KEY_IADDR(bb,i,cur) \ - (XFS_BTREE_KEY_ADDR(XFS_BMAP_BLOCK_ISIZE( \ - be16_to_cpu((bb)->bb_level), cur), \ - xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS( \ - be16_to_cpu((bb)->bb_level), cur))) + (XFS_BTREE_KEY_ADDR(xfs_bmbt, bb, i)) #define XFS_BMAP_PTR_DADDR(bb,i,cur) \ - (XFS_BTREE_PTR_ADDR(XFS_BMAP_BLOCK_DSIZE( \ - be16_to_cpu((bb)->bb_level), cur), \ - xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS( \ + (XFS_BTREE_PTR_ADDR(xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS( \ be16_to_cpu((bb)->bb_level), cur))) #define XFS_BMAP_PTR_IADDR(bb,i,cur) \ - (XFS_BTREE_PTR_ADDR(XFS_BMAP_BLOCK_ISIZE( \ - be16_to_cpu((bb)->bb_level), cur), \ - xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS( \ + (XFS_BTREE_PTR_ADDR(xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS( \ be16_to_cpu((bb)->bb_level), cur))) /* @@ -247,11 +199,11 @@ typedef struct xfs_btree_lblock xfs_bmbt_block_t; * we don't have a cursor. */ #define XFS_BMAP_BROOT_REC_ADDR(bb,i,sz) \ - (XFS_BTREE_REC_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz))) + (XFS_BTREE_REC_ADDR(xfs_bmbt,bb,i)) #define XFS_BMAP_BROOT_KEY_ADDR(bb,i,sz) \ - (XFS_BTREE_KEY_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz))) + (XFS_BTREE_KEY_ADDR(xfs_bmbt,bb,i)) #define XFS_BMAP_BROOT_PTR_ADDR(bb,i,sz) \ - (XFS_BTREE_PTR_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz))) + (XFS_BTREE_PTR_ADDR(xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz))) #define XFS_BMAP_BROOT_NUMRECS(bb) be16_to_cpu((bb)->bb_numrecs) #define XFS_BMAP_BROOT_MAXRECS(sz) XFS_BTREE_BLOCK_MAXRECS(sz,xfs_bmbt,0) @@ -298,33 +250,25 @@ typedef struct xfs_btree_lblock xfs_bmbt_block_t; extern ktrace_t *xfs_bmbt_trace_buf; #endif +#endif /* __KERNEL__ */ + /* * Prototypes for xfs_bmap.c to call. */ extern void xfs_bmdr_to_bmbt(xfs_bmdr_block_t *, int, xfs_bmbt_block_t *, int); extern int xfs_bmbt_decrement(struct xfs_btree_cur *, int, int *); extern int xfs_bmbt_delete(struct xfs_btree_cur *, int *); -extern void xfs_bmbt_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); +extern void xfs_bmbt_get_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s); extern xfs_bmbt_block_t *xfs_bmbt_get_block(struct xfs_btree_cur *cur, int, struct xfs_buf **bpp); -extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_t *r); -extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_t *r); -extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_t *r); -extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_t *r); +extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_host_t *r); +extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_host_t *r); +extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_host_t *r); +extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_host_t *r); -#ifndef XFS_NATIVE_HOST extern void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); -extern xfs_exntst_t xfs_bmbt_disk_get_state(xfs_bmbt_rec_t *r); extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r); -extern xfs_fsblock_t xfs_bmbt_disk_get_startblock(xfs_bmbt_rec_t *r); extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r); -#else -#define xfs_bmbt_disk_get_all(r, s) xfs_bmbt_get_all(r, s) -#define xfs_bmbt_disk_get_state(r) xfs_bmbt_get_state(r) -#define xfs_bmbt_disk_get_blockcount(r) xfs_bmbt_get_blockcount(r) -#define xfs_bmbt_disk_get_startblock(r) xfs_bmbt_get_blockcount(r) -#define xfs_bmbt_disk_get_startoff(r) xfs_bmbt_get_startoff(r) -#endif /* XFS_NATIVE_HOST */ extern int xfs_bmbt_increment(struct xfs_btree_cur *, int, int *); extern int xfs_bmbt_insert(struct xfs_btree_cur *, int *); @@ -342,44 +286,21 @@ extern int xfs_bmbt_lookup_ge(struct xfs_btree_cur *, xfs_fileoff_t, */ extern int xfs_bmbt_newroot(struct xfs_btree_cur *cur, int *lflags, int *stat); -extern void xfs_bmbt_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); -extern void xfs_bmbt_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o, +extern void xfs_bmbt_set_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s); +extern void xfs_bmbt_set_allf(xfs_bmbt_rec_host_t *r, xfs_fileoff_t o, xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); -extern void xfs_bmbt_set_blockcount(xfs_bmbt_rec_t *r, xfs_filblks_t v); -extern void xfs_bmbt_set_startblock(xfs_bmbt_rec_t *r, xfs_fsblock_t v); -extern void xfs_bmbt_set_startoff(xfs_bmbt_rec_t *r, xfs_fileoff_t v); -extern void xfs_bmbt_set_state(xfs_bmbt_rec_t *r, xfs_exntst_t v); +extern void xfs_bmbt_set_blockcount(xfs_bmbt_rec_host_t *r, xfs_filblks_t v); +extern void xfs_bmbt_set_startblock(xfs_bmbt_rec_host_t *r, xfs_fsblock_t v); +extern void xfs_bmbt_set_startoff(xfs_bmbt_rec_host_t *r, xfs_fileoff_t v); +extern void xfs_bmbt_set_state(xfs_bmbt_rec_host_t *r, xfs_exntst_t v); -#ifndef XFS_NATIVE_HOST extern void xfs_bmbt_disk_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); extern void xfs_bmbt_disk_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o, xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); -#else -#define xfs_bmbt_disk_set_all(r, s) xfs_bmbt_set_all(r, s) -#define xfs_bmbt_disk_set_allf(r, o, b, c, v) xfs_bmbt_set_allf(r, o, b, c, v) -#endif /* XFS_NATIVE_HOST */ extern void xfs_bmbt_to_bmdr(xfs_bmbt_block_t *, int, xfs_bmdr_block_t *, int); extern int xfs_bmbt_update(struct xfs_btree_cur *, xfs_fileoff_t, xfs_fsblock_t, xfs_filblks_t, xfs_exntst_t); -#ifdef DEBUG -/* - * Get the data from the pointed-to record. - */ -extern int xfs_bmbt_get_rec(struct xfs_btree_cur *, xfs_fileoff_t *, - xfs_fsblock_t *, xfs_filblks_t *, - xfs_exntst_t *, int *); -#endif - -/* - * Search an extent list for the extent which includes block - * bno. - */ -xfs_bmbt_rec_t *xfs_bmap_do_search_extents(xfs_bmbt_rec_t *, - xfs_extnum_t, xfs_extnum_t, xfs_fileoff_t, int *, - xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *); - -#endif /* __KERNEL__ */ #endif /* __XFS_BMAP_BTREE_H__ */ diff --git a/include/xfs_btree.h b/include/xfs_btree.h index 44f1bd980..2e9764f91 100644 --- a/include/xfs_btree.h +++ b/include/xfs_btree.h @@ -24,6 +24,8 @@ struct xfs_inode; struct xfs_mount; struct xfs_trans; +extern kmem_zone_t *xfs_btree_cur_zone; + /* * This nonsense is to make -wlint happy. */ @@ -122,13 +124,13 @@ extern const __uint32_t xfs_magics[]; * Given block size, type prefix, block pointer, and index of requested entry * (first entry numbered 1). */ -#define XFS_BTREE_REC_ADDR(bsz,t,bb,i,mxr) \ +#define XFS_BTREE_REC_ADDR(t,bb,i) \ ((t ## _rec_t *)((char *)(bb) + sizeof(t ## _block_t) + \ ((i) - 1) * sizeof(t ## _rec_t))) -#define XFS_BTREE_KEY_ADDR(bsz,t,bb,i,mxr) \ +#define XFS_BTREE_KEY_ADDR(t,bb,i) \ ((t ## _key_t *)((char *)(bb) + sizeof(t ## _block_t) + \ ((i) - 1) * sizeof(t ## _key_t))) -#define XFS_BTREE_PTR_ADDR(bsz,t,bb,i,mxr) \ +#define XFS_BTREE_PTR_ADDR(t,bb,i,mxr) \ ((t ## _ptr_t *)((char *)(bb) + sizeof(t ## _block_t) + \ (mxr) * sizeof(t ## _key_t) + ((i) - 1) * sizeof(t ## _ptr_t))) @@ -145,7 +147,7 @@ typedef struct xfs_btree_cur union { xfs_alloc_rec_incore_t a; xfs_bmbt_irec_t b; - xfs_inobt_rec_t i; + xfs_inobt_rec_incore_t i; } bc_rec; /* current insert/search record value */ struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */ int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */ @@ -156,8 +158,8 @@ typedef struct xfs_btree_cur __uint8_t bc_blocklog; /* log2(blocksize) of btree blocks */ xfs_btnum_t bc_btnum; /* identifies which btree type */ union { - struct { /* needed for BNO, CNT */ - struct xfs_buf *agbp; /* agf buffer pointer */ + struct { /* needed for BNO, CNT, INO */ + struct xfs_buf *agbp; /* agf/agi buffer pointer */ xfs_agnumber_t agno; /* ag number */ } a; struct { /* needed for BMAP */ @@ -170,10 +172,6 @@ typedef struct xfs_btree_cur char flags; /* flags */ #define XFS_BTCUR_BPRV_WASDEL 1 /* was delayed */ } b; - struct { /* needed for INO */ - struct xfs_buf *agbp; /* agi buffer pointer */ - xfs_agnumber_t agno; /* ag number */ - } i; } bc_private; /* per-btree type data */ } xfs_btree_cur_t; @@ -188,8 +186,6 @@ typedef struct xfs_btree_cur #define XFS_BUF_TO_SBLOCK(bp) ((xfs_btree_sblock_t *)XFS_BUF_PTR(bp)) -#ifdef __KERNEL__ - #ifdef DEBUG /* * Debug routine: check that block header is ok. @@ -243,6 +239,9 @@ xfs_btree_check_lptr( xfs_dfsbno_t ptr, /* btree block disk address */ int level); /* btree block level */ +#define xfs_btree_check_lptr_disk(cur, ptr, level) \ + xfs_btree_check_lptr(cur, be64_to_cpu(ptr), level) + /* * Checking routine: check that short form block header is ok. */ @@ -435,36 +434,18 @@ xfs_btree_setbuf( int lev, /* level in btree */ struct xfs_buf *bp); /* new buffer to set */ -#endif /* __KERNEL__ */ - /* * Min and max functions for extlen, agblock, fileoff, and filblks types. */ -#define XFS_EXTLEN_MIN(a,b) \ - ((xfs_extlen_t)(a) < (xfs_extlen_t)(b) ? \ - (xfs_extlen_t)(a) : (xfs_extlen_t)(b)) -#define XFS_EXTLEN_MAX(a,b) \ - ((xfs_extlen_t)(a) > (xfs_extlen_t)(b) ? \ - (xfs_extlen_t)(a) : (xfs_extlen_t)(b)) -#define XFS_AGBLOCK_MIN(a,b) \ - ((xfs_agblock_t)(a) < (xfs_agblock_t)(b) ? \ - (xfs_agblock_t)(a) : (xfs_agblock_t)(b)) -#define XFS_AGBLOCK_MAX(a,b) \ - ((xfs_agblock_t)(a) > (xfs_agblock_t)(b) ? \ - (xfs_agblock_t)(a) : (xfs_agblock_t)(b)) -#define XFS_FILEOFF_MIN(a,b) \ - ((xfs_fileoff_t)(a) < (xfs_fileoff_t)(b) ? \ - (xfs_fileoff_t)(a) : (xfs_fileoff_t)(b)) -#define XFS_FILEOFF_MAX(a,b) \ - ((xfs_fileoff_t)(a) > (xfs_fileoff_t)(b) ? \ - (xfs_fileoff_t)(a) : (xfs_fileoff_t)(b)) -#define XFS_FILBLKS_MIN(a,b) \ - ((xfs_filblks_t)(a) < (xfs_filblks_t)(b) ? \ - (xfs_filblks_t)(a) : (xfs_filblks_t)(b)) -#define XFS_FILBLKS_MAX(a,b) \ - ((xfs_filblks_t)(a) > (xfs_filblks_t)(b) ? \ - (xfs_filblks_t)(a) : (xfs_filblks_t)(b)) +#define XFS_EXTLEN_MIN(a,b) min_t(xfs_extlen_t, (a), (b)) +#define XFS_EXTLEN_MAX(a,b) max_t(xfs_extlen_t, (a), (b)) +#define XFS_AGBLOCK_MIN(a,b) min_t(xfs_agblock_t, (a), (b)) +#define XFS_AGBLOCK_MAX(a,b) max_t(xfs_agblock_t, (a), (b)) +#define XFS_FILEOFF_MIN(a,b) min_t(xfs_fileoff_t, (a), (b)) +#define XFS_FILEOFF_MAX(a,b) max_t(xfs_fileoff_t, (a), (b)) +#define XFS_FILBLKS_MIN(a,b) min_t(xfs_filblks_t, (a), (b)) +#define XFS_FILBLKS_MAX(a,b) max_t(xfs_filblks_t, (a), (b)) #define XFS_FSB_SANITY_CHECK(mp,fsb) \ (XFS_FSB_TO_AGNO(mp, fsb) < mp->m_sb.sb_agcount && \ diff --git a/include/xfs_buf_item.h b/include/xfs_buf_item.h index 07c708c2b..5a41c348b 100644 --- a/include/xfs_buf_item.h +++ b/include/xfs_buf_item.h @@ -18,26 +18,12 @@ #ifndef __XFS_BUF_ITEM_H__ #define __XFS_BUF_ITEM_H__ +extern kmem_zone_t *xfs_buf_item_zone; + /* * This is the structure used to lay out a buf log item in the * log. The data map describes which 128 byte chunks of the buffer - * have been logged. This structure works only on buffers that - * reside up to the first TB in the filesystem. These buffers are - * generated only by pre-6.2 systems and are known as XFS_LI_6_1_BUF. - */ -typedef struct xfs_buf_log_format_v1 { - unsigned short blf_type; /* buf log item type indicator */ - unsigned short blf_size; /* size of this item */ - __int32_t blf_blkno; /* starting blkno of this buf */ - ushort blf_flags; /* misc state */ - ushort blf_len; /* number of blocks in this buf */ - unsigned int blf_map_size; /* size of data bitmap in words */ - unsigned int blf_data_map[1];/* variable size bitmap of */ - /* regions of buffer in this item */ -} xfs_buf_log_format_v1_t; - -/* - * This is a form of the above structure with a 64 bit blkno field. + * have been logged. * For 6.2 and beyond, this is XFS_LI_BUF. We use this to log everything. */ typedef struct xfs_buf_log_format_t { diff --git a/include/xfs_da_btree.h b/include/xfs_da_btree.h index 49e38167e..70b710c17 100644 --- a/include/xfs_da_btree.h +++ b/include/xfs_da_btree.h @@ -36,19 +36,15 @@ struct zone; * level in the Btree, and to identify which type of block this is. */ #define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */ -#define XFS_DIR_LEAF_MAGIC 0xfeeb /* magic number: directory leaf blks */ #define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */ #define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */ #define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */ -#define XFS_DIRX_LEAF_MAGIC(mp) \ - (XFS_DIR_IS_V1(mp) ? XFS_DIR_LEAF_MAGIC : XFS_DIR2_LEAFN_MAGIC) - typedef struct xfs_da_blkinfo { - xfs_dablk_t forw; /* previous block in list */ - xfs_dablk_t back; /* following block in list */ - __uint16_t magic; /* validity check on block */ - __uint16_t pad; /* unused */ + __be32 forw; /* previous block in list */ + __be32 back; /* following block in list */ + __be16 magic; /* validity check on block */ + __be16 pad; /* unused */ } xfs_da_blkinfo_t; /* @@ -65,38 +61,18 @@ typedef struct xfs_da_blkinfo { typedef struct xfs_da_intnode { struct xfs_da_node_hdr { /* constant-structure header block */ xfs_da_blkinfo_t info; /* block type, links, etc. */ - __uint16_t count; /* count of active entries */ - __uint16_t level; /* level above leaves (leaf == 0) */ + __be16 count; /* count of active entries */ + __be16 level; /* level above leaves (leaf == 0) */ } hdr; struct xfs_da_node_entry { - xfs_dahash_t hashval; /* hash value for this descendant */ - xfs_dablk_t before; /* Btree block before this key */ + __be32 hashval; /* hash value for this descendant */ + __be32 before; /* Btree block before this key */ } btree[1]; /* variable sized array of keys */ } xfs_da_intnode_t; typedef struct xfs_da_node_hdr xfs_da_node_hdr_t; typedef struct xfs_da_node_entry xfs_da_node_entry_t; -#define XFS_DA_MAXHASH ((xfs_dahash_t)-1) /* largest valid hash value */ - #define XFS_LBSIZE(mp) (mp)->m_sb.sb_blocksize -#define XFS_LBLOG(mp) (mp)->m_sb.sb_blocklog - -#define XFS_DA_MAKE_BNOENTRY(mp,bno,entry) \ - (((bno) << (mp)->m_dircook_elog) | (entry)) -#define XFS_DA_MAKE_COOKIE(mp,bno,entry,hash) \ - (((xfs_off_t)XFS_DA_MAKE_BNOENTRY(mp, bno, entry) << 32) | (hash)) -#define XFS_DA_COOKIE_HASH(mp,cookie) ((xfs_dahash_t)cookie) -#define XFS_DA_COOKIE_BNO(mp,cookie) \ - ((((xfs_off_t)(cookie) >> 31) == -1LL ? \ - (xfs_dablk_t)0 : \ - (xfs_dablk_t)((xfs_off_t)(cookie) >> \ - ((mp)->m_dircook_elog + 32)))) -#define XFS_DA_COOKIE_ENTRY(mp,cookie) \ - ((((xfs_off_t)(cookie) >> 31) == -1LL ? \ - (xfs_dablk_t)0 : \ - (xfs_dablk_t)(((xfs_off_t)(cookie) >> 32) & \ - ((1 << (mp)->m_dircook_elog) - 1)))) - /*======================================================================== * Btree searching and modification structure definitions. @@ -136,13 +112,19 @@ typedef struct xfs_da_args { int index2; /* index of 2nd attr in blk */ xfs_dablk_t rmtblkno2; /* remote attr value starting blkno */ int rmtblkcnt2; /* remote attr value block count */ - unsigned char justcheck; /* T/F: check for ok with no space */ - 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 */ + int op_flags; /* operation flags */ enum xfs_dacmp cmpresult; /* name compare result for lookups */ } xfs_da_args_t; +/* + * Operation flags: + */ +#define XFS_DA_OP_JUSTCHECK 0x0001 /* check for ok with no space */ +#define XFS_DA_OP_RENAME 0x0002 /* this is an atomic rename op */ +#define XFS_DA_OP_ADDNAME 0x0004 /* this is an add operation */ +#define XFS_DA_OP_OKNOENT 0x0008 /* lookup/add op, ENOENT ok, else die */ +#define XFS_DA_OP_CILOOKUP 0x0010 /* lookup to return CI name if found */ + /* * Structure to describe buffer(s) for a block. * This is needed in the directory version 2 format case, when @@ -219,14 +201,13 @@ typedef struct xfs_da_state { * 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); + xfs_dahash_t (*hashname)(struct xfs_name *); + enum xfs_dacmp (*compname)(struct xfs_da_args *, const char *, int); }; -#ifdef __KERNEL__ /*======================================================================== - * Function prototypes for the kernel. + * Function prototypes. *========================================================================*/ /* @@ -271,10 +252,10 @@ 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); +enum xfs_dacmp xfs_da_compname(struct xfs_da_args *args, + const char *name, int len); + -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); @@ -286,6 +267,6 @@ void xfs_da_binval(struct xfs_trans *tp, xfs_dabuf_t *dabuf); xfs_daddr_t xfs_da_blkno(xfs_dabuf_t *dabuf); extern struct kmem_zone *xfs_da_state_zone; -#endif /* __KERNEL__ */ +extern struct kmem_zone *xfs_dabuf_zone; #endif /* __XFS_DA_BTREE_H__ */ diff --git a/include/xfs_dfrag.h b/include/xfs_dfrag.h index f678559ab..da178205b 100644 --- a/include/xfs_dfrag.h +++ b/include/xfs_dfrag.h @@ -48,6 +48,9 @@ typedef struct xfs_swapext */ int xfs_swapext(struct xfs_swapext __user *sx); +int xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip, + struct xfs_swapext *sxp); + #endif /* __KERNEL__ */ #endif /* __XFS_DFRAG_H__ */ diff --git a/include/xfs_dinode.h b/include/xfs_dinode.h index bf4428d06..c9065eaf2 100644 --- a/include/xfs_dinode.h +++ b/include/xfs_dinode.h @@ -34,41 +34,41 @@ struct xfs_mount; * because we only need the core part in the in-core inode. */ typedef struct xfs_timestamp { - __int32_t t_sec; /* timestamp seconds */ - __int32_t t_nsec; /* timestamp nanoseconds */ + __be32 t_sec; /* timestamp seconds */ + __be32 t_nsec; /* timestamp nanoseconds */ } xfs_timestamp_t; /* * Note: Coordinate changes to this structure with the XFS_DI_* #defines - * below and the offsets table in xfs_ialloc_log_di(). + * below, the offsets table in xfs_ialloc_log_di() and struct xfs_icdinode + * in xfs_inode.h. */ -typedef struct xfs_dinode_core -{ - __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ - __uint16_t di_mode; /* mode and type of file */ - __int8_t di_version; /* inode version */ - __int8_t di_format; /* format of di_c data */ - __uint16_t di_onlink; /* old number of links to file */ - __uint32_t di_uid; /* owner's user id */ - __uint32_t di_gid; /* owner's group id */ - __uint32_t di_nlink; /* number of links to file */ - __uint16_t di_projid; /* owner's project id */ - __uint8_t di_pad[8]; /* unused, zeroed space */ - __uint16_t di_flushiter; /* incremented on flush */ +typedef struct xfs_dinode_core { + __be16 di_magic; /* inode magic # = XFS_DINODE_MAGIC */ + __be16 di_mode; /* mode and type of file */ + __u8 di_version; /* inode version */ + __u8 di_format; /* format of di_c data */ + __be16 di_onlink; /* old number of links to file */ + __be32 di_uid; /* owner's user id */ + __be32 di_gid; /* owner's group id */ + __be32 di_nlink; /* number of links to file */ + __be16 di_projid; /* owner's project id */ + __u8 di_pad[8]; /* unused, zeroed space */ + __be16 di_flushiter; /* incremented on flush */ xfs_timestamp_t di_atime; /* time last accessed */ xfs_timestamp_t di_mtime; /* time last modified */ xfs_timestamp_t di_ctime; /* time created/inode modified */ - xfs_fsize_t di_size; /* number of bytes in file */ - xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */ - xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ - xfs_extnum_t di_nextents; /* number of extents in data fork */ - xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ - __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ - __int8_t di_aformat; /* format of attr fork's data */ - __uint32_t di_dmevmask; /* DMIG event mask */ - __uint16_t di_dmstate; /* DMIG state info */ - __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ - __uint32_t di_gen; /* generation number */ + __be64 di_size; /* number of bytes in file */ + __be64 di_nblocks; /* # of direct & btree blocks used */ + __be32 di_extsize; /* basic/minimum extent size for file */ + __be32 di_nextents; /* number of extents in data fork */ + __be16 di_anextents; /* number of extents in attribute fork*/ + __u8 di_forkoff; /* attr fork offs, <<3 for 64b align */ + __s8 di_aformat; /* format of attr fork's data */ + __be32 di_dmevmask; /* DMIG event mask */ + __be16 di_dmstate; /* DMIG state info */ + __be16 di_flags; /* random flags, XFS_DIFLAG_... */ + __be32 di_gen; /* generation number */ } xfs_dinode_core_t; #define DI_MAX_FLUSH 0xffff @@ -81,14 +81,13 @@ typedef struct xfs_dinode * sure to update the macros like XFS_LITINO below and * XFS_BMAP_RBLOCK_DSIZE in xfs_bmap_btree.h. */ - xfs_agino_t di_next_unlinked;/* agi unlinked list ptr */ + __be32 di_next_unlinked;/* agi unlinked list ptr */ union { xfs_bmdr_block_t di_bmbt; /* btree root block */ xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */ - xfs_dir_shortform_t di_dirsf; /* shortform directory */ xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */ char di_c[1]; /* local contents */ - xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */ + __be32 di_dev; /* device for S_IFCHR/S_IFBLK */ uuid_t di_muuid; /* mount point value */ char di_symlink[1]; /* local symbolic link */ } di_u; @@ -172,70 +171,35 @@ typedef enum xfs_dinode_fmt /* * Inode data & attribute fork sizes, per inode. */ -#define XFS_CFORK_Q(dcp) ((dcp)->di_forkoff != 0) -#define XFS_CFORK_Q_DISK(dcp) ((dcp)->di_forkoff != 0) - -#define XFS_CFORK_BOFF(dcp) ((int)((dcp)->di_forkoff << 3)) -#define XFS_CFORK_BOFF_DISK(dcp) \ - ((int)(INT_GET((dcp)->di_forkoff, ARCH_CONVERT) << 3)) - -#define XFS_CFORK_DSIZE_DISK(dcp,mp) \ - (XFS_CFORK_Q_DISK(dcp) ? XFS_CFORK_BOFF_DISK(dcp) : XFS_LITINO(mp)) -#define XFS_CFORK_DSIZE(dcp,mp) \ - (XFS_CFORK_Q(dcp) ? XFS_CFORK_BOFF(dcp) : XFS_LITINO(mp)) - -#define XFS_CFORK_ASIZE_DISK(dcp,mp) \ - (XFS_CFORK_Q_DISK(dcp) ? XFS_LITINO(mp) - XFS_CFORK_BOFF_DISK(dcp) : 0) -#define XFS_CFORK_ASIZE(dcp,mp) \ - (XFS_CFORK_Q(dcp) ? XFS_LITINO(mp) - XFS_CFORK_BOFF(dcp) : 0) - -#define XFS_CFORK_SIZE_DISK(dcp,mp,w) \ - ((w) == XFS_DATA_FORK ? \ - XFS_CFORK_DSIZE_DISK(dcp, mp) : \ - XFS_CFORK_ASIZE_DISK(dcp, mp)) -#define XFS_CFORK_SIZE(dcp,mp,w) \ - ((w) == XFS_DATA_FORK ? \ - XFS_CFORK_DSIZE(dcp, mp) : XFS_CFORK_ASIZE(dcp, mp)) +#define XFS_DFORK_Q(dip) ((dip)->di_core.di_forkoff != 0) +#define XFS_DFORK_BOFF(dip) ((int)((dip)->di_core.di_forkoff << 3)) #define XFS_DFORK_DSIZE(dip,mp) \ - XFS_CFORK_DSIZE_DISK(&(dip)->di_core, mp) -#define XFS_DFORK_DSIZE_HOST(dip,mp) \ - XFS_CFORK_DSIZE(&(dip)->di_core, mp) + (XFS_DFORK_Q(dip) ? \ + XFS_DFORK_BOFF(dip) : \ + XFS_LITINO(mp)) #define XFS_DFORK_ASIZE(dip,mp) \ - XFS_CFORK_ASIZE_DISK(&(dip)->di_core, mp) -#define XFS_DFORK_ASIZE_HOST(dip,mp) \ - XFS_CFORK_ASIZE(&(dip)->di_core, mp) -#define XFS_DFORK_SIZE(dip,mp,w) \ - XFS_CFORK_SIZE_DISK(&(dip)->di_core, mp, w) -#define XFS_DFORK_SIZE_HOST(dip,mp,w) \ - XFS_CFORK_SIZE(&(dip)->di_core, mp, w) + (XFS_DFORK_Q(dip) ? \ + XFS_LITINO(mp) - XFS_DFORK_BOFF(dip) : \ + 0) +#define XFS_DFORK_SIZE(dip,mp,w) \ + ((w) == XFS_DATA_FORK ? \ + XFS_DFORK_DSIZE(dip, mp) : \ + XFS_DFORK_ASIZE(dip, mp)) -#define XFS_DFORK_Q(dip) XFS_CFORK_Q_DISK(&(dip)->di_core) -#define XFS_DFORK_BOFF(dip) XFS_CFORK_BOFF_DISK(&(dip)->di_core) -#define XFS_DFORK_DPTR(dip) ((dip)->di_u.di_c) -#define XFS_DFORK_APTR(dip) \ +#define XFS_DFORK_DPTR(dip) ((dip)->di_u.di_c) +#define XFS_DFORK_APTR(dip) \ ((dip)->di_u.di_c + XFS_DFORK_BOFF(dip)) -#define XFS_DFORK_PTR(dip,w) \ +#define XFS_DFORK_PTR(dip,w) \ ((w) == XFS_DATA_FORK ? XFS_DFORK_DPTR(dip) : XFS_DFORK_APTR(dip)) -#define XFS_CFORK_FORMAT(dcp,w) \ - ((w) == XFS_DATA_FORK ? (dcp)->di_format : (dcp)->di_aformat) -#define XFS_CFORK_FMT_SET(dcp,w,n) \ - ((w) == XFS_DATA_FORK ? \ - ((dcp)->di_format = (n)) : ((dcp)->di_aformat = (n))) -#define XFS_DFORK_FORMAT(dip,w) XFS_CFORK_FORMAT(&(dip)->di_core, w) - -#define XFS_CFORK_NEXTENTS_DISK(dcp,w) \ +#define XFS_DFORK_FORMAT(dip,w) \ ((w) == XFS_DATA_FORK ? \ - INT_GET((dcp)->di_nextents, ARCH_CONVERT) : \ - INT_GET((dcp)->di_anextents, ARCH_CONVERT)) -#define XFS_CFORK_NEXTENTS(dcp,w) \ - ((w) == XFS_DATA_FORK ? (dcp)->di_nextents : (dcp)->di_anextents) -#define XFS_DFORK_NEXTENTS(dip,w) XFS_CFORK_NEXTENTS_DISK(&(dip)->di_core, w) -#define XFS_DFORK_NEXTENTS_HOST(dip,w) XFS_CFORK_NEXTENTS(&(dip)->di_core, w) - -#define XFS_CFORK_NEXT_SET(dcp,w,n) \ + (dip)->di_core.di_format : \ + (dip)->di_core.di_aformat) +#define XFS_DFORK_NEXTENTS(dip,w) \ ((w) == XFS_DATA_FORK ? \ - ((dcp)->di_nextents = (n)) : ((dcp)->di_anextents = (n))) + be32_to_cpu((dip)->di_core.di_nextents) : \ + be16_to_cpu((dip)->di_core.di_anextents)) #define XFS_BUF_TO_DINODE(bp) ((xfs_dinode_t *)XFS_BUF_PTR(bp)) @@ -258,7 +222,7 @@ typedef enum xfs_dinode_fmt #define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */ #define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */ #define XFS_DIFLAG_NODEFRAG_BIT 13 /* do not reorganize/defragment */ -#define XFS_DIFLAG_FILESTREAM_BIT 14 /* use filestream allocator */ +#define XFS_DIFLAG_FILESTREAM_BIT 14 /* use filestream allocator */ #define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT) #define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT) #define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT) @@ -275,6 +239,12 @@ typedef enum xfs_dinode_fmt #define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT) #define XFS_DIFLAG_FILESTREAM (1 << XFS_DIFLAG_FILESTREAM_BIT) +#ifdef CONFIG_XFS_RT +#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) +#else +#define XFS_IS_REALTIME_INODE(ip) (0) +#endif + #define XFS_DIFLAG_ANY \ (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \ XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \ diff --git a/include/xfs_dir.h b/include/xfs_dir.h deleted file mode 100644 index 8cc8afb9f..000000000 --- a/include/xfs_dir.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2000,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_DIR_H__ -#define __XFS_DIR_H__ - -/* - * Large directories are structured around Btrees where all the data - * elements are in the leaf nodes. Filenames are hashed into an int, - * then that int is used as the index into the Btree. Since the hashval - * of a filename may not be unique, we may have duplicate keys. The - * internal links in the Btree are logical block offsets into the file. - * - * Small directories use a different format and are packed as tightly - * as possible so as to fit into the literal area of the inode. - */ - -/*======================================================================== - * Function prototypes for the kernel. - *========================================================================*/ - -struct uio; -struct xfs_bmap_free; -struct xfs_da_args; -struct xfs_dinode; -struct xfs_inode; -struct xfs_mount; -struct xfs_trans; - -/* - * Directory function types. - * Put in structures (xfs_dirops_t) for v1 and v2 directories. - */ -typedef void (*xfs_dir_mount_t)(struct xfs_mount *mp); -typedef int (*xfs_dir_isempty_t)(struct xfs_inode *dp); -typedef int (*xfs_dir_init_t)(struct xfs_trans *tp, - struct xfs_inode *dp, - struct xfs_inode *pdp); -typedef int (*xfs_dir_createname_t)(struct xfs_trans *tp, - struct xfs_inode *dp, - char *name, - int namelen, - xfs_ino_t inum, - xfs_fsblock_t *first, - struct xfs_bmap_free *flist, - xfs_extlen_t total); -typedef int (*xfs_dir_lookup_t)(struct xfs_trans *tp, - struct xfs_inode *dp, - char *name, - int namelen, - xfs_ino_t *inum); -typedef int (*xfs_dir_removename_t)(struct xfs_trans *tp, - struct xfs_inode *dp, - char *name, - int namelen, - xfs_ino_t ino, - xfs_fsblock_t *first, - struct xfs_bmap_free *flist, - xfs_extlen_t total); -typedef int (*xfs_dir_getdents_t)(struct xfs_trans *tp, - struct xfs_inode *dp, - struct uio *uio, - int *eofp); -typedef int (*xfs_dir_replace_t)(struct xfs_trans *tp, - struct xfs_inode *dp, - char *name, - int namelen, - xfs_ino_t inum, - xfs_fsblock_t *first, - struct xfs_bmap_free *flist, - xfs_extlen_t total); -typedef int (*xfs_dir_canenter_t)(struct xfs_trans *tp, - struct xfs_inode *dp, - char *name, - int namelen); -typedef int (*xfs_dir_shortform_validate_ondisk_t)(struct xfs_mount *mp, - struct xfs_dinode *dip); -typedef int (*xfs_dir_shortform_to_single_t)(struct xfs_da_args *args); - -typedef struct xfs_dirops { - xfs_dir_mount_t xd_mount; - xfs_dir_isempty_t xd_isempty; - xfs_dir_init_t xd_init; - xfs_dir_createname_t xd_createname; - xfs_dir_lookup_t xd_lookup; - xfs_dir_removename_t xd_removename; - xfs_dir_getdents_t xd_getdents; - xfs_dir_replace_t xd_replace; - xfs_dir_canenter_t xd_canenter; - xfs_dir_shortform_validate_ondisk_t xd_shortform_validate_ondisk; - xfs_dir_shortform_to_single_t xd_shortform_to_single; -} xfs_dirops_t; - -/* - * Overall external interface routines. - */ -void xfs_dir_startup(void); /* called exactly once */ - -#define XFS_DIR_MOUNT(mp) \ - ((mp)->m_dirops.xd_mount(mp)) -#define XFS_DIR_ISEMPTY(mp,dp) \ - ((mp)->m_dirops.xd_isempty(dp)) -#define XFS_DIR_INIT(mp,tp,dp,pdp) \ - ((mp)->m_dirops.xd_init(tp,dp,pdp)) -#define XFS_DIR_CREATENAME(mp,tp,dp,name,namelen,inum,first,flist,total) \ - ((mp)->m_dirops.xd_createname(tp,dp,name,namelen,inum,first,flist,\ - total)) -#define XFS_DIR_LOOKUP(mp,tp,dp,name,namelen,inum) \ - ((mp)->m_dirops.xd_lookup(tp,dp,name,namelen,inum)) -#define XFS_DIR_REMOVENAME(mp,tp,dp,name,namelen,ino,first,flist,total) \ - ((mp)->m_dirops.xd_removename(tp,dp,name,namelen,ino,first,flist,total)) -#define XFS_DIR_GETDENTS(mp,tp,dp,uio,eofp) \ - ((mp)->m_dirops.xd_getdents(tp,dp,uio,eofp)) -#define XFS_DIR_REPLACE(mp,tp,dp,name,namelen,inum,first,flist,total) \ - ((mp)->m_dirops.xd_replace(tp,dp,name,namelen,inum,first,flist,total)) -#define XFS_DIR_CANENTER(mp,tp,dp,name,namelen) \ - ((mp)->m_dirops.xd_canenter(tp,dp,name,namelen)) -#define XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp,dip) \ - ((mp)->m_dirops.xd_shortform_validate_ondisk(mp,dip)) -#define XFS_DIR_SHORTFORM_TO_SINGLE(mp,args) \ - ((mp)->m_dirops.xd_shortform_to_single(args)) - -#define XFS_DIR_IS_V1(mp) ((mp)->m_dirversion == 1) -#define XFS_DIR_IS_V2(mp) ((mp)->m_dirversion == 2) -extern xfs_dirops_t xfsv1_dirops; -extern xfs_dirops_t xfsv2_dirops; - -#endif /* __XFS_DIR_H__ */ diff --git a/include/xfs_dir2.h b/include/xfs_dir2.h index 3158f5dc4..1d9ef96f3 100644 --- a/include/xfs_dir2.h +++ b/include/xfs_dir2.h @@ -22,7 +22,9 @@ struct uio; struct xfs_dabuf; struct xfs_da_args; struct xfs_dir2_put_args; +struct xfs_bmap_free; struct xfs_inode; +struct xfs_mount; struct xfs_trans; /* @@ -55,38 +57,50 @@ typedef __uint32_t xfs_dir2_db_t; /* * Byte offset in a directory. */ -typedef xfs_off_t xfs_dir2_off_t; +typedef xfs_off_t xfs_dir2_off_t; + +extern struct xfs_name xfs_name_dotdot; /* - * For getdents, argument struct for put routines. + * Generic directory interface routines */ -typedef int (*xfs_dir2_put_t)(struct xfs_dir2_put_args *pa); -typedef struct xfs_dir2_put_args { - xfs_off_t cook; /* cookie of (next) entry */ - xfs_intino_t ino; /* inode number */ - struct xfs_dirent *dbp; /* buffer pointer */ - char *name; /* directory entry name */ - int namelen; /* length of name */ - int done; /* output: set if value was stored */ - xfs_dir2_put_t put; /* put function ptr (i/o) */ - struct uio *uio; /* uio control structure */ -} xfs_dir2_put_args_t; +extern void xfs_dir_startup(void); +extern void xfs_dir_mount(struct xfs_mount *mp); +extern int xfs_dir_isempty(struct xfs_inode *dp); +extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp, + struct xfs_inode *pdp); +extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp, + struct xfs_name *name, xfs_ino_t inum, + xfs_fsblock_t *first, + struct xfs_bmap_free *flist, xfs_extlen_t tot); +extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp, + struct xfs_name *name, xfs_ino_t *inum, + struct xfs_name *ci_name); +extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp, + struct xfs_name *name, xfs_ino_t ino, + xfs_fsblock_t *first, + struct xfs_bmap_free *flist, xfs_extlen_t tot); +extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp, + struct xfs_name *name, xfs_ino_t inum, + xfs_fsblock_t *first, + struct xfs_bmap_free *flist, xfs_extlen_t tot); +extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, + struct xfs_name *name, uint resblks); +extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); /* - * Other interfaces used by the rest of the dir v2 code. + * Utility routines for v2 directories. */ -extern int - xfs_dir2_grow_inode(struct xfs_da_args *args, int space, - xfs_dir2_db_t *dbp); - -extern int - xfs_dir2_isblock(struct xfs_trans *tp, struct xfs_inode *dp, int *vp); - -extern int - xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp, int *vp); +extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, + xfs_dir2_db_t *dbp); +extern int xfs_dir2_isblock(struct xfs_trans *tp, struct xfs_inode *dp, + int *vp); +extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp, + int *vp); +extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, + struct xfs_dabuf *bp); -extern int - xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, - struct xfs_dabuf *bp); +extern int xfs_dir_cilookup_result(struct xfs_da_args *args, const char *name, + int len); #endif /* __XFS_DIR2_H__ */ diff --git a/include/xfs_dir2_block.h b/include/xfs_dir2_block.h index a2e5cb98a..10e689676 100644 --- a/include/xfs_dir2_block.h +++ b/include/xfs_dir2_block.h @@ -43,8 +43,8 @@ struct xfs_trans; #define XFS_DIR2_BLOCK_MAGIC 0x58443242 /* XD2B: for one block dirs */ typedef struct xfs_dir2_block_tail { - __uint32_t count; /* count of leaf entries */ - __uint32_t stale; /* count of stale lf entries */ + __be32 count; /* count of leaf entries */ + __be32 stale; /* count of stale lf entries */ } xfs_dir2_block_tail_t; /* @@ -60,7 +60,6 @@ typedef struct xfs_dir2_block { /* * Pointer to the leaf header embedded in a data block (1-block format) */ -#define XFS_DIR2_BLOCK_TAIL_P(mp,block) xfs_dir2_block_tail_p(mp,block) static inline xfs_dir2_block_tail_t * xfs_dir2_block_tail_p(struct xfs_mount *mp, xfs_dir2_block_t *block) { @@ -71,21 +70,18 @@ xfs_dir2_block_tail_p(struct xfs_mount *mp, xfs_dir2_block_t *block) /* * Pointer to the leaf entries embedded in a data block (1-block format) */ -#define XFS_DIR2_BLOCK_LEAF_P(btp) xfs_dir2_block_leaf_p(btp) static inline struct xfs_dir2_leaf_entry * xfs_dir2_block_leaf_p(xfs_dir2_block_tail_t *btp) { - return (((struct xfs_dir2_leaf_entry *) - (btp)) - INT_GET((btp)->count, ARCH_CONVERT)); + return ((struct xfs_dir2_leaf_entry *)btp) - be32_to_cpu(btp->count); } /* * Function declarations. */ extern int xfs_dir2_block_addname(struct xfs_da_args *args); -extern int xfs_dir2_block_getdents(struct xfs_trans *tp, struct xfs_inode *dp, - struct uio *uio, int *eofp, - struct xfs_dirent *dbp, xfs_dir2_put_t put); +extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent, + xfs_off_t *offset, filldir_t filldir); extern int xfs_dir2_block_lookup(struct xfs_da_args *args); extern int xfs_dir2_block_removename(struct xfs_da_args *args); extern int xfs_dir2_block_replace(struct xfs_da_args *args); diff --git a/include/xfs_dir2_data.h b/include/xfs_dir2_data.h index 5e3a7f9ec..b816e0252 100644 --- a/include/xfs_dir2_data.h +++ b/include/xfs_dir2_data.h @@ -44,7 +44,7 @@ struct xfs_trans; #define XFS_DIR2_DATA_SPACE 0 #define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE) #define XFS_DIR2_DATA_FIRSTDB(mp) \ - XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_DATA_OFFSET) + xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET) /* * Offsets of . and .. in data space (always block 0) @@ -52,9 +52,9 @@ struct xfs_trans; #define XFS_DIR2_DATA_DOT_OFFSET \ ((xfs_dir2_data_aoff_t)sizeof(xfs_dir2_data_hdr_t)) #define XFS_DIR2_DATA_DOTDOT_OFFSET \ - (XFS_DIR2_DATA_DOT_OFFSET + XFS_DIR2_DATA_ENTSIZE(1)) + (XFS_DIR2_DATA_DOT_OFFSET + xfs_dir2_data_entsize(1)) #define XFS_DIR2_DATA_FIRST_OFFSET \ - (XFS_DIR2_DATA_DOTDOT_OFFSET + XFS_DIR2_DATA_ENTSIZE(2)) + (XFS_DIR2_DATA_DOTDOT_OFFSET + xfs_dir2_data_entsize(2)) /* * Structures. @@ -65,8 +65,8 @@ struct xfs_trans; * The freespace will be formatted as a xfs_dir2_data_unused_t. */ typedef struct xfs_dir2_data_free { - xfs_dir2_data_off_t offset; /* start of freespace */ - xfs_dir2_data_off_t length; /* length of freespace */ + __be16 offset; /* start of freespace */ + __be16 length; /* length of freespace */ } xfs_dir2_data_free_t; /* @@ -75,7 +75,7 @@ typedef struct xfs_dir2_data_free { * The code knows that XFS_DIR2_DATA_FD_COUNT is 3. */ typedef struct xfs_dir2_data_hdr { - __uint32_t magic; /* XFS_DIR2_DATA_MAGIC */ + __be32 magic; /* XFS_DIR2_DATA_MAGIC */ /* or XFS_DIR2_BLOCK_MAGIC */ xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT]; } xfs_dir2_data_hdr_t; @@ -85,11 +85,11 @@ typedef struct xfs_dir2_data_hdr { * Tag appears as the last 2 bytes. */ typedef struct xfs_dir2_data_entry { - xfs_ino_t inumber; /* inode number */ - __uint8_t namelen; /* name length */ - __uint8_t name[1]; /* name bytes, no null */ + __be64 inumber; /* inode number */ + __u8 namelen; /* name length */ + __u8 name[1]; /* name bytes, no null */ /* variable offset */ - xfs_dir2_data_off_t tag; /* starting offset of us */ + __be16 tag; /* starting offset of us */ } xfs_dir2_data_entry_t; /* @@ -97,10 +97,10 @@ typedef struct xfs_dir2_data_entry { * Tag appears as the last 2 bytes. */ typedef struct xfs_dir2_data_unused { - __uint16_t freetag; /* XFS_DIR2_DATA_FREE_TAG */ - xfs_dir2_data_off_t length; /* total free length */ + __be16 freetag; /* XFS_DIR2_DATA_FREE_TAG */ + __be16 length; /* total free length */ /* variable offset */ - xfs_dir2_data_off_t tag; /* starting offset of us */ + __be16 tag; /* starting offset of us */ } xfs_dir2_data_unused_t; typedef union { @@ -123,7 +123,6 @@ typedef struct xfs_dir2_data { /* * Size of a data entry. */ -#define XFS_DIR2_DATA_ENTSIZE(n) xfs_dir2_data_entsize(n) static inline int xfs_dir2_data_entsize(int n) { return (int)roundup(offsetof(xfs_dir2_data_entry_t, name[0]) + (n) + \ @@ -133,26 +132,21 @@ static inline int xfs_dir2_data_entsize(int n) /* * Pointer to an entry's tag word. */ -#define XFS_DIR2_DATA_ENTRY_TAG_P(dep) xfs_dir2_data_entry_tag_p(dep) -static inline xfs_dir2_data_off_t * +static inline __be16 * xfs_dir2_data_entry_tag_p(xfs_dir2_data_entry_t *dep) { - return (xfs_dir2_data_off_t *) \ - ((char *)(dep) + XFS_DIR2_DATA_ENTSIZE((dep)->namelen) - \ - (uint)sizeof(xfs_dir2_data_off_t)); + return (__be16 *)((char *)dep + + xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16)); } /* * Pointer to a freespace's tag word. */ -#define XFS_DIR2_DATA_UNUSED_TAG_P(dup) \ - xfs_dir2_data_unused_tag_p(dup) -static inline xfs_dir2_data_off_t * +static inline __be16 * xfs_dir2_data_unused_tag_p(xfs_dir2_data_unused_t *dup) { - return (xfs_dir2_data_off_t *) \ - ((char *)(dup) + INT_GET((dup)->length, ARCH_CONVERT) \ - - (uint)sizeof(xfs_dir2_data_off_t)); + return (__be16 *)((char *)dup + + be16_to_cpu(dup->length) - sizeof(__be16)); } /* @@ -168,7 +162,7 @@ extern xfs_dir2_data_free_t *xfs_dir2_data_freefind(xfs_dir2_data_t *d, extern xfs_dir2_data_free_t *xfs_dir2_data_freeinsert(xfs_dir2_data_t *d, xfs_dir2_data_unused_t *dup, int *loghead); extern void xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d, - int *loghead, char *aendp); + int *loghead); extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno, struct xfs_dabuf **bpp); extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp, diff --git a/include/xfs_dir2_leaf.h b/include/xfs_dir2_leaf.h index 1393993d6..6c9539f06 100644 --- a/include/xfs_dir2_leaf.h +++ b/include/xfs_dir2_leaf.h @@ -32,7 +32,7 @@ struct xfs_trans; #define XFS_DIR2_LEAF_SPACE 1 #define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE) #define XFS_DIR2_LEAF_FIRSTDB(mp) \ - XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_LEAF_OFFSET) + xfs_dir2_byte_to_db(mp, XFS_DIR2_LEAF_OFFSET) /* * Offset in data space of a data entry. @@ -46,23 +46,23 @@ typedef __uint32_t xfs_dir2_dataptr_t; */ typedef struct xfs_dir2_leaf_hdr { xfs_da_blkinfo_t info; /* header for da routines */ - __uint16_t count; /* count of entries */ - __uint16_t stale; /* count of stale entries */ + __be16 count; /* count of entries */ + __be16 stale; /* count of stale entries */ } xfs_dir2_leaf_hdr_t; /* * Leaf block entry. */ typedef struct xfs_dir2_leaf_entry { - xfs_dahash_t hashval; /* hash value of name */ - xfs_dir2_dataptr_t address; /* address of data entry */ + __be32 hashval; /* hash value of name */ + __be32 address; /* address of data entry */ } xfs_dir2_leaf_entry_t; /* * Leaf block tail. */ typedef struct xfs_dir2_leaf_tail { - __uint32_t bestcount; + __be32 bestcount; } xfs_dir2_leaf_tail_t; /* @@ -82,7 +82,6 @@ typedef struct xfs_dir2_leaf { * DB blocks here are logical directory block numbers, not filesystem blocks. */ -#define XFS_DIR2_MAX_LEAF_ENTS(mp) xfs_dir2_max_leaf_ents(mp) static inline int xfs_dir2_max_leaf_ents(struct xfs_mount *mp) { return (int)(((mp)->m_dirblksize - (uint)sizeof(xfs_dir2_leaf_hdr_t)) / @@ -92,7 +91,6 @@ static inline int xfs_dir2_max_leaf_ents(struct xfs_mount *mp) /* * Get address of the bestcount field in the single-leaf block. */ -#define XFS_DIR2_LEAF_TAIL_P(mp,lp) xfs_dir2_leaf_tail_p(mp, lp) static inline xfs_dir2_leaf_tail_t * xfs_dir2_leaf_tail_p(struct xfs_mount *mp, xfs_dir2_leaf_t *lp) { @@ -104,18 +102,15 @@ xfs_dir2_leaf_tail_p(struct xfs_mount *mp, xfs_dir2_leaf_t *lp) /* * Get address of the bests array in the single-leaf block. */ -#define XFS_DIR2_LEAF_BESTS_P(ltp) xfs_dir2_leaf_bests_p(ltp) -static inline xfs_dir2_data_off_t * +static inline __be16 * xfs_dir2_leaf_bests_p(xfs_dir2_leaf_tail_t *ltp) { - return (xfs_dir2_data_off_t *) - (ltp) - INT_GET((ltp)->bestcount, ARCH_CONVERT); + return (__be16 *)ltp - be32_to_cpu(ltp->bestcount); } /* * Convert dataptr to byte in file space */ -#define XFS_DIR2_DATAPTR_TO_BYTE(mp,dp) xfs_dir2_dataptr_to_byte(mp, dp) static inline xfs_dir2_off_t xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) { @@ -125,7 +120,6 @@ xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) /* * Convert byte in file space to dataptr. It had better be aligned. */ -#define XFS_DIR2_BYTE_TO_DATAPTR(mp,by) xfs_dir2_byte_to_dataptr(mp,by) static inline xfs_dir2_dataptr_t xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by) { @@ -135,7 +129,6 @@ xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by) /* * Convert byte in space to (DB) block */ -#define XFS_DIR2_BYTE_TO_DB(mp,by) xfs_dir2_byte_to_db(mp, by) static inline xfs_dir2_db_t xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by) { @@ -146,17 +139,15 @@ xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by) /* * Convert dataptr to a block number */ -#define XFS_DIR2_DATAPTR_TO_DB(mp,dp) xfs_dir2_dataptr_to_db(mp, dp) static inline xfs_dir2_db_t xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) { - return XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_DATAPTR_TO_BYTE(mp, dp)); + return xfs_dir2_byte_to_db(mp, xfs_dir2_dataptr_to_byte(mp, dp)); } /* * Convert byte in space to offset in a block */ -#define XFS_DIR2_BYTE_TO_OFF(mp,by) xfs_dir2_byte_to_off(mp, by) static inline xfs_dir2_data_aoff_t xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by) { @@ -167,18 +158,15 @@ xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by) /* * Convert dataptr to a byte offset in a block */ -#define XFS_DIR2_DATAPTR_TO_OFF(mp,dp) xfs_dir2_dataptr_to_off(mp, dp) static inline xfs_dir2_data_aoff_t xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) { - return XFS_DIR2_BYTE_TO_OFF(mp, XFS_DIR2_DATAPTR_TO_BYTE(mp, dp)); + return xfs_dir2_byte_to_off(mp, xfs_dir2_dataptr_to_byte(mp, dp)); } /* * Convert block and offset to byte in space */ -#define XFS_DIR2_DB_OFF_TO_BYTE(mp,db,o) \ - xfs_dir2_db_off_to_byte(mp, db, o) static inline xfs_dir2_off_t xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db, xfs_dir2_data_aoff_t o) @@ -190,7 +178,6 @@ xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db, /* * Convert block (DB) to block (dablk) */ -#define XFS_DIR2_DB_TO_DA(mp,db) xfs_dir2_db_to_da(mp, db) static inline xfs_dablk_t xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db) { @@ -200,29 +187,25 @@ xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db) /* * Convert byte in space to (DA) block */ -#define XFS_DIR2_BYTE_TO_DA(mp,by) xfs_dir2_byte_to_da(mp, by) static inline xfs_dablk_t xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by) { - return XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_BYTE_TO_DB(mp, by)); + return xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, by)); } /* * Convert block and offset to dataptr */ -#define XFS_DIR2_DB_OFF_TO_DATAPTR(mp,db,o) \ - xfs_dir2_db_off_to_dataptr(mp, db, o) static inline xfs_dir2_dataptr_t xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db, xfs_dir2_data_aoff_t o) { - return XFS_DIR2_BYTE_TO_DATAPTR(mp, XFS_DIR2_DB_OFF_TO_BYTE(mp, db, o)); + return xfs_dir2_byte_to_dataptr(mp, xfs_dir2_db_off_to_byte(mp, db, o)); } /* * Convert block (dablk) to block (DB) */ -#define XFS_DIR2_DA_TO_DB(mp,da) xfs_dir2_da_to_db(mp, da) static inline xfs_dir2_db_t xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da) { @@ -232,11 +215,10 @@ xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da) /* * Convert block (dablk) to byte offset in space */ -#define XFS_DIR2_DA_TO_BYTE(mp,da) xfs_dir2_da_to_byte(mp, da) static inline xfs_dir2_off_t xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da) { - return XFS_DIR2_DB_OFF_TO_BYTE(mp, XFS_DIR2_DA_TO_DB(mp, da), 0); + return xfs_dir2_db_off_to_byte(mp, xfs_dir2_da_to_db(mp, da), 0); } /* @@ -250,9 +232,9 @@ extern void xfs_dir2_leaf_compact(struct xfs_da_args *args, extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp, int *lowstalep, int *highstalep, int *lowlogp, int *highlogp); -extern int xfs_dir2_leaf_getdents(struct xfs_trans *tp, struct xfs_inode *dp, - struct uio *uio, int *eofp, - struct xfs_dirent *dbp, xfs_dir2_put_t put); +extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent, + size_t bufsize, xfs_off_t *offset, + filldir_t filldir); extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno, struct xfs_dabuf **bpp, int magic); extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp, diff --git a/include/xfs_dir2_node.h b/include/xfs_dir2_node.h index 0ab8fbd59..dde72db3d 100644 --- a/include/xfs_dir2_node.h +++ b/include/xfs_dir2_node.h @@ -36,20 +36,20 @@ struct xfs_trans; #define XFS_DIR2_FREE_SPACE 2 #define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE) #define XFS_DIR2_FREE_FIRSTDB(mp) \ - XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_FREE_OFFSET) + xfs_dir2_byte_to_db(mp, XFS_DIR2_FREE_OFFSET) #define XFS_DIR2_FREE_MAGIC 0x58443246 /* XD2F */ typedef struct xfs_dir2_free_hdr { - __uint32_t magic; /* XFS_DIR2_FREE_MAGIC */ - __int32_t firstdb; /* db of first entry */ - __int32_t nvalid; /* count of valid entries */ - __int32_t nused; /* count of used entries */ + __be32 magic; /* XFS_DIR2_FREE_MAGIC */ + __be32 firstdb; /* db of first entry */ + __be32 nvalid; /* count of valid entries */ + __be32 nused; /* count of used entries */ } xfs_dir2_free_hdr_t; typedef struct xfs_dir2_free { xfs_dir2_free_hdr_t hdr; /* block header */ - xfs_dir2_data_off_t bests[1]; /* best free counts */ + __be16 bests[1]; /* best free counts */ /* unused entries are -1 */ } xfs_dir2_free_t; @@ -60,7 +60,6 @@ typedef struct xfs_dir2_free { /* * Convert data space db to the corresponding free db. */ -#define XFS_DIR2_DB_TO_FDB(mp,db) xfs_dir2_db_to_fdb(mp, db) static inline xfs_dir2_db_t xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db) { @@ -70,7 +69,6 @@ xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db) /* * Convert data space db to the corresponding index in a free db. */ -#define XFS_DIR2_DB_TO_FDINDEX(mp,db) xfs_dir2_db_to_fdindex(mp, db) static inline int xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db) { diff --git a/include/xfs_dir2_sf.h b/include/xfs_dir2_sf.h index 5c4740f5e..deecc9d23 100644 --- a/include/xfs_dir2_sf.h +++ b/include/xfs_dir2_sf.h @@ -83,14 +83,13 @@ typedef struct xfs_dir2_sf_entry { xfs_dir2_sf_off_t offset; /* saved offset */ __uint8_t name[1]; /* name, variable size */ xfs_dir2_inou_t inumber; /* inode number, var. offset */ -} __arch_pack xfs_dir2_sf_entry_t; +} __arch_pack xfs_dir2_sf_entry_t; typedef struct xfs_dir2_sf { xfs_dir2_sf_hdr_t hdr; /* shortform header */ xfs_dir2_sf_entry_t list[1]; /* shortform entries */ } xfs_dir2_sf_t; -#define XFS_DIR2_SF_HDR_SIZE(i8count) xfs_dir2_sf_hdr_size(i8count) static inline int xfs_dir2_sf_hdr_size(int i8count) { return ((uint)sizeof(xfs_dir2_sf_hdr_t) - \ @@ -98,14 +97,11 @@ static inline int xfs_dir2_sf_hdr_size(int i8count) ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); } -#define XFS_DIR2_SF_INUMBERP(sfep) xfs_dir2_sf_inumberp(sfep) static inline xfs_dir2_inou_t *xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep) { return (xfs_dir2_inou_t *)&(sfep)->name[(sfep)->namelen]; } -#define XFS_DIR2_SF_GET_INUMBER(sfp, from) \ - xfs_dir2_sf_get_inumber(sfp, from) static inline xfs_intino_t xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from) { @@ -114,8 +110,6 @@ xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from) (xfs_intino_t)XFS_GET_DIR_INO8((from)->i8)); } -#define XFS_DIR2_SF_PUT_INUMBER(sfp,from,to) \ - xfs_dir2_sf_put_inumber(sfp,from,to) static inline void xfs_dir2_sf_put_inumber(xfs_dir2_sf_t *sfp, xfs_ino_t *from, xfs_dir2_inou_t *to) { @@ -125,24 +119,18 @@ static inline void xfs_dir2_sf_put_inumber(xfs_dir2_sf_t *sfp, xfs_ino_t *from, XFS_PUT_DIR_INO8(*(from), (to)->i8); } -#define XFS_DIR2_SF_GET_OFFSET(sfep) \ - xfs_dir2_sf_get_offset(sfep) static inline xfs_dir2_data_aoff_t xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep) { return INT_GET_UNALIGNED_16_BE(&(sfep)->offset.i); } -#define XFS_DIR2_SF_PUT_OFFSET(sfep,off) \ - xfs_dir2_sf_put_offset(sfep,off) static inline void xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off) { INT_SET_UNALIGNED_16_BE(&(sfep)->offset.i, off); } -#define XFS_DIR2_SF_ENTSIZE_BYNAME(sfp,len) \ - xfs_dir2_sf_entsize_byname(sfp,len) static inline int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len) { return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (len) - \ @@ -150,8 +138,6 @@ static inline int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len) ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); } -#define XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep) \ - xfs_dir2_sf_entsize_byentry(sfp,sfep) static inline int xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) { @@ -160,19 +146,17 @@ xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); } -#define XFS_DIR2_SF_FIRSTENTRY(sfp) xfs_dir2_sf_firstentry(sfp) static inline xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_t *sfp) { return ((xfs_dir2_sf_entry_t *) \ - ((char *)(sfp) + XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count))); + ((char *)(sfp) + xfs_dir2_sf_hdr_size(sfp->hdr.i8count))); } -#define XFS_DIR2_SF_NEXTENTRY(sfp,sfep) xfs_dir2_sf_nextentry(sfp,sfep) static inline xfs_dir2_sf_entry_t * xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) { return ((xfs_dir2_sf_entry_t *) \ - ((char *)(sfep) + XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep))); + ((char *)(sfep) + xfs_dir2_sf_entsize_byentry(sfp,sfep))); } /* @@ -185,9 +169,8 @@ extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp, int size, xfs_dir2_sf_hdr_t *sfhp); extern int xfs_dir2_sf_addname(struct xfs_da_args *args); extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino); -extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, struct uio *uio, - int *eofp, struct xfs_dirent *dbp, - xfs_dir2_put_t put); +extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent, + xfs_off_t *offset, filldir_t filldir); extern int xfs_dir2_sf_lookup(struct xfs_da_args *args); extern int xfs_dir2_sf_removename(struct xfs_da_args *args); extern int xfs_dir2_sf_replace(struct xfs_da_args *args); diff --git a/include/xfs_dir_leaf.h b/include/xfs_dir_leaf.h index eb8cd9a46..948b0cd21 100644 --- a/include/xfs_dir_leaf.h +++ b/include/xfs_dir_leaf.h @@ -19,7 +19,8 @@ #define __XFS_DIR_LEAF_H__ /* - * Directory layout, internal structure, access macros, etc. + * Version 1 Directory layout, internal structure, access macros, etc. + * to allow various xfsprogs tools to read these structures. * * Large directories are structured around Btrees where all the data * elements are in the leaf nodes. Filenames are hashed into an int, @@ -28,17 +29,6 @@ * internal links in the Btree are logical block offsets into the file. */ -struct uio; -struct xfs_bmap_free; -struct xfs_dabuf; -struct xfs_da_args; -struct xfs_da_state; -struct xfs_da_state_blk; -struct xfs_dir_put_args; -struct xfs_inode; -struct xfs_mount; -struct xfs_trans; - /*======================================================================== * Directory Structure when equal to XFS_LBSIZE(mp) bytes. *========================================================================*/ @@ -65,33 +55,37 @@ struct xfs_trans; * Note that the count being a __uint16_t limits us to something like a * blocksize of 1.3MB in the face of worst case (short) filenames. */ + +#define XFS_DIR_LEAF_MAGIC 0xfeeb + #define XFS_DIR_LEAF_MAPSIZE 3 /* how many freespace slots */ + typedef struct xfs_dir_leaf_map { /* RLE map of free bytes */ - __uint16_t base; /* base of free region */ - __uint16_t size; /* run length of free region */ + __be16 base; /* base of free region */ + __be16 size; /* run length of free region */ } xfs_dir_leaf_map_t; typedef struct xfs_dir_leaf_hdr { /* constant-structure header block */ xfs_da_blkinfo_t info; /* block type, links, etc. */ - __uint16_t count; /* count of active leaf_entry's */ - __uint16_t namebytes; /* num bytes of name strings stored */ - __uint16_t firstused; /* first used byte in name area */ - __uint8_t holes; /* != 0 if blk needs compaction */ - __uint8_t pad1; + __be16 count; /* count of active leaf_entry's */ + __be16 namebytes; /* num bytes of name strings stored */ + __be16 firstused; /* first used byte in name area */ + __u8 holes; /* != 0 if blk needs compaction */ + __u8 pad1; xfs_dir_leaf_map_t freemap[XFS_DIR_LEAF_MAPSIZE]; } xfs_dir_leaf_hdr_t; typedef struct xfs_dir_leaf_entry { /* sorted on key, not name */ - xfs_dahash_t hashval; /* hash value of name */ - __uint16_t nameidx; /* index into buffer of name */ - __uint8_t namelen; /* length of name string */ - __uint8_t pad2; + __be32 hashval; /* hash value of name */ + __be16 nameidx; /* index into buffer of name */ + __u8 namelen; /* length of name string */ + __u8 pad2; } xfs_dir_leaf_entry_t; typedef struct xfs_dir_leaf_name { xfs_dir_ino_t inumber; /* inode number for this key */ - __uint8_t name[1]; /* name string itself */ + __u8 name[1]; /* name string itself */ } xfs_dir_leaf_name_t; typedef struct xfs_dir_leafblock { @@ -100,132 +94,20 @@ typedef struct xfs_dir_leafblock { xfs_dir_leaf_name_t namelist[1]; /* grows from bottom of buf */ } xfs_dir_leafblock_t; -/* - * Length of name for which a 512-byte block filesystem - * can get a double split. - */ -#define XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN \ - (512 - (uint)sizeof(xfs_dir_leaf_hdr_t) - \ - (uint)sizeof(xfs_dir_leaf_entry_t) * 2 - \ - (uint)sizeof(xfs_dir_leaf_name_t) * 2 - (MAXNAMELEN - 2) + 1 + 1) - -typedef int (*xfs_dir_put_t)(struct xfs_dir_put_args *pa); - -typedef union { - xfs_off_t o; /* offset (cookie) */ - /* - * Watch the order here (endian-ness dependent). - */ - struct { -#ifndef XFS_NATIVE_HOST - xfs_dahash_t h; /* hash value */ - __uint32_t be; /* block and entry */ -#else - __uint32_t be; /* block and entry */ - xfs_dahash_t h; /* hash value */ -#endif /* XFS_NATIVE_HOST */ - } s; -} xfs_dircook_t; - -#define XFS_PUT_COOKIE(c,mp,bno,entry,hash) \ - ((c).s.be = XFS_DA_MAKE_BNOENTRY(mp, bno, entry), (c).s.h = (hash)) - -typedef struct xfs_dir_put_args { - xfs_dircook_t cook; /* cookie of (next) entry */ - xfs_intino_t ino; /* inode number */ - struct xfs_dirent *dbp; /* buffer pointer */ - char *name; /* directory entry name */ - int namelen; /* length of name */ - int done; /* output: set if value was stored */ - xfs_dir_put_t put; /* put function ptr (i/o) */ - struct uio *uio; /* uio control structure */ -} xfs_dir_put_args_t; - -#define XFS_DIR_LEAF_ENTSIZE_BYNAME(len) \ - xfs_dir_leaf_entsize_byname(len) static inline int xfs_dir_leaf_entsize_byname(int len) { return (uint)sizeof(xfs_dir_leaf_name_t)-1 + len; } -#define XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry) \ - xfs_dir_leaf_entsize_byentry(entry) static inline int xfs_dir_leaf_entsize_byentry(xfs_dir_leaf_entry_t *entry) { return (uint)sizeof(xfs_dir_leaf_name_t)-1 + (entry)->namelen; } -#define XFS_DIR_LEAF_NAMESTRUCT(leafp,offset) \ - xfs_dir_leaf_namestruct(leafp,offset) static inline xfs_dir_leaf_name_t * xfs_dir_leaf_namestruct(xfs_dir_leafblock_t *leafp, int offset) { return (xfs_dir_leaf_name_t *)&((char *)(leafp))[offset]; } -/*======================================================================== - * Function prototypes for the kernel. - *========================================================================*/ - -/* - * Internal routines when dirsize < XFS_LITINO(mp). - */ -int xfs_dir_shortform_create(struct xfs_da_args *args, xfs_ino_t parent); -int xfs_dir_shortform_addname(struct xfs_da_args *args); -int xfs_dir_shortform_lookup(struct xfs_da_args *args); -int xfs_dir_shortform_to_leaf(struct xfs_da_args *args); -int xfs_dir_shortform_removename(struct xfs_da_args *args); -int xfs_dir_shortform_getdents(struct xfs_inode *dp, struct uio *uio, int *eofp, - struct xfs_dirent *dbp, xfs_dir_put_t put); -int xfs_dir_shortform_replace(struct xfs_da_args *args); - -/* - * Internal routines when dirsize == XFS_LBSIZE(mp). - */ -int xfs_dir_leaf_to_node(struct xfs_da_args *args); -int xfs_dir_leaf_to_shortform(struct xfs_da_args *args); - -/* - * Routines used for growing the Btree. - */ -int xfs_dir_leaf_split(struct xfs_da_state *state, - struct xfs_da_state_blk *oldblk, - struct xfs_da_state_blk *newblk); -int xfs_dir_leaf_add(struct xfs_dabuf *leaf_buffer, - struct xfs_da_args *args, int insertion_index); -int xfs_dir_leaf_addname(struct xfs_da_args *args); -int xfs_dir_leaf_lookup_int(struct xfs_dabuf *leaf_buffer, - struct xfs_da_args *args, - int *index_found_at); -int xfs_dir_leaf_remove(struct xfs_trans *trans, - struct xfs_dabuf *leaf_buffer, - int index_to_remove); -int xfs_dir_leaf_getdents_int(struct xfs_dabuf *bp, struct xfs_inode *dp, - xfs_dablk_t bno, struct uio *uio, - int *eobp, struct xfs_dirent *dbp, - xfs_dir_put_t put, xfs_daddr_t nextda); - -/* - * Routines used for shrinking the Btree. - */ -int xfs_dir_leaf_toosmall(struct xfs_da_state *state, int *retval); -void xfs_dir_leaf_unbalance(struct xfs_da_state *state, - struct xfs_da_state_blk *drop_blk, - struct xfs_da_state_blk *save_blk); - -/* - * Utility routines. - */ -uint xfs_dir_leaf_lasthash(struct xfs_dabuf *bp, int *count); -int xfs_dir_leaf_order(struct xfs_dabuf *leaf1_bp, - struct xfs_dabuf *leaf2_bp); -int xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa); -int xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa); -int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); - -/* - * Global data. - */ -extern xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot; - #endif /* __XFS_DIR_LEAF_H__ */ diff --git a/include/xfs_dir_sf.h b/include/xfs_dir_sf.h index 5b20b4d3f..792f14d85 100644 --- a/include/xfs_dir_sf.h +++ b/include/xfs_dir_sf.h @@ -37,13 +37,13 @@ typedef struct { __uint8_t i[sizeof(xfs_ino_t)]; } xfs_dir_ino_t; */ typedef struct xfs_dir_sf_hdr { /* constant-structure header block */ xfs_dir_ino_t parent; /* parent dir inode number */ - __uint8_t count; /* count of active entries */ + __u8 count; /* count of active entries */ } xfs_dir_sf_hdr_t; typedef struct xfs_dir_sf_entry { xfs_dir_ino_t inumber; /* referenced inode number */ - __uint8_t namelen; /* actual length of name (no NULL) */ - __uint8_t name[1]; /* name */ + __u8 namelen; /* actual length of name (no NULL) */ + __u8 name[1]; /* name */ } xfs_dir_sf_entry_t; typedef struct xfs_dir_shortform { @@ -56,100 +56,44 @@ typedef struct xfs_dir_shortform { * hash-order. Else seekdir won't work. */ typedef struct xfs_dir_sf_sort { - __uint8_t entno; /* .=0, ..=1, else entry# + 2 */ - __uint8_t seqno; /* sequence # with same hash value */ - __uint8_t namelen; /* length of name value (no null) */ - xfs_dahash_t hash; /* this entry's hash value */ + __u8 entno; /* .=0, ..=1, else entry# + 2 */ + __u8 seqno; /* sequence # with same hash value */ + __u8 namelen; /* length of name value (no null) */ + __be32 hash; /* this entry's hash value */ xfs_intino_t ino; /* this entry's inode number */ - char *name; /* name value, pointer into buffer */ + __u8 *name; /* name value, pointer into buffer */ } xfs_dir_sf_sort_t; -#define XFS_DIR_SF_GET_DIRINO(from,to) xfs_dir_sf_get_dirino(from, to) static inline void xfs_dir_sf_get_dirino(xfs_dir_ino_t *from, xfs_ino_t *to) { - *(to) = XFS_GET_DIR_INO8(*from); + *to = XFS_GET_DIR_INO8(*from); } -#define XFS_DIR_SF_PUT_DIRINO(from,to) xfs_dir_sf_put_dirino(from, to) static inline void xfs_dir_sf_put_dirino(xfs_ino_t *from, xfs_dir_ino_t *to) { - XFS_PUT_DIR_INO8(*(from), *(to)); + XFS_PUT_DIR_INO8(*from, *to); } -#define XFS_DIR_SF_ENTSIZE_BYNAME(len) xfs_dir_sf_entsize_byname(len) static inline int xfs_dir_sf_entsize_byname(int len) { - return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (len); + return sizeof(xfs_dir_sf_entry_t) - 1 + len; } -#define XFS_DIR_SF_ENTSIZE_BYENTRY(sfep) xfs_dir_sf_entsize_byentry(sfep) static inline int xfs_dir_sf_entsize_byentry(xfs_dir_sf_entry_t *sfep) { - return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (sfep)->namelen; + return sizeof(xfs_dir_sf_entry_t) - 1 + sfep->namelen; } -#define XFS_DIR_SF_NEXTENTRY(sfep) xfs_dir_sf_nextentry(sfep) static inline xfs_dir_sf_entry_t *xfs_dir_sf_nextentry(xfs_dir_sf_entry_t *sfep) { - return (xfs_dir_sf_entry_t *) \ - ((char *)(sfep) + XFS_DIR_SF_ENTSIZE_BYENTRY(sfep)); + return (xfs_dir_sf_entry_t *)((char *)sfep + + xfs_dir_sf_entsize_byentry(sfep)); } -#define XFS_DIR_SF_ALLFIT(count,totallen) \ - xfs_dir_sf_allfit(count,totallen) static inline int xfs_dir_sf_allfit(int count, int totallen) { - return ((uint)sizeof(xfs_dir_sf_hdr_t) + \ - ((uint)sizeof(xfs_dir_sf_entry_t)-1)*(count) + (totallen)); + return sizeof(xfs_dir_sf_hdr_t) + + (sizeof(xfs_dir_sf_entry_t) - 1) * count + totallen; } -#if defined(XFS_DIR_TRACE) - -/* - * Kernel tracing support for directories. - */ -struct uio; -struct xfs_inode; -struct xfs_da_intnode; -struct xfs_dinode; -struct xfs_dir_leafblock; -struct xfs_dir_leaf_entry; - -#define XFS_DIR_TRACE_SIZE 4096 /* size of global trace buffer */ -extern ktrace_t *xfs_dir_trace_buf; - -/* - * Trace record types. - */ -#define XFS_DIR_KTRACE_G_DU 1 /* dp, uio */ -#define XFS_DIR_KTRACE_G_DUB 2 /* dp, uio, bno */ -#define XFS_DIR_KTRACE_G_DUN 3 /* dp, uio, node */ -#define XFS_DIR_KTRACE_G_DUL 4 /* dp, uio, leaf */ -#define XFS_DIR_KTRACE_G_DUE 5 /* dp, uio, leaf entry */ -#define XFS_DIR_KTRACE_G_DUC 6 /* dp, uio, cookie */ - -void xfs_dir_trace_g_du(char *where, struct xfs_inode *dp, struct uio *uio); -void xfs_dir_trace_g_dub(char *where, struct xfs_inode *dp, struct uio *uio, - xfs_dablk_t bno); -void xfs_dir_trace_g_dun(char *where, struct xfs_inode *dp, struct uio *uio, - struct xfs_da_intnode *node); -void xfs_dir_trace_g_dul(char *where, struct xfs_inode *dp, struct uio *uio, - struct xfs_dir_leafblock *leaf); -void xfs_dir_trace_g_due(char *where, struct xfs_inode *dp, struct uio *uio, - struct xfs_dir_leaf_entry *entry); -void xfs_dir_trace_g_duc(char *where, struct xfs_inode *dp, struct uio *uio, - xfs_off_t cookie); -void xfs_dir_trace_enter(int type, char *where, - void *a0, void *a1, void *a2, void *a3, - void *a4, void *a5, void *a6, void *a7, - void *a8, void *a9, void *a10, void *a11); -#else -#define xfs_dir_trace_g_du(w,d,u) -#define xfs_dir_trace_g_dub(w,d,u,b) -#define xfs_dir_trace_g_dun(w,d,u,n) -#define xfs_dir_trace_g_dul(w,d,u,l) -#define xfs_dir_trace_g_due(w,d,u,e) -#define xfs_dir_trace_g_duc(w,d,u,c) -#endif /* DEBUG */ - #endif /* __XFS_DIR_SF_H__ */ diff --git a/include/xfs_fs.h b/include/xfs_fs.h index 7d22bbd72..01c0cc88d 100644 --- a/include/xfs_fs.h +++ b/include/xfs_fs.h @@ -22,8 +22,6 @@ * SGI's XFS filesystem's major stuff (constants, structures) */ -#define XFS_NAME "xfs" - /* * Direct I/O attribute record used with XFS_IOC_DIOINFO * d_miniosz is the min xfer size, xfer size multiple and file seek offset @@ -67,16 +65,16 @@ struct fsxattr { #define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */ #define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */ #define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */ -#define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */ +#define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */ #define XFS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */ #define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ /* * Structure for XFS_IOC_GETBMAP. * On input, fill in bmv_offset and bmv_length of the first structure - * to indicate the area of interest in the file, and bmv_entry with the - * number of array elements given. The first structure is updated on - * return to give the offset and length for the next call. + * to indicate the area of interest in the file, and bmv_entries with + * the number of array elements given back. The first structure is + * updated on return to give the offset and length for the next call. */ #ifndef HAVE_GETBMAP struct getbmap { @@ -374,6 +372,9 @@ typedef struct xfs_fsop_attrlist_handlereq { typedef struct xfs_attr_multiop { __u32 am_opcode; +#define ATTR_OP_GET 1 /* return the indicated attr's value */ +#define ATTR_OP_SET 2 /* set/create the indicated attr/value pair */ +#define ATTR_OP_REMOVE 3 /* remove the indicated attr */ __s32 am_error; void __user *am_attrname; void __user *am_attrvalue; @@ -392,30 +393,13 @@ typedef struct xfs_fsop_attrmulti_handlereq { */ typedef struct { __u32 val[2]; } xfs_fsid_t; /* file system id type */ - -#ifndef HAVE_FID -#define MAXFIDSZ 46 - -typedef struct fid { - __u16 fid_len; /* length of data in bytes */ - unsigned char fid_data[MAXFIDSZ]; /* data (fid_len worth) */ -} fid_t; -#endif - typedef struct xfs_fid { - __u16 xfs_fid_len; /* length of remainder */ - __u16 xfs_fid_pad; - __u32 xfs_fid_gen; /* generation number */ - __u64 xfs_fid_ino; /* 64 bits inode number */ + __u16 fid_len; /* length of remainder */ + __u16 fid_pad; + __u32 fid_gen; /* generation number */ + __u64 fid_ino; /* 64 bits inode number */ } xfs_fid_t; -typedef struct xfs_fid2 { - __u16 fid_len; /* length of remainder */ - __u16 fid_pad; /* padding, must be zero */ - __u32 fid_gen; /* generation number */ - __u64 fid_ino; /* inode number */ -} xfs_fid2_t; - typedef struct xfs_handle { union { __s64 align; /* force alignment of ha_fid */ @@ -425,13 +409,9 @@ typedef struct xfs_handle { } xfs_handle_t; #define ha_fsid ha_u._ha_fsid -#define XFS_HSIZE(handle) (((char *) &(handle).ha_fid.xfs_fid_pad \ +#define XFS_HSIZE(handle) (((char *) &(handle).ha_fid.fid_pad \ - (char *) &(handle)) \ - + (handle).ha_fid.xfs_fid_len) - -#define XFS_HANDLE_CMP(h1, h2) memcmp(h1, h2, sizeof(xfs_handle_t)) - -#define FSHSIZE sizeof(fsid_t) + + (handle).ha_fid.fid_len) /* * Flags for going down operation @@ -443,9 +423,13 @@ typedef struct xfs_handle { /* * ioctl commands that are used by Linux filesystems */ -#define XFS_IOC_GETXFLAGS _IOR('f', 1, long) -#define XFS_IOC_SETXFLAGS _IOW('f', 2, long) -#define XFS_IOC_GETVERSION _IOR('v', 1, long) +#define XFS_IOC_GETXFLAGS FS_IOC_GETFLAGS +#define XFS_IOC_SETXFLAGS FS_IOC_SETFLAGS +#define XFS_IOC_GETVERSION FS_IOC_GETVERSION +/* 32-bit compat counterparts */ +#define XFS_IOC32_GETXFLAGS FS_IOC32_GETFLAGS +#define XFS_IOC32_SETXFLAGS FS_IOC32_SETFLAGS +#define XFS_IOC32_GETVERSION FS_IOC32_GETVERSION /* * ioctl commands that replace IRIX fcntl()'s diff --git a/include/xfs_ialloc.h b/include/xfs_ialloc.h index 97f404093..97fcec963 100644 --- a/include/xfs_ialloc.h +++ b/include/xfs_ialloc.h @@ -30,14 +30,9 @@ struct xfs_trans; #define XFS_IALLOC_BLOCKS(mp) (mp)->m_ialloc_blks /* - * For small block file systems, move inodes in clusters of this size. - * When we don't have a lot of memory, however, we go a bit smaller - * to reduce the number of AGI and ialloc btree blocks we need to keep - * around for xfs_dilocate(). We choose which one to use in - * xfs_mount_int(). + * Move inodes in clusters of this size. */ #define XFS_INODE_BIG_CLUSTER_SIZE 8192 -#define XFS_INODE_SMALL_CLUSTER_SIZE 4096 #define XFS_INODE_CLUSTER_SIZE(mp) (mp)->m_inode_cluster_size /* @@ -61,7 +56,6 @@ static inline int xfs_ialloc_find_free(xfs_inofree_t *fp) } -#ifdef __KERNEL__ /* * Allocate an inode on disk. * Mode is used to tell whether the new inode will need space, and whether @@ -159,6 +153,4 @@ xfs_ialloc_pagi_init( struct xfs_trans *tp, /* transaction pointer */ xfs_agnumber_t agno); /* allocation group number */ -#endif /* __KERNEL__ */ - #endif /* __XFS_IALLOC_H__ */ diff --git a/include/xfs_ialloc_btree.h b/include/xfs_ialloc_btree.h index ae3904cb1..8efc4a5b8 100644 --- a/include/xfs_ialloc_btree.h +++ b/include/xfs_ialloc_btree.h @@ -47,19 +47,24 @@ static inline xfs_inofree_t xfs_inobt_maskn(int i, int n) /* * Data record structure */ -typedef struct xfs_inobt_rec -{ +typedef struct xfs_inobt_rec { + __be32 ir_startino; /* starting inode number */ + __be32 ir_freecount; /* count of free inodes (set bits) */ + __be64 ir_free; /* free inode mask */ +} xfs_inobt_rec_t; + +typedef struct xfs_inobt_rec_incore { xfs_agino_t ir_startino; /* starting inode number */ __int32_t ir_freecount; /* count of free inodes (set bits) */ xfs_inofree_t ir_free; /* free inode mask */ -} xfs_inobt_rec_t; +} xfs_inobt_rec_incore_t; + /* * Key structure */ -typedef struct xfs_inobt_key -{ - xfs_agino_t ir_startino; /* starting inode number */ +typedef struct xfs_inobt_key { + __be32 ir_startino; /* starting inode number */ } xfs_inobt_key_t; /* btree pointer type */ @@ -76,15 +81,12 @@ typedef struct xfs_btree_sblock xfs_inobt_block_t; #define XFS_INOBT_MASK(i) ((xfs_inofree_t)1 << (i)) #define XFS_INOBT_IS_FREE(rp,i) \ (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0) -#define XFS_INOBT_IS_FREE_DISK(rp,i) \ - ((INT_GET((rp)->ir_free,ARCH_CONVERT) & XFS_INOBT_MASK(i)) != 0) #define XFS_INOBT_SET_FREE(rp,i) ((rp)->ir_free |= XFS_INOBT_MASK(i)) #define XFS_INOBT_CLR_FREE(rp,i) ((rp)->ir_free &= ~XFS_INOBT_MASK(i)) /* * Real block structures have a size equal to the disk block size. */ -#define XFS_INOBT_BLOCK_SIZE(lev,cur) (1 << (cur)->bc_blocklog) #define XFS_INOBT_BLOCK_MAXRECS(lev,cur) ((cur)->bc_mp->m_inobt_mxr[lev != 0]) #define XFS_INOBT_BLOCK_MINRECS(lev,cur) ((cur)->bc_mp->m_inobt_mnr[lev != 0]) #define XFS_INOBT_IS_LAST_REC(cur) \ @@ -105,14 +107,13 @@ typedef struct xfs_btree_sblock xfs_inobt_block_t; * Record, key, and pointer address macros for btree blocks. */ #define XFS_INOBT_REC_ADDR(bb,i,cur) \ - (XFS_BTREE_REC_ADDR(XFS_INOBT_BLOCK_SIZE(0,cur), xfs_inobt, bb, \ - i, XFS_INOBT_BLOCK_MAXRECS(0, cur))) + (XFS_BTREE_REC_ADDR(xfs_inobt, bb, i)) + #define XFS_INOBT_KEY_ADDR(bb,i,cur) \ - (XFS_BTREE_KEY_ADDR(XFS_INOBT_BLOCK_SIZE(1,cur), xfs_inobt, bb, \ - i, XFS_INOBT_BLOCK_MAXRECS(1, cur))) + (XFS_BTREE_KEY_ADDR(xfs_inobt, bb, i)) #define XFS_INOBT_PTR_ADDR(bb,i,cur) \ - (XFS_BTREE_PTR_ADDR(XFS_INOBT_BLOCK_SIZE(1,cur), xfs_inobt, bb, \ + (XFS_BTREE_PTR_ADDR(xfs_inobt, bb, \ i, XFS_INOBT_BLOCK_MAXRECS(1, cur))) /* diff --git a/include/xfs_imap.h b/include/xfs_imap.h index d36450003..f9ce62890 100644 --- a/include/xfs_imap.h +++ b/include/xfs_imap.h @@ -30,11 +30,9 @@ typedef struct xfs_imap { ushort im_boffset; /* inode offset in block in bytes */ } xfs_imap_t; -#ifdef __KERNEL__ struct xfs_mount; struct xfs_trans; int xfs_imap(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, xfs_imap_t *, uint); -#endif #endif /* __XFS_IMAP_H__ */ diff --git a/include/xfs_inode.h b/include/xfs_inode.h index 124d30e61..912fc8584 100644 --- a/include/xfs_inode.h +++ b/include/xfs_inode.h @@ -18,17 +18,48 @@ #ifndef __XFS_INODE_H__ #define __XFS_INODE_H__ +struct xfs_dinode; +struct xfs_dinode_core; +struct xfs_inode; + /* * Fork identifiers. */ #define XFS_DATA_FORK 0 #define XFS_ATTR_FORK 1 +/* + * The following xfs_ext_irec_t struct introduces a second (top) level + * to the in-core extent allocation scheme. These structs are allocated + * in a contiguous block, creating an indirection array where each entry + * (irec) contains a pointer to a buffer of in-core extent records which + * it manages. Each extent buffer is 4k in size, since 4k is the system + * page size on Linux i386 and systems with larger page sizes don't seem + * to gain much, if anything, by using their native page size as the + * extent buffer size. Also, using 4k extent buffers everywhere provides + * a consistent interface for CXFS across different platforms. + * + * There is currently no limit on the number of irec's (extent lists) + * allowed, so heavily fragmented files may require an indirection array + * which spans multiple system pages of memory. The number of extents + * which would require this amount of contiguous memory is very large + * and should not cause problems in the foreseeable future. However, + * if the memory needed for the contiguous array ever becomes a problem, + * it is possible that a third level of indirection may be required. + */ +typedef struct xfs_ext_irec { + xfs_bmbt_rec_host_t *er_extbuf; /* block of extent records */ + xfs_extnum_t er_extoff; /* extent offset in file */ + xfs_extnum_t er_extcount; /* number of extents in page/block */ +} xfs_ext_irec_t; + /* * File incore extent information, present for each of data & attr forks. */ -#define XFS_INLINE_EXTS 2 -#define XFS_INLINE_DATA 32 +#define XFS_IEXT_BUFSZ 4096 +#define XFS_LINEAR_EXTS (XFS_IEXT_BUFSZ / (uint)sizeof(xfs_bmbt_rec_t)) +#define XFS_INLINE_EXTS 2 +#define XFS_INLINE_DATA 32 typedef struct xfs_ifork { int if_bytes; /* bytes in if_u1 */ int if_real_bytes; /* bytes allocated in if_u1 */ @@ -38,11 +69,12 @@ typedef struct xfs_ifork { unsigned char if_ext_max; /* max # of extent records */ xfs_extnum_t if_lastex; /* last if_extents used */ union { - xfs_bmbt_rec_t *if_extents; /* linear map file exts */ + xfs_bmbt_rec_host_t *if_extents;/* linear map file exts */ + xfs_ext_irec_t *if_ext_irec; /* irec map file exts */ char *if_data; /* inline file data */ } if_u1; union { - xfs_bmbt_rec_t if_inline_ext[XFS_INLINE_EXTS]; + xfs_bmbt_rec_host_t if_inline_ext[XFS_INLINE_EXTS]; /* very small file extents */ char if_inline_data[XFS_INLINE_DATA]; /* very small file data */ @@ -51,41 +83,137 @@ typedef struct xfs_ifork { } if_u2; } xfs_ifork_t; +/* + * This is the xfs in-core inode structure. + * Most of the on-disk inode is embedded in the i_d field. + * + * The extent pointers/inline file space, however, are managed + * separately. The memory for this information is pointed to by + * the if_u1 unions depending on the type of the data. + * This is used to linearize the array of extents for fast in-core + * access. This is used until the file's number of extents + * surpasses XFS_MAX_INCORE_EXTENTS, at which point all extent pointers + * are accessed through the buffer cache. + * + * Other state kept in the in-core inode is used for identification, + * locking, transactional updating, etc of the inode. + * + * Generally, we do not want to hold the i_rlock while holding the + * i_ilock. Hierarchy is i_iolock followed by i_rlock. + * + * xfs_iptr_t contains all the inode fields upto and including the + * i_mnext and i_mprev fields, it is used as a marker in the inode + * chain off the mount structure by xfs_sync calls. + */ + +typedef struct xfs_ictimestamp { + __int32_t t_sec; /* timestamp seconds */ + __int32_t t_nsec; /* timestamp nanoseconds */ +} xfs_ictimestamp_t; + +/* + * NOTE: This structure must be kept identical to struct xfs_dinode_core + * in xfs_dinode.h except for the endianess annotations. + */ +typedef struct xfs_icdinode { + __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ + __uint16_t di_mode; /* mode and type of file */ + __int8_t di_version; /* inode version */ + __int8_t di_format; /* format of di_c data */ + __uint16_t di_onlink; /* old number of links to file */ + __uint32_t di_uid; /* owner's user id */ + __uint32_t di_gid; /* owner's group id */ + __uint32_t di_nlink; /* number of links to file */ + __uint16_t di_projid; /* owner's project id */ + __uint8_t di_pad[8]; /* unused, zeroed space */ + __uint16_t di_flushiter; /* incremented on flush */ + xfs_ictimestamp_t di_atime; /* time last accessed */ + xfs_ictimestamp_t di_mtime; /* time last modified */ + xfs_ictimestamp_t di_ctime; /* time created/inode modified */ + xfs_fsize_t di_size; /* number of bytes in file */ + xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */ + xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ + xfs_extnum_t di_nextents; /* number of extents in data fork */ + xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ + __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ + __int8_t di_aformat; /* format of attr fork's data */ + __uint32_t di_dmevmask; /* DMIG event mask */ + __uint16_t di_dmstate; /* DMIG state info */ + __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ + __uint32_t di_gen; /* generation number */ +} xfs_icdinode_t; + /* * Flags for xfs_ichgtime(). */ #define XFS_ICHGTIME_MOD 0x1 /* data fork modification timestamp */ -#define XFS_ICHGTIME_ACC 0x2 /* data fork access timestamp */ -#define XFS_ICHGTIME_CHG 0x4 /* inode field change timestamp */ +#define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */ /* * Per-fork incore inode flags. */ -#define XFS_IFINLINE 0x0001 /* Inline data is read in */ -#define XFS_IFEXTENTS 0x0002 /* All extent pointers are read in */ -#define XFS_IFBROOT 0x0004 /* i_broot points to the bmap b-tree root */ +#define XFS_IFINLINE 0x01 /* Inline data is read in */ +#define XFS_IFEXTENTS 0x02 /* All extent pointers are read in */ +#define XFS_IFBROOT 0x04 /* i_broot points to the bmap b-tree root */ +#define XFS_IFEXTIREC 0x08 /* Indirection array of extent blocks */ /* - * Flags for xfs_imap() and xfs_dilocate(). + * Flags for xfs_itobp(), xfs_imap() and xfs_dilocate(). */ -#define XFS_IMAP_LOOKUP 0x1 +#define XFS_IMAP_LOOKUP 0x1 +#define XFS_IMAP_BULKSTAT 0x2 /* - * Maximum number of extent pointers in if_u1.if_extents. + * Fork handling. */ -#define XFS_MAX_INCORE_EXTENTS 32768 + +#define XFS_IFORK_Q(ip) ((ip)->i_d.di_forkoff != 0) +#define XFS_IFORK_BOFF(ip) ((int)((ip)->i_d.di_forkoff << 3)) + +#define XFS_IFORK_PTR(ip,w) \ + ((w) == XFS_DATA_FORK ? \ + &(ip)->i_df : \ + (ip)->i_afp) +#define XFS_IFORK_DSIZE(ip) \ + (XFS_IFORK_Q(ip) ? \ + XFS_IFORK_BOFF(ip) : \ + XFS_LITINO((ip)->i_mount)) +#define XFS_IFORK_ASIZE(ip) \ + (XFS_IFORK_Q(ip) ? \ + XFS_LITINO((ip)->i_mount) - XFS_IFORK_BOFF(ip) : \ + 0) +#define XFS_IFORK_SIZE(ip,w) \ + ((w) == XFS_DATA_FORK ? \ + XFS_IFORK_DSIZE(ip) : \ + XFS_IFORK_ASIZE(ip)) +#define XFS_IFORK_FORMAT(ip,w) \ + ((w) == XFS_DATA_FORK ? \ + (ip)->i_d.di_format : \ + (ip)->i_d.di_aformat) +#define XFS_IFORK_FMT_SET(ip,w,n) \ + ((w) == XFS_DATA_FORK ? \ + ((ip)->i_d.di_format = (n)) : \ + ((ip)->i_d.di_aformat = (n))) +#define XFS_IFORK_NEXTENTS(ip,w) \ + ((w) == XFS_DATA_FORK ? \ + (ip)->i_d.di_nextents : \ + (ip)->i_d.di_anextents) +#define XFS_IFORK_NEXT_SET(ip,w,n) \ + ((w) == XFS_DATA_FORK ? \ + ((ip)->i_d.di_nextents = (n)) : \ + ((ip)->i_d.di_anextents = (n))) + #ifdef __KERNEL__ + struct bhv_desc; struct cred; struct ktrace; -struct vnode; struct xfs_buf; struct xfs_bmap_free; struct xfs_bmbt_irec; struct xfs_bmbt_block; -struct xfs_inode; struct xfs_inode_log_item; struct xfs_mount; struct xfs_trans; @@ -105,122 +233,19 @@ typedef struct dm_attrs_s { __uint16_t da_pad; /* DMIG extra padding */ } dm_attrs_t; -typedef struct xfs_iocore { - void *io_obj; /* pointer to container - * inode or dcxvn structure */ - struct xfs_mount *io_mount; /* fs mount struct ptr */ -#ifdef DEBUG - mrlock_t *io_lock; /* inode IO lock */ - mrlock_t *io_iolock; /* inode IO lock */ -#endif - - /* I/O state */ - xfs_fsize_t io_new_size; /* sz when write completes */ - - /* Miscellaneous state. */ - unsigned int io_flags; /* IO related flags */ - - /* DMAPI state */ - dm_attrs_t io_dmattrs; - -} xfs_iocore_t; - -#define io_dmevmask io_dmattrs.da_dmevmask -#define io_dmstate io_dmattrs.da_dmstate - -#define XFS_IO_INODE(io) ((xfs_inode_t *) ((io)->io_obj)) -#define XFS_IO_DCXVN(io) ((dcxvn_t *) ((io)->io_obj)) - -/* - * Flags in the flags field - */ - -#define XFS_IOCORE_RT 0x1 - -/* - * xfs_iocore prototypes - */ - -extern void xfs_iocore_inode_init(struct xfs_inode *); -extern void xfs_iocore_inode_reinit(struct xfs_inode *); - - -/* - * This is the type used in the xfs inode hash table. - * An array of these is allocated for each mounted - * file system to hash the inodes for that file system. - */ -typedef struct xfs_ihash { - struct xfs_inode *ih_next; - rwlock_t ih_lock; - uint ih_version; -} xfs_ihash_t; - -#define XFS_IHASH(mp,ino) ((mp)->m_ihash + (((uint)(ino)) % (mp)->m_ihsize)) - -/* - * This is the xfs inode cluster hash. This hash is used by xfs_iflush to - * find inodes that share a cluster and can be flushed to disk at the same - * time. - */ -typedef struct xfs_chashlist { - struct xfs_chashlist *chl_next; - struct xfs_inode *chl_ip; - xfs_daddr_t chl_blkno; /* starting block number of - * the cluster */ - struct xfs_buf *chl_buf; /* the inode buffer */ -} xfs_chashlist_t; - -typedef struct xfs_chash { - xfs_chashlist_t *ch_list; - lock_t ch_lock; -} xfs_chash_t; - -#define XFS_CHASH(mp,blk) ((mp)->m_chash + (((uint)blk) % (mp)->m_chsize)) - - -/* - * This is the xfs in-core inode structure. - * Most of the on-disk inode is embedded in the i_d field. - * - * The extent pointers/inline file space, however, are managed - * separately. The memory for this information is pointed to by - * the if_u1 unions depending on the type of the data. - * This is used to linearize the array of extents for fast in-core - * access. This is used until the file's number of extents - * surpasses XFS_MAX_INCORE_EXTENTS, at which point all extent pointers - * are accessed through the buffer cache. - * - * Other state kept in the in-core inode is used for identification, - * locking, transactional updating, etc of the inode. - * - * Generally, we do not want to hold the i_rlock while holding the - * i_ilock. Hierarchy is i_iolock followed by i_rlock. - * - * xfs_iptr_t contains all the inode fields upto and including the - * i_mnext and i_mprev fields, it is used as a marker in the inode - * chain off the mount structure by xfs_sync calls. - */ - typedef struct { - struct xfs_ihash *ip_hash; /* pointer to hash header */ - struct xfs_inode *ip_next; /* inode hash link forw */ struct xfs_inode *ip_mnext; /* next inode in mount list */ struct xfs_inode *ip_mprev; /* ptr to prev inode */ - struct xfs_inode **ip_prevp; /* ptr to prev i_next */ struct xfs_mount *ip_mount; /* fs mount struct ptr */ } xfs_iptr_t; typedef struct xfs_inode { /* Inode linking and identification information. */ - struct xfs_ihash *i_hash; /* pointer to hash header */ - struct xfs_inode *i_next; /* inode hash link forw */ struct xfs_inode *i_mnext; /* next inode in mount list */ struct xfs_inode *i_mprev; /* ptr to prev inode */ - struct xfs_inode **i_prevp; /* ptr to prev i_next */ struct xfs_mount *i_mount; /* fs mount struct ptr */ struct list_head i_reclaim; /* reclaim list */ - struct bhv_desc i_bhv_desc; /* inode behavior descriptor*/ + struct inode *i_vnode; /* vnode backpointer */ struct xfs_dquot *i_udquot; /* user dquot */ struct xfs_dquot *i_gdquot; /* group dquot */ @@ -239,16 +264,10 @@ typedef struct xfs_inode { struct xfs_inode_log_item *i_itemp; /* logging information */ mrlock_t i_lock; /* inode lock */ mrlock_t i_iolock; /* inode IO lock */ - sema_t i_flock; /* inode flush lock */ + struct completion i_flush; /* inode flush completion q */ atomic_t i_pincount; /* inode pin count */ wait_queue_head_t i_ipin_wait; /* inode pinning wait queue */ -#ifdef HAVE_REFCACHE - struct xfs_inode **i_refcache; /* ptr to entry in ref cache */ - struct xfs_inode *i_release; /* inode to unref */ -#endif - /* I/O state */ - xfs_iocore_t i_iocore; /* I/O core */ - + spinlock_t i_flags_lock; /* inode i_flags lock */ /* Miscellaneous state. */ unsigned short i_flags; /* see defined flags below */ unsigned char i_update_core; /* timestamps/size is dirty */ @@ -256,12 +275,15 @@ typedef struct xfs_inode { unsigned int i_gen; /* generation count */ unsigned int i_delayed_blks; /* count of delay alloc blks */ - xfs_dinode_core_t i_d; /* most of ondisk inode */ - xfs_chashlist_t *i_chash; /* cluster hash list header */ - struct xfs_inode *i_cnext; /* cluster hash link forward */ - struct xfs_inode *i_cprev; /* cluster hash link backward */ + xfs_icdinode_t i_d; /* most of ondisk inode */ + xfs_fsize_t i_size; /* in-memory size */ + xfs_fsize_t i_new_size; /* size when write completes */ + atomic_t i_iocount; /* outstanding I/O count */ /* Trace buffers per inode. */ +#ifdef XFS_INODE_TRACE + struct ktrace *i_trace; /* general inode trace */ +#endif #ifdef XFS_BMAP_TRACE struct ktrace *i_xtrace; /* inode extent list trace */ #endif @@ -279,25 +301,94 @@ typedef struct xfs_inode { #endif } xfs_inode_t; -#endif /* __KERNEL__ */ +#define XFS_ISIZE(ip) (((ip)->i_d.di_mode & S_IFMT) == S_IFREG) ? \ + (ip)->i_size : (ip)->i_d.di_size; + +/* Convert from vfs inode to xfs inode */ +static inline struct xfs_inode *XFS_I(struct inode *inode) +{ + return (struct xfs_inode *)inode->i_private; +} +/* convert from xfs inode to vfs inode */ +static inline struct inode *VFS_I(struct xfs_inode *ip) +{ + return (struct inode *)ip->i_vnode; +} /* - * Fork handling. + * i_flags helper functions + */ +static inline void +__xfs_iflags_set(xfs_inode_t *ip, unsigned short flags) +{ + ip->i_flags |= flags; +} + +static inline void +xfs_iflags_set(xfs_inode_t *ip, unsigned short flags) +{ + spin_lock(&ip->i_flags_lock); + __xfs_iflags_set(ip, flags); + spin_unlock(&ip->i_flags_lock); +} + +static inline void +xfs_iflags_clear(xfs_inode_t *ip, unsigned short flags) +{ + spin_lock(&ip->i_flags_lock); + ip->i_flags &= ~flags; + spin_unlock(&ip->i_flags_lock); +} + +static inline int +__xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) +{ + return (ip->i_flags & flags); +} + +static inline int +xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) +{ + int ret; + spin_lock(&ip->i_flags_lock); + ret = __xfs_iflags_test(ip, flags); + spin_unlock(&ip->i_flags_lock); + return ret; +} + +static inline int +xfs_iflags_test_and_clear(xfs_inode_t *ip, unsigned short flags) +{ + int ret; + + spin_lock(&ip->i_flags_lock); + ret = ip->i_flags & flags; + if (ret) + ip->i_flags &= ~flags; + spin_unlock(&ip->i_flags_lock); + return ret; +} + +/* + * Manage the i_flush queue embedded in the inode. This completion + * queue synchronizes processes attempting to flush the in-core + * inode back to disk. */ -#define XFS_IFORK_PTR(ip,w) \ - ((w) == XFS_DATA_FORK ? &(ip)->i_df : (ip)->i_afp) -#define XFS_IFORK_Q(ip) XFS_CFORK_Q(&(ip)->i_d) -#define XFS_IFORK_DSIZE(ip) XFS_CFORK_DSIZE(&ip->i_d, ip->i_mount) -#define XFS_IFORK_ASIZE(ip) XFS_CFORK_ASIZE(&ip->i_d, ip->i_mount) -#define XFS_IFORK_SIZE(ip,w) XFS_CFORK_SIZE(&ip->i_d, ip->i_mount, w) -#define XFS_IFORK_FORMAT(ip,w) XFS_CFORK_FORMAT(&ip->i_d, w) -#define XFS_IFORK_FMT_SET(ip,w,n) XFS_CFORK_FMT_SET(&ip->i_d, w, n) -#define XFS_IFORK_NEXTENTS(ip,w) XFS_CFORK_NEXTENTS(&ip->i_d, w) -#define XFS_IFORK_NEXT_SET(ip,w,n) XFS_CFORK_NEXT_SET(&ip->i_d, w, n) +static inline void xfs_iflock(xfs_inode_t *ip) +{ + wait_for_completion(&ip->i_flush); +} +static inline int xfs_iflock_nowait(xfs_inode_t *ip) +{ + return try_wait_for_completion(&ip->i_flush); +} -#ifdef __KERNEL__ +static inline void xfs_ifunlock(xfs_inode_t *ip) +{ + complete(&ip->i_flush); +} /* * In-core inode flags. @@ -309,29 +400,57 @@ typedef struct xfs_inode { #define XFS_ISTALE 0x0010 /* inode has been staled */ #define XFS_IRECLAIMABLE 0x0020 /* inode can be reclaimed */ #define XFS_INEW 0x0040 +#define XFS_IFILESTREAM 0x0080 /* inode is in a filestream directory */ +#define XFS_IMODIFIED 0x0100 /* XFS inode state possibly differs */ + /* to the Linux inode state. */ +#define XFS_ITRUNCATED 0x0200 /* truncated down so flush-on-close */ /* * Flags for inode locking. + * Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield) + * 1<<16 - 1<<32-1 -- lockdep annotation (integers) */ -#define XFS_IOLOCK_EXCL 0x001 -#define XFS_IOLOCK_SHARED 0x002 -#define XFS_ILOCK_EXCL 0x004 -#define XFS_ILOCK_SHARED 0x008 -#define XFS_IUNLOCK_NONOTIFY 0x010 -/* XFS_IOLOCK_NESTED 0x020 */ -#define XFS_EXTENT_TOKEN_RD 0x040 -#define XFS_SIZE_TOKEN_RD 0x080 -#define XFS_EXTSIZE_RD (XFS_EXTENT_TOKEN_RD|XFS_SIZE_TOKEN_RD) -#define XFS_WILLLEND 0x100 /* Always acquire tokens for lending */ -#define XFS_EXTENT_TOKEN_WR (XFS_EXTENT_TOKEN_RD | XFS_WILLLEND) -#define XFS_SIZE_TOKEN_WR (XFS_SIZE_TOKEN_RD | XFS_WILLLEND) -#define XFS_EXTSIZE_WR (XFS_EXTSIZE_RD | XFS_WILLLEND) -/* XFS_SIZE_TOKEN_WANT 0x200 */ - -#define XFS_LOCK_MASK \ - (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED | XFS_ILOCK_EXCL | \ - XFS_ILOCK_SHARED | XFS_EXTENT_TOKEN_RD | XFS_SIZE_TOKEN_RD | \ - XFS_WILLLEND) +#define XFS_IOLOCK_EXCL (1<<0) +#define XFS_IOLOCK_SHARED (1<<1) +#define XFS_ILOCK_EXCL (1<<2) +#define XFS_ILOCK_SHARED (1<<3) +#define XFS_IUNLOCK_NONOTIFY (1<<4) + +#define XFS_LOCK_MASK (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED \ + | XFS_ILOCK_EXCL | XFS_ILOCK_SHARED) + +/* + * Flags for lockdep annotations. + * + * XFS_I[O]LOCK_PARENT - for operations that require locking two inodes + * (ie directory operations that require locking a directory inode and + * an entry inode). The first inode gets locked with this flag so it + * gets a lockdep subclass of 1 and the second lock will have a lockdep + * subclass of 0. + * + * XFS_LOCK_INUMORDER - for locking several inodes at the some time + * with xfs_lock_inodes(). This flag is used as the starting subclass + * and each subsequent lock acquired will increment the subclass by one. + * So the first lock acquired will have a lockdep subclass of 2, the + * second lock will have a lockdep subclass of 3, and so on. It is + * the responsibility of the class builder to shift this to the correct + * portion of the lock_mode lockdep mask. + */ +#define XFS_LOCK_PARENT 1 +#define XFS_LOCK_INUMORDER 2 + +#define XFS_IOLOCK_SHIFT 16 +#define XFS_IOLOCK_PARENT (XFS_LOCK_PARENT << XFS_IOLOCK_SHIFT) + +#define XFS_ILOCK_SHIFT 24 +#define XFS_ILOCK_PARENT (XFS_LOCK_PARENT << XFS_ILOCK_SHIFT) + +#define XFS_IOLOCK_DEP_MASK 0x00ff0000 +#define XFS_ILOCK_DEP_MASK 0xff000000 +#define XFS_LOCK_DEP_MASK (XFS_IOLOCK_DEP_MASK | XFS_ILOCK_DEP_MASK) + +#define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT) +#define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT) /* * Flags for xfs_iflush() @@ -341,6 +460,7 @@ typedef struct xfs_inode { #define XFS_IFLUSH_SYNC 3 #define XFS_IFLUSH_ASYNC 4 #define XFS_IFLUSH_DELWRI 5 +#define XFS_IFLUSH_ASYNC_NOBLOCK 6 /* * Flags for xfs_itruncate_start(). @@ -348,34 +468,28 @@ typedef struct xfs_inode { #define XFS_ITRUNC_DEFINITE 0x1 #define XFS_ITRUNC_MAYBE 0x2 -#define XFS_ITOV(ip) BHV_TO_VNODE(XFS_ITOBHV(ip)) -#define XFS_ITOV_NULL(ip) BHV_TO_VNODE_NULL(XFS_ITOBHV(ip)) -#define XFS_ITOBHV(ip) ((struct bhv_desc *)(&((ip)->i_bhv_desc))) -#define XFS_BHVTOI(bhvp) ((xfs_inode_t *)((char *)(bhvp) - \ - (char *)&(((xfs_inode_t *)0)->i_bhv_desc))) -#define BHV_IS_XFS(bdp) (BHV_OPS(bdp) == &xfs_vnodeops) - /* * For multiple groups support: if S_ISGID bit is set in the parent * directory, group of new file is set to that of the parent, and * new subdirectory gets S_ISGID bit from parent. */ -#define XFS_INHERIT_GID(pip, vfsp) \ - (((vfsp)->vfs_flag & VFS_GRPID) || ((pip)->i_d.di_mode & S_ISGID)) +#define XFS_INHERIT_GID(pip) \ + (((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \ + ((pip)->i_d.di_mode & S_ISGID)) /* - * xfs_iget.c prototypes. + * Flags for xfs_iget() */ +#define XFS_IGET_CREATE 0x1 +#define XFS_IGET_BULKSTAT 0x2 -#define IGET_CREATE 1 - +/* + * xfs_iget.c prototypes. + */ void xfs_ihash_init(struct xfs_mount *); void xfs_ihash_free(struct xfs_mount *); -void xfs_chash_init(struct xfs_mount *); -void xfs_chash_free(struct xfs_mount *); xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, struct xfs_trans *); -void xfs_inode_lock_init(xfs_inode_t *, struct vnode *); int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, uint, uint, xfs_inode_t **, xfs_daddr_t); void xfs_iput(xfs_inode_t *, uint); @@ -384,11 +498,9 @@ void xfs_ilock(xfs_inode_t *, uint); int xfs_ilock_nowait(xfs_inode_t *, uint); void xfs_iunlock(xfs_inode_t *, uint); void xfs_ilock_demote(xfs_inode_t *, uint); -void xfs_iflock(xfs_inode_t *); -int xfs_iflock_nowait(xfs_inode_t *); +int xfs_isilocked(xfs_inode_t *, uint); uint xfs_ilock_map_shared(xfs_inode_t *); void xfs_iunlock_map_shared(xfs_inode_t *, uint); -void xfs_ifunlock(xfs_inode_t *); void xfs_ireclaim(xfs_inode_t *); int xfs_finish_reclaim(xfs_inode_t *, int, int); int xfs_finish_reclaim_all(struct xfs_mount *, int); @@ -396,50 +508,83 @@ int xfs_finish_reclaim_all(struct xfs_mount *, int); /* * xfs_inode.c prototypes. */ -int xfs_itobp(struct xfs_mount *, struct xfs_trans *, - xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **, - xfs_daddr_t); int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, - xfs_inode_t **, xfs_daddr_t); -int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int); + xfs_inode_t **, xfs_daddr_t, uint); int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t, int, struct xfs_buf **, boolean_t *, xfs_inode_t **); -void xfs_xlate_dinode_core(xfs_caddr_t, struct xfs_dinode_core *, - int); + uint xfs_ip2xflags(struct xfs_inode *); -uint xfs_dic2xflags(struct xfs_dinode_core *); +uint xfs_dic2xflags(struct xfs_dinode *); int xfs_ifree(struct xfs_trans *, xfs_inode_t *, struct xfs_bmap_free *); -void xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t); +int xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t); int xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *, xfs_fsize_t, int, int); int xfs_iunlink(struct xfs_trans *, xfs_inode_t *); -int xfs_igrow_start(xfs_inode_t *, xfs_fsize_t, struct cred *); -void xfs_igrow_finish(struct xfs_trans *, xfs_inode_t *, - xfs_fsize_t, int); -void xfs_idestroy_fork(xfs_inode_t *, int); +struct xfs_inode * xfs_inode_alloc(struct xfs_mount *, xfs_ino_t); void xfs_idestroy(xfs_inode_t *); -void xfs_idata_realloc(xfs_inode_t *, int, int); void xfs_iextract(xfs_inode_t *); void xfs_iext_realloc(xfs_inode_t *, int, int); -void xfs_iroot_realloc(xfs_inode_t *, int, int); void xfs_ipin(xfs_inode_t *); void xfs_iunpin(xfs_inode_t *); -int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int); int xfs_iflush(xfs_inode_t *, uint); void xfs_iflush_all(struct xfs_mount *); -int xfs_iaccess(xfs_inode_t *, mode_t, cred_t *); -uint xfs_iroundup(uint); void xfs_ichgtime(xfs_inode_t *, int); xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); -void xfs_lock_inodes(xfs_inode_t **, int, int, uint); +void xfs_lock_inodes(xfs_inode_t **, int, uint); +void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); + +void xfs_synchronize_atime(xfs_inode_t *); +void xfs_mark_inode_dirty_sync(xfs_inode_t *); + +#endif /* __KERNEL__ */ + +int xfs_itobp(struct xfs_mount *, struct xfs_trans *, + struct xfs_inode *, struct xfs_dinode **, + struct xfs_buf **, xfs_daddr_t, uint, uint); +void xfs_dinode_from_disk(struct xfs_icdinode *, + struct xfs_dinode_core *); +void xfs_dinode_to_disk(struct xfs_dinode_core *, + struct xfs_icdinode *); +void xfs_idestroy_fork(struct xfs_inode *, int); +void xfs_idata_realloc(struct xfs_inode *, int, int); +void xfs_iroot_realloc(struct xfs_inode *, int, int); +int xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int); +int xfs_iextents_copy(struct xfs_inode *, xfs_bmbt_rec_t *, int); + +xfs_bmbt_rec_host_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t); +void xfs_iext_insert(xfs_ifork_t *, xfs_extnum_t, xfs_extnum_t, + xfs_bmbt_irec_t *); +void xfs_iext_add(xfs_ifork_t *, xfs_extnum_t, int); +void xfs_iext_add_indirect_multi(xfs_ifork_t *, int, xfs_extnum_t, int); +void xfs_iext_remove(xfs_ifork_t *, xfs_extnum_t, int); +void xfs_iext_remove_inline(xfs_ifork_t *, xfs_extnum_t, int); +void xfs_iext_remove_direct(xfs_ifork_t *, xfs_extnum_t, int); +void xfs_iext_remove_indirect(xfs_ifork_t *, xfs_extnum_t, int); +void xfs_iext_realloc_direct(xfs_ifork_t *, int); +void xfs_iext_realloc_indirect(xfs_ifork_t *, int); +void xfs_iext_indirect_to_direct(xfs_ifork_t *); +void xfs_iext_direct_to_inline(xfs_ifork_t *, xfs_extnum_t); +void xfs_iext_inline_to_direct(xfs_ifork_t *, int); +void xfs_iext_destroy(xfs_ifork_t *); +xfs_bmbt_rec_host_t *xfs_iext_bno_to_ext(xfs_ifork_t *, xfs_fileoff_t, int *); +xfs_ext_irec_t *xfs_iext_bno_to_irec(xfs_ifork_t *, xfs_fileoff_t, int *); +xfs_ext_irec_t *xfs_iext_idx_to_irec(xfs_ifork_t *, xfs_extnum_t *, int *, int); +void xfs_iext_irec_init(xfs_ifork_t *); +xfs_ext_irec_t *xfs_iext_irec_new(xfs_ifork_t *, int); +void xfs_iext_irec_remove(xfs_ifork_t *, int); +void xfs_iext_irec_compact(xfs_ifork_t *); +void xfs_iext_irec_compact_pages(xfs_ifork_t *); +void xfs_iext_irec_compact_full(xfs_ifork_t *); +void xfs_iext_irec_update_extoffs(xfs_ifork_t *, int, int); #define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount)) #ifdef DEBUG -void xfs_isize_check(struct xfs_mount *, xfs_inode_t *, xfs_fsize_t); +void xfs_isize_check(struct xfs_mount *, struct xfs_inode *, + xfs_fsize_t); #else /* DEBUG */ #define xfs_isize_check(mp, ip, isize) #endif /* DEBUG */ @@ -450,12 +595,8 @@ void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *); #define xfs_inobp_check(mp, bp) #endif /* DEBUG */ -extern struct kmem_zone *xfs_chashlist_zone; extern struct kmem_zone *xfs_ifork_zone; extern struct kmem_zone *xfs_inode_zone; extern struct kmem_zone *xfs_ili_zone; -extern struct vnodeops xfs_vnodeops; - -#endif /* __KERNEL__ */ #endif /* __XFS_INODE_H__ */ diff --git a/include/xfs_inode_item.h b/include/xfs_inode_item.h index bfe92ea17..1ff04cc32 100644 --- a/include/xfs_inode_item.h +++ b/include/xfs_inode_item.h @@ -112,6 +112,24 @@ typedef struct xfs_inode_log_format_64 { #define XFS_ILI_IOLOCKED_ANY (XFS_ILI_IOLOCKED_EXCL | XFS_ILI_IOLOCKED_SHARED) +#define XFS_ILOG_FBROOT(w) xfs_ilog_fbroot(w) +static inline int xfs_ilog_fbroot(int w) +{ + return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT); +} + +#define XFS_ILOG_FEXT(w) xfs_ilog_fext(w) +static inline int xfs_ilog_fext(int w) +{ + return (w == XFS_DATA_FORK ? XFS_ILOG_DEXT : XFS_ILOG_AEXT); +} + +#define XFS_ILOG_FDATA(w) xfs_ilog_fdata(w) +static inline int xfs_ilog_fdata(int w) +{ + return (w == XFS_DATA_FORK ? XFS_ILOG_DDATA : XFS_ILOG_ADATA); +} + #ifdef __KERNEL__ struct xfs_buf; @@ -148,28 +166,13 @@ typedef struct xfs_inode_log_item { } xfs_inode_log_item_t; -#define XFS_ILOG_FDATA(w) xfs_ilog_fdata(w) -static inline int xfs_ilog_fdata(int w) -{ - return (w == XFS_DATA_FORK ? XFS_ILOG_DDATA : XFS_ILOG_ADATA); -} - -#endif /* __KERNEL__ */ - -#define XFS_ILOG_FBROOT(w) xfs_ilog_fbroot(w) -static inline int xfs_ilog_fbroot(int w) +static inline int xfs_inode_clean(xfs_inode_t *ip) { - return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT); + return (!ip->i_itemp || + !(ip->i_itemp->ili_format.ilf_fields & XFS_ILOG_ALL)) && + !ip->i_update_core; } -#define XFS_ILOG_FEXT(w) xfs_ilog_fext(w) -static inline int xfs_ilog_fext(int w) -{ - return (w == XFS_DATA_FORK ? XFS_ILOG_DEXT : XFS_ILOG_AEXT); -} - -#ifdef __KERNEL__ - extern void xfs_inode_item_init(struct xfs_inode *, struct xfs_mount *); extern void xfs_inode_item_destroy(struct xfs_inode *); extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *); diff --git a/include/xfs_log.h b/include/xfs_log.h index 158829ca5..d47b91f10 100644 --- a/include/xfs_log.h +++ b/include/xfs_log.h @@ -22,21 +22,16 @@ #define CYCLE_LSN(lsn) ((uint)((lsn)>>32)) #define BLOCK_LSN(lsn) ((uint)(lsn)) + /* this is used in a spot where we might otherwise double-endian-flip */ -#define CYCLE_LSN_DISK(lsn) (((uint *)&(lsn))[0]) +#define CYCLE_LSN_DISK(lsn) (((__be32 *)&(lsn))[0]) #ifdef __KERNEL__ /* - * By comparing each compnent, we don't have to worry about extra + * By comparing each component, we don't have to worry about extra * endian issues in treating two 32 bit numbers as one 64 bit number */ -static -#if defined(__GNUC__) && (__GNUC__ == 2) && ( (__GNUC_MINOR__ == 95) || (__GNUC_MINOR__ == 96)) -__attribute__((unused)) /* gcc 2.95, 2.96 miscompile this when inlined */ -#else -__inline__ -#endif -xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) +static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) { if (CYCLE_LSN(lsn1) != CYCLE_LSN(lsn2)) return (CYCLE_LSN(lsn1)i_type = (t)) -#else -#define XLOG_VEC_SET_TYPE(vecp, t) -#endif - typedef struct xfs_log_iovec { xfs_caddr_t i_addr; /* beginning address of region */ int i_len; /* length in bytes of region */ -#if defined(XFS_LOG_RES_DEBUG) - uint i_type; /* type of region */ -#endif + uint i_type; /* type of region */ } xfs_log_iovec_t; typedef void* xfs_log_ticket_t; @@ -164,13 +142,14 @@ int _xfs_log_force(struct xfs_mount *mp, xfs_lsn_t lsn, uint flags, int *log_forced); -#define xfs_log_force(mp, lsn, flags) \ - _xfs_log_force(mp, lsn, flags, NULL); +void xfs_log_force(struct xfs_mount *mp, + xfs_lsn_t lsn, + uint flags); int xfs_log_mount(struct xfs_mount *mp, struct xfs_buftarg *log_target, xfs_daddr_t start_block, int num_bblocks); -int xfs_log_mount_finish(struct xfs_mount *mp, int); +int xfs_log_mount_finish(struct xfs_mount *mp); void xfs_log_move_tail(struct xfs_mount *mp, xfs_lsn_t tail_lsn); int xfs_log_notify(struct xfs_mount *mp, diff --git a/include/xfs_log_priv.h b/include/xfs_log_priv.h index 4518b188a..e7d8f8444 100644 --- a/include/xfs_log_priv.h +++ b/include/xfs_log_priv.h @@ -30,18 +30,16 @@ struct xfs_mount; */ #define XLOG_MIN_ICLOGS 2 -#define XLOG_MED_ICLOGS 4 #define XLOG_MAX_ICLOGS 8 -#define XLOG_CALLBACK_SIZE 10 #define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe /* Invalid cycle number */ #define XLOG_VERSION_1 1 #define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */ #define XLOG_VERSION_OKBITS (XLOG_VERSION_1 | XLOG_VERSION_2) -#define XLOG_RECORD_BSIZE (16*1024) /* eventually 32k */ +#define XLOG_MIN_RECORD_BSIZE (16*1024) /* eventually 32k */ #define XLOG_BIG_RECORD_BSIZE (32*1024) /* 32k buffers */ #define XLOG_MAX_RECORD_BSIZE (256*1024) #define XLOG_HEADER_CYCLE_SIZE (32*1024) /* cycle data in header */ -#define XLOG_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */ +#define XLOG_MIN_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */ #define XLOG_BIG_RECORD_BSHIFT 15 /* 32k == 1 << 15 */ #define XLOG_MAX_RECORD_BSHIFT 18 /* 256k == 1 << 18 */ #define XLOG_BTOLSUNIT(log, b) (((b)+(log)->l_mp->m_sb.sb_logsunit-1) / \ @@ -51,38 +49,27 @@ struct xfs_mount; #define XLOG_HEADER_SIZE 512 #define XLOG_REC_SHIFT(log) \ - BTOBB(1 << (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? \ + BTOBB(1 << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \ XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) #define XLOG_TOTAL_REC_SHIFT(log) \ - BTOBB(XLOG_MAX_ICLOGS << (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? \ + BTOBB(XLOG_MAX_ICLOGS << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \ XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) -/* - * set lsns - */ -#define ASSIGN_ANY_LSN_HOST(lsn,cycle,block) \ - { \ - (lsn) = ((xfs_lsn_t)(cycle)<<32)|(block); \ - } -#define ASSIGN_ANY_LSN_DISK(lsn,cycle,block) \ - { \ - INT_SET(((uint *)&(lsn))[0], ARCH_CONVERT, (cycle)); \ - INT_SET(((uint *)&(lsn))[1], ARCH_CONVERT, (block)); \ - } -#define ASSIGN_LSN(lsn,log) \ - ASSIGN_ANY_LSN_DISK(lsn,(log)->l_curr_cycle,(log)->l_curr_block); - -#define XLOG_SET(f,b) (((f) & (b)) == (b)) - -#define GET_CYCLE(ptr, arch) \ - (INT_GET(*(uint *)(ptr), arch) == XLOG_HEADER_MAGIC_NUM ? \ - INT_GET(*((uint *)(ptr)+1), arch) : \ - INT_GET(*(uint *)(ptr), arch) \ - ) +static inline xfs_lsn_t xlog_assign_lsn(uint cycle, uint block) +{ + return ((xfs_lsn_t)cycle << 32) | block; +} -#define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1) +static inline uint xlog_get_cycle(char *ptr) +{ + if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM) + return be32_to_cpu(*((__be32 *)ptr + 1)); + else + return be32_to_cpu(*(__be32 *)ptr); +} +#define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1) #ifdef __KERNEL__ @@ -98,19 +85,10 @@ struct xfs_mount; * * this has endian issues, of course. */ - -#ifndef XFS_NATIVE_HOST -#define GET_CLIENT_ID(i,arch) \ - ((i) & 0xff) -#else -#define GET_CLIENT_ID(i,arch) \ - ((i) >> 24) -#endif - -#define GRANT_LOCK(log) mutex_spinlock(&(log)->l_grant_lock) -#define GRANT_UNLOCK(log, s) mutex_spinunlock(&(log)->l_grant_lock, s) -#define LOG_LOCK(log) mutex_spinlock(&(log)->l_icloglock) -#define LOG_UNLOCK(log, s) mutex_spinunlock(&(log)->l_icloglock, s) +static inline uint xlog_get_client_id(__be32 i) +{ + return be32_to_cpu(i) >> 24; +} #define xlog_panic(args...) cmn_err(CE_PANIC, ## args) #define xlog_exit(args...) cmn_err(CE_PANIC, ## args) @@ -149,9 +127,6 @@ struct xfs_mount; #define XLOG_WAS_CONT_TRANS 0x08 /* Cont this trans into new region */ #define XLOG_END_TRANS 0x10 /* End a continued transaction */ #define XLOG_UNMOUNT_TRANS 0x20 /* Unmount a filesystem transaction */ -#define XLOG_SKIP_TRANS (XLOG_COMMIT_TRANS | XLOG_CONTINUE_TRANS | \ - XLOG_WAS_CONT_TRANS | XLOG_END_TRANS | \ - XLOG_UNMOUNT_TRANS) #ifdef __KERNEL__ /* @@ -253,24 +228,7 @@ typedef __uint32_t xlog_tid_t; /* Ticket reservation region accounting */ -#if defined(XFS_LOG_RES_DEBUG) #define XLOG_TIC_LEN_MAX 15 -#define XLOG_TIC_RESET_RES(t) ((t)->t_res_num = \ - (t)->t_res_arr_sum = (t)->t_res_num_ophdrs = 0) -#define XLOG_TIC_ADD_OPHDR(t) ((t)->t_res_num_ophdrs++) -#define XLOG_TIC_ADD_REGION(t, len, type) \ - do { \ - if ((t)->t_res_num == XLOG_TIC_LEN_MAX) { \ - /* add to overflow and start again */ \ - (t)->t_res_o_flow += (t)->t_res_arr_sum; \ - (t)->t_res_num = 0; \ - (t)->t_res_arr_sum = 0; \ - } \ - (t)->t_res_arr[(t)->t_res_num].r_len = (len); \ - (t)->t_res_arr[(t)->t_res_num].r_type = (type); \ - (t)->t_res_arr_sum += (len); \ - (t)->t_res_num++; \ - } while (0) /* * Reservation region @@ -278,19 +236,13 @@ typedef __uint32_t xlog_tid_t; * we don't care about. */ typedef struct xlog_res { - uint r_len; - uint r_type; + uint r_len; /* region length :4 */ + uint r_type; /* region's transaction type :4 */ } xlog_res_t; -#else -#define XLOG_TIC_RESET_RES(t) -#define XLOG_TIC_ADD_OPHDR(t) -#define XLOG_TIC_ADD_REGION(t, len, type) -#endif - typedef struct xlog_ticket { - sv_t t_sema; /* sleep on this semaphore : 20 */ - struct xlog_ticket *t_next; /* :4|8 */ + sv_t t_wait; /* ticket wait queue : 20 */ + struct xlog_ticket *t_next; /* :4|8 */ struct xlog_ticket *t_prev; /* :4|8 */ xlog_tid_t t_tid; /* transaction identifier : 4 */ int t_curr_res; /* current reservation in bytes : 4 */ @@ -301,25 +253,23 @@ typedef struct xlog_ticket { char t_flags; /* properties of reservation : 1 */ uint t_trans_type; /* transaction type : 4 */ -#if defined (XFS_LOG_RES_DEBUG) /* reservation array fields */ uint t_res_num; /* num in array : 4 */ - xlog_res_t t_res_arr[XLOG_TIC_LEN_MAX]; /* array of res : X */ uint t_res_num_ophdrs; /* num op hdrs : 4 */ uint t_res_arr_sum; /* array sum : 4 */ uint t_res_o_flow; /* sum overflow : 4 */ -#endif + xlog_res_t t_res_arr[XLOG_TIC_LEN_MAX]; /* array of res : 8 * 15 */ } xlog_ticket_t; #endif typedef struct xlog_op_header { - xlog_tid_t oh_tid; /* transaction id of operation : 4 b */ - int oh_len; /* bytes in data region : 4 b */ - __uint8_t oh_clientid; /* who sent me this : 1 b */ - __uint8_t oh_flags; /* : 1 b */ - ushort oh_res2; /* 32 bit align : 2 b */ + __be32 oh_tid; /* transaction id of operation : 4 b */ + __be32 oh_len; /* bytes in data region : 4 b */ + __u8 oh_clientid; /* who sent me this : 1 b */ + __u8 oh_flags; /* : 1 b */ + __u16 oh_res2; /* 32 bit align : 2 b */ } xlog_op_header_t; @@ -337,25 +287,25 @@ typedef struct xlog_op_header { #endif typedef struct xlog_rec_header { - uint h_magicno; /* log record (LR) identifier : 4 */ - uint h_cycle; /* write cycle of log : 4 */ - int h_version; /* LR version : 4 */ - int h_len; /* len in bytes; should be 64-bit aligned: 4 */ - xfs_lsn_t h_lsn; /* lsn of this LR : 8 */ - xfs_lsn_t h_tail_lsn; /* lsn of 1st LR w/ buffers not committed: 8 */ - uint h_chksum; /* may not be used; non-zero if used : 4 */ - int h_prev_block; /* block number to previous LR : 4 */ - int h_num_logops; /* number of log operations in this LR : 4 */ - uint h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; + __be32 h_magicno; /* log record (LR) identifier : 4 */ + __be32 h_cycle; /* write cycle of log : 4 */ + __be32 h_version; /* LR version : 4 */ + __be32 h_len; /* len in bytes; should be 64-bit aligned: 4 */ + __be64 h_lsn; /* lsn of this LR : 8 */ + __be64 h_tail_lsn; /* lsn of 1st LR w/ buffers not committed: 8 */ + __be32 h_chksum; /* may not be used; non-zero if used : 4 */ + __be32 h_prev_block; /* block number to previous LR : 4 */ + __be32 h_num_logops; /* number of log operations in this LR : 4 */ + __be32 h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* new fields */ - int h_fmt; /* format of log record : 4 */ - uuid_t h_fs_uuid; /* uuid of FS : 16 */ - int h_size; /* iclog size : 4 */ + __be32 h_fmt; /* format of log record : 4 */ + uuid_t h_fs_uuid; /* uuid of FS : 16 */ + __be32 h_size; /* iclog size : 4 */ } xlog_rec_header_t; typedef struct xlog_rec_ext_header { - uint xh_cycle; /* write cycle of log : 4 */ - uint xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* : 256 */ + __be32 xh_cycle; /* write cycle of log : 4 */ + __be32 xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* : 256 */ } xlog_rec_ext_header_t; #ifdef __KERNEL__ @@ -364,7 +314,7 @@ typedef struct xlog_rec_ext_header { * xlog_rec_header_t into the reserved space. * - ic_data follows, so a write to disk can start at the beginning of * the iclog. - * - ic_forcesema is used to implement synchronous forcing of the iclog to disk. + * - ic_forcewait is used to implement synchronous forcing of the iclog to disk. * - ic_next is the pointer to the next iclog in the ring. * - ic_bp is a pointer to the buffer used to write this incore log to disk. * - ic_log is a pointer back to the global log structure. @@ -374,25 +324,43 @@ typedef struct xlog_rec_ext_header { * - ic_offset is the current number of bytes written to in this iclog. * - ic_refcnt is bumped when someone is writing to the log. * - ic_state is the state of the iclog. + * + * Because of cacheline contention on large machines, we need to separate + * various resources onto different cachelines. To start with, make the + * structure cacheline aligned. The following fields can be contended on + * by independent processes: + * + * - ic_callback_* + * - ic_refcnt + * - fields protected by the global l_icloglock + * + * so we need to ensure that these fields are located in separate cachelines. + * We'll put all the read-only and l_icloglock fields in the first cacheline, + * and move everything else out to subsequent cachelines. */ typedef struct xlog_iclog_fields { - sv_t ic_forcesema; - sv_t ic_writesema; + sv_t ic_force_wait; + sv_t ic_write_wait; struct xlog_in_core *ic_next; struct xlog_in_core *ic_prev; struct xfs_buf *ic_bp; struct log *ic_log; - xfs_log_callback_t *ic_callback; - xfs_log_callback_t **ic_callback_tail; -#ifdef XFS_LOG_TRACE - struct ktrace *ic_trace; -#endif int ic_size; int ic_offset; - int ic_refcnt; int ic_bwritecnt; ushort_t ic_state; char *ic_datap; /* pointer to iclog data */ +#ifdef XFS_LOG_TRACE + struct ktrace *ic_trace; +#endif + + /* Callback structures need their own cacheline */ + spinlock_t ic_callback_lock ____cacheline_aligned_in_smp; + xfs_log_callback_t *ic_callback; + xfs_log_callback_t **ic_callback_tail; + + /* reference counts need their own cacheline */ + atomic_t ic_refcnt ____cacheline_aligned_in_smp; } xlog_iclog_fields_t; typedef union xlog_in_core2 { @@ -409,13 +377,14 @@ typedef struct xlog_in_core { /* * Defines to save our code from this glop. */ -#define ic_forcesema hic_fields.ic_forcesema -#define ic_writesema hic_fields.ic_writesema +#define ic_force_wait hic_fields.ic_force_wait +#define ic_write_wait hic_fields.ic_write_wait #define ic_next hic_fields.ic_next #define ic_prev hic_fields.ic_prev #define ic_bp hic_fields.ic_bp #define ic_log hic_fields.ic_log #define ic_callback hic_fields.ic_callback +#define ic_callback_lock hic_fields.ic_callback_lock #define ic_callback_tail hic_fields.ic_callback_tail #define ic_trace hic_fields.ic_trace #define ic_size hic_fields.ic_size @@ -433,43 +402,44 @@ typedef struct xlog_in_core { * that round off problems won't occur when releasing partial reservations. */ typedef struct log { - /* The following block of fields are changed while holding icloglock */ - sema_t l_flushsema; /* iclog flushing semaphore */ - int l_flushcnt; /* # of procs waiting on this - * sema */ - int l_ticket_cnt; /* free ticket count */ - int l_ticket_tcnt; /* total ticket count */ - int l_covered_state;/* state of "covering disk - * log entries" */ - xlog_ticket_t *l_freelist; /* free list of tickets */ - xlog_ticket_t *l_unmount_free;/* kmem_free these addresses */ - xlog_ticket_t *l_tail; /* free list of tickets */ - xlog_in_core_t *l_iclog; /* head log queue */ - lock_t l_icloglock; /* grab to change iclog state */ - xfs_lsn_t l_tail_lsn; /* lsn of 1st LR with unflushed - * buffers */ - xfs_lsn_t l_last_sync_lsn;/* lsn of last LR on disk */ + /* The following fields don't need locking */ struct xfs_mount *l_mp; /* mount point */ struct xfs_buf *l_xbuf; /* extra buffer for log * wrapping */ struct xfs_buftarg *l_targ; /* buftarg of log */ + uint l_flags; + uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */ + struct xfs_buf_cancel **l_buf_cancel_table; + int l_iclog_hsize; /* size of iclog header */ + int l_iclog_heads; /* # of iclog header sectors */ + uint l_sectbb_log; /* log2 of sector size in BBs */ + uint l_sectbb_mask; /* sector size (in BBs) + * alignment mask */ + int l_iclog_size; /* size of log in bytes */ + int l_iclog_size_log; /* log power size of log */ + int l_iclog_bufs; /* number of iclog buffers */ xfs_daddr_t l_logBBstart; /* start block of log */ int l_logsize; /* size of log in bytes */ int l_logBBsize; /* size of log in BB chunks */ + + /* The following block of fields are changed while holding icloglock */ + sv_t l_flush_wait ____cacheline_aligned_in_smp; + /* waiting for iclog flush */ + int l_covered_state;/* state of "covering disk + * log entries" */ + xlog_in_core_t *l_iclog; /* head log queue */ + spinlock_t l_icloglock; /* grab to change iclog state */ + xfs_lsn_t l_tail_lsn; /* lsn of 1st LR with unflushed + * buffers */ + xfs_lsn_t l_last_sync_lsn;/* lsn of last LR on disk */ int l_curr_cycle; /* Cycle number of log writes */ int l_prev_cycle; /* Cycle number before last * block increment */ int l_curr_block; /* current logical log block */ int l_prev_block; /* previous logical log block */ - int l_iclog_size; /* size of log in bytes */ - int l_iclog_size_log; /* log power size of log */ - int l_iclog_bufs; /* number of iclog buffers */ - - /* The following field are used for debugging; need to hold icloglock */ - char *l_iclog_bak[XLOG_MAX_ICLOGS]; /* The following block of fields are changed while holding grant_lock */ - lock_t l_grant_lock; + spinlock_t l_grant_lock ____cacheline_aligned_in_smp; xlog_ticket_t *l_reserve_headq; xlog_ticket_t *l_write_headq; int l_grant_reserve_cycle; @@ -477,89 +447,27 @@ typedef struct log { int l_grant_write_cycle; int l_grant_write_bytes; - /* The following fields don't need locking */ #ifdef XFS_LOG_TRACE - struct ktrace *l_trace; struct ktrace *l_grant_trace; #endif - uint l_flags; - uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */ - struct xfs_buf_cancel **l_buf_cancel_table; - int l_iclog_hsize; /* size of iclog header */ - int l_iclog_heads; /* # of iclog header sectors */ - uint l_sectbb_log; /* log2 of sector size in BBs */ - uint l_sectbb_mask; /* sector size (in BBs) - * alignment mask */ + + /* The following field are used for debugging; need to hold icloglock */ +#ifdef DEBUG + char *l_iclog_bak[XLOG_MAX_ICLOGS]; +#endif + } xlog_t; #define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR) -#define XLOG_GRANT_SUB_SPACE(log,bytes,type) \ - { \ - if (type == 'w') { \ - (log)->l_grant_write_bytes -= (bytes); \ - if ((log)->l_grant_write_bytes < 0) { \ - (log)->l_grant_write_bytes += (log)->l_logsize; \ - (log)->l_grant_write_cycle--; \ - } \ - } else { \ - (log)->l_grant_reserve_bytes -= (bytes); \ - if ((log)->l_grant_reserve_bytes < 0) { \ - (log)->l_grant_reserve_bytes += (log)->l_logsize;\ - (log)->l_grant_reserve_cycle--; \ - } \ - } \ - } -#define XLOG_GRANT_ADD_SPACE(log,bytes,type) \ - { \ - if (type == 'w') { \ - (log)->l_grant_write_bytes += (bytes); \ - if ((log)->l_grant_write_bytes > (log)->l_logsize) { \ - (log)->l_grant_write_bytes -= (log)->l_logsize; \ - (log)->l_grant_write_cycle++; \ - } \ - } else { \ - (log)->l_grant_reserve_bytes += (bytes); \ - if ((log)->l_grant_reserve_bytes > (log)->l_logsize) { \ - (log)->l_grant_reserve_bytes -= (log)->l_logsize;\ - (log)->l_grant_reserve_cycle++; \ - } \ - } \ - } -#define XLOG_INS_TICKETQ(q, tic) \ - { \ - if (q) { \ - (tic)->t_next = (q); \ - (tic)->t_prev = (q)->t_prev; \ - (q)->t_prev->t_next = (tic); \ - (q)->t_prev = (tic); \ - } else { \ - (tic)->t_prev = (tic)->t_next = (tic); \ - (q) = (tic); \ - } \ - (tic)->t_flags |= XLOG_TIC_IN_Q; \ - } -#define XLOG_DEL_TICKETQ(q, tic) \ - { \ - if ((tic) == (tic)->t_next) { \ - (q) = NULL; \ - } else { \ - (q) = (tic)->t_next; \ - (tic)->t_next->t_prev = (tic)->t_prev; \ - (tic)->t_prev->t_next = (tic)->t_next; \ - } \ - (tic)->t_next = (tic)->t_prev = NULL; \ - (tic)->t_flags &= ~XLOG_TIC_IN_Q; \ - } /* common routines */ extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp); extern int xlog_find_tail(xlog_t *log, xfs_daddr_t *head_blk, - xfs_daddr_t *tail_blk, - int readonly); -extern int xlog_recover(xlog_t *log, int readonly); -extern int xlog_recover_finish(xlog_t *log, int mfsi_flags); + xfs_daddr_t *tail_blk); +extern int xlog_recover(xlog_t *log); +extern int xlog_recover_finish(xlog_t *log); extern void xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int); extern void xlog_recover_process_iunlinks(xlog_t *log); @@ -567,12 +475,20 @@ extern struct xfs_buf *xlog_get_bp(xlog_t *, int); extern void xlog_put_bp(struct xfs_buf *); extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *); +extern kmem_zone_t *xfs_log_ticket_zone; + /* iclog tracing */ #define XLOG_TRACE_GRAB_FLUSH 1 #define XLOG_TRACE_REL_FLUSH 2 #define XLOG_TRACE_SLEEP_FLUSH 3 #define XLOG_TRACE_WAKE_FLUSH 4 +/* + * Unmount record type is used as a pseudo transaction type for the ticket. + * It's value must be outside the range of XFS_TRANS_* values. + */ +#define XLOG_UNMOUNT_REC_TYPE (-1U) + #endif /* __KERNEL__ */ #endif /* __XFS_LOG_PRIV_H__ */ diff --git a/include/xfs_mount.h b/include/xfs_mount.h index 874d9f21b..ad61380b9 100644 --- a/include/xfs_mount.h +++ b/include/xfs_mount.h @@ -18,6 +18,7 @@ #ifndef __XFS_MOUNT_H__ #define __XFS_MOUNT_H__ + typedef struct xfs_trans_reservations { uint tr_write; /* extent alloc trans */ uint tr_itruncate; /* truncate trans */ @@ -43,50 +44,40 @@ typedef struct xfs_trans_reservations { } xfs_trans_reservations_t; #ifndef __KERNEL__ -/* - * Moved here from xfs_ag.h to avoid reordering header files - */ + #define XFS_DADDR_TO_AGNO(mp,d) \ ((xfs_agnumber_t)(XFS_BB_TO_FSBT(mp, d) / (mp)->m_sb.sb_agblocks)) #define XFS_DADDR_TO_AGBNO(mp,d) \ ((xfs_agblock_t)(XFS_BB_TO_FSBT(mp, d) % (mp)->m_sb.sb_agblocks)) -#else + +#else /* __KERNEL__ */ + struct cred; struct log; -struct vfs; -struct vnode; struct xfs_mount_args; -struct xfs_ihash; -struct xfs_chash; struct xfs_inode; -struct xfs_perag; -struct xfs_iocore; struct xfs_bmbt_irec; struct xfs_bmap_free; - -extern struct vfsops xfs_vfsops; -extern struct vnodeops xfs_vnodeops; - -#define AIL_LOCK_T lock_t -#define AIL_LOCKINIT(x,y) spinlock_init(x,y) -#define AIL_LOCK_DESTROY(x) spinlock_destroy(x) -#define AIL_LOCK(mp,s) s=mutex_spinlock(&(mp)->m_ail_lock) -#define AIL_UNLOCK(mp,s) mutex_spinunlock(&(mp)->m_ail_lock, s) - +struct xfs_extdelta; +struct xfs_swapext; +struct xfs_mru_cache; +struct xfs_nameops; /* * Prototypes and functions for the Data Migration subsystem. */ -typedef int (*xfs_send_data_t)(int, struct vnode *, - xfs_off_t, size_t, int, vrwlock_t *); +typedef int (*xfs_send_data_t)(int, struct xfs_inode *, + xfs_off_t, size_t, int, int *); typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint); -typedef int (*xfs_send_destroy_t)(struct vnode *, dm_right_t); -typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct vfs *, - struct vnode *, - dm_right_t, struct vnode *, dm_right_t, - char *, char *, mode_t, int, int); -typedef void (*xfs_send_unmount_t)(struct vfs *, struct vnode *, +typedef int (*xfs_send_destroy_t)(struct xfs_inode *, dm_right_t); +typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct xfs_mount *, + struct xfs_inode *, dm_right_t, + struct xfs_inode *, dm_right_t, + const char *, const char *, mode_t, int, int); +typedef int (*xfs_send_mount_t)(struct xfs_mount *, dm_right_t, + char *, char *); +typedef void (*xfs_send_unmount_t)(struct xfs_mount *, struct xfs_inode *, dm_right_t, mode_t, int, int); typedef struct xfs_dmops { @@ -94,21 +85,24 @@ typedef struct xfs_dmops { xfs_send_mmap_t xfs_send_mmap; xfs_send_destroy_t xfs_send_destroy; xfs_send_namesp_t xfs_send_namesp; + xfs_send_mount_t xfs_send_mount; xfs_send_unmount_t xfs_send_unmount; } xfs_dmops_t; -#define XFS_SEND_DATA(mp, ev,vp,off,len,fl,lock) \ - (*(mp)->m_dm_ops.xfs_send_data)(ev,vp,off,len,fl,lock) +#define XFS_SEND_DATA(mp, ev,ip,off,len,fl,lock) \ + (*(mp)->m_dm_ops->xfs_send_data)(ev,ip,off,len,fl,lock) #define XFS_SEND_MMAP(mp, vma,fl) \ - (*(mp)->m_dm_ops.xfs_send_mmap)(vma,fl) -#define XFS_SEND_DESTROY(mp, vp,right) \ - (*(mp)->m_dm_ops.xfs_send_destroy)(vp,right) + (*(mp)->m_dm_ops->xfs_send_mmap)(vma,fl) +#define XFS_SEND_DESTROY(mp, ip,right) \ + (*(mp)->m_dm_ops->xfs_send_destroy)(ip,right) #define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ - (*(mp)->m_dm_ops.xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl) -#define XFS_SEND_PREUNMOUNT(mp, vfs,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ - (*(mp)->m_dm_ops.xfs_send_namesp)(DM_EVENT_PREUNMOUNT,vfs,b1,r1,b2,r2,n1,n2,mode,rval,fl) -#define XFS_SEND_UNMOUNT(mp, vfsp,vp,right,mode,rval,fl) \ - (*(mp)->m_dm_ops.xfs_send_unmount)(vfsp,vp,right,mode,rval,fl) + (*(mp)->m_dm_ops->xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl) +#define XFS_SEND_PREUNMOUNT(mp,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ + (*(mp)->m_dm_ops->xfs_send_namesp)(DM_EVENT_PREUNMOUNT,mp,b1,r1,b2,r2,n1,n2,mode,rval,fl) +#define XFS_SEND_MOUNT(mp,right,path,name) \ + (*(mp)->m_dm_ops->xfs_send_mount)(mp,right,path,name) +#define XFS_SEND_UNMOUNT(mp, ip,right,mode,rval,fl) \ + (*(mp)->m_dm_ops->xfs_send_unmount)(mp,ip,right,mode,rval,fl) /* @@ -120,7 +114,7 @@ struct xfs_dqtrxops; struct xfs_quotainfo; typedef int (*xfs_qminit_t)(struct xfs_mount *, uint *, uint *); -typedef int (*xfs_qmmount_t)(struct xfs_mount *, uint, uint, int); +typedef int (*xfs_qmmount_t)(struct xfs_mount *, uint, uint); typedef int (*xfs_qmunmount_t)(struct xfs_mount *); typedef void (*xfs_qmdone_t)(struct xfs_mount *); typedef void (*xfs_dqrele_t)(struct xfs_dquot *); @@ -138,6 +132,9 @@ typedef struct xfs_dquot * (*xfs_dqvopchown_t)( struct xfs_dquot **, struct xfs_dquot *); typedef int (*xfs_dqvopchownresv_t)(struct xfs_trans *, struct xfs_inode *, struct xfs_dquot *, struct xfs_dquot *, uint); +typedef void (*xfs_dqstatvfs_t)(struct xfs_inode *, bhv_statvfs_t *); +typedef int (*xfs_dqsync_t)(struct xfs_mount *, int flags); +typedef int (*xfs_quotactl_t)(struct xfs_mount *, int, int, xfs_caddr_t); typedef struct xfs_qmops { xfs_qminit_t xfs_qminit; @@ -153,129 +150,93 @@ typedef struct xfs_qmops { xfs_dqvoprename_t xfs_dqvoprename; xfs_dqvopchown_t xfs_dqvopchown; xfs_dqvopchownresv_t xfs_dqvopchownresv; + xfs_dqstatvfs_t xfs_dqstatvfs; + xfs_dqsync_t xfs_dqsync; + xfs_quotactl_t xfs_quotactl; struct xfs_dqtrxops *xfs_dqtrxops; } xfs_qmops_t; #define XFS_QM_INIT(mp, mnt, fl) \ - (*(mp)->m_qm_ops.xfs_qminit)(mp, mnt, fl) -#define XFS_QM_MOUNT(mp, mnt, fl, mfsi_flags) \ - (*(mp)->m_qm_ops.xfs_qmmount)(mp, mnt, fl, mfsi_flags) + (*(mp)->m_qm_ops->xfs_qminit)(mp, mnt, fl) +#define XFS_QM_MOUNT(mp, mnt, fl) \ + (*(mp)->m_qm_ops->xfs_qmmount)(mp, mnt, fl) #define XFS_QM_UNMOUNT(mp) \ - (*(mp)->m_qm_ops.xfs_qmunmount)(mp) + (*(mp)->m_qm_ops->xfs_qmunmount)(mp) #define XFS_QM_DONE(mp) \ - (*(mp)->m_qm_ops.xfs_qmdone)(mp) + (*(mp)->m_qm_ops->xfs_qmdone)(mp) #define XFS_QM_DQRELE(mp, dq) \ - (*(mp)->m_qm_ops.xfs_dqrele)(dq) + (*(mp)->m_qm_ops->xfs_dqrele)(dq) #define XFS_QM_DQATTACH(mp, ip, fl) \ - (*(mp)->m_qm_ops.xfs_dqattach)(ip, fl) + (*(mp)->m_qm_ops->xfs_dqattach)(ip, fl) #define XFS_QM_DQDETACH(mp, ip) \ - (*(mp)->m_qm_ops.xfs_dqdetach)(ip) + (*(mp)->m_qm_ops->xfs_dqdetach)(ip) #define XFS_QM_DQPURGEALL(mp, fl) \ - (*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl) + (*(mp)->m_qm_ops->xfs_dqpurgeall)(mp, fl) #define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \ - (*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2) + (*(mp)->m_qm_ops->xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2) #define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \ - (*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2) + (*(mp)->m_qm_ops->xfs_dqvopcreate)(tp, ip, dq1, dq2) #define XFS_QM_DQVOPRENAME(mp, ip) \ - (*(mp)->m_qm_ops.xfs_dqvoprename)(ip) + (*(mp)->m_qm_ops->xfs_dqvoprename)(ip) #define XFS_QM_DQVOPCHOWN(mp, tp, ip, dqp, dq) \ - (*(mp)->m_qm_ops.xfs_dqvopchown)(tp, ip, dqp, dq) + (*(mp)->m_qm_ops->xfs_dqvopchown)(tp, ip, dqp, dq) #define XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, dq1, dq2, fl) \ - (*(mp)->m_qm_ops.xfs_dqvopchownresv)(tp, ip, dq1, dq2, fl) + (*(mp)->m_qm_ops->xfs_dqvopchownresv)(tp, ip, dq1, dq2, fl) +#define XFS_QM_DQSTATVFS(ip, statp) \ + (*(ip)->i_mount->m_qm_ops->xfs_dqstatvfs)(ip, statp) +#define XFS_QM_DQSYNC(mp, flags) \ + (*(mp)->m_qm_ops->xfs_dqsync)(mp, flags) +#define XFS_QM_QUOTACTL(mp, cmd, id, addr) \ + (*(mp)->m_qm_ops->xfs_quotactl)(mp, cmd, id, addr) +#ifdef HAVE_PERCPU_SB /* - * Prototypes and functions for I/O core modularization. + * Valid per-cpu incore superblock counters. Note that if you add new counters, + * you may need to define new counter disabled bit field descriptors as there + * are more possible fields in the superblock that can fit in a bitfield on a + * 32 bit platform. The XFS_SBS_* values for the current current counters just + * fit. */ +typedef struct xfs_icsb_cnts { + uint64_t icsb_fdblocks; + uint64_t icsb_ifree; + uint64_t icsb_icount; + unsigned long icsb_flags; +} xfs_icsb_cnts_t; + +#define XFS_ICSB_FLAG_LOCK (1 << 0) /* counter lock bit */ + +#define XFS_ICSB_LAZY_COUNT (1 << 1) /* accuracy not needed */ + +extern int xfs_icsb_init_counters(struct xfs_mount *); +extern void xfs_icsb_reinit_counters(struct xfs_mount *); +extern void xfs_icsb_destroy_counters(struct xfs_mount *); +extern void xfs_icsb_sync_counters(struct xfs_mount *, int); +extern void xfs_icsb_sync_counters_locked(struct xfs_mount *, int); -typedef int (*xfs_ioinit_t)(struct vfs *, - struct xfs_mount_args *, int); -typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, - xfs_fileoff_t, xfs_filblks_t, int, - xfs_fsblock_t *, xfs_extlen_t, - struct xfs_bmbt_irec *, int *, - struct xfs_bmap_free *); -typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *); -typedef int (*xfs_iomap_write_direct_t)( - void *, xfs_off_t, size_t, int, - struct xfs_bmbt_irec *, int *, int); -typedef int (*xfs_iomap_write_delay_t)( - void *, xfs_off_t, size_t, int, - struct xfs_bmbt_irec *, int *); -typedef int (*xfs_iomap_write_allocate_t)( - void *, xfs_off_t, size_t, - struct xfs_bmbt_irec *, int *); -typedef int (*xfs_iomap_write_unwritten_t)( - void *, xfs_off_t, size_t); -typedef uint (*xfs_lck_map_shared_t)(void *); -typedef void (*xfs_lock_t)(void *, uint); -typedef void (*xfs_lock_demote_t)(void *, uint); -typedef int (*xfs_lock_nowait_t)(void *, uint); -typedef void (*xfs_unlk_t)(void *, unsigned int); -typedef xfs_fsize_t (*xfs_size_t)(void *); -typedef xfs_fsize_t (*xfs_iodone_t)(struct vfs *); - -typedef struct xfs_ioops { - xfs_ioinit_t xfs_ioinit; - xfs_bmapi_t xfs_bmapi_func; - xfs_bmap_eof_t xfs_bmap_eof_func; - xfs_iomap_write_direct_t xfs_iomap_write_direct; - xfs_iomap_write_delay_t xfs_iomap_write_delay; - xfs_iomap_write_allocate_t xfs_iomap_write_allocate; - xfs_iomap_write_unwritten_t xfs_iomap_write_unwritten; - xfs_lock_t xfs_ilock; - xfs_lck_map_shared_t xfs_lck_map_shared; - xfs_lock_demote_t xfs_ilock_demote; - xfs_lock_nowait_t xfs_ilock_nowait; - xfs_unlk_t xfs_unlock; - xfs_size_t xfs_size_func; - xfs_iodone_t xfs_iodone; -} xfs_ioops_t; - -#define XFS_IOINIT(vfsp, args, flags) \ - (*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags) -#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist) \ - (*(mp)->m_io_ops.xfs_bmapi_func) \ - (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist) -#define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \ - (*(mp)->m_io_ops.xfs_bmap_eof_func) \ - ((io)->io_obj, endoff, whichfork, eof) -#define XFS_IOMAP_WRITE_DIRECT(mp, io, offset, count, flags, mval, nmap, found)\ - (*(mp)->m_io_ops.xfs_iomap_write_direct) \ - ((io)->io_obj, offset, count, flags, mval, nmap, found) -#define XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, flags, mval, nmap) \ - (*(mp)->m_io_ops.xfs_iomap_write_delay) \ - ((io)->io_obj, offset, count, flags, mval, nmap) -#define XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count, mval, nmap) \ - (*(mp)->m_io_ops.xfs_iomap_write_allocate) \ - ((io)->io_obj, offset, count, mval, nmap) -#define XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count) \ - (*(mp)->m_io_ops.xfs_iomap_write_unwritten) \ - ((io)->io_obj, offset, count) -#define XFS_LCK_MAP_SHARED(mp, io) \ - (*(mp)->m_io_ops.xfs_lck_map_shared)((io)->io_obj) -#define XFS_ILOCK(mp, io, mode) \ - (*(mp)->m_io_ops.xfs_ilock)((io)->io_obj, mode) -#define XFS_ILOCK_NOWAIT(mp, io, mode) \ - (*(mp)->m_io_ops.xfs_ilock_nowait)((io)->io_obj, mode) -#define XFS_IUNLOCK(mp, io, mode) \ - (*(mp)->m_io_ops.xfs_unlock)((io)->io_obj, mode) -#define XFS_ILOCK_DEMOTE(mp, io, mode) \ - (*(mp)->m_io_ops.xfs_ilock_demote)((io)->io_obj, mode) -#define XFS_SIZE(mp, io) \ - (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj) -#define XFS_IODONE(vfsp) \ - (*(mp)->m_io_ops.xfs_iodone)(vfsp) +#else +#define xfs_icsb_init_counters(mp) (0) +#define xfs_icsb_destroy_counters(mp) do { } while (0) +#define xfs_icsb_reinit_counters(mp) do { } while (0) +#define xfs_icsb_sync_counters(mp, flags) do { } while (0) +#define xfs_icsb_sync_counters_locked(mp, flags) do { } while (0) +#endif +typedef struct xfs_ail { + struct list_head xa_ail; + uint xa_gen; + struct task_struct *xa_task; + xfs_lsn_t xa_target; +} xfs_ail_t; typedef struct xfs_mount { - bhv_desc_t m_bhv; /* vfs xfs behavior */ + struct super_block *m_super; xfs_tid_t m_tid; /* next unused tid for fs */ - AIL_LOCK_T m_ail_lock; /* fs AIL mutex */ - xfs_ail_entry_t m_ail; /* fs active log item list */ - uint m_ail_gen; /* fs AIL generation count */ + spinlock_t m_ail_lock; /* fs AIL mutex */ + xfs_ail_t m_ail; /* fs active log item list */ xfs_sb_t m_sb; /* copy of fs superblock */ - lock_t m_sb_lock; /* sb counter mutex */ + spinlock_t m_sb_lock; /* sb counter lock */ struct xfs_buf *m_sb_bp; /* buffer for superblock */ char *m_fsname; /* filesystem name */ int m_fsname_len; /* strlen of fs name */ @@ -284,10 +245,8 @@ typedef struct xfs_mount { int m_bsize; /* fs logical block size */ xfs_agnumber_t m_agfrotor; /* last ag where space found */ xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ - lock_t m_agirotor_lock;/* .. and lock protecting it */ + spinlock_t m_agirotor_lock;/* .. and lock protecting it */ xfs_agnumber_t m_maxagi; /* highest inode alloc group */ - uint m_ihsize; /* size of next field */ - struct xfs_ihash *m_ihash; /* fs private inode hash table*/ struct xfs_inode *m_inodes; /* active inode list */ struct list_head m_del_inodes; /* inodes to reclaim */ mutex_t m_ilock; /* inode list mutex */ @@ -308,13 +267,10 @@ typedef struct xfs_mount { xfs_buftarg_t *m_ddev_targp; /* saves taking the address */ xfs_buftarg_t *m_logdev_targp;/* ptr to log device */ xfs_buftarg_t *m_rtdev_targp; /* ptr to rt device */ -#define m_dev m_ddev_targp->pbr_dev - __uint8_t m_dircook_elog; /* log d-cookie entry bits */ __uint8_t m_blkbit_log; /* blocklog + NBBY */ __uint8_t m_blkbb_log; /* blocklog - BBSHIFT */ __uint8_t m_agno_log; /* log #ag's */ __uint8_t m_agino_log; /* #bits for agino in inum */ - __uint8_t m_nreadaheads; /* #readahead buffers */ __uint16_t m_inode_cluster_size;/* min inode buf size */ uint m_blockmask; /* sb_blocksize-1 */ uint m_blockwsize; /* sb_blocksize in words */ @@ -330,7 +286,7 @@ typedef struct xfs_mount { uint m_in_maxlevels; /* XFS_IN_MAXLEVELS */ struct xfs_perag *m_perag; /* per-ag accounting info */ struct rw_semaphore m_peraglock; /* lock for m_perag (pointer) */ - sema_t m_growlock; /* growfs mutex */ + struct mutex m_growlock; /* growfs mutex */ int m_fixedfsid[2]; /* unchanged for life of FS */ uint m_dmevmask; /* DMI events for this FS */ __uint64_t m_flags; /* global mount flags */ @@ -352,15 +308,14 @@ typedef struct xfs_mount { #endif int m_dalign; /* stripe unit */ int m_swidth; /* stripe width */ - int m_sinoalign; /* stripe unit inode alignmnt */ + int m_sinoalign; /* stripe unit inode alignment */ int m_attr_magicpct;/* 37% of the blocksize */ int m_dir_magicpct; /* 37% of the dir blocksize */ __uint8_t m_mk_sharedro; /* mark shared ro on unmount */ __uint8_t m_inode_quiesce;/* call quiesce on new inodes. field governed by m_ilock */ __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ - __uint8_t m_dirversion; /* 1 or 2 */ - xfs_dirops_t m_dirops; /* table of dir funcs */ + 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 */ @@ -369,32 +324,43 @@ typedef struct xfs_mount { uint m_chsize; /* size of next field */ struct xfs_chash *m_chash; /* fs private inode per-cluster * hash table */ - struct xfs_dmops m_dm_ops; /* vector of DMI ops */ - struct xfs_qmops m_qm_ops; /* vector of XQM ops */ - struct xfs_ioops m_io_ops; /* vector of I/O ops */ + struct xfs_dmops *m_dm_ops; /* vector of DMI ops */ + struct xfs_qmops *m_qm_ops; /* vector of XQM ops */ atomic_t m_active_trans; /* number trans frozen */ +#ifdef HAVE_PERCPU_SB + xfs_icsb_cnts_t *m_sb_cnts; /* per-cpu superblock counters */ + unsigned long m_icsb_counters; /* disabled per-cpu counters */ + struct notifier_block m_icsb_notifier; /* hotplug cpu notifier */ + struct mutex m_icsb_mutex; /* balancer sync lock */ +#endif + struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ + struct task_struct *m_sync_task; /* generalised sync thread */ + bhv_vfs_sync_work_t m_sync_work; /* work item for VFS_SYNC */ + struct list_head m_sync_list; /* sync thread work item list */ + spinlock_t m_sync_lock; /* work item list lock */ + int m_sync_seq; /* sync thread generation no. */ + wait_queue_head_t m_wait_single_sync_task; + struct vfsmount *m_vfsmount; } xfs_mount_t; /* * Flags for m_flags. */ -#define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops +#define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops must be synchronous except for space allocations */ -#define XFS_MOUNT_INO64 (1ULL << 1) - /* (1ULL << 2) -- currently unused */ +#define XFS_MOUNT_INO64 (1ULL << 1) +#define XFS_MOUNT_DMAPI (1ULL << 2) /* dmapi is enabled */ #define XFS_MOUNT_WAS_CLEAN (1ULL << 3) #define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem operations, typically for disk errors in metadata */ -#define XFS_MOUNT_NOATIME (1ULL << 5) /* don't modify inode access - times on reads */ #define XFS_MOUNT_RETERR (1ULL << 6) /* return alignment errors to user */ #define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment allocations */ -#define XFS_MOUNT_COMPAT_ATTR (1ULL << 8) /* do not use attr2 format */ - /* (1ULL << 9) -- currently unused */ +#define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */ +#define XFS_MOUNT_GRPID (1ULL << 9) /* group-ID assigned from directory */ #define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */ #define XFS_MOUNT_SHARED (1ULL << 11) /* shared mount */ #define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */ @@ -402,16 +368,21 @@ typedef struct xfs_mount { /* osyncisdsync is now default*/ #define XFS_MOUNT_32BITINODES (1ULL << 14) /* do not create inodes above * 32 bits in size */ - /* (1ULL << 15) -- currently unused */ +#define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */ #define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ #define XFS_MOUNT_BARRIER (1ULL << 17) -#define XFS_MOUNT_IDELETE (1ULL << 18) /* delete empty inode clusters*/ +#define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/ #define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width * allocation */ -#define XFS_MOUNT_IHASHSIZE (1ULL << 20) /* inode hash table size */ +#define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */ #define XFS_MOUNT_DIRSYNC (1ULL << 21) /* synchronous directory ops */ #define XFS_MOUNT_COMPAT_IOSIZE (1ULL << 22) /* don't report large preferred * I/O size in stat() */ +#define XFS_MOUNT_NO_PERCPU_SB (1ULL << 23) /* don't use per-cpu superblock + counters */ +#define XFS_MOUNT_FILESTREAMS (1ULL << 24) /* enable the filestreams + allocator */ +#define XFS_MOUNT_NOATTR2 (1ULL << 25) /* disable use of attr2 format */ /* @@ -436,7 +407,7 @@ typedef struct xfs_mount { /* * Allow large block sizes to be reported to userspace programs if the - * "largeio" mount option is used. + * "largeio" mount option is used. * * If compatibility mode is specified, simply return the basic unit of caching * so that we don't get inefficient read/modify/write I/O from user apps. @@ -463,52 +434,15 @@ xfs_preferred_iosize(xfs_mount_t *mp) #define XFS_LAST_UNMOUNT_WAS_CLEAN(mp) \ ((mp)->m_flags & XFS_MOUNT_WAS_CLEAN) #define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) +void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, + int lnnum); #define xfs_force_shutdown(m,f) \ - VFS_FORCE_SHUTDOWN((XFS_MTOVFS(m)), f, __FILE__, __LINE__) - -/* - * Flags sent to xfs_force_shutdown. - */ -#define XFS_METADATA_IO_ERROR 0x1 -#define XFS_LOG_IO_ERROR 0x2 -#define XFS_FORCE_UMOUNT 0x4 -#define XFS_CORRUPT_INCORE 0x8 /* Corrupt in-memory data structures */ -#define XFS_SHUTDOWN_REMOTE_REQ 0x10 /* Shutdown came from remote cell */ - -/* - * xflags for xfs_syncsub - */ -#define XFS_XSYNC_RELOC 0x01 + xfs_do_force_shutdown(m, f, __FILE__, __LINE__) /* * Flags for xfs_mountfs */ -#define XFS_MFSI_SECOND 0x01 /* Secondary mount -- skip stuff */ -#define XFS_MFSI_CLIENT 0x02 /* Is a client -- skip lots of stuff */ -#define XFS_MFSI_NOUNLINK 0x08 /* Skip unlinked inode processing in */ - /* log recovery */ -#define XFS_MFSI_NO_QUOTACHECK 0x10 /* Skip quotacheck processing */ - -/* - * Macros for getting from mount to vfs and back. - */ -#define XFS_MTOVFS(mp) xfs_mtovfs(mp) -static inline struct vfs *xfs_mtovfs(xfs_mount_t *mp) -{ - return bhvtovfs(&mp->m_bhv); -} - -#define XFS_BHVTOM(bdp) xfs_bhvtom(bdp) -static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp) -{ - return (xfs_mount_t *)BHV_PDATA(bdp); -} - -#define XFS_VFSTOM(vfs) xfs_vfstom(vfs) -static inline xfs_mount_t *xfs_vfstom(vfs_t *vfs) -{ - return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops)); -} +#define XFS_MFSI_QUIET 0x40 /* Be silent if mount errors found */ #define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d) static inline xfs_agnumber_t @@ -527,50 +461,85 @@ xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d) return (xfs_agblock_t) do_div(ld, mp->m_sb.sb_agblocks); } +/* + * perag get/put wrappers for eventual ref counting + */ +static inline xfs_perag_t * +xfs_get_perag(struct xfs_mount *mp, xfs_ino_t ino) +{ + return &mp->m_perag[XFS_INO_TO_AGNO(mp, ino)]; +} + +static inline void +xfs_put_perag(struct xfs_mount *mp, xfs_perag_t *pag) +{ + /* nothing to see here, move along */ +} + +/* + * Per-cpu superblock locking functions + */ +#ifdef HAVE_PERCPU_SB +STATIC_INLINE void +xfs_icsb_lock(xfs_mount_t *mp) +{ + mutex_lock(&mp->m_icsb_mutex); +} + +STATIC_INLINE void +xfs_icsb_unlock(xfs_mount_t *mp) +{ + mutex_unlock(&mp->m_icsb_mutex); +} +#else +#define xfs_icsb_lock(mp) +#define xfs_icsb_unlock(mp) +#endif + /* * This structure is for use by the xfs_mod_incore_sb_batch() routine. + * xfs_growfs can specify a few fields which are more than int limit */ typedef struct xfs_mod_sb { xfs_sb_field_t msb_field; /* Field to modify, see below */ - int msb_delta; /* Change to make to specified field */ + int64_t msb_delta; /* Change to make to specified field */ } xfs_mod_sb_t; -#define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock), PINOD) +#define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock)) #define XFS_MOUNT_IUNLOCK(mp) mutex_unlock(&((mp)->m_ilock)) -#define XFS_SB_LOCK(mp) mutex_spinlock(&(mp)->m_sb_lock) -#define XFS_SB_UNLOCK(mp,s) mutex_spinunlock(&(mp)->m_sb_lock,(s)) -extern xfs_mount_t *xfs_mount_init(void); -extern void xfs_mod_sb(xfs_trans_t *, __int64_t); extern int xfs_log_sbcount(xfs_mount_t *, uint); -extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv); -extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, int); +extern int xfs_mountfs(xfs_mount_t *mp); extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); -extern int xfs_unmountfs(xfs_mount_t *, struct cred *); -extern void xfs_unmountfs_close(xfs_mount_t *, struct cred *); +extern void xfs_unmountfs(xfs_mount_t *); extern int xfs_unmountfs_writesb(xfs_mount_t *); extern int xfs_unmount_flush(xfs_mount_t *, int); -extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int, int); +extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int); +extern int xfs_mod_incore_sb_unlocked(xfs_mount_t *, xfs_sb_field_t, + int64_t, int); extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, uint, int); extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); -extern int xfs_readsb(xfs_mount_t *mp); +extern int xfs_readsb(xfs_mount_t *, int); extern void xfs_freesb(xfs_mount_t *); -extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int); -extern int xfs_syncsub(xfs_mount_t *, int, int, int *); -extern int xfs_sync_inodes(xfs_mount_t *, int, int, int *); -extern xfs_agnumber_t xfs_initialize_perag(struct vfs *, xfs_mount_t *, - xfs_agnumber_t); -extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t); +extern int xfs_fs_writable(xfs_mount_t *); +extern int xfs_syncsub(xfs_mount_t *, int, int *); +extern int xfs_sync_inodes(xfs_mount_t *, int, int *); +extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); -extern struct xfs_dmops xfs_dmcore_stub; -extern struct xfs_qmops xfs_qmcore_stub; -extern struct xfs_ioops xfs_iocore_xfs; +extern int xfs_dmops_get(struct xfs_mount *, struct xfs_mount_args *); +extern void xfs_dmops_put(struct xfs_mount *); +extern int xfs_qmops_get(struct xfs_mount *, struct xfs_mount_args *); +extern void xfs_qmops_put(struct xfs_mount *); -extern int xfs_init(void); -extern void xfs_cleanup(void); +extern struct xfs_dmops xfs_dmcore_xfs; #endif /* __KERNEL__ */ +extern void xfs_mod_sb(struct xfs_trans *, __int64_t); +extern xfs_agnumber_t xfs_initialize_perag(struct xfs_mount *, xfs_agnumber_t); +extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *); +extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t); + #endif /* __XFS_MOUNT_H__ */ diff --git a/include/xfs_quota.h b/include/xfs_quota.h index 82a08baf4..12c4ec775 100644 --- a/include/xfs_quota.h +++ b/include/xfs_quota.h @@ -31,7 +31,7 @@ typedef __uint32_t xfs_dqid_t; /* - * Eventhough users may not have quota limits occupying all 64-bits, + * Even though users may not have quota limits occupying all 64-bits, * they may need 64-bit accounting. Hence, 64-bit quota-counters, * and quota-limits. This is a waste in the common case, but hey ... */ @@ -154,10 +154,11 @@ typedef struct xfs_qoff_logformat { #define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD) #define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) -#define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD) #define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT) #define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT) #define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT) +#define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD) +#define XFS_IS_OQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_OQUOTA_ENFD) /* * Incore only flags for quotaoff - these bits get cleared when quota(s) @@ -196,10 +197,11 @@ typedef struct xfs_qoff_logformat { #define XFS_QMOPT_QUOTAOFF 0x0000080 /* quotas are being turned off */ #define XFS_QMOPT_UMOUNTING 0x0000100 /* filesys is being unmounted */ #define XFS_QMOPT_DOLOG 0x0000200 /* log buf changes (in quotacheck) */ -#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */ +#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if needed */ #define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */ -#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot, if damaged. */ +#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */ #define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */ +#define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */ /* * flags to xfs_trans_mod_dquot to indicate which field needs to be @@ -246,7 +248,7 @@ typedef struct xfs_qoff_logformat { #ifdef __KERNEL__ /* * This check is done typically without holding the inode lock; - * that may seem racey, but it is harmless in the context that it is used. + * that may seem racy, but it is harmless in the context that it is used. * The inode cannot go inactive as long a reference is kept, and * therefore if dquot(s) were attached, they'll stay consistent. * If, for example, the ownership of the inode changes while @@ -280,8 +282,6 @@ typedef struct xfs_qoff_logformat { XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\ XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\ XFS_GQUOTA_ACCT) -#define XFS_MOUNT_QUOTA_MASK (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \ - XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE) /* @@ -330,12 +330,12 @@ typedef struct xfs_dqtrxops { } xfs_dqtrxops_t; #define XFS_DQTRXOP(mp, tp, op, args...) \ - ((mp)->m_qm_ops.xfs_dqtrxops ? \ - ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : 0) + ((mp)->m_qm_ops->xfs_dqtrxops ? \ + ((mp)->m_qm_ops->xfs_dqtrxops->op)(tp, ## args) : 0) #define XFS_DQTRXOP_VOID(mp, tp, op, args...) \ - ((mp)->m_qm_ops.xfs_dqtrxops ? \ - ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : (void)0) + ((mp)->m_qm_ops->xfs_dqtrxops ? \ + ((mp)->m_qm_ops->xfs_dqtrxops->op)(tp, ## args) : (void)0) #define XFS_TRANS_DUP_DQINFO(mp, otp, ntp) \ XFS_DQTRXOP_VOID(mp, otp, qo_dup_dqinfo, ntp) @@ -364,7 +364,7 @@ typedef struct xfs_dqtrxops { extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); extern int xfs_mount_reset_sbqflags(struct xfs_mount *); -extern struct bhv_vfsops xfs_qmops; +extern struct xfs_qmops xfs_qmcore_xfs; #endif /* __KERNEL__ */ diff --git a/include/xfs_rtalloc.h b/include/xfs_rtalloc.h index ae832b121..8d8dcd215 100644 --- a/include/xfs_rtalloc.h +++ b/include/xfs_rtalloc.h @@ -21,10 +21,9 @@ struct xfs_mount; struct xfs_trans; -#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) - /* Min and max rt extent sizes, specified in bytes */ #define XFS_MAX_RTEXTSIZE (1024 * 1024 * 1024) /* 1GB */ +#define XFS_DFL_RTEXTSIZE (64 * 1024) /* 64KB */ #define XFS_MIN_RTEXTSIZE (4 * 1024) /* 4KB */ /* @@ -132,24 +131,6 @@ xfs_rtpick_extent( xfs_extlen_t len, /* allocation length (rtextents) */ xfs_rtblock_t *pick); /* result rt extent */ -/* - * Debug code: print out the value of a range in the bitmap. - */ -void -xfs_rtprint_range( - struct xfs_mount *mp, /* file system mount structure */ - struct xfs_trans *tp, /* transaction pointer */ - xfs_rtblock_t start, /* starting block to print */ - xfs_extlen_t len); /* length to print */ - -/* - * Debug code: print the summary file. - */ -void -xfs_rtprint_summary( - struct xfs_mount *mp, /* file system mount structure */ - struct xfs_trans *tp); /* transaction pointer */ - /* * Grow the realtime area of the filesystem. */ diff --git a/include/xfs_sb.h b/include/xfs_sb.h index 41c6e3fbf..1e864893a 100644 --- a/include/xfs_sb.h +++ b/include/xfs_sb.h @@ -46,7 +46,7 @@ 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_BORGBIT 0x4000 /* ASCII only case-insens. */ #define XFS_SB_VERSION_MOREBITSBIT 0x8000 #define XFS_SB_VERSION_OKSASHFBITS \ (XFS_SB_VERSION_EXTFLGBIT | \ @@ -62,10 +62,6 @@ struct xfs_mount; XFS_SB_VERSION_LOGV2BIT | \ XFS_SB_VERSION_SECTORBIT | \ XFS_SB_VERSION_MOREBITSBIT) -#define XFS_SB_VERSION_OKSASHBITS \ - (XFS_SB_VERSION_NUMBITS | \ - XFS_SB_VERSION_REALFBITS | \ - XFS_SB_VERSION_OKSASHFBITS) #define XFS_SB_VERSION_OKREALBITS \ (XFS_SB_VERSION_NUMBITS | \ XFS_SB_VERSION_OKREALFBITS | \ @@ -79,26 +75,26 @@ struct xfs_mount; * These defines represent bits in sb_features2. */ #define XFS_SB_VERSION2_REALFBITS 0x00ffffff /* Mask: features */ -#define XFS_SB_VERSION2_DONOTUSEBIT1 0x00000001 -#define XFS_SB_VERSION2_LAZYSBCOUNTBIT 0x00000002 /* Lazy SB counters */ -#define XFS_SB_VERSION2_DONOTUSEBIT2 0x00000004 +#define XFS_SB_VERSION2_RESERVED1BIT 0x00000001 +#define XFS_SB_VERSION2_LAZYSBCOUNTBIT 0x00000002 /* Superblk counters */ +#define XFS_SB_VERSION2_RESERVED4BIT 0x00000004 #define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ -#define XFS_SB_VERSION2_PARENTBIT 0x00000010 /* Parent pointers */ -#define XFS_SB_VERSION2_SASHFBITS 0xff000000 /* Mask: features that - require changing - PROM and SASH */ +#define XFS_SB_VERSION2_PARENTBIT 0x00000010 /* parent pointers */ #define XFS_SB_VERSION2_OKREALFBITS \ - (XFS_SB_VERSION2_ATTR2BIT | \ - XFS_SB_VERSION2_LAZYSBCOUNTBIT) + (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \ + XFS_SB_VERSION2_ATTR2BIT) #define XFS_SB_VERSION2_OKSASHFBITS \ (0) #define XFS_SB_VERSION2_OKREALBITS \ (XFS_SB_VERSION2_OKREALFBITS | \ XFS_SB_VERSION2_OKSASHFBITS ) -typedef struct xfs_sb -{ +/* + * Superblock - in core version. Must match the ondisk version below. + * Must be padded to 64 bit alignment. + */ +typedef struct xfs_sb { __uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */ __uint32_t sb_blocksize; /* logical block size, bytes */ xfs_drfsbno_t sb_dblocks; /* number of data blocks */ @@ -153,9 +149,88 @@ typedef struct xfs_sb __uint16_t sb_logsectsize; /* sector size for the log, bytes */ __uint32_t sb_logsunit; /* stripe unit size for the log */ __uint32_t sb_features2; /* additional feature bits */ - __uint32_t sb_bad_features2; /* unusable space */ + + /* + * bad features2 field as a result of failing to pad the sb + * structure to 64 bits. Some machines will be using this field + * for features2 bits. Easiest just to mark it bad and not use + * it for anything else. + */ + __uint32_t sb_bad_features2; + + /* must be padded to 64 bit alignment */ } xfs_sb_t; +/* + * Superblock - on disk version. Must match the in core version above. + * Must be padded to 64 bit alignment. + */ +typedef struct xfs_dsb { + __be32 sb_magicnum; /* magic number == XFS_SB_MAGIC */ + __be32 sb_blocksize; /* logical block size, bytes */ + __be64 sb_dblocks; /* number of data blocks */ + __be64 sb_rblocks; /* number of realtime blocks */ + __be64 sb_rextents; /* number of realtime extents */ + uuid_t sb_uuid; /* file system unique id */ + __be64 sb_logstart; /* starting block of log if internal */ + __be64 sb_rootino; /* root inode number */ + __be64 sb_rbmino; /* bitmap inode for realtime extents */ + __be64 sb_rsumino; /* summary inode for rt bitmap */ + __be32 sb_rextsize; /* realtime extent size, blocks */ + __be32 sb_agblocks; /* size of an allocation group */ + __be32 sb_agcount; /* number of allocation groups */ + __be32 sb_rbmblocks; /* number of rt bitmap blocks */ + __be32 sb_logblocks; /* number of log blocks */ + __be16 sb_versionnum; /* header version == XFS_SB_VERSION */ + __be16 sb_sectsize; /* volume sector size, bytes */ + __be16 sb_inodesize; /* inode size, bytes */ + __be16 sb_inopblock; /* inodes per block */ + char sb_fname[12]; /* file system name */ + __u8 sb_blocklog; /* log2 of sb_blocksize */ + __u8 sb_sectlog; /* log2 of sb_sectsize */ + __u8 sb_inodelog; /* log2 of sb_inodesize */ + __u8 sb_inopblog; /* log2 of sb_inopblock */ + __u8 sb_agblklog; /* log2 of sb_agblocks (rounded up) */ + __u8 sb_rextslog; /* log2 of sb_rextents */ + __u8 sb_inprogress; /* mkfs is in progress, don't mount */ + __u8 sb_imax_pct; /* max % of fs for inode space */ + /* statistics */ + /* + * These fields must remain contiguous. If you really + * want to change their layout, make sure you fix the + * code in xfs_trans_apply_sb_deltas(). + */ + __be64 sb_icount; /* allocated inodes */ + __be64 sb_ifree; /* free inodes */ + __be64 sb_fdblocks; /* free data blocks */ + __be64 sb_frextents; /* free realtime extents */ + /* + * End contiguous fields. + */ + __be64 sb_uquotino; /* user quota inode */ + __be64 sb_gquotino; /* group quota inode */ + __be16 sb_qflags; /* quota flags */ + __u8 sb_flags; /* misc. flags */ + __u8 sb_shared_vn; /* shared version number */ + __be32 sb_inoalignmt; /* inode chunk alignment, fsblocks */ + __be32 sb_unit; /* stripe or raid unit */ + __be32 sb_width; /* stripe or raid width */ + __u8 sb_dirblklog; /* log2 of dir block size (fsbs) */ + __u8 sb_logsectlog; /* log2 of the log sector size */ + __be16 sb_logsectsize; /* sector size for the log, bytes */ + __be32 sb_logsunit; /* stripe unit size for the log */ + __be32 sb_features2; /* additional feature bits */ + /* + * bad features2 field as a result of failing to pad the sb + * structure to 64 bits. Some machines will be using this field + * for features2 bits. Easiest just to mark it bad and not use + * it for anything else. + */ + __be32 sb_bad_features2; + + /* must be padded to 64 bit alignment */ +} xfs_dsb_t; + /* * Sequence number values for the fields. */ @@ -197,13 +272,15 @@ typedef enum { #define XFS_SB_IFREE XFS_SB_MVAL(IFREE) #define XFS_SB_FDBLOCKS XFS_SB_MVAL(FDBLOCKS) #define XFS_SB_FEATURES2 XFS_SB_MVAL(FEATURES2) +#define XFS_SB_BAD_FEATURES2 XFS_SB_MVAL(BAD_FEATURES2) #define XFS_SB_NUM_BITS ((int)XFS_SBS_FIELDCOUNT) #define XFS_SB_ALL_BITS ((1LL << XFS_SB_NUM_BITS) - 1) #define XFS_SB_MOD_BITS \ (XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \ XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \ XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \ - XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2) + XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2 | \ + XFS_SB_BAD_FEATURES2) /* @@ -220,7 +297,6 @@ typedef enum { #define XFS_SB_VERSION_NUM(sbp) ((sbp)->sb_versionnum & XFS_SB_VERSION_NUMBITS) -#define XFS_SB_GOOD_VERSION(sbp) xfs_sb_good_version(sbp) #ifdef __KERNEL__ static inline int xfs_sb_good_version(xfs_sb_t *sbp) { @@ -246,13 +322,15 @@ static inline int xfs_sb_good_version(xfs_sb_t *sbp) } #endif /* __KERNEL__ */ -#define XFS_SB_GOOD_SASH_VERSION(sbp) \ - ((((sbp)->sb_versionnum >= XFS_SB_VERSION_1) && \ - ((sbp)->sb_versionnum <= XFS_SB_VERSION_3)) || \ - ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ - !((sbp)->sb_versionnum & ~XFS_SB_VERSION_OKSASHBITS))) +/* + * Detect a mismatched features2 field. Older kernels read/wrote + * this into the wrong slot, so to be safe we keep them in sync. + */ +static inline int xfs_sb_has_mismatched_features2(xfs_sb_t *sbp) +{ + return (sbp->sb_bad_features2 != sbp->sb_features2); +} -#define XFS_SB_VERSION_TONEW(v) xfs_sb_version_tonew(v) static inline unsigned xfs_sb_version_tonew(unsigned v) { return ((((v) == XFS_SB_VERSION_1) ? \ @@ -263,7 +341,6 @@ static inline unsigned xfs_sb_version_tonew(unsigned v) XFS_SB_VERSION_4); } -#define XFS_SB_VERSION_TOOLD(v) xfs_sb_version_toold(v) static inline unsigned xfs_sb_version_toold(unsigned v) { return (((v) & (XFS_SB_VERSION_QUOTABIT | XFS_SB_VERSION_ALIGNBIT)) ? \ @@ -275,7 +352,6 @@ static inline unsigned xfs_sb_version_toold(unsigned v) XFS_SB_VERSION_1))); } -#define XFS_SB_VERSION_HASATTR(sbp) xfs_sb_version_hasattr(sbp) static inline int xfs_sb_version_hasattr(xfs_sb_t *sbp) { return ((sbp)->sb_versionnum == XFS_SB_VERSION_2) || \ @@ -284,7 +360,6 @@ static inline int xfs_sb_version_hasattr(xfs_sb_t *sbp) ((sbp)->sb_versionnum & XFS_SB_VERSION_ATTRBIT)); } -#define XFS_SB_VERSION_ADDATTR(sbp) xfs_sb_version_addattr(sbp) static inline void xfs_sb_version_addattr(xfs_sb_t *sbp) { (sbp)->sb_versionnum = (((sbp)->sb_versionnum == XFS_SB_VERSION_1) ? \ @@ -294,7 +369,6 @@ static inline void xfs_sb_version_addattr(xfs_sb_t *sbp) (XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT))); } -#define XFS_SB_VERSION_HASNLINK(sbp) xfs_sb_version_hasnlink(sbp) static inline int xfs_sb_version_hasnlink(xfs_sb_t *sbp) { return ((sbp)->sb_versionnum == XFS_SB_VERSION_3) || \ @@ -302,7 +376,6 @@ static inline int xfs_sb_version_hasnlink(xfs_sb_t *sbp) ((sbp)->sb_versionnum & XFS_SB_VERSION_NLINKBIT)); } -#define XFS_SB_VERSION_ADDNLINK(sbp) xfs_sb_version_addnlink(sbp) static inline void xfs_sb_version_addnlink(xfs_sb_t *sbp) { (sbp)->sb_versionnum = ((sbp)->sb_versionnum <= XFS_SB_VERSION_2 ? \ @@ -310,108 +383,57 @@ static inline void xfs_sb_version_addnlink(xfs_sb_t *sbp) ((sbp)->sb_versionnum | XFS_SB_VERSION_NLINKBIT)); } -#define XFS_SB_VERSION_HASQUOTA(sbp) xfs_sb_version_hasquota(sbp) static inline int xfs_sb_version_hasquota(xfs_sb_t *sbp) { return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ ((sbp)->sb_versionnum & XFS_SB_VERSION_QUOTABIT); } -#define XFS_SB_VERSION_ADDQUOTA(sbp) xfs_sb_version_addquota(sbp) static inline void xfs_sb_version_addquota(xfs_sb_t *sbp) { (sbp)->sb_versionnum = \ (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 ? \ ((sbp)->sb_versionnum | XFS_SB_VERSION_QUOTABIT) : \ - (XFS_SB_VERSION_TONEW((sbp)->sb_versionnum) | \ + (xfs_sb_version_tonew((sbp)->sb_versionnum) | \ XFS_SB_VERSION_QUOTABIT)); } -#define XFS_SB_VERSION_HASALIGN(sbp) xfs_sb_version_hasalign(sbp) static inline int xfs_sb_version_hasalign(xfs_sb_t *sbp) { return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ ((sbp)->sb_versionnum & XFS_SB_VERSION_ALIGNBIT); } -#define XFS_SB_VERSION_SUBALIGN(sbp) xfs_sb_version_subalign(sbp) -static inline void xfs_sb_version_subalign(xfs_sb_t *sbp) -{ - (sbp)->sb_versionnum = \ - XFS_SB_VERSION_TOOLD((sbp)->sb_versionnum & ~XFS_SB_VERSION_ALIGNBIT); -} - -#define XFS_SB_VERSION_HASDALIGN(sbp) xfs_sb_version_hasdalign(sbp) static inline int xfs_sb_version_hasdalign(xfs_sb_t *sbp) { return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ ((sbp)->sb_versionnum & XFS_SB_VERSION_DALIGNBIT); } -#define XFS_SB_VERSION_ADDDALIGN(sbp) xfs_sb_version_adddalign(sbp) -static inline int xfs_sb_version_adddalign(xfs_sb_t *sbp) -{ - return (sbp)->sb_versionnum = \ - ((sbp)->sb_versionnum | XFS_SB_VERSION_DALIGNBIT); -} - -#define XFS_SB_VERSION_HASSHARED(sbp) xfs_sb_version_hasshared(sbp) static inline int xfs_sb_version_hasshared(xfs_sb_t *sbp) { return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ ((sbp)->sb_versionnum & XFS_SB_VERSION_SHAREDBIT); } -#define XFS_SB_VERSION_ADDSHARED(sbp) xfs_sb_version_addshared(sbp) -static inline int xfs_sb_version_addshared(xfs_sb_t *sbp) -{ - return (sbp)->sb_versionnum = \ - ((sbp)->sb_versionnum | XFS_SB_VERSION_SHAREDBIT); -} - -#define XFS_SB_VERSION_SUBSHARED(sbp) xfs_sb_version_subshared(sbp) -static inline int xfs_sb_version_subshared(xfs_sb_t *sbp) -{ - return (sbp)->sb_versionnum = \ - ((sbp)->sb_versionnum & ~XFS_SB_VERSION_SHAREDBIT); -} - -#define XFS_SB_VERSION_HASDIRV2(sbp) xfs_sb_version_hasdirv2(sbp) static inline int xfs_sb_version_hasdirv2(xfs_sb_t *sbp) { return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ ((sbp)->sb_versionnum & XFS_SB_VERSION_DIRV2BIT); } -#define XFS_SB_VERSION_HASLOGV2(sbp) xfs_sb_version_haslogv2(sbp) static inline int xfs_sb_version_haslogv2(xfs_sb_t *sbp) { return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ ((sbp)->sb_versionnum & XFS_SB_VERSION_LOGV2BIT); } -#define XFS_SB_VERSION_HASEXTFLGBIT(sbp) xfs_sb_version_hasextflgbit(sbp) static inline int xfs_sb_version_hasextflgbit(xfs_sb_t *sbp) { return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ ((sbp)->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT); } -#define XFS_SB_VERSION_ADDEXTFLGBIT(sbp) xfs_sb_version_addextflgbit(sbp) -static inline int xfs_sb_version_addextflgbit(xfs_sb_t *sbp) -{ - return (sbp)->sb_versionnum = \ - ((sbp)->sb_versionnum | XFS_SB_VERSION_EXTFLGBIT); -} - -#define XFS_SB_VERSION_SUBEXTFLGBIT(sbp) xfs_sb_version_subextflgbit(sbp) -static inline int xfs_sb_version_subextflgbit(xfs_sb_t *sbp) -{ - return (sbp)->sb_versionnum = \ - ((sbp)->sb_versionnum & ~XFS_SB_VERSION_EXTFLGBIT); -} - -#define XFS_SB_VERSION_HASSECTOR(sbp) xfs_sb_version_hassector(sbp) static inline int xfs_sb_version_hassector(xfs_sb_t *sbp) { return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ @@ -424,7 +446,6 @@ static inline int xfs_sb_version_hasasciici(xfs_sb_t *sbp) (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) { return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ @@ -437,25 +458,22 @@ static inline int xfs_sb_version_hasmorebits(xfs_sb_t *sbp) * For example, for a bit defined as XFS_SB_VERSION2_FUNBIT, has a macro: * * SB_VERSION_HASFUNBIT(xfs_sb_t *sbp) - * ((XFS_SB_VERSION_HASMOREBITS(sbp) && + * ((xfs_sb_version_hasmorebits(sbp) && * ((sbp)->sb_features2 & XFS_SB_VERSION2_FUNBIT) */ -#define XFS_SB_VERSION_LAZYSBCOUNT(sbp) xfs_sb_version_haslazysbcount(sbp) static inline int xfs_sb_version_haslazysbcount(xfs_sb_t *sbp) { - return (XFS_SB_VERSION_HASMOREBITS(sbp) && + return (xfs_sb_version_hasmorebits(sbp) && \ ((sbp)->sb_features2 & XFS_SB_VERSION2_LAZYSBCOUNTBIT)); } -#define XFS_SB_VERSION_HASATTR2(sbp) xfs_sb_version_hasattr2(sbp) static inline int xfs_sb_version_hasattr2(xfs_sb_t *sbp) { - return (XFS_SB_VERSION_HASMOREBITS(sbp)) && \ + return (xfs_sb_version_hasmorebits(sbp)) && \ ((sbp)->sb_features2 & XFS_SB_VERSION2_ATTR2BIT); } -#define XFS_SB_VERSION_ADDATTR2(sbp) xfs_sb_version_addattr2(sbp) static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp) { ((sbp)->sb_versionnum = \ @@ -464,13 +482,20 @@ static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp) ((sbp)->sb_features2 | XFS_SB_VERSION2_ATTR2BIT))); } +static inline void xfs_sb_version_removeattr2(xfs_sb_t *sbp) +{ + sbp->sb_features2 &= ~XFS_SB_VERSION2_ATTR2BIT; + if (!sbp->sb_features2) + sbp->sb_versionnum &= ~XFS_SB_VERSION_MOREBITSBIT; +} + /* * end of superblock version macros */ #define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */ #define XFS_SB_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_SB_DADDR) -#define XFS_BUF_TO_SBP(bp) ((xfs_sb_t *)XFS_BUF_PTR(bp)) +#define XFS_BUF_TO_SBP(bp) ((xfs_dsb_t *)XFS_BUF_PTR(bp)) #define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d)) #define XFS_DADDR_TO_FSB(mp,d) XFS_AGB_TO_FSB(mp, \ @@ -482,15 +507,6 @@ static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp) * File system sector to basic block conversions. */ #define XFS_FSS_TO_BB(mp,sec) ((sec) << (mp)->m_sectbb_log) -#define XFS_BB_TO_FSS(mp,bb) \ - (((bb) + (XFS_FSS_TO_BB(mp,1) - 1)) >> (mp)->m_sectbb_log) -#define XFS_BB_TO_FSST(mp,bb) ((bb) >> (mp)->m_sectbb_log) - -/* - * File system sector to byte conversions. - */ -#define XFS_FSS_TO_B(mp,sectno) ((xfs_fsize_t)(sectno) << (mp)->m_sb.sb_sectlog) -#define XFS_B_TO_FSST(mp,b) (((__uint64_t)(b)) >> (mp)->m_sb.sb_sectlog) /* * File system block to basic block conversions. diff --git a/include/xfs_trans.h b/include/xfs_trans.h index aaee33bb6..1d89d50a5 100644 --- a/include/xfs_trans.h +++ b/include/xfs_trans.h @@ -18,6 +18,8 @@ #ifndef __XFS_TRANS_H__ #define __XFS_TRANS_H__ +struct xfs_log_item; + /* * This is the structure written in the log at the head of * every transaction. It identifies the type and id of the @@ -39,13 +41,9 @@ typedef struct xfs_trans_header { /* * Log item types. */ -#define XFS_LI_5_3_BUF 0x1234 /* v1 bufs, 1-block inode buffers */ -#define XFS_LI_5_3_INODE 0x1235 /* 1-block inode buffers */ #define XFS_LI_EFI 0x1236 #define XFS_LI_EFD 0x1237 #define XFS_LI_IUNLINK 0x1238 -#define XFS_LI_6_1_INODE 0x1239 /* 4K non-aligned inode bufs */ -#define XFS_LI_6_1_BUF 0x123a /* v1, 4K inode buffers */ #define XFS_LI_INODE 0x123b /* aligned ino chunks, var-size ibufs */ #define XFS_LI_BUF 0x123c /* v2 bufs, variable sized inode bufs */ #define XFS_LI_DQUOT 0x123d @@ -102,83 +100,6 @@ typedef struct xfs_trans_header { #define XFS_TRANS_TYPE_MAX 41 /* new transaction types need to be reflected in xfs_logprint(8) */ - -#ifdef __KERNEL__ -struct xfs_buf; -struct xfs_buftarg; -struct xfs_efd_log_item; -struct xfs_efi_log_item; -struct xfs_inode; -struct xfs_item_ops; -struct xfs_log_iovec; -struct xfs_log_item; -struct xfs_log_item_desc; -struct xfs_mount; -struct xfs_trans; -struct xfs_dquot_acct; - -typedef struct xfs_ail_entry { - struct xfs_log_item *ail_forw; /* AIL forw pointer */ - struct xfs_log_item *ail_back; /* AIL back pointer */ -} xfs_ail_entry_t; - -typedef struct xfs_log_item { - xfs_ail_entry_t li_ail; /* AIL pointers */ - xfs_lsn_t li_lsn; /* last on-disk lsn */ - struct xfs_log_item_desc *li_desc; /* ptr to current desc*/ - struct xfs_mount *li_mountp; /* ptr to fs mount */ - uint li_type; /* item type */ - uint li_flags; /* misc flags */ - struct xfs_log_item *li_bio_list; /* buffer item list */ - void (*li_cb)(struct xfs_buf *, - struct xfs_log_item *); - /* buffer item iodone */ - /* callback func */ - struct xfs_item_ops *li_ops; /* function list */ -} xfs_log_item_t; - -#define XFS_LI_IN_AIL 0x1 -#define XFS_LI_ABORTED 0x2 - -typedef struct xfs_item_ops { - uint (*iop_size)(xfs_log_item_t *); - void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); - void (*iop_pin)(xfs_log_item_t *); - void (*iop_unpin)(xfs_log_item_t *, int); - void (*iop_unpin_remove)(xfs_log_item_t *, struct xfs_trans *); - uint (*iop_trylock)(xfs_log_item_t *); - void (*iop_unlock)(xfs_log_item_t *); - xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t); - void (*iop_push)(xfs_log_item_t *); - void (*iop_abort)(xfs_log_item_t *); - void (*iop_pushbuf)(xfs_log_item_t *); - void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); -} xfs_item_ops_t; - -#define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip) -#define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp) -#define IOP_PIN(ip) (*(ip)->li_ops->iop_pin)(ip) -#define IOP_UNPIN(ip, flags) (*(ip)->li_ops->iop_unpin)(ip, flags) -#define IOP_UNPIN_REMOVE(ip,tp) (*(ip)->li_ops->iop_unpin_remove)(ip, tp) -#define IOP_TRYLOCK(ip) (*(ip)->li_ops->iop_trylock)(ip) -#define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip) -#define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn) -#define IOP_PUSH(ip) (*(ip)->li_ops->iop_push)(ip) -#define IOP_ABORT(ip) (*(ip)->li_ops->iop_abort)(ip) -#define IOP_PUSHBUF(ip) (*(ip)->li_ops->iop_pushbuf)(ip) -#define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn) - -/* - * Return values for the IOP_TRYLOCK() routines. - */ -#define XFS_ITEM_SUCCESS 0 -#define XFS_ITEM_PINNED 1 -#define XFS_ITEM_LOCKED 2 -#define XFS_ITEM_FLUSHING 3 -#define XFS_ITEM_PUSHBUF 4 - -#endif /* __KERNEL__ */ - /* * This structure is used to track log items associated with * a transaction. It points to the log item and keeps some @@ -187,7 +108,7 @@ typedef struct xfs_item_ops { * once we get to commit processing (see xfs_trans_commit()). */ typedef struct xfs_log_item_desc { - xfs_log_item_t *lid_item; + struct xfs_log_item *lid_item; ushort lid_size; unsigned char lid_flags; unsigned char lid_index; @@ -221,62 +142,52 @@ typedef struct xfs_log_item_chunk { * lic_unused to the right value (0 matches all free). The * lic_descs.lid_index values are set up as each desc is allocated. */ -#define XFS_LIC_INIT(cp) xfs_lic_init(cp) static inline void xfs_lic_init(xfs_log_item_chunk_t *cp) { cp->lic_free = XFS_LIC_FREEMASK; } -#define XFS_LIC_INIT_SLOT(cp,slot) xfs_lic_init_slot(cp, slot) static inline void xfs_lic_init_slot(xfs_log_item_chunk_t *cp, int slot) { cp->lic_descs[slot].lid_index = (unsigned char)(slot); } -#define XFS_LIC_VACANCY(cp) xfs_lic_vacancy(cp) static inline int xfs_lic_vacancy(xfs_log_item_chunk_t *cp) { return cp->lic_free & XFS_LIC_FREEMASK; } -#define XFS_LIC_ALL_FREE(cp) xfs_lic_all_free(cp) static inline void xfs_lic_all_free(xfs_log_item_chunk_t *cp) { cp->lic_free = XFS_LIC_FREEMASK; } -#define XFS_LIC_ARE_ALL_FREE(cp) xfs_lic_are_all_free(cp) static inline int xfs_lic_are_all_free(xfs_log_item_chunk_t *cp) { return ((cp->lic_free & XFS_LIC_FREEMASK) == XFS_LIC_FREEMASK); } -#define XFS_LIC_ISFREE(cp,slot) xfs_lic_isfree(cp,slot) static inline int xfs_lic_isfree(xfs_log_item_chunk_t *cp, int slot) { return (cp->lic_free & (1 << slot)); } -#define XFS_LIC_CLAIM(cp,slot) xfs_lic_claim(cp,slot) static inline void xfs_lic_claim(xfs_log_item_chunk_t *cp, int slot) { cp->lic_free &= ~(1 << slot); } -#define XFS_LIC_RELSE(cp,slot) xfs_lic_relse(cp,slot) static inline void xfs_lic_relse(xfs_log_item_chunk_t *cp, int slot) { cp->lic_free |= 1 << slot; } -#define XFS_LIC_SLOT(cp,slot) xfs_lic_slot(cp,slot) static inline xfs_log_item_desc_t * xfs_lic_slot(xfs_log_item_chunk_t *cp, int slot) { return &(cp->lic_descs[slot]); } -#define XFS_LIC_DESC_TO_SLOT(dp) xfs_lic_desc_to_slot(dp) static inline int xfs_lic_desc_to_slot(xfs_log_item_desc_t *dp) { return (uint)dp->lid_index; @@ -289,7 +200,6 @@ static inline int xfs_lic_desc_to_slot(xfs_log_item_desc_t *dp) * All of this yields the address of the chunk, which is * cast to a chunk pointer. */ -#define XFS_LIC_DESC_TO_CHUNK(dp) xfs_lic_desc_to_chunk(dp) static inline xfs_log_item_chunk_t * xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp) { @@ -298,95 +208,6 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp) (xfs_caddr_t)(((xfs_log_item_chunk_t*)0)->lic_descs)); } -#ifdef __KERNEL__ -/* - * This structure is used to maintain a list of block ranges that have been - * freed in the transaction. The ranges are listed in the perag[] busy list - * between when they're freed and the transaction is committed to disk. - */ - -typedef struct xfs_log_busy_slot { - xfs_agnumber_t lbc_ag; - ushort lbc_idx; /* index in perag.busy[] */ -} xfs_log_busy_slot_t; - -#define XFS_LBC_NUM_SLOTS 31 -typedef struct xfs_log_busy_chunk { - struct xfs_log_busy_chunk *lbc_next; - uint lbc_free; /* free slots bitmask */ - ushort lbc_unused; /* first unused */ - xfs_log_busy_slot_t lbc_busy[XFS_LBC_NUM_SLOTS]; -} xfs_log_busy_chunk_t; - -#define XFS_LBC_MAX_SLOT (XFS_LBC_NUM_SLOTS - 1) -#define XFS_LBC_FREEMASK ((1U << XFS_LBC_NUM_SLOTS) - 1) - -#define XFS_LBC_INIT(cp) ((cp)->lbc_free = XFS_LBC_FREEMASK) -#define XFS_LBC_CLAIM(cp, slot) ((cp)->lbc_free &= ~(1 << (slot))) -#define XFS_LBC_SLOT(cp, slot) (&((cp)->lbc_busy[(slot)])) -#define XFS_LBC_VACANCY(cp) (((cp)->lbc_free) & XFS_LBC_FREEMASK) -#define XFS_LBC_ISFREE(cp, slot) ((cp)->lbc_free & (1 << (slot))) - -/* - * This is the type of function which can be given to xfs_trans_callback() - * to be called upon the transaction's commit to disk. - */ -typedef void (*xfs_trans_callback_t)(struct xfs_trans *, void *); - -/* - * This is the structure maintained for every active transaction. - */ -typedef struct xfs_trans { - unsigned int t_magic; /* magic number */ - xfs_log_callback_t t_logcb; /* log callback struct */ - struct xfs_trans *t_forw; /* async list pointers */ - struct xfs_trans *t_back; /* async list pointers */ - unsigned int t_type; /* transaction type */ - unsigned int t_log_res; /* amt of log space resvd */ - unsigned int t_log_count; /* count for perm log res */ - unsigned int t_blk_res; /* # of blocks resvd */ - unsigned int t_blk_res_used; /* # of resvd blocks used */ - unsigned int t_rtx_res; /* # of rt extents resvd */ - unsigned int t_rtx_res_used; /* # of resvd rt extents used */ - xfs_log_ticket_t t_ticket; /* log mgr ticket */ - sema_t t_sema; /* sema for commit completion */ - xfs_lsn_t t_lsn; /* log seq num of start of - * transaction. */ - xfs_lsn_t t_commit_lsn; /* log seq num of end of - * transaction. */ - struct xfs_mount *t_mountp; /* ptr to fs mount struct */ - struct xfs_dquot_acct *t_dqinfo; /* accting info for dquots */ - xfs_trans_callback_t t_callback; /* transaction callback */ - void *t_callarg; /* callback arg */ - unsigned int t_flags; /* misc flags */ - long t_icount_delta; /* superblock icount change */ - long t_ifree_delta; /* superblock ifree change */ - long t_fdblocks_delta; /* superblock fdblocks chg */ - long t_res_fdblocks_delta; /* on-disk only chg */ - long t_frextents_delta;/* superblock freextents chg*/ - long t_res_frextents_delta; /* on-disk only chg */ - long t_ag_freeblks_delta; /* debugging counter */ - long t_ag_flist_delta; /* debugging counter */ - long t_ag_btree_delta; /* debugging counter */ - long t_dblocks_delta;/* superblock dblocks change */ - long t_agcount_delta;/* superblock agcount change */ - long t_imaxpct_delta;/* superblock imaxpct change */ - long t_rextsize_delta;/* superblock rextsize chg */ - long t_rbmblocks_delta;/* superblock rbmblocks chg */ - long t_rblocks_delta;/* superblock rblocks change */ - long t_rextents_delta;/* superblocks rextents chg */ - long t_rextslog_delta;/* superblocks rextslog chg */ - unsigned int t_items_free; /* log item descs free */ - xfs_log_item_chunk_t t_items; /* first log item desc chunk */ - xfs_trans_header_t t_header; /* header for in-log trans */ - unsigned int t_busy_free; /* busy descs free */ - xfs_log_busy_chunk_t t_busy; /* busy/async free blocks */ - xfs_pflags_t t_pflags; /* saved pflags state */ -} xfs_trans_t; - -#endif /* __KERNEL__ */ - - #define XFS_TRANS_MAGIC 0x5452414E /* 'TRAN' */ /* * Values for t_flags. @@ -806,12 +627,9 @@ typedef struct xfs_trans { ((mp)->m_sb.sb_inodesize + \ (mp)->m_sb.sb_sectsize * 2 + \ (mp)->m_dirblksize + \ - (XFS_DIR_IS_V1(mp) ? 0 : \ - XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1))) + \ + XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1)) + \ XFS_ALLOCFREE_LOG_RES(mp, 1) + \ - (128 * (4 + \ - (XFS_DIR_IS_V1(mp) ? 0 : \ - XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \ + (128 * (4 + (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \ XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) #define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) @@ -932,6 +750,156 @@ typedef struct xfs_trans { #define XFS_DQUOT_REF 1 #ifdef __KERNEL__ + +struct xfs_buf; +struct xfs_buftarg; +struct xfs_efd_log_item; +struct xfs_efi_log_item; +struct xfs_inode; +struct xfs_item_ops; +struct xfs_log_iovec; +struct xfs_log_item_desc; +struct xfs_mount; +struct xfs_trans; +struct xfs_dquot_acct; + +typedef struct xfs_log_item { + struct list_head li_ail; /* AIL pointers */ + xfs_lsn_t li_lsn; /* last on-disk lsn */ + struct xfs_log_item_desc *li_desc; /* ptr to current desc*/ + struct xfs_mount *li_mountp; /* ptr to fs mount */ + uint li_type; /* item type */ + uint li_flags; /* misc flags */ + struct xfs_log_item *li_bio_list; /* buffer item list */ + void (*li_cb)(struct xfs_buf *, + struct xfs_log_item *); + /* buffer item iodone */ + /* callback func */ + struct xfs_item_ops *li_ops; /* function list */ +} xfs_log_item_t; + +#define XFS_LI_IN_AIL 0x1 +#define XFS_LI_ABORTED 0x2 + +typedef struct xfs_item_ops { + uint (*iop_size)(xfs_log_item_t *); + void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); + void (*iop_pin)(xfs_log_item_t *); + void (*iop_unpin)(xfs_log_item_t *, int); + void (*iop_unpin_remove)(xfs_log_item_t *, struct xfs_trans *); + uint (*iop_trylock)(xfs_log_item_t *); + void (*iop_unlock)(xfs_log_item_t *); + xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t); + void (*iop_push)(xfs_log_item_t *); + void (*iop_pushbuf)(xfs_log_item_t *); + void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); +} xfs_item_ops_t; + +#define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip) +#define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp) +#define IOP_PIN(ip) (*(ip)->li_ops->iop_pin)(ip) +#define IOP_UNPIN(ip, flags) (*(ip)->li_ops->iop_unpin)(ip, flags) +#define IOP_UNPIN_REMOVE(ip,tp) (*(ip)->li_ops->iop_unpin_remove)(ip, tp) +#define IOP_TRYLOCK(ip) (*(ip)->li_ops->iop_trylock)(ip) +#define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip) +#define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn) +#define IOP_PUSH(ip) (*(ip)->li_ops->iop_push)(ip) +#define IOP_PUSHBUF(ip) (*(ip)->li_ops->iop_pushbuf)(ip) +#define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn) + +/* + * Return values for the IOP_TRYLOCK() routines. + */ +#define XFS_ITEM_SUCCESS 0 +#define XFS_ITEM_PINNED 1 +#define XFS_ITEM_LOCKED 2 +#define XFS_ITEM_FLUSHING 3 +#define XFS_ITEM_PUSHBUF 4 + +/* + * This structure is used to maintain a list of block ranges that have been + * freed in the transaction. The ranges are listed in the perag[] busy list + * between when they're freed and the transaction is committed to disk. + */ + +typedef struct xfs_log_busy_slot { + xfs_agnumber_t lbc_ag; + ushort lbc_idx; /* index in perag.busy[] */ +} xfs_log_busy_slot_t; + +#define XFS_LBC_NUM_SLOTS 31 +typedef struct xfs_log_busy_chunk { + struct xfs_log_busy_chunk *lbc_next; + uint lbc_free; /* free slots bitmask */ + ushort lbc_unused; /* first unused */ + xfs_log_busy_slot_t lbc_busy[XFS_LBC_NUM_SLOTS]; +} xfs_log_busy_chunk_t; + +#define XFS_LBC_MAX_SLOT (XFS_LBC_NUM_SLOTS - 1) +#define XFS_LBC_FREEMASK ((1U << XFS_LBC_NUM_SLOTS) - 1) + +#define XFS_LBC_INIT(cp) ((cp)->lbc_free = XFS_LBC_FREEMASK) +#define XFS_LBC_CLAIM(cp, slot) ((cp)->lbc_free &= ~(1 << (slot))) +#define XFS_LBC_SLOT(cp, slot) (&((cp)->lbc_busy[(slot)])) +#define XFS_LBC_VACANCY(cp) (((cp)->lbc_free) & XFS_LBC_FREEMASK) +#define XFS_LBC_ISFREE(cp, slot) ((cp)->lbc_free & (1 << (slot))) + +/* + * This is the type of function which can be given to xfs_trans_callback() + * to be called upon the transaction's commit to disk. + */ +typedef void (*xfs_trans_callback_t)(struct xfs_trans *, void *); + +/* + * This is the structure maintained for every active transaction. + */ +typedef struct xfs_trans { + unsigned int t_magic; /* magic number */ + xfs_log_callback_t t_logcb; /* log callback struct */ + unsigned int t_type; /* transaction type */ + unsigned int t_log_res; /* amt of log space resvd */ + unsigned int t_log_count; /* count for perm log res */ + unsigned int t_blk_res; /* # of blocks resvd */ + unsigned int t_blk_res_used; /* # of resvd blocks used */ + unsigned int t_rtx_res; /* # of rt extents resvd */ + unsigned int t_rtx_res_used; /* # of resvd rt extents used */ + xfs_log_ticket_t t_ticket; /* log mgr ticket */ + xfs_lsn_t t_lsn; /* log seq num of start of + * transaction. */ + xfs_lsn_t t_commit_lsn; /* log seq num of end of + * transaction. */ + struct xfs_mount *t_mountp; /* ptr to fs mount struct */ + struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */ + xfs_trans_callback_t t_callback; /* transaction callback */ + void *t_callarg; /* callback arg */ + unsigned int t_flags; /* misc flags */ + int64_t t_icount_delta; /* superblock icount change */ + int64_t t_ifree_delta; /* superblock ifree change */ + int64_t t_fdblocks_delta; /* superblock fdblocks chg */ + int64_t t_res_fdblocks_delta; /* on-disk only chg */ + int64_t t_frextents_delta;/* superblock freextents chg*/ + int64_t t_res_frextents_delta; /* on-disk only chg */ +#ifdef DEBUG + int64_t t_ag_freeblks_delta; /* debugging counter */ + int64_t t_ag_flist_delta; /* debugging counter */ + int64_t t_ag_btree_delta; /* debugging counter */ +#endif + int64_t t_dblocks_delta;/* superblock dblocks change */ + int64_t t_agcount_delta;/* superblock agcount change */ + int64_t t_imaxpct_delta;/* superblock imaxpct change */ + int64_t t_rextsize_delta;/* superblock rextsize chg */ + int64_t t_rbmblocks_delta;/* superblock rbmblocks chg */ + int64_t t_rblocks_delta;/* superblock rblocks change */ + int64_t t_rextents_delta;/* superblocks rextents chg */ + int64_t t_rextslog_delta;/* superblocks rextslog chg */ + unsigned int t_items_free; /* log item descs free */ + xfs_log_item_chunk_t t_items; /* first log item desc chunk */ + xfs_trans_header_t t_header; /* header for in-log trans */ + unsigned int t_busy_free; /* busy descs free */ + xfs_log_busy_chunk_t t_busy; /* busy/async free blocks */ + unsigned long t_pflags; /* saved process flags state */ +} xfs_trans_t; + /* * XFS transaction mechanism exported interfaces that are * actually macros. @@ -942,9 +910,9 @@ typedef struct xfs_trans { #define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC) #ifdef DEBUG -#define xfs_trans_agblocks_delta(tp, d) ((tp)->t_ag_freeblks_delta += (long)d) -#define xfs_trans_agflist_delta(tp, d) ((tp)->t_ag_flist_delta += (long)d) -#define xfs_trans_agbtree_delta(tp, d) ((tp)->t_ag_btree_delta += (long)d) +#define xfs_trans_agblocks_delta(tp, d) ((tp)->t_ag_freeblks_delta += (int64_t)d) +#define xfs_trans_agflist_delta(tp, d) ((tp)->t_ag_flist_delta += (int64_t)d) +#define xfs_trans_agbtree_delta(tp, d) ((tp)->t_ag_btree_delta += (int64_t)d) #else #define xfs_trans_agblocks_delta(tp, d) #define xfs_trans_agflist_delta(tp, d) @@ -954,13 +922,12 @@ typedef struct xfs_trans { /* * XFS transaction mechanism exported interfaces. */ -void xfs_trans_init(struct xfs_mount *); xfs_trans_t *xfs_trans_alloc(struct xfs_mount *, uint); xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint); xfs_trans_t *xfs_trans_dup(xfs_trans_t *); int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, uint, uint); -void xfs_trans_mod_sb(xfs_trans_t *, uint, long); +void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t); struct xfs_buf *xfs_trans_get_buf(xfs_trans_t *, struct xfs_buftarg *, xfs_daddr_t, int, uint); int xfs_trans_read_buf(struct xfs_mount *, xfs_trans_t *, @@ -998,13 +965,12 @@ void xfs_trans_log_efd_extent(xfs_trans_t *, xfs_extlen_t); int _xfs_trans_commit(xfs_trans_t *, uint flags, - xfs_lsn_t *, int *); -#define xfs_trans_commit(tp, flags, lsn) \ - _xfs_trans_commit(tp, flags, lsn, NULL) +#define xfs_trans_commit(tp, flags) _xfs_trans_commit(tp, flags, NULL) void xfs_trans_cancel(xfs_trans_t *, int); -void xfs_trans_ail_init(struct xfs_mount *); -xfs_lsn_t xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t); +int xfs_trans_ail_init(struct xfs_mount *); +void xfs_trans_ail_destroy(struct xfs_mount *); +void xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t); xfs_lsn_t xfs_trans_tail_ail(struct xfs_mount *); void xfs_trans_unlocked_item(struct xfs_mount *, xfs_log_item_t *); @@ -1012,6 +978,11 @@ xfs_log_busy_slot_t *xfs_trans_add_busy(xfs_trans_t *tp, xfs_agnumber_t ag, xfs_extlen_t idx); +extern kmem_zone_t *xfs_trans_zone; + #endif /* __KERNEL__ */ +void xfs_trans_init(struct xfs_mount *); +int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *); + #endif /* __XFS_TRANS_H__ */ diff --git a/include/xfs_trans_space.h b/include/xfs_trans_space.h index 7fe3792b1..4ea2e5074 100644 --- a/include/xfs_trans_space.h +++ b/include/xfs_trans_space.h @@ -30,8 +30,7 @@ XFS_EXTENTADD_SPACE_RES(mp,w)) #define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1) #define XFS_DAENTER_DBS(mp,w) \ - (XFS_DA_NODE_MAXDEPTH + \ - ((XFS_DIR_IS_V2(mp) && (w) == XFS_DATA_FORK) ? 2 : 0)) + (XFS_DA_NODE_MAXDEPTH + (((w) == XFS_DATA_FORK) ? 2 : 0)) #define XFS_DAENTER_BLOCKS(mp,w) \ (XFS_DAENTER_1B(mp,w) * XFS_DAENTER_DBS(mp,w)) #define XFS_DAENTER_BMAP1B(mp,w) \ @@ -41,10 +40,7 @@ #define XFS_DAENTER_SPACE_RES(mp,w) \ (XFS_DAENTER_BLOCKS(mp,w) + XFS_DAENTER_BMAPS(mp,w)) #define XFS_DAREMOVE_SPACE_RES(mp,w) XFS_DAENTER_BMAPS(mp,w) -#define XFS_DIRENTER_MAX_SPLIT(mp,nl) \ - (((mp)->m_sb.sb_blocksize == 512 && \ - XFS_DIR_IS_V1(mp) && \ - (nl) >= XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN) ? 2 : 1) +#define XFS_DIRENTER_MAX_SPLIT(mp,nl) 1 #define XFS_DIRENTER_SPACE_RES(mp,nl) \ (XFS_DAENTER_SPACE_RES(mp, XFS_DATA_FORK) * \ XFS_DIRENTER_MAX_SPLIT(mp,nl)) @@ -57,8 +53,7 @@ * Space reservation values for various transactions. */ #define XFS_ADDAFORK_SPACE_RES(mp) \ - ((mp)->m_dirblkfsbs + \ - (XFS_DIR_IS_V1(mp) ? 0 : XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK))) + ((mp)->m_dirblkfsbs + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK)) #define XFS_ATTRRM_SPACE_RES(mp) \ XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK) /* This macro is not used - see inline code in xfs_attr_set */ diff --git a/include/xfs_types.h b/include/xfs_types.h index 104f64a98..0f5191644 100644 --- a/include/xfs_types.h +++ b/include/xfs_types.h @@ -151,18 +151,6 @@ typedef __uint8_t xfs_arch_t; /* architecture of an xfs fs */ */ #define MAXNAMELEN 256 -typedef struct xfs_dirent { /* data from readdir() */ - xfs_ino_t d_ino; /* inode number of entry */ - xfs_off_t d_off; /* offset of disk directory entry */ - unsigned short d_reclen; /* length of this record */ - char d_name[1]; /* name of file */ -} xfs_dirent_t; - -#define DIRENTBASESIZE (((xfs_dirent_t *)0)->d_name - (char *)0) -#define DIRENTSIZE(namelen) \ - ((DIRENTBASESIZE + (namelen) + \ - sizeof(xfs_off_t)) & ~(sizeof(xfs_off_t) - 1)) - typedef enum { XFS_LOOKUP_EQi, XFS_LOOKUP_LEi, XFS_LOOKUP_GEi } xfs_lookup_t; @@ -172,4 +160,9 @@ typedef enum { XFS_BTNUM_MAX } xfs_btnum_t; +struct xfs_name { + const char *name; + int len; +}; + #endif /* __XFS_TYPES_H__ */ diff --git a/io/parent.c b/io/parent.c index 6f429b7e4..ea2efa839 100644 --- a/io/parent.c +++ b/io/parent.c @@ -242,7 +242,7 @@ parent_check(void) fsfd = file->fd; fshandlep = jdm_getfshandle(mntpt); - if (fshandlep == 0) { + if (fshandlep == NULL) { fprintf(stderr, _("unable to open \"%s\" for jdm: %s\n"), mntpt, strerror(errno)); diff --git a/libdisk/Makefile b/libdisk/Makefile index 54ee492ee..e77289146 100644 --- a/libdisk/Makefile +++ b/libdisk/Makefile @@ -28,3 +28,5 @@ install: default install-dev: default $(INSTALL_LTLIB_STATIC) + +install-qa: install-dev diff --git a/libdisk/fstype.c b/libdisk/fstype.c index b5568a646..c6376546d 100644 --- a/libdisk/fstype.c +++ b/libdisk/fstype.c @@ -199,11 +199,11 @@ fstype(const char *device) { to a block device or ordinary file */ if (stat (device, &statbuf) || !(S_ISBLK(statbuf.st_mode) || S_ISREG(statbuf.st_mode))) - return 0; + return NULL; fd = open(device, O_RDONLY); if (fd < 0) - return 0; + return NULL; /* do seeks and reads in disk order, otherwise a very short partition may cause a failure because of read error */ @@ -409,5 +409,5 @@ fstype(const char *device) { io_error: close(fd); - return 0; + return NULL; } diff --git a/libhandle/Makefile b/libhandle/Makefile index 7344561d0..369252d50 100644 --- a/libhandle/Makefile +++ b/libhandle/Makefile @@ -21,3 +21,5 @@ install: default install-dev: default $(INSTALL_LTLIB_DEV) + +install-qa: install-dev diff --git a/libhandle/jdm.c b/libhandle/jdm.c index 453e3f738..852c58688 100644 --- a/libhandle/jdm.c +++ b/libhandle/jdm.c @@ -70,7 +70,7 @@ jdm_getfshandle( char *mntpnt ) ASSERT( sizeofmember( filehandle_t, fh_pad ) == FILEHANDLE_SZ_PAD ); ASSERT( FILEHANDLE_SZ_PAD == sizeof( int16_t )); - fshandlep = 0; /* for lint */ + fshandlep = NULL; /* for lint */ fshandlesz = sizeof( *fshandlep ); if (!realpath( mntpnt, resolved )) diff --git a/libxcmd/Makefile b/libxcmd/Makefile index dea5f8bcc..c03849d05 100644 --- a/libxcmd/Makefile +++ b/libxcmd/Makefile @@ -24,7 +24,4 @@ default: $(LTLIBRARY) include $(BUILDRULES) -install: default - -install-dev: default - $(INSTALL_LTLIB_STATIC) +install install-dev install-qa: default diff --git a/libxcmd/projects.c b/libxcmd/projects.c index 9ea4a7fc0..a0f5bc989 100644 --- a/libxcmd/projects.c +++ b/libxcmd/projects.c @@ -44,14 +44,14 @@ setprfiles(void) } void -setprent() +setprent(void) { setprfiles(); projects = fopen(projid_file, "r"); } void -setprpathent() +setprpathent(void) { setprfiles(); project_paths = fopen(projects_file, "r"); diff --git a/libxfs/Makefile b/libxfs/Makefile index 8cc780ec8..1914927de 100644 --- a/libxfs/Makefile +++ b/libxfs/Makefile @@ -11,13 +11,12 @@ LT_REVISION = 0 LT_AGE = 0 HFILES = xfs.h init.h -CFILES = bit.c cache.c init.c logitem.c rdwr.c trans.c util.c \ - xfs_alloc.c xfs_ialloc.c xfs_rtalloc.c \ - xfs_inode.c xfs_btree.c xfs_alloc_btree.c xfs_ialloc_btree.c \ - xfs_bmap_btree.c xfs_da_btree.c xfs_dir.c xfs_dir_leaf.c \ +CFILES = cache.c init.c kmem.c logitem.c rdwr.c trans.c util.c \ + xfs_alloc.c xfs_ialloc.c xfs_inode.c xfs_btree.c xfs_alloc_btree.c \ + xfs_ialloc_btree.c xfs_bmap_btree.c xfs_da_btree.c \ xfs_dir2.c xfs_dir2_leaf.c xfs_attr_leaf.c xfs_dir2_block.c \ xfs_dir2_node.c xfs_dir2_data.c xfs_dir2_sf.c xfs_bmap.c \ - xfs_mount.c xfs_trans.c xfs_attr.c + xfs_mount.c xfs_rtalloc.c xfs_trans.c xfs_attr.c CFILES += $(PKG_PLATFORM).c PCFILES = darwin.c freebsd.c irix.c linux.c @@ -44,4 +43,5 @@ include $(BUILDRULES) install: default install-dev: default - $(INSTALL_LTLIB_STATIC) + +install-qa: default diff --git a/libxfs/bit.c b/libxfs/bit.c deleted file mode 100644 index f7c8d5976..000000000 --- a/libxfs/bit.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * XFS bit manipulation routines - */ - -#include - -/* - * Index of low bit number in byte, -1 for none set, 0..7 otherwise. - */ -static const char xfs_lowbit[256] = { - -1, 0, 1, 0, 2, 0, 1, 0, /* 00 .. 07 */ - 3, 0, 1, 0, 2, 0, 1, 0, /* 08 .. 0f */ - 4, 0, 1, 0, 2, 0, 1, 0, /* 10 .. 17 */ - 3, 0, 1, 0, 2, 0, 1, 0, /* 18 .. 1f */ - 5, 0, 1, 0, 2, 0, 1, 0, /* 20 .. 27 */ - 3, 0, 1, 0, 2, 0, 1, 0, /* 28 .. 2f */ - 4, 0, 1, 0, 2, 0, 1, 0, /* 30 .. 37 */ - 3, 0, 1, 0, 2, 0, 1, 0, /* 38 .. 3f */ - 6, 0, 1, 0, 2, 0, 1, 0, /* 40 .. 47 */ - 3, 0, 1, 0, 2, 0, 1, 0, /* 48 .. 4f */ - 4, 0, 1, 0, 2, 0, 1, 0, /* 50 .. 57 */ - 3, 0, 1, 0, 2, 0, 1, 0, /* 58 .. 5f */ - 5, 0, 1, 0, 2, 0, 1, 0, /* 60 .. 67 */ - 3, 0, 1, 0, 2, 0, 1, 0, /* 68 .. 6f */ - 4, 0, 1, 0, 2, 0, 1, 0, /* 70 .. 77 */ - 3, 0, 1, 0, 2, 0, 1, 0, /* 78 .. 7f */ - 7, 0, 1, 0, 2, 0, 1, 0, /* 80 .. 87 */ - 3, 0, 1, 0, 2, 0, 1, 0, /* 88 .. 8f */ - 4, 0, 1, 0, 2, 0, 1, 0, /* 90 .. 97 */ - 3, 0, 1, 0, 2, 0, 1, 0, /* 98 .. 9f */ - 5, 0, 1, 0, 2, 0, 1, 0, /* a0 .. a7 */ - 3, 0, 1, 0, 2, 0, 1, 0, /* a8 .. af */ - 4, 0, 1, 0, 2, 0, 1, 0, /* b0 .. b7 */ - 3, 0, 1, 0, 2, 0, 1, 0, /* b8 .. bf */ - 6, 0, 1, 0, 2, 0, 1, 0, /* c0 .. c7 */ - 3, 0, 1, 0, 2, 0, 1, 0, /* c8 .. cf */ - 4, 0, 1, 0, 2, 0, 1, 0, /* d0 .. d7 */ - 3, 0, 1, 0, 2, 0, 1, 0, /* d8 .. df */ - 5, 0, 1, 0, 2, 0, 1, 0, /* e0 .. e7 */ - 3, 0, 1, 0, 2, 0, 1, 0, /* e8 .. ef */ - 4, 0, 1, 0, 2, 0, 1, 0, /* f0 .. f7 */ - 3, 0, 1, 0, 2, 0, 1, 0, /* f8 .. ff */ -}; - -/* - * Index of high bit number in byte, -1 for none set, 0..7 otherwise. - */ -static const char xfs_highbit[256] = { - -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */ - 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */ - 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */ - 4, 4, 4, 4, 4, 4, 4, 4, /* 18 .. 1f */ - 5, 5, 5, 5, 5, 5, 5, 5, /* 20 .. 27 */ - 5, 5, 5, 5, 5, 5, 5, 5, /* 28 .. 2f */ - 5, 5, 5, 5, 5, 5, 5, 5, /* 30 .. 37 */ - 5, 5, 5, 5, 5, 5, 5, 5, /* 38 .. 3f */ - 6, 6, 6, 6, 6, 6, 6, 6, /* 40 .. 47 */ - 6, 6, 6, 6, 6, 6, 6, 6, /* 48 .. 4f */ - 6, 6, 6, 6, 6, 6, 6, 6, /* 50 .. 57 */ - 6, 6, 6, 6, 6, 6, 6, 6, /* 58 .. 5f */ - 6, 6, 6, 6, 6, 6, 6, 6, /* 60 .. 67 */ - 6, 6, 6, 6, 6, 6, 6, 6, /* 68 .. 6f */ - 6, 6, 6, 6, 6, 6, 6, 6, /* 70 .. 77 */ - 6, 6, 6, 6, 6, 6, 6, 6, /* 78 .. 7f */ - 7, 7, 7, 7, 7, 7, 7, 7, /* 80 .. 87 */ - 7, 7, 7, 7, 7, 7, 7, 7, /* 88 .. 8f */ - 7, 7, 7, 7, 7, 7, 7, 7, /* 90 .. 97 */ - 7, 7, 7, 7, 7, 7, 7, 7, /* 98 .. 9f */ - 7, 7, 7, 7, 7, 7, 7, 7, /* a0 .. a7 */ - 7, 7, 7, 7, 7, 7, 7, 7, /* a8 .. af */ - 7, 7, 7, 7, 7, 7, 7, 7, /* b0 .. b7 */ - 7, 7, 7, 7, 7, 7, 7, 7, /* b8 .. bf */ - 7, 7, 7, 7, 7, 7, 7, 7, /* c0 .. c7 */ - 7, 7, 7, 7, 7, 7, 7, 7, /* c8 .. cf */ - 7, 7, 7, 7, 7, 7, 7, 7, /* d0 .. d7 */ - 7, 7, 7, 7, 7, 7, 7, 7, /* d8 .. df */ - 7, 7, 7, 7, 7, 7, 7, 7, /* e0 .. e7 */ - 7, 7, 7, 7, 7, 7, 7, 7, /* e8 .. ef */ - 7, 7, 7, 7, 7, 7, 7, 7, /* f0 .. f7 */ - 7, 7, 7, 7, 7, 7, 7, 7, /* f8 .. ff */ -}; - -/* - * xfs_lowbit32: get low bit set out of 32-bit argument, -1 if none set. - */ -int -xfs_lowbit32( - __uint32_t v) -{ - int i; - - if (v & 0x0000ffff) - if (v & 0x000000ff) - i = 0; - else - i = 8; - else if (v & 0xffff0000) - if (v & 0x00ff0000) - i = 16; - else - i = 24; - else - return -1; - return i + xfs_lowbit[(v >> i) & 0xff]; -} - -/* - * xfs_highbit32: get high bit set out of 32-bit argument, -1 if none set. - */ -int -xfs_highbit32( - __uint32_t v) -{ - int i; - - if (v & 0xffff0000) - if (v & 0xff000000) - i = 24; - else - i = 16; - else if (v & 0x0000ffff) - if (v & 0x0000ff00) - i = 8; - else - i = 0; - else - return -1; - return i + xfs_highbit[(v >> i) & 0xff]; -} - -/* - * xfs_lowbit64: get low bit set out of 64-bit argument, -1 if none set. - */ -int -xfs_lowbit64( - __uint64_t v) -{ - int i; -#if XFS_64 - if (v & 0x00000000ffffffff) - if (v & 0x000000000000ffff) - if (v & 0x00000000000000ff) - i = 0; - else - i = 8; - else - if (v & 0x0000000000ff0000) - i = 16; - else - i = 24; - else if (v & 0xffffffff00000000) - if (v & 0x0000ffff00000000) - if (v & 0x000000ff00000000) - i = 32; - else - i = 40; - else - if (v & 0x00ff000000000000) - i = 48; - else - i = 56; - else - return -1; - return i + xfs_lowbit[(v >> i) & 0xff]; -#else - __uint32_t vw; - - if ((vw = v)) { - if (vw & 0x0000ffff) - if (vw & 0x000000ff) - i = 0; - else - i = 8; - else - if (vw & 0x00ff0000) - i = 16; - else - i = 24; - return i + xfs_lowbit[(vw >> i) & 0xff]; - } else if ((vw = v >> 32)) { - if (vw & 0x0000ffff) - if (vw & 0x000000ff) - i = 32; - else - i = 40; - else - if (vw & 0x00ff0000) - i = 48; - else - i = 56; - return i + xfs_lowbit[(vw >> (i - 32)) & 0xff]; - } else - return -1; -#endif -} - -/* - * xfs_highbit64: get high bit set out of 64-bit argument, -1 if none set. - */ -int -xfs_highbit64( - __uint64_t v) -{ - int i; -#if XFS_64 - if (v & 0xffffffff00000000) - if (v & 0xffff000000000000) - if (v & 0xff00000000000000) - i = 56; - else - i = 48; - else - if (v & 0x0000ff0000000000) - i = 40; - else - i = 32; - else if (v & 0x00000000ffffffff) - if (v & 0x00000000ffff0000) - if (v & 0x00000000ff000000) - i = 24; - else - i = 16; - else - if (v & 0x000000000000ff00) - i = 8; - else - i = 0; - else - return -1; - return i + xfs_highbit[(v >> i) & 0xff]; -#else - __uint32_t vw; - - if ((vw = v >> 32)) { - if (vw & 0xffff0000) - if (vw & 0xff000000) - i = 56; - else - i = 48; - else - if (vw & 0x0000ff00) - i = 40; - else - i = 32; - return i + xfs_highbit[(vw >> (i - 32)) & 0xff]; - } else if ((vw = v)) { - if (vw & 0xffff0000) - if (vw & 0xff000000) - i = 24; - else - i = 16; - else - if (vw & 0x0000ff00) - i = 8; - else - i = 0; - return i + xfs_highbit[(vw >> i) & 0xff]; - } else - return -1; -#endif -} diff --git a/libxfs/init.c b/libxfs/init.c index e31c26b41..d47cc5ddf 100644 --- a/libxfs/init.c +++ b/libxfs/init.c @@ -16,7 +16,7 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include +#include #include #include "init.h" @@ -338,6 +338,13 @@ libxfs_init(libxfs_init_t *a) libxfs_bhash_size = LIBXFS_BHASHSIZE(sbp); libxfs_bcache = cache_init(libxfs_bhash_size, &libxfs_bcache_operations); use_xfs_buf_lock = a->usebuflock; +#ifndef HAVE_PTHREAD_T + if (use_xfs_buf_lock) { + fprintf(stderr, _("%s: can't use buffer locks without pthreads\n"), + progname); + goto done; + } +#endif manage_zones(0); rval = 1; done: @@ -365,42 +372,42 @@ done: static void manage_zones(int release) { - extern xfs_zone_t *xfs_buf_zone; - extern xfs_zone_t *xfs_ili_zone; - extern xfs_zone_t *xfs_inode_zone; - extern xfs_zone_t *xfs_ifork_zone; - extern xfs_zone_t *xfs_dabuf_zone; - extern xfs_zone_t *xfs_buf_item_zone; - extern xfs_zone_t *xfs_da_state_zone; - extern xfs_zone_t *xfs_btree_cur_zone; - extern xfs_zone_t *xfs_bmap_free_item_zone; + extern kmem_zone_t *xfs_buf_zone; + extern kmem_zone_t *xfs_ili_zone; + extern kmem_zone_t *xfs_inode_zone; + extern kmem_zone_t *xfs_ifork_zone; + extern kmem_zone_t *xfs_dabuf_zone; + extern kmem_zone_t *xfs_buf_item_zone; + extern kmem_zone_t *xfs_da_state_zone; + extern kmem_zone_t *xfs_btree_cur_zone; + extern kmem_zone_t *xfs_bmap_free_item_zone; extern void xfs_dir_startup(); if (release) { /* free zone allocation */ - libxfs_free(xfs_buf_zone); - libxfs_free(xfs_inode_zone); - libxfs_free(xfs_ifork_zone); - libxfs_free(xfs_dabuf_zone); - libxfs_free(xfs_buf_item_zone); - libxfs_free(xfs_da_state_zone); - libxfs_free(xfs_btree_cur_zone); - libxfs_free(xfs_bmap_free_item_zone); + kmem_free(xfs_buf_zone); + kmem_free(xfs_inode_zone); + kmem_free(xfs_ifork_zone); + kmem_free(xfs_dabuf_zone); + kmem_free(xfs_buf_item_zone); + kmem_free(xfs_da_state_zone); + kmem_free(xfs_btree_cur_zone); + kmem_free(xfs_bmap_free_item_zone); return; } /* otherwise initialise zone allocation */ - xfs_buf_zone = libxfs_zone_init(sizeof(xfs_buf_t), "xfs_buffer"); - xfs_inode_zone = libxfs_zone_init(sizeof(xfs_inode_t), "xfs_inode"); - xfs_ifork_zone = libxfs_zone_init(sizeof(xfs_ifork_t), "xfs_ifork"); - xfs_dabuf_zone = libxfs_zone_init(sizeof(xfs_dabuf_t), "xfs_dabuf"); - xfs_ili_zone = libxfs_zone_init( + xfs_buf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buffer"); + xfs_inode_zone = kmem_zone_init(sizeof(xfs_inode_t), "xfs_inode"); + xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork"); + xfs_dabuf_zone = kmem_zone_init(sizeof(xfs_dabuf_t), "xfs_dabuf"); + xfs_ili_zone = kmem_zone_init( sizeof(xfs_inode_log_item_t), "xfs_inode_log_item"); - xfs_buf_item_zone = libxfs_zone_init( + xfs_buf_item_zone = kmem_zone_init( sizeof(xfs_buf_log_item_t), "xfs_buf_log_item"); - xfs_da_state_zone = libxfs_zone_init( + xfs_da_state_zone = kmem_zone_init( sizeof(xfs_da_state_t), "xfs_da_state"); - xfs_btree_cur_zone = libxfs_zone_init( + xfs_btree_cur_zone = kmem_zone_init( sizeof(xfs_btree_cur_t), "xfs_btree_cur"); - xfs_bmap_free_item_zone = libxfs_zone_init( + xfs_bmap_free_item_zone = kmem_zone_init( sizeof(xfs_bmap_free_item_t), "xfs_bmap_free_item"); xfs_dir_startup(); } @@ -493,6 +500,22 @@ rtmount_init( return 0; } + +/* + * Core dir v1 mount code for allowing reading of these dirs. + */ +static void +libxfs_dirv1_mount( + xfs_mount_t *mp) +{ + mp->m_dir_node_ents = mp->m_attr_node_ents = + (XFS_LBSIZE(mp) - (uint)sizeof(xfs_da_node_hdr_t)) / + (uint)sizeof(xfs_da_node_entry_t); + mp->m_dir_magicpct = (XFS_LBSIZE(mp) * 37) / 100; + mp->m_dirblksize = mp->m_sb.sb_blocksize; + mp->m_dirblkfsbs = 1; +} + /* * Mount structure initialization, provides a filled-in xfs_mount_t * such that the numerous XFS_* macros can be used. If dev is zero, @@ -520,12 +543,12 @@ libxfs_mount( mp->m_sb = *sb; sbp = &(mp->m_sb); - libxfs_mount_common(mp, sb); + xfs_mount_common(mp, sb); - libxfs_alloc_compute_maxlevels(mp); - libxfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK); - libxfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK); - libxfs_ialloc_compute_maxlevels(mp); + xfs_alloc_compute_maxlevels(mp); + xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK); + xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK); + xfs_ialloc_compute_maxlevels(mp); if (sbp->sb_imax_pct) { /* Make sure the maximum inode count is a multiple of the @@ -542,7 +565,7 @@ libxfs_mount( /* * Set whether we're using stripe alignment. */ - if (XFS_SB_VERSION_HASDALIGN(&mp->m_sb)) { + if (xfs_sb_version_hasdalign(&mp->m_sb)) { mp->m_dalign = sbp->sb_unit; mp->m_swidth = sbp->sb_width; } @@ -550,7 +573,7 @@ libxfs_mount( /* * Set whether we're using inode alignment. */ - if (XFS_SB_VERSION_HASALIGN(&mp->m_sb) && + if (xfs_sb_version_hasalign(&mp->m_sb) && mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size)) mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1; @@ -560,8 +583,8 @@ libxfs_mount( * If we are using stripe alignment, check whether * the stripe unit is a multiple of the inode alignment */ - if ( mp->m_dalign - && mp->m_inoalign_mask && !(mp->m_dalign & mp->m_inoalign_mask)) + if (mp->m_dalign && mp->m_inoalign_mask && + !(mp->m_dalign & mp->m_inoalign_mask)) mp->m_sinoalign = mp->m_dalign; else mp->m_sinoalign = 0; @@ -577,16 +600,21 @@ libxfs_mount( } /* Initialize the appropriate directory manager */ - if (XFS_SB_VERSION_HASDIRV2(sbp)) - libxfs_dir2_mount(mp); - else - libxfs_dir_mount(mp); + if (xfs_sb_version_hasdirv2(sbp)) + xfs_dir_mount(mp); + else { + fprintf(stderr, _("%s: WARNING - filesystem uses v1 dirs," + "limited functionality provided.\n"), progname); + libxfs_dirv1_mount(mp); + } /* Initialize cached values for the attribute manager */ mp->m_attr_magicpct = (mp->m_sb.sb_blocksize * 37) / 100; + if (xfs_sb_version_hasattr2(&mp->m_sb)) + mp->m_flags |= LIBXFS_MOUNT_ATTR2; /* Initialize the precomputed transaction reservations values */ - libxfs_trans_init(mp); + xfs_trans_init(mp); if (dev == 0) /* maxtrres, we have no device so leave now */ return mp; @@ -632,7 +660,7 @@ libxfs_mount( exit(1); } - mp->m_maxagi = libxfs_initialize_perag(mp, sbp->sb_agcount); + mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount); /* * mkfs calls mount before the root inode is allocated. @@ -657,8 +685,8 @@ libxfs_mount( * mkfs calls mount before the AGF/AGI structures are written. */ if ((flags & LIBXFS_MOUNT_ROOTINOS) && sbp->sb_rootino != NULLFSINO && - XFS_SB_VERSION_LAZYSBCOUNT(&mp->m_sb)) { - error = libxfs_initialize_perag_data(mp, sbp->sb_agcount); + xfs_sb_version_haslazysbcount(&mp->m_sb)) { + error = xfs_initialize_perag_data(mp, sbp->sb_agcount); if (error) { fprintf(stderr, _("%s: cannot init perag data (%d)\n"), progname, error); diff --git a/libxfs/kmem.c b/libxfs/kmem.c new file mode 100644 index 000000000..5d3b9b64d --- /dev/null +++ b/libxfs/kmem.c @@ -0,0 +1,83 @@ + + +#include + +/* + * Simple memory interface + */ + +kmem_zone_t * +kmem_zone_init(int size, char *name) +{ + kmem_zone_t *ptr = malloc(sizeof(kmem_zone_t)); + + if (ptr == NULL) { + fprintf(stderr, _("%s: zone init failed (%s, %d bytes): %s\n"), + progname, name, (int)sizeof(kmem_zone_t), + strerror(errno)); + exit(1); + } + ptr->zone_unitsize = size; + ptr->zone_name = name; + ptr->allocated = 0; + return ptr; +} + +void * +kmem_zone_alloc(kmem_zone_t *zone, int flags) +{ + void *ptr = malloc(zone->zone_unitsize); + + if (ptr == NULL) { + fprintf(stderr, _("%s: zone alloc failed (%s, %d bytes): %s\n"), + progname, zone->zone_name, zone->zone_unitsize, + strerror(errno)); + exit(1); + } + zone->allocated++; + return ptr; +} +void * +kmem_zone_zalloc(kmem_zone_t *zone, int flags) +{ + void *ptr = kmem_zone_alloc(zone, flags); + + memset(ptr, 0, zone->zone_unitsize); + return ptr; +} + + +void * +kmem_alloc(size_t size, int flags) +{ + void *ptr = malloc(size); + + if (ptr == NULL) { + fprintf(stderr, _("%s: malloc failed (%d bytes): %s\n"), + progname, (int)size, strerror(errno)); + exit(1); + } + return ptr; +} + +void * +kmem_zalloc(size_t size, int flags) +{ + void *ptr = kmem_alloc(size, flags); + + memset(ptr, 0, size); + return ptr; +} + +void * +kmem_realloc(void *ptr, size_t new_size, size_t old_size, int flags) +{ + ptr = realloc(ptr, new_size); + if (ptr == NULL) { + fprintf(stderr, _("%s: realloc failed (%d bytes): %s\n"), + progname, (int)new_size, strerror(errno)); + exit(1); + } + return ptr; +} + diff --git a/libxfs/logitem.c b/libxfs/logitem.c index c6e893814..d6ef10bea 100644 --- a/libxfs/logitem.c +++ b/libxfs/logitem.c @@ -18,9 +18,12 @@ #include -xfs_zone_t *xfs_buf_item_zone; -xfs_zone_t *xfs_ili_zone; /* inode log item zone */ +kmem_zone_t *xfs_buf_item_zone; +kmem_zone_t *xfs_ili_zone; /* inode log item zone */ +/* + * Following functions from fs/xfs/xfs_trans_item.c + */ /* * This is called to add the given log item to the transaction's @@ -51,11 +54,11 @@ xfs_trans_add_item( * Initialize the chunk, and then * claim the first slot in the newly allocated chunk. */ - XFS_LIC_INIT(licp); - XFS_LIC_CLAIM(licp, 0); + xfs_lic_init(licp); + xfs_lic_claim(licp, 0); licp->lic_unused = 1; - XFS_LIC_INIT_SLOT(licp, 0); - lidp = XFS_LIC_SLOT(licp, 0); + xfs_lic_init_slot(licp, 0); + lidp = xfs_lic_slot(licp, 0); /* * Link in the new chunk and update the free count. @@ -77,7 +80,7 @@ xfs_trans_add_item( lidp->lid_size = 0; lip->li_desc = lidp; lip->li_mountp = tp->t_mountp; - return (lidp); + return lidp; } /* @@ -86,14 +89,14 @@ xfs_trans_add_item( */ licp = &tp->t_items; while (licp != NULL) { - if (XFS_LIC_VACANCY(licp)) { + if (xfs_lic_vacancy(licp)) { if (licp->lic_unused <= XFS_LIC_MAX_SLOT) { i = licp->lic_unused; - ASSERT(XFS_LIC_ISFREE(licp, i)); + ASSERT(xfs_lic_isfree(licp, i)); break; } for (i = 0; i <= XFS_LIC_MAX_SLOT; i++) { - if (XFS_LIC_ISFREE(licp, i)) + if (xfs_lic_isfree(licp, i)) break; } ASSERT(i <= XFS_LIC_MAX_SLOT); @@ -106,19 +109,19 @@ xfs_trans_add_item( * If we find a free descriptor, claim it, * initialize it, and return it. */ - XFS_LIC_CLAIM(licp, i); + xfs_lic_claim(licp, i); if (licp->lic_unused <= i) { licp->lic_unused = i + 1; - XFS_LIC_INIT_SLOT(licp, i); + xfs_lic_init_slot(licp, i); } - lidp = XFS_LIC_SLOT(licp, i); + lidp = xfs_lic_slot(licp, i); tp->t_items_free--; lidp->lid_item = lip; lidp->lid_flags = 0; lidp->lid_size = 0; lip->li_desc = lidp; lip->li_mountp = tp->t_mountp; - return (lidp); + return lidp; } /* @@ -136,9 +139,9 @@ xfs_trans_free_item( xfs_log_item_chunk_t *licp; xfs_log_item_chunk_t **licpp; - slot = XFS_LIC_DESC_TO_SLOT(lidp); - licp = XFS_LIC_DESC_TO_CHUNK(lidp); - XFS_LIC_RELSE(licp, slot); + slot = xfs_lic_desc_to_slot(lidp); + licp = xfs_lic_desc_to_chunk(lidp); + xfs_lic_relse(licp, slot); lidp->lid_item->li_desc = NULL; tp->t_items_free++; @@ -148,20 +151,20 @@ xfs_trans_free_item( * the chunk. First pull it from the chunk list and then * free it back to the heap. We didn't bother with a doubly * linked list here because the lists should be very short - * and this is not a performance path. It's better to save + * and this is not a performance path. It's better to save * the memory of the extra pointer. * * Also decrement the transaction structure's count of free items * by the number in a chunk since we are freeing an empty chunk. */ - if (XFS_LIC_ARE_ALL_FREE(licp) && (licp != &(tp->t_items))) { + if (xfs_lic_are_all_free(licp) && (licp != &(tp->t_items))) { licpp = &(tp->t_items.lic_next); while (*licpp != licp) { ASSERT(*licpp != NULL); licpp = &((*licpp)->lic_next); } *licpp = licp->lic_next; - kmem_free(licp, sizeof(xfs_log_item_chunk_t)); + kmem_free(licp); tp->t_items_free -= XFS_LIC_NUM_SLOTS; } } @@ -182,7 +185,7 @@ xfs_trans_find_item( { ASSERT(lip->li_desc != NULL); - return (lip->li_desc); + return lip->li_desc; } /* @@ -206,9 +209,9 @@ xfs_trans_free_items( /* * Special case the embedded chunk so we don't free it below. */ - if (!XFS_LIC_ARE_ALL_FREE(licp)) { + if (!xfs_lic_are_all_free(licp)) { (void) xfs_trans_unlock_chunk(licp, 1, abort, NULLCOMMITLSN); - XFS_LIC_ALL_FREE(licp); + xfs_lic_all_free(licp); licp->lic_unused = 0; } licp = licp->lic_next; @@ -217,10 +220,10 @@ xfs_trans_free_items( * Unlock each item in each chunk and free the chunks. */ while (licp != NULL) { - ASSERT(!XFS_LIC_ARE_ALL_FREE(licp)); + ASSERT(!xfs_lic_are_all_free(licp)); (void) xfs_trans_unlock_chunk(licp, 1, abort, NULLCOMMITLSN); next_licp = licp->lic_next; - kmem_free(licp, sizeof(xfs_log_item_chunk_t)); + kmem_free(licp); licp = next_licp; } @@ -231,12 +234,16 @@ xfs_trans_free_items( tp->t_items.lic_next = NULL; } +/* + * Following functions from fs/xfs/xfs_trans_buf.c + */ + /* * Check to see if a buffer matching the given parameters is already * a part of the given transaction. Only check the first, embedded * chunk, since we don't want to spend all day scanning large transactions. */ -STATIC xfs_buf_t * +xfs_buf_t * xfs_trans_buf_item_match( xfs_trans_t *tp, xfs_buftarg_t *target, @@ -256,16 +263,16 @@ xfs_trans_buf_item_match( bp = NULL; len = BBTOB(len); licp = &tp->t_items; - if (!XFS_LIC_ARE_ALL_FREE(licp)) { + if (!xfs_lic_are_all_free(licp)) { for (i = 0; i < licp->lic_unused; i++) { /* * Skip unoccupied slots. */ - if (XFS_LIC_ISFREE(licp, i)) { + if (xfs_lic_isfree(licp, i)) { continue; } - lidp = XFS_LIC_SLOT(licp, i); + lidp = xfs_lic_slot(licp, i); blip = (xfs_buf_log_item_t *)lidp->lid_item; #ifdef LI_DEBUG fprintf(stderr, @@ -311,7 +318,7 @@ xfs_trans_buf_item_match( * a part of the given transaction. Check all the chunks, we * want to be thorough. */ -STATIC xfs_buf_t * +xfs_buf_t * xfs_trans_buf_item_match_all( xfs_trans_t *tp, xfs_buftarg_t *target, @@ -332,7 +339,7 @@ xfs_trans_buf_item_match_all( bp = NULL; len = BBTOB(len); for (licp = &tp->t_items; licp != NULL; licp = licp->lic_next) { - if (XFS_LIC_ARE_ALL_FREE(licp)) { + if (xfs_lic_are_all_free(licp)) { ASSERT(licp == &tp->t_items); ASSERT(licp->lic_next == NULL); return NULL; @@ -341,11 +348,11 @@ xfs_trans_buf_item_match_all( /* * Skip unoccupied slots. */ - if (XFS_LIC_ISFREE(licp, i)) { + if (xfs_lic_isfree(licp, i)) { continue; } - lidp = XFS_LIC_SLOT(licp, i); + lidp = xfs_lic_slot(licp, i); blip = (xfs_buf_log_item_t *)lidp->lid_item; #ifdef LI_DEBUG fprintf(stderr, @@ -386,6 +393,10 @@ xfs_trans_buf_item_match_all( return NULL; } +/* + * The following are from fs/xfs/xfs_buf_item.c + */ + /* * Allocate a new buf log item to go with the given buffer. * Set the buffer's b_fsprivate field to point to the new diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index 3fe0fc3a5..0876ff6a0 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -81,11 +81,11 @@ static void unmount_record(void *p) } magic = { XLOG_UNMOUNT_TYPE, 0, 0 }; memset(p, 0, BBSIZE); - INT_SET(op->oh_tid, ARCH_CONVERT, 1); - INT_SET(op->oh_len, ARCH_CONVERT, sizeof(magic)); - INT_SET(op->oh_clientid, ARCH_CONVERT, XFS_LOG); - INT_SET(op->oh_flags, ARCH_CONVERT, XLOG_UNMOUNT_TRANS); - INT_SET(op->oh_res2, ARCH_CONVERT, 0); + op->oh_tid = cpu_to_be32(1); + op->oh_len = cpu_to_be32(sizeof(magic)); + op->oh_clientid = XFS_LOG; + op->oh_flags = XLOG_UNMOUNT_TRANS; + op->oh_res2 = 0; /* and the data for this op */ memcpy((char *)p + sizeof(xlog_op_header_t), &magic, sizeof(magic)); @@ -142,7 +142,7 @@ libxfs_log_header( { xlog_rec_header_t *head = (xlog_rec_header_t *)caddr; xfs_caddr_t p = caddr; - uint cycle_lsn; + __be32 cycle_lsn; int i, len; len = ((version == 2) && sunit) ? BTOBB(sunit) : 1; @@ -152,22 +152,22 @@ libxfs_log_header( * way things end up on disk. */ memset(p, 0, BBSIZE); - INT_SET(head->h_magicno, ARCH_CONVERT, XLOG_HEADER_MAGIC_NUM); - INT_SET(head->h_cycle, ARCH_CONVERT, 1); - INT_SET(head->h_version, ARCH_CONVERT, version); + head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM); + head->h_cycle = cpu_to_be32(1); + head->h_version = cpu_to_be32(version); if (len != 1) - INT_SET(head->h_len, ARCH_CONVERT, sunit - BBSIZE); + head->h_len = cpu_to_be32(sunit - BBSIZE); else - INT_SET(head->h_len, ARCH_CONVERT, 20); - INT_SET(head->h_chksum, ARCH_CONVERT, 0); - INT_SET(head->h_prev_block, ARCH_CONVERT, -1); - INT_SET(head->h_num_logops, ARCH_CONVERT, 1); - INT_SET(head->h_cycle_data[0], ARCH_CONVERT, 0xb0c0d0d0); - INT_SET(head->h_fmt, ARCH_CONVERT, fmt); - INT_SET(head->h_size, ARCH_CONVERT, XLOG_HEADER_CYCLE_SIZE); + head->h_len = cpu_to_be32(20); + head->h_chksum = cpu_to_be32(0); + head->h_prev_block = cpu_to_be32(-1); + head->h_num_logops = cpu_to_be32(1); + head->h_cycle_data[0] = cpu_to_be32(0xb0c0d0d0); + head->h_fmt = cpu_to_be32(fmt); + head->h_size = cpu_to_be32(XLOG_HEADER_CYCLE_SIZE); - ASSIGN_ANY_LSN_DISK(head->h_lsn, 1, 0); - ASSIGN_ANY_LSN_DISK(head->h_tail_lsn, 1, 0); + head->h_lsn = cpu_to_be64(xlog_assign_lsn(1, 0)); + head->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(1, 0)); memcpy(&head->h_fs_uuid, fs_uuid, sizeof(uuid_t)); @@ -179,7 +179,7 @@ libxfs_log_header( for (i = 2; i < len; i++) { p = nextfunc(p, BBSIZE, private); memset(p, 0, BBSIZE); - *(uint *)p = cycle_lsn; + *(__be32 *)p = cycle_lsn; } return BBTOB(len); @@ -257,7 +257,7 @@ libxfs_getsb(xfs_mount_t *mp, int flags) XFS_FSS_TO_BB(mp, 1), flags); } -xfs_zone_t *xfs_buf_zone; +kmem_zone_t *xfs_buf_zone; static struct cache_mru xfs_buf_freelist = {{&xfs_buf_freelist.cm_list, &xfs_buf_freelist.cm_list}, @@ -355,7 +355,7 @@ libxfs_getbufr(dev_t device, xfs_daddr_t blkno, int bblen) bp->b_addr = NULL; } } else - bp = libxfs_zone_zalloc(xfs_buf_zone); + bp = kmem_zone_zalloc(xfs_buf_zone, 0); pthread_mutex_unlock(&xfs_buf_freelist.cm_mutex); if (bp != NULL) @@ -644,117 +644,12 @@ struct cache_operations libxfs_bcache_operations = { }; -/* - * Simple memory interface - */ - -xfs_zone_t * -libxfs_zone_init(int size, char *name) -{ - xfs_zone_t *ptr; - - if ((ptr = malloc(sizeof(xfs_zone_t))) == NULL) { - fprintf(stderr, _("%s: zone init failed (%s, %d bytes): %s\n"), - progname, name, (int)sizeof(xfs_zone_t), strerror(errno)); - exit(1); - } - ptr->zone_unitsize = size; - ptr->zone_name = name; -#ifdef MEM_DEBUG - ptr->allocated = 0; - fprintf(stderr, "new zone %p for \"%s\", size=%d\n", ptr, name, size); -#endif - return ptr; -} - -void * -libxfs_zone_zalloc(xfs_zone_t *z) -{ - void *ptr; - - if ((ptr = calloc(z->zone_unitsize, 1)) == NULL) { - fprintf(stderr, _("%s: zone calloc failed (%s, %d bytes): %s\n"), - progname, z->zone_name, z->zone_unitsize, - strerror(errno)); - exit(1); - } -#ifdef MEM_DEBUG - z->allocated++; - fprintf(stderr, "## zone alloc'd item %p from %s (%d bytes) (%d active)\n", - ptr, z->zone_name, z->zone_unitsize, - z->allocated); -#endif - return ptr; -} - -void -libxfs_zone_free(xfs_zone_t *z, void *ptr) -{ -#ifdef MEM_DEBUG - z->allocated--; - fprintf(stderr, "## zone freed item %p from %s (%d bytes) (%d active)\n", - ptr, z->zone_name, z->zone_unitsize, - z->allocated); -#endif - if (ptr != NULL) { - free(ptr); - ptr = NULL; - } -} - -void * -libxfs_malloc(size_t size) -{ - void *ptr; - - if ((ptr = calloc(1, size)) == NULL) { - fprintf(stderr, _("%s: calloc failed (%d bytes): %s\n"), - progname, (int)size, strerror(errno)); - exit(1); - } -#ifdef MEM_DEBUG - fprintf(stderr, "## calloc'd item %p size %d bytes\n", ptr, size); -#endif - return ptr; -} - -void -libxfs_free(void *ptr) -{ -#ifdef MEM_DEBUG - fprintf(stderr, "## freed item %p\n", ptr); -#endif - if (ptr != NULL) { - free(ptr); - ptr = NULL; - } -} - -void * -libxfs_realloc(void *ptr, size_t size) -{ -#ifdef MEM_DEBUG - void *optr=ptr; -#endif - if ((ptr = realloc(ptr, size)) == NULL) { - fprintf(stderr, _("%s: realloc failed (%d bytes): %s\n"), - progname, (int)size, strerror(errno)); - exit(1); - } -#ifdef MEM_DEBUG - fprintf(stderr, "## realloc'd item %p now %p size %d bytes\n", - optr, ptr, size); -#endif - return ptr; -} - - /* * Inode cache interfaces */ -extern xfs_zone_t *xfs_ili_zone; -extern xfs_zone_t *xfs_inode_zone; +extern kmem_zone_t *xfs_ili_zone; +extern kmem_zone_t *xfs_inode_zone; static unsigned int libxfs_ihash(cache_key_t key, unsigned int hashsize) @@ -801,7 +696,7 @@ libxfs_iput(xfs_inode_t *ip, uint lock_flags) static struct cache_node * libxfs_ialloc(cache_key_t key) { - return libxfs_zone_zalloc(xfs_inode_zone); + return kmem_zone_zalloc(xfs_inode_zone, 0); } static void @@ -825,10 +720,10 @@ libxfs_irelse(struct cache_node *node) if (ip != NULL) { if (ip->i_itemp) - libxfs_zone_free(xfs_ili_zone, ip->i_itemp); + kmem_zone_free(xfs_ili_zone, ip->i_itemp); ip->i_itemp = NULL; libxfs_idestroy(ip); - libxfs_zone_free(xfs_inode_zone, ip); + kmem_zone_free(xfs_inode_zone, ip); ip = NULL; } } diff --git a/libxfs/trans.c b/libxfs/trans.c index c37dd808c..1c60f382a 100644 --- a/libxfs/trans.c +++ b/libxfs/trans.c @@ -37,7 +37,7 @@ libxfs_trans_alloc( ptr->t_mountp = mp; ptr->t_type = type; ptr->t_items_free = XFS_LIC_NUM_SLOTS; - XFS_LIC_INIT(&(ptr->t_items)); + xfs_lic_init(&ptr->t_items); #ifdef XACT_DEBUG fprintf(stderr, "allocated new transaction %p\n", ptr); #endif @@ -566,7 +566,7 @@ libxfs_trans_mod_sb( * Transaction commital code follows (i.e. write to disk in libxfs) */ -STATIC void +static void inode_item_done( xfs_inode_log_item_t *iip) { @@ -576,7 +576,7 @@ inode_item_done( xfs_buf_t *bp; int hold; int error; - extern xfs_zone_t *xfs_ili_zone; + extern kmem_zone_t *xfs_ili_zone; ip = iip->ili_inode; mp = iip->ili_item.li_mountp; @@ -592,7 +592,7 @@ inode_item_done( /* * Get the buffer containing the on-disk inode. */ - error = libxfs_itobp(mp, NULL, ip, &dip, &bp, 0); + error = xfs_itobp(mp, NULL, ip, &dip, &bp, 0, 0, 0); if (error) { fprintf(stderr, _("%s: warning - itobp failed (%d)\n"), progname, error); @@ -630,13 +630,13 @@ ili_done: ip->i_itemp = NULL; } -STATIC void +static void buf_item_done( xfs_buf_log_item_t *bip) { xfs_buf_t *bp; int hold; - extern xfs_zone_t *xfs_buf_item_zone; + extern kmem_zone_t *xfs_buf_item_zone; bp = bip->bli_buf; ASSERT(bp != NULL); @@ -673,7 +673,7 @@ trans_chunk_committed( lidp = licp->lic_descs; for (i = 0; i < licp->lic_unused; i++, lidp++) { - if (XFS_LIC_ISFREE(licp, i)) + if (xfs_lic_isfree(licp, i)) continue; lip = lidp->lid_item; if (lip->li_type == XFS_LI_BUF) @@ -702,7 +702,7 @@ trans_committed( * Special case the chunk embedded in the transaction. */ licp = &(tp->t_items); - if (!(XFS_LIC_ARE_ALL_FREE(licp))) { + if (!(xfs_lic_are_all_free(licp))) { trans_chunk_committed(licp); } @@ -713,12 +713,12 @@ trans_committed( while (licp != NULL) { trans_chunk_committed(licp); next_licp = licp->lic_next; - kmem_free(licp, sizeof(xfs_log_item_chunk_t)); + kmem_free(licp); licp = next_licp; } } -STATIC void +static void buf_item_unlock( xfs_buf_log_item_t *bip) { @@ -734,7 +734,7 @@ buf_item_unlock( bip->bli_flags &= ~XFS_BLI_HOLD; } -STATIC void +static void inode_item_unlock( xfs_inode_log_item_t *iip) { @@ -773,7 +773,7 @@ xfs_trans_unlock_chunk( freed = 0; lidp = licp->lic_descs; for (i = 0; i < licp->lic_unused; i++, lidp++) { - if (XFS_LIC_ISFREE(licp, i)) { + if (xfs_lic_isfree(licp, i)) { continue; } lip = lidp->lid_item; @@ -799,7 +799,7 @@ xfs_trans_unlock_chunk( */ if (!(freeing_chunk) && (!(lidp->lid_flags & XFS_LID_DIRTY) || abort)) { - XFS_LIC_RELSE(licp, i); + xfs_lic_relse(licp, i); freed++; } } @@ -814,8 +814,7 @@ xfs_trans_unlock_chunk( int libxfs_trans_commit( xfs_trans_t *tp, - uint flags, - xfs_lsn_t *commit_lsn_p) + uint flags) { xfs_sb_t *sbp; @@ -842,7 +841,7 @@ libxfs_trans_commit( sbp->sb_fdblocks += tp->t_fdblocks_delta; if (tp->t_frextents_delta) sbp->sb_frextents += tp->t_frextents_delta; - libxfs_mod_sb(tp, XFS_SB_ALL_BITS); + xfs_mod_sb(tp, XFS_SB_ALL_BITS); } #ifdef XACT_DEBUG diff --git a/libxfs/util.c b/libxfs/util.c index d7aa57992..be9ad09e0 100644 --- a/libxfs/util.c +++ b/libxfs/util.c @@ -40,10 +40,6 @@ libxfs_ichgtime(xfs_inode_t *ip, int flags) ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec; ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec; } - if (flags & XFS_ICHGTIME_ACC) { - ip->i_d.di_atime.t_sec = (__int32_t)tv.tv_sec; - ip->i_d.di_atime.t_nsec = (__int32_t)tv.tv_nsec; - } if (flags & XFS_ICHGTIME_CHG) { ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec; ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec; @@ -57,6 +53,11 @@ libxfs_ichgtime(xfs_inode_t *ip, int flags) * * Initialize the inode's attributes and extent pointers if it * already has them (it will not if the inode has no links). + * + * NOTE: this has slightly different behaviour to the kernel in + * that this version requires the already allocated *ip being + * passed in while the kernel version does the allocation and + * returns it in **ip. */ int libxfs_iread( @@ -72,35 +73,95 @@ libxfs_iread( ip->i_ino = ino; ip->i_mount = mp; - if ((error = xfs_itobp(mp, tp, ip, &dip, &bp, bno))) + + /* + * Get pointer's to the on-disk inode and the buffer containing it. + * If the inode number refers to a block outside the file system + * then xfs_itobp() will return NULL. In this case we should + * return NULL as well. Set i_blkno to 0 so that xfs_itobp() will + * know that this is a new incore inode. + */ + error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, 0, XFS_BUF_LOCK); + if (error) return error; - if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC) { + + /* + * If we got something that isn't an inode it means someone + * (nfs or dmi) has a stale handle. + */ + if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC) { xfs_trans_brelse(tp, bp); return EINVAL; } + + /* + * If the on-disk inode is already linked to a directory + * entry, copy all of the inode into the in-core inode. + * xfs_iformat() handles copying in the inode format + * specific information. + * Otherwise, just get the truly permanent information. + */ if (dip->di_core.di_mode) { - xfs_xlate_dinode_core((xfs_caddr_t)&dip->di_core, - &(ip->i_d), 1); - if ((error = xfs_iformat(ip, dip))) { + xfs_dinode_from_disk(&ip->i_d, &dip->di_core); + error = xfs_iformat(ip, dip); + if (error) { xfs_trans_brelse(tp, bp); return error; } } else { - ip->i_d.di_magic = INT_GET(dip->di_core.di_magic, ARCH_CONVERT); - ip->i_d.di_version = INT_GET(dip->di_core.di_version, ARCH_CONVERT); - ip->i_d.di_gen = INT_GET(dip->di_core.di_gen, ARCH_CONVERT); - ip->i_d.di_flushiter = INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT); + ip->i_d.di_magic = be16_to_cpu(dip->di_core.di_magic); + ip->i_d.di_version = dip->di_core.di_version; + ip->i_d.di_gen = be32_to_cpu(dip->di_core.di_gen); + ip->i_d.di_flushiter = be16_to_cpu(dip->di_core.di_flushiter); + /* + * Make sure to pull in the mode here as well in + * case the inode is released without being used. + * This ensures that xfs_inactive() will see that + * the inode is already free and not try to mess + * with the uninitialized part of it. + */ ip->i_d.di_mode = 0; + /* + * Initialize the per-fork minima and maxima for a new + * inode here. xfs_iformat will do it for old inodes. + */ ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); } + + /* + * The inode format changed when we moved the link count and + * made it 32 bits long. If this is an old format inode, + * convert it in memory to look like a new one. If it gets + * flushed to disk we will convert back before flushing or + * logging it. We zero out the new projid field and the old link + * count field. We'll handle clearing the pad field (the remains + * of the old uuid field) when we actually convert the inode to + * the new format. We don't change the version number so that we + * can distinguish this from a real new format inode. + */ if (ip->i_d.di_version == XFS_DINODE_VERSION_1) { ip->i_d.di_nlink = ip->i_d.di_onlink; ip->i_d.di_onlink = 0; ip->i_d.di_projid = 0; } + ip->i_delayed_blks = 0; - XFS_BUF_SET_REF(bp, XFS_INO_REF); + ip->i_size = ip->i_d.di_size; + + /* + * Use xfs_trans_brelse() to release the buffer containing the + * on-disk inode, because it was acquired with xfs_trans_read_buf() + * in xfs_itobp() above. If tp is NULL, this is just a normal + * brelse(). If we're within a transaction, then xfs_trans_brelse() + * will only release the buffer if it is not dirty within the + * transaction. It will be OK to release the buffer in this case, + * because inodes on disk are never destroyed and we will be + * locking the new in-core inode before putting it in the hash + * table where other processes can find it. Thus we don't have + * to worry about the inode being changed just because we released + * the buffer. + */ xfs_trans_brelse(tp, bp); return 0; } @@ -114,7 +175,7 @@ libxfs_iread( * This was once shared with the kernel, but has diverged to the point * where its no longer worth the hassle of maintaining common code. */ -static int +int libxfs_ialloc( xfs_trans_t *tp, xfs_inode_t *pip, @@ -167,7 +228,7 @@ libxfs_ialloc( * the inode version number now. This way we only do the conversion * here rather than here and in the flush/logging code. */ - if (XFS_SB_VERSION_HASNLINK(&tp->t_mountp->m_sb) && + if (xfs_sb_version_hasnlink(&tp->t_mountp->m_sb) && ip->i_d.di_version == XFS_DINODE_VERSION_1) { ip->i_d.di_version = XFS_DINODE_VERSION_2; /* old link count, projid field, pad field already zeroed */ @@ -182,7 +243,7 @@ libxfs_ialloc( ip->i_d.di_size = 0; ip->i_d.di_nextents = 0; ASSERT(ip->i_d.di_nblocks == 0); - xfs_ichgtime(ip, XFS_ICHGTIME_CHG|XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD); + xfs_ichgtime(ip, XFS_ICHGTIME_CHG|XFS_ICHGTIME_MOD); /* * di_gen will have been taken care of in xfs_iread. */ @@ -250,10 +311,11 @@ libxfs_ialloc( } void -libxfs_iprint(xfs_inode_t *ip) +libxfs_iprint( + xfs_inode_t *ip) { - xfs_dinode_core_t *dip; - xfs_bmbt_rec_t *ep; + xfs_icdinode_t *dip; + xfs_bmbt_rec_host_t *ep; xfs_extnum_t i; xfs_extnum_t nextents; @@ -268,7 +330,8 @@ libxfs_iprint(xfs_inode_t *ip) (unsigned long)ip->i_df.if_u1.if_extents); if (ip->i_df.if_flags & XFS_IFEXTENTS) { nextents = ip->i_df.if_bytes / (uint)sizeof(*ep); - for (ep = ip->i_df.if_u1.if_extents, i = 0; i < nextents; i++, ep++) { + for (ep = ip->i_df.if_u1.if_extents, i = 0; i < nextents; + i++, ep++) { xfs_bmbt_irec_t rec; xfs_bmbt_get_all(ep, &rec); @@ -283,7 +346,7 @@ libxfs_iprint(xfs_inode_t *ip) printf(" i_df.if_broot %lx\n", (unsigned long)ip->i_df.if_broot); printf(" i_df.if_broot_bytes %x\n", ip->i_df.if_broot_bytes); - dip = &(ip->i_d); + dip = &ip->i_d; printf("\nOn disk portion\n"); printf(" di_magic %x\n", dip->di_magic); printf(" di_mode %o\n", dip->di_mode); @@ -334,7 +397,6 @@ libxfs_iflush_int(xfs_inode_t *ip, xfs_buf_t *bp) /* set *dip = inode's place in the buffer */ dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_boffset); -#ifdef DEBUG ASSERT(ip->i_d.di_magic == XFS_DINODE_MAGIC); if ((ip->i_d.di_mode & S_IFMT) == S_IFREG) { ASSERT( (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS) || @@ -347,7 +409,6 @@ libxfs_iflush_int(xfs_inode_t *ip, xfs_buf_t *bp) } ASSERT(ip->i_d.di_nextents+ip->i_d.di_anextents <= ip->i_d.di_nblocks); ASSERT(ip->i_d.di_forkoff <= mp->m_sb.sb_inodesize); -#endif /* * Copy the dirty parts of the inode into the on-disk @@ -355,7 +416,7 @@ libxfs_iflush_int(xfs_inode_t *ip, xfs_buf_t *bp) * because if the inode is dirty at all the core must * be. */ - xfs_xlate_dinode_core((xfs_caddr_t)&(dip->di_core), &(ip->i_d), -1); + xfs_dinode_to_disk(&dip->di_core, &ip->i_d); /* * If this is really an old format inode and the superblock version @@ -364,15 +425,14 @@ libxfs_iflush_int(xfs_inode_t *ip, xfs_buf_t *bp) * has been updated, then make the conversion permanent. */ ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1 || - XFS_SB_VERSION_HASNLINK(&mp->m_sb)); + xfs_sb_version_hasnlink(&mp->m_sb)); if (ip->i_d.di_version == XFS_DINODE_VERSION_1) { - if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) { + if (!xfs_sb_version_hasnlink(&mp->m_sb)) { /* * Convert it back. */ ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1); - INT_SET(dip->di_core.di_onlink, ARCH_CONVERT, - ip->i_d.di_nlink); + dip->di_core.di_onlink = cpu_to_be16(ip->i_d.di_nlink); } else { /* * The superblock version has already been bumped, @@ -380,185 +440,23 @@ libxfs_iflush_int(xfs_inode_t *ip, xfs_buf_t *bp) * format permanent. */ ip->i_d.di_version = XFS_DINODE_VERSION_2; - INT_SET(dip->di_core.di_version, ARCH_CONVERT, - XFS_DINODE_VERSION_2); + dip->di_core.di_version = XFS_DINODE_VERSION_2; ip->i_d.di_onlink = 0; dip->di_core.di_onlink = 0; memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); memset(&(dip->di_core.di_pad[0]), 0, - sizeof(dip->di_core.di_pad)); + sizeof(dip->di_core.di_pad)); ASSERT(ip->i_d.di_projid == 0); } } - if (xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK, bp) == EFSCORRUPTED) - return EFSCORRUPTED; - if (XFS_IFORK_Q(ip)) { - /* The only error from xfs_iflush_fork is on the data fork. */ + xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK, bp); + if (XFS_IFORK_Q(ip)) xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK, bp); - } return 0; } -/* - * Given a block number in a fork, return the next valid block number - * (not a hole). - * If this is the last block number then NULLFILEOFF is returned. - * - * This was originally in the kernel, but only used in xfs_repair. - */ -int -libxfs_bmap_next_offset( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode */ - xfs_fileoff_t *bnop, /* current block */ - int whichfork) /* data or attr fork */ -{ - xfs_fileoff_t bno; /* current block */ - int eof; /* hit end of file */ - int error; /* error return value */ - xfs_bmbt_irec_t got; /* current extent value */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_extnum_t lastx; /* last extent used */ - xfs_bmbt_irec_t prev; /* previous extent value */ - - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) - return XFS_ERROR(EIO); - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { - *bnop = NULLFILEOFF; - return 0; - } - ifp = XFS_IFORK_PTR(ip, whichfork); - if (!(ifp->if_flags & XFS_IFEXTENTS) && - (error = xfs_iread_extents(tp, ip, whichfork))) - return error; - bno = *bnop + 1; - xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); - if (eof) - *bnop = NULLFILEOFF; - else - *bnop = got.br_startoff < bno ? bno : got.br_startoff; - return 0; -} - -/* - * Like xfs_dir_removename, but only for removing entries with - * (name, hashvalue) pairs that may not be consistent (hashvalue - * may not be correctly set for the name). - * - * This was originally in the kernel, but only used in xfs_repair. - */ -int -xfs_dir_bogus_removename(xfs_trans_t *trans, xfs_inode_t *dp, uchar_t *name, - xfs_fsblock_t *firstblock, xfs_bmap_free_t *flist, - xfs_extlen_t total, xfs_dahash_t hashval, int namelen) -{ - xfs_da_args_t args; - int count, totallen, newsize, retval; - - ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); - if (namelen >= MAXNAMELEN) { - return EINVAL; - } - - /* - * Fill in the arg structure for this request. - */ - args.name = name; - args.namelen = namelen; - args.hashval = hashval; - args.inumber = 0; - args.dp = dp; - args.firstblock = firstblock; - args.flist = flist; - args.total = total; - args.whichfork = XFS_DATA_FORK; - args.trans = trans; - args.justcheck = args.addname = 0; - args.oknoent = 1; - - /* - * Decide on what work routines to call based on the inode size. - */ - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { - retval = xfs_dir_shortform_removename(&args); - } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { - retval = xfs_dir_leaf_removename(&args, &count, &totallen); - if (retval == 0) { - newsize = XFS_DIR_SF_ALLFIT(count, totallen); - if (newsize <= XFS_IFORK_DSIZE(dp)) { - retval = xfs_dir_leaf_to_shortform(&args); - } - } - } else { - retval = xfs_dir_node_removename(&args); - } - return(retval); -} - -/* - * Like xfs_dir_removename, but only for removing entries with - * (name, hashvalue) pairs that may not be consistent (hashvalue - * may not be correctly set for the name). - * - * This was originally in the kernel, but only used in xfs_repair. - */ -int -xfs_dir2_bogus_removename( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *dp, /* incore directory inode */ - uchar_t *name, /* name of entry to remove */ - xfs_fsblock_t *first, /* bmap's firstblock */ - xfs_bmap_free_t *flist, /* bmap's freeblock list */ - xfs_extlen_t total, /* bmap's total block count */ - xfs_dahash_t hash, /* name's real hash value */ - int namelen) /* entry's name length */ -{ - xfs_da_args_t args; /* operation arguments */ - int rval; /* return value */ - int v; /* type-checking value */ - - ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); - if (namelen >= MAXNAMELEN) - return EINVAL; - - /* - * Fill in the arg structure for this request. - */ - args.name = name; - args.namelen = namelen; - args.hashval = hash; - args.inumber = 0; - args.dp = dp; - args.firstblock = first; - args.flist = flist; - args.total = total; - args.whichfork = XFS_DATA_FORK; - args.trans = tp; - args.justcheck = args.addname = 0; - args.oknoent = 1; - - /* - * Decide on what work routines to call based on the inode size. - */ - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) - rval = xfs_dir2_sf_removename(&args); - else if ((rval = xfs_dir2_isblock(tp, dp, &v))) - return rval; - else if (v) - rval = xfs_dir2_block_removename(&args); - else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) - return rval; - else if (v) - rval = xfs_dir2_leaf_removename(&args); - else - rval = xfs_dir2_node_removename(&args); - return rval; -} - /* * Utility routine common used to apply a delta to a field in the * in-core superblock. @@ -566,10 +464,14 @@ xfs_dir2_bogus_removename( * Fields are not allowed to dip below zero, so if the delta would * do this do not apply it and return EINVAL. * - * Originally derived from xfs_mod_incore_sb(). + * Originally derived from xfs_mod_incore_sb_unlocked(). */ int -libxfs_mod_incore_sb(xfs_mount_t *mp, xfs_sb_field_t field, int delta, int rsvd) +libxfs_mod_incore_sb( + xfs_mount_t *mp, + xfs_sb_field_t field, + int64_t delta, + int rsvd) { long long lcounter; /* long counter for 64 bit fields */ @@ -578,20 +480,19 @@ libxfs_mod_incore_sb(xfs_mount_t *mp, xfs_sb_field_t field, int delta, int rsvd) lcounter = (long long)mp->m_sb.sb_fdblocks; lcounter += delta; if (lcounter < 0) - return (XFS_ERROR(ENOSPC)); + return XFS_ERROR(ENOSPC); mp->m_sb.sb_fdblocks = lcounter; - break; + return 0; default: ASSERT(0); + return XFS_ERROR(EINVAL); } - return 0; } int libxfs_bmap_finish( xfs_trans_t **tp, xfs_bmap_free_t *flist, - xfs_fsblock_t firstblock, int *committed) { xfs_bmap_free_item_t *free; /* free extent list item */ @@ -670,16 +571,16 @@ libxfs_alloc_file_space( XFS_BMAP_INIT(&free_list, &firstfsb); error = xfs_bmapi(tp, ip, startoffset_fsb, allocatesize_fsb, xfs_bmapi_flags, &firstfsb, 0, imapp, - &reccount, &free_list); + &reccount, &free_list, NULL); if (error) break; /* complete the transaction */ - error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed); + error = xfs_bmap_finish(&tp, &free_list, &committed); if (error) break; - error = xfs_trans_commit(tp, 0, NULL); + error = xfs_trans_commit(tp, 0); if (error) break; @@ -721,7 +622,7 @@ libxfs_da_read_bufr( xfs_dabuf_t **bpp, int whichfork) { - return libxfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 2, + return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 2, (inst_t *)__return_address); } @@ -790,7 +691,7 @@ libxfs_inode_alloc( if (call_again) { xfs_trans_bhold(*tp, ialloc_context); ntp = xfs_trans_dup(*tp); - xfs_trans_commit(*tp, 0, NULL); + xfs_trans_commit(*tp, 0); *tp = ntp; if ((i = xfs_trans_reserve(*tp, 0, 0, 0, 0, 0))) { fprintf(stderr, _("%s: cannot reserve space: %s\n"), @@ -817,7 +718,7 @@ libxfs_inode_alloc( * Userspace versions of common diagnostic routines (varargs fun). */ void -xfs_fs_repair_cmn_err(int level, xfs_mount_t *mp, char *fmt, ...) +libxfs_fs_repair_cmn_err(int level, xfs_mount_t *mp, char *fmt, ...) { va_list ap; @@ -830,7 +731,7 @@ xfs_fs_repair_cmn_err(int level, xfs_mount_t *mp, char *fmt, ...) } void -xfs_fs_cmn_err(int level, xfs_mount_t *mp, char *fmt, ...) +libxfs_fs_cmn_err(int level, xfs_mount_t *mp, char *fmt, ...) { va_list ap; diff --git a/libxfs/xfs.h b/libxfs/xfs.h index 7da88a931..b99e569d6 100644 --- a/libxfs/xfs.h +++ b/libxfs/xfs.h @@ -44,140 +44,152 @@ #include +typedef struct { dev_t dev; } xfs_buftarg_t; + +typedef __uint32_t uint_t; +typedef __uint32_t inst_t; /* an instruction */ + + +#define m_ddev_targp m_dev + +#define STATIC static +#define STATIC_INLINE static inline + +#define ATTR_ROOT LIBXFS_ATTR_ROOT +#define ATTR_SECURE LIBXFS_ATTR_SECURE +#define ATTR_CREATE LIBXFS_ATTR_CREATE +#define ATTR_REPLACE LIBXFS_ATTR_REPLACE +#define ATTR_KERNOTIME 0 +#define ATTR_KERNOVAL 0 + +#define IHOLD(ip) ((void) 0) + +#define XFS_CORRUPTION_ERROR(e,l,mp,m) ((void) 0) +#define XFS_QM_DQATTACH(mp,ip,flags) 0 +#define XFS_ERROR(e) (e) +#define XFS_ERROR_REPORT(e,l,mp) ((void) 0) +#define XFS_ERRLEVEL_LOW 1 +#define XFS_FORCED_SHUTDOWN(mp) 0 +#define XFS_ILOCK_EXCL 0 +#define XFS_STATS_INC(count) do { } while (0) +#define XFS_STATS_DEC(count, x) do { } while (0) +#define XFS_STATS_ADD(count, x) do { } while (0) +#define XFS_TRANS_MOD_DQUOT_BYINO(mp,tp,ip,field,delta) do { } while (0) +#define XFS_TRANS_RESERVE_QUOTA_NBLKS(mp,tp,ip,nblks,ninos,fl) 0 +#define XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp,tp,ip,nblks,ninos,fl) 0 +#define XFS_TEST_ERROR(expr,a,b,c) ( expr ) +#define XFS_WANT_CORRUPTED_GOTO(expr,l) \ + { if (!(expr)) { error = EFSCORRUPTED; goto l; } } +#define XFS_WANT_CORRUPTED_RETURN(expr) \ + { if (!(expr)) { return EFSCORRUPTED; } } + +#define TRACE_FREE(s,a,b,x,f) ((void) 0) +#define TRACE_ALLOC(s,a) ((void) 0) +#define TRACE_MODAGF(a,b,c) ((void) 0) + +#ifdef __GNUC__ +#define __return_address __builtin_return_address(0) +#endif + +/* miscellaneous kernel routines not in user space */ +#define down_read(a) ((void) 0) +#define up_read(a) ((void) 0) +#define spin_lock_init(a) ((void) 0) +#define spin_lock(a) ((void) 0) +#define spin_unlock(a) ((void) 0) +#define likely(x) (x) +#define unlikely(x) (x) + /* - * Map XFS kernel routine names to libxfs.h names + * random32 is used for di_gen inode allocation, it must be zero for libxfs + * or all sorts of badness can occur! */ +#define random32() 0 -#define xfs_xlatesb libxfs_xlate_sb -#define xfs_xlate_dinode_core libxfs_xlate_dinode_core -#define xfs_bmbt_get_all libxfs_bmbt_get_all -#if __BYTE_ORDER != __BIG_ENDIAN -#define xfs_bmbt_disk_get_all libxfs_bmbt_disk_get_all -#else -#define xfs_bmbt_disk_get_all libxfs_bmbt_get_all -#endif -#define xfs_da_hashname libxfs_da_hashname -#define xfs_da_log2_roundup libxfs_da_log2_roundup -#define xfs_highbit32 libxfs_highbit32 -#define xfs_highbit64 libxfs_highbit64 -#define xfs_alloc_compute_maxlevels libxfs_alloc_compute_maxlevels -#define xfs_bmap_compute_maxlevels libxfs_bmap_compute_maxlevels -#define xfs_ialloc_compute_maxlevels libxfs_ialloc_compute_maxlevels - -#define xfs_dir_init libxfs_dir_init -#define xfs_dir2_init libxfs_dir2_init -#define xfs_dir_mount libxfs_dir_mount -#define xfs_dir2_mount libxfs_dir2_mount -#define xfs_dir_createname libxfs_dir_createname -#define xfs_dir2_createname libxfs_dir2_createname -#define xfs_dir_lookup libxfs_dir_lookup -#define xfs_dir2_lookup libxfs_dir2_lookup -#define xfs_dir_replace libxfs_dir_replace -#define xfs_dir2_replace libxfs_dir2_replace -#define xfs_dir_removename libxfs_dir_removename -#define xfs_dir2_removename libxfs_dir2_removename -#define xfs_dir_bogus_removename libxfs_dir_bogus_removename -#define xfs_dir2_bogus_removename libxfs_dir2_bogus_removename -#define xfs_dir_shortform_to_leaf libxfs_dir_shortform_to_leaf -#define xfs_dir2_sf_to_block libxfs_dir2_sf_to_block -#define XFS_DIR_SHORTFORM_TO_SINGLE(mp, daargs) XFS_DIR_IS_V2(mp) ? \ - libxfs_dir2_sf_to_block(daargs) : \ - libxfs_dir_shortform_to_leaf(daargs); - -#define xfs_mount_common libxfs_mount_common -#define xfs_initialize_perag libxfs_initialize_perag -#define xfs_initialize_perag_data libxfs_initialize_perag_data -#define xfs_rtmount_init libxfs_rtmount_init -#define xfs_alloc_fix_freelist libxfs_alloc_fix_freelist -#define xfs_idata_realloc libxfs_idata_realloc -#define xfs_idestroy_fork libxfs_idestroy_fork -#define xfs_iread libxfs_iread -#define xfs_itobp libxfs_itobp -#define xfs_iformat libxfs_iformat -#define xfs_ichgtime libxfs_ichgtime -#define xfs_bmapi libxfs_bmapi -#define xfs_bmapi_single libxfs_bmapi_single -#define xfs_bmap_finish libxfs_bmap_finish -#define xfs_bmap_cancel libxfs_bmap_cancel -#define xfs_bmap_del_free libxfs_bmap_del_free -#define xfs_bmap_last_offset libxfs_bmap_last_offset -#define xfs_bunmapi libxfs_bunmapi -#define xfs_free_extent libxfs_free_extent -#define xfs_rtfree_extent libxfs_rtfree_extent -#define xfs_mod_sb libxfs_mod_sb -#define xfs_mod_incore_sb libxfs_mod_incore_sb +#define PAGE_CACHE_SIZE getpagesize() -#define xfs_trans_init libxfs_trans_init -#define xfs_trans_dup libxfs_trans_dup -#define xfs_trans_iget libxfs_trans_iget -#define xfs_trans_ijoin libxfs_trans_ijoin -#define xfs_trans_ihold libxfs_trans_ihold -#define xfs_trans_bjoin libxfs_trans_bjoin -#define xfs_trans_bhold libxfs_trans_bhold -#define xfs_trans_alloc libxfs_trans_alloc -#define xfs_trans_commit libxfs_trans_commit -#define xfs_trans_cancel libxfs_trans_cancel -#define xfs_trans_reserve libxfs_trans_reserve -#define xfs_trans_getsb libxfs_trans_getsb -#define xfs_trans_mod_sb libxfs_trans_mod_sb -#define xfs_trans_get_buf libxfs_trans_get_buf -#define xfs_trans_log_buf libxfs_trans_log_buf -#define xfs_trans_read_buf libxfs_trans_read_buf -#define xfs_trans_log_inode libxfs_trans_log_inode -#define xfs_trans_inode_alloc_buf libxfs_trans_inode_alloc_buf -#define xfs_trans_brelse libxfs_trans_brelse -#define xfs_trans_binval libxfs_trans_binval +#define INIT_LIST_HEAD(x) + +static inline int __do_div(unsigned long long *n, unsigned base) +{ + int __res; + __res = (int)(((unsigned long) *n) % (unsigned) base); + *n = ((unsigned long) *n) / (unsigned) base; + return __res; +} + +#define do_div(n,base) (__do_div((unsigned long long *)&(n), (base))) +#define do_mod(a, b) ((a) % (b)) +#define rol32(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) -#define xfs_da_shrink_inode libxfs_da_shrink_inode -#define xfs_da_grow_inode libxfs_da_grow_inode -#define xfs_da_brelse libxfs_da_brelse -#define xfs_da_read_buf libxfs_da_read_buf -#define xfs_da_get_buf libxfs_da_get_buf -#define xfs_da_log_buf libxfs_da_log_buf -#define xfs_da_do_buf libxfs_da_do_buf -#define xfs_dir2_shrink_inode libxfs_dir2_shrink_inode -#define xfs_dir2_grow_inode libxfs_dir2_grow_inode -#define xfs_dir2_isleaf libxfs_dir2_isleaf -#define xfs_dir2_isblock libxfs_dir2_isblock -#define xfs_dir2_data_use_free libxfs_dir2_data_use_free -#define xfs_dir2_data_make_free libxfs_dir2_data_make_free -#define xfs_dir2_data_log_entry libxfs_dir2_data_log_entry -#define xfs_dir2_data_log_header libxfs_dir2_data_log_header -#define xfs_dir2_data_freescan libxfs_dir2_data_freescan -#define xfs_dir2_free_log_bests libxfs_dir2_free_log_bests - -#define xfs_attr_leaf_newentsize libxfs_attr_leaf_newentsize -#define xfs_attr_set_int libxfs_attr_set_int -#define xfs_attr_remove_int libxfs_attr_remove_int +#define min_t(type,x,y) \ + ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) +#define max_t(type,x,y) \ + ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) +/* only 64 bit accesses used in xfs kernel code */ +static inline __u64 get_unaligned_be64(void *ptr) +{ + __be64 __tmp; + memmove(&__tmp, ptr, 8); + return be64_to_cpu(__tmp); +} + +static inline void put_unaligned(__be64 val, void *ptr) +{ + memmove(ptr, &val, 8); +} + +static inline __attribute__((const)) +int is_power_of_2(unsigned long n) +{ + return (n != 0 && ((n & (n - 1)) == 0)); +} /* - * Infrastructure to support building kernel XFS code in user space + * xfs_iroundup: round up argument to next power of two */ +static inline uint +roundup_pow_of_two(uint v) +{ + int i; + uint m; + + if ((v & (v - 1)) == 0) + return v; + ASSERT((v & 0x80000000) == 0); + if ((v & (v + 1)) == 0) + return v + 1; + for (i = 0, m = 1; i < 31; i++, m <<= 1) { + if (v & m) + continue; + v |= m; + if ((v & (v + 1)) == 0) + return v + 1; + } + ASSERT(0); + return 0; +} /* buffer management */ #define XFS_BUF_LOCK 0 -#define XFS_BUF_MAPPED 0 #define XFS_BUF_TRYLOCK 0 #define XFS_BUF_GETERROR(bp) 0 #define XFS_BUF_DONE(bp) ((bp)->b_flags |= LIBXFS_B_UPTODATE) #define XFS_BUF_ISDONE(bp) ((bp)->b_flags & LIBXFS_B_UPTODATE) #define XFS_BUF_STALE(bp) ((bp)->b_flags |= LIBXFS_B_STALE) #define XFS_BUF_UNDELAYWRITE(bp) ((bp)->b_flags &= ~LIBXFS_B_DIRTY) -#define XFS_BUF_SET_REF(a,b) ((void) 0) #define XFS_BUF_SET_VTYPE(a,b) ((void) 0) #define XFS_BUF_SET_VTYPE_REF(a,b,c) ((void) 0) #define XFS_BUF_SET_BDSTRAT_FUNC(a,b) ((void) 0) + #define xfs_incore(bt,blkno,len,lockit) 0 -#define xfs_baread(a,b,c) ((void) 0) /* no readahead */ -#define xfs_buftrace(x,y) ((void) 0) /* debug only */ -#define xfs_buf_item_log_debug(bip,a,b) ((void) 0) /* debug only */ -#define xfs_validate_extents(e,n,d,f) ((void) 0) /* debug only */ #define xfs_buf_relse(bp) libxfs_putbuf(bp) #define xfs_read_buf(mp,devp,blkno,len,f,bpp) \ - ( *(bpp) = libxfs_readbuf( *(dev_t*)devp, (blkno), (len), 1), 0 ) + (*(bpp) = libxfs_readbuf((devp), \ + (blkno), (len), 1), 0) #define xfs_buf_get_flags(devp,blkno,len,f) \ - ( libxfs_getbuf( devp, (blkno), (len) ) ) + (libxfs_getbuf((devp), (blkno), (len))) #define xfs_bwrite(mp,bp) libxfs_writebuf((bp), 0) #define XFS_B_READ LIBXFS_BREAD @@ -185,32 +197,63 @@ #define xfs_biomove(bp,off,len,data,f) libxfs_iomove(bp,off,len,data,f) #define xfs_biozero(bp,off,len) libxfs_iomove(bp,off,len,0,LIBXFS_BZERO) -/* transaction management */ -#define xfs_trans_set_sync(tp) ((void) 0) -#define xfs_trans_agblocks_delta(tp, d) ((void) 0) /* debug only */ -#define xfs_trans_agflist_delta(tp, d) ((void) 0) /* debug only */ -#define xfs_trans_agbtree_delta(tp, d) ((void) 0) /* debug only */ -#define xfs_trans_mod_dquot_byino(tp,ip,f,d) ((void) 0) -#define xfs_trans_get_block_res(tp) 1 -#define xfs_trans_reserve_blkquota(tp,i,n) 0 -#define xfs_trans_unreserve_blkquota(tp,i,n) ((void) 0) -#define xfs_trans_unreserve_rtblkquota(tp,i,n) ((void) 0) - -/* memory management */ -#define KM_SLEEP 1 -#define KM_SLEEP_IO 2 -#define kmem_zone xfs_zone -#define kmem_zone_t xfs_zone_t -#define kmem_zone_init(a, b) libxfs_zone_init(a, b) -#define kmem_zone_alloc(z, f) libxfs_zone_zalloc(z) -#define kmem_zone_zalloc(z, f) libxfs_zone_zalloc(z) -#define kmem_zone_free(z, p) libxfs_zone_free(z, p) -#define kmem_realloc(p,sz,u,f) libxfs_realloc(p,sz) -#define kmem_zalloc(size, f) libxfs_malloc(size) -#define kmem_alloc(size, f) libxfs_malloc(size) -#define kmem_free(p, size) libxfs_free(p) - -/* directory management */ +/* mount stuff */ +#define XFS_MOUNT_32BITINODES LIBXFS_MOUNT_32BITINODES +#define XFS_MOUNT_ATTR2 LIBXFS_MOUNT_ATTR2 +#define XFS_MOUNT_SMALL_INUMS 0 /* ignored in userspace */ +#define XFS_MOUNT_WSYNC 0 /* ignored in userspace */ +#define XFS_MOUNT_NOALIGN 0 /* ignored in userspace */ + +/* + * Map XFS kernel routine names to libxfs versions + */ + +#define xfs_alloc_fix_freelist libxfs_alloc_fix_freelist +#define xfs_attr_get libxfs_attr_get +#define xfs_attr_set libxfs_attr_set +#define xfs_attr_remove libxfs_attr_remove +#define xfs_rtfree_extent libxfs_rtfree_extent + +#define xfs_fs_repair_cmn_err libxfs_fs_repair_cmn_err +#define xfs_fs_cmn_err libxfs_fs_cmn_err + +#define xfs_bmap_finish libxfs_bmap_finish +#define xfs_ichgtime libxfs_ichgtime +#define xfs_mod_incore_sb libxfs_mod_incore_sb + +#define xfs_trans_alloc libxfs_trans_alloc +#define xfs_trans_bhold libxfs_trans_bhold +#define xfs_trans_binval libxfs_trans_binval +#define xfs_trans_bjoin libxfs_trans_bjoin +#define xfs_trans_brelse libxfs_trans_brelse +#define xfs_trans_commit libxfs_trans_commit +#define xfs_trans_cancel libxfs_trans_cancel +#define xfs_trans_dup libxfs_trans_dup +#define xfs_trans_get_buf libxfs_trans_get_buf +#define xfs_trans_getsb libxfs_trans_getsb +#define xfs_trans_iget libxfs_trans_iget +#define xfs_trans_ihold libxfs_trans_ihold +#define xfs_trans_ijoin libxfs_trans_ijoin +#define xfs_trans_inode_alloc_buf libxfs_trans_inode_alloc_buf +#define xfs_trans_log_buf libxfs_trans_log_buf +#define xfs_trans_log_inode libxfs_trans_log_inode +#define xfs_trans_mod_sb libxfs_trans_mod_sb +#define xfs_trans_read_buf libxfs_trans_read_buf +#define xfs_trans_reserve libxfs_trans_reserve + +#define xfs_trans_get_block_res(tp) 1 +#define xfs_trans_set_sync(tp) ((void) 0) +#define xfs_trans_agblocks_delta(tp, d) +#define xfs_trans_agflist_delta(tp, d) +#define xfs_trans_agbtree_delta(tp, d) + +#define xfs_baread(a,b,c) ((void) 0) /* no readahead */ +#define xfs_btree_reada_bufl(m,fsb,c) ((void) 0) +#define xfs_btree_reada_bufs(m,fsb,c,x) ((void) 0) +#define xfs_buftrace(x,y) ((void) 0) /* debug only */ + +#define xfs_cmn_err(tag,level,mp,fmt,args...) cmn_err(level,fmt, ## args) + #define xfs_dir2_trace_args(where, args) ((void) 0) #define xfs_dir2_trace_args_b(where, args, bp) ((void) 0) #define xfs_dir2_trace_args_bb(where, args, lbp, dbp) ((void) 0) @@ -219,440 +262,53 @@ #define xfs_dir2_trace_args_i(where, args, i) ((void) 0) #define xfs_dir2_trace_args_s(where, args, s) ((void) 0) #define xfs_dir2_trace_args_sb(where, args, s, bp) ((void) 0) -#define xfs_dir_shortform_validate_ondisk(a,b) ((void) 0) - -/* block management */ -#define xfs_bmap_check_extents(ip,w) ((void) 0) -#define xfs_bmap_trace_delete(f,d,ip,i,c,w) ((void) 0) -#define xfs_bmap_trace_exlist(f,ip,i,w) ((void) 0) -#define xfs_bmap_trace_insert(f,d,ip,i,c,r1,r2,w) ((void) 0) -#define xfs_bmap_trace_post_update(f,d,ip,i,w) ((void) 0) -#define xfs_bmap_trace_pre_update(f,d,ip,i,w) ((void) 0) -#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) ((void) 0) -#define xfs_bunmap_trace(ip, bno, len, flags, ra) ((void) 0) -#define XFS_BMBT_TRACE_ARGBI(c,b,i) ((void) 0) -#define XFS_BMBT_TRACE_ARGBII(c,b,i,j) ((void) 0) -#define XFS_BMBT_TRACE_ARGFFFI(c,o,b,i,j) ((void) 0) -#define XFS_BMBT_TRACE_ARGI(c,i) ((void) 0) -#define XFS_BMBT_TRACE_ARGIFK(c,i,f,k) ((void) 0) -#define XFS_BMBT_TRACE_ARGIFR(c,i,f,r) ((void) 0) -#define XFS_BMBT_TRACE_ARGIK(c,i,k) ((void) 0) -#define XFS_BMBT_TRACE_CURSOR(c,s) ((void) 0) - -/* space allocation */ -#define xfs_alloc_search_busy(tp,ag,b,len) ((void) 0) -#define xfs_alloc_mark_busy(tp,ag,b,len) ((void) 0) -#define xfs_rotorstep 1 - -#define xfs_ilock(ip, mode) ((void)0) -#define xfs_iunlock(ip, mode) ((void)0) - -/* anything else */ -#if !defined(__sgi__) -typedef __uint32_t uint_t; -typedef __uint32_t inst_t; /* an instruction */ -#endif -typedef struct { dev_t dev; } xfs_buftarg_t; -#undef MASK -#define NBPP getpagesize() -#define STATIC -#define VN_HOLD(vp) -#define ATTR_ROOT LIBXFS_ATTR_ROOT -#define ATTR_SECURE LIBXFS_ATTR_SECURE -#define ATTR_CREATE LIBXFS_ATTR_CREATE -#define ATTR_REPLACE LIBXFS_ATTR_REPLACE -#define ATTR_KERNOTIME 0 -#define ktrace_t void -#define m_ddev_targp m_dev -#define unlikely(x) (x) -#define INIT_LIST_HEAD(x) -#define KERN_WARNING -#define XFS_ERROR(e) (e) -#define XFS_ERRLEVEL_LOW 1 -#define XFS_ERROR_REPORT(e,l,mp) ((void) 0) -#define XFS_CORRUPTION_ERROR(e,l,mp,m) ((void) 0) -#define XFS_TEST_ERROR(expr,a,b,c) ( expr ) -#define XFS_WANT_CORRUPTED_GOTO(expr,l) \ - { if (!(expr)) { error = EFSCORRUPTED; goto l; } } -#define XFS_WANT_CORRUPTED_RETURN(expr) \ - { if (!(expr)) { return EFSCORRUPTED; } } -#define TRACE_FREE(s,a,b,x,f) ((void) 0) -#define TRACE_ALLOC(s,a) ((void) 0) -#define TRACE_MODAGF(a,b,c) ((void) 0) -#define XFS_FORCED_SHUTDOWN(mp) 0 -#define XFS_STATS_INC(count) do { } while (0) -#define XFS_STATS_DEC(count, x) do { } while (0) -#define XFS_STATS_ADD(count, x) do { } while (0) -#define XFS_MOUNT_WSYNC 0 /* ignored in userspace */ -#define XFS_MOUNT_NOALIGN 0 /* ignored in userspace */ -#define XFS_MOUNT_32BITINODES LIBXFS_MOUNT_32BITINODES -#define XFS_MOUNT_32BITINOOPT LIBXFS_MOUNT_32BITINOOPT -#define XFS_MOUNT_COMPAT_ATTR LIBXFS_MOUNT_COMPAT_ATTR -#define XFS_ILOCK_EXCL 0 -#define xfs_sort qsort -#define down_read(a) ((void) 0) -#define up_read(a) ((void) 0) -#define mrlock(a,b,c) ((void) 0) -#define mraccunlock(a) ((void) 0) -#define mrunlock(a) ((void) 0) -#define mraccess(a) ((void) 0) -#define ismrlocked(a,b) 1 -#define spinlock_init(a,b) ((void) 0) -#define spin_lock(a) ((void) 0) -#define spin_unlock(a) ((void) 0) -#define xfs_btree_reada_bufl(m,fsb,c) ((void) 0) -#define xfs_btree_reada_bufs(m,fsb,c,x) ((void) 0) -#define XFS_SB_LOCK(mp) 0 -#define XFS_SB_UNLOCK(mp,s) ((void) 0) -#undef XFS_DIR_SHORTFORM_VALIDATE_ONDISK -#define XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp,dip) 0 -#define XFS_QM_DQATTACH(mp,ip,flags) 0 -#define XFS_TRANS_MOD_DQUOT_BYINO(mp,tp,ip,field,delta) do { } while (0) -#define XFS_TRANS_RESERVE_BLKQUOTA(mp,tp,ip,nblks) 0 -#define XFS_TRANS_UNRESERVE_BLKQUOTA(mp,tp,ip,nblks) 0 -#define XFS_TRANS_RESERVE_QUOTA_NBLKS(mp,tp,ip,nblks,ninos,fl) 0 -#define XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp,tp,ip,nblks,ninos,fl) 0 +#define xfs_sort qsort -extern void xfs_fs_repair_cmn_err(int, struct xfs_mount *, char *, ...); -extern void xfs_fs_cmn_err(int, struct xfs_mount *, char *, ...); +#define xfs_icsb_reinit_counters(mp) do { } while (0) +#define xfs_initialize_perag_icache(pag) ((void) 0) -#ifdef __GNUC__ -#define __return_address __builtin_return_address(0) -#endif - -static inline __u64 __get_unaligned64(void *ptr) -{ - __u64 __tmp; - memmove(&__tmp, ptr, 8); - return __tmp; -} - -static inline void __put_unaligned64(__u64 val, void *ptr) -{ - __u64 __tmp = val; - memmove(ptr, &__tmp, 8); -} - -#define get_unaligned(ptr) __get_unaligned64(ptr) -#define put_unaligned(val,ptr) __put_unaligned64(val,ptr) - -static inline int __do_div(unsigned long long *n, unsigned base) -{ - int __res; - __res = (int)(((unsigned long) *n) % (unsigned) base); - *n = ((unsigned long) *n) / (unsigned) base; - return __res; -} -#define do_div(n,base) (__do_div((unsigned long long *)&(n), (base))) -#define do_mod(a, b) ((a) % (b)) -#define rol32(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) +#define xfs_ilock(ip,mode) ((void) 0) +#define xfs_iunlock(ip,mode) ((void) 0) +/* space allocation */ +#define xfs_alloc_search_busy(tp,ag,b,len) ((void) 0) +#define xfs_alloc_mark_busy(tp,ag,b,len) ((void) 0) +#define xfs_rotorstep 1 +#define xfs_bmap_rtalloc(a) (ENOSYS) +#define xfs_rtpick_extent(mp,tp,len,p) (ENOSYS) +#define xfs_get_extsz_hint(ip) (0) +#define xfs_inode_is_filestream(ip) (0) +#define xfs_filestream_lookup_ag(ip) (0) +#define xfs_filestream_new_ag(ip,ag) (0) /* - * Prototypes needed for a clean build + * Prototypes for kernel static functions that are aren't in their + * associated header files */ -/* xfs_alloc.c */ -int xfs_alloc_get_freelist (xfs_trans_t *, xfs_buf_t *, xfs_agblock_t *, int); -void xfs_alloc_log_agf (xfs_trans_t *, xfs_buf_t *, int); -int xfs_alloc_put_freelist (xfs_trans_t *, xfs_buf_t *, xfs_buf_t *, - xfs_agblock_t, int); -int xfs_alloc_read_agf (xfs_mount_t *, xfs_trans_t *, xfs_agnumber_t, - int, xfs_buf_t **); -int xfs_alloc_vextent (xfs_alloc_arg_t *); -int xfs_alloc_pagf_init (xfs_mount_t *, xfs_trans_t *, xfs_agnumber_t, int); -int xfs_alloc_ag_vextent_size (xfs_alloc_arg_t *); -int xfs_alloc_ag_vextent_near (xfs_alloc_arg_t *); -int xfs_alloc_ag_vextent_exact (xfs_alloc_arg_t *); -int xfs_alloc_ag_vextent_small (xfs_alloc_arg_t *, xfs_btree_cur_t *, - xfs_agblock_t *, xfs_extlen_t *, int *); - -/* xfs_ialloc.c */ -int xfs_dialloc (xfs_trans_t *, xfs_ino_t, mode_t, int, xfs_buf_t **, - boolean_t *, xfs_ino_t *); -void xfs_ialloc_log_agi (xfs_trans_t *, xfs_buf_t *, int); -int xfs_ialloc_read_agi (xfs_mount_t *, xfs_trans_t *, xfs_agnumber_t, - xfs_buf_t **); -int xfs_ialloc_pagi_init (xfs_mount_t *, xfs_trans_t *, xfs_agnumber_t); -int xfs_dilocate (xfs_mount_t *, xfs_trans_t *, xfs_ino_t, xfs_fsblock_t *, - int *, int *, uint); - -/* xfs_rtalloc.c */ -int xfs_rtpick_extent (xfs_mount_t *, xfs_trans_t *, xfs_extlen_t, - xfs_rtblock_t *); -int xfs_rtfree_extent (xfs_trans_t *, xfs_rtblock_t, xfs_extlen_t); -int xfs_rtmodify_range (xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t, - xfs_extlen_t, int); -int xfs_rtmodify_summary (xfs_mount_t *, xfs_trans_t *, int, - xfs_rtblock_t, int, xfs_buf_t **, xfs_fsblock_t *); - -/* xfs_btree.c */ -extern xfs_zone_t *xfs_btree_cur_zone; -void xfs_btree_check_key (xfs_btnum_t, void *, void *); -void xfs_btree_check_rec (xfs_btnum_t, void *, void *); -int xfs_btree_check_lblock (xfs_btree_cur_t *, xfs_btree_lblock_t *, - int, xfs_buf_t *); -int xfs_btree_check_sblock (xfs_btree_cur_t *, xfs_btree_sblock_t *, - int, xfs_buf_t *); -int xfs_btree_check_sptr (xfs_btree_cur_t *, xfs_agblock_t, int); -int xfs_btree_check_lptr (xfs_btree_cur_t *, xfs_dfsbno_t, int); -void xfs_btree_del_cursor (xfs_btree_cur_t *, int); -int xfs_btree_dup_cursor (xfs_btree_cur_t *, xfs_btree_cur_t **); -int xfs_btree_firstrec (xfs_btree_cur_t *, int); -xfs_btree_block_t *xfs_btree_get_block (xfs_btree_cur_t *, int, xfs_buf_t **); -xfs_buf_t *xfs_btree_get_bufs (xfs_mount_t *, xfs_trans_t *, xfs_agnumber_t, - xfs_agblock_t, uint); -xfs_buf_t *xfs_btree_get_bufl (xfs_mount_t *, xfs_trans_t *tp, - xfs_fsblock_t, uint); -xfs_btree_cur_t *xfs_btree_init_cursor (xfs_mount_t *, xfs_trans_t *, - xfs_buf_t *, xfs_agnumber_t, xfs_btnum_t, - xfs_inode_t *, int); -int xfs_btree_islastblock (xfs_btree_cur_t *, int); -int xfs_btree_lastrec (xfs_btree_cur_t *, int); -void xfs_btree_offsets (__int64_t, const short *, int, int *, int *); -void xfs_btree_setbuf (xfs_btree_cur_t *, int, xfs_buf_t *); -int xfs_btree_read_bufs (xfs_mount_t *, xfs_trans_t *, xfs_agnumber_t, - xfs_agblock_t, uint, xfs_buf_t **, int); -int xfs_btree_read_bufl (xfs_mount_t *, xfs_trans_t *, xfs_fsblock_t, - uint, xfs_buf_t **, int); -int xfs_btree_readahead_core (xfs_btree_cur_t *, int, int); -static inline int xfs_btree_readahead (xfs_btree_cur_t *cur, int lev, int lr) -{ - if ((cur->bc_ra[lev] | lr) == cur->bc_ra[lev]) - return 0; - return xfs_btree_readahead_core(cur, lev, lr); -} - - -/* xfs_inode.c */ -int xfs_ialloc (xfs_trans_t *, xfs_inode_t *, mode_t, nlink_t, xfs_dev_t, cred_t *, - xfs_prid_t, int, xfs_buf_t **, boolean_t *, xfs_inode_t **); -int xfs_iread (xfs_mount_t *, xfs_trans_t *, xfs_ino_t, xfs_inode_t *, - xfs_daddr_t); -int xfs_iread_extents (xfs_trans_t *, xfs_inode_t *, int); -int xfs_imap (xfs_mount_t *, xfs_trans_t *, xfs_ino_t, xfs_imap_t *, uint); -int xfs_iextents_copy (xfs_inode_t *, xfs_bmbt_rec_t *, int); -int xfs_iflush_int (xfs_inode_t *, xfs_buf_t *); -int xfs_iflush_fork (xfs_inode_t *, xfs_dinode_t *, xfs_inode_log_item_t *, - int, xfs_buf_t *); -int xfs_iformat_local (xfs_inode_t *, xfs_dinode_t *, int, int); -int xfs_iformat_extents (xfs_inode_t *, xfs_dinode_t *, int); -int xfs_iformat_btree (xfs_inode_t *, xfs_dinode_t *, int); -void xfs_iroot_realloc (xfs_inode_t *, int, int); -void xfs_idata_realloc (xfs_inode_t *, int, int); -void xfs_iext_realloc (xfs_inode_t *, int, int); -void xfs_idestroy_fork (xfs_inode_t *, int); -uint xfs_iroundup (uint); +/* xfs_attr.c */ +int xfs_attr_rmtval_get(struct xfs_da_args *); /* xfs_bmap.c */ -int xfs_bmap_local_to_extents (xfs_trans_t *, xfs_inode_t *, - xfs_fsblock_t *, xfs_extlen_t, int *, int); -xfs_bmbt_rec_t *xfs_bmap_search_extents (xfs_inode_t *, - xfs_fileoff_t, int, int *, xfs_extnum_t *, - xfs_bmbt_irec_t *, xfs_bmbt_irec_t *); -int xfs_bmap_read_extents (xfs_trans_t *, xfs_inode_t *, int); -int xfs_bmap_add_attrfork (xfs_inode_t *, int, int); -void xfs_bmap_add_free (xfs_fsblock_t, xfs_filblks_t, xfs_bmap_free_t *, - xfs_mount_t *); -int xfs_bmap_first_unused (xfs_trans_t *, xfs_inode_t *, xfs_extlen_t, - xfs_fileoff_t *, int); -int xfs_bmap_last_offset (xfs_trans_t *, xfs_inode_t *, xfs_fileoff_t *, int); -int xfs_bmap_last_before (xfs_trans_t *, xfs_inode_t *, xfs_fileoff_t *, int); -int xfs_bmap_one_block (xfs_inode_t *, int); -int xfs_bmapi_single (xfs_trans_t *, xfs_inode_t *, int, xfs_fsblock_t *, - xfs_fileoff_t); -int xfs_bmapi (xfs_trans_t *, xfs_inode_t *, xfs_fileoff_t, - xfs_filblks_t, int, xfs_fsblock_t *, xfs_extlen_t, - xfs_bmbt_irec_t *, int *, xfs_bmap_free_t *); -int xfs_bunmapi (xfs_trans_t *, xfs_inode_t *, xfs_fileoff_t, - xfs_filblks_t, int, xfs_extnum_t, xfs_fsblock_t *, - xfs_bmap_free_t *, int *); -int xfs_bmap_add_extent_hole_delay (xfs_inode_t *ip, xfs_extnum_t, - xfs_btree_cur_t *, xfs_bmbt_irec_t *, int *, int); -int xfs_bmap_add_extent_hole_real (xfs_inode_t *, xfs_extnum_t, - xfs_btree_cur_t *, xfs_bmbt_irec_t *, int *, int); -int xfs_bmap_add_extent_unwritten_real (xfs_inode_t *, xfs_extnum_t, - xfs_btree_cur_t **, xfs_bmbt_irec_t *, int *); -int xfs_bmap_add_extent_delay_real (xfs_inode_t *, xfs_extnum_t, - xfs_btree_cur_t **, xfs_bmbt_irec_t *, xfs_filblks_t *, - xfs_fsblock_t *, xfs_bmap_free_t *, int *, int); -int xfs_bmap_extents_to_btree (xfs_trans_t *, xfs_inode_t *, xfs_fsblock_t *, - xfs_bmap_free_t *, xfs_btree_cur_t **, int, int *, int); -void xfs_bmap_delete_exlist (xfs_inode_t *, xfs_extnum_t, xfs_extnum_t, int); -xfs_filblks_t xfs_bmap_worst_indlen (xfs_inode_t *, xfs_filblks_t); -void xfs_bmap_cancel (xfs_bmap_free_t *); -int xfs_bmap_isaeof (xfs_inode_t *, xfs_fileoff_t, int, char *); -void xfs_bmap_insert_exlist (xfs_inode_t *, xfs_extnum_t, xfs_extnum_t, - xfs_bmbt_irec_t *, int); - -/* xfs_bmap_btree.c */ -int xfs_check_nostate_extents (xfs_bmbt_rec_t *, xfs_extnum_t); -void xfs_bmbt_log_ptrs (xfs_btree_cur_t *, xfs_buf_t *, int, int); -void xfs_bmbt_log_keys (xfs_btree_cur_t *, xfs_buf_t *, int, int); -int xfs_bmbt_newroot (xfs_btree_cur_t *, int *, int *); -int xfs_bmbt_killroot (xfs_btree_cur_t *); -int xfs_bmbt_updkey (xfs_btree_cur_t *, xfs_bmbt_key_t *, int); -int xfs_bmbt_lshift (xfs_btree_cur_t *, int, int *); -int xfs_bmbt_rshift (xfs_btree_cur_t *, int, int *); -int xfs_bmbt_split (xfs_btree_cur_t *, int, xfs_fsblock_t *, - xfs_bmbt_key_t *, xfs_btree_cur_t **, int *); -void xfs_bmbt_set_all (xfs_bmbt_rec_t *, xfs_bmbt_irec_t *); -void xfs_bmbt_set_allf (xfs_bmbt_rec_t *, xfs_fileoff_t, xfs_fsblock_t, - xfs_filblks_t, xfs_exntst_t); -void xfs_bmbt_set_blockcount (xfs_bmbt_rec_t *, xfs_filblks_t); -void xfs_bmbt_set_startblock (xfs_bmbt_rec_t *, xfs_fsblock_t); -void xfs_bmbt_set_startoff (xfs_bmbt_rec_t *, xfs_fileoff_t); -void xfs_bmbt_set_state (xfs_bmbt_rec_t *, xfs_exntst_t); -void xfs_bmbt_log_block (struct xfs_btree_cur *, struct xfs_buf *, int); -void xfs_bmbt_log_recs (struct xfs_btree_cur *, struct xfs_buf *, int, int); -int xfs_bmbt_lookup_eq (struct xfs_btree_cur *, xfs_fileoff_t, xfs_fsblock_t, - xfs_filblks_t, int *); -int xfs_bmbt_lookup_ge (struct xfs_btree_cur *, xfs_fileoff_t, xfs_fsblock_t, - xfs_filblks_t, int *); -xfs_fsblock_t xfs_bmbt_get_startblock (xfs_bmbt_rec_t *); -xfs_filblks_t xfs_bmbt_get_blockcount (xfs_bmbt_rec_t *); -xfs_fileoff_t xfs_bmbt_get_startoff (xfs_bmbt_rec_t *); -xfs_exntst_t xfs_bmbt_get_state (xfs_bmbt_rec_t *); -xfs_bmbt_block_t * xfs_bmbt_get_block (xfs_btree_cur_t *, int, - struct xfs_buf **); -int xfs_bmbt_increment (struct xfs_btree_cur *, int, int *); -int xfs_bmbt_insert (struct xfs_btree_cur *, int *); -int xfs_bmbt_decrement (struct xfs_btree_cur *, int, int *); -int xfs_bmbt_delete (struct xfs_btree_cur *, int *); -int xfs_bmbt_update (struct xfs_btree_cur *, xfs_fileoff_t, xfs_fsblock_t, - xfs_filblks_t, xfs_exntst_t); -void xfs_bmbt_to_bmdr (xfs_bmbt_block_t *, int, xfs_bmdr_block_t *, int); -void xfs_bmdr_to_bmbt (xfs_bmdr_block_t *, int, xfs_bmbt_block_t *, int); -#if __BYTE_ORDER != __BIG_ENDIAN -xfs_fileoff_t xfs_bmbt_disk_get_startoff (xfs_bmbt_rec_t *); -void xfs_bmbt_disk_set_all (xfs_bmbt_rec_t *, xfs_bmbt_irec_t *); -void xfs_bmbt_disk_set_allf (xfs_bmbt_rec_t *, xfs_fileoff_t, xfs_fsblock_t, - xfs_filblks_t, xfs_exntst_t); -#else -#define xfs_bmbt_disk_get_startoff(r) xfs_bmbt_get_startoff(r) -#define xfs_bmbt_disk_set_all(r, s) xfs_bmbt_set_all(r, s) -#define xfs_bmbt_disk_set_allf(r, o, b, c, v) xfs_bmbt_set_allf(r, o, b, c, v) -#endif - -/* xfs_ialloc_btree.c */ -int xfs_inobt_newroot (xfs_btree_cur_t *, int *); -int xfs_inobt_rshift (xfs_btree_cur_t *, int, int *); -int xfs_inobt_lshift (xfs_btree_cur_t *, int, int *); -int xfs_inobt_split (xfs_btree_cur_t *, int, xfs_agblock_t *, - xfs_inobt_key_t *, xfs_btree_cur_t **, int *); -void xfs_inobt_log_keys (xfs_btree_cur_t *, xfs_buf_t *, int, int); -void xfs_inobt_log_ptrs (xfs_btree_cur_t *, xfs_buf_t *, int, int); -void xfs_inobt_log_recs (xfs_btree_cur_t *, xfs_buf_t *, int, int); -void xfs_inobt_log_block (xfs_trans_t *, xfs_buf_t *, int); -int xfs_inobt_updkey (xfs_btree_cur_t *, xfs_inobt_key_t *, int); - -/* xfs_alloc_btree.c */ -void xfs_alloc_log_ptrs (xfs_btree_cur_t *, xfs_buf_t *, int, int); -void xfs_alloc_log_keys (xfs_btree_cur_t *, xfs_buf_t *, int, int); -void xfs_alloc_log_recs (xfs_btree_cur_t *, xfs_buf_t *, int, int); -void xfs_alloc_log_block (xfs_trans_t *, xfs_buf_t *, int); -int xfs_alloc_updkey (xfs_btree_cur_t *, xfs_alloc_key_t *, int); -int xfs_alloc_lshift (xfs_btree_cur_t *, int, int *); -int xfs_alloc_rshift (xfs_btree_cur_t *, int, int *); -int xfs_alloc_newroot (xfs_btree_cur_t *, int *); -int xfs_alloc_split (xfs_btree_cur_t *, int, xfs_agblock_t *, - xfs_alloc_key_t *, xfs_btree_cur_t **, int *); +void xfs_bmap_del_free(xfs_bmap_free_t *, xfs_bmap_free_item_t *, + xfs_bmap_free_item_t *); /* xfs_da_btree.c */ -xfs_dabuf_t *xfs_da_buf_make (int, xfs_buf_t **, inst_t *); -void xfs_da_binval (struct xfs_trans *, xfs_dabuf_t *); -void xfs_da_buf_done (xfs_dabuf_t *); -int xfs_da_root_join (xfs_da_state_t *, xfs_da_state_blk_t *); -int xfs_da_root_split (xfs_da_state_t *, xfs_da_state_blk_t *, - xfs_da_state_blk_t *); -void xfs_da_node_add (xfs_da_state_t *, xfs_da_state_blk_t *, - xfs_da_state_blk_t *); -int xfs_da_node_split (xfs_da_state_t *, xfs_da_state_blk_t *, - xfs_da_state_blk_t *, xfs_da_state_blk_t *, int, int *); -void xfs_da_node_rebalance (xfs_da_state_t *, xfs_da_state_blk_t *, - xfs_da_state_blk_t *); -void xfs_da_node_remove (xfs_da_state_t *, xfs_da_state_blk_t *); -void xfs_da_node_unbalance (xfs_da_state_t *, xfs_da_state_blk_t *, - xfs_da_state_blk_t *); -int xfs_da_node_order (xfs_dabuf_t *, xfs_dabuf_t *); -int xfs_da_node_toosmall (xfs_da_state_t *, int *); -uint xfs_da_node_lasthash (xfs_dabuf_t *, int *); -int xfs_da_do_buf (xfs_trans_t *, xfs_inode_t *, xfs_dablk_t, xfs_daddr_t *, +int xfs_da_do_buf(xfs_trans_t *, xfs_inode_t *, xfs_dablk_t, xfs_daddr_t *, xfs_dabuf_t **, int, int, inst_t *); -int xfs_da_split (xfs_da_state_t *); -int xfs_da_node_create (xfs_da_args_t *, xfs_dablk_t, int, - xfs_dabuf_t **, int); -int xfs_da_join (xfs_da_state_t *); -void xfs_da_fixhashpath (xfs_da_state_t *, xfs_da_state_path_t *); -int xfs_da_node_lookup_int (xfs_da_state_t *, int *); -int xfs_da_path_shift (xfs_da_state_t *, xfs_da_state_path_t *, - int, int, int *); -int xfs_da_blk_unlink (xfs_da_state_t *, xfs_da_state_blk_t *, - xfs_da_state_blk_t *); -int xfs_da_blk_link (xfs_da_state_t *, xfs_da_state_blk_t *, - xfs_da_state_blk_t *); -xfs_da_state_t *xfs_da_state_alloc (void); -void xfs_da_state_free (xfs_da_state_t *); -void xfs_da_state_kill_altpath (xfs_da_state_t *); -xfs_daddr_t xfs_da_blkno(xfs_dabuf_t *); - -/* xfs_dir.c */ -int xfs_dir_node_addname (xfs_da_args_t *); -int xfs_dir_leaf_create (xfs_da_args_t *, xfs_dablk_t, xfs_dabuf_t **); -int xfs_dir_leaf_lookup (xfs_da_args_t *); -int xfs_dir_node_lookup (xfs_da_args_t *); -int xfs_dir_leaf_replace (xfs_da_args_t *); -int xfs_dir_node_replace (xfs_da_args_t *); -int xfs_dir_node_removename (xfs_da_args_t *); -int xfs_dir_leaf_removename (xfs_da_args_t *, int *, int *); - -/* xfs_dir_leaf.c */ -void xfs_dir_leaf_rebalance (xfs_da_state_t *, xfs_da_state_blk_t *, - xfs_da_state_blk_t *); -void xfs_dir_leaf_add_work (xfs_dabuf_t *, xfs_da_args_t *, int, int); -int xfs_dir_leaf_compact (xfs_trans_t *, xfs_dabuf_t *, int, int); -int xfs_dir_leaf_figure_balance (xfs_da_state_t *, xfs_da_state_blk_t *, - xfs_da_state_blk_t *, int *, int *); -void xfs_dir_leaf_moveents (xfs_dir_leafblock_t *, int, - xfs_dir_leafblock_t *, int, int, xfs_mount_t *); -int xfs_dir_shortform_to_leaf (xfs_da_args_t *); - -/* xfs_dir2_leaf.c */ -void xfs_dir2_leaf_check (xfs_inode_t *, xfs_dabuf_t *); -int xfs_dir2_leaf_lookup_int (xfs_da_args_t *, xfs_dabuf_t **, - int *, xfs_dabuf_t **); - -/* xfs_dir2_block.c */ -void xfs_dir2_block_log_tail (xfs_trans_t *, xfs_dabuf_t *); -void xfs_dir2_block_log_leaf (xfs_trans_t *, xfs_dabuf_t *, int, int); -int xfs_dir2_block_lookup_int (xfs_da_args_t *, xfs_dabuf_t **, int *); - -/* xfs_dir2_node.c */ -void xfs_dir2_leafn_check (xfs_inode_t *, xfs_dabuf_t *); -int xfs_dir2_leafn_remove (xfs_da_args_t *, xfs_dabuf_t *, int, - xfs_da_state_blk_t *, int *); -int xfs_dir2_node_addname_int (xfs_da_args_t *, xfs_da_state_blk_t *); -int xfs_dir2_sf_to_block (xfs_da_args_t *); - -/* xfs_dir2_sf.c */ -void xfs_dir2_sf_check (xfs_da_args_t *); -int xfs_dir2_sf_addname_pick (xfs_da_args_t *, int, - xfs_dir2_sf_entry_t **, xfs_dir2_data_aoff_t *); -void xfs_dir2_sf_addname_easy (xfs_da_args_t *, xfs_dir2_sf_entry_t *, - xfs_dir2_data_aoff_t, int); -void xfs_dir2_sf_addname_hard (xfs_da_args_t *, int, int); -void xfs_dir2_sf_toino8 (xfs_da_args_t *); -void xfs_dir2_sf_toino4 (xfs_da_args_t *); - -/* xfs_attr_leaf.c */ -void xfs_attr_leaf_rebalance (xfs_da_state_t *, xfs_da_state_blk_t *, - xfs_da_state_blk_t *); -int xfs_attr_leaf_add_work (xfs_dabuf_t *, xfs_da_args_t *, int); -void xfs_attr_leaf_compact (xfs_trans_t *, xfs_dabuf_t *); -void xfs_attr_leaf_moveents (xfs_attr_leafblock_t *, int, - xfs_attr_leafblock_t *, int, int, xfs_mount_t *); -int xfs_attr_leaf_figure_balance (xfs_da_state_t *, xfs_da_state_blk_t *, - xfs_da_state_blk_t *, int *, int *); + +/* xfs_inode.c */ +void xfs_iflush_fork(xfs_inode_t *, xfs_dinode_t *, xfs_inode_log_item_t *, + int, xfs_buf_t *); +int xfs_iformat(xfs_inode_t *, xfs_dinode_t *); + +/* xfs_mount.c */ +int xfs_initialize_perag_data(xfs_mount_t *, xfs_agnumber_t); +void xfs_mount_common(xfs_mount_t *, xfs_sb_t *); + +/* + * logitem.c and trans.c prototypes + */ /* xfs_trans_item.c */ xfs_log_item_desc_t *xfs_trans_add_item (xfs_trans_t *, xfs_log_item_t *); @@ -660,12 +316,6 @@ xfs_log_item_desc_t *xfs_trans_find_item (xfs_trans_t *, xfs_log_item_t *); void xfs_trans_free_item (xfs_trans_t *, xfs_log_item_desc_t *); void xfs_trans_free_items (xfs_trans_t *, int); -/* xfs_trans_buf.c */ -xfs_buf_t *xfs_trans_buf_item_match (xfs_trans_t *, xfs_buftarg_t *, - xfs_daddr_t, int); -xfs_buf_t *xfs_trans_buf_item_match_all (xfs_trans_t *, xfs_buftarg_t *, - xfs_daddr_t, int); - /* xfs_inode_item.c */ void xfs_inode_item_init (xfs_inode_t *, xfs_mount_t *); @@ -673,20 +323,13 @@ void xfs_inode_item_init (xfs_inode_t *, xfs_mount_t *); void xfs_buf_item_init (xfs_buf_t *, xfs_mount_t *); void xfs_buf_item_log (xfs_buf_log_item_t *, uint, uint); +/* xfs_trans_buf.c */ +xfs_buf_t *xfs_trans_buf_item_match (xfs_trans_t *, xfs_buftarg_t *, + xfs_daddr_t, int); +xfs_buf_t *xfs_trans_buf_item_match_all (xfs_trans_t *, xfs_buftarg_t *, + xfs_daddr_t, int); + /* local source files */ -int xfs_mod_incore_sb (xfs_mount_t *, xfs_sb_field_t, int, int); -void xfs_trans_mod_sb (xfs_trans_t *, uint, long); +int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int); +void xfs_trans_mod_sb(xfs_trans_t *, uint, long); int xfs_trans_unlock_chunk (xfs_log_item_chunk_t *, int, int, xfs_lsn_t); - - -#ifndef DEBUG -#define xfs_inobp_check(mp,bp) ((void) 0) -#define xfs_btree_check_key(a,b,c) ((void) 0) -#define xfs_btree_check_rec(a,b,c) ((void) 0) -#define xfs_btree_check_block(a,b,c,d) ((void) 0) -#define xfs_dir2_sf_check(args) ((void) 0) -#define xfs_dir2_leaf_check(dp,bp) ((void) 0) -#define xfs_dir2_leafn_check(dp,bp) ((void) 0) -#undef xfs_dir2_data_check -#define xfs_dir2_data_check(dp,bp) ((void) 0) -#endif diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index 1566b8351..7d141917f 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -15,18 +15,32 @@ * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #include #define XFS_ABSDIFF(a,b) (((a) <= (b)) ? ((b) - (a)) : ((a) - (b))) -#define XFSA_FIXUP_BNO_OK 1 -#define XFSA_FIXUP_CNT_OK 2 + +#define XFSA_FIXUP_BNO_OK 1 +#define XFSA_FIXUP_CNT_OK 2 + +/* + * Prototypes for per-ag allocation routines + */ + +STATIC int xfs_alloc_ag_vextent_exact(xfs_alloc_arg_t *); +STATIC int xfs_alloc_ag_vextent_near(xfs_alloc_arg_t *); +STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *); +STATIC int xfs_alloc_ag_vextent_small(xfs_alloc_arg_t *, + xfs_btree_cur_t *, xfs_agblock_t *, xfs_extlen_t *, int *); + +/* + * Internal functions. + */ /* * Compute aligned version of the found extent. * Takes alignment and min length into account. */ -STATIC int /* success (>= minlen) */ +STATIC void xfs_alloc_compute_aligned( xfs_agblock_t foundbno, /* starting block in found extent */ xfs_extlen_t foundlen, /* length in found extent */ @@ -49,7 +63,6 @@ xfs_alloc_compute_aligned( } *resbno = bno; *reslen = len; - return len >= minlen; } /* @@ -347,99 +360,6 @@ xfs_alloc_read_agfl( return 0; } -#if 0 -//#if defined(XFS_ALLOC_TRACE) -/* - * Add an allocation trace entry for an alloc call. - */ -STATIC void -xfs_alloc_trace_alloc( - char *name, /* function tag string */ - char *str, /* additional string */ - xfs_alloc_arg_t *args, /* allocation argument structure */ - int line) /* source line number */ -{ - ktrace_enter(xfs_alloc_trace_buf, - (void *)(__psint_t)(XFS_ALLOC_KTRACE_ALLOC | (line << 16)), - (void *)name, - (void *)str, - (void *)args->mp, - (void *)(__psunsigned_t)args->agno, - (void *)(__psunsigned_t)args->agbno, - (void *)(__psunsigned_t)args->minlen, - (void *)(__psunsigned_t)args->maxlen, - (void *)(__psunsigned_t)args->mod, - (void *)(__psunsigned_t)args->prod, - (void *)(__psunsigned_t)args->minleft, - (void *)(__psunsigned_t)args->total, - (void *)(__psunsigned_t)args->alignment, - (void *)(__psunsigned_t)args->len, - (void *)((((__psint_t)args->type) << 16) | - (__psint_t)args->otype), - (void *)(__psint_t)((args->wasdel << 3) | - (args->wasfromfl << 2) | - (args->isfl << 1) | - (args->userdata << 0))); -} - -/* - * Add an allocation trace entry for a free call. - */ -STATIC void -xfs_alloc_trace_free( - char *name, /* function tag string */ - char *str, /* additional string */ - xfs_mount_t *mp, /* file system mount point */ - xfs_agnumber_t agno, /* allocation group number */ - xfs_agblock_t agbno, /* a.g. relative block number */ - xfs_extlen_t len, /* length of extent */ - int isfl, /* set if is freelist allocation/free */ - int line) /* source line number */ -{ - ktrace_enter(xfs_alloc_trace_buf, - (void *)(__psint_t)(XFS_ALLOC_KTRACE_FREE | (line << 16)), - (void *)name, - (void *)str, - (void *)mp, - (void *)(__psunsigned_t)agno, - (void *)(__psunsigned_t)agbno, - (void *)(__psunsigned_t)len, - (void *)(__psint_t)isfl, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); -} - -/* - * Add an allocation trace entry for modifying an agf. - */ -STATIC void -xfs_alloc_trace_modagf( - char *name, /* function tag string */ - char *str, /* additional string */ - xfs_mount_t *mp, /* file system mount point */ - xfs_agf_t *agf, /* new agf value */ - int flags, /* logging flags for agf */ - int line) /* source line number */ -{ - ktrace_enter(xfs_alloc_trace_buf, - (void *)(__psint_t)(XFS_ALLOC_KTRACE_MODAGF | (line << 16)), - (void *)name, - (void *)str, - (void *)mp, - (void *)(__psint_t)flags, - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_seqno). - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_length), - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]), - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]). - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]). - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]). - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_flfirst), - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_fllast), - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_flcount), - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_freeblks), - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_longest)); -} -#endif /* XFS_ALLOC_TRACE */ - /* * Allocation group level functions. */ @@ -457,9 +377,6 @@ xfs_alloc_ag_vextent( xfs_alloc_arg_t *args) /* argument structure for allocation */ { int error=0; -#ifdef XFS_ALLOC_TRACE - static char fname[] = "xfs_alloc_ag_vextent"; -#endif ASSERT(args->minlen > 0); ASSERT(args->maxlen > 0); @@ -503,7 +420,7 @@ xfs_alloc_ag_vextent( if (!(args->wasfromfl)) { agf = XFS_BUF_TO_AGF(args->agbp); - be32_add(&agf->agf_freeblks, -(args->len)); + be32_add_cpu(&agf->agf_freeblks, -(args->len)); xfs_trans_agblocks_delta(args->tp, -((long)(args->len))); args->pag->pagf_freeblks -= args->len; @@ -543,9 +460,6 @@ xfs_alloc_ag_vextent_exact( xfs_agblock_t fbno; /* start block of found extent */ xfs_agblock_t fend; /* end block of found extent */ xfs_extlen_t flen; /* length of found extent */ -#ifdef XFS_ALLOC_TRACE - static char fname[] = "xfs_alloc_ag_vextent_exact"; -#endif int i; /* success/failure of operation */ xfs_agblock_t maxend; /* end of maximal extent */ xfs_agblock_t minend; /* end of minimal extent */ @@ -645,9 +559,6 @@ xfs_alloc_ag_vextent_near( xfs_btree_cur_t *bno_cur_gt; /* cursor for bno btree, right side */ xfs_btree_cur_t *bno_cur_lt; /* cursor for bno btree, left side */ xfs_btree_cur_t *cnt_cur; /* cursor for count btree */ -#ifdef XFS_ALLOC_TRACE - static char fname[] = "xfs_alloc_ag_vextent_near"; -#endif xfs_agblock_t gtbno; /* start bno of right side entry */ xfs_agblock_t gtbnoa; /* aligned ... */ xfs_extlen_t gtdiff; /* difference to right side entry */ @@ -672,7 +583,7 @@ xfs_alloc_ag_vextent_near( */ int dofirst; /* set to do first algorithm */ - dofirst = random() & 1; + dofirst = random32() & 1; #endif /* * Get a cursor for the by-size btree. @@ -754,9 +665,9 @@ xfs_alloc_ag_vextent_near( if ((error = xfs_alloc_get_rec(cnt_cur, <bno, <len, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); - if (!xfs_alloc_compute_aligned(ltbno, ltlen, - args->alignment, args->minlen, - <bnoa, <lena)) + xfs_alloc_compute_aligned(ltbno, ltlen, args->alignment, + args->minlen, <bnoa, <lena); + if (ltlena < args->minlen) continue; args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); xfs_alloc_fix_len(args); @@ -875,9 +786,9 @@ xfs_alloc_ag_vextent_near( if ((error = xfs_alloc_get_rec(bno_cur_lt, <bno, <len, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); - if (xfs_alloc_compute_aligned(ltbno, ltlen, - args->alignment, args->minlen, - <bnoa, <lena)) + xfs_alloc_compute_aligned(ltbno, ltlen, args->alignment, + args->minlen, <bnoa, <lena); + if (ltlena >= args->minlen) break; if ((error = xfs_alloc_decrement(bno_cur_lt, 0, &i))) goto error0; @@ -891,9 +802,9 @@ xfs_alloc_ag_vextent_near( if ((error = xfs_alloc_get_rec(bno_cur_gt, >bno, >len, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); - if (xfs_alloc_compute_aligned(gtbno, gtlen, - args->alignment, args->minlen, - >bnoa, >lena)) + xfs_alloc_compute_aligned(gtbno, gtlen, args->alignment, + args->minlen, >bnoa, >lena); + if (gtlena >= args->minlen) break; if ((error = xfs_alloc_increment(bno_cur_gt, 0, &i))) goto error0; @@ -1178,9 +1089,6 @@ xfs_alloc_ag_vextent_size( int error; /* error result */ xfs_agblock_t fbno; /* start of found freespace */ xfs_extlen_t flen; /* length of found freespace */ -#ifdef XFS_ALLOC_TRACE - static char fname[] = "xfs_alloc_ag_vextent_size"; -#endif int i; /* temp status variable */ xfs_agblock_t rbno; /* returned block number */ xfs_extlen_t rlen; /* length of returned extent */ @@ -1335,9 +1243,6 @@ xfs_alloc_ag_vextent_small( int error; xfs_agblock_t fbno; xfs_extlen_t flen; -#ifdef XFS_ALLOC_TRACE - static char fname[] = "xfs_alloc_ag_vextent_small"; -#endif int i; if ((error = xfs_alloc_decrement(ccur, 0, &i))) @@ -1386,8 +1291,10 @@ xfs_alloc_ag_vextent_small( /* * Can't allocate from the freelist for some reason. */ - else + else { + fbno = NULLAGBLOCK; flen = 0; + } /* * Can't do the allocation, give up. */ @@ -1422,9 +1329,6 @@ xfs_free_ag_extent( xfs_btree_cur_t *bno_cur; /* cursor for by-block btree */ xfs_btree_cur_t *cnt_cur; /* cursor for by-size btree */ int error; /* error return value */ -#ifdef XFS_ALLOC_TRACE - static char fname[] = "xfs_free_ag_extent"; -#endif xfs_agblock_t gtbno; /* start of right neighbor block */ xfs_extlen_t gtlen; /* length of right neighbor block */ int haveleft; /* have a left neighbor block */ @@ -1644,7 +1548,7 @@ xfs_free_ag_extent( agf = XFS_BUF_TO_AGF(agbp); pag = &mp->m_perag[agno]; - be32_add(&agf->agf_freeblks, len); + be32_add_cpu(&agf->agf_freeblks, len); xfs_trans_agblocks_delta(tp, len); pag->pagf_freeblks += len; XFS_WANT_CORRUPTED_GOTO( @@ -1716,7 +1620,8 @@ xfs_alloc_compute_maxlevels( /* * Decide whether to use this allocation group for this allocation. * If so, fix up the btree freelist's size. - * This is external so mkfs can call it, too. + * + * Note: This is public so mkfs can call it */ int /* error */ xfs_alloc_fix_freelist( @@ -1745,40 +1650,47 @@ xfs_alloc_fix_freelist( &agbp))) return error; if (!pag->pagf_init) { + ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK); + ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); args->agbp = NULL; return 0; } } else agbp = NULL; - /* If this is a metadata prefered pag and we are user data + /* + * If this is a metadata preferred pag and we are user data * then try somewhere else if we are not being asked to * try harder at this point */ - if (pag->pagf_metadata && args->userdata && flags) { + if (pag->pagf_metadata && args->userdata && + (flags & XFS_ALLOC_FLAG_TRYLOCK)) { + ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); args->agbp = NULL; return 0; } - need = XFS_MIN_FREELIST_PAG(pag, mp); - delta = need > pag->pagf_flcount ? need - pag->pagf_flcount : 0; - /* - * If it looks like there isn't a long enough extent, or enough - * total blocks, reject it. - */ - longest = (pag->pagf_longest > delta) ? - (pag->pagf_longest - delta) : - (pag->pagf_flcount > 0 || pag->pagf_longest > 0); - if (args->minlen + args->alignment + args->minalignslop - 1 > longest || - (args->minleft && - (int)(pag->pagf_freeblks + pag->pagf_flcount - - need - args->total) < - (int)args->minleft)) { - if (agbp) - xfs_trans_brelse(tp, agbp); - args->agbp = NULL; - return 0; + if (!(flags & XFS_ALLOC_FLAG_FREEING)) { + need = XFS_MIN_FREELIST_PAG(pag, mp); + delta = need > pag->pagf_flcount ? need - pag->pagf_flcount : 0; + /* + * If it looks like there isn't a long enough extent, or enough + * total blocks, reject it. + */ + longest = (pag->pagf_longest > delta) ? + (pag->pagf_longest - delta) : + (pag->pagf_flcount > 0 || pag->pagf_longest > 0); + if ((args->minlen + args->alignment + args->minalignslop - 1) > + longest || + ((int)(pag->pagf_freeblks + pag->pagf_flcount - + need - args->total) < (int)args->minleft)) { + if (agbp) + xfs_trans_brelse(tp, agbp); + args->agbp = NULL; + return 0; + } } + /* * Get the a.g. freespace buffer. * Can fail if we're not blocking on locks, and it's held. @@ -1788,6 +1700,8 @@ xfs_alloc_fix_freelist( &agbp))) return error; if (agbp == NULL) { + ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK); + ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); args->agbp = NULL; return 0; } @@ -1797,22 +1711,24 @@ xfs_alloc_fix_freelist( */ agf = XFS_BUF_TO_AGF(agbp); need = XFS_MIN_FREELIST(agf, mp); - delta = need > be32_to_cpu(agf->agf_flcount) ? - (need - be32_to_cpu(agf->agf_flcount)) : 0; /* * If there isn't enough total or single-extent, reject it. */ - longest = be32_to_cpu(agf->agf_longest); - longest = (longest > delta) ? (longest - delta) : - (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); - if (args->minlen + args->alignment + args->minalignslop - 1 > longest || - (args->minleft && - (int)(be32_to_cpu(agf->agf_freeblks) + - be32_to_cpu(agf->agf_flcount) - need - args->total) < - (int)args->minleft)) { - xfs_trans_brelse(tp, agbp); - args->agbp = NULL; - return 0; + if (!(flags & XFS_ALLOC_FLAG_FREEING)) { + delta = need > be32_to_cpu(agf->agf_flcount) ? + (need - be32_to_cpu(agf->agf_flcount)) : 0; + longest = be32_to_cpu(agf->agf_longest); + longest = (longest > delta) ? (longest - delta) : + (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); + if ((args->minlen + args->alignment + args->minalignslop - 1) > + longest || + ((int)(be32_to_cpu(agf->agf_freeblks) + + be32_to_cpu(agf->agf_flcount) - need - args->total) < + (int)args->minleft)) { + xfs_trans_brelse(tp, agbp); + args->agbp = NULL; + return 0; + } } /* * Make the freelist shorter if it's too long. @@ -1820,7 +1736,8 @@ xfs_alloc_fix_freelist( while (be32_to_cpu(agf->agf_flcount) > need) { xfs_buf_t *bp; - if ((error = xfs_alloc_get_freelist(tp, agbp, &bno, 0))) + error = xfs_alloc_get_freelist(tp, agbp, &bno, 0); + if (error) return error; if ((error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, 1))) return error; @@ -1859,14 +1776,20 @@ xfs_alloc_fix_freelist( * the restrictions correctly. Can happen for free calls * on a completely full ag. */ - if (targs.agbno == NULLAGBLOCK) - break; + if (targs.agbno == NULLAGBLOCK) { + if (flags & XFS_ALLOC_FLAG_FREEING) + break; + xfs_trans_brelse(tp, agflbp); + args->agbp = NULL; + return 0; + } /* * Put each allocated block on the list. */ for (bno = targs.agbno; bno < targs.agbno + targs.len; bno++) { - if ((error = xfs_alloc_put_freelist(tp, agbp, agflbp, - bno, 0))) + error = xfs_alloc_put_freelist(tp, agbp, + agflbp, bno, 0); + if (error) return error; } } @@ -1892,9 +1815,6 @@ xfs_alloc_get_freelist( xfs_agblock_t bno; /* block number returned */ int error; int logflags; -#ifdef XFS_ALLOC_TRACE - static char fname[] = "xfs_alloc_get_freelist"; -#endif xfs_mount_t *mp; /* mount structure */ xfs_perag_t *pag; /* per allocation group data */ @@ -1917,19 +1837,19 @@ xfs_alloc_get_freelist( /* * Get the block number and update the data structures. */ - bno = INT_GET(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)], ARCH_CONVERT); - be32_add(&agf->agf_flfirst, 1); + bno = be32_to_cpu(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)]); + be32_add_cpu(&agf->agf_flfirst, 1); xfs_trans_brelse(tp, agflbp); if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp)) agf->agf_flfirst = 0; pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)]; - be32_add(&agf->agf_flcount, -1); + be32_add_cpu(&agf->agf_flcount, -1); xfs_trans_agflist_delta(tp, -1); pag->pagf_flcount--; logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT; if (btreeblk) { - be32_add(&agf->agf_btreeblks, 1); + be32_add_cpu(&agf->agf_btreeblks, 1); pag->pagf_btreeblks++; logflags |= XFS_AGF_BTREEBLKS; } @@ -2014,12 +1934,9 @@ xfs_alloc_put_freelist( { xfs_agf_t *agf; /* a.g. freespace structure */ xfs_agfl_t *agfl; /* a.g. free block array */ - xfs_agblock_t *blockp;/* pointer to array entry */ + __be32 *blockp;/* pointer to array entry */ int error; int logflags; -#ifdef XFS_ALLOC_TRACE - static char fname[] = "xfs_alloc_put_freelist"; -#endif xfs_mount_t *mp; /* mount structure */ xfs_perag_t *pag; /* per allocation group data */ @@ -2030,24 +1947,27 @@ xfs_alloc_put_freelist( be32_to_cpu(agf->agf_seqno), &agflbp))) return error; agfl = XFS_BUF_TO_AGFL(agflbp); - be32_add(&agf->agf_fllast, 1); + be32_add_cpu(&agf->agf_fllast, 1); if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp)) agf->agf_fllast = 0; pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)]; - be32_add(&agf->agf_flcount, 1); + be32_add_cpu(&agf->agf_flcount, 1); xfs_trans_agflist_delta(tp, 1); pag->pagf_flcount++; logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT; if (btreeblk) { - be32_add(&agf->agf_btreeblks, -1); + be32_add_cpu(&agf->agf_btreeblks, -1); pag->pagf_btreeblks--; logflags |= XFS_AGF_BTREEBLKS; } + TRACE_MODAGF(NULL, agf, logflags); + xfs_alloc_log_agf(tp, agbp, logflags); + ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)); blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)]; - INT_SET(*blockp, ARCH_CONVERT, bno); + *blockp = cpu_to_be32(bno); TRACE_MODAGF(NULL, agf, logflags); xfs_alloc_log_agf(tp, agbp, logflags); xfs_trans_log_buf(tp, agflbp, @@ -2070,7 +1990,6 @@ xfs_alloc_read_agf( { xfs_agf_t *agf; /* ag freelist header */ int agf_ok; /* set if agf is consistent */ - int agf_length; /* ag length from agf */ xfs_buf_t *bp; /* return value */ xfs_perag_t *pag; /* per allocation group data */ int error; @@ -2093,12 +2012,11 @@ xfs_alloc_read_agf( * Validate the magic number of the agf block. */ agf = XFS_BUF_TO_AGF(bp); - agf_length = be32_to_cpu(agf->agf_length); agf_ok = be32_to_cpu(agf->agf_magicnum) == XFS_AGF_MAGIC && XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) && - be32_to_cpu(agf->agf_freeblks) <= agf_length && - be32_to_cpu(agf->agf_btreeblks) <= agf_length && + be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) && + be32_to_cpu(agf->agf_btreeblks) <= be32_to_cpu(agf->agf_length) && be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) && be32_to_cpu(agf->agf_fllast) < XFS_AGFL_SIZE(mp) && be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp); @@ -2119,7 +2037,7 @@ xfs_alloc_read_agf( be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]); pag->pagf_levels[XFS_BTNUM_CNTi] = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]); - spinlock_init(&pag->pagb_lock, "xfspagb"); + spin_lock_init(&pag->pagb_lock); pag->pagb_list = kmem_zalloc(XFS_PAGB_NUM_SLOTS * sizeof(xfs_perag_busy_t), KM_SLEEP); pag->pagf_init = 1; @@ -2153,9 +2071,6 @@ xfs_alloc_vextent( xfs_agblock_t agsize; /* allocation group size */ int error; int flags; /* XFS_ALLOC_FLAG_... locking flags */ -#ifdef XFS_ALLOC_TRACE - static char fname[] = "xfs_alloc_vextent"; -#endif xfs_extlen_t minleft;/* minimum left value, temp copy */ xfs_mount_t *mp; /* mount structure pointer */ xfs_agnumber_t sagno; /* starting allocation group number */ @@ -2294,8 +2209,19 @@ xfs_alloc_vextent( if (args->agno == sagno && type == XFS_ALLOCTYPE_START_BNO) args->type = XFS_ALLOCTYPE_THIS_AG; - if (++(args->agno) == mp->m_sb.sb_agcount) - args->agno = 0; + /* + * For the first allocation, we can try any AG to get + * space. However, if we already have allocated a + * block, we don't want to try AGs whose number is below + * sagno. Otherwise, we may end up with out-of-order + * locking of AGF, which might cause deadlock. + */ + if (++(args->agno) == mp->m_sb.sb_agcount) { + if (args->firstblock != NULLFSBLOCK) + args->agno = sagno; + else + args->agno = 0; + } /* * Reached the starting a.g., must either be done * or switch to non-trylock mode. @@ -2361,31 +2287,26 @@ xfs_free_extent( xfs_fsblock_t bno, /* starting block number of extent */ xfs_extlen_t len) /* length of extent */ { -#ifdef DEBUG - xfs_agf_t *agf; /* a.g. freespace header */ -#endif - xfs_alloc_arg_t args; /* allocation argument structure */ + xfs_alloc_arg_t args; int error; ASSERT(len != 0); + memset(&args, 0, sizeof(xfs_alloc_arg_t)); args.tp = tp; args.mp = tp->t_mountp; args.agno = XFS_FSB_TO_AGNO(args.mp, bno); ASSERT(args.agno < args.mp->m_sb.sb_agcount); args.agbno = XFS_FSB_TO_AGBNO(args.mp, bno); - args.alignment = 1; - args.minlen = args.minleft = args.minalignslop = 0; down_read(&args.mp->m_peraglock); args.pag = &args.mp->m_perag[args.agno]; - if ((error = xfs_alloc_fix_freelist(&args, 0))) + if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING))) goto error0; #ifdef DEBUG ASSERT(args.agbp != NULL); - agf = XFS_BUF_TO_AGF(args.agbp); - ASSERT(args.agbno + len <= be32_to_cpu(agf->agf_length)); + ASSERT((args.agbno + len) <= + be32_to_cpu(XFS_BUF_TO_AGF(args.agbp)->agf_length)); #endif - error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, - len, 0); + error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); error0: up_read(&args.mp->m_peraglock); return error; diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c index 21381b989..4c232344b 100644 --- a/libxfs/xfs_alloc_btree.c +++ b/libxfs/xfs_alloc_btree.c @@ -22,6 +22,25 @@ #include +/* + * Prototypes for internal functions. + */ + +STATIC void xfs_alloc_log_block(xfs_trans_t *, xfs_buf_t *, int); +STATIC void xfs_alloc_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int); +STATIC void xfs_alloc_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int); +STATIC void xfs_alloc_log_recs(xfs_btree_cur_t *, xfs_buf_t *, int, int); +STATIC int xfs_alloc_lshift(xfs_btree_cur_t *, int, int *); +STATIC int xfs_alloc_newroot(xfs_btree_cur_t *, int *); +STATIC int xfs_alloc_rshift(xfs_btree_cur_t *, int, int *); +STATIC int xfs_alloc_split(xfs_btree_cur_t *, int, xfs_agblock_t *, + xfs_alloc_key_t *, xfs_btree_cur_t **, int *); +STATIC int xfs_alloc_updkey(xfs_btree_cur_t *, xfs_alloc_key_t *, int); + +/* + * Internal functions. + */ + /* * Single level of the xfs_alloc_delete record deletion routine. * Delete record pointed to by cur/level. @@ -56,6 +75,7 @@ xfs_alloc_delrec( xfs_alloc_key_t *rkp; /* right block key pointer */ xfs_alloc_ptr_t *rpp; /* right block address pointer */ int rrecs=0; /* number of records in right block */ + int numrecs; xfs_alloc_rec_t *rrp; /* right block record pointer */ xfs_btree_cur_t *tcur; /* temporary btree cursor */ @@ -79,7 +99,8 @@ xfs_alloc_delrec( /* * Fail if we're off the end of the block. */ - if (ptr > be16_to_cpu(block->bb_numrecs)) { + numrecs = be16_to_cpu(block->bb_numrecs); + if (ptr > numrecs) { *stat = 0; return 0; } @@ -93,18 +114,18 @@ xfs_alloc_delrec( lkp = XFS_ALLOC_KEY_ADDR(block, 1, cur); lpp = XFS_ALLOC_PTR_ADDR(block, 1, cur); #ifdef DEBUG - for (i = ptr; i < be16_to_cpu(block->bb_numrecs); i++) { + for (i = ptr; i < numrecs; i++) { if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level))) return error; } #endif - if (ptr < be16_to_cpu(block->bb_numrecs)) { + if (ptr < numrecs) { memmove(&lkp[ptr - 1], &lkp[ptr], - (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lkp)); + (numrecs - ptr) * sizeof(*lkp)); memmove(&lpp[ptr - 1], &lpp[ptr], - (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lpp)); - xfs_alloc_log_ptrs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1); - xfs_alloc_log_keys(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1); + (numrecs - ptr) * sizeof(*lpp)); + xfs_alloc_log_ptrs(cur, bp, ptr, numrecs - 1); + xfs_alloc_log_keys(cur, bp, ptr, numrecs - 1); } } /* @@ -113,10 +134,10 @@ xfs_alloc_delrec( */ else { lrp = XFS_ALLOC_REC_ADDR(block, 1, cur); - if (ptr < be16_to_cpu(block->bb_numrecs)) { + if (ptr < numrecs) { memmove(&lrp[ptr - 1], &lrp[ptr], - (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lrp)); - xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1); + (numrecs - ptr) * sizeof(*lrp)); + xfs_alloc_log_recs(cur, bp, ptr, numrecs - 1); } /* * If it's the first record in the block, we'll need a key @@ -131,7 +152,8 @@ xfs_alloc_delrec( /* * Decrement and log the number of entries in the block. */ - be16_add(&block->bb_numrecs, -1); + numrecs--; + block->bb_numrecs = cpu_to_be16(numrecs); xfs_alloc_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS); /* * See if the longest free extent in the allocation group was @@ -145,14 +167,14 @@ xfs_alloc_delrec( if (level == 0 && cur->bc_btnum == XFS_BTNUM_CNT && be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK && - ptr > be16_to_cpu(block->bb_numrecs)) { - ASSERT(ptr == be16_to_cpu(block->bb_numrecs) + 1); + ptr > numrecs) { + ASSERT(ptr == numrecs + 1); /* * There are still records in the block. Grab the size * from the last one. */ - if (be16_to_cpu(block->bb_numrecs)) { - rrp = XFS_ALLOC_REC_ADDR(block, be16_to_cpu(block->bb_numrecs), cur); + if (numrecs) { + rrp = XFS_ALLOC_REC_ADDR(block, numrecs, cur); agf->agf_longest = rrp->ar_blockcount; } /* @@ -175,20 +197,21 @@ xfs_alloc_delrec( * and it's NOT the leaf level, * then we can get rid of this level. */ - if (be16_to_cpu(block->bb_numrecs) == 1 && level > 0) { + if (numrecs == 1 && level > 0) { /* * lpp is still set to the first pointer in the block. * Make it the new root of the btree. */ bno = be32_to_cpu(agf->agf_roots[cur->bc_btnum]); agf->agf_roots[cur->bc_btnum] = *lpp; - be32_add(&agf->agf_levels[cur->bc_btnum], -1); + be32_add_cpu(&agf->agf_levels[cur->bc_btnum], -1); mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_levels[cur->bc_btnum]--; /* * Put this buffer/block on the ag's freelist. */ - if ((error = xfs_alloc_put_freelist(cur->bc_tp, - cur->bc_private.a.agbp, NULL, bno, 1))) + error = xfs_alloc_put_freelist(cur->bc_tp, + cur->bc_private.a.agbp, NULL, bno, 1); + if (error) return error; /* * Since blocks move to the free list without the @@ -231,7 +254,7 @@ xfs_alloc_delrec( * If the number of records remaining in the block is at least * the minimum, we're done. */ - if (be16_to_cpu(block->bb_numrecs) >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) { + if (numrecs >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) { if (level > 0 && (error = xfs_alloc_decrement(cur, level, &i))) return error; *stat = 1; @@ -383,19 +406,21 @@ xfs_alloc_delrec( * See if we can join with the left neighbor block. */ if (lbno != NULLAGBLOCK && - lrecs + be16_to_cpu(block->bb_numrecs) <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { + lrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { /* * Set "right" to be the starting block, * "left" to be the left neighbor. */ rbno = bno; right = block; + rrecs = be16_to_cpu(right->bb_numrecs); rbp = bp; if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, cur->bc_private.a.agno, lbno, 0, &lbp, XFS_ALLOC_BTREE_REF))) return error; left = XFS_BUF_TO_ALLOC_BLOCK(lbp); + lrecs = be16_to_cpu(left->bb_numrecs); if ((error = xfs_btree_check_sblock(cur, left, level, lbp))) return error; } @@ -403,20 +428,21 @@ xfs_alloc_delrec( * If that won't work, see if we can join with the right neighbor block. */ else if (rbno != NULLAGBLOCK && - rrecs + be16_to_cpu(block->bb_numrecs) <= - XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { + rrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { /* * Set "left" to be the starting block, * "right" to be the right neighbor. */ lbno = bno; left = block; + lrecs = be16_to_cpu(left->bb_numrecs); lbp = bp; if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, cur->bc_private.a.agno, rbno, 0, &rbp, XFS_ALLOC_BTREE_REF))) return error; right = XFS_BUF_TO_ALLOC_BLOCK(rbp); + rrecs = be16_to_cpu(right->bb_numrecs); if ((error = xfs_btree_check_sblock(cur, right, level, rbp))) return error; } @@ -438,34 +464,28 @@ xfs_alloc_delrec( /* * It's a non-leaf. Move keys and pointers. */ - lkp = XFS_ALLOC_KEY_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur); - lpp = XFS_ALLOC_PTR_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur); + lkp = XFS_ALLOC_KEY_ADDR(left, lrecs + 1, cur); + lpp = XFS_ALLOC_PTR_ADDR(left, lrecs + 1, cur); rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur); rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur); #ifdef DEBUG - for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) { + for (i = 0; i < rrecs; i++) { if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level))) return error; } #endif - memcpy(lkp, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*lkp)); - memcpy(lpp, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*lpp)); - xfs_alloc_log_keys(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1, - be16_to_cpu(left->bb_numrecs) + - be16_to_cpu(right->bb_numrecs)); - xfs_alloc_log_ptrs(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1, - be16_to_cpu(left->bb_numrecs) + - be16_to_cpu(right->bb_numrecs)); + memcpy(lkp, rkp, rrecs * sizeof(*lkp)); + memcpy(lpp, rpp, rrecs * sizeof(*lpp)); + xfs_alloc_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs); + xfs_alloc_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs); } else { /* * It's a leaf. Move records. */ - lrp = XFS_ALLOC_REC_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur); + lrp = XFS_ALLOC_REC_ADDR(left, lrecs + 1, cur); rrp = XFS_ALLOC_REC_ADDR(right, 1, cur); - memcpy(lrp, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*lrp)); - xfs_alloc_log_recs(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1, - be16_to_cpu(left->bb_numrecs) + - be16_to_cpu(right->bb_numrecs)); + memcpy(lrp, rrp, rrecs * sizeof(*lrp)); + xfs_alloc_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs); } /* * If we joined with the left neighbor, set the buffer in the @@ -473,7 +493,7 @@ xfs_alloc_delrec( */ if (bp != lbp) { xfs_btree_setbuf(cur, level, lbp); - cur->bc_ptrs[level] += be16_to_cpu(left->bb_numrecs); + cur->bc_ptrs[level] += lrecs; } /* * If we joined with the right neighbor and there's a level above @@ -485,7 +505,8 @@ xfs_alloc_delrec( /* * Fix up the number of records in the surviving block. */ - be16_add(&left->bb_numrecs, be16_to_cpu(right->bb_numrecs)); + lrecs += rrecs; + left->bb_numrecs = cpu_to_be16(lrecs); /* * Fix up the right block pointer in the surviving block, and log it. */ @@ -512,8 +533,9 @@ xfs_alloc_delrec( /* * Free the deleting block by putting it on the freelist. */ - if ((error = xfs_alloc_put_freelist(cur->bc_tp, cur->bc_private.a.agbp, - NULL, rbno, 1))) + error = xfs_alloc_put_freelist(cur->bc_tp, + cur->bc_private.a.agbp, NULL, rbno, 1); + if (error) return error; /* * Since blocks move to the free list without the coordination @@ -572,6 +594,7 @@ xfs_alloc_insrec( xfs_btree_cur_t *ncur; /* new cursor to be used at next lvl */ xfs_alloc_key_t nkey; /* new key value, from split */ xfs_alloc_rec_t nrec; /* new record value, for caller */ + int numrecs; int optr; /* old ptr value */ xfs_alloc_ptr_t *pp; /* pointer to btree addresses */ int ptr; /* index in btree block for this rec */ @@ -617,13 +640,14 @@ xfs_alloc_insrec( */ bp = cur->bc_bufs[level]; block = XFS_BUF_TO_ALLOC_BLOCK(bp); + numrecs = be16_to_cpu(block->bb_numrecs); #ifdef DEBUG if ((error = xfs_btree_check_sblock(cur, block, level, bp))) return error; /* * Check that the new entry is being inserted in the right place. */ - if (ptr <= be16_to_cpu(block->bb_numrecs)) { + if (ptr <= numrecs) { if (level == 0) { rp = XFS_ALLOC_REC_ADDR(block, ptr, cur); xfs_btree_check_rec(cur->bc_btnum, recp, rp); @@ -634,12 +658,12 @@ xfs_alloc_insrec( } #endif nbno = NULLAGBLOCK; - ncur = (xfs_btree_cur_t *)0; + ncur = NULL; /* * If the block is full, we can't insert the new entry until we * make the block un-full. */ - if (be16_to_cpu(block->bb_numrecs) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { + if (numrecs == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { /* * First, try shifting an entry to the right neighbor. */ @@ -693,6 +717,7 @@ xfs_alloc_insrec( * At this point we know there's room for our new entry in the block * we're pointing at. */ + numrecs = be16_to_cpu(block->bb_numrecs); if (level > 0) { /* * It's a non-leaf entry. Make a hole for the new data @@ -701,15 +726,15 @@ xfs_alloc_insrec( kp = XFS_ALLOC_KEY_ADDR(block, 1, cur); pp = XFS_ALLOC_PTR_ADDR(block, 1, cur); #ifdef DEBUG - for (i = be16_to_cpu(block->bb_numrecs); i >= ptr; i--) { + for (i = numrecs; i >= ptr; i--) { if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level))) return error; } #endif memmove(&kp[ptr], &kp[ptr - 1], - (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*kp)); + (numrecs - ptr + 1) * sizeof(*kp)); memmove(&pp[ptr], &pp[ptr - 1], - (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*pp)); + (numrecs - ptr + 1) * sizeof(*pp)); #ifdef DEBUG if ((error = xfs_btree_check_sptr(cur, *bnop, level))) return error; @@ -719,11 +744,12 @@ xfs_alloc_insrec( */ kp[ptr - 1] = key; pp[ptr - 1] = cpu_to_be32(*bnop); - be16_add(&block->bb_numrecs, 1); - xfs_alloc_log_keys(cur, bp, ptr, be16_to_cpu(block->bb_numrecs)); - xfs_alloc_log_ptrs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs)); + numrecs++; + block->bb_numrecs = cpu_to_be16(numrecs); + xfs_alloc_log_keys(cur, bp, ptr, numrecs); + xfs_alloc_log_ptrs(cur, bp, ptr, numrecs); #ifdef DEBUG - if (ptr < be16_to_cpu(block->bb_numrecs)) + if (ptr < numrecs) xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1, kp + ptr); #endif @@ -733,16 +759,17 @@ xfs_alloc_insrec( */ rp = XFS_ALLOC_REC_ADDR(block, 1, cur); memmove(&rp[ptr], &rp[ptr - 1], - (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*rp)); + (numrecs - ptr + 1) * sizeof(*rp)); /* * Now stuff the new record in, bump numrecs * and log the new data. */ - rp[ptr - 1] = *recp; /* INT_: struct copy */ - be16_add(&block->bb_numrecs, 1); - xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs)); + rp[ptr - 1] = *recp; + numrecs++; + block->bb_numrecs = cpu_to_be16(numrecs); + xfs_alloc_log_recs(cur, bp, ptr, numrecs); #ifdef DEBUG - if (ptr < be16_to_cpu(block->bb_numrecs)) + if (ptr < numrecs) xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1, rp + ptr); #endif @@ -783,8 +810,8 @@ xfs_alloc_insrec( */ *bnop = nbno; if (nbno != NULLAGBLOCK) { - *recp = nrec; /* INT_: struct copy */ - *curp = ncur; /* INT_: struct copy */ + *recp = nrec; + *curp = ncur; } *stat = 1; return 0; @@ -945,7 +972,7 @@ xfs_alloc_lookup( */ bp = cur->bc_bufs[level]; if (bp && XFS_BUF_ADDR(bp) != d) - bp = (xfs_buf_t *)0; + bp = NULL; if (!bp) { /* * Need to get a new buffer. Read it, then @@ -1193,7 +1220,7 @@ xfs_alloc_lshift( if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level))) return error; #endif - *lpp = *rpp; /* INT_: copy */ + *lpp = *rpp; xfs_alloc_log_ptrs(cur, lbp, nrec, nrec); xfs_btree_check_key(cur->bc_btnum, lkp - 1, lkp); } @@ -1212,9 +1239,9 @@ xfs_alloc_lshift( /* * Bump and log left's numrecs, decrement and log right's numrecs. */ - be16_add(&left->bb_numrecs, 1); + be16_add_cpu(&left->bb_numrecs, 1); xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS); - be16_add(&right->bb_numrecs, -1); + be16_add_cpu(&right->bb_numrecs, -1); xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS); /* * Slide the contents of right down one entry. @@ -1278,8 +1305,9 @@ xfs_alloc_newroot( /* * Get a buffer from the freelist blocks, for the new root. */ - if ((error = xfs_alloc_get_freelist(cur->bc_tp, cur->bc_private.a.agbp, - &nbno, 1))) + error = xfs_alloc_get_freelist(cur->bc_tp, + cur->bc_private.a.agbp, &nbno, 1); + if (error) return error; /* * None available, we fail. @@ -1301,7 +1329,7 @@ xfs_alloc_newroot( agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); agf->agf_roots[cur->bc_btnum] = cpu_to_be32(nbno); - be32_add(&agf->agf_levels[cur->bc_btnum], 1); + be32_add_cpu(&agf->agf_levels[cur->bc_btnum], 1); seqno = be32_to_cpu(agf->agf_seqno); mp->m_perag[seqno].pagf_levels[cur->bc_btnum]++; xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, @@ -1370,8 +1398,8 @@ xfs_alloc_newroot( kp = XFS_ALLOC_KEY_ADDR(new, 1, cur); if (be16_to_cpu(left->bb_level) > 0) { - kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur); /* INT_: structure copy */ - kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur);/* INT_: structure copy */ + kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur); + kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur); } else { xfs_alloc_rec_t *rp; /* btree record pointer */ @@ -1491,8 +1519,8 @@ xfs_alloc_rshift( if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level))) return error; #endif - *rkp = *lkp; /* INT_: copy */ - *rpp = *lpp; /* INT_: copy */ + *rkp = *lkp; + *rpp = *lpp; xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1); @@ -1513,9 +1541,9 @@ xfs_alloc_rshift( /* * Decrement and log left's numrecs, bump and log right's numrecs. */ - be16_add(&left->bb_numrecs, -1); + be16_add_cpu(&left->bb_numrecs, -1); xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS); - be16_add(&right->bb_numrecs, 1); + be16_add_cpu(&right->bb_numrecs, 1); xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS); /* * Using a temporary cursor, update the parent key values of the @@ -1562,8 +1590,9 @@ xfs_alloc_split( * Allocate the new block from the freelist. * If we can't do it, we're toast. Give up. */ - if ((error = xfs_alloc_get_freelist(cur->bc_tp, cur->bc_private.a.agbp, - &rbno, 1))) + error = xfs_alloc_get_freelist(cur->bc_tp, + cur->bc_private.a.agbp, &rbno, 1); + if (error) return error; if (rbno == NULLAGBLOCK) { *stat = 0; @@ -1597,7 +1626,7 @@ xfs_alloc_split( */ if ((be16_to_cpu(left->bb_numrecs) & 1) && cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1) - be16_add(&right->bb_numrecs, 1); + be16_add_cpu(&right->bb_numrecs, 1); i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1; /* * For non-leaf blocks, copy keys and addresses over to the new block. @@ -1643,7 +1672,7 @@ xfs_alloc_split( * Adjust numrecs, sibling pointers. */ lbno = XFS_DADDR_TO_AGBNO(cur->bc_mp, XFS_BUF_ADDR(lbp)); - be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); + be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); right->bb_rightsib = left->bb_rightsib; left->bb_rightsib = cpu_to_be32(rbno); right->bb_leftsib = cpu_to_be32(lbno); @@ -2008,7 +2037,7 @@ xfs_alloc_insert( nbno = NULLAGBLOCK; nrec.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock); nrec.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount); - ncur = (xfs_btree_cur_t *)0; + ncur = NULL; pcur = cur; /* * Loop going up the tree, starting at the leaf level. @@ -2040,7 +2069,7 @@ xfs_alloc_insert( */ if (ncur) { pcur = ncur; - ncur = (xfs_btree_cur_t *)0; + ncur = NULL; } } while (nbno != NULLAGBLOCK); *stat = i; diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c index 1601a2517..7ab37ff8b 100644 --- a/libxfs/xfs_attr.c +++ b/libxfs/xfs_attr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -39,7 +39,6 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args); STATIC int xfs_attr_leaf_get(xfs_da_args_t *args); STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args); STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args); -STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context); /* * Internal routines when attribute list is more than one block. @@ -47,35 +46,168 @@ STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context); STATIC int xfs_attr_node_get(xfs_da_args_t *args); STATIC int xfs_attr_node_addname(xfs_da_args_t *args); STATIC int xfs_attr_node_removename(xfs_da_args_t *args); -STATIC int xfs_attr_node_list(xfs_attr_list_context_t *context); STATIC int xfs_attr_fillstate(xfs_da_state_t *state); STATIC int xfs_attr_refillstate(xfs_da_state_t *state); /* * Routines to manipulate out-of-line attribute values. */ -STATIC int xfs_attr_rmtval_get(xfs_da_args_t *args); STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args); STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args); #define ATTR_RMTVALUE_MAPSIZE 1 /* # of map entries at once */ +STATIC int +xfs_attr_name_to_xname( + struct xfs_name *xname, + const char *aname) +{ + if (!aname) + return EINVAL; + xname->name = aname; + xname->len = strlen(aname); + if (xname->len >= MAXNAMELEN) + return EFAULT; /* match IRIX behaviour */ + + return 0; +} + +STATIC int +xfs_inode_hasattr( + struct xfs_inode *ip) +{ + if (!XFS_IFORK_Q(ip) || + (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && + ip->i_d.di_anextents == 0)) + return 0; + return 1; +} + /*======================================================================== * Overall external interface routines. *========================================================================*/ int -xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, - char *value, int valuelen, int flags) +xfs_attr_fetch(xfs_inode_t *ip, struct xfs_name *name, + char *value, int *valuelenp, int flags) +{ + xfs_da_args_t args; + int error; + + if (!xfs_inode_hasattr(ip)) + return ENOATTR; + + /* + * Fill in the arg structure for this request. + */ + memset((char *)&args, 0, sizeof(args)); + args.name = name->name; + args.namelen = name->len; + args.value = value; + args.valuelen = *valuelenp; + args.flags = flags; + args.hashval = xfs_da_hashname(args.name, args.namelen); + args.dp = ip; + args.whichfork = XFS_ATTR_FORK; + + /* + * Decide on what work routines to call based on the inode size. + */ + if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { + error = xfs_attr_shortform_getvalue(&args); + } else if (xfs_bmap_one_block(ip, XFS_ATTR_FORK)) { + error = xfs_attr_leaf_get(&args); + } else { + error = xfs_attr_node_get(&args); + } + + /* + * Return the number of bytes in the value to the caller. + */ + *valuelenp = args.valuelen; + + if (error == EEXIST) + error = 0; + return(error); +} + +int +xfs_attr_get( + xfs_inode_t *ip, + const char *name, + char *value, + int *valuelenp, + int flags) +{ + int error; + struct xfs_name xname; + + XFS_STATS_INC(xs_attr_get); + + if (XFS_FORCED_SHUTDOWN(ip->i_mount)) + return(EIO); + + error = xfs_attr_name_to_xname(&xname, name); + if (error) + return error; + + xfs_ilock(ip, XFS_ILOCK_SHARED); + error = xfs_attr_fetch(ip, &xname, value, valuelenp, flags); + xfs_iunlock(ip, XFS_ILOCK_SHARED); + return(error); +} + +/* + * Calculate how many blocks we need for the new attribute, + */ +int +xfs_attr_calc_size( + struct xfs_inode *ip, + int namelen, + int valuelen, + int *local) +{ + struct xfs_mount *mp = ip->i_mount; + int size; + int nblks; + + /* + * Determine space new attribute will use, and if it would be + * "local" or "remote" (note: local != inline). + */ + size = xfs_attr_leaf_newentsize(namelen, valuelen, + mp->m_sb.sb_blocksize, local); + + nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); + if (*local) { + if (size > (mp->m_sb.sb_blocksize >> 1)) { + /* Double split possible */ + nblks *= 2; + } + } else { + /* + * Out of line attribute, cannot double split, but + * make room for the attribute value itself. + */ + uint dblocks = XFS_B_TO_FSB(mp, valuelen); + nblks += dblocks; + nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK); + } + + return nblks; +} + +STATIC int +xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, + char *value, int valuelen, int flags) { xfs_da_args_t args; xfs_fsblock_t firstblock; xfs_bmap_free_t flist; int error, err2, committed; - int local, size; - uint nblks; xfs_mount_t *mp = dp->i_mount; int rsvd = (flags & ATTR_ROOT) != 0; + int local; /* * Attach the dquots to the inode. @@ -83,19 +215,15 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, if ((error = XFS_QM_DQATTACH(mp, dp, 0))) return (error); - /* - * Determine space new attribute will use, and if it would be - * "local" or "remote" (note: local != inline). - */ - size = xfs_attr_leaf_newentsize(namelen, valuelen, - mp->m_sb.sb_blocksize, &local); - /* * If the inode doesn't have an attribute fork, add one. * (inode must not be locked when we call this routine) */ if (XFS_IFORK_Q(dp) == 0) { - if ((error = xfs_bmap_add_attrfork(dp, size, rsvd))) + int sf_size = sizeof(xfs_attr_sf_hdr_t) + + XFS_ATTR_SF_ENTSIZE_BYNAME(name->len, valuelen); + + if ((error = xfs_bmap_add_attrfork(dp, sf_size, rsvd))) return(error); } @@ -103,9 +231,9 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, * Fill in the arg structure for this request. */ memset((char *)&args, 0, sizeof(args)); - args.name = (const uchar_t *)name; - args.namelen = namelen; - args.value = (uchar_t *)value; + args.name = name->name; + args.namelen = name->len; + args.value = value; args.valuelen = valuelen; args.flags = flags; args.hashval = xfs_da_hashname(args.name, args.namelen); @@ -113,26 +241,10 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, args.firstblock = &firstblock; args.flist = &flist; args.whichfork = XFS_ATTR_FORK; - args.addname = 1; - args.oknoent = 1; - - nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); - if (local) { - if (size > (mp->m_sb.sb_blocksize >> 1)) { - /* Double split possible */ - nblks <<= 1; - } - } else { - uint dblocks = XFS_B_TO_FSB(mp, valuelen); - /* Out of line attribute, cannot double split, but make - * room for the attribute value itself. - */ - nblks += dblocks; - nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK); - } + args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; /* Size is now blocks for attribute data */ - args.total = nblks; + args.total = xfs_attr_calc_size(dp, name->len, valuelen, &local); /* * Start our first transaction of the day. @@ -154,18 +266,17 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, if (rsvd) args.trans->t_flags |= XFS_TRANS_RESERVE; - if ((error = xfs_trans_reserve(args.trans, (uint) nblks, - XFS_ATTRSET_LOG_RES(mp, nblks), - 0, XFS_TRANS_PERM_LOG_RES, - XFS_ATTRSET_LOG_COUNT))) { + if ((error = xfs_trans_reserve(args.trans, args.total, + XFS_ATTRSET_LOG_RES(mp, args.total), 0, + XFS_TRANS_PERM_LOG_RES, XFS_ATTRSET_LOG_COUNT))) { xfs_trans_cancel(args.trans, 0); return(error); } xfs_ilock(dp, XFS_ILOCK_EXCL); - error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, args.trans, dp, nblks, 0, - rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : - XFS_QMOPT_RES_REGBLKS); + error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, args.trans, dp, args.total, 0, + rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : + XFS_QMOPT_RES_REGBLKS); if (error) { xfs_iunlock(dp, XFS_ILOCK_EXCL); xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES); @@ -176,7 +287,7 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, xfs_trans_ihold(args.trans, dp); /* - * If the attribute list is non-existant or a shortform list, + * If the attribute list is non-existent or a shortform list, * upgrade it to a single-leaf-block attribute list. */ if ((dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) || @@ -210,8 +321,7 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, xfs_trans_set_sync(args.trans); } err2 = xfs_trans_commit(args.trans, - XFS_TRANS_RELEASE_LOG_RES, - NULL); + XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); /* @@ -231,7 +341,7 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, error = xfs_attr_shortform_to_leaf(&args); if (!error) { error = xfs_bmap_finish(&args.trans, args.flist, - *args.firstblock, &committed); + &committed); } if (error) { ASSERT(committed); @@ -253,7 +363,9 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, * Commit the leaf transformation. We'll need another (linked) * transaction to add the new attribute to the leaf. */ - if ((error = xfs_attr_rolltrans(&args.trans, dp))) + + error = xfs_trans_roll(&args.trans, dp); + if (error) goto out; } @@ -279,8 +391,7 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, * Commit the last in the sequence of transactions. */ xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE); - error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES, - NULL); + error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); /* @@ -300,8 +411,35 @@ out: return(error); } +int +xfs_attr_set( + xfs_inode_t *dp, + const char *name, + char *value, + int valuelen, + int flags) +{ + int error; + struct xfs_name xname; + + XFS_STATS_INC(xs_attr_set); + + if (XFS_FORCED_SHUTDOWN(dp->i_mount)) + return (EIO); + + error = xfs_attr_name_to_xname(&xname, name); + if (error) + return error; + + return xfs_attr_set_int(dp, &xname, value, valuelen, flags); +} + +/* + * Generic handler routine to remove a name from an attribute list. + * Transitions attribute list from Btree to shortform as necessary. + */ STATIC int -xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags) +xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) { xfs_da_args_t args; xfs_fsblock_t firstblock; @@ -313,8 +451,8 @@ xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags) * Fill in the arg structure for this request. */ memset((char *)&args, 0, sizeof(args)); - args.name = (const uchar_t *)name; - args.namelen = namelen; + args.name = name->name; + args.namelen = name->len; args.flags = flags; args.hashval = xfs_da_hashname(args.name, args.namelen); args.dp = dp; @@ -369,9 +507,7 @@ xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags) /* * Decide on what work routines to call based on the inode size. */ - if (XFS_IFORK_Q(dp) == 0 || - (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && - dp->i_d.di_anextents == 0)) { + if (!xfs_inode_hasattr(dp)) { error = XFS_ERROR(ENOATTR); goto out; } @@ -402,8 +538,7 @@ xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags) * Commit the last in the sequence of transactions. */ xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE); - error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES, - NULL); + error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); /* @@ -423,6 +558,34 @@ out: return(error); } +int +xfs_attr_remove( + xfs_inode_t *dp, + const char *name, + int flags) +{ + int error; + struct xfs_name xname; + + XFS_STATS_INC(xs_attr_remove); + + if (XFS_FORCED_SHUTDOWN(dp->i_mount)) + return (EIO); + + error = xfs_attr_name_to_xname(&xname, name); + if (error) + return error; + + xfs_ilock(dp, XFS_ILOCK_SHARED); + if (!xfs_inode_hasattr(dp)) { + xfs_iunlock(dp, XFS_ILOCK_SHARED); + return XFS_ERROR(ENOATTR); + } + xfs_iunlock(dp, XFS_ILOCK_SHARED); + + return xfs_attr_remove_int(dp, &xname, flags); +} + /*======================================================================== * External routines when attribute list is inside the inode @@ -473,7 +636,7 @@ xfs_attr_shortform_addname(xfs_da_args_t *args) * This leaf block cannot have a "remote" value, we only call this routine * if bmap_one_block() says there is only one block (ie: no remote blks). */ -int +STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args) { xfs_inode_t *dp; @@ -504,7 +667,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) xfs_da_brelse(args->trans, bp); return(retval); } - args->rename = 1; /* an atomic rename */ + args->op_flags |= XFS_DA_OP_RENAME; /* an atomic rename */ args->blkno2 = args->blkno; /* set 2nd entry info*/ args->index2 = args->index; args->rmtblkno2 = args->rmtblkno; @@ -527,7 +690,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) error = xfs_attr_leaf_to_node(args); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, - *args->firstblock, &committed); + &committed); } if (error) { ASSERT(committed); @@ -549,7 +712,8 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) * Commit the current trans (including the inode) and start * a new one. */ - if ((error = xfs_attr_rolltrans(&args->trans, dp))) + error = xfs_trans_roll(&args->trans, dp); + if (error) return (error); /* @@ -563,7 +727,8 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) * Commit the transaction that added the attr name so that * later routines can manage their own transactions. */ - if ((error = xfs_attr_rolltrans(&args->trans, dp))) + error = xfs_trans_roll(&args->trans, dp); + if (error) return (error); /* @@ -584,7 +749,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) * so that one disappears and one appears atomically. Then we * must remove the "old" attribute/value pair. */ - if (args->rename) { + if (args->op_flags & XFS_DA_OP_RENAME) { /* * In a separate transaction, set the incomplete flag on the * "old" attr and clear the incomplete flag on the "new" attr. @@ -628,7 +793,6 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, - *args->firstblock, &committed); } if (error) { @@ -653,7 +817,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) /* * Commit the remove and start the next trans in series. */ - error = xfs_attr_rolltrans(&args->trans, dp); + error = xfs_trans_roll(&args->trans, dp); } else if (args->rmtblkno > 0) { /* @@ -706,7 +870,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) /* bp is gone due to xfs_da_shrink_inode */ if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, - *args->firstblock, &committed); + &committed); } if (error) { ASSERT(committed); @@ -728,6 +892,39 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) return(0); } +/* + * Look up a name in a leaf attribute list structure. + * + * This leaf block cannot have a "remote" value, we only call this routine + * if bmap_one_block() says there is only one block (ie: no remote blks). + */ +STATIC int +xfs_attr_leaf_get(xfs_da_args_t *args) +{ + xfs_dabuf_t *bp; + int error; + + args->blkno = 0; + error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, + XFS_ATTR_FORK); + if (error) + return(error); + ASSERT(bp != NULL); + + error = xfs_attr_leaf_lookup_int(bp, args); + if (error != EEXIST) { + xfs_da_brelse(args->trans, bp); + return(error); + } + error = xfs_attr_leaf_getvalue(bp, args); + xfs_da_brelse(args->trans, bp); + if (!error && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) { + error = xfs_attr_rmtval_get(args); + } + return(error); +} + + /*======================================================================== * External routines when attribute list size > XFS_LBSIZE(mp). *========================================================================*/ @@ -777,7 +974,7 @@ restart: } else if (retval == EEXIST) { if (args->flags & ATTR_CREATE) goto out; - args->rename = 1; /* atomic rename op */ + args->op_flags |= XFS_DA_OP_RENAME; /* atomic rename op */ args->blkno2 = args->blkno; /* set 2nd entry info*/ args->index2 = args->index; args->rmtblkno2 = args->rmtblkno; @@ -800,7 +997,6 @@ restart: if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, - *args->firstblock, &committed); } if (error) { @@ -824,7 +1020,8 @@ restart: * Commit the node conversion and start the next * trans in the chain. */ - if ((error = xfs_attr_rolltrans(&args->trans, dp))) + error = xfs_trans_roll(&args->trans, dp); + if (error) goto out; goto restart; @@ -840,7 +1037,7 @@ restart: error = xfs_da_split(state); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, - *args->firstblock, &committed); + &committed); } if (error) { ASSERT(committed); @@ -875,7 +1072,8 @@ restart: * Commit the leaf addition or btree split and start the next * trans in the chain. */ - if ((error = xfs_attr_rolltrans(&args->trans, dp))) + error = xfs_trans_roll(&args->trans, dp); + if (error) goto out; /* @@ -896,7 +1094,7 @@ restart: * so that one disappears and one appears atomically. Then we * must remove the "old" attribute/value pair. */ - if (args->rename) { + if (args->op_flags & XFS_DA_OP_RENAME) { /* * In a separate transaction, set the incomplete flag on the * "old" attr and clear the incomplete flag on the "new" attr. @@ -952,7 +1150,6 @@ restart: if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, - *args->firstblock, &committed); } if (error) { @@ -976,7 +1173,8 @@ restart: /* * Commit and start the next trans in the chain. */ - if ((error = xfs_attr_rolltrans(&args->trans, dp))) + error = xfs_trans_roll(&args->trans, dp); + if (error) goto out; } else if (args->rmtblkno > 0) { @@ -1087,7 +1285,7 @@ xfs_attr_node_removename(xfs_da_args_t *args) error = xfs_da_join(state); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, - *args->firstblock, &committed); + &committed); } if (error) { ASSERT(committed); @@ -1108,7 +1306,8 @@ xfs_attr_node_removename(xfs_da_args_t *args) /* * Commit the Btree join operation and start a new trans. */ - if ((error = xfs_attr_rolltrans(&args->trans, dp))) + error = xfs_trans_roll(&args->trans, dp); + if (error) goto out; } @@ -1128,8 +1327,8 @@ xfs_attr_node_removename(xfs_da_args_t *args) XFS_ATTR_FORK); if (error) goto out; - ASSERT(INT_GET(((xfs_attr_leafblock_t *) - bp->data)->hdr.info.magic, ARCH_CONVERT) + ASSERT(be16_to_cpu(((xfs_attr_leafblock_t *) + bp->data)->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { @@ -1139,7 +1338,6 @@ xfs_attr_node_removename(xfs_da_args_t *args) if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, - *args->firstblock, &committed); } if (error) { @@ -1172,7 +1370,7 @@ out: * Fill in the disk block numbers in the state structure for the buffers * that are attached to the state structure. * This is done so that we can quickly reattach ourselves to those buffers - * after some set of transaction commit's has released these buffers. + * after some set of transaction commits have released these buffers. */ STATIC int xfs_attr_fillstate(xfs_da_state_t *state) @@ -1219,7 +1417,7 @@ xfs_attr_fillstate(xfs_da_state_t *state) /* * Reattach the buffers to the state structure based on the disk block * numbers stored in the state structure. - * This is done after some set of transaction commit's has released those + * This is done after some set of transaction commits have released those * buffers from our grip. */ STATIC int @@ -1270,6 +1468,120 @@ xfs_attr_refillstate(xfs_da_state_t *state) return(0); } +/* + * Look up a filename in a node attribute list. + * + * This routine gets called for any attribute fork that has more than one + * block, ie: both true Btree attr lists and for single-leaf-blocks with + * "remote" values taking up more blocks. + */ +STATIC int +xfs_attr_node_get(xfs_da_args_t *args) +{ + xfs_da_state_t *state; + xfs_da_state_blk_t *blk; + int error, retval; + int i; + + state = xfs_da_state_alloc(); + state->args = args; + state->mp = args->dp->i_mount; + state->blocksize = state->mp->m_sb.sb_blocksize; + state->node_ents = state->mp->m_attr_node_ents; + + /* + * Search to see if name exists, and get back a pointer to it. + */ + error = xfs_da_node_lookup_int(state, &retval); + if (error) { + retval = error; + } else if (retval == EEXIST) { + blk = &state->path.blk[ state->path.active-1 ]; + ASSERT(blk->bp != NULL); + ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); + + /* + * Get the value, local or "remote" + */ + retval = xfs_attr_leaf_getvalue(blk->bp, args); + if (!retval && (args->rmtblkno > 0) + && !(args->flags & ATTR_KERNOVAL)) { + retval = xfs_attr_rmtval_get(args); + } + } + + /* + * If not in a transaction, we have to release all the buffers. + */ + for (i = 0; i < state->path.active; i++) { + xfs_da_brelse(args->trans, state->path.blk[i].bp); + state->path.blk[i].bp = NULL; + } + + xfs_da_state_free(state); + return(retval); +} + + +/*======================================================================== + * External routines for manipulating out-of-line attribute values. + *========================================================================*/ + +/* + * Read the value associated with an attribute from the out-of-line buffer + * that we stored it in. + */ +int +xfs_attr_rmtval_get(xfs_da_args_t *args) +{ + xfs_bmbt_irec_t map[ATTR_RMTVALUE_MAPSIZE]; + xfs_mount_t *mp; + xfs_daddr_t dblkno; + xfs_caddr_t dst; + xfs_buf_t *bp; + int nmap, error, tmp, valuelen, blkcnt, i; + xfs_dablk_t lblkno; + + ASSERT(!(args->flags & ATTR_KERNOVAL)); + + mp = args->dp->i_mount; + dst = args->value; + valuelen = args->valuelen; + lblkno = args->rmtblkno; + while (valuelen > 0) { + nmap = ATTR_RMTVALUE_MAPSIZE; + error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno, + args->rmtblkcnt, + XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, + NULL, 0, map, &nmap, NULL, NULL); + if (error) + return(error); + ASSERT(nmap >= 1); + + for (i = 0; (i < nmap) && (valuelen > 0); i++) { + ASSERT((map[i].br_startblock != DELAYSTARTBLOCK) && + (map[i].br_startblock != HOLESTARTBLOCK)); + dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock); + blkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount); + error = xfs_read_buf(mp, mp->m_ddev_targp, dblkno, + blkcnt, XFS_BUF_LOCK, &bp); + if (error) + return(error); + + tmp = (valuelen < XFS_BUF_SIZE(bp)) + ? valuelen : XFS_BUF_SIZE(bp); + xfs_biomove(bp, 0, tmp, dst, XFS_B_READ); + xfs_buf_relse(bp); + dst += tmp; + valuelen -= tmp; + + lblkno += map[i].br_blockcount; + } + } + ASSERT(valuelen == 0); + return(0); +} + /* * Write the value associated with an attribute into the out-of-line buffer * that we have defined for it. @@ -1289,7 +1601,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args) dp = args->dp; mp = dp->i_mount; - src = (xfs_caddr_t)args->value; + src = args->value; /* * Find a "hole" in the attribute address space large enough for @@ -1319,10 +1631,10 @@ xfs_attr_rmtval_set(xfs_da_args_t *args) XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA | XFS_BMAPI_WRITE, args->firstblock, args->total, &map, &nmap, - args->flist); + args->flist, NULL); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, - *args->firstblock, &committed); + &committed); } if (error) { ASSERT(committed); @@ -1349,7 +1661,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args) /* * Start the next trans in the chain. */ - if ((error = xfs_attr_rolltrans(&args->trans, dp))) + error = xfs_trans_roll(&args->trans, dp); + if (error) return (error); } @@ -1370,7 +1683,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args) error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno, args->rmtblkcnt, XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, - args->firstblock, 0, &map, &nmap, NULL); + args->firstblock, 0, &map, &nmap, + NULL, NULL); if (error) { return(error); } @@ -1435,7 +1749,7 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args) args->rmtblkcnt, XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, args->firstblock, 0, &map, &nmap, - args->flist); + args->flist, NULL); if (error) { return(error); } @@ -1473,10 +1787,11 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args) XFS_BMAP_INIT(args->flist, args->firstblock); error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, - 1, args->firstblock, args->flist, &done); + 1, args->firstblock, args->flist, + NULL, &done); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, - *args->firstblock, &committed); + &committed); } if (error) { ASSERT(committed); @@ -1497,7 +1812,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args) /* * Close out trans and start the next one in the chain. */ - if ((error = xfs_attr_rolltrans(&args->trans, args->dp))) + error = xfs_trans_roll(&args->trans, args->dp); + if (error) return (error); } return(0); diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c index 496bb1fb7..f8f926fb1 100644 --- a/libxfs/xfs_attr_leaf.c +++ b/libxfs/xfs_attr_leaf.c @@ -24,12 +24,54 @@ * Routines to implement leaf blocks of attributes as Btrees of hashed names. */ +/*======================================================================== + * Function prototypes for the kernel. + *========================================================================*/ + +/* + * Routines used for growing the Btree. + */ STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t which_block, - xfs_dabuf_t **bpp); + xfs_dabuf_t **bpp); +STATIC int xfs_attr_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args, + int freemap_index); +STATIC void xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer); +STATIC void xfs_attr_leaf_rebalance(xfs_da_state_t *state, + xfs_da_state_blk_t *blk1, + xfs_da_state_blk_t *blk2); +STATIC int xfs_attr_leaf_figure_balance(xfs_da_state_t *state, + xfs_da_state_blk_t *leaf_blk_1, + xfs_da_state_blk_t *leaf_blk_2, + int *number_entries_in_blk1, + int *number_usedbytes_in_blk1); + +/* + * Utility routines. + */ +STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf, + int src_start, + xfs_attr_leafblock_t *dst_leaf, + int dst_start, int move_count, + xfs_mount_t *mp); STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); /*======================================================================== - * External routines when attributes < XFS_LITINO(mp). + * Namespace helper routines + *========================================================================*/ + +/* + * If namespace bits don't match return 0. + * If all match then return 1. + */ +STATIC_INLINE int +xfs_attr_namesp_match(int arg_flags, int ondisk_flags) +{ + return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags); +} + + +/*======================================================================== + * External routines when attribute fork size < XFS_LITINO(mp). *========================================================================*/ /* @@ -47,6 +89,7 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes) int offset; int minforkoff; /* lower limit on valid forkoff locations */ int maxforkoff; /* upper limit on valid forkoff locations */ + int dsize; xfs_mount_t *mp = dp->i_mount; offset = (XFS_LITINO(mp) - bytes) >> 3; /* rounded down */ @@ -60,14 +103,49 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes) return (offset >= minforkoff) ? minforkoff : 0; } - if (unlikely(mp->m_flags & XFS_MOUNT_COMPAT_ATTR)) { + if (!(mp->m_flags & XFS_MOUNT_ATTR2)) { if (bytes <= XFS_IFORK_ASIZE(dp)) - return mp->m_attroffset >> 3; + return dp->i_d.di_forkoff; return 0; } - /* data fork btree root can have at least this many key/ptr pairs */ - minforkoff = MAX(dp->i_df.if_bytes, XFS_BMDR_SPACE_CALC(MINDBTPTRS)); + dsize = dp->i_df.if_bytes; + + switch (dp->i_d.di_format) { + case XFS_DINODE_FMT_EXTENTS: + /* + * If there is no attr fork and the data fork is extents, + * determine if creating the default attr fork will result + * in the extents form migrating to btree. If so, the + * minimum offset only needs to be the space required for + * the btree root. + */ + if (!dp->i_d.di_forkoff && dp->i_df.if_bytes > mp->m_attroffset) + dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS); + break; + + case XFS_DINODE_FMT_BTREE: + /* + * If have data btree then keep forkoff if we have one, + * otherwise we are adding a new attr, so then we set + * minforkoff to where the btree root can finish so we have + * plenty of room for attrs + */ + if (dp->i_d.di_forkoff) { + if (offset < dp->i_d.di_forkoff) + return 0; + else + return dp->i_d.di_forkoff; + } else + dsize = XFS_BMAP_BROOT_SPACE(dp->i_df.if_broot); + break; + } + + /* + * A data fork btree root must have space for at least + * MINDBTPTRS key/ptr pairs if the data fork is small or empty. + */ + minforkoff = MAX(dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS)); minforkoff = roundup(minforkoff, 8) >> 3; /* attr fork btree root can have at least this many key/ptr pairs */ @@ -87,17 +165,15 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes) STATIC void xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp) { - unsigned long s; - - if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR) && - !(XFS_SB_VERSION_HASATTR2(&mp->m_sb))) { - s = XFS_SB_LOCK(mp); - if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) { - XFS_SB_VERSION_ADDATTR2(&mp->m_sb); - XFS_SB_UNLOCK(mp, s); + if ((mp->m_flags & XFS_MOUNT_ATTR2) && + !(xfs_sb_version_hasattr2(&mp->m_sb))) { + spin_lock(&mp->m_sb_lock); + if (!xfs_sb_version_hasattr2(&mp->m_sb)) { + xfs_sb_version_addattr2(&mp->m_sb); + spin_unlock(&mp->m_sb_lock); xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); } else - XFS_SB_UNLOCK(mp, s); + spin_unlock(&mp->m_sb_lock); } } @@ -126,7 +202,7 @@ xfs_attr_shortform_create(xfs_da_args_t *args) xfs_idata_realloc(dp, sizeof(*hdr), XFS_ATTR_FORK); hdr = (xfs_attr_sf_hdr_t *)ifp->if_u1.if_data; hdr->count = 0; - INT_SET(hdr->totsize, ARCH_CONVERT, sizeof(*hdr)); + hdr->totsize = cpu_to_be16(sizeof(*hdr)); xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); } @@ -156,18 +232,13 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff) ASSERT(ifp->if_flags & XFS_IFINLINE); sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; sfe = &sf->list[0]; - for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT); - sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) { + for (i = 0; i < sf->hdr.count; sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) { #ifdef DEBUG if (sfe->namelen != args->namelen) continue; if (memcmp(args->name, sfe->nameval, args->namelen) != 0) continue; - if (((args->flags & ATTR_SECURE) != 0) != - ((sfe->flags & XFS_ATTR_SECURE) != 0)) - continue; - if (((args->flags & ATTR_ROOT) != 0) != - ((sfe->flags & XFS_ATTR_ROOT) != 0)) + if (!xfs_attr_namesp_match(args->flags, sfe->flags)) continue; ASSERT(0); #endif @@ -180,13 +251,12 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff) sfe = (xfs_attr_sf_entry_t *)((char *)sf + offset); sfe->namelen = args->namelen; - INT_SET(sfe->valuelen, ARCH_CONVERT, args->valuelen); - sfe->flags = (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE : - ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0); + sfe->valuelen = args->valuelen; + sfe->flags = XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags); memcpy(sfe->nameval, args->name, args->namelen); memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen); - INT_MOD(sf->hdr.count, ARCH_CONVERT, 1); - INT_MOD(sf->hdr.totsize, ARCH_CONVERT, size); + sf->hdr.count++; + be16_add_cpu(&sf->hdr.totsize, size); xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); xfs_sbversion_add_attr2(mp, args->trans); @@ -209,7 +279,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) base = sizeof(xfs_attr_sf_hdr_t); sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data; sfe = &sf->list[0]; - end = INT_GET(sf->hdr.count, ARCH_CONVERT); + end = sf->hdr.count; for (i = 0; i < end; sfe = XFS_ATTR_SF_NEXTENTRY(sfe), base += size, i++) { size = XFS_ATTR_SF_ENTSIZE(sfe); @@ -217,11 +287,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) continue; if (memcmp(sfe->nameval, args->name, args->namelen) != 0) continue; - if (((args->flags & ATTR_SECURE) != 0) != - ((sfe->flags & XFS_ATTR_SECURE) != 0)) - continue; - if (((args->flags & ATTR_ROOT) != 0) != - ((sfe->flags & XFS_ATTR_ROOT) != 0)) + if (!xfs_attr_namesp_match(args->flags, sfe->flags)) continue; break; } @@ -232,18 +298,20 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) * Fix up the attribute fork data, covering the hole */ end = base + size; - totsize = INT_GET(sf->hdr.totsize, ARCH_CONVERT); + totsize = be16_to_cpu(sf->hdr.totsize); if (end != totsize) memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end); - INT_MOD(sf->hdr.count, ARCH_CONVERT, -1); - INT_MOD(sf->hdr.totsize, ARCH_CONVERT, -size); + sf->hdr.count--; + be16_add_cpu(&sf->hdr.totsize, -size); /* * Fix up the start offset of the attribute fork */ totsize -= size; - if (totsize == sizeof(xfs_attr_sf_hdr_t) && !args->addname && - !(mp->m_flags & XFS_MOUNT_COMPAT_ATTR)) { + if (totsize == sizeof(xfs_attr_sf_hdr_t) && + !(args->op_flags & XFS_DA_OP_ADDNAME) && + (mp->m_flags & XFS_MOUNT_ATTR2) && + (dp->i_d.di_format != XFS_DINODE_FMT_BTREE)) { /* * Last attribute now removed, revert to original * inode format making all literal area available @@ -261,8 +329,10 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize); ASSERT(dp->i_d.di_forkoff); - ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || args->addname || - (mp->m_flags & XFS_MOUNT_COMPAT_ATTR)); + ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || + (args->op_flags & XFS_DA_OP_ADDNAME) || + !(mp->m_flags & XFS_MOUNT_ATTR2) || + dp->i_d.di_format == XFS_DINODE_FMT_BTREE); dp->i_afp->if_ext_max = XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t); dp->i_df.if_ext_max = @@ -292,18 +362,52 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args) ASSERT(ifp->if_flags & XFS_IFINLINE); sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; sfe = &sf->list[0]; - for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT); + for (i = 0; i < sf->hdr.count; sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) { if (sfe->namelen != args->namelen) continue; if (memcmp(args->name, sfe->nameval, args->namelen) != 0) continue; - if (((args->flags & ATTR_SECURE) != 0) != - ((sfe->flags & XFS_ATTR_SECURE) != 0)) + if (!xfs_attr_namesp_match(args->flags, sfe->flags)) continue; - if (((args->flags & ATTR_ROOT) != 0) != - ((sfe->flags & XFS_ATTR_ROOT) != 0)) + return(XFS_ERROR(EEXIST)); + } + return(XFS_ERROR(ENOATTR)); +} + +/* + * Look up a name in a shortform attribute list structure. + */ +/*ARGSUSED*/ +int +xfs_attr_shortform_getvalue(xfs_da_args_t *args) +{ + xfs_attr_shortform_t *sf; + xfs_attr_sf_entry_t *sfe; + int i; + + ASSERT(args->dp->i_d.di_aformat == XFS_IFINLINE); + sf = (xfs_attr_shortform_t *)args->dp->i_afp->if_u1.if_data; + sfe = &sf->list[0]; + for (i = 0; i < sf->hdr.count; + sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) { + if (sfe->namelen != args->namelen) continue; + if (memcmp(args->name, sfe->nameval, args->namelen) != 0) + continue; + if (!xfs_attr_namesp_match(args->flags, sfe->flags)) + continue; + if (args->flags & ATTR_KERNOVAL) { + args->valuelen = sfe->valuelen; + return(XFS_ERROR(EEXIST)); + } + if (args->valuelen < sfe->valuelen) { + args->valuelen = sfe->valuelen; + return(XFS_ERROR(ERANGE)); + } + args->valuelen = sfe->valuelen; + memcpy(args->value, &sfe->nameval[args->namelen], + args->valuelen); return(XFS_ERROR(EEXIST)); } return(XFS_ERROR(ENOATTR)); @@ -328,7 +432,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) dp = args->dp; ifp = dp->i_afp; sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; - size = INT_GET(sf->hdr.totsize, ARCH_CONVERT); + size = be16_to_cpu(sf->hdr.totsize); tmpbuffer = kmem_alloc(size, KM_SLEEP); ASSERT(tmpbuffer != NULL); memcpy(tmpbuffer, ifp->if_u1.if_data, size); @@ -368,18 +472,17 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) nargs.total = args->total; nargs.whichfork = XFS_ATTR_FORK; nargs.trans = args->trans; - nargs.oknoent = 1; + nargs.op_flags = XFS_DA_OP_OKNOENT; sfe = &sf->list[0]; - for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT); i++) { - nargs.name = (const uchar_t *)sfe->nameval; + for (i = 0; i < sf->hdr.count; i++) { + nargs.name = (char *)sfe->nameval; nargs.namelen = sfe->namelen; - nargs.value = (uchar_t *)&sfe->nameval[nargs.namelen]; - nargs.valuelen = INT_GET(sfe->valuelen, ARCH_CONVERT); - nargs.hashval = xfs_da_hashname((const uchar_t *)sfe->nameval, + nargs.value = (char *)&sfe->nameval[nargs.namelen]; + nargs.valuelen = sfe->valuelen; + nargs.hashval = xfs_da_hashname((char *)sfe->nameval, sfe->namelen); - nargs.flags = (sfe->flags & XFS_ATTR_SECURE) ? ATTR_SECURE : - ((sfe->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0); + nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags); error = xfs_attr_leaf_lookup_int(bp, &nargs); /* set a->index */ ASSERT(error == ENOATTR); error = xfs_attr_leaf_add(bp, &nargs); @@ -393,16 +496,13 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) out: if(bp) xfs_da_buf_done(bp); - kmem_free(tmpbuffer, size); + kmem_free(tmpbuffer); return(error); } /* * Check a leaf attribute block to see if all the entries would fit into * a shortform attribute list. - * Returns zero if not, minus one if no entries at all exist now, or the - * value that should be used for di_forkoff in the inode after switching - * it to shortform attributes. */ int xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp) @@ -413,12 +513,11 @@ xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp) int bytes, i; leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); entry = &leaf->entries[0]; bytes = sizeof(struct xfs_attr_sf_hdr); - for (i = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); entry++, i++) { + for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { if (entry->flags & XFS_ATTR_INCOMPLETE) continue; /* don't copy partial entries */ if (!(entry->flags & XFS_ATTR_LOCAL)) @@ -426,13 +525,14 @@ xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp) name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); if (name_loc->namelen >= XFS_ATTR_SF_ENTSIZE_MAX) return(0); - if (INT_GET(name_loc->valuelen, ARCH_CONVERT) >= XFS_ATTR_SF_ENTSIZE_MAX) + if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX) return(0); bytes += sizeof(struct xfs_attr_sf_entry)-1 + name_loc->namelen - + INT_GET(name_loc->valuelen, ARCH_CONVERT); + + be16_to_cpu(name_loc->valuelen); } - if (!(dp->i_mount->m_flags & XFS_MOUNT_COMPAT_ATTR) && + if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) && + (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && (bytes == sizeof(struct xfs_attr_sf_hdr))) return(-1); return(xfs_attr_shortform_bytesfit(dp, bytes)); @@ -459,8 +559,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff) ASSERT(bp != NULL); memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount)); leaf = (xfs_attr_leafblock_t *)tmpbuffer; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); memset(bp->data, 0, XFS_LBSIZE(dp->i_mount)); /* @@ -471,7 +570,8 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff) goto out; if (forkoff == -1) { - ASSERT(!(dp->i_mount->m_flags & XFS_MOUNT_COMPAT_ATTR)); + ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2); + ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE); /* * Last attribute was removed, revert to original @@ -501,28 +601,27 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff) nargs.total = args->total; nargs.whichfork = XFS_ATTR_FORK; nargs.trans = args->trans; - nargs.oknoent = 1; + nargs.op_flags = XFS_DA_OP_OKNOENT; entry = &leaf->entries[0]; - for (i = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); entry++, i++) { + for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { if (entry->flags & XFS_ATTR_INCOMPLETE) continue; /* don't copy partial entries */ if (!entry->nameidx) continue; ASSERT(entry->flags & XFS_ATTR_LOCAL); name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); - nargs.name = (const uchar_t *)name_loc->nameval; + nargs.name = (char *)name_loc->nameval; nargs.namelen = name_loc->namelen; - nargs.value = (uchar_t *)&name_loc->nameval[nargs.namelen]; - nargs.valuelen = INT_GET(name_loc->valuelen, ARCH_CONVERT); - nargs.hashval = INT_GET(entry->hashval, ARCH_CONVERT); - nargs.flags = (entry->flags & XFS_ATTR_SECURE) ? ATTR_SECURE : - ((entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0); + nargs.value = (char *)&name_loc->nameval[nargs.namelen]; + nargs.valuelen = be16_to_cpu(name_loc->valuelen); + nargs.hashval = be32_to_cpu(entry->hashval); + nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(entry->flags); xfs_attr_shortform_add(&nargs, forkoff); } error = 0; out: - kmem_free(tmpbuffer, XFS_LBSIZE(dp->i_mount)); + kmem_free(tmpbuffer); return(error); } @@ -568,13 +667,12 @@ xfs_attr_leaf_to_node(xfs_da_args_t *args) goto out; node = bp1->data; leaf = bp2->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); /* both on-disk, don't endian-flip twice */ node->btree[0].hashval = - leaf->entries[INT_GET(leaf->hdr.count, ARCH_CONVERT)-1 ].hashval; - INT_SET(node->btree[0].before, ARCH_CONVERT, blkno); - INT_SET(node->hdr.count, ARCH_CONVERT, 1); + leaf->entries[be16_to_cpu(leaf->hdr.count)-1 ].hashval; + node->btree[0].before = cpu_to_be32(blkno); + node->hdr.count = cpu_to_be16(1); xfs_da_log_buf(args->trans, bp1, 0, XFS_LBSIZE(dp->i_mount) - 1); error = 0; out: @@ -585,6 +683,7 @@ out: return(error); } + /*======================================================================== * Routines used for growing the Btree. *========================================================================*/ @@ -593,7 +692,7 @@ out: * Create the initial contents of a leaf attribute list * or a leaf in a node attribute list. */ -int +STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) { xfs_attr_leafblock_t *leaf; @@ -612,19 +711,16 @@ xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) leaf = bp->data; memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount)); hdr = &leaf->hdr; - INT_SET(hdr->info.magic, ARCH_CONVERT, XFS_ATTR_LEAF_MAGIC); - INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount)); + hdr->info.magic = cpu_to_be16(XFS_ATTR_LEAF_MAGIC); + hdr->firstused = cpu_to_be16(XFS_LBSIZE(dp->i_mount)); if (!hdr->firstused) { - INT_SET(hdr->firstused, ARCH_CONVERT, + hdr->firstused = cpu_to_be16( XFS_LBSIZE(dp->i_mount) - XFS_ATTR_LEAF_NAME_ALIGN); } - INT_SET(hdr->freemap[0].base, ARCH_CONVERT, - sizeof(xfs_attr_leaf_hdr_t)); - INT_SET(hdr->freemap[0].size, ARCH_CONVERT, - INT_GET(hdr->firstused, ARCH_CONVERT) - - INT_GET(hdr->freemap[0].base, - ARCH_CONVERT)); + hdr->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t)); + hdr->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr->firstused) - + sizeof(xfs_attr_leaf_hdr_t)); xfs_da_log_buf(args->trans, bp, 0, XFS_LBSIZE(dp->i_mount) - 1); @@ -696,10 +792,9 @@ xfs_attr_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args) int tablesize, entsize, sum, tmp, i; leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); ASSERT((args->index >= 0) - && (args->index <= INT_GET(leaf->hdr.count, ARCH_CONVERT))); + && (args->index <= be16_to_cpu(leaf->hdr.count))); hdr = &leaf->hdr; entsize = xfs_attr_leaf_newentsize(args->namelen, args->valuelen, args->trans->t_mountp->m_sb.sb_blocksize, NULL); @@ -708,26 +803,25 @@ xfs_attr_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args) * Search through freemap for first-fit on new name length. * (may need to figure in size of entry struct too) */ - tablesize = (INT_GET(hdr->count, ARCH_CONVERT) + 1) + tablesize = (be16_to_cpu(hdr->count) + 1) * sizeof(xfs_attr_leaf_entry_t) + sizeof(xfs_attr_leaf_hdr_t); map = &hdr->freemap[XFS_ATTR_LEAF_MAPSIZE-1]; for (sum = 0, i = XFS_ATTR_LEAF_MAPSIZE-1; i >= 0; map--, i--) { - if (tablesize > INT_GET(hdr->firstused, ARCH_CONVERT)) { - sum += INT_GET(map->size, ARCH_CONVERT); + if (tablesize > be16_to_cpu(hdr->firstused)) { + sum += be16_to_cpu(map->size); continue; } if (!map->size) continue; /* no space in this map */ tmp = entsize; - if (INT_GET(map->base, ARCH_CONVERT) - < INT_GET(hdr->firstused, ARCH_CONVERT)) + if (be16_to_cpu(map->base) < be16_to_cpu(hdr->firstused)) tmp += sizeof(xfs_attr_leaf_entry_t); - if (INT_GET(map->size, ARCH_CONVERT) >= tmp) { + if (be16_to_cpu(map->size) >= tmp) { tmp = xfs_attr_leaf_add_work(bp, args, i); return(tmp); } - sum += INT_GET(map->size, ARCH_CONVERT); + sum += be16_to_cpu(map->size); } /* @@ -748,7 +842,7 @@ xfs_attr_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args) * After compaction, the block is guaranteed to have only one * free region, in freemap[0]. If it is not big enough, give up. */ - if (INT_GET(hdr->freemap[0].size, ARCH_CONVERT) + if (be16_to_cpu(hdr->freemap[0].size) < (entsize + sizeof(xfs_attr_leaf_entry_t))) return(XFS_ERROR(ENOSPC)); @@ -771,49 +865,45 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) int tmp, i; leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); hdr = &leaf->hdr; ASSERT((mapindex >= 0) && (mapindex < XFS_ATTR_LEAF_MAPSIZE)); - ASSERT((args->index >= 0) - && (args->index <= INT_GET(hdr->count, ARCH_CONVERT))); + ASSERT((args->index >= 0) && (args->index <= be16_to_cpu(hdr->count))); /* * Force open some space in the entry array and fill it in. */ entry = &leaf->entries[args->index]; - if (args->index < INT_GET(hdr->count, ARCH_CONVERT)) { - tmp = INT_GET(hdr->count, ARCH_CONVERT) - args->index; + if (args->index < be16_to_cpu(hdr->count)) { + tmp = be16_to_cpu(hdr->count) - args->index; tmp *= sizeof(xfs_attr_leaf_entry_t); memmove((char *)(entry+1), (char *)entry, tmp); xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); } - INT_MOD(hdr->count, ARCH_CONVERT, 1); + be16_add_cpu(&hdr->count, 1); /* * Allocate space for the new string (at the end of the run). */ map = &hdr->freemap[mapindex]; mp = args->trans->t_mountp; - ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp)); - ASSERT((INT_GET(map->base, ARCH_CONVERT) & 0x3) == 0); - ASSERT(INT_GET(map->size, ARCH_CONVERT) >= + ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp)); + ASSERT((be16_to_cpu(map->base) & 0x3) == 0); + ASSERT(be16_to_cpu(map->size) >= xfs_attr_leaf_newentsize(args->namelen, args->valuelen, mp->m_sb.sb_blocksize, NULL)); - ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp)); - ASSERT((INT_GET(map->size, ARCH_CONVERT) & 0x3) == 0); - INT_MOD(map->size, ARCH_CONVERT, + ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); + ASSERT((be16_to_cpu(map->size) & 0x3) == 0); + be16_add_cpu(&map->size, -xfs_attr_leaf_newentsize(args->namelen, args->valuelen, mp->m_sb.sb_blocksize, &tmp)); - INT_SET(entry->nameidx, ARCH_CONVERT, - INT_GET(map->base, ARCH_CONVERT) - + INT_GET(map->size, ARCH_CONVERT)); - INT_SET(entry->hashval, ARCH_CONVERT, args->hashval); + entry->nameidx = cpu_to_be16(be16_to_cpu(map->base) + + be16_to_cpu(map->size)); + entry->hashval = cpu_to_be32(args->hashval); entry->flags = tmp ? XFS_ATTR_LOCAL : 0; - entry->flags |= (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE : - ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0); - if (args->rename) { + entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags); + if (args->op_flags & XFS_DA_OP_RENAME) { entry->flags |= XFS_ATTR_INCOMPLETE; if ((args->blkno2 == args->blkno) && (args->index2 <= args->index)) { @@ -822,12 +912,10 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) } xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); - ASSERT((args->index == 0) || (INT_GET(entry->hashval, ARCH_CONVERT) - >= INT_GET((entry-1)->hashval, - ARCH_CONVERT))); - ASSERT((args->index == INT_GET(hdr->count, ARCH_CONVERT)-1) || - (INT_GET(entry->hashval, ARCH_CONVERT) - <= (INT_GET((entry+1)->hashval, ARCH_CONVERT)))); + ASSERT((args->index == 0) || + (be32_to_cpu(entry->hashval) >= be32_to_cpu((entry-1)->hashval))); + ASSERT((args->index == be16_to_cpu(hdr->count)-1) || + (be32_to_cpu(entry->hashval) <= be32_to_cpu((entry+1)->hashval))); /* * Copy the attribute name and value into the new space. @@ -841,10 +929,10 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) if (entry->flags & XFS_ATTR_LOCAL) { name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, args->index); name_loc->namelen = args->namelen; - INT_SET(name_loc->valuelen, ARCH_CONVERT, args->valuelen); + name_loc->valuelen = cpu_to_be16(args->valuelen); memcpy((char *)name_loc->nameval, args->name, args->namelen); memcpy((char *)&name_loc->nameval[args->namelen], args->value, - INT_GET(name_loc->valuelen, ARCH_CONVERT)); + be16_to_cpu(name_loc->valuelen)); } else { name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, args->index); name_rmt->namelen = args->namelen; @@ -863,28 +951,23 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) /* * Update the control info for this leaf node */ - if (INT_GET(entry->nameidx, ARCH_CONVERT) - < INT_GET(hdr->firstused, ARCH_CONVERT)) { + if (be16_to_cpu(entry->nameidx) < be16_to_cpu(hdr->firstused)) { /* both on-disk, don't endian-flip twice */ hdr->firstused = entry->nameidx; } - ASSERT(INT_GET(hdr->firstused, ARCH_CONVERT) - >= ((INT_GET(hdr->count, ARCH_CONVERT) - * sizeof(*entry))+sizeof(*hdr))); - tmp = (INT_GET(hdr->count, ARCH_CONVERT)-1) - * sizeof(xfs_attr_leaf_entry_t) + ASSERT(be16_to_cpu(hdr->firstused) >= + ((be16_to_cpu(hdr->count) * sizeof(*entry)) + sizeof(*hdr))); + tmp = (be16_to_cpu(hdr->count)-1) * sizeof(xfs_attr_leaf_entry_t) + sizeof(xfs_attr_leaf_hdr_t); map = &hdr->freemap[0]; for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) { - if (INT_GET(map->base, ARCH_CONVERT) == tmp) { - INT_MOD(map->base, ARCH_CONVERT, - sizeof(xfs_attr_leaf_entry_t)); - INT_MOD(map->size, ARCH_CONVERT, - -sizeof(xfs_attr_leaf_entry_t)); + if (be16_to_cpu(map->base) == tmp) { + be16_add_cpu(&map->base, sizeof(xfs_attr_leaf_entry_t)); + be16_add_cpu(&map->size, + -((int)sizeof(xfs_attr_leaf_entry_t))); } } - INT_MOD(hdr->usedbytes, ARCH_CONVERT, - xfs_attr_leaf_entsize(leaf, args->index)); + be16_add_cpu(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index)); xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); return(0); @@ -915,31 +998,28 @@ xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp) hdr_s = &leaf_s->hdr; hdr_d = &leaf_d->hdr; hdr_d->info = hdr_s->info; /* struct copy */ - INT_SET(hdr_d->firstused, ARCH_CONVERT, XFS_LBSIZE(mp)); + hdr_d->firstused = cpu_to_be16(XFS_LBSIZE(mp)); /* handle truncation gracefully */ if (!hdr_d->firstused) { - INT_SET(hdr_d->firstused, ARCH_CONVERT, + hdr_d->firstused = cpu_to_be16( XFS_LBSIZE(mp) - XFS_ATTR_LEAF_NAME_ALIGN); } hdr_d->usedbytes = 0; hdr_d->count = 0; hdr_d->holes = 0; - INT_SET(hdr_d->freemap[0].base, ARCH_CONVERT, - sizeof(xfs_attr_leaf_hdr_t)); - INT_SET(hdr_d->freemap[0].size, ARCH_CONVERT, - INT_GET(hdr_d->firstused, ARCH_CONVERT) - - INT_GET(hdr_d->freemap[0].base, ARCH_CONVERT)); + hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t)); + hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) - + sizeof(xfs_attr_leaf_hdr_t)); /* * Copy all entry's in the same (sorted) order, * but allocate name/value pairs packed and in sequence. */ xfs_attr_leaf_moveents(leaf_s, 0, leaf_d, 0, - (int)INT_GET(hdr_s->count, ARCH_CONVERT), mp); - + be16_to_cpu(hdr_s->count), mp); xfs_da_log_buf(trans, bp, 0, XFS_LBSIZE(mp) - 1); - kmem_free(tmpbuffer, XFS_LBSIZE(mp)); + kmem_free(tmpbuffer); } /* @@ -971,10 +1051,8 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC); leaf1 = blk1->bp->data; leaf2 = blk2->bp->data; - ASSERT(INT_GET(leaf1->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); - ASSERT(INT_GET(leaf2->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); args = state->args; /* @@ -1011,22 +1089,21 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, /* * Move any entries required from leaf to leaf: */ - if (count < INT_GET(hdr1->count, ARCH_CONVERT)) { + if (count < be16_to_cpu(hdr1->count)) { /* * Figure the total bytes to be added to the destination leaf. */ /* number entries being moved */ - count = INT_GET(hdr1->count, ARCH_CONVERT) - count; - space = INT_GET(hdr1->usedbytes, ARCH_CONVERT) - totallen; + count = be16_to_cpu(hdr1->count) - count; + space = be16_to_cpu(hdr1->usedbytes) - totallen; space += count * sizeof(xfs_attr_leaf_entry_t); /* * leaf2 is the destination, compact it if it looks tight. */ - max = INT_GET(hdr2->firstused, ARCH_CONVERT) + max = be16_to_cpu(hdr2->firstused) - sizeof(xfs_attr_leaf_hdr_t); - max -= INT_GET(hdr2->count, ARCH_CONVERT) - * sizeof(xfs_attr_leaf_entry_t); + max -= be16_to_cpu(hdr2->count) * sizeof(xfs_attr_leaf_entry_t); if (space > max) { xfs_attr_leaf_compact(args->trans, blk2->bp); } @@ -1034,13 +1111,12 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, /* * Move high entries from leaf1 to low end of leaf2. */ - xfs_attr_leaf_moveents(leaf1, - INT_GET(hdr1->count, ARCH_CONVERT)-count, + xfs_attr_leaf_moveents(leaf1, be16_to_cpu(hdr1->count) - count, leaf2, 0, count, state->mp); xfs_da_log_buf(args->trans, blk1->bp, 0, state->blocksize-1); xfs_da_log_buf(args->trans, blk2->bp, 0, state->blocksize-1); - } else if (count > INT_GET(hdr1->count, ARCH_CONVERT)) { + } else if (count > be16_to_cpu(hdr1->count)) { /* * I assert that since all callers pass in an empty * second buffer, this code should never execute. @@ -1050,17 +1126,16 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, * Figure the total bytes to be added to the destination leaf. */ /* number entries being moved */ - count -= INT_GET(hdr1->count, ARCH_CONVERT); - space = totallen - INT_GET(hdr1->usedbytes, ARCH_CONVERT); + count -= be16_to_cpu(hdr1->count); + space = totallen - be16_to_cpu(hdr1->usedbytes); space += count * sizeof(xfs_attr_leaf_entry_t); /* * leaf1 is the destination, compact it if it looks tight. */ - max = INT_GET(hdr1->firstused, ARCH_CONVERT) + max = be16_to_cpu(hdr1->firstused) - sizeof(xfs_attr_leaf_hdr_t); - max -= INT_GET(hdr1->count, ARCH_CONVERT) - * sizeof(xfs_attr_leaf_entry_t); + max -= be16_to_cpu(hdr1->count) * sizeof(xfs_attr_leaf_entry_t); if (space > max) { xfs_attr_leaf_compact(args->trans, blk1->bp); } @@ -1069,8 +1144,7 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, * Move low entries from leaf2 to high end of leaf1. */ xfs_attr_leaf_moveents(leaf2, 0, leaf1, - (int)INT_GET(hdr1->count, ARCH_CONVERT), count, - state->mp); + be16_to_cpu(hdr1->count), count, state->mp); xfs_da_log_buf(args->trans, blk1->bp, 0, state->blocksize-1); xfs_da_log_buf(args->trans, blk2->bp, 0, state->blocksize-1); @@ -1079,12 +1153,10 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, /* * Copy out last hashval in each block for B-tree code. */ - blk1->hashval = - INT_GET(leaf1->entries[INT_GET(leaf1->hdr.count, - ARCH_CONVERT)-1].hashval, ARCH_CONVERT); - blk2->hashval = - INT_GET(leaf2->entries[INT_GET(leaf2->hdr.count, - ARCH_CONVERT)-1].hashval, ARCH_CONVERT); + blk1->hashval = be32_to_cpu( + leaf1->entries[be16_to_cpu(leaf1->hdr.count)-1].hashval); + blk2->hashval = be32_to_cpu( + leaf2->entries[be16_to_cpu(leaf2->hdr.count)-1].hashval); /* * Adjust the expected index for insertion. @@ -1098,13 +1170,12 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, * inserting. The index/blkno fields refer to the "old" entry, * while the index2/blkno2 fields refer to the "new" entry. */ - if (blk1->index > INT_GET(leaf1->hdr.count, ARCH_CONVERT)) { + if (blk1->index > be16_to_cpu(leaf1->hdr.count)) { ASSERT(state->inleaf == 0); - blk2->index = blk1->index - - INT_GET(leaf1->hdr.count, ARCH_CONVERT); + blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count); args->index = args->index2 = blk2->index; args->blkno = args->blkno2 = blk2->blkno; - } else if (blk1->index == INT_GET(leaf1->hdr.count, ARCH_CONVERT)) { + } else if (blk1->index == be16_to_cpu(leaf1->hdr.count)) { if (state->inleaf) { args->index = blk1->index; args->blkno = blk1->blkno; @@ -1112,7 +1183,7 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, args->blkno2 = blk2->blkno; } else { blk2->index = blk1->index - - INT_GET(leaf1->hdr.count, ARCH_CONVERT); + - be16_to_cpu(leaf1->hdr.count); args->index = args->index2 = blk2->index; args->blkno = args->blkno2 = blk2->blkno; } @@ -1156,15 +1227,14 @@ xfs_attr_leaf_figure_balance(xfs_da_state_t *state, * Examine entries until we reduce the absolute difference in * byte usage between the two blocks to a minimum. */ - max = INT_GET(hdr1->count, ARCH_CONVERT) - + INT_GET(hdr2->count, ARCH_CONVERT); + max = be16_to_cpu(hdr1->count) + be16_to_cpu(hdr2->count); half = (max+1) * sizeof(*entry); - half += INT_GET(hdr1->usedbytes, ARCH_CONVERT) - + INT_GET(hdr2->usedbytes, ARCH_CONVERT) - + xfs_attr_leaf_newentsize( - state->args->namelen, - state->args->valuelen, - state->blocksize, NULL); + half += be16_to_cpu(hdr1->usedbytes) + + be16_to_cpu(hdr2->usedbytes) + + xfs_attr_leaf_newentsize( + state->args->namelen, + state->args->valuelen, + state->blocksize, NULL); half /= 2; lastdelta = state->blocksize; entry = &leaf1->entries[0]; @@ -1190,7 +1260,7 @@ xfs_attr_leaf_figure_balance(xfs_da_state_t *state, /* * Wrap around into the second block if necessary. */ - if (count == INT_GET(hdr1->count, ARCH_CONVERT)) { + if (count == be16_to_cpu(hdr1->count)) { leaf1 = leaf2; entry = &leaf1->entries[0]; index = 0; @@ -1258,12 +1328,12 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action) */ blk = &state->path.blk[ state->path.active-1 ]; info = blk->bp->data; - ASSERT(INT_GET(info->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC); leaf = (xfs_attr_leafblock_t *)info; - count = INT_GET(leaf->hdr.count, ARCH_CONVERT); + count = be16_to_cpu(leaf->hdr.count); bytes = sizeof(xfs_attr_leaf_hdr_t) + count * sizeof(xfs_attr_leaf_entry_t) + - INT_GET(leaf->hdr.usedbytes, ARCH_CONVERT); + be16_to_cpu(leaf->hdr.usedbytes); if (bytes > (state->blocksize >> 1)) { *action = 0; /* blk over 50%, don't try to join */ return(0); @@ -1272,7 +1342,7 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action) /* * Check for the degenerate case of the block being empty. * If the block is empty, we'll simply delete it, no need to - * coalesce it with a sibling block. We choose (aribtrarily) + * coalesce it with a sibling block. We choose (arbitrarily) * to merge with the forward block unless it is NULL. */ if (count == 0) { @@ -1280,7 +1350,7 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action) * Make altpath point to the block we want to keep and * path point to the block we want to drop (this one). */ - forward = info->forw; + forward = (info->forw != 0); memcpy(&state->altpath, &state->path, sizeof(state->path)); error = xfs_da_path_shift(state, &state->altpath, forward, 0, &retval); @@ -1302,13 +1372,12 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action) * to shrink an attribute list over time. */ /* start with smaller blk num */ - forward = (INT_GET(info->forw, ARCH_CONVERT) - < INT_GET(info->back, ARCH_CONVERT)); + forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back)); for (i = 0; i < 2; forward = !forward, i++) { if (forward) - blkno = INT_GET(info->forw, ARCH_CONVERT); + blkno = be32_to_cpu(info->forw); else - blkno = INT_GET(info->back, ARCH_CONVERT); + blkno = be32_to_cpu(info->back); if (blkno == 0) continue; error = xfs_da_read_buf(state->args->trans, state->args->dp, @@ -1318,14 +1387,13 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action) ASSERT(bp != NULL); leaf = (xfs_attr_leafblock_t *)info; - count = INT_GET(leaf->hdr.count, ARCH_CONVERT); + count = be16_to_cpu(leaf->hdr.count); bytes = state->blocksize - (state->blocksize>>2); - bytes -= INT_GET(leaf->hdr.usedbytes, ARCH_CONVERT); + bytes -= be16_to_cpu(leaf->hdr.usedbytes); leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); - count += INT_GET(leaf->hdr.count, ARCH_CONVERT); - bytes -= INT_GET(leaf->hdr.usedbytes, ARCH_CONVERT); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); + count += be16_to_cpu(leaf->hdr.count); + bytes -= be16_to_cpu(leaf->hdr.usedbytes); bytes -= count * sizeof(xfs_attr_leaf_entry_t); bytes -= sizeof(xfs_attr_leaf_hdr_t); xfs_da_brelse(state->args->trans, bp); @@ -1377,21 +1445,18 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) xfs_mount_t *mp; leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); hdr = &leaf->hdr; mp = args->trans->t_mountp; - ASSERT((INT_GET(hdr->count, ARCH_CONVERT) > 0) - && (INT_GET(hdr->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8))); + ASSERT((be16_to_cpu(hdr->count) > 0) + && (be16_to_cpu(hdr->count) < (XFS_LBSIZE(mp)/8))); ASSERT((args->index >= 0) - && (args->index < INT_GET(hdr->count, ARCH_CONVERT))); - ASSERT(INT_GET(hdr->firstused, ARCH_CONVERT) - >= ((INT_GET(hdr->count, ARCH_CONVERT) - * sizeof(*entry))+sizeof(*hdr))); + && (args->index < be16_to_cpu(hdr->count))); + ASSERT(be16_to_cpu(hdr->firstused) >= + ((be16_to_cpu(hdr->count) * sizeof(*entry)) + sizeof(*hdr))); entry = &leaf->entries[args->index]; - ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) - >= INT_GET(hdr->firstused, ARCH_CONVERT)); - ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) < XFS_LBSIZE(mp)); + ASSERT(be16_to_cpu(entry->nameidx) >= be16_to_cpu(hdr->firstused)); + ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); /* * Scan through free region table: @@ -1399,33 +1464,30 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) * find smallest free region in case we need to replace it, * adjust any map that borders the entry table, */ - tablesize = INT_GET(hdr->count, ARCH_CONVERT) - * sizeof(xfs_attr_leaf_entry_t) + tablesize = be16_to_cpu(hdr->count) * sizeof(xfs_attr_leaf_entry_t) + sizeof(xfs_attr_leaf_hdr_t); map = &hdr->freemap[0]; - tmp = INT_GET(map->size, ARCH_CONVERT); + tmp = be16_to_cpu(map->size); before = after = -1; smallest = XFS_ATTR_LEAF_MAPSIZE - 1; entsize = xfs_attr_leaf_entsize(leaf, args->index); for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) { - ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp)); - ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp)); - if (INT_GET(map->base, ARCH_CONVERT) == tablesize) { - INT_MOD(map->base, ARCH_CONVERT, - -sizeof(xfs_attr_leaf_entry_t)); - INT_MOD(map->size, ARCH_CONVERT, - sizeof(xfs_attr_leaf_entry_t)); + ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp)); + ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); + if (be16_to_cpu(map->base) == tablesize) { + be16_add_cpu(&map->base, + -((int)sizeof(xfs_attr_leaf_entry_t))); + be16_add_cpu(&map->size, sizeof(xfs_attr_leaf_entry_t)); } - if ((INT_GET(map->base, ARCH_CONVERT) - + INT_GET(map->size, ARCH_CONVERT)) - == INT_GET(entry->nameidx, ARCH_CONVERT)) { + if ((be16_to_cpu(map->base) + be16_to_cpu(map->size)) + == be16_to_cpu(entry->nameidx)) { before = i; - } else if (INT_GET(map->base, ARCH_CONVERT) - == (INT_GET(entry->nameidx, ARCH_CONVERT) + entsize)) { + } else if (be16_to_cpu(map->base) + == (be16_to_cpu(entry->nameidx) + entsize)) { after = i; - } else if (INT_GET(map->size, ARCH_CONVERT) < tmp) { - tmp = INT_GET(map->size, ARCH_CONVERT); + } else if (be16_to_cpu(map->size) < tmp) { + tmp = be16_to_cpu(map->size); smallest = i; } } @@ -1437,38 +1499,35 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) if ((before >= 0) || (after >= 0)) { if ((before >= 0) && (after >= 0)) { map = &hdr->freemap[before]; - INT_MOD(map->size, ARCH_CONVERT, entsize); - INT_MOD(map->size, ARCH_CONVERT, - INT_GET(hdr->freemap[after].size, - ARCH_CONVERT)); + be16_add_cpu(&map->size, entsize); + be16_add_cpu(&map->size, + be16_to_cpu(hdr->freemap[after].size)); hdr->freemap[after].base = 0; hdr->freemap[after].size = 0; } else if (before >= 0) { map = &hdr->freemap[before]; - INT_MOD(map->size, ARCH_CONVERT, entsize); + be16_add_cpu(&map->size, entsize); } else { map = &hdr->freemap[after]; /* both on-disk, don't endian flip twice */ map->base = entry->nameidx; - INT_MOD(map->size, ARCH_CONVERT, entsize); + be16_add_cpu(&map->size, entsize); } } else { /* * Replace smallest region (if it is smaller than free'd entry) */ map = &hdr->freemap[smallest]; - if (INT_GET(map->size, ARCH_CONVERT) < entsize) { - INT_SET(map->base, ARCH_CONVERT, - INT_GET(entry->nameidx, ARCH_CONVERT)); - INT_SET(map->size, ARCH_CONVERT, entsize); + if (be16_to_cpu(map->size) < entsize) { + map->base = cpu_to_be16(be16_to_cpu(entry->nameidx)); + map->size = cpu_to_be16(entsize); } } /* * Did we remove the first entry? */ - if (INT_GET(entry->nameidx, ARCH_CONVERT) - == INT_GET(hdr->firstused, ARCH_CONVERT)) + if (be16_to_cpu(entry->nameidx) == be16_to_cpu(hdr->firstused)) smallest = 1; else smallest = 0; @@ -1477,18 +1536,18 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) * Compress the remaining entries and zero out the removed stuff. */ memset(XFS_ATTR_LEAF_NAME(leaf, args->index), 0, entsize); - INT_MOD(hdr->usedbytes, ARCH_CONVERT, -entsize); + be16_add_cpu(&hdr->usedbytes, -entsize); xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, XFS_ATTR_LEAF_NAME(leaf, args->index), entsize)); - tmp = (INT_GET(hdr->count, ARCH_CONVERT) - args->index) + tmp = (be16_to_cpu(hdr->count) - args->index) * sizeof(xfs_attr_leaf_entry_t); memmove((char *)entry, (char *)(entry+1), tmp); - INT_MOD(hdr->count, ARCH_CONVERT, -1); + be16_add_cpu(&hdr->count, -1); xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); - entry = &leaf->entries[INT_GET(hdr->count, ARCH_CONVERT)]; + entry = &leaf->entries[be16_to_cpu(hdr->count)]; memset((char *)entry, 0, sizeof(xfs_attr_leaf_entry_t)); /* @@ -1500,18 +1559,17 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) if (smallest) { tmp = XFS_LBSIZE(mp); entry = &leaf->entries[0]; - for (i = INT_GET(hdr->count, ARCH_CONVERT)-1; - i >= 0; entry++, i--) { - ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) - >= INT_GET(hdr->firstused, ARCH_CONVERT)); - ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) - < XFS_LBSIZE(mp)); - if (INT_GET(entry->nameidx, ARCH_CONVERT) < tmp) - tmp = INT_GET(entry->nameidx, ARCH_CONVERT); + for (i = be16_to_cpu(hdr->count)-1; i >= 0; entry++, i--) { + ASSERT(be16_to_cpu(entry->nameidx) >= + be16_to_cpu(hdr->firstused)); + ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); + + if (be16_to_cpu(entry->nameidx) < tmp) + tmp = be16_to_cpu(entry->nameidx); } - INT_SET(hdr->firstused, ARCH_CONVERT, tmp); + hdr->firstused = cpu_to_be16(tmp); if (!hdr->firstused) { - INT_SET(hdr->firstused, ARCH_CONVERT, + hdr->firstused = cpu_to_be16( tmp - XFS_ATTR_LEAF_NAME_ALIGN); } } else { @@ -1525,9 +1583,8 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) * "join" the leaf with a sibling if so. */ tmp = sizeof(xfs_attr_leaf_hdr_t); - tmp += INT_GET(leaf->hdr.count, ARCH_CONVERT) - * sizeof(xfs_attr_leaf_entry_t); - tmp += INT_GET(leaf->hdr.usedbytes, ARCH_CONVERT); + tmp += be16_to_cpu(leaf->hdr.count) * sizeof(xfs_attr_leaf_entry_t); + tmp += be16_to_cpu(leaf->hdr.usedbytes); return(tmp < mp->m_attr_magicpct); /* leaf is < 37% full */ } @@ -1551,20 +1608,16 @@ xfs_attr_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, ASSERT(save_blk->magic == XFS_ATTR_LEAF_MAGIC); drop_leaf = drop_blk->bp->data; save_leaf = save_blk->bp->data; - ASSERT(INT_GET(drop_leaf->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); - ASSERT(INT_GET(save_leaf->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); drop_hdr = &drop_leaf->hdr; save_hdr = &save_leaf->hdr; /* * Save last hashval from dying block for later Btree fixup. */ - drop_blk->hashval = - INT_GET(drop_leaf->entries[INT_GET(drop_leaf->hdr.count, - ARCH_CONVERT)-1].hashval, - ARCH_CONVERT); + drop_blk->hashval = be32_to_cpu( + drop_leaf->entries[be16_to_cpu(drop_leaf->hdr.count)-1].hashval); /* * Check if we need a temp buffer, or can we do it in place. @@ -1578,12 +1631,11 @@ xfs_attr_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, */ if (xfs_attr_leaf_order(save_blk->bp, drop_blk->bp)) { xfs_attr_leaf_moveents(drop_leaf, 0, save_leaf, 0, - (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp); + be16_to_cpu(drop_hdr->count), mp); } else { xfs_attr_leaf_moveents(drop_leaf, 0, save_leaf, - INT_GET(save_hdr->count, ARCH_CONVERT), - (int)INT_GET(drop_hdr->count, ARCH_CONVERT), - mp); + be16_to_cpu(save_hdr->count), + be16_to_cpu(drop_hdr->count), mp); } } else { /* @@ -1597,31 +1649,27 @@ xfs_attr_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, tmp_hdr = &tmp_leaf->hdr; tmp_hdr->info = save_hdr->info; /* struct copy */ tmp_hdr->count = 0; - INT_SET(tmp_hdr->firstused, ARCH_CONVERT, state->blocksize); + tmp_hdr->firstused = cpu_to_be16(state->blocksize); if (!tmp_hdr->firstused) { - INT_SET(tmp_hdr->firstused, ARCH_CONVERT, + tmp_hdr->firstused = cpu_to_be16( state->blocksize - XFS_ATTR_LEAF_NAME_ALIGN); } tmp_hdr->usedbytes = 0; if (xfs_attr_leaf_order(save_blk->bp, drop_blk->bp)) { xfs_attr_leaf_moveents(drop_leaf, 0, tmp_leaf, 0, - (int)INT_GET(drop_hdr->count, ARCH_CONVERT), - mp); + be16_to_cpu(drop_hdr->count), mp); xfs_attr_leaf_moveents(save_leaf, 0, tmp_leaf, - INT_GET(tmp_leaf->hdr.count, ARCH_CONVERT), - (int)INT_GET(save_hdr->count, ARCH_CONVERT), - mp); + be16_to_cpu(tmp_leaf->hdr.count), + be16_to_cpu(save_hdr->count), mp); } else { xfs_attr_leaf_moveents(save_leaf, 0, tmp_leaf, 0, - (int)INT_GET(save_hdr->count, ARCH_CONVERT), - mp); + be16_to_cpu(save_hdr->count), mp); xfs_attr_leaf_moveents(drop_leaf, 0, tmp_leaf, - INT_GET(tmp_leaf->hdr.count, ARCH_CONVERT), - (int)INT_GET(drop_hdr->count, ARCH_CONVERT), - mp); + be16_to_cpu(tmp_leaf->hdr.count), + be16_to_cpu(drop_hdr->count), mp); } memcpy((char *)save_leaf, (char *)tmp_leaf, state->blocksize); - kmem_free(tmpbuffer, state->blocksize); + kmem_free(tmpbuffer); } xfs_da_log_buf(state->args->trans, save_blk->bp, 0, @@ -1630,10 +1678,8 @@ xfs_attr_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, /* * Copy out last hashval in each block for B-tree code. */ - save_blk->hashval = - INT_GET(save_leaf->entries[INT_GET(save_leaf->hdr.count, - ARCH_CONVERT)-1].hashval, - ARCH_CONVERT); + save_blk->hashval = be32_to_cpu( + save_leaf->entries[be16_to_cpu(save_leaf->hdr.count)-1].hashval); } /*======================================================================== @@ -1664,48 +1710,45 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) xfs_dahash_t hashval; leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); - ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.count) < (XFS_LBSIZE(args->dp->i_mount)/8)); /* * Binary search. (note: small blocks will skip this loop) */ hashval = args->hashval; - probe = span = INT_GET(leaf->hdr.count, ARCH_CONVERT) / 2; + probe = span = be16_to_cpu(leaf->hdr.count) / 2; for (entry = &leaf->entries[probe]; span > 4; entry = &leaf->entries[probe]) { span /= 2; - if (INT_GET(entry->hashval, ARCH_CONVERT) < hashval) + if (be32_to_cpu(entry->hashval) < hashval) probe += span; - else if (INT_GET(entry->hashval, ARCH_CONVERT) > hashval) + else if (be32_to_cpu(entry->hashval) > hashval) probe -= span; else break; } - ASSERT((probe >= 0) && + ASSERT((probe >= 0) && (!leaf->hdr.count - || (probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)))); - ASSERT((span <= 4) || (INT_GET(entry->hashval, ARCH_CONVERT) - == hashval)); + || (probe < be16_to_cpu(leaf->hdr.count)))); + ASSERT((span <= 4) || (be32_to_cpu(entry->hashval) == hashval)); /* * Since we may have duplicate hashval's, find the first matching * hashval in the leaf. */ - while ((probe > 0) && (INT_GET(entry->hashval, ARCH_CONVERT) - >= hashval)) { + while ((probe > 0) && (be32_to_cpu(entry->hashval) >= hashval)) { entry--; probe--; } - while ((probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)) - && (INT_GET(entry->hashval, ARCH_CONVERT) < hashval)) { + while ((probe < be16_to_cpu(leaf->hdr.count)) && + (be32_to_cpu(entry->hashval) < hashval)) { entry++; probe++; } - if ((probe == INT_GET(leaf->hdr.count, ARCH_CONVERT)) - || (INT_GET(entry->hashval, ARCH_CONVERT) != hashval)) { + if ((probe == be16_to_cpu(leaf->hdr.count)) || + (be32_to_cpu(entry->hashval) != hashval)) { args->index = probe; return(XFS_ERROR(ENOATTR)); } @@ -1713,8 +1756,8 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) /* * Duplicate keys may be present, so search all of them for a match. */ - for ( ; (probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)) - && (INT_GET(entry->hashval, ARCH_CONVERT) == hashval); + for ( ; (probe < be16_to_cpu(leaf->hdr.count)) && + (be32_to_cpu(entry->hashval) == hashval); entry++, probe++) { /* * GROT: Add code to remove incomplete entries. @@ -1731,14 +1774,9 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, probe); if (name_loc->namelen != args->namelen) continue; - if (memcmp(args->name, (char *)name_loc->nameval, - args->namelen) != 0) + if (memcmp(args->name, (char *)name_loc->nameval, args->namelen) != 0) continue; - if (((args->flags & ATTR_SECURE) != 0) != - ((entry->flags & XFS_ATTR_SECURE) != 0)) - continue; - if (((args->flags & ATTR_ROOT) != 0) != - ((entry->flags & XFS_ATTR_ROOT) != 0)) + if (!xfs_attr_namesp_match(args->flags, entry->flags)) continue; args->index = probe; return(XFS_ERROR(EEXIST)); @@ -1749,18 +1787,12 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) if (memcmp(args->name, (char *)name_rmt->name, args->namelen) != 0) continue; - if (((args->flags & ATTR_SECURE) != 0) != - ((entry->flags & XFS_ATTR_SECURE) != 0)) - continue; - if (((args->flags & ATTR_ROOT) != 0) != - ((entry->flags & XFS_ATTR_ROOT) != 0)) + if (!xfs_attr_namesp_match(args->flags, entry->flags)) continue; args->index = probe; - args->rmtblkno - = INT_GET(name_rmt->valueblk, ARCH_CONVERT); + args->rmtblkno = be32_to_cpu(name_rmt->valueblk); args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, - INT_GET(name_rmt->valuelen, - ARCH_CONVERT)); + be32_to_cpu(name_rmt->valuelen)); return(XFS_ERROR(EEXIST)); } } @@ -1768,6 +1800,60 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) return(XFS_ERROR(ENOATTR)); } +/* + * Get the value associated with an attribute name from a leaf attribute + * list structure. + */ +int +xfs_attr_leaf_getvalue(xfs_dabuf_t *bp, xfs_da_args_t *args) +{ + int valuelen; + xfs_attr_leafblock_t *leaf; + xfs_attr_leaf_entry_t *entry; + xfs_attr_leaf_name_local_t *name_loc; + xfs_attr_leaf_name_remote_t *name_rmt; + + leaf = bp->data; + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.count) + < (XFS_LBSIZE(args->dp->i_mount)/8)); + ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); + + entry = &leaf->entries[args->index]; + if (entry->flags & XFS_ATTR_LOCAL) { + name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, args->index); + ASSERT(name_loc->namelen == args->namelen); + ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0); + valuelen = be16_to_cpu(name_loc->valuelen); + if (args->flags & ATTR_KERNOVAL) { + args->valuelen = valuelen; + return(0); + } + if (args->valuelen < valuelen) { + args->valuelen = valuelen; + return(XFS_ERROR(ERANGE)); + } + args->valuelen = valuelen; + memcpy(args->value, &name_loc->nameval[args->namelen], valuelen); + } else { + name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, args->index); + ASSERT(name_rmt->namelen == args->namelen); + ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0); + valuelen = be32_to_cpu(name_rmt->valuelen); + args->rmtblkno = be32_to_cpu(name_rmt->valueblk); + args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, valuelen); + if (args->flags & ATTR_KERNOVAL) { + args->valuelen = valuelen; + return(0); + } + if (args->valuelen < valuelen) { + args->valuelen = valuelen; + return(XFS_ERROR(ERANGE)); + } + args->valuelen = valuelen; + } + return(0); +} /*======================================================================== * Utility routines. @@ -1796,32 +1882,29 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s, /* * Set up environment. */ - ASSERT(INT_GET(leaf_s->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); - ASSERT(INT_GET(leaf_d->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(leaf_s->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(leaf_d->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); hdr_s = &leaf_s->hdr; hdr_d = &leaf_d->hdr; - ASSERT((INT_GET(hdr_s->count, ARCH_CONVERT) > 0) - && (INT_GET(hdr_s->count, ARCH_CONVERT) - < (XFS_LBSIZE(mp)/8))); - ASSERT(INT_GET(hdr_s->firstused, ARCH_CONVERT) >= - ((INT_GET(hdr_s->count, ARCH_CONVERT) + ASSERT((be16_to_cpu(hdr_s->count) > 0) && + (be16_to_cpu(hdr_s->count) < (XFS_LBSIZE(mp)/8))); + ASSERT(be16_to_cpu(hdr_s->firstused) >= + ((be16_to_cpu(hdr_s->count) * sizeof(*entry_s))+sizeof(*hdr_s))); - ASSERT(INT_GET(hdr_d->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8)); - ASSERT(INT_GET(hdr_d->firstused, ARCH_CONVERT) >= - ((INT_GET(hdr_d->count, ARCH_CONVERT) + ASSERT(be16_to_cpu(hdr_d->count) < (XFS_LBSIZE(mp)/8)); + ASSERT(be16_to_cpu(hdr_d->firstused) >= + ((be16_to_cpu(hdr_d->count) * sizeof(*entry_d))+sizeof(*hdr_d))); - ASSERT(start_s < INT_GET(hdr_s->count, ARCH_CONVERT)); - ASSERT(start_d <= INT_GET(hdr_d->count, ARCH_CONVERT)); - ASSERT(count <= INT_GET(hdr_s->count, ARCH_CONVERT)); + ASSERT(start_s < be16_to_cpu(hdr_s->count)); + ASSERT(start_d <= be16_to_cpu(hdr_d->count)); + ASSERT(count <= be16_to_cpu(hdr_s->count)); /* * Move the entries in the destination leaf up to make a hole? */ - if (start_d < INT_GET(hdr_d->count, ARCH_CONVERT)) { - tmp = INT_GET(hdr_d->count, ARCH_CONVERT) - start_d; + if (start_d < be16_to_cpu(hdr_d->count)) { + tmp = be16_to_cpu(hdr_d->count) - start_d; tmp *= sizeof(xfs_attr_leaf_entry_t); entry_s = &leaf_d->entries[start_d]; entry_d = &leaf_d->entries[start_d + count]; @@ -1836,8 +1919,8 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s, entry_d = &leaf_d->entries[start_d]; desti = start_d; for (i = 0; i < count; entry_s++, entry_d++, desti++, i++) { - ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) - >= INT_GET(hdr_s->firstused, ARCH_CONVERT)); + ASSERT(be16_to_cpu(entry_s->nameidx) + >= be16_to_cpu(hdr_s->firstused)); tmp = xfs_attr_leaf_entsize(leaf_s, start_s + i); #ifdef GROT /* @@ -1847,35 +1930,35 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s, */ if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */ memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp); - INT_MOD(hdr_s->usedbytes, ARCH_CONVERT, -tmp); - INT_MOD(hdr_s->count, ARCH_CONVERT, -1); + be16_add_cpu(&hdr_s->usedbytes, -tmp); + be16_add_cpu(&hdr_s->count, -1); entry_d--; /* to compensate for ++ in loop hdr */ desti--; if ((start_s + i) < offset) result++; /* insertion index adjustment */ } else { #endif /* GROT */ - INT_MOD(hdr_d->firstused, ARCH_CONVERT, -tmp); + be16_add_cpu(&hdr_d->firstused, -tmp); /* both on-disk, don't endian flip twice */ entry_d->hashval = entry_s->hashval; /* both on-disk, don't endian flip twice */ entry_d->nameidx = hdr_d->firstused; entry_d->flags = entry_s->flags; - ASSERT(INT_GET(entry_d->nameidx, ARCH_CONVERT) + tmp + ASSERT(be16_to_cpu(entry_d->nameidx) + tmp <= XFS_LBSIZE(mp)); memmove(XFS_ATTR_LEAF_NAME(leaf_d, desti), XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), tmp); - ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) + tmp + ASSERT(be16_to_cpu(entry_s->nameidx) + tmp <= XFS_LBSIZE(mp)); memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp); - INT_MOD(hdr_s->usedbytes, ARCH_CONVERT, -tmp); - INT_MOD(hdr_d->usedbytes, ARCH_CONVERT, tmp); - INT_MOD(hdr_s->count, ARCH_CONVERT, -1); - INT_MOD(hdr_d->count, ARCH_CONVERT, 1); - tmp = INT_GET(hdr_d->count, ARCH_CONVERT) + be16_add_cpu(&hdr_s->usedbytes, -tmp); + be16_add_cpu(&hdr_d->usedbytes, tmp); + be16_add_cpu(&hdr_s->count, -1); + be16_add_cpu(&hdr_d->count, 1); + tmp = be16_to_cpu(hdr_d->count) * sizeof(xfs_attr_leaf_entry_t) + sizeof(xfs_attr_leaf_hdr_t); - ASSERT(INT_GET(hdr_d->firstused, ARCH_CONVERT) >= tmp); + ASSERT(be16_to_cpu(hdr_d->firstused) >= tmp); #ifdef GROT } #endif /* GROT */ @@ -1884,7 +1967,7 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s, /* * Zero out the entries we just copied. */ - if (start_s == INT_GET(hdr_s->count, ARCH_CONVERT)) { + if (start_s == be16_to_cpu(hdr_s->count)) { tmp = count * sizeof(xfs_attr_leaf_entry_t); entry_s = &leaf_s->entries[start_s]; ASSERT(((char *)entry_s + tmp) <= @@ -1895,15 +1978,14 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s, * Move the remaining entries down to fill the hole, * then zero the entries at the top. */ - tmp = INT_GET(hdr_s->count, ARCH_CONVERT) - count; + tmp = be16_to_cpu(hdr_s->count) - count; tmp *= sizeof(xfs_attr_leaf_entry_t); entry_s = &leaf_s->entries[start_s + count]; entry_d = &leaf_s->entries[start_s]; memmove((char *)entry_d, (char *)entry_s, tmp); tmp = count * sizeof(xfs_attr_leaf_entry_t); - entry_s = &leaf_s->entries[INT_GET(hdr_s->count, - ARCH_CONVERT)]; + entry_s = &leaf_s->entries[be16_to_cpu(hdr_s->count)]; ASSERT(((char *)entry_s + tmp) <= ((char *)leaf_s + XFS_LBSIZE(mp))); memset((char *)entry_s, 0, tmp); @@ -1912,14 +1994,11 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s, /* * Fill in the freemap information */ - INT_SET(hdr_d->freemap[0].base, ARCH_CONVERT, - sizeof(xfs_attr_leaf_hdr_t)); - INT_MOD(hdr_d->freemap[0].base, ARCH_CONVERT, - INT_GET(hdr_d->count, ARCH_CONVERT) - * sizeof(xfs_attr_leaf_entry_t)); - INT_SET(hdr_d->freemap[0].size, ARCH_CONVERT, - INT_GET(hdr_d->firstused, ARCH_CONVERT) - - INT_GET(hdr_d->freemap[0].base, ARCH_CONVERT)); + hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t)); + be16_add_cpu(&hdr_d->freemap[0].base, be16_to_cpu(hdr_d->count) * + sizeof(xfs_attr_leaf_entry_t)); + hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) + - be16_to_cpu(hdr_d->freemap[0].base)); hdr_d->freemap[1].base = 0; hdr_d->freemap[2].base = 0; hdr_d->freemap[1].size = 0; @@ -1938,18 +2017,16 @@ xfs_attr_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp) leaf1 = leaf1_bp->data; leaf2 = leaf2_bp->data; - ASSERT((INT_GET(leaf1->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC) && - (INT_GET(leaf2->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC)); - if ( (INT_GET(leaf1->hdr.count, ARCH_CONVERT) > 0) - && (INT_GET(leaf2->hdr.count, ARCH_CONVERT) > 0) - && ( (INT_GET(leaf2->entries[ 0 ].hashval, ARCH_CONVERT) < - INT_GET(leaf1->entries[ 0 ].hashval, ARCH_CONVERT)) - || (INT_GET(leaf2->entries[INT_GET(leaf2->hdr.count, - ARCH_CONVERT)-1].hashval, ARCH_CONVERT) < - INT_GET(leaf1->entries[INT_GET(leaf1->hdr.count, - ARCH_CONVERT)-1].hashval, ARCH_CONVERT))) ) { + ASSERT((be16_to_cpu(leaf1->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC) && + (be16_to_cpu(leaf2->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC)); + if ((be16_to_cpu(leaf1->hdr.count) > 0) && + (be16_to_cpu(leaf2->hdr.count) > 0) && + ((be32_to_cpu(leaf2->entries[0].hashval) < + be32_to_cpu(leaf1->entries[0].hashval)) || + (be32_to_cpu(leaf2->entries[ + be16_to_cpu(leaf2->hdr.count)-1].hashval) < + be32_to_cpu(leaf1->entries[ + be16_to_cpu(leaf1->hdr.count)-1].hashval)))) { return(1); } return(0); @@ -1964,34 +2041,30 @@ xfs_attr_leaf_lasthash(xfs_dabuf_t *bp, int *count) xfs_attr_leafblock_t *leaf; leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); if (count) - *count = INT_GET(leaf->hdr.count, ARCH_CONVERT); + *count = be16_to_cpu(leaf->hdr.count); if (!leaf->hdr.count) return(0); - return(INT_GET(leaf->entries[INT_GET(leaf->hdr.count, - ARCH_CONVERT)-1].hashval, ARCH_CONVERT)); + return be32_to_cpu(leaf->entries[be16_to_cpu(leaf->hdr.count)-1].hashval); } /* * Calculate the number of bytes used to store the indicated attribute * (whether local or remote only calculate bytes in this block). */ -int +STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index) { xfs_attr_leaf_name_local_t *name_loc; xfs_attr_leaf_name_remote_t *name_rmt; int size; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); if (leaf->entries[index].flags & XFS_ATTR_LOCAL) { name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, index); size = XFS_ATTR_LEAF_ENTSIZE_LOCAL(name_loc->namelen, - INT_GET(name_loc->valuelen, - ARCH_CONVERT)); + be16_to_cpu(name_loc->valuelen)); } else { name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, index); size = XFS_ATTR_LEAF_ENTSIZE_REMOTE(name_rmt->namelen); @@ -2056,9 +2129,8 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args) ASSERT(bp != NULL); leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); - ASSERT(args->index < INT_GET(leaf->hdr.count, ARCH_CONVERT)); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); + ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); ASSERT(args->index >= 0); entry = &leaf->entries[ args->index ]; ASSERT(entry->flags & XFS_ATTR_INCOMPLETE); @@ -2073,7 +2145,7 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args) namelen = name_rmt->namelen; name = (char *)name_rmt->name; } - ASSERT(INT_GET(entry->hashval, ARCH_CONVERT) == args->hashval); + ASSERT(be32_to_cpu(entry->hashval) == args->hashval); ASSERT(namelen == args->namelen); ASSERT(memcmp(name, args->name, namelen) == 0); #endif /* DEBUG */ @@ -2085,8 +2157,8 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args) if (args->rmtblkno) { ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0); name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, args->index); - INT_SET(name_rmt->valueblk, ARCH_CONVERT, args->rmtblkno); - INT_SET(name_rmt->valuelen, ARCH_CONVERT, args->valuelen); + name_rmt->valueblk = cpu_to_be32(args->rmtblkno); + name_rmt->valuelen = cpu_to_be32(args->valuelen); xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); } @@ -2095,9 +2167,7 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args) /* * Commit the flag value change and start the next trans in series. */ - error = xfs_attr_rolltrans(&args->trans, args->dp); - - return(error); + return xfs_trans_roll(&args->trans, args->dp); } /* @@ -2123,9 +2193,8 @@ xfs_attr_leaf_setflag(xfs_da_args_t *args) ASSERT(bp != NULL); leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); - ASSERT(args->index < INT_GET(leaf->hdr.count, ARCH_CONVERT)); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); + ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); ASSERT(args->index >= 0); entry = &leaf->entries[ args->index ]; @@ -2145,9 +2214,7 @@ xfs_attr_leaf_setflag(xfs_da_args_t *args) /* * Commit the flag value change and start the next trans in series. */ - error = xfs_attr_rolltrans(&args->trans, args->dp); - - return(error); + return xfs_trans_roll(&args->trans, args->dp); } /* @@ -2196,16 +2263,14 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args) } leaf1 = bp1->data; - ASSERT(INT_GET(leaf1->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); - ASSERT(args->index < INT_GET(leaf1->hdr.count, ARCH_CONVERT)); + ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); + ASSERT(args->index < be16_to_cpu(leaf1->hdr.count)); ASSERT(args->index >= 0); entry1 = &leaf1->entries[ args->index ]; leaf2 = bp2->data; - ASSERT(INT_GET(leaf2->hdr.info.magic, ARCH_CONVERT) - == XFS_ATTR_LEAF_MAGIC); - ASSERT(args->index2 < INT_GET(leaf2->hdr.count, ARCH_CONVERT)); + ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); + ASSERT(args->index2 < be16_to_cpu(leaf2->hdr.count)); ASSERT(args->index2 >= 0); entry2 = &leaf2->entries[ args->index2 ]; @@ -2228,7 +2293,7 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args) namelen2 = name_rmt->namelen; name2 = (char *)name_rmt->name; } - ASSERT(INT_GET(entry1->hashval, ARCH_CONVERT) == INT_GET(entry2->hashval, ARCH_CONVERT)); + ASSERT(be32_to_cpu(entry1->hashval) == be32_to_cpu(entry2->hashval)); ASSERT(namelen1 == namelen2); ASSERT(memcmp(name1, name2, namelen1) == 0); #endif /* DEBUG */ @@ -2242,8 +2307,8 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args) if (args->rmtblkno) { ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0); name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf1, args->index); - INT_SET(name_rmt->valueblk, ARCH_CONVERT, args->rmtblkno); - INT_SET(name_rmt->valuelen, ARCH_CONVERT, args->valuelen); + name_rmt->valueblk = cpu_to_be32(args->rmtblkno); + name_rmt->valuelen = cpu_to_be32(args->valuelen); xfs_da_log_buf(args->trans, bp1, XFS_DA_LOGRANGE(leaf1, name_rmt, sizeof(*name_rmt))); } @@ -2265,128 +2330,7 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args) /* * Commit the flag value change and start the next trans in series. */ - error = xfs_attr_rolltrans(&args->trans, args->dp); + error = xfs_trans_roll(&args->trans, args->dp); return(error); } - -#if 0 -/* - * Look at all the extents for this logical region, - * invalidate any buffers that are incore/in transactions. - */ -STATIC int -xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp, - xfs_dablk_t blkno, int blkcnt) -{ - xfs_bmbt_irec_t map; - xfs_dablk_t tblkno; - int tblkcnt, dblkcnt, nmap, error; - xfs_daddr_t dblkno; - xfs_buf_t *bp; - - /* - * Roll through the "value", invalidating the attribute value's - * blocks. - */ - tblkno = blkno; - tblkcnt = blkcnt; - while (tblkcnt > 0) { - /* - * Try to remember where we decided to put the value. - */ - nmap = 1; - error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt, - XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, - NULL, 0, &map, &nmap, NULL); - if (error) { - return(error); - } - ASSERT(nmap == 1); - ASSERT(map.br_startblock != DELAYSTARTBLOCK); - - /* - * If it's a hole, these are already unmapped - * so there's nothing to invalidate. - */ - if (map.br_startblock != HOLESTARTBLOCK) { - - dblkno = XFS_FSB_TO_DADDR(dp->i_mount, - map.br_startblock); - dblkcnt = XFS_FSB_TO_BB(dp->i_mount, - map.br_blockcount); - bp = xfs_trans_get_buf(*trans, - dp->i_mount->m_ddev_targp, - dblkno, dblkcnt, XFS_BUF_LOCK); - xfs_trans_binval(*trans, bp); - /* - * Roll to next transaction. - */ - if ((error = xfs_attr_rolltrans(trans, dp))) - return (error); - } - - tblkno += map.br_blockcount; - tblkcnt -= map.br_blockcount; - } - - return(0); -} -#endif - - -/* - * Roll from one trans in the sequence of PERMANENT transactions to the next. - */ -int -xfs_attr_rolltrans(xfs_trans_t **transp, xfs_inode_t *dp) -{ - xfs_trans_t *trans; - unsigned int logres, count; - int error; - - /* - * Ensure that the inode is always logged. - */ - trans = *transp; - xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE); - - /* - * Copy the critical parameters from one trans to the next. - */ - logres = trans->t_log_res; - count = trans->t_log_count; - *transp = xfs_trans_dup(trans); - - /* - * Commit the current transaction. - * If this commit failed, then it'd just unlock those items that - * are not marked ihold. That also means that a filesystem shutdown - * is in progress. The caller takes the responsibility to cancel - * the duplicate transaction that gets returned. - */ - if ((error = xfs_trans_commit(trans, 0, NULL))) - return (error); - - trans = *transp; - - /* - * Reserve space in the log for th next transaction. - * This also pushes items in the "AIL", the list of logged items, - * out to disk if they are taking up space at the tail of the log - * that we want to use. This requires that either nothing be locked - * across this call, or that anything that is locked be logged in - * the prior and the next transactions. - */ - error = xfs_trans_reserve(trans, 0, logres, 0, - XFS_TRANS_PERM_LOG_RES, count); - /* - * Ensure that the inode is in the new transaction and locked. - */ - if (!error) { - xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL); - xfs_trans_ihold(trans, dp); - } - return (error); - -} diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index 3fcc1b60e..6d186222a 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -18,9 +18,318 @@ #include -extern xfs_zone_t *xfs_ifork_zone; -xfs_zone_t *xfs_bmap_free_item_zone; +#ifdef DEBUG +STATIC void +xfs_bmap_check_leaf_extents(xfs_btree_cur_t *cur, xfs_inode_t *ip, int whichfork); +#endif + +kmem_zone_t *xfs_bmap_free_item_zone; + +/* + * Prototypes for internal bmap routines. + */ + + +/* + * Called from xfs_bmap_add_attrfork to handle extents format files. + */ +STATIC int /* error */ +xfs_bmap_add_attrfork_extents( + xfs_trans_t *tp, /* transaction pointer */ + xfs_inode_t *ip, /* incore inode pointer */ + xfs_fsblock_t *firstblock, /* first block allocated */ + xfs_bmap_free_t *flist, /* blocks to free at commit */ + int *flags); /* inode logging flags */ + +/* + * Called from xfs_bmap_add_attrfork to handle local format files. + */ +STATIC int /* error */ +xfs_bmap_add_attrfork_local( + xfs_trans_t *tp, /* transaction pointer */ + xfs_inode_t *ip, /* incore inode pointer */ + xfs_fsblock_t *firstblock, /* first block allocated */ + xfs_bmap_free_t *flist, /* blocks to free at commit */ + int *flags); /* inode logging flags */ + +/* + * Called by xfs_bmapi to update file extent records and the btree + * after allocating space (or doing a delayed allocation). + */ +STATIC int /* error */ +xfs_bmap_add_extent( + xfs_inode_t *ip, /* incore inode pointer */ + xfs_extnum_t idx, /* extent number to update/insert */ + xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ + xfs_bmbt_irec_t *new, /* new data to add to file extents */ + xfs_fsblock_t *first, /* pointer to firstblock variable */ + xfs_bmap_free_t *flist, /* list of extents to be freed */ + int *logflagsp, /* inode logging flags */ + xfs_extdelta_t *delta, /* Change made to incore extents */ + int whichfork, /* data or attr fork */ + int rsvd); /* OK to allocate reserved blocks */ + +/* + * Called by xfs_bmap_add_extent to handle cases converting a delayed + * allocation to a real allocation. + */ +STATIC int /* error */ +xfs_bmap_add_extent_delay_real( + xfs_inode_t *ip, /* incore inode pointer */ + xfs_extnum_t idx, /* extent number to update/insert */ + xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ + xfs_bmbt_irec_t *new, /* new data to add to file extents */ + xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ + xfs_fsblock_t *first, /* pointer to firstblock variable */ + xfs_bmap_free_t *flist, /* list of extents to be freed */ + int *logflagsp, /* inode logging flags */ + xfs_extdelta_t *delta, /* Change made to incore extents */ + int rsvd); /* OK to allocate reserved blocks */ + +/* + * Called by xfs_bmap_add_extent to handle cases converting a hole + * to a delayed allocation. + */ +STATIC int /* error */ +xfs_bmap_add_extent_hole_delay( + xfs_inode_t *ip, /* incore inode pointer */ + xfs_extnum_t idx, /* extent number to update/insert */ + xfs_bmbt_irec_t *new, /* new data to add to file extents */ + int *logflagsp,/* inode logging flags */ + xfs_extdelta_t *delta, /* Change made to incore extents */ + int rsvd); /* OK to allocate reserved blocks */ + +/* + * Called by xfs_bmap_add_extent to handle cases converting a hole + * to a real allocation. + */ +STATIC int /* error */ +xfs_bmap_add_extent_hole_real( + xfs_inode_t *ip, /* incore inode pointer */ + xfs_extnum_t idx, /* extent number to update/insert */ + xfs_btree_cur_t *cur, /* if null, not a btree */ + xfs_bmbt_irec_t *new, /* new data to add to file extents */ + int *logflagsp, /* inode logging flags */ + xfs_extdelta_t *delta, /* Change made to incore extents */ + int whichfork); /* data or attr fork */ + +/* + * Called by xfs_bmap_add_extent to handle cases converting an unwritten + * allocation to a real allocation or vice versa. + */ +STATIC int /* error */ +xfs_bmap_add_extent_unwritten_real( + xfs_inode_t *ip, /* incore inode pointer */ + xfs_extnum_t idx, /* extent number to update/insert */ + xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ + xfs_bmbt_irec_t *new, /* new data to add to file extents */ + int *logflagsp, /* inode logging flags */ + xfs_extdelta_t *delta); /* Change made to incore extents */ + +/* + * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. + * It figures out where to ask the underlying allocator to put the new extent. + */ +STATIC int /* error */ +xfs_bmap_alloc( + xfs_bmalloca_t *ap); /* bmap alloc argument struct */ +/* + * Transform a btree format file with only one leaf node, where the + * extents list will fit in the inode, into an extents format file. + * Since the file extents are already in-core, all we have to do is + * give up the space for the btree root and pitch the leaf block. + */ +STATIC int /* error */ +xfs_bmap_btree_to_extents( + xfs_trans_t *tp, /* transaction pointer */ + xfs_inode_t *ip, /* incore inode pointer */ + xfs_btree_cur_t *cur, /* btree cursor */ + int *logflagsp, /* inode logging flags */ + int whichfork); /* data or attr fork */ + +/* + * Called by xfs_bmapi to update file extent records and the btree + * after removing space (or undoing a delayed allocation). + */ +STATIC int /* error */ +xfs_bmap_del_extent( + xfs_inode_t *ip, /* incore inode pointer */ + xfs_trans_t *tp, /* current trans pointer */ + xfs_extnum_t idx, /* extent number to update/insert */ + xfs_bmap_free_t *flist, /* list of extents to be freed */ + xfs_btree_cur_t *cur, /* if null, not a btree */ + xfs_bmbt_irec_t *new, /* new data to add to file extents */ + int *logflagsp,/* inode logging flags */ + xfs_extdelta_t *delta, /* Change made to incore extents */ + int whichfork, /* data or attr fork */ + int rsvd); /* OK to allocate reserved blocks */ + +/* + * Remove the entry "free" from the free item list. Prev points to the + * previous entry, unless "free" is the head of the list. + * + * Note: this requires user-space public scope for libxfs_iread + */ +void +xfs_bmap_del_free( + xfs_bmap_free_t *flist, /* free item list header */ + xfs_bmap_free_item_t *prev, /* previous item on list, if any */ + xfs_bmap_free_item_t *free); /* list item to be freed */ + +/* + * Convert an extents-format file into a btree-format file. + * The new file will have a root block (in the inode) and a single child block. + */ +STATIC int /* error */ +xfs_bmap_extents_to_btree( + xfs_trans_t *tp, /* transaction pointer */ + xfs_inode_t *ip, /* incore inode pointer */ + xfs_fsblock_t *firstblock, /* first-block-allocated */ + xfs_bmap_free_t *flist, /* blocks freed in xaction */ + xfs_btree_cur_t **curp, /* cursor returned to caller */ + int wasdel, /* converting a delayed alloc */ + int *logflagsp, /* inode logging flags */ + int whichfork); /* data or attr fork */ + +/* + * Convert a local file to an extents file. + * This code is sort of bogus, since the file data needs to get + * logged so it won't be lost. The bmap-level manipulations are ok, though. + */ +STATIC int /* error */ +xfs_bmap_local_to_extents( + xfs_trans_t *tp, /* transaction pointer */ + xfs_inode_t *ip, /* incore inode pointer */ + xfs_fsblock_t *firstblock, /* first block allocated in xaction */ + xfs_extlen_t total, /* total blocks needed by transaction */ + int *logflagsp, /* inode logging flags */ + int whichfork); /* data or attr fork */ + +/* + * Check the last inode extent to determine whether this allocation will result + * in blocks being allocated at the end of the file. When we allocate new data + * blocks at the end of the file which do not start at the previous data block, + * we will try to align the new blocks at stripe unit boundaries. + */ +STATIC int /* error */ +xfs_bmap_isaeof( + xfs_inode_t *ip, /* incore inode pointer */ + xfs_fileoff_t off, /* file offset in fsblocks */ + int whichfork, /* data or attribute fork */ + char *aeof); /* return value */ + +#ifdef XFS_BMAP_TRACE +/* + * Add bmap trace entry prior to a call to xfs_iext_remove. + */ +STATIC void +xfs_bmap_trace_delete( + const char *fname, /* function name */ + char *desc, /* operation description */ + xfs_inode_t *ip, /* incore inode pointer */ + xfs_extnum_t idx, /* index of entry(entries) deleted */ + xfs_extnum_t cnt, /* count of entries deleted, 1 or 2 */ + int whichfork); /* data or attr fork */ + +/* + * Add bmap trace entry prior to a call to xfs_iext_insert, or + * reading in the extents list from the disk (in the btree). + */ +STATIC void +xfs_bmap_trace_insert( + const char *fname, /* function name */ + char *desc, /* operation description */ + xfs_inode_t *ip, /* incore inode pointer */ + xfs_extnum_t idx, /* index of entry(entries) inserted */ + xfs_extnum_t cnt, /* count of entries inserted, 1 or 2 */ + xfs_bmbt_irec_t *r1, /* inserted record 1 */ + xfs_bmbt_irec_t *r2, /* inserted record 2 or null */ + int whichfork); /* data or attr fork */ + +/* + * Add bmap trace entry after updating an extent record in place. + */ +STATIC void +xfs_bmap_trace_post_update( + const char *fname, /* function name */ + char *desc, /* operation description */ + xfs_inode_t *ip, /* incore inode pointer */ + xfs_extnum_t idx, /* index of entry updated */ + int whichfork); /* data or attr fork */ + +/* + * Add bmap trace entry prior to updating an extent record in place. + */ +STATIC void +xfs_bmap_trace_pre_update( + const char *fname, /* function name */ + char *desc, /* operation description */ + xfs_inode_t *ip, /* incore inode pointer */ + xfs_extnum_t idx, /* index of entry to be updated */ + int whichfork); /* data or attr fork */ + +#define XFS_BMAP_TRACE_DELETE(d,ip,i,c,w) \ + xfs_bmap_trace_delete(__func__,d,ip,i,c,w) +#define XFS_BMAP_TRACE_INSERT(d,ip,i,c,r1,r2,w) \ + xfs_bmap_trace_insert(__func__,d,ip,i,c,r1,r2,w) +#define XFS_BMAP_TRACE_POST_UPDATE(d,ip,i,w) \ + xfs_bmap_trace_post_update(__func__,d,ip,i,w) +#define XFS_BMAP_TRACE_PRE_UPDATE(d,ip,i,w) \ + xfs_bmap_trace_pre_update(__func__,d,ip,i,w) +#else +#define XFS_BMAP_TRACE_DELETE(d,ip,i,c,w) +#define XFS_BMAP_TRACE_INSERT(d,ip,i,c,r1,r2,w) +#define XFS_BMAP_TRACE_POST_UPDATE(d,ip,i,w) +#define XFS_BMAP_TRACE_PRE_UPDATE(d,ip,i,w) +#endif /* XFS_BMAP_TRACE */ + +/* + * Compute the worst-case number of indirect blocks that will be used + * for ip's delayed extent of length "len". + */ +STATIC xfs_filblks_t +xfs_bmap_worst_indlen( + xfs_inode_t *ip, /* incore inode pointer */ + xfs_filblks_t len); /* delayed extent length */ + +#ifdef DEBUG +/* + * Perform various validation checks on the values being returned + * from xfs_bmapi(). + */ +STATIC void +xfs_bmap_validate_ret( + xfs_fileoff_t bno, + xfs_filblks_t len, + int flags, + xfs_bmbt_irec_t *mval, + int nmap, + int ret_nmap); +#else +#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) +#endif /* DEBUG */ + +#if defined(XFS_RW_TRACE) +STATIC void +xfs_bunmap_trace( + xfs_inode_t *ip, + xfs_fileoff_t bno, + xfs_filblks_t len, + int flags, + inst_t *ra); +#else +#define xfs_bunmap_trace(ip, bno, len, flags, ra) +#endif /* XFS_RW_TRACE */ + + +/* + * Bmap internal routines. + */ + +/* + * Called from xfs_bmap_add_attrfork to handle btree format files. + */ STATIC int /* error */ xfs_bmap_add_attrfork_btree( xfs_trans_t *tp, /* transaction pointer */ @@ -44,7 +353,8 @@ xfs_bmap_add_attrfork_btree( cur->bc_private.b.firstblock = *firstblock; if ((error = xfs_bmbt_lookup_ge(cur, 0, 0, 0, &stat))) goto error0; - ASSERT(stat == 1); /* must be at least one entry */ + /* must be at least one entry */ + XFS_WANT_CORRUPTED_GOTO(stat == 1, error0); if ((error = xfs_bmbt_newroot(cur, flags, &stat))) goto error0; if (stat == 0) { @@ -114,7 +424,7 @@ xfs_bmap_add_attrfork_local( dargs.total = mp->m_dirblkfsbs; dargs.whichfork = XFS_DATA_FORK; dargs.trans = tp; - error = XFS_DIR_SHORTFORM_TO_SINGLE(mp, &dargs); + error = xfs_dir2_sf_to_block(&dargs); } else error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags, XFS_DATA_FORK); @@ -122,7 +432,7 @@ xfs_bmap_add_attrfork_local( } /* - * Called by xfs_bmapi to update extent list structure and the btree + * Called by xfs_bmapi to update file extent records and the btree * after allocating space (or doing a delayed allocation). */ STATIC int /* error */ @@ -130,10 +440,11 @@ xfs_bmap_add_extent( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* extent number to update/insert */ xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ - xfs_bmbt_irec_t *new, /* new data to put in extent list */ + xfs_bmbt_irec_t *new, /* new data to add to file extents */ xfs_fsblock_t *first, /* pointer to firstblock variable */ xfs_bmap_free_t *flist, /* list of extents to be freed */ int *logflagsp, /* inode logging flags */ + xfs_extdelta_t *delta, /* Change made to incore extents */ int whichfork, /* data or attr fork */ int rsvd) /* OK to use reserved data blocks */ { @@ -141,9 +452,6 @@ xfs_bmap_add_extent( xfs_filblks_t da_new; /* new count del alloc blocks used */ xfs_filblks_t da_old; /* old count del alloc blocks used */ int error; /* error return value */ -#ifdef XFS_BMAP_TRACE - static char fname[] = "xfs_bmap_add_extent"; -#endif xfs_ifork_t *ifp; /* inode fork ptr */ int logflags; /* returned value */ xfs_extnum_t nextents; /* number of extents in file now */ @@ -161,9 +469,9 @@ xfs_bmap_add_extent( * already extents in the list. */ if (nextents == 0) { - xfs_bmap_trace_insert(fname, "insert empty", ip, 0, 1, new, - NULL, whichfork); - xfs_bmap_insert_exlist(ip, 0, 1, new, whichfork); + XFS_BMAP_TRACE_INSERT("insert empty", ip, 0, 1, new, NULL, + whichfork); + xfs_iext_insert(ifp, 0, 1, new); ASSERT(cur == NULL); ifp->if_lastex = 0; if (!ISNULLSTARTBLOCK(new->br_startblock)) { @@ -171,6 +479,15 @@ xfs_bmap_add_extent( logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); } else logflags = 0; + /* DELTA: single new extent */ + if (delta) { + if (delta->xed_startoff > new->br_startoff) + delta->xed_startoff = new->br_startoff; + if (delta->xed_blockcount < + new->br_startoff + new->br_blockcount) + delta->xed_blockcount = new->br_startoff + + new->br_blockcount; + } } /* * Any kind of new delayed allocation goes here. @@ -179,8 +496,8 @@ xfs_bmap_add_extent( if (cur) ASSERT((cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL) == 0); - if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new, - &logflags, rsvd))) + if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, new, + &logflags, delta, rsvd))) goto done; } /* @@ -191,7 +508,7 @@ xfs_bmap_add_extent( ASSERT((cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL) == 0); if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, - &logflags, whichfork))) + &logflags, delta, whichfork))) goto done; } else { xfs_bmbt_irec_t prev; /* old extent at offset idx */ @@ -199,7 +516,7 @@ xfs_bmap_add_extent( /* * Get the record referred to by idx. */ - xfs_bmbt_get_all(&ifp->if_u1.if_extents[idx], &prev); + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), &prev); /* * If it's a real allocation record, and the new allocation ends * after the start of the referred to record, then we're filling @@ -216,17 +533,17 @@ xfs_bmap_add_extent( XFS_BTCUR_BPRV_WASDEL); if ((error = xfs_bmap_add_extent_delay_real(ip, idx, &cur, new, &da_new, first, flist, - &logflags, rsvd))) + &logflags, delta, rsvd))) goto done; } else if (new->br_state == XFS_EXT_NORM) { ASSERT(new->br_state == XFS_EXT_NORM); if ((error = xfs_bmap_add_extent_unwritten_real( - ip, idx, &cur, new, &logflags))) + ip, idx, &cur, new, &logflags, delta))) goto done; } else { ASSERT(new->br_state == XFS_EXT_UNWRITTEN); if ((error = xfs_bmap_add_extent_unwritten_real( - ip, idx, &cur, new, &logflags))) + ip, idx, &cur, new, &logflags, delta))) goto done; } ASSERT(*curp == cur || *curp == NULL); @@ -239,7 +556,7 @@ xfs_bmap_add_extent( ASSERT((cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL) == 0); if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, - new, &logflags, whichfork))) + new, &logflags, delta, whichfork))) goto done; } } @@ -272,7 +589,7 @@ xfs_bmap_add_extent( ASSERT(nblks <= da_old); if (nblks < da_old) xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, - (int)(da_old - nblks), rsvd); + (int64_t)(da_old - nblks), rsvd); } /* * Clear out the allocated field, done with it now in any case. @@ -299,29 +616,27 @@ xfs_bmap_add_extent_delay_real( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* extent number to update/insert */ xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ - xfs_bmbt_irec_t *new, /* new data to put in extent list */ + xfs_bmbt_irec_t *new, /* new data to add to file extents */ xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ xfs_fsblock_t *first, /* pointer to firstblock variable */ xfs_bmap_free_t *flist, /* list of extents to be freed */ int *logflagsp, /* inode logging flags */ + xfs_extdelta_t *delta, /* Change made to incore extents */ int rsvd) /* OK to use reserved data block allocation */ { - xfs_bmbt_rec_t *base; /* base of extent entry list */ xfs_btree_cur_t *cur; /* btree cursor */ int diff; /* temp value */ - xfs_bmbt_rec_t *ep; /* extent entry for idx */ + xfs_bmbt_rec_host_t *ep; /* extent entry for idx */ int error; /* error return value */ -#ifdef XFS_BMAP_TRACE - static char fname[] = "xfs_bmap_add_extent_delay_real"; -#endif int i; /* temp state */ + xfs_ifork_t *ifp; /* inode fork pointer */ xfs_fileoff_t new_endoff; /* end offset of new entry */ xfs_bmbt_irec_t r[3]; /* neighbor extent entries */ /* left is 0, right is 1, prev is 2 */ int rval=0; /* return value (logging flags) */ int state = 0;/* state bits, accessed thru macros */ - xfs_filblks_t temp; /* value for dnew calculations */ - xfs_filblks_t temp2; /* value for dnew calculations */ + xfs_filblks_t temp=0; /* value for dnew calculations */ + xfs_filblks_t temp2=0;/* value for dnew calculations */ int tmp_rval; /* partial logging flags */ enum { /* bit number definitions for state */ LEFT_CONTIG, RIGHT_CONTIG, @@ -348,8 +663,8 @@ xfs_bmap_add_extent_delay_real( * Set up a bunch of variables to make the tests simpler. */ cur = *curp; - base = ip->i_df.if_u1.if_extents; - ep = &base[idx]; + ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); + ep = xfs_iext_get_ext(ifp, idx); xfs_bmbt_get_all(ep, &PREV); new_endoff = new->br_startoff + new->br_blockcount; ASSERT(PREV.br_startoff <= new->br_startoff); @@ -366,7 +681,7 @@ xfs_bmap_add_extent_delay_real( * Don't set contiguous if the combined extent would be too large. */ if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { - xfs_bmbt_get_all(ep - 1, &LEFT); + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT); STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(LEFT.br_startblock)); } STATE_SET(LEFT_CONTIG, @@ -383,7 +698,7 @@ xfs_bmap_add_extent_delay_real( if (STATE_SET_TEST(RIGHT_VALID, idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) { - xfs_bmbt_get_all(ep + 1, &RIGHT); + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT); STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(RIGHT.br_startblock)); } STATE_SET(RIGHT_CONTIG, @@ -408,16 +723,15 @@ xfs_bmap_add_extent_delay_real( * Filling in all of a previously delayed allocation extent. * The left and right neighbors are both contiguous with new. */ - xfs_bmap_trace_pre_update(fname, "LF|RF|LC|RC", ip, idx - 1, + XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|LC|RC", ip, idx - 1, XFS_DATA_FORK); - xfs_bmbt_set_blockcount(ep - 1, + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + PREV.br_blockcount + RIGHT.br_blockcount); - xfs_bmap_trace_post_update(fname, "LF|RF|LC|RC", ip, idx - 1, + XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC|RC", ip, idx - 1, XFS_DATA_FORK); - xfs_bmap_trace_delete(fname, "LF|RF|LC|RC", ip, idx, 2, - XFS_DATA_FORK); - xfs_bmap_delete_exlist(ip, idx, 2, XFS_DATA_FORK); + XFS_BMAP_TRACE_DELETE("LF|RF|LC|RC", ip, idx, 2, XFS_DATA_FORK); + xfs_iext_remove(ifp, idx, 2); ip->i_df.if_lastex = idx - 1; ip->i_d.di_nextents--; if (cur == NULL) @@ -428,13 +742,13 @@ xfs_bmap_add_extent_delay_real( RIGHT.br_startblock, RIGHT.br_blockcount, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_delete(cur, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_decrement(cur, 0, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, LEFT.br_startblock, LEFT.br_blockcount + @@ -443,6 +757,11 @@ xfs_bmap_add_extent_delay_real( goto done; } *dnew = 0; + /* DELTA: Three in-core extents are replaced by one. */ + temp = LEFT.br_startoff; + temp2 = LEFT.br_blockcount + + PREV.br_blockcount + + RIGHT.br_blockcount; break; case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): @@ -450,16 +769,15 @@ xfs_bmap_add_extent_delay_real( * Filling in all of a previously delayed allocation extent. * The left neighbor is contiguous, the right is not. */ - xfs_bmap_trace_pre_update(fname, "LF|RF|LC", ip, idx - 1, + XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|LC", ip, idx - 1, XFS_DATA_FORK); - xfs_bmbt_set_blockcount(ep - 1, + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + PREV.br_blockcount); - xfs_bmap_trace_post_update(fname, "LF|RF|LC", ip, idx - 1, + XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC", ip, idx - 1, XFS_DATA_FORK); ip->i_df.if_lastex = idx - 1; - xfs_bmap_trace_delete(fname, "LF|RF|LC", ip, idx, 1, - XFS_DATA_FORK); - xfs_bmap_delete_exlist(ip, idx, 1, XFS_DATA_FORK); + XFS_BMAP_TRACE_DELETE("LF|RF|LC", ip, idx, 1, XFS_DATA_FORK); + xfs_iext_remove(ifp, idx, 1); if (cur == NULL) rval = XFS_ILOG_DEXT; else { @@ -468,7 +786,7 @@ xfs_bmap_add_extent_delay_real( LEFT.br_startblock, LEFT.br_blockcount, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, LEFT.br_startblock, LEFT.br_blockcount + @@ -476,6 +794,10 @@ xfs_bmap_add_extent_delay_real( goto done; } *dnew = 0; + /* DELTA: Two in-core extents are replaced by one. */ + temp = LEFT.br_startoff; + temp2 = LEFT.br_blockcount + + PREV.br_blockcount; break; case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): @@ -483,17 +805,14 @@ xfs_bmap_add_extent_delay_real( * Filling in all of a previously delayed allocation extent. * The right neighbor is contiguous, the left is not. */ - xfs_bmap_trace_pre_update(fname, "LF|RF|RC", ip, idx, - XFS_DATA_FORK); + XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|RC", ip, idx, XFS_DATA_FORK); xfs_bmbt_set_startblock(ep, new->br_startblock); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount + RIGHT.br_blockcount); - xfs_bmap_trace_post_update(fname, "LF|RF|RC", ip, idx, - XFS_DATA_FORK); + XFS_BMAP_TRACE_POST_UPDATE("LF|RF|RC", ip, idx, XFS_DATA_FORK); ip->i_df.if_lastex = idx; - xfs_bmap_trace_delete(fname, "LF|RF|RC", ip, idx + 1, 1, - XFS_DATA_FORK); - xfs_bmap_delete_exlist(ip, idx + 1, 1, XFS_DATA_FORK); + XFS_BMAP_TRACE_DELETE("LF|RF|RC", ip, idx + 1, 1, XFS_DATA_FORK); + xfs_iext_remove(ifp, idx + 1, 1); if (cur == NULL) rval = XFS_ILOG_DEXT; else { @@ -502,7 +821,7 @@ xfs_bmap_add_extent_delay_real( RIGHT.br_startblock, RIGHT.br_blockcount, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, PREV.br_startoff, new->br_startblock, PREV.br_blockcount + @@ -510,6 +829,10 @@ xfs_bmap_add_extent_delay_real( goto done; } *dnew = 0; + /* DELTA: Two in-core extents are replaced by one. */ + temp = PREV.br_startoff; + temp2 = PREV.br_blockcount + + RIGHT.br_blockcount; break; case MASK2(LEFT_FILLING, RIGHT_FILLING): @@ -518,11 +841,9 @@ xfs_bmap_add_extent_delay_real( * Neither the left nor right neighbors are contiguous with * the new one. */ - xfs_bmap_trace_pre_update(fname, "LF|RF", ip, idx, - XFS_DATA_FORK); + XFS_BMAP_TRACE_PRE_UPDATE("LF|RF", ip, idx, XFS_DATA_FORK); xfs_bmbt_set_startblock(ep, new->br_startblock); - xfs_bmap_trace_post_update(fname, "LF|RF", ip, idx, - XFS_DATA_FORK); + XFS_BMAP_TRACE_POST_UPDATE("LF|RF", ip, idx, XFS_DATA_FORK); ip->i_df.if_lastex = idx; ip->i_d.di_nextents++; if (cur == NULL) @@ -533,13 +854,16 @@ xfs_bmap_add_extent_delay_real( new->br_startblock, new->br_blockcount, &i))) goto done; - ASSERT(i == 0); + XFS_WANT_CORRUPTED_GOTO(i == 0, done); cur->bc_rec.b.br_state = XFS_EXT_NORM; if ((error = xfs_bmbt_insert(cur, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); } *dnew = 0; + /* DELTA: The in-core extent described by new changed type. */ + temp = new->br_startoff; + temp2 = new->br_blockcount; break; case MASK2(LEFT_FILLING, LEFT_CONTIG): @@ -547,17 +871,14 @@ xfs_bmap_add_extent_delay_real( * Filling in the first part of a previous delayed allocation. * The left neighbor is contiguous. */ - xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx - 1, - XFS_DATA_FORK); - xfs_bmbt_set_blockcount(ep - 1, + XFS_BMAP_TRACE_PRE_UPDATE("LF|LC", ip, idx - 1, XFS_DATA_FORK); + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + new->br_blockcount); xfs_bmbt_set_startoff(ep, PREV.br_startoff + new->br_blockcount); - xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx - 1, - XFS_DATA_FORK); + XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx - 1, XFS_DATA_FORK); temp = PREV.br_blockcount - new->br_blockcount; - xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx, - XFS_DATA_FORK); + XFS_BMAP_TRACE_PRE_UPDATE("LF|LC", ip, idx, XFS_DATA_FORK); xfs_bmbt_set_blockcount(ep, temp); ip->i_df.if_lastex = idx - 1; if (cur == NULL) @@ -568,7 +889,7 @@ xfs_bmap_add_extent_delay_real( LEFT.br_startblock, LEFT.br_blockcount, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, LEFT.br_startblock, LEFT.br_blockcount + @@ -579,9 +900,12 @@ xfs_bmap_add_extent_delay_real( temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), STARTBLOCKVAL(PREV.br_startblock)); xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); - xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx, - XFS_DATA_FORK); + XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx, XFS_DATA_FORK); *dnew = temp; + /* DELTA: The boundary between two in-core extents moved. */ + temp = LEFT.br_startoff; + temp2 = LEFT.br_blockcount + + PREV.br_blockcount; break; case MASK(LEFT_FILLING): @@ -589,13 +913,13 @@ xfs_bmap_add_extent_delay_real( * Filling in the first part of a previous delayed allocation. * The left neighbor is not contiguous. */ - xfs_bmap_trace_pre_update(fname, "LF", ip, idx, XFS_DATA_FORK); + XFS_BMAP_TRACE_PRE_UPDATE("LF", ip, idx, XFS_DATA_FORK); xfs_bmbt_set_startoff(ep, new_endoff); temp = PREV.br_blockcount - new->br_blockcount; xfs_bmbt_set_blockcount(ep, temp); - xfs_bmap_trace_insert(fname, "LF", ip, idx, 1, new, NULL, + XFS_BMAP_TRACE_INSERT("LF", ip, idx, 1, new, NULL, XFS_DATA_FORK); - xfs_bmap_insert_exlist(ip, idx, 1, new, XFS_DATA_FORK); + xfs_iext_insert(ifp, idx, 1, new); ip->i_df.if_lastex = idx; ip->i_d.di_nextents++; if (cur == NULL) @@ -606,11 +930,11 @@ xfs_bmap_add_extent_delay_real( new->br_startblock, new->br_blockcount, &i))) goto done; - ASSERT(i == 0); + XFS_WANT_CORRUPTED_GOTO(i == 0, done); cur->bc_rec.b.br_state = XFS_EXT_NORM; if ((error = xfs_bmbt_insert(cur, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); } if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && ip->i_d.di_nextents > ip->i_df.if_ext_max) { @@ -624,12 +948,13 @@ xfs_bmap_add_extent_delay_real( temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), STARTBLOCKVAL(PREV.br_startblock) - (cur ? cur->bc_private.b.allocated : 0)); - base = ip->i_df.if_u1.if_extents; - ep = &base[idx + 1]; + ep = xfs_iext_get_ext(ifp, idx + 1); xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); - xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1, - XFS_DATA_FORK); + XFS_BMAP_TRACE_POST_UPDATE("LF", ip, idx + 1, XFS_DATA_FORK); *dnew = temp; + /* DELTA: One in-core extent is split in two. */ + temp = PREV.br_startoff; + temp2 = PREV.br_blockcount; break; case MASK2(RIGHT_FILLING, RIGHT_CONTIG): @@ -638,16 +963,14 @@ xfs_bmap_add_extent_delay_real( * The right neighbor is contiguous with the new allocation. */ temp = PREV.br_blockcount - new->br_blockcount; - xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx, - XFS_DATA_FORK); - xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx + 1, - XFS_DATA_FORK); + XFS_BMAP_TRACE_PRE_UPDATE("RF|RC", ip, idx, XFS_DATA_FORK); + XFS_BMAP_TRACE_PRE_UPDATE("RF|RC", ip, idx + 1, XFS_DATA_FORK); xfs_bmbt_set_blockcount(ep, temp); - xfs_bmbt_set_allf(ep + 1, new->br_startoff, new->br_startblock, + xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), + new->br_startoff, new->br_startblock, new->br_blockcount + RIGHT.br_blockcount, RIGHT.br_state); - xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx + 1, - XFS_DATA_FORK); + XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx + 1, XFS_DATA_FORK); ip->i_df.if_lastex = idx + 1; if (cur == NULL) rval = XFS_ILOG_DEXT; @@ -657,7 +980,7 @@ xfs_bmap_add_extent_delay_real( RIGHT.br_startblock, RIGHT.br_blockcount, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, new->br_startoff, new->br_startblock, new->br_blockcount + @@ -668,9 +991,12 @@ xfs_bmap_add_extent_delay_real( temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), STARTBLOCKVAL(PREV.br_startblock)); xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); - xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx, - XFS_DATA_FORK); + XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx, XFS_DATA_FORK); *dnew = temp; + /* DELTA: The boundary between two in-core extents moved. */ + temp = PREV.br_startoff; + temp2 = PREV.br_blockcount + + RIGHT.br_blockcount; break; case MASK(RIGHT_FILLING): @@ -679,11 +1005,11 @@ xfs_bmap_add_extent_delay_real( * The right neighbor is not contiguous. */ temp = PREV.br_blockcount - new->br_blockcount; - xfs_bmap_trace_pre_update(fname, "RF", ip, idx, XFS_DATA_FORK); + XFS_BMAP_TRACE_PRE_UPDATE("RF", ip, idx, XFS_DATA_FORK); xfs_bmbt_set_blockcount(ep, temp); - xfs_bmap_trace_insert(fname, "RF", ip, idx + 1, 1, - new, NULL, XFS_DATA_FORK); - xfs_bmap_insert_exlist(ip, idx + 1, 1, new, XFS_DATA_FORK); + XFS_BMAP_TRACE_INSERT("RF", ip, idx + 1, 1, new, NULL, + XFS_DATA_FORK); + xfs_iext_insert(ifp, idx + 1, 1, new); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents++; if (cur == NULL) @@ -694,11 +1020,11 @@ xfs_bmap_add_extent_delay_real( new->br_startblock, new->br_blockcount, &i))) goto done; - ASSERT(i == 0); + XFS_WANT_CORRUPTED_GOTO(i == 0, done); cur->bc_rec.b.br_state = XFS_EXT_NORM; if ((error = xfs_bmbt_insert(cur, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); } if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && ip->i_d.di_nextents > ip->i_df.if_ext_max) { @@ -712,11 +1038,13 @@ xfs_bmap_add_extent_delay_real( temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), STARTBLOCKVAL(PREV.br_startblock) - (cur ? cur->bc_private.b.allocated : 0)); - base = ip->i_df.if_u1.if_extents; - ep = &base[idx]; + ep = xfs_iext_get_ext(ifp, idx); xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); - xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK); + XFS_BMAP_TRACE_POST_UPDATE("RF", ip, idx, XFS_DATA_FORK); *dnew = temp; + /* DELTA: One in-core extent is split in two. */ + temp = PREV.br_startoff; + temp2 = PREV.br_blockcount; break; case 0: @@ -726,15 +1054,17 @@ xfs_bmap_add_extent_delay_real( * This case is avoided almost all the time. */ temp = new->br_startoff - PREV.br_startoff; - xfs_bmap_trace_pre_update(fname, "0", ip, idx, XFS_DATA_FORK); + XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx, XFS_DATA_FORK); xfs_bmbt_set_blockcount(ep, temp); r[0] = *new; + r[1].br_state = PREV.br_state; + r[1].br_startblock = 0; r[1].br_startoff = new_endoff; temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; r[1].br_blockcount = temp2; - xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 2, &r[0], &r[1], + XFS_BMAP_TRACE_INSERT("0", ip, idx + 1, 2, &r[0], &r[1], XFS_DATA_FORK); - xfs_bmap_insert_exlist(ip, idx + 1, 2, &r[0], XFS_DATA_FORK); + xfs_iext_insert(ifp, idx + 1, 2, &r[0]); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents++; if (cur == NULL) @@ -745,11 +1075,11 @@ xfs_bmap_add_extent_delay_real( new->br_startblock, new->br_blockcount, &i))) goto done; - ASSERT(i == 0); + XFS_WANT_CORRUPTED_GOTO(i == 0, done); cur->bc_rec.b.br_state = XFS_EXT_NORM; if ((error = xfs_bmbt_insert(cur, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); } if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && ip->i_d.di_nextents > ip->i_df.if_ext_max) { @@ -765,7 +1095,7 @@ xfs_bmap_add_extent_delay_real( diff = (int)(temp + temp2 - STARTBLOCKVAL(PREV.br_startblock) - (cur ? cur->bc_private.b.allocated : 0)); if (diff > 0 && - xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, -diff, rsvd)) { + xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, -((int64_t)diff), rsvd)) { /* * Ick gross gag me with a spoon. */ @@ -776,7 +1106,7 @@ xfs_bmap_add_extent_delay_real( diff--; if (!diff || !xfs_mod_incore_sb(ip->i_mount, - XFS_SBS_FDBLOCKS, -diff, rsvd)) + XFS_SBS_FDBLOCKS, -((int64_t)diff), rsvd)) break; } if (temp2) { @@ -784,21 +1114,22 @@ xfs_bmap_add_extent_delay_real( diff--; if (!diff || !xfs_mod_incore_sb(ip->i_mount, - XFS_SBS_FDBLOCKS, -diff, rsvd)) + XFS_SBS_FDBLOCKS, -((int64_t)diff), rsvd)) break; } } } - base = ip->i_df.if_u1.if_extents; - ep = &base[idx]; + ep = xfs_iext_get_ext(ifp, idx); xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); - xfs_bmap_trace_post_update(fname, "0", ip, idx, XFS_DATA_FORK); - xfs_bmap_trace_pre_update(fname, "0", ip, idx + 2, - XFS_DATA_FORK); - xfs_bmbt_set_startblock(ep + 2, NULLSTARTBLOCK((int)temp2)); - xfs_bmap_trace_post_update(fname, "0", ip, idx + 2, - XFS_DATA_FORK); + XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx, XFS_DATA_FORK); + XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx + 2, XFS_DATA_FORK); + xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx + 2), + NULLSTARTBLOCK((int)temp2)); + XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx + 2, XFS_DATA_FORK); *dnew = temp + temp2; + /* DELTA: One in-core extent is split in three. */ + temp = PREV.br_startoff; + temp2 = PREV.br_blockcount; break; case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): @@ -814,6 +1145,13 @@ xfs_bmap_add_extent_delay_real( ASSERT(0); } *curp = cur; + if (delta) { + temp2 += temp; + if (delta->xed_startoff > temp) + delta->xed_startoff = temp; + if (delta->xed_blockcount < temp2) + delta->xed_blockcount = temp2; + } done: *logflagsp = rval; return error; @@ -839,17 +1177,15 @@ xfs_bmap_add_extent_unwritten_real( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* extent number to update/insert */ xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ - xfs_bmbt_irec_t *new, /* new data to put in extent list */ - int *logflagsp) /* inode logging flags */ + xfs_bmbt_irec_t *new, /* new data to add to file extents */ + int *logflagsp, /* inode logging flags */ + xfs_extdelta_t *delta) /* Change made to incore extents */ { - xfs_bmbt_rec_t *base; /* base of extent entry list */ xfs_btree_cur_t *cur; /* btree cursor */ - xfs_bmbt_rec_t *ep; /* extent entry for idx */ + xfs_bmbt_rec_host_t *ep; /* extent entry for idx */ int error; /* error return value */ -#ifdef XFS_BMAP_TRACE - static char fname[] = "xfs_bmap_add_extent_unwritten_real"; -#endif int i; /* temp state */ + xfs_ifork_t *ifp; /* inode fork pointer */ xfs_fileoff_t new_endoff; /* end offset of new entry */ xfs_exntst_t newext; /* new extent state */ xfs_exntst_t oldext; /* old extent state */ @@ -857,6 +1193,8 @@ xfs_bmap_add_extent_unwritten_real( /* left is 0, right is 1, prev is 2 */ int rval=0; /* return value (logging flags) */ int state = 0;/* state bits, accessed thru macros */ + xfs_filblks_t temp=0; + xfs_filblks_t temp2=0; enum { /* bit number definitions for state */ LEFT_CONTIG, RIGHT_CONTIG, LEFT_FILLING, RIGHT_FILLING, @@ -883,8 +1221,8 @@ xfs_bmap_add_extent_unwritten_real( */ error = 0; cur = *curp; - base = ip->i_df.if_u1.if_extents; - ep = &base[idx]; + ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); + ep = xfs_iext_get_ext(ifp, idx); xfs_bmbt_get_all(ep, &PREV); newext = new->br_state; oldext = (newext == XFS_EXT_UNWRITTEN) ? @@ -905,7 +1243,7 @@ xfs_bmap_add_extent_unwritten_real( * Don't set contiguous if the combined extent would be too large. */ if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { - xfs_bmbt_get_all(ep - 1, &LEFT); + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT); STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(LEFT.br_startblock)); } STATE_SET(LEFT_CONTIG, @@ -922,7 +1260,7 @@ xfs_bmap_add_extent_unwritten_real( if (STATE_SET_TEST(RIGHT_VALID, idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) { - xfs_bmbt_get_all(ep + 1, &RIGHT); + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT); STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(RIGHT.br_startblock)); } STATE_SET(RIGHT_CONTIG, @@ -946,16 +1284,15 @@ xfs_bmap_add_extent_unwritten_real( * Setting all of a previous oldext extent to newext. * The left and right neighbors are both contiguous with new. */ - xfs_bmap_trace_pre_update(fname, "LF|RF|LC|RC", ip, idx - 1, + XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|LC|RC", ip, idx - 1, XFS_DATA_FORK); - xfs_bmbt_set_blockcount(ep - 1, + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + PREV.br_blockcount + RIGHT.br_blockcount); - xfs_bmap_trace_post_update(fname, "LF|RF|LC|RC", ip, idx - 1, - XFS_DATA_FORK); - xfs_bmap_trace_delete(fname, "LF|RF|LC|RC", ip, idx, 2, + XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC|RC", ip, idx - 1, XFS_DATA_FORK); - xfs_bmap_delete_exlist(ip, idx, 2, XFS_DATA_FORK); + XFS_BMAP_TRACE_DELETE("LF|RF|LC|RC", ip, idx, 2, XFS_DATA_FORK); + xfs_iext_remove(ifp, idx, 2); ip->i_df.if_lastex = idx - 1; ip->i_d.di_nextents -= 2; if (cur == NULL) @@ -966,25 +1303,30 @@ xfs_bmap_add_extent_unwritten_real( RIGHT.br_startblock, RIGHT.br_blockcount, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_delete(cur, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_decrement(cur, 0, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_delete(cur, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_decrement(cur, 0, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, LEFT.br_startblock, LEFT.br_blockcount + PREV.br_blockcount + RIGHT.br_blockcount, LEFT.br_state))) goto done; } + /* DELTA: Three in-core extents are replaced by one. */ + temp = LEFT.br_startoff; + temp2 = LEFT.br_blockcount + + PREV.br_blockcount + + RIGHT.br_blockcount; break; case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): @@ -992,16 +1334,15 @@ xfs_bmap_add_extent_unwritten_real( * Setting all of a previous oldext extent to newext. * The left neighbor is contiguous, the right is not. */ - xfs_bmap_trace_pre_update(fname, "LF|RF|LC", ip, idx - 1, + XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|LC", ip, idx - 1, XFS_DATA_FORK); - xfs_bmbt_set_blockcount(ep - 1, + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + PREV.br_blockcount); - xfs_bmap_trace_post_update(fname, "LF|RF|LC", ip, idx - 1, + XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC", ip, idx - 1, XFS_DATA_FORK); ip->i_df.if_lastex = idx - 1; - xfs_bmap_trace_delete(fname, "LF|RF|LC", ip, idx, 1, - XFS_DATA_FORK); - xfs_bmap_delete_exlist(ip, idx, 1, XFS_DATA_FORK); + XFS_BMAP_TRACE_DELETE("LF|RF|LC", ip, idx, 1, XFS_DATA_FORK); + xfs_iext_remove(ifp, idx, 1); ip->i_d.di_nextents--; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; @@ -1011,19 +1352,23 @@ xfs_bmap_add_extent_unwritten_real( PREV.br_startblock, PREV.br_blockcount, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_delete(cur, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_decrement(cur, 0, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, LEFT.br_startblock, LEFT.br_blockcount + PREV.br_blockcount, LEFT.br_state))) goto done; } + /* DELTA: Two in-core extents are replaced by one. */ + temp = LEFT.br_startoff; + temp2 = LEFT.br_blockcount + + PREV.br_blockcount; break; case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): @@ -1031,17 +1376,16 @@ xfs_bmap_add_extent_unwritten_real( * Setting all of a previous oldext extent to newext. * The right neighbor is contiguous, the left is not. */ - xfs_bmap_trace_pre_update(fname, "LF|RF|RC", ip, idx, + XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|RC", ip, idx, XFS_DATA_FORK); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount + RIGHT.br_blockcount); xfs_bmbt_set_state(ep, newext); - xfs_bmap_trace_post_update(fname, "LF|RF|RC", ip, idx, + XFS_BMAP_TRACE_POST_UPDATE("LF|RF|RC", ip, idx, XFS_DATA_FORK); ip->i_df.if_lastex = idx; - xfs_bmap_trace_delete(fname, "LF|RF|RC", ip, idx + 1, 1, - XFS_DATA_FORK); - xfs_bmap_delete_exlist(ip, idx + 1, 1, XFS_DATA_FORK); + XFS_BMAP_TRACE_DELETE("LF|RF|RC", ip, idx + 1, 1, XFS_DATA_FORK); + xfs_iext_remove(ifp, idx + 1, 1); ip->i_d.di_nextents--; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; @@ -1051,19 +1395,23 @@ xfs_bmap_add_extent_unwritten_real( RIGHT.br_startblock, RIGHT.br_blockcount, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_delete(cur, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_decrement(cur, 0, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, new->br_startoff, new->br_startblock, new->br_blockcount + RIGHT.br_blockcount, newext))) goto done; } + /* DELTA: Two in-core extents are replaced by one. */ + temp = PREV.br_startoff; + temp2 = PREV.br_blockcount + + RIGHT.br_blockcount; break; case MASK2(LEFT_FILLING, RIGHT_FILLING): @@ -1072,10 +1420,10 @@ xfs_bmap_add_extent_unwritten_real( * Neither the left nor right neighbors are contiguous with * the new one. */ - xfs_bmap_trace_pre_update(fname, "LF|RF", ip, idx, + XFS_BMAP_TRACE_PRE_UPDATE("LF|RF", ip, idx, XFS_DATA_FORK); xfs_bmbt_set_state(ep, newext); - xfs_bmap_trace_post_update(fname, "LF|RF", ip, idx, + XFS_BMAP_TRACE_POST_UPDATE("LF|RF", ip, idx, XFS_DATA_FORK); ip->i_df.if_lastex = idx; if (cur == NULL) @@ -1086,12 +1434,15 @@ xfs_bmap_add_extent_unwritten_real( new->br_startblock, new->br_blockcount, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, new->br_startoff, new->br_startblock, new->br_blockcount, newext))) goto done; } + /* DELTA: The in-core extent described by new changed type. */ + temp = new->br_startoff; + temp2 = new->br_blockcount; break; case MASK2(LEFT_FILLING, LEFT_CONTIG): @@ -1099,21 +1450,21 @@ xfs_bmap_add_extent_unwritten_real( * Setting the first part of a previous oldext extent to newext. * The left neighbor is contiguous. */ - xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx - 1, + XFS_BMAP_TRACE_PRE_UPDATE("LF|LC", ip, idx - 1, XFS_DATA_FORK); - xfs_bmbt_set_blockcount(ep - 1, + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + new->br_blockcount); xfs_bmbt_set_startoff(ep, PREV.br_startoff + new->br_blockcount); - xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx - 1, + XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx - 1, XFS_DATA_FORK); - xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx, + XFS_BMAP_TRACE_PRE_UPDATE("LF|LC", ip, idx, XFS_DATA_FORK); xfs_bmbt_set_startblock(ep, new->br_startblock + new->br_blockcount); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount - new->br_blockcount); - xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx, + XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx, XFS_DATA_FORK); ip->i_df.if_lastex = idx - 1; if (cur == NULL) @@ -1124,7 +1475,7 @@ xfs_bmap_add_extent_unwritten_real( PREV.br_startblock, PREV.br_blockcount, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, PREV.br_startoff + new->br_blockcount, PREV.br_startblock + new->br_blockcount, @@ -1139,6 +1490,10 @@ xfs_bmap_add_extent_unwritten_real( LEFT.br_state)) goto done; } + /* DELTA: The boundary between two in-core extents moved. */ + temp = LEFT.br_startoff; + temp2 = LEFT.br_blockcount + + PREV.br_blockcount; break; case MASK(LEFT_FILLING): @@ -1146,17 +1501,17 @@ xfs_bmap_add_extent_unwritten_real( * Setting the first part of a previous oldext extent to newext. * The left neighbor is not contiguous. */ - xfs_bmap_trace_pre_update(fname, "LF", ip, idx, XFS_DATA_FORK); + XFS_BMAP_TRACE_PRE_UPDATE("LF", ip, idx, XFS_DATA_FORK); ASSERT(ep && xfs_bmbt_get_state(ep) == oldext); xfs_bmbt_set_startoff(ep, new_endoff); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount - new->br_blockcount); xfs_bmbt_set_startblock(ep, new->br_startblock + new->br_blockcount); - xfs_bmap_trace_post_update(fname, "LF", ip, idx, XFS_DATA_FORK); - xfs_bmap_trace_insert(fname, "LF", ip, idx, 1, new, NULL, + XFS_BMAP_TRACE_POST_UPDATE("LF", ip, idx, XFS_DATA_FORK); + XFS_BMAP_TRACE_INSERT("LF", ip, idx, 1, new, NULL, XFS_DATA_FORK); - xfs_bmap_insert_exlist(ip, idx, 1, new, XFS_DATA_FORK); + xfs_iext_insert(ifp, idx, 1, new); ip->i_df.if_lastex = idx; ip->i_d.di_nextents++; if (cur == NULL) @@ -1167,7 +1522,7 @@ xfs_bmap_add_extent_unwritten_real( PREV.br_startblock, PREV.br_blockcount, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, PREV.br_startoff + new->br_blockcount, PREV.br_startblock + new->br_blockcount, @@ -1177,8 +1532,11 @@ xfs_bmap_add_extent_unwritten_real( cur->bc_rec.b = *new; if ((error = xfs_bmbt_insert(cur, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); } + /* DELTA: One in-core extent is split in two. */ + temp = PREV.br_startoff; + temp2 = PREV.br_blockcount; break; case MASK2(RIGHT_FILLING, RIGHT_CONTIG): @@ -1186,17 +1544,18 @@ xfs_bmap_add_extent_unwritten_real( * Setting the last part of a previous oldext extent to newext. * The right neighbor is contiguous with the new allocation. */ - xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx, + XFS_BMAP_TRACE_PRE_UPDATE("RF|RC", ip, idx, XFS_DATA_FORK); - xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx + 1, + XFS_BMAP_TRACE_PRE_UPDATE("RF|RC", ip, idx + 1, XFS_DATA_FORK); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount - new->br_blockcount); - xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx, + XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx, XFS_DATA_FORK); - xfs_bmbt_set_allf(ep + 1, new->br_startoff, new->br_startblock, + xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), + new->br_startoff, new->br_startblock, new->br_blockcount + RIGHT.br_blockcount, newext); - xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx + 1, + XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx + 1, XFS_DATA_FORK); ip->i_df.if_lastex = idx + 1; if (cur == NULL) @@ -1207,7 +1566,7 @@ xfs_bmap_add_extent_unwritten_real( PREV.br_startblock, PREV.br_blockcount, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, PREV.br_startoff, PREV.br_startblock, PREV.br_blockcount - new->br_blockcount, @@ -1221,6 +1580,10 @@ xfs_bmap_add_extent_unwritten_real( newext))) goto done; } + /* DELTA: The boundary between two in-core extents moved. */ + temp = PREV.br_startoff; + temp2 = PREV.br_blockcount + + RIGHT.br_blockcount; break; case MASK(RIGHT_FILLING): @@ -1228,13 +1591,13 @@ xfs_bmap_add_extent_unwritten_real( * Setting the last part of a previous oldext extent to newext. * The right neighbor is not contiguous. */ - xfs_bmap_trace_pre_update(fname, "RF", ip, idx, XFS_DATA_FORK); + XFS_BMAP_TRACE_PRE_UPDATE("RF", ip, idx, XFS_DATA_FORK); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount - new->br_blockcount); - xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK); - xfs_bmap_trace_insert(fname, "RF", ip, idx + 1, 1, - new, NULL, XFS_DATA_FORK); - xfs_bmap_insert_exlist(ip, idx + 1, 1, new, XFS_DATA_FORK); + XFS_BMAP_TRACE_POST_UPDATE("RF", ip, idx, XFS_DATA_FORK); + XFS_BMAP_TRACE_INSERT("RF", ip, idx + 1, 1, new, NULL, + XFS_DATA_FORK); + xfs_iext_insert(ifp, idx + 1, 1, new); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents++; if (cur == NULL) @@ -1245,7 +1608,7 @@ xfs_bmap_add_extent_unwritten_real( PREV.br_startblock, PREV.br_blockcount, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, PREV.br_startoff, PREV.br_startblock, PREV.br_blockcount - new->br_blockcount, @@ -1255,12 +1618,15 @@ xfs_bmap_add_extent_unwritten_real( new->br_startblock, new->br_blockcount, &i))) goto done; - ASSERT(i == 0); + XFS_WANT_CORRUPTED_GOTO(i == 0, done); cur->bc_rec.b.br_state = XFS_EXT_NORM; if ((error = xfs_bmbt_insert(cur, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); } + /* DELTA: One in-core extent is split in two. */ + temp = PREV.br_startoff; + temp2 = PREV.br_blockcount; break; case 0: @@ -1269,19 +1635,19 @@ xfs_bmap_add_extent_unwritten_real( * newext. Contiguity is impossible here. * One extent becomes three extents. */ - xfs_bmap_trace_pre_update(fname, "0", ip, idx, XFS_DATA_FORK); + XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx, XFS_DATA_FORK); xfs_bmbt_set_blockcount(ep, new->br_startoff - PREV.br_startoff); - xfs_bmap_trace_post_update(fname, "0", ip, idx, XFS_DATA_FORK); + XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx, XFS_DATA_FORK); r[0] = *new; r[1].br_startoff = new_endoff; r[1].br_blockcount = PREV.br_startoff + PREV.br_blockcount - new_endoff; r[1].br_startblock = new->br_startblock + new->br_blockcount; r[1].br_state = oldext; - xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 2, &r[0], &r[1], + XFS_BMAP_TRACE_INSERT("0", ip, idx + 1, 2, &r[0], &r[1], XFS_DATA_FORK); - xfs_bmap_insert_exlist(ip, idx + 1, 2, &r[0], XFS_DATA_FORK); + xfs_iext_insert(ifp, idx + 1, 2, &r[0]); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents += 2; if (cur == NULL) @@ -1292,28 +1658,38 @@ xfs_bmap_add_extent_unwritten_real( PREV.br_startblock, PREV.br_blockcount, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); /* new right extent - oldext */ if ((error = xfs_bmbt_update(cur, r[1].br_startoff, r[1].br_startblock, r[1].br_blockcount, r[1].br_state))) goto done; /* new left extent - oldext */ - PREV.br_blockcount = - new->br_startoff - PREV.br_startoff; cur->bc_rec.b = PREV; + cur->bc_rec.b.br_blockcount = + new->br_startoff - PREV.br_startoff; if ((error = xfs_bmbt_insert(cur, &i))) goto done; - ASSERT(i == 1); - if ((error = xfs_bmbt_increment(cur, 0, &i))) + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + /* + * Reset the cursor to the position of the new extent + * we are about to insert as we can't trust it after + * the previous insert. + */ + if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, + new->br_startblock, new->br_blockcount, + &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 0, done); /* new middle extent - newext */ - cur->bc_rec.b = *new; + cur->bc_rec.b.br_state = new->br_state; if ((error = xfs_bmbt_insert(cur, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); } + /* DELTA: One in-core extent is split in three. */ + temp = PREV.br_startoff; + temp2 = PREV.br_blockcount; break; case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): @@ -1329,6 +1705,13 @@ xfs_bmap_add_extent_unwritten_real( ASSERT(0); } *curp = cur; + if (delta) { + temp2 += temp; + if (delta->xed_startoff > temp) + delta->xed_startoff = temp; + if (delta->xed_blockcount < temp2) + delta->xed_blockcount = temp2; + } done: *logflagsp = rval; return error; @@ -1354,22 +1737,20 @@ STATIC int /* error */ xfs_bmap_add_extent_hole_delay( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* extent number to update/insert */ - xfs_btree_cur_t *cur, /* if null, not a btree */ - xfs_bmbt_irec_t *new, /* new data to put in extent list */ + xfs_bmbt_irec_t *new, /* new data to add to file extents */ int *logflagsp, /* inode logging flags */ + xfs_extdelta_t *delta, /* Change made to incore extents */ int rsvd) /* OK to allocate reserved blocks */ { - xfs_bmbt_rec_t *base; /* base of extent entry list */ - xfs_bmbt_rec_t *ep; /* extent list entry for idx */ -#ifdef XFS_BMAP_TRACE - static char fname[] = "xfs_bmap_add_extent_hole_delay"; -#endif + xfs_bmbt_rec_host_t *ep; /* extent record for idx */ + xfs_ifork_t *ifp; /* inode fork pointer */ xfs_bmbt_irec_t left; /* left neighbor extent entry */ xfs_filblks_t newlen=0; /* new indirect size */ xfs_filblks_t oldlen=0; /* old indirect size */ xfs_bmbt_irec_t right; /* right neighbor extent entry */ int state; /* state bits, accessed thru macros */ - xfs_filblks_t temp; /* temp for indirect calculations */ + xfs_filblks_t temp=0; /* temp for indirect calculations */ + xfs_filblks_t temp2=0; enum { /* bit number definitions for state */ LEFT_CONTIG, RIGHT_CONTIG, LEFT_DELAY, RIGHT_DELAY, @@ -1384,15 +1765,15 @@ xfs_bmap_add_extent_hole_delay( ((state &= ~MASK(b)), 0)) #define SWITCH_STATE (state & MASK2(LEFT_CONTIG, RIGHT_CONTIG)) - base = ip->i_df.if_u1.if_extents; - ep = &base[idx]; + ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); + ep = xfs_iext_get_ext(ifp, idx); state = 0; ASSERT(ISNULLSTARTBLOCK(new->br_startblock)); /* * Check and set flags if this segment has a left neighbor */ if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { - xfs_bmbt_get_all(ep - 1, &left); + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left); STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(left.br_startblock)); } /* @@ -1429,24 +1810,27 @@ xfs_bmap_add_extent_hole_delay( /* * New allocation is contiguous with delayed allocations * on the left and on the right. - * Merge all three into a single extent list entry. + * Merge all three into a single extent record. */ temp = left.br_blockcount + new->br_blockcount + right.br_blockcount; - xfs_bmap_trace_pre_update(fname, "LC|RC", ip, idx - 1, + XFS_BMAP_TRACE_PRE_UPDATE("LC|RC", ip, idx - 1, XFS_DATA_FORK); - xfs_bmbt_set_blockcount(ep - 1, temp); + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); oldlen = STARTBLOCKVAL(left.br_startblock) + STARTBLOCKVAL(new->br_startblock) + STARTBLOCKVAL(right.br_startblock); newlen = xfs_bmap_worst_indlen(ip, temp); - xfs_bmbt_set_startblock(ep - 1, NULLSTARTBLOCK((int)newlen)); - xfs_bmap_trace_post_update(fname, "LC|RC", ip, idx - 1, - XFS_DATA_FORK); - xfs_bmap_trace_delete(fname, "LC|RC", ip, idx, 1, + xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), + NULLSTARTBLOCK((int)newlen)); + XFS_BMAP_TRACE_POST_UPDATE("LC|RC", ip, idx - 1, XFS_DATA_FORK); - xfs_bmap_delete_exlist(ip, idx, 1, XFS_DATA_FORK); + XFS_BMAP_TRACE_DELETE("LC|RC", ip, idx, 1, XFS_DATA_FORK); + xfs_iext_remove(ifp, idx, 1); ip->i_df.if_lastex = idx - 1; + /* DELTA: Two in-core extents were replaced by one. */ + temp2 = temp; + temp = left.br_startoff; break; case MASK(LEFT_CONTIG): @@ -1456,16 +1840,20 @@ xfs_bmap_add_extent_hole_delay( * Merge the new allocation with the left neighbor. */ temp = left.br_blockcount + new->br_blockcount; - xfs_bmap_trace_pre_update(fname, "LC", ip, idx - 1, + XFS_BMAP_TRACE_PRE_UPDATE("LC", ip, idx - 1, XFS_DATA_FORK); - xfs_bmbt_set_blockcount(ep - 1, temp); + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); oldlen = STARTBLOCKVAL(left.br_startblock) + STARTBLOCKVAL(new->br_startblock); newlen = xfs_bmap_worst_indlen(ip, temp); - xfs_bmbt_set_startblock(ep - 1, NULLSTARTBLOCK((int)newlen)); - xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, + xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), + NULLSTARTBLOCK((int)newlen)); + XFS_BMAP_TRACE_POST_UPDATE("LC", ip, idx - 1, XFS_DATA_FORK); ip->i_df.if_lastex = idx - 1; + /* DELTA: One in-core extent grew into a hole. */ + temp2 = temp; + temp = left.br_startoff; break; case MASK(RIGHT_CONTIG): @@ -1474,15 +1862,18 @@ xfs_bmap_add_extent_hole_delay( * on the right. * Merge the new allocation with the right neighbor. */ - xfs_bmap_trace_pre_update(fname, "RC", ip, idx, XFS_DATA_FORK); + XFS_BMAP_TRACE_PRE_UPDATE("RC", ip, idx, XFS_DATA_FORK); temp = new->br_blockcount + right.br_blockcount; oldlen = STARTBLOCKVAL(new->br_startblock) + STARTBLOCKVAL(right.br_startblock); newlen = xfs_bmap_worst_indlen(ip, temp); xfs_bmbt_set_allf(ep, new->br_startoff, NULLSTARTBLOCK((int)newlen), temp, right.br_state); - xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK); + XFS_BMAP_TRACE_POST_UPDATE("RC", ip, idx, XFS_DATA_FORK); ip->i_df.if_lastex = idx; + /* DELTA: One in-core extent grew into a hole. */ + temp2 = temp; + temp = new->br_startoff; break; case 0: @@ -1492,20 +1883,30 @@ xfs_bmap_add_extent_hole_delay( * Insert a new entry. */ oldlen = newlen = 0; - xfs_bmap_trace_insert(fname, "0", ip, idx, 1, new, NULL, + XFS_BMAP_TRACE_INSERT("0", ip, idx, 1, new, NULL, XFS_DATA_FORK); - xfs_bmap_insert_exlist(ip, idx, 1, new, XFS_DATA_FORK); + xfs_iext_insert(ifp, idx, 1, new); ip->i_df.if_lastex = idx; + /* DELTA: A new in-core extent was added in a hole. */ + temp2 = new->br_blockcount; + temp = new->br_startoff; break; } if (oldlen != newlen) { ASSERT(oldlen > newlen); xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, - (int)(oldlen - newlen), rsvd); + (int64_t)(oldlen - newlen), rsvd); /* * Nothing to do for disk quota accounting here. */ } + if (delta) { + temp2 += temp; + if (delta->xed_startoff > temp) + delta->xed_startoff = temp; + if (delta->xed_blockcount < temp2) + delta->xed_blockcount = temp2; + } *logflagsp = 0; return 0; #undef MASK @@ -1525,20 +1926,21 @@ xfs_bmap_add_extent_hole_real( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* extent number to update/insert */ xfs_btree_cur_t *cur, /* if null, not a btree */ - xfs_bmbt_irec_t *new, /* new data to put in extent list */ + xfs_bmbt_irec_t *new, /* new data to add to file extents */ int *logflagsp, /* inode logging flags */ + xfs_extdelta_t *delta, /* Change made to incore extents */ int whichfork) /* data or attr fork */ { - xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */ + xfs_bmbt_rec_host_t *ep; /* pointer to extent entry ins. point */ int error; /* error return value */ -#ifdef XFS_BMAP_TRACE - static char fname[] = "xfs_bmap_add_extent_hole_real"; -#endif int i; /* temp state */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_bmbt_irec_t left; /* left neighbor extent entry */ xfs_bmbt_irec_t right; /* right neighbor extent entry */ + int rval=0; /* return value (logging flags) */ int state; /* state bits, accessed thru macros */ + xfs_filblks_t temp=0; + xfs_filblks_t temp2=0; enum { /* bit number definitions for state */ LEFT_CONTIG, RIGHT_CONTIG, LEFT_DELAY, RIGHT_DELAY, @@ -1555,13 +1957,13 @@ xfs_bmap_add_extent_hole_real( ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT(idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); - ep = &ifp->if_u1.if_extents[idx]; + ep = xfs_iext_get_ext(ifp, idx); state = 0; /* * Check and set flags if this segment has a left neighbor. */ if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { - xfs_bmbt_get_all(ep - 1, &left); + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left); STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(left.br_startblock)); } /* @@ -1595,6 +1997,7 @@ xfs_bmap_add_extent_hole_real( left.br_blockcount + new->br_blockcount + right.br_blockcount <= MAXEXTLEN)); + error = 0; /* * Select which case we're in here, and implement it. */ @@ -1604,41 +2007,50 @@ xfs_bmap_add_extent_hole_real( /* * New allocation is contiguous with real allocations on the * left and on the right. - * Merge all three into a single extent list entry. + * Merge all three into a single extent record. */ - xfs_bmap_trace_pre_update(fname, "LC|RC", ip, idx - 1, + XFS_BMAP_TRACE_PRE_UPDATE("LC|RC", ip, idx - 1, whichfork); - xfs_bmbt_set_blockcount(ep - 1, + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), left.br_blockcount + new->br_blockcount + right.br_blockcount); - xfs_bmap_trace_post_update(fname, "LC|RC", ip, idx - 1, + XFS_BMAP_TRACE_POST_UPDATE("LC|RC", ip, idx - 1, whichfork); - xfs_bmap_trace_delete(fname, "LC|RC", ip, - idx, 1, whichfork); - xfs_bmap_delete_exlist(ip, idx, 1, whichfork); + XFS_BMAP_TRACE_DELETE("LC|RC", ip, idx, 1, whichfork); + xfs_iext_remove(ifp, idx, 1); ifp->if_lastex = idx - 1; XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) - 1); if (cur == NULL) { - *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); - return 0; + rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); + } else { + rval = XFS_ILOG_CORE; + if ((error = xfs_bmbt_lookup_eq(cur, + right.br_startoff, + right.br_startblock, + right.br_blockcount, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_bmbt_delete(cur, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_bmbt_decrement(cur, 0, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_bmbt_update(cur, left.br_startoff, + left.br_startblock, + left.br_blockcount + + new->br_blockcount + + right.br_blockcount, + left.br_state))) + goto done; } - *logflagsp = XFS_ILOG_CORE; - if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, - right.br_startblock, right.br_blockcount, &i))) - return error; - ASSERT(i == 1); - if ((error = xfs_bmbt_delete(cur, &i))) - return error; - ASSERT(i == 1); - if ((error = xfs_bmbt_decrement(cur, 0, &i))) - return error; - ASSERT(i == 1); - error = xfs_bmbt_update(cur, left.br_startoff, - left.br_startblock, - left.br_blockcount + new->br_blockcount + - right.br_blockcount, left.br_state); - return error; + /* DELTA: Two in-core extents were replaced by one. */ + temp = left.br_startoff; + temp2 = left.br_blockcount + + new->br_blockcount + + right.br_blockcount; + break; case MASK(LEFT_CONTIG): /* @@ -1646,25 +2058,33 @@ xfs_bmap_add_extent_hole_real( * on the left. * Merge the new allocation with the left neighbor. */ - xfs_bmap_trace_pre_update(fname, "LC", ip, idx - 1, whichfork); - xfs_bmbt_set_blockcount(ep - 1, + XFS_BMAP_TRACE_PRE_UPDATE("LC", ip, idx - 1, whichfork); + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), left.br_blockcount + new->br_blockcount); - xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork); + XFS_BMAP_TRACE_POST_UPDATE("LC", ip, idx - 1, whichfork); ifp->if_lastex = idx - 1; if (cur == NULL) { - *logflagsp = XFS_ILOG_FEXT(whichfork); - return 0; + rval = XFS_ILOG_FEXT(whichfork); + } else { + rval = 0; + if ((error = xfs_bmbt_lookup_eq(cur, + left.br_startoff, + left.br_startblock, + left.br_blockcount, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_bmbt_update(cur, left.br_startoff, + left.br_startblock, + left.br_blockcount + + new->br_blockcount, + left.br_state))) + goto done; } - *logflagsp = 0; - if ((error = xfs_bmbt_lookup_eq(cur, left.br_startoff, - left.br_startblock, left.br_blockcount, &i))) - return error; - ASSERT(i == 1); - error = xfs_bmbt_update(cur, left.br_startoff, - left.br_startblock, - left.br_blockcount + new->br_blockcount, - left.br_state); - return error; + /* DELTA: One in-core extent grew. */ + temp = left.br_startoff; + temp2 = left.br_blockcount + + new->br_blockcount; + break; case MASK(RIGHT_CONTIG): /* @@ -1672,26 +2092,34 @@ xfs_bmap_add_extent_hole_real( * on the right. * Merge the new allocation with the right neighbor. */ - xfs_bmap_trace_pre_update(fname, "RC", ip, idx, whichfork); + XFS_BMAP_TRACE_PRE_UPDATE("RC", ip, idx, whichfork); xfs_bmbt_set_allf(ep, new->br_startoff, new->br_startblock, new->br_blockcount + right.br_blockcount, right.br_state); - xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork); + XFS_BMAP_TRACE_POST_UPDATE("RC", ip, idx, whichfork); ifp->if_lastex = idx; if (cur == NULL) { - *logflagsp = XFS_ILOG_FEXT(whichfork); - return 0; + rval = XFS_ILOG_FEXT(whichfork); + } else { + rval = 0; + if ((error = xfs_bmbt_lookup_eq(cur, + right.br_startoff, + right.br_startblock, + right.br_blockcount, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); + if ((error = xfs_bmbt_update(cur, new->br_startoff, + new->br_startblock, + new->br_blockcount + + right.br_blockcount, + right.br_state))) + goto done; } - *logflagsp = 0; - if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, - right.br_startblock, right.br_blockcount, &i))) - return error; - ASSERT(i == 1); - error = xfs_bmbt_update(cur, new->br_startoff, - new->br_startblock, - new->br_blockcount + right.br_blockcount, - right.br_state); - return error; + /* DELTA: One in-core extent grew. */ + temp = new->br_startoff; + temp2 = new->br_blockcount + + right.br_blockcount; + break; case 0: /* @@ -1699,41 +2127,51 @@ xfs_bmap_add_extent_hole_real( * real allocation. * Insert a new entry. */ - xfs_bmap_trace_insert(fname, "0", ip, idx, 1, new, NULL, - whichfork); - xfs_bmap_insert_exlist(ip, idx, 1, new, whichfork); + XFS_BMAP_TRACE_INSERT("0", ip, idx, 1, new, NULL, whichfork); + xfs_iext_insert(ifp, idx, 1, new); ifp->if_lastex = idx; XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) + 1); if (cur == NULL) { - *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); - return 0; + rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); + } else { + rval = XFS_ILOG_CORE; + if ((error = xfs_bmbt_lookup_eq(cur, + new->br_startoff, + new->br_startblock, + new->br_blockcount, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 0, done); + cur->bc_rec.b.br_state = new->br_state; + if ((error = xfs_bmbt_insert(cur, &i))) + goto done; + XFS_WANT_CORRUPTED_GOTO(i == 1, done); } - *logflagsp = XFS_ILOG_CORE; - if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, - new->br_startblock, new->br_blockcount, &i))) - return error; - ASSERT(i == 0); - cur->bc_rec.b.br_state = new->br_state; - if ((error = xfs_bmbt_insert(cur, &i))) - return error; - ASSERT(i == 1); - return 0; + /* DELTA: A new extent was added in a hole. */ + temp = new->br_startoff; + temp2 = new->br_blockcount; + break; + } + if (delta) { + temp2 += temp; + if (delta->xed_startoff > temp) + delta->xed_startoff = temp; + if (delta->xed_blockcount < temp2) + delta->xed_blockcount = temp2; } +done: + *logflagsp = rval; + return error; #undef MASK #undef MASK2 #undef STATE_SET #undef STATE_TEST #undef STATE_SET_TEST #undef SWITCH_STATE - /* NOTREACHED */ - ASSERT(0); - return 0; /* keep gcc quite */ } /* - * xfs_bmap_alloc_extsize_align is called by xfs_bmapi_alloc to adjust - * size of the extent-to-be-allocated based on inode and rt extsize. + * Adjust the size of the new extent based on di_extsize and rt extsize. */ STATIC int xfs_bmap_extsize_align( @@ -1897,102 +2335,27 @@ xfs_bmap_extsize_align( #define XFS_ALLOC_GAP_UNITS 4 -/* - * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. - * It figures out where to ask the underlying allocator to put the new extent. - */ -STATIC int -xfs_bmap_alloc( +STATIC void +xfs_bmap_adjacent( xfs_bmalloca_t *ap) /* bmap alloc argument struct */ { xfs_fsblock_t adjust; /* adjustment to block numbers */ - xfs_alloctype_t atype=0; /* type for allocation routines */ - int error; /* error return value */ xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ xfs_mount_t *mp; /* mount point structure */ int nullfb; /* true if ap->firstblock isn't set */ int rt; /* true if inode is realtime */ - xfs_extlen_t prod = 0; /* product factor for allocators */ - xfs_extlen_t ralen = 0; /* realtime allocation length */ - xfs_extlen_t align; /* minimum allocation alignment */ - xfs_rtblock_t rtx; - -#define ISVALID(x,y) \ - (rt ? \ - (x) < mp->m_sb.sb_rblocks : \ - XFS_FSB_TO_AGNO(mp, x) == XFS_FSB_TO_AGNO(mp, y) && \ - XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \ - XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks) - - /* - * Set up variables. - */ - mp = ap->ip->i_mount; - nullfb = ap->firstblock == NULLFSBLOCK; - rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata; - fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); - if (rt) { - align = ap->ip->i_d.di_extsize ? - ap->ip->i_d.di_extsize : mp->m_sb.sb_rextsize; - /* Set prod to match the extent size */ - prod = align / mp->m_sb.sb_rextsize; - - error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, - align, rt, ap->eof, 0, - ap->conv, &ap->off, &ap->alen); - if (error) - return error; - ASSERT(ap->alen); - ASSERT(ap->alen % mp->m_sb.sb_rextsize == 0); - /* - * If the offset & length are not perfectly aligned - * then kill prod, it will just get us in trouble. - */ - if (do_mod(ap->off, align) || ap->alen % align) - prod = 1; - /* - * Set ralen to be the actual requested length in rtextents. - */ - ralen = ap->alen / mp->m_sb.sb_rextsize; - /* - * If the old value was close enough to MAXEXTLEN that - * we rounded up to it, cut it back so it's valid again. - * Note that if it's a really large request (bigger than - * MAXEXTLEN), we don't hear about that number, and can't - * adjust the starting point to match it. - */ - if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN) - ralen = MAXEXTLEN / mp->m_sb.sb_rextsize; - /* - * If it's an allocation to an empty file at offset 0, - * pick an extent that will space things out in the rt area. - */ - if (ap->eof && ap->off == 0) { - error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx); - if (error) - return error; - ap->rval = rtx * mp->m_sb.sb_rextsize; - } else - ap->rval = 0; - } else { - align = (ap->userdata && ap->ip->i_d.di_extsize && - (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)) ? - ap->ip->i_d.di_extsize : 0; - if (unlikely(align)) { - error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, - align, rt, - ap->eof, 0, ap->conv, - &ap->off, &ap->alen); - ASSERT(!error); - ASSERT(ap->alen); - } - if (nullfb) - ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino); - else - ap->rval = ap->firstblock; - } +#define ISVALID(x,y) \ + (rt ? \ + (x) < mp->m_sb.sb_rblocks : \ + XFS_FSB_TO_AGNO(mp, x) == XFS_FSB_TO_AGNO(mp, y) && \ + XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \ + XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks) + mp = ap->ip->i_mount; + nullfb = ap->firstblock == NULLFSBLOCK; + rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata; + fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); /* * If allocating at eof, and there's a previous real block, * try to use it's last block as our starting point. @@ -2117,287 +2480,340 @@ xfs_bmap_alloc( else if (gotbno != NULLFSBLOCK) ap->rval = gotbno; } +#undef ISVALID +} + +STATIC int +xfs_bmap_btalloc( + xfs_bmalloca_t *ap) /* bmap alloc argument struct */ +{ + xfs_mount_t *mp; /* mount point structure */ + xfs_alloctype_t atype = 0; /* type for allocation routines */ + xfs_extlen_t align; /* minimum allocation alignment */ + xfs_agnumber_t ag; + xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ + xfs_agnumber_t startag; + xfs_alloc_arg_t args; + xfs_extlen_t blen; + xfs_extlen_t delta; + xfs_extlen_t longest; + xfs_extlen_t need; + xfs_extlen_t nextminlen = 0; + xfs_perag_t *pag; + int nullfb; /* true if ap->firstblock isn't set */ + int isaligned; + int notinit; + int tryagain; + int error; + + mp = ap->ip->i_mount; + align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0; + if (unlikely(align)) { + error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, + align, 0, ap->eof, 0, ap->conv, + &ap->off, &ap->alen); + ASSERT(!error); + ASSERT(ap->alen); + } + nullfb = ap->firstblock == NULLFSBLOCK; + fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); + if (nullfb) { + if (ap->userdata && xfs_inode_is_filestream(ap->ip)) { + ag = xfs_filestream_lookup_ag(ap->ip); + ag = (ag != NULLAGNUMBER) ? ag : 0; + ap->rval = XFS_AGB_TO_FSB(mp, ag, 0); + } else { + ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino); + } + } else + ap->rval = ap->firstblock; + + xfs_bmap_adjacent(ap); + /* * If allowed, use ap->rval; otherwise must use firstblock since * it's in the right allocation group. */ - if (nullfb || rt || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno) + if (nullfb || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno) ; else ap->rval = ap->firstblock; - /* - * Realtime allocation, done through xfs_rtallocate_extent. - */ - if (rt) { -#ifndef __KERNEL__ - ASSERT(0); -#else - xfs_rtblock_t rtb; - - atype = ap->rval == 0 ? - XFS_ALLOCTYPE_ANY_AG : XFS_ALLOCTYPE_NEAR_BNO; - do_div(ap->rval, mp->m_sb.sb_rextsize); - rtb = ap->rval; - ap->alen = ralen; - if ((error = xfs_rtallocate_extent(ap->tp, ap->rval, 1, ap->alen, - &ralen, atype, ap->wasdel, prod, &rtb))) - return error; - if (rtb == NULLFSBLOCK && prod > 1 && - (error = xfs_rtallocate_extent(ap->tp, ap->rval, 1, - ap->alen, &ralen, atype, - ap->wasdel, 1, &rtb))) - return error; - ap->rval = rtb; - if (ap->rval != NULLFSBLOCK) { - ap->rval *= mp->m_sb.sb_rextsize; - ralen *= mp->m_sb.sb_rextsize; - ap->alen = ralen; - ap->ip->i_d.di_nblocks += ralen; - xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); - if (ap->wasdel) - ap->ip->i_delayed_blks -= ralen; - /* - * Adjust the disk quota also. This was reserved - * earlier. - */ - XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip, - ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT : - XFS_TRANS_DQ_RTBCOUNT, - (long) ralen); - } else - ap->alen = 0; -#endif /* __KERNEL__ */ - } /* * Normal allocation, done through xfs_alloc_vextent. */ - else { - xfs_agnumber_t ag; - xfs_alloc_arg_t args; - xfs_extlen_t blen; - xfs_extlen_t delta; - int isaligned; - xfs_extlen_t longest; - xfs_extlen_t need; - xfs_extlen_t nextminlen=0; - int notinit; - xfs_perag_t *pag; - xfs_agnumber_t startag; - int tryagain; - - tryagain = isaligned = 0; - args.tp = ap->tp; - args.mp = mp; - args.fsbno = ap->rval; - args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks); - blen = 0; - if (nullfb) { + tryagain = isaligned = 0; + args.tp = ap->tp; + args.mp = mp; + args.fsbno = ap->rval; + args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks); + args.firstblock = ap->firstblock; + blen = 0; + if (nullfb) { + if (ap->userdata && xfs_inode_is_filestream(ap->ip)) + args.type = XFS_ALLOCTYPE_NEAR_BNO; + else args.type = XFS_ALLOCTYPE_START_BNO; - args.total = ap->total; + args.total = ap->total; + + /* + * Search for an allocation group with a single extent + * large enough for the request. + * + * If one isn't found, then adjust the minimum allocation + * size to the largest space found. + */ + startag = ag = XFS_FSB_TO_AGNO(mp, args.fsbno); + if (startag == NULLAGNUMBER) + startag = ag = 0; + notinit = 0; + down_read(&mp->m_peraglock); + while (blen < ap->alen) { + pag = &mp->m_perag[ag]; + if (!pag->pagf_init && + (error = xfs_alloc_pagf_init(mp, args.tp, + ag, XFS_ALLOC_FLAG_TRYLOCK))) { + up_read(&mp->m_peraglock); + return error; + } /* - * Find the longest available space. - * We're going to try for the whole allocation at once. + * See xfs_alloc_fix_freelist... */ - startag = ag = XFS_FSB_TO_AGNO(mp, args.fsbno); - notinit = 0; - down_read(&mp->m_peraglock); - while (blen < ap->alen) { - pag = &mp->m_perag[ag]; - if (!pag->pagf_init && - (error = xfs_alloc_pagf_init(mp, args.tp, - ag, XFS_ALLOC_FLAG_TRYLOCK))) { - up_read(&mp->m_peraglock); - return error; - } - /* - * See xfs_alloc_fix_freelist... - */ - if (pag->pagf_init) { - need = XFS_MIN_FREELIST_PAG(pag, mp); - delta = need > pag->pagf_flcount ? - need - pag->pagf_flcount : 0; - longest = (pag->pagf_longest > delta) ? - (pag->pagf_longest - delta) : - (pag->pagf_flcount > 0 || - pag->pagf_longest > 0); - if (blen < longest) - blen = longest; - } else - notinit = 1; - if (++ag == mp->m_sb.sb_agcount) - ag = 0; - if (ag == startag) + if (pag->pagf_init) { + need = XFS_MIN_FREELIST_PAG(pag, mp); + delta = need > pag->pagf_flcount ? + need - pag->pagf_flcount : 0; + longest = (pag->pagf_longest > delta) ? + (pag->pagf_longest - delta) : + (pag->pagf_flcount > 0 || + pag->pagf_longest > 0); + if (blen < longest) + blen = longest; + } else + notinit = 1; + + if (xfs_inode_is_filestream(ap->ip)) { + if (blen >= ap->alen) break; + + if (ap->userdata) { + /* + * If startag is an invalid AG, we've + * come here once before and + * xfs_filestream_new_ag picked the + * best currently available. + * + * Don't continue looping, since we + * could loop forever. + */ + if (startag == NULLAGNUMBER) + break; + + error = xfs_filestream_new_ag(ap, &ag); + if (error) { + up_read(&mp->m_peraglock); + return error; + } + + /* loop again to set 'blen'*/ + startag = NULLAGNUMBER; + continue; + } } - up_read(&mp->m_peraglock); + if (++ag == mp->m_sb.sb_agcount) + ag = 0; + if (ag == startag) + break; + } + up_read(&mp->m_peraglock); + /* + * Since the above loop did a BUF_TRYLOCK, it is + * possible that there is space for this request. + */ + if (notinit || blen < ap->minlen) + args.minlen = ap->minlen; + /* + * If the best seen length is less than the request + * length, use the best as the minimum. + */ + else if (blen < ap->alen) + args.minlen = blen; + /* + * Otherwise we've seen an extent as big as alen, + * use that as the minimum. + */ + else + args.minlen = ap->alen; + + /* + * set the failure fallback case to look in the selected + * AG as the stream may have moved. + */ + if (xfs_inode_is_filestream(ap->ip)) + ap->rval = args.fsbno = XFS_AGB_TO_FSB(mp, ag, 0); + } else if (ap->low) { + if (xfs_inode_is_filestream(ap->ip)) + args.type = XFS_ALLOCTYPE_FIRST_AG; + else + args.type = XFS_ALLOCTYPE_START_BNO; + args.total = args.minlen = ap->minlen; + } else { + args.type = XFS_ALLOCTYPE_NEAR_BNO; + args.total = ap->total; + args.minlen = ap->minlen; + } + /* apply extent size hints if obtained earlier */ + if (unlikely(align)) { + args.prod = align; + if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod))) + args.mod = (xfs_extlen_t)(args.prod - args.mod); + } else if (mp->m_sb.sb_blocksize >= PAGE_CACHE_SIZE) { + args.prod = 1; + args.mod = 0; + } else { + args.prod = PAGE_CACHE_SIZE >> mp->m_sb.sb_blocklog; + if ((args.mod = (xfs_extlen_t)(do_mod(ap->off, args.prod)))) + args.mod = (xfs_extlen_t)(args.prod - args.mod); + } + /* + * If we are not low on available data blocks, and the + * underlying logical volume manager is a stripe, and + * the file offset is zero then try to allocate data + * blocks on stripe unit boundary. + * NOTE: ap->aeof is only set if the allocation length + * is >= the stripe unit and the allocation offset is + * at the end of file. + */ + if (!ap->low && ap->aeof) { + if (!ap->off) { + args.alignment = mp->m_dalign; + atype = args.type; + isaligned = 1; /* - * Since the above loop did a BUF_TRYLOCK, it is - * possible that there is space for this request. + * Adjust for alignment */ - if (notinit || blen < ap->minlen) - args.minlen = ap->minlen; + if (blen > args.alignment && blen <= ap->alen) + args.minlen = blen - args.alignment; + args.minalignslop = 0; + } else { /* - * If the best seen length is less than the request - * length, use the best as the minimum. + * First try an exact bno allocation. + * If it fails then do a near or start bno + * allocation with alignment turned on. */ - else if (blen < ap->alen) - args.minlen = blen; + atype = args.type; + tryagain = 1; + args.type = XFS_ALLOCTYPE_THIS_BNO; + args.alignment = 1; /* - * Otherwise we've seen an extent as big as alen, - * use that as the minimum. + * Compute the minlen+alignment for the + * next case. Set slop so that the value + * of minlen+alignment+slop doesn't go up + * between the calls. */ + if (blen > mp->m_dalign && blen <= ap->alen) + nextminlen = blen - mp->m_dalign; else - args.minlen = ap->alen; - } else if (ap->low) { - args.type = XFS_ALLOCTYPE_FIRST_AG; - args.total = args.minlen = ap->minlen; - } else { - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.total = ap->total; - args.minlen = ap->minlen; - } - if (unlikely(ap->userdata && ap->ip->i_d.di_extsize && - (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE))) { - args.prod = ap->ip->i_d.di_extsize; - if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod))) - args.mod = (xfs_extlen_t)(args.prod - args.mod); - } else if (unlikely(mp->m_sb.sb_blocksize >= NBPP)) { - args.prod = 1; - args.mod = 0; - } else { - args.prod = NBPP >> mp->m_sb.sb_blocklog; - if ((args.mod = (xfs_extlen_t)(do_mod(ap->off, args.prod)))) - args.mod = (xfs_extlen_t)(args.prod - args.mod); + nextminlen = args.minlen; + if (nextminlen + mp->m_dalign > args.minlen + 1) + args.minalignslop = + nextminlen + mp->m_dalign - + args.minlen - 1; + else + args.minalignslop = 0; } + } else { + args.alignment = 1; + args.minalignslop = 0; + } + args.minleft = ap->minleft; + args.wasdel = ap->wasdel; + args.isfl = 0; + args.userdata = ap->userdata; + if ((error = xfs_alloc_vextent(&args))) + return error; + if (tryagain && args.fsbno == NULLFSBLOCK) { /* - * If we are not low on available data blocks, and the - * underlying logical volume manager is a stripe, and - * the file offset is zero then try to allocate data - * blocks on stripe unit boundary. - * NOTE: ap->aeof is only set if the allocation length - * is >= the stripe unit and the allocation offset is - * at the end of file. + * Exact allocation failed. Now try with alignment + * turned on. */ - if (!ap->low && ap->aeof) { - if (!ap->off) { - args.alignment = mp->m_dalign; - atype = args.type; - isaligned = 1; - /* - * Adjust for alignment - */ - if (blen > args.alignment && blen <= ap->alen) - args.minlen = blen - args.alignment; - args.minalignslop = 0; - } else { - /* - * First try an exact bno allocation. - * If it fails then do a near or start bno - * allocation with alignment turned on. - */ - atype = args.type; - tryagain = 1; - args.type = XFS_ALLOCTYPE_THIS_BNO; - args.alignment = 1; - /* - * Compute the minlen+alignment for the - * next case. Set slop so that the value - * of minlen+alignment+slop doesn't go up - * between the calls. - */ - if (blen > mp->m_dalign && blen <= ap->alen) - nextminlen = blen - mp->m_dalign; - else - nextminlen = args.minlen; - if (nextminlen + mp->m_dalign > args.minlen + 1) - args.minalignslop = - nextminlen + mp->m_dalign - - args.minlen - 1; - else - args.minalignslop = 0; - } - } else { - args.alignment = 1; - args.minalignslop = 0; - } - args.minleft = ap->minleft; - args.wasdel = ap->wasdel; - args.isfl = 0; - args.userdata = ap->userdata; + args.type = atype; + args.fsbno = ap->rval; + args.alignment = mp->m_dalign; + args.minlen = nextminlen; + args.minalignslop = 0; + isaligned = 1; if ((error = xfs_alloc_vextent(&args))) return error; - if (tryagain && args.fsbno == NULLFSBLOCK) { - /* - * Exact allocation failed. Now try with alignment - * turned on. - */ - args.type = atype; - args.fsbno = ap->rval; - args.alignment = mp->m_dalign; - args.minlen = nextminlen; - args.minalignslop = 0; - isaligned = 1; - if ((error = xfs_alloc_vextent(&args))) - return error; - } - if (isaligned && args.fsbno == NULLFSBLOCK) { - /* - * allocation failed, so turn off alignment and - * try again. - */ - args.type = atype; - args.fsbno = ap->rval; - args.alignment = 0; - if ((error = xfs_alloc_vextent(&args))) - return error; - } - if (args.fsbno == NULLFSBLOCK && nullfb && - args.minlen > ap->minlen) { - args.minlen = ap->minlen; - args.type = XFS_ALLOCTYPE_START_BNO; - args.fsbno = ap->rval; - if ((error = xfs_alloc_vextent(&args))) - return error; - } - if (args.fsbno == NULLFSBLOCK && nullfb) { - args.fsbno = 0; - args.type = XFS_ALLOCTYPE_FIRST_AG; - args.total = ap->minlen; - args.minleft = 0; - if ((error = xfs_alloc_vextent(&args))) - return error; - ap->low = 1; - } - if (args.fsbno != NULLFSBLOCK) { - ap->firstblock = ap->rval = args.fsbno; - ASSERT(nullfb || fb_agno == args.agno || - (ap->low && fb_agno < args.agno)); - ap->alen = args.len; - ap->ip->i_d.di_nblocks += args.len; - xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); - if (ap->wasdel) - ap->ip->i_delayed_blks -= args.len; - /* - * Adjust the disk quota also. This was reserved - * earlier. - */ - XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip, - ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT : - XFS_TRANS_DQ_BCOUNT, - (long) args.len); - } else { - ap->rval = NULLFSBLOCK; - ap->alen = 0; - } + } + if (isaligned && args.fsbno == NULLFSBLOCK) { + /* + * allocation failed, so turn off alignment and + * try again. + */ + args.type = atype; + args.fsbno = ap->rval; + args.alignment = 0; + if ((error = xfs_alloc_vextent(&args))) + return error; + } + if (args.fsbno == NULLFSBLOCK && nullfb && + args.minlen > ap->minlen) { + args.minlen = ap->minlen; + args.type = XFS_ALLOCTYPE_START_BNO; + args.fsbno = ap->rval; + if ((error = xfs_alloc_vextent(&args))) + return error; + } + if (args.fsbno == NULLFSBLOCK && nullfb) { + args.fsbno = 0; + args.type = XFS_ALLOCTYPE_FIRST_AG; + args.total = ap->minlen; + args.minleft = 0; + if ((error = xfs_alloc_vextent(&args))) + return error; + ap->low = 1; + } + if (args.fsbno != NULLFSBLOCK) { + ap->firstblock = ap->rval = args.fsbno; + ASSERT(nullfb || fb_agno == args.agno || + (ap->low && fb_agno < args.agno)); + ap->alen = args.len; + ap->ip->i_d.di_nblocks += args.len; + xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); + if (ap->wasdel) + ap->ip->i_delayed_blks -= args.len; + /* + * Adjust the disk quota also. This was reserved + * earlier. + */ + XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip, + ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT : + XFS_TRANS_DQ_BCOUNT, + (long) args.len); + } else { + ap->rval = NULLFSBLOCK; + ap->alen = 0; } return 0; -#undef ISVALID +} + +/* + * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. + * It figures out where to ask the underlying allocator to put the new extent. + */ +STATIC int +xfs_bmap_alloc( + xfs_bmalloca_t *ap) /* bmap alloc argument struct */ +{ + if (XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata) + return xfs_bmap_rtalloc(ap); + return xfs_bmap_btalloc(ap); } /* * Transform a btree format file with only one leaf node, where the * extents list will fit in the inode, into an extents format file. - * Since the extent list is already in-core, all we have to do is + * Since the file extents are already in-core, all we have to do is * give up the space for the btree root and pitch the leaf block. */ STATIC int /* error */ @@ -2415,7 +2831,7 @@ xfs_bmap_btree_to_extents( int error; /* error return value */ xfs_ifork_t *ifp; /* inode fork data */ xfs_mount_t *mp; /* mount point structure */ - xfs_bmbt_ptr_t *pp; /* ptr to block address */ + __be64 *pp; /* ptr to block address */ xfs_bmbt_block_t *rblock;/* root btree block */ ifp = XFS_IFORK_PTR(ip, whichfork); @@ -2427,12 +2843,12 @@ xfs_bmap_btree_to_extents( ASSERT(XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes) == 1); mp = ip->i_mount; pp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, ifp->if_broot_bytes); + cbno = be64_to_cpu(*pp); *logflagsp = 0; #ifdef DEBUG - if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), 1))) + if ((error = xfs_btree_check_lptr(cur, cbno, 1))) return error; #endif - cbno = INT_GET(*pp, ARCH_CONVERT); if ((error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, XFS_BMAP_BTREE_REF))) return error; @@ -2454,7 +2870,7 @@ xfs_bmap_btree_to_extents( } /* - * Called by xfs_bmapi to update extent list structure and the btree + * Called by xfs_bmapi to update file extent records and the btree * after removing space (or undoing a delayed allocation). */ STATIC int /* error */ @@ -2464,8 +2880,9 @@ xfs_bmap_del_extent( xfs_extnum_t idx, /* extent number to update/delete */ xfs_bmap_free_t *flist, /* list of extents to be freed */ xfs_btree_cur_t *cur, /* if null, not a btree */ - xfs_bmbt_irec_t *del, /* data to remove from extent list */ + xfs_bmbt_irec_t *del, /* data to remove from extents */ int *logflagsp, /* inode logging flags */ + xfs_extdelta_t *delta, /* Change made to incore extents */ int whichfork, /* data or attr fork */ int rsvd) /* OK to allocate reserved blocks */ { @@ -2475,12 +2892,9 @@ xfs_bmap_del_extent( xfs_fileoff_t del_endoff; /* first offset past del */ int delay; /* current block is delayed allocated */ int do_fx; /* free extent at end of routine */ - xfs_bmbt_rec_t *ep; /* current extent entry pointer */ + xfs_bmbt_rec_host_t *ep; /* current extent entry pointer */ int error; /* error return value */ int flags; /* inode logging flags */ -#ifdef XFS_BMAP_TRACE - static char fname[] = "xfs_bmap_del_extent"; -#endif xfs_bmbt_irec_t got; /* current extent entry */ xfs_fileoff_t got_endoff; /* first offset past got */ int i; /* temp state */ @@ -2489,7 +2903,6 @@ xfs_bmap_del_extent( xfs_filblks_t nblks; /* quota/sb block count */ xfs_bmbt_irec_t new; /* new record to be inserted */ /* REFERENCED */ - xfs_extnum_t nextents; /* number of extents in list */ uint qfield; /* quota field to update */ xfs_filblks_t temp; /* for indirect length calculations */ xfs_filblks_t temp2; /* for indirect length calculations */ @@ -2497,10 +2910,10 @@ xfs_bmap_del_extent( XFS_STATS_INC(xs_del_exlist); mp = ip->i_mount; ifp = XFS_IFORK_PTR(ip, whichfork); - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - ASSERT(idx >= 0 && idx < nextents); + ASSERT((idx >= 0) && (idx < ifp->if_bytes / + (uint)sizeof(xfs_bmbt_rec_t))); ASSERT(del->br_blockcount > 0); - ep = &ifp->if_u1.if_extents[idx]; + ep = xfs_iext_get_ext(ifp, idx); xfs_bmbt_get_all(ep, &got); ASSERT(got.br_startoff <= del->br_startoff); del_endoff = del->br_startoff + del->br_blockcount; @@ -2519,8 +2932,7 @@ xfs_bmap_del_extent( /* * Realtime allocation. Free it and record di_nblocks update. */ - if (whichfork == XFS_DATA_FORK && - (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) { + if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) { xfs_fsblock_t bno; xfs_filblks_t len; @@ -2556,7 +2968,7 @@ xfs_bmap_del_extent( got.br_startblock, got.br_blockcount, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); } da_old = da_new = 0; } else { @@ -2575,8 +2987,8 @@ xfs_bmap_del_extent( /* * Matches the whole extent. Delete the entry. */ - xfs_bmap_trace_delete(fname, "3", ip, idx, 1, whichfork); - xfs_bmap_delete_exlist(ip, idx, 1, whichfork); + XFS_BMAP_TRACE_DELETE("3", ip, idx, 1, whichfork); + xfs_iext_remove(ifp, idx, 1); ifp->if_lastex = idx; if (delay) break; @@ -2589,14 +3001,14 @@ xfs_bmap_del_extent( } if ((error = xfs_bmbt_delete(cur, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); break; case 2: /* * Deleting the first part of the extent. */ - xfs_bmap_trace_pre_update(fname, "2", ip, idx, whichfork); + XFS_BMAP_TRACE_PRE_UPDATE("2", ip, idx, whichfork); xfs_bmbt_set_startoff(ep, del_endoff); temp = got.br_blockcount - del->br_blockcount; xfs_bmbt_set_blockcount(ep, temp); @@ -2605,13 +3017,13 @@ xfs_bmap_del_extent( temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), da_old); xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); - xfs_bmap_trace_post_update(fname, "2", ip, idx, + XFS_BMAP_TRACE_POST_UPDATE("2", ip, idx, whichfork); da_new = temp; break; } xfs_bmbt_set_startblock(ep, del_endblock); - xfs_bmap_trace_post_update(fname, "2", ip, idx, whichfork); + XFS_BMAP_TRACE_POST_UPDATE("2", ip, idx, whichfork); if (!cur) { flags |= XFS_ILOG_FEXT(whichfork); break; @@ -2627,19 +3039,19 @@ xfs_bmap_del_extent( * Deleting the last part of the extent. */ temp = got.br_blockcount - del->br_blockcount; - xfs_bmap_trace_pre_update(fname, "1", ip, idx, whichfork); + XFS_BMAP_TRACE_PRE_UPDATE("1", ip, idx, whichfork); xfs_bmbt_set_blockcount(ep, temp); ifp->if_lastex = idx; if (delay) { temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), da_old); xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); - xfs_bmap_trace_post_update(fname, "1", ip, idx, + XFS_BMAP_TRACE_POST_UPDATE("1", ip, idx, whichfork); da_new = temp; break; } - xfs_bmap_trace_post_update(fname, "1", ip, idx, whichfork); + XFS_BMAP_TRACE_POST_UPDATE("1", ip, idx, whichfork); if (!cur) { flags |= XFS_ILOG_FEXT(whichfork); break; @@ -2656,7 +3068,7 @@ xfs_bmap_del_extent( * Deleting the middle of the extent. */ temp = del->br_startoff - got.br_startoff; - xfs_bmap_trace_pre_update(fname, "0", ip, idx, whichfork); + XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx, whichfork); xfs_bmbt_set_blockcount(ep, temp); new.br_startoff = del_endoff; temp2 = got_endoff - del_endoff; @@ -2693,7 +3105,7 @@ xfs_bmap_del_extent( got.br_startblock, temp, &i))) goto done; - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); /* * Update the btree record back * to the original value. @@ -2714,7 +3126,7 @@ xfs_bmap_del_extent( error = XFS_ERROR(ENOSPC); goto done; } - ASSERT(i == 1); + XFS_WANT_CORRUPTED_GOTO(i == 1, done); } else flags |= XFS_ILOG_FEXT(whichfork); XFS_IFORK_NEXT_SET(ip, whichfork, @@ -2743,10 +3155,10 @@ xfs_bmap_del_extent( } } } - xfs_bmap_trace_post_update(fname, "0", ip, idx, whichfork); - xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 1, &new, NULL, + XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx, whichfork); + XFS_BMAP_TRACE_INSERT("0", ip, idx + 1, 1, &new, NULL, whichfork); - xfs_bmap_insert_exlist(ip, idx + 1, 1, &new, whichfork); + xfs_iext_insert(ifp, idx + 1, 1, &new); ifp->if_lastex = idx + 1; break; } @@ -2773,8 +3185,16 @@ xfs_bmap_del_extent( */ ASSERT(da_old >= da_new); if (da_old > da_new) - xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new), + xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int64_t)(da_old - da_new), rsvd); + if (delta) { + /* DELTA: report the original extent. */ + if (delta->xed_startoff > got.br_startoff) + delta->xed_startoff = got.br_startoff; + if (delta->xed_blockcount < got.br_startoff+got.br_blockcount) + delta->xed_blockcount = got.br_startoff + + got.br_blockcount; + } done: *logflagsp = flags; return error; @@ -2783,8 +3203,10 @@ done: /* * Remove the entry "free" from the free item list. Prev points to the * previous entry, unless "free" is the head of the list. + * + * Note: this requires user-space public scope for libxfs_iread */ -STATIC void +void xfs_bmap_del_free( xfs_bmap_free_t *flist, /* free item list header */ xfs_bmap_free_item_t *prev, /* previous item on list, if any */ @@ -2798,31 +3220,6 @@ xfs_bmap_del_free( kmem_zone_free(xfs_bmap_free_item_zone, free); } -/* - * Remove count entries from the extents array for inode "ip", starting - * at index "idx". Copies the remaining items down over the deleted ones, - * and gives back the excess memory. - */ -STATIC void -xfs_bmap_delete_exlist( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* starting delete index */ - xfs_extnum_t count, /* count of items to delete */ - int whichfork) /* data or attr fork */ -{ - xfs_bmbt_rec_t *base; /* base of extent list */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_extnum_t nextents; /* number of extents in list after */ - - ifp = XFS_IFORK_PTR(ip, whichfork); - ASSERT(ifp->if_flags & XFS_IFEXTENTS); - base = ifp->if_u1.if_extents; - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - count; - memmove(&base[idx], &base[idx + count], - (nextents - idx) * sizeof(*base)); - xfs_iext_realloc(ip, -count, whichfork); -} - /* * Convert an extents-format file into a btree-format file. * The new file will have a root block (in the inode) and a single child block. @@ -2844,13 +3241,13 @@ xfs_bmap_extents_to_btree( xfs_bmbt_rec_t *arp; /* child record pointer */ xfs_bmbt_block_t *block; /* btree root block */ xfs_btree_cur_t *cur; /* bmap btree cursor */ - xfs_bmbt_rec_t *ep; /* extent list pointer */ + xfs_bmbt_rec_host_t *ep; /* extent record pointer */ int error; /* error return value */ - xfs_extnum_t i, cnt; /* extent list index */ + xfs_extnum_t i, cnt; /* extent record index */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_bmbt_key_t *kp; /* root block key pointer */ xfs_mount_t *mp; /* mount structure */ - xfs_extnum_t nextents; /* extent list size */ + xfs_extnum_t nextents; /* number of file extents */ xfs_bmbt_ptr_t *pp; /* root block address pointer */ ifp = XFS_IFORK_PTR(ip, whichfork); @@ -2886,6 +3283,7 @@ xfs_bmap_extents_to_btree( XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); args.tp = tp; args.mp = mp; + args.firstblock = *firstblock; if (*firstblock == NULLFSBLOCK) { args.type = XFS_ALLOCTYPE_START_BNO; args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); @@ -2929,10 +3327,11 @@ xfs_bmap_extents_to_btree( ablock->bb_rightsib = cpu_to_be64(NULLDFSBNO); arp = XFS_BMAP_REC_IADDR(ablock, 1, cur); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - for (ep = ifp->if_u1.if_extents, cnt = i = 0; i < nextents; i++, ep++) { + for (cnt = i = 0; i < nextents; i++) { + ep = xfs_iext_get_ext(ifp, i); if (!ISNULLSTARTBLOCK(xfs_bmbt_get_startblock(ep))) { - arp->l0 = INT_GET(ep->l0, ARCH_CONVERT); - arp->l1 = INT_GET(ep->l1, ARCH_CONVERT); + arp->l0 = cpu_to_be64(ep->l0); + arp->l1 = cpu_to_be64(ep->l1); arp++; cnt++; } } @@ -2943,9 +3342,9 @@ xfs_bmap_extents_to_btree( */ kp = XFS_BMAP_KEY_IADDR(block, 1, cur); arp = XFS_BMAP_REC_IADDR(ablock, 1, cur); - INT_SET(kp->br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(arp)); + kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp)); pp = XFS_BMAP_PTR_IADDR(block, 1, cur); - INT_SET(*pp, ARCH_CONVERT, args.fsbno); + *pp = cpu_to_be64(args.fsbno); /* * Do all this logging at the end so that * the root is at the right level. @@ -2958,38 +3357,10 @@ xfs_bmap_extents_to_btree( return 0; } -/* - * Insert new item(s) in the extent list for inode "ip". - * Count new items are inserted at offset idx. - */ -STATIC void -xfs_bmap_insert_exlist( - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* starting index of new items */ - xfs_extnum_t count, /* number of inserted items */ - xfs_bmbt_irec_t *new, /* items to insert */ - int whichfork) /* data or attr fork */ -{ - xfs_bmbt_rec_t *base; /* extent list base */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_extnum_t nextents; /* extent list size */ - xfs_extnum_t to; /* extent list index */ - - ifp = XFS_IFORK_PTR(ip, whichfork); - ASSERT(ifp->if_flags & XFS_IFEXTENTS); - xfs_iext_realloc(ip, count, whichfork); - base = ifp->if_u1.if_extents; - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - memmove(&base[idx + count], &base[idx], - (nextents - (idx + count)) * sizeof(*base)); - for (to = idx; to < idx + count; to++, new++) - xfs_bmbt_set_all(&base[to], new); -} - /* * Helper routine to reset inode di_forkoff field when switching - * attributes from local to extents. This can increase the space - * we have available for inline extents. + * attribute fork from local to extent format - we reset it where + * possible to make space available for inline data fork extents. */ STATIC void xfs_bmap_forkoff_reset( @@ -3000,6 +3371,7 @@ xfs_bmap_forkoff_reset( if (whichfork == XFS_ATTR_FORK && (ip->i_d.di_format != XFS_DINODE_FMT_DEV) && (ip->i_d.di_format != XFS_DINODE_FMT_UUID) && + (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) && ((mp->m_attroffset >> 3) > ip->i_d.di_forkoff)) { ip->i_d.di_forkoff = mp->m_attroffset >> 3; ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) / @@ -3026,9 +3398,6 @@ xfs_bmap_local_to_extents( { int error; /* error return value */ int flags; /* logging flags returned */ -#ifdef XFS_BMAP_TRACE - static char fname[] = "xfs_bmap_local_to_extents"; -#endif xfs_ifork_t *ifp; /* inode fork pointer */ /* @@ -3043,12 +3412,14 @@ xfs_bmap_local_to_extents( error = 0; if (ifp->if_bytes) { xfs_alloc_arg_t args; /* allocation arguments */ - xfs_buf_t *bp; /* buffer for extent list block */ - xfs_bmbt_rec_t *ep; /* extent list pointer */ + xfs_buf_t *bp; /* buffer for extent block */ + xfs_bmbt_rec_host_t *ep;/* extent record pointer */ args.tp = tp; args.mp = ip->i_mount; - ASSERT(ifp->if_flags & XFS_IFINLINE); + args.firstblock = *firstblock; + ASSERT((ifp->if_flags & + (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE); /* * Allocate a block. We know we need only one, since the * file currently fits in an inode. @@ -3078,10 +3449,10 @@ xfs_bmap_local_to_extents( xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1); xfs_bmap_forkoff_reset(args.mp, ip, whichfork); xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); - xfs_iext_realloc(ip, 1, whichfork); - ep = ifp->if_u1.if_extents; + xfs_iext_add(ifp, 0, 1); + ep = xfs_iext_get_ext(ifp, 0); xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM); - xfs_bmap_trace_post_update(fname, "new", ip, 0, whichfork); + XFS_BMAP_TRACE_POST_UPDATE("new", ip, 0, whichfork); XFS_IFORK_NEXT_SET(ip, whichfork, 1); ip->i_d.di_nblocks = 1; XFS_TRANS_MOD_DQUOT_BYINO(args.mp, tp, ip, @@ -3100,110 +3471,54 @@ done: return error; } -xfs_bmbt_rec_t * /* pointer to found extent entry */ -xfs_bmap_do_search_extents( - xfs_bmbt_rec_t *base, /* base of extent list */ - xfs_extnum_t lastx, /* last extent index used */ - xfs_extnum_t nextents, /* extent list size */ +/* + * Search the extent records for the entry containing block bno. + * If bno lies in a hole, point to the next entry. If bno lies + * past eof, *eofp will be set, and *prevp will contain the last + * entry (null if none). Else, *lastxp will be set to the index + * of the found entry; *gotp will contain the entry. + */ +xfs_bmbt_rec_host_t * /* pointer to found extent entry */ +xfs_bmap_search_multi_extents( + xfs_ifork_t *ifp, /* inode fork pointer */ xfs_fileoff_t bno, /* block number searched for */ int *eofp, /* out: end of file found */ xfs_extnum_t *lastxp, /* out: last extent index */ xfs_bmbt_irec_t *gotp, /* out: extent entry found */ xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ { - xfs_bmbt_rec_t *ep; /* extent list entry pointer */ - xfs_bmbt_irec_t got; /* extent list entry, decoded */ - int high; /* high index of binary search */ - int low; /* low index of binary search */ + xfs_bmbt_rec_host_t *ep; /* extent record pointer */ + xfs_extnum_t lastx; /* last extent index */ /* * Initialize the extent entry structure to catch access to * uninitialized br_startblock field. */ - got.br_startoff = 0xffa5a5a5a5a5a5a5LL; - got.br_blockcount = 0xa55a5a5a5a5a5a5aLL; - got.br_state = XFS_EXT_INVALID; - + gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL; + gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL; + gotp->br_state = XFS_EXT_INVALID; #if XFS_BIG_BLKNOS - got.br_startblock = 0xffffa5a5a5a5a5a5LL; + gotp->br_startblock = 0xffffa5a5a5a5a5a5LL; #else - got.br_startblock = 0xffffa5a5; + gotp->br_startblock = 0xffffa5a5; #endif - - if (lastx != NULLEXTNUM && lastx < nextents) - ep = base + lastx; - else - ep = NULL; prevp->br_startoff = NULLFILEOFF; - if (ep && bno >= (got.br_startoff = xfs_bmbt_get_startoff(ep)) && - bno < got.br_startoff + - (got.br_blockcount = xfs_bmbt_get_blockcount(ep))) - *eofp = 0; - else if (ep && lastx < nextents - 1 && - bno >= (got.br_startoff = xfs_bmbt_get_startoff(ep + 1)) && - bno < got.br_startoff + - (got.br_blockcount = xfs_bmbt_get_blockcount(ep + 1))) { - lastx++; - ep++; - *eofp = 0; - } else if (nextents == 0) - *eofp = 1; - else if (bno == 0 && - (got.br_startoff = xfs_bmbt_get_startoff(base)) == 0) { - ep = base; - lastx = 0; - got.br_blockcount = xfs_bmbt_get_blockcount(ep); + + ep = xfs_iext_bno_to_ext(ifp, bno, &lastx); + if (lastx > 0) { + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp); + } + if (lastx < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) { + xfs_bmbt_get_all(ep, gotp); *eofp = 0; } else { - /* binary search the extents array */ - low = 0; - high = nextents - 1; - while (low <= high) { - XFS_STATS_INC(xs_cmp_exlist); - lastx = (low + high) >> 1; - ep = base + lastx; - got.br_startoff = xfs_bmbt_get_startoff(ep); - got.br_blockcount = xfs_bmbt_get_blockcount(ep); - if (bno < got.br_startoff) - high = lastx - 1; - else if (bno >= got.br_startoff + got.br_blockcount) - low = lastx + 1; - else { - got.br_startblock = xfs_bmbt_get_startblock(ep); - got.br_state = xfs_bmbt_get_state(ep); - *eofp = 0; - *lastxp = lastx; - *gotp = got; - return ep; - } - } - if (bno >= got.br_startoff + got.br_blockcount) { - lastx++; - if (lastx == nextents) { - *eofp = 1; - got.br_startblock = xfs_bmbt_get_startblock(ep); - got.br_state = xfs_bmbt_get_state(ep); - *prevp = got; - ep = NULL; - } else { - *eofp = 0; - xfs_bmbt_get_all(ep, prevp); - ep++; - got.br_startoff = xfs_bmbt_get_startoff(ep); - got.br_blockcount = xfs_bmbt_get_blockcount(ep); - } - } else { - *eofp = 0; - if (ep > base) - xfs_bmbt_get_all(ep - 1, prevp); + if (lastx > 0) { + *gotp = *prevp; } - } - if (ep) { - got.br_startblock = xfs_bmbt_get_startblock(ep); - got.br_state = xfs_bmbt_get_state(ep); + *eofp = 1; + ep = NULL; } *lastxp = lastx; - *gotp = got; return ep; } @@ -3213,44 +3528,43 @@ xfs_bmap_do_search_extents( * *eofp will be set, and *prevp will contain the last entry (null if none). * Else, *lastxp will be set to the index of the found * entry; *gotp will contain the entry. + * + * Note this is public in libxfs for xfs_repair's phase6. */ -STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */ +xfs_bmbt_rec_host_t * /* pointer to found extent entry */ xfs_bmap_search_extents( xfs_inode_t *ip, /* incore inode pointer */ xfs_fileoff_t bno, /* block number searched for */ - int whichfork, /* data or attr fork */ + int fork, /* data or attr fork */ int *eofp, /* out: end of file found */ xfs_extnum_t *lastxp, /* out: last extent index */ xfs_bmbt_irec_t *gotp, /* out: extent entry found */ xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ { xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_bmbt_rec_t *base; /* base of extent list */ - xfs_extnum_t lastx; /* last extent index used */ - xfs_extnum_t nextents; /* extent list size */ - xfs_bmbt_rec_t *ep; /* extent list entry pointer */ - int rt; /* realtime flag */ + xfs_bmbt_rec_host_t *ep; /* extent record pointer */ XFS_STATS_INC(xs_look_exlist); - ifp = XFS_IFORK_PTR(ip, whichfork); - lastx = ifp->if_lastex; - nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - base = &ifp->if_u1.if_extents[0]; + ifp = XFS_IFORK_PTR(ip, fork); - ep = xfs_bmap_do_search_extents(base, lastx, nextents, bno, eofp, - lastxp, gotp, prevp); - rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); - if (unlikely(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM))) { - cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld " - "start_block : %llx start_off : %llx blkcnt : %llx " - "extent-state : %x \n", - (ip->i_mount)->m_fsname, (long long)ip->i_ino, + ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp); + + if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) && + !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) { + xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount, + "Access to block zero in inode %llu " + "start_block: %llx start_off: %llx " + "blkcnt: %llx extent-state: %x lastx: %x\n", + (unsigned long long)ip->i_ino, (unsigned long long)gotp->br_startblock, (unsigned long long)gotp->br_startoff, (unsigned long long)gotp->br_blockcount, - gotp->br_state); - } - return ep; + gotp->br_state, *lastxp); + *lastxp = NULLEXTNUM; + *eofp = 1; + return NULL; + } + return ep; } /* @@ -3295,10 +3609,9 @@ xfs_bmap_add_attrfork( int rsvd) /* xact may use reserved blks */ { xfs_fsblock_t firstblock; /* 1st block/ag allocated */ - xfs_bmap_free_t flist; /* freed extent list */ + xfs_bmap_free_t flist; /* freed extent records */ xfs_mount_t *mp; /* mount structure */ xfs_trans_t *tp; /* transaction pointer */ - unsigned long s; /* spinlock spl value */ int blks; /* space reservation */ int version = 1; /* superblock attr version */ int committed; /* xaction was committed */ @@ -3337,7 +3650,7 @@ xfs_bmap_add_attrfork( ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; } ASSERT(ip->i_d.di_anextents == 0); - VN_HOLD(XFS_ITOV(ip)); + IHOLD(ip); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); switch (ip->i_d.di_format) { @@ -3353,7 +3666,7 @@ xfs_bmap_add_attrfork( ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size); if (!ip->i_d.di_forkoff) ip->i_d.di_forkoff = mp->m_attroffset >> 3; - else if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR)) + else if (mp->m_flags & XFS_MOUNT_ATTR2) version = 2; break; default: @@ -3391,35 +3704,34 @@ xfs_bmap_add_attrfork( xfs_trans_log_inode(tp, ip, logflags); if (error) goto error2; - if (!XFS_SB_VERSION_HASATTR(&mp->m_sb) || - (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2)) { + if (!xfs_sb_version_hasattr(&mp->m_sb) || + (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) { __int64_t sbfields = 0; - s = XFS_SB_LOCK(mp); - if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) { - XFS_SB_VERSION_ADDATTR(&mp->m_sb); + spin_lock(&mp->m_sb_lock); + if (!xfs_sb_version_hasattr(&mp->m_sb)) { + xfs_sb_version_addattr(&mp->m_sb); sbfields |= XFS_SB_VERSIONNUM; } - if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2) { - XFS_SB_VERSION_ADDATTR2(&mp->m_sb); + if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) { + xfs_sb_version_addattr2(&mp->m_sb); sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); } if (sbfields) { - XFS_SB_UNLOCK(mp, s); + spin_unlock(&mp->m_sb_lock); xfs_mod_sb(tp, sbfields); } else - XFS_SB_UNLOCK(mp, s); + spin_unlock(&mp->m_sb_lock); } - if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) + if ((error = xfs_bmap_finish(&tp, &flist, &committed))) goto error2; - error = xfs_trans_commit(tp, XFS_TRANS_PERM_LOG_RES, NULL); + error = xfs_trans_commit(tp, XFS_TRANS_PERM_LOG_RES); ASSERT(ip->i_df.if_ext_max == XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t)); return error; error2: xfs_bmap_cancel(&flist); error1: - ASSERT(ismrlocked(&ip->i_lock,MR_UPDATE)); xfs_iunlock(ip, XFS_ILOCK_EXCL); error0: xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); @@ -3498,16 +3810,21 @@ xfs_bmap_compute_maxlevels( * number of leaf entries, is controlled by the type of di_nextents * (a signed 32-bit number, xfs_extnum_t), or by di_anextents * (a signed 16-bit number, xfs_aextnum_t). + * + * Note that we can no longer assume that if we are in ATTR1 that + * the fork offset of all the inodes will be (m_attroffset >> 3) + * because we could have mounted with ATTR2 and then mounted back + * with ATTR1, keeping the di_forkoff's fixed but probably at + * various positions. Therefore, for both ATTR1 and ATTR2 + * we have to assume the worst case scenario of a minimum size + * available. */ if (whichfork == XFS_DATA_FORK) { maxleafents = MAXEXTNUM; - sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ? - mp->m_attroffset : XFS_BMDR_SPACE_CALC(MINDBTPTRS); + sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS); } else { maxleafents = MAXAEXTNUM; - sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ? - mp->m_sb.sb_inodesize - mp->m_attroffset : - XFS_BMDR_SPACE_CALC(MINABTPTRS); + sz = XFS_BMDR_SPACE_CALC(MINABTPTRS); } maxrootrecs = (int)XFS_BTREE_BLOCK_MAXRECS(sz, xfs_bmdr, 0); minleafrecs = mp->m_bmap_dmnr[0]; @@ -3557,9 +3874,8 @@ xfs_bmap_first_unused( xfs_fileoff_t *first_unused, /* unused block */ int whichfork) /* data or attr fork */ { - xfs_bmbt_rec_t *base; /* base of extent array */ - xfs_bmbt_rec_t *ep; /* pointer to an extent entry */ int error; /* error return value */ + int idx; /* extent record index */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_fileoff_t lastaddr; /* last block number seen */ xfs_fileoff_t lowest; /* lowest useful block */ @@ -3580,10 +3896,8 @@ xfs_bmap_first_unused( return error; lowest = *first_unused; nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - base = &ifp->if_u1.if_extents[0]; - for (lastaddr = 0, max = lowest, ep = base; - ep < &base[nextents]; - ep++) { + for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) { + xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx); off = xfs_bmbt_get_startoff(ep); /* * See if the hole before this extent will work. @@ -3602,8 +3916,8 @@ xfs_bmap_first_unused( /* * Returns the file-relative block number of the last block + 1 before * last_block (input value) in the file. - * This is not based on i_size, it is based on the extent list. - * Returns 0 for local files, as they do not have an extent list. + * This is not based on i_size, it is based on the extent records. + * Returns 0 for local files, as they do not have extent records. */ int /* error */ xfs_bmap_last_before( @@ -3614,7 +3928,7 @@ xfs_bmap_last_before( { xfs_fileoff_t bno; /* input file offset */ int eof; /* hit end of file */ - xfs_bmbt_rec_t *ep; /* pointer to last extent */ + xfs_bmbt_rec_host_t *ep; /* pointer to last extent */ int error; /* error return value */ xfs_bmbt_irec_t got; /* current extent value */ xfs_ifork_t *ifp; /* inode fork pointer */ @@ -3650,8 +3964,8 @@ xfs_bmap_last_before( /* * Returns the file-relative block number of the first block past eof in - * the file. This is not based on i_size, it is based on the extent list. - * Returns 0 for local files, as they do not have an extent list. + * the file. This is not based on i_size, it is based on the extent records. + * Returns 0 for local files, as they do not have extent records. */ int /* error */ xfs_bmap_last_offset( @@ -3660,8 +3974,7 @@ xfs_bmap_last_offset( xfs_fileoff_t *last_block, /* last block */ int whichfork) /* data or attr fork */ { - xfs_bmbt_rec_t *base; /* base of extent array */ - xfs_bmbt_rec_t *ep; /* pointer to last extent */ + xfs_bmbt_rec_host_t *ep; /* pointer to last extent */ int error; /* error return value */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_extnum_t nextents; /* number of extent entries */ @@ -3683,9 +3996,7 @@ xfs_bmap_last_offset( *last_block = 0; return 0; } - base = &ifp->if_u1.if_extents[0]; - ASSERT(base != NULL); - ep = &base[nextents - 1]; + ep = xfs_iext_get_ext(ifp, nextents - 1); *last_block = xfs_bmbt_get_startoff(ep) + xfs_bmbt_get_blockcount(ep); return 0; } @@ -3700,14 +4011,17 @@ xfs_bmap_one_block( xfs_inode_t *ip, /* incore inode */ int whichfork) /* data or attr fork */ { - xfs_bmbt_rec_t *ep; /* ptr to fork's extent */ + xfs_bmbt_rec_host_t *ep; /* ptr to fork's extent */ xfs_ifork_t *ifp; /* inode fork pointer */ int rval; /* return value */ xfs_bmbt_irec_t s; /* internal version of extent */ #ifndef DEBUG - if (whichfork == XFS_DATA_FORK) - return ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize; + if (whichfork == XFS_DATA_FORK) { + return ((ip->i_d.di_mode & S_IFMT) == S_IFREG) ? + (ip->i_size == ip->i_mount->m_sb.sb_blocksize) : + (ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize); + } #endif /* !DEBUG */ if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1) return 0; @@ -3715,11 +4029,11 @@ xfs_bmap_one_block( return 0; ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT(ifp->if_flags & XFS_IFEXTENTS); - ep = ifp->if_u1.if_extents; + ep = xfs_iext_get_ext(ifp, 0); xfs_bmbt_get_all(ep, &s); rval = s.br_startoff == 0 && s.br_blockcount == 1; if (rval && whichfork == XFS_DATA_FORK) - ASSERT(ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize); + ASSERT(ip->i_size == ip->i_mount->m_sb.sb_blocksize); return rval; } @@ -3740,17 +4054,13 @@ xfs_bmap_read_extents( xfs_buf_t *bp; /* buffer for "block" */ int error; /* error return value */ xfs_exntfmt_t exntf; /* XFS_EXTFMT_NOSTATE, if checking */ -#ifdef XFS_BMAP_TRACE - static char fname[] = "xfs_bmap_read_extents"; -#endif xfs_extnum_t i, j; /* index into the extents list */ xfs_ifork_t *ifp; /* fork structure */ int level; /* btree level, for checking */ xfs_mount_t *mp; /* file system mount structure */ - xfs_bmbt_ptr_t *pp; /* pointer to block address */ + __be64 *pp; /* pointer to block address */ /* REFERENCED */ xfs_extnum_t room; /* number of entries there's room for */ - xfs_bmbt_rec_t *trp; /* target record pointer */ bno = NULLFSBLOCK; mp = ip->i_mount; @@ -3764,10 +4074,10 @@ xfs_bmap_read_extents( level = be16_to_cpu(block->bb_level); ASSERT(level > 0); pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes); - ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO); - ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount); - ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks); - bno = INT_GET(*pp, ARCH_CONVERT); + bno = be64_to_cpu(*pp); + ASSERT(bno != NULLDFSBNO); + ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); + ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); /* * Go down the tree until leaf level is reached, following the first * pointer (leftmost) at each level. @@ -3782,27 +4092,24 @@ xfs_bmap_read_extents( error0); if (level == 0) break; - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, - 1, mp->m_bmap_dmxr[1]); - XFS_WANT_CORRUPTED_GOTO( - XFS_FSB_SANITY_CHECK(mp, INT_GET(*pp, ARCH_CONVERT)), - error0); - bno = INT_GET(*pp, ARCH_CONVERT); + pp = XFS_BTREE_PTR_ADDR(xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]); + bno = be64_to_cpu(*pp); + XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0); xfs_trans_brelse(tp, bp); } /* * Here with bp and block set to the leftmost leaf node in the tree. */ - room = ifp->if_bytes / (uint)sizeof(*trp); - trp = ifp->if_u1.if_extents; + room = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); i = 0; /* - * Loop over all leaf nodes. Copy information to the extent list. + * Loop over all leaf nodes. Copy information to the extent records. */ for (;;) { - xfs_bmbt_rec_t *frp, *temp; + xfs_bmbt_rec_t *frp; xfs_fsblock_t nextbno; xfs_extnum_t num_recs; + xfs_extnum_t start; num_recs = be16_to_cpu(block->bb_numrecs); @@ -3826,14 +4133,14 @@ xfs_bmap_read_extents( if (nextbno != NULLFSBLOCK) xfs_btree_reada_bufl(mp, nextbno, 1); /* - * Copy records into the extent list. + * Copy records into the extent records. */ - frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, - block, 1, mp->m_bmap_dmxr[0]); - temp = trp; - for (j = 0; j < num_recs; j++, frp++, trp++) { - trp->l0 = INT_GET(frp->l0, ARCH_CONVERT); - trp->l1 = INT_GET(frp->l1, ARCH_CONVERT); + frp = XFS_BTREE_REC_ADDR(xfs_bmbt, block, 1); + start = i; + for (j = 0; j < num_recs; j++, i++, frp++) { + xfs_bmbt_rec_host_t *trp = xfs_iext_get_ext(ifp, i); + trp->l0 = be64_to_cpu(frp->l0); + trp->l1 = be64_to_cpu(frp->l1); } if (exntf == XFS_EXTFMT_NOSTATE) { /* @@ -3841,14 +4148,14 @@ xfs_bmap_read_extents( * any "older" data bmap btree records for a * set bit in the "extent flag" position. */ - if (unlikely(xfs_check_nostate_extents(temp, num_recs))) { + if (unlikely(xfs_check_nostate_extents(ifp, + start, num_recs))) { XFS_ERROR_REPORT("xfs_bmap_read_extents(2)", XFS_ERRLEVEL_LOW, ip->i_mount); goto error0; } } - i += num_recs; xfs_trans_brelse(tp, bp); bno = nextbno; /* @@ -3861,9 +4168,9 @@ xfs_bmap_read_extents( return error; block = XFS_BUF_TO_BMBT_BLOCK(bp); } - ASSERT(i == ifp->if_bytes / (uint)sizeof(*trp)); + ASSERT(i == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))); ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork)); - xfs_bmap_trace_exlist(fname, ip, i, whichfork); + XFS_BMAP_TRACE_EXLIST(ip, i, whichfork); return 0; error0: xfs_trans_brelse(tp, bp); @@ -3895,7 +4202,8 @@ xfs_bmapi( xfs_extlen_t total, /* total blocks needed */ xfs_bmbt_irec_t *mval, /* output: map values */ int *nmap, /* i/o: mval size/count */ - xfs_bmap_free_t *flist) /* i/o: list extents to free */ + xfs_bmap_free_t *flist, /* i/o: list extents to free */ + xfs_extdelta_t *delta) /* o: change made to incore extents */ { xfs_fsblock_t abno; /* allocated block number */ xfs_extlen_t alen; /* allocated extent length */ @@ -3903,14 +4211,10 @@ xfs_bmapi( xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */ xfs_btree_cur_t *cur; /* bmap btree cursor */ xfs_fileoff_t end; /* end of mapped file region */ - int eof; /* we've hit the end of extent list */ - char contig; /* allocation must be one extent */ - char delay; /* this request is for delayed alloc */ - char exact; /* don't do all of wasdelayed extent */ - char convert; /* unwritten extent I/O completion */ - xfs_bmbt_rec_t *ep; /* extent list entry pointer */ + int eof; /* we've hit the end of extents */ + xfs_bmbt_rec_host_t *ep; /* extent record pointer */ int error; /* error return */ - xfs_bmbt_irec_t got; /* current extent list record */ + xfs_bmbt_irec_t got; /* current file extent record */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_extlen_t indlen; /* indirect blocks length */ xfs_extnum_t lastx; /* last useful extent number */ @@ -3922,17 +4226,13 @@ xfs_bmapi( int nallocs; /* number of extents alloc\'d */ xfs_extnum_t nextents; /* number of extents in file */ xfs_fileoff_t obno; /* old block number (offset) */ - xfs_bmbt_irec_t prev; /* previous extent list record */ + xfs_bmbt_irec_t prev; /* previous file extent record */ int tmp_logflags; /* temp flags holder */ int whichfork; /* data or attr fork */ char inhole; /* current location is hole in file */ - char stateless; /* ignore state flag set */ - char trim; /* output trimmed to match range */ - char userdata; /* allocating non-metadata */ char wasdelay; /* old extent was delayed */ char wr; /* this is a write request */ char rt; /* this is a realtime file */ - char rsvd; /* OK to allocate reserved blocks */ #ifdef DEBUG xfs_fileoff_t orig_bno; /* original block number value */ int orig_flags; /* original flags arg value */ @@ -3969,15 +4269,8 @@ xfs_bmapi( XFS_STATS_INC(xs_blk_mapw); else XFS_STATS_INC(xs_blk_mapr); - delay = (flags & XFS_BMAPI_DELAY) != 0; - trim = (flags & XFS_BMAPI_ENTIRE) == 0; - userdata = (flags & XFS_BMAPI_METADATA) == 0; - convert = (flags & XFS_BMAPI_CONVERT) != 0; - exact = (flags & XFS_BMAPI_EXACT) != 0; - rsvd = (flags & XFS_BMAPI_RSVBLOCKS) != 0; - contig = (flags & XFS_BMAPI_CONTIG) != 0; /* - * stateless is used to combine extents which + * IGSTATE flag is used to combine extents which * differ only due to the state of the extents. * This technique is used from xfs_getbmap() * when the caller does not wish to see the @@ -3993,10 +4286,9 @@ xfs_bmapi( * xfs_strat_comp(), where the xfs_bmapi() call * is transactioned, and the extents combined. */ - stateless = (flags & XFS_BMAPI_IGSTATE) != 0; - if (stateless && wr) /* if writing unwritten space, no */ - wr = 0; /* allocations are allowed */ - ASSERT(wr || !delay); + if ((flags & XFS_BMAPI_IGSTATE) && wr) /* if writing unwritten space */ + wr = 0; /* no allocations are allowed */ + ASSERT(wr || !(flags & XFS_BMAPI_DELAY)); logflags = 0; nallocs = 0; cur = NULL; @@ -4023,6 +4315,10 @@ xfs_bmapi( end = bno + len; obno = bno; bma.ip = NULL; + if (delta) { + delta->xed_startoff = NULLFILEOFF; + delta->xed_blockcount = 0; + } while (bno < end && n < *nmap) { /* * Reading past eof, act as though there's a hole @@ -4031,7 +4327,7 @@ xfs_bmapi( if (eof && !wr) got.br_startoff = end; inhole = eof || got.br_startoff > bno; - wasdelay = wr && !inhole && !delay && + wasdelay = wr && !inhole && !(flags & XFS_BMAPI_DELAY) && ISNULLSTARTBLOCK(got.br_startblock); /* * First, deal with the hole before the allocated space @@ -4043,11 +4339,11 @@ xfs_bmapi( * allocate the stuff asked for in this bmap call * but that wouldn't be as good. */ - if (wasdelay && !exact) { + if (wasdelay && !(flags & XFS_BMAPI_EXACT)) { alen = (xfs_extlen_t)got.br_blockcount; aoff = got.br_startoff; if (lastx != NULLEXTNUM && lastx) { - ep = &ifp->if_u1.if_extents[lastx - 1]; + ep = xfs_iext_get_ext(ifp, lastx - 1); xfs_bmbt_get_all(ep, &prev); } } else if (wasdelay) { @@ -4065,21 +4361,18 @@ xfs_bmapi( got.br_startoff - bno); aoff = bno; } - minlen = contig ? alen : 1; - if (delay) { + minlen = (flags & XFS_BMAPI_CONTIG) ? alen : 1; + if (flags & XFS_BMAPI_DELAY) { xfs_extlen_t extsz; /* Figure out the extent size, adjust alen */ - if (rt) { - if (!(extsz = ip->i_d.di_extsize)) - extsz = mp->m_sb.sb_rextsize; - } else { - extsz = ip->i_d.di_extsize; - } + extsz = xfs_get_extsz_hint(ip); if (extsz) { error = xfs_bmap_extsize_align(mp, &got, &prev, extsz, - rt, eof, delay, convert, + rt, eof, + flags&XFS_BMAPI_DELAY, + flags&XFS_BMAPI_CONVERT, &aoff, &alen); ASSERT(!error); } @@ -4090,18 +4383,17 @@ xfs_bmapi( /* * Make a transaction-less quota reservation for * delayed allocation blocks. This number gets - * adjusted later. - * We return EDQUOT if we haven't allocated - * blks already inside this loop; + * adjusted later. We return if we haven't + * allocated blocks already inside this loop. */ - if (XFS_TRANS_RESERVE_QUOTA_NBLKS( + if ((error = XFS_TRANS_RESERVE_QUOTA_NBLKS( mp, NULL, ip, (long)alen, 0, rt ? XFS_QMOPT_RES_RTBLKS : - XFS_QMOPT_RES_REGBLKS)) { + XFS_QMOPT_RES_REGBLKS))) { if (n == 0) { *nmap = 0; ASSERT(cur == NULL); - return XFS_ERROR(EDQUOT); + return error; } break; } @@ -4117,24 +4409,29 @@ xfs_bmapi( if (rt) { error = xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, - -(extsz), rsvd); + -((int64_t)extsz), (flags & + XFS_BMAPI_RSVBLOCKS)); } else { error = xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, - -(alen), rsvd); + -((int64_t)alen), (flags & + XFS_BMAPI_RSVBLOCKS)); } if (!error) { error = xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, - -(indlen), rsvd); + -((int64_t)indlen), (flags & + XFS_BMAPI_RSVBLOCKS)); if (error && rt) xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, - extsz, rsvd); + (int64_t)extsz, (flags & + XFS_BMAPI_RSVBLOCKS)); else if (error) xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, - alen, rsvd); + (int64_t)alen, (flags & + XFS_BMAPI_RSVBLOCKS)); } if (error) { @@ -4167,7 +4464,7 @@ xfs_bmapi( /* Indicate if this is the first user data * in the file, or just any user data. */ - if (userdata) { + if (!(flags & XFS_BMAPI_METADATA)) { bma.userdata = (aoff == 0) ? XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; @@ -4179,7 +4476,7 @@ xfs_bmapi( bma.firstblock = *firstblock; bma.alen = alen; bma.off = aoff; - bma.conv = convert; + bma.conv = !!(flags & XFS_BMAPI_CONVERT); bma.wasdel = wasdelay; bma.minlen = minlen; bma.low = flist->xbf_low; @@ -4190,7 +4487,8 @@ xfs_bmapi( * is larger than a stripe unit. */ if (mp->m_dalign && alen >= mp->m_dalign && - userdata && whichfork == XFS_DATA_FORK) { + (!(flags & XFS_BMAPI_METADATA)) && + (whichfork == XFS_DATA_FORK)) { if ((error = xfs_bmap_isaeof(ip, aoff, whichfork, &bma.aeof))) goto error0; @@ -4247,25 +4545,25 @@ xfs_bmapi( * A wasdelay extent has been initialized, so * shouldn't be flagged as unwritten. */ - if (wr && XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { + if (wr && xfs_sb_version_hasextflgbit(&mp->m_sb)) { if (!wasdelay && (flags & XFS_BMAPI_PREALLOC)) got.br_state = XFS_EXT_UNWRITTEN; } error = xfs_bmap_add_extent(ip, lastx, &cur, &got, - firstblock, flist, &tmp_logflags, whichfork, - rsvd); + firstblock, flist, &tmp_logflags, delta, + whichfork, (flags & XFS_BMAPI_RSVBLOCKS)); logflags |= tmp_logflags; if (error) goto error0; lastx = ifp->if_lastex; - ep = &ifp->if_u1.if_extents[lastx]; + ep = xfs_iext_get_ext(ifp, lastx); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); xfs_bmbt_get_all(ep, &got); ASSERT(got.br_startoff <= aoff); ASSERT(got.br_startoff + got.br_blockcount >= aoff + alen); #ifdef DEBUG - if (delay) { + if (flags & XFS_BMAPI_DELAY) { ASSERT(ISNULLSTARTBLOCK(got.br_startblock)); ASSERT(STARTBLOCKVAL(got.br_startblock) > 0); } @@ -4294,14 +4592,15 @@ xfs_bmapi( * Then deal with the allocated space we found. */ ASSERT(ep != NULL); - if (trim && (got.br_startoff + got.br_blockcount > obno)) { + if (!(flags & XFS_BMAPI_ENTIRE) && + (got.br_startoff + got.br_blockcount > obno)) { if (obno > bno) bno = obno; ASSERT((bno >= obno) || (n == 0)); ASSERT(bno < end); mval->br_startoff = bno; if (ISNULLSTARTBLOCK(got.br_startblock)) { - ASSERT(!wr || delay); + ASSERT(!wr || (flags & XFS_BMAPI_DELAY)); mval->br_startblock = DELAYSTARTBLOCK; } else mval->br_startblock = @@ -4323,7 +4622,7 @@ xfs_bmapi( } else { *mval = got; if (ISNULLSTARTBLOCK(mval->br_startblock)) { - ASSERT(!wr || delay); + ASSERT(!wr || (flags & XFS_BMAPI_DELAY)); mval->br_startblock = DELAYSTARTBLOCK; } } @@ -4348,13 +4647,13 @@ xfs_bmapi( } mval->br_state = XFS_EXT_NORM; error = xfs_bmap_add_extent(ip, lastx, &cur, mval, - firstblock, flist, &tmp_logflags, whichfork, - rsvd); + firstblock, flist, &tmp_logflags, delta, + whichfork, (flags & XFS_BMAPI_RSVBLOCKS)); logflags |= tmp_logflags; if (error) goto error0; lastx = ifp->if_lastex; - ep = &ifp->if_u1.if_extents[lastx]; + ep = xfs_iext_get_ext(ifp, lastx); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); xfs_bmbt_get_all(ep, &got); /* @@ -4366,9 +4665,10 @@ xfs_bmapi( continue; } - ASSERT(!trim || + ASSERT((flags & XFS_BMAPI_ENTIRE) || ((mval->br_startoff + mval->br_blockcount) <= end)); - ASSERT(!trim || (mval->br_blockcount <= len) || + ASSERT((flags & XFS_BMAPI_ENTIRE) || + (mval->br_blockcount <= len) || (mval->br_startoff < obno)); bno = mval->br_startoff + mval->br_blockcount; len = end - bno; @@ -4383,7 +4683,8 @@ xfs_bmapi( mval[-1].br_startblock != HOLESTARTBLOCK && mval->br_startblock == mval[-1].br_startblock + mval[-1].br_blockcount && - (stateless || mval[-1].br_state == mval->br_state)) { + ((flags & XFS_BMAPI_IGSTATE) || + mval[-1].br_state == mval->br_state)) { ASSERT(mval->br_startoff == mval[-1].br_startoff + mval[-1].br_blockcount); mval[-1].br_blockcount += mval->br_blockcount; @@ -4410,12 +4711,11 @@ xfs_bmapi( /* * Else go on to the next record. */ - ep++; - lastx++; - if (lastx >= nextents) { + ep = xfs_iext_get_ext(ifp, ++lastx); + prev = got; + if (lastx >= nextents) eof = 1; - prev = got; - } else + else xfs_bmbt_get_all(ep, &got); } ifp->if_lastex = lastx; @@ -4437,11 +4737,18 @@ xfs_bmapi( ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max); error = 0; - + if (delta && delta->xed_startoff != NULLFILEOFF) { + /* A change was actually made. + * Note that delta->xed_blockount is an offset at this + * point and needs to be converted to a block count. + */ + ASSERT(delta->xed_blockcount > delta->xed_startoff); + delta->xed_blockcount -= delta->xed_startoff; + } error0: /* * Log everything. Do this after conversion, there's no point in - * logging the extent list if we've converted to btree format. + * logging the extent records if we've converted to btree format. */ if ((logflags & XFS_ILOG_FEXT(whichfork)) && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) @@ -4494,12 +4801,12 @@ xfs_bmapi_single( xfs_fsblock_t *fsb, /* output: mapped block */ xfs_fileoff_t bno) /* starting file offs. mapped */ { - int eof; /* we've hit the end of extent list */ + int eof; /* we've hit the end of extents */ int error; /* error return */ - xfs_bmbt_irec_t got; /* current extent list record */ + xfs_bmbt_irec_t got; /* current file extent record */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_extnum_t lastx; /* last useful extent number */ - xfs_bmbt_irec_t prev; /* previous extent list record */ + xfs_bmbt_irec_t prev; /* previous file extent record */ ifp = XFS_IFORK_PTR(ip, whichfork); if (unlikely( @@ -4549,23 +4856,25 @@ xfs_bunmapi( xfs_fsblock_t *firstblock, /* first allocated block controls a.g. for allocs */ xfs_bmap_free_t *flist, /* i/o: list extents to free */ + xfs_extdelta_t *delta, /* o: change made to incore + extents */ int *done) /* set if not done yet */ { xfs_btree_cur_t *cur; /* bmap btree cursor */ xfs_bmbt_irec_t del; /* extent being deleted */ int eof; /* is deleting at eof */ - xfs_bmbt_rec_t *ep; /* extent list entry pointer */ + xfs_bmbt_rec_host_t *ep; /* extent record pointer */ int error; /* error return value */ xfs_extnum_t extno; /* extent number in list */ - xfs_bmbt_irec_t got; /* current extent list entry */ + xfs_bmbt_irec_t got; /* current extent record */ xfs_ifork_t *ifp; /* inode fork pointer */ int isrt; /* freeing in rt area */ xfs_extnum_t lastx; /* last extent index used */ int logflags; /* transaction logging flags */ xfs_extlen_t mod; /* rt extent offset */ xfs_mount_t *mp; /* mount structure */ - xfs_extnum_t nextents; /* size of extent list */ - xfs_bmbt_irec_t prev; /* previous extent list entry */ + xfs_extnum_t nextents; /* number of file extents */ + xfs_bmbt_irec_t prev; /* previous extent record */ xfs_fileoff_t start; /* first file offset deleted */ int tmp_logflags; /* partial logging flags */ int wasdel; /* was a delayed alloc extent */ @@ -4606,12 +4915,16 @@ xfs_bunmapi( bno = start + len - 1; ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); + if (delta) { + delta->xed_startoff = NULLFILEOFF; + delta->xed_blockcount = 0; + } /* * Check to see if the given block number is past the end of the * file, back up to the last block if so... */ if (eof) { - ep = &ifp->if_u1.if_extents[--lastx]; + ep = xfs_iext_get_ext(ifp, --lastx); xfs_bmbt_get_all(ep, &got); bno = got.br_startoff + got.br_blockcount - 1; } @@ -4635,7 +4948,7 @@ xfs_bunmapi( if (got.br_startoff > bno) { if (--lastx < 0) break; - ep--; + ep = xfs_iext_get_ext(ifp, lastx); xfs_bmbt_get_all(ep, &got); } /* @@ -4672,7 +4985,7 @@ xfs_bunmapi( * get rid of part of a realtime extent. */ if (del.br_state == XFS_EXT_UNWRITTEN || - !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { + !xfs_sb_version_hasextflgbit(&mp->m_sb)) { /* * This piece is unwritten, or we're not * using unwritten extents. Skip over it. @@ -4682,7 +4995,8 @@ xfs_bunmapi( del.br_blockcount : mod; if (bno < got.br_startoff) { if (--lastx >= 0) - xfs_bmbt_get_all(--ep, &got); + xfs_bmbt_get_all(xfs_iext_get_ext( + ifp, lastx), &got); } continue; } @@ -4703,7 +5017,8 @@ xfs_bunmapi( } del.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent(ip, lastx, &cur, &del, - firstblock, flist, &logflags, XFS_DATA_FORK, 0); + firstblock, flist, &logflags, delta, + XFS_DATA_FORK, 0); if (error) goto error0; goto nodelete; @@ -4722,7 +5037,7 @@ xfs_bunmapi( } else if ((del.br_startoff == start && (del.br_state == XFS_EXT_UNWRITTEN || xfs_trans_get_block_res(tp) == 0)) || - !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { + !xfs_sb_version_hasextflgbit(&mp->m_sb)) { /* * Can't make it unwritten. There isn't * a full extent here so just skip it. @@ -4742,7 +5057,8 @@ xfs_bunmapi( * try again. */ ASSERT(lastx > 0); - xfs_bmbt_get_all(ep - 1, &prev); + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, + lastx - 1), &prev); ASSERT(prev.br_state == XFS_EXT_NORM); ASSERT(!ISNULLSTARTBLOCK(prev.br_startblock)); ASSERT(del.br_startblock == @@ -4756,7 +5072,7 @@ xfs_bunmapi( prev.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent(ip, lastx - 1, &cur, &prev, firstblock, flist, &logflags, - XFS_DATA_FORK, 0); + delta, XFS_DATA_FORK, 0); if (error) goto error0; goto nodelete; @@ -4765,7 +5081,7 @@ xfs_bunmapi( del.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent(ip, lastx, &cur, &del, firstblock, flist, &logflags, - XFS_DATA_FORK, 0); + delta, XFS_DATA_FORK, 0); if (error) goto error0; goto nodelete; @@ -4780,13 +5096,13 @@ xfs_bunmapi( rtexts = XFS_FSB_TO_B(mp, del.br_blockcount); do_div(rtexts, mp->m_sb.sb_rextsize); xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, - (int)rtexts, rsvd); + (int64_t)rtexts, rsvd); (void)XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip, -((long)del.br_blockcount), 0, XFS_QMOPT_RES_RTBLKS); } else { xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, - (int)del.br_blockcount, rsvd); + (int64_t)del.br_blockcount, rsvd); (void)XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip, -((long)del.br_blockcount), 0, XFS_QMOPT_RES_REGBLKS); @@ -4818,7 +5134,7 @@ xfs_bunmapi( goto error0; } error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del, - &tmp_logflags, whichfork, rsvd); + &tmp_logflags, delta, whichfork, rsvd); logflags |= tmp_logflags; if (error) goto error0; @@ -4829,12 +5145,12 @@ nodelete: * If not done go on to the next (previous) record. * Reset ep in case the extents array was re-alloced. */ - ep = &ifp->if_u1.if_extents[lastx]; + ep = xfs_iext_get_ext(ifp, lastx); if (bno != (xfs_fileoff_t)-1 && bno >= start) { if (lastx >= XFS_IFORK_NEXTENTS(ip, whichfork) || xfs_bmbt_get_startoff(ep) > bno) { - lastx--; - ep--; + if (--lastx >= 0) + ep = xfs_iext_get_ext(ifp, lastx); } if (lastx >= 0) xfs_bmbt_get_all(ep, &got); @@ -4875,10 +5191,18 @@ nodelete: ASSERT(ifp->if_ext_max == XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); error = 0; + if (delta && delta->xed_startoff != NULLFILEOFF) { + /* A change was actually made. + * Note that delta->xed_blockount is an offset at this + * point and needs to be converted to a block count. + */ + ASSERT(delta->xed_blockcount > delta->xed_startoff); + delta->xed_blockcount -= delta->xed_startoff; + } error0: /* * Log everything. Do this after conversion, there's no point in - * logging the extent list if we've converted to btree format. + * logging the extent records if we've converted to btree format. */ if ((logflags & XFS_ILOG_FEXT(whichfork)) && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) @@ -4909,7 +5233,7 @@ error0: * blocks at the end of the file which do not start at the previous data block, * we will try to align the new blocks at stripe unit boundaries. */ -int /* error */ +STATIC int /* error */ xfs_bmap_isaeof( xfs_inode_t *ip, /* incore inode pointer */ xfs_fileoff_t off, /* file offset in fsblocks */ @@ -4918,9 +5242,9 @@ xfs_bmap_isaeof( { int error; /* error return value */ xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_bmbt_rec_t *lastrec; /* extent list entry pointer */ - xfs_extnum_t nextents; /* size of extent list */ - xfs_bmbt_irec_t s; /* expanded extent list entry */ + xfs_bmbt_rec_host_t *lastrec; /* extent record pointer */ + xfs_extnum_t nextents; /* number of file extents */ + xfs_bmbt_irec_t s; /* expanded extent record */ ASSERT(whichfork == XFS_DATA_FORK); ifp = XFS_IFORK_PTR(ip, whichfork); @@ -4935,7 +5259,7 @@ xfs_bmap_isaeof( /* * Go to the last extent */ - lastrec = &ifp->if_u1.if_extents[nextents - 1]; + lastrec = xfs_iext_get_ext(ifp, nextents - 1); xfs_bmbt_get_all(lastrec, &s); /* * Check we are allocating in the last extent (for delayed allocations) diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c index ddf3a2fed..05644b441 100644 --- a/libxfs/xfs_bmap_btree.c +++ b/libxfs/xfs_bmap_btree.c @@ -15,9 +15,35 @@ * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #include +/* + * Prototypes for internal btree functions. + */ + + +STATIC int xfs_bmbt_killroot(xfs_btree_cur_t *); +STATIC void xfs_bmbt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int); +STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int); +STATIC int xfs_bmbt_lshift(xfs_btree_cur_t *, int, int *); +STATIC int xfs_bmbt_rshift(xfs_btree_cur_t *, int, int *); +STATIC int xfs_bmbt_split(xfs_btree_cur_t *, int, xfs_fsblock_t *, + __uint64_t *, xfs_btree_cur_t **, int *); +STATIC int xfs_bmbt_updkey(xfs_btree_cur_t *, xfs_bmbt_key_t *, int); + +#define XFS_BMBT_TRACE_ARGBI(c,b,i) +#define XFS_BMBT_TRACE_ARGBII(c,b,i,j) +#define XFS_BMBT_TRACE_ARGFFFI(c,o,b,i,j) +#define XFS_BMBT_TRACE_ARGI(c,i) +#define XFS_BMBT_TRACE_ARGIFK(c,i,f,s) +#define XFS_BMBT_TRACE_ARGIFR(c,i,f,r) +#define XFS_BMBT_TRACE_ARGIK(c,i,k) +#define XFS_BMBT_TRACE_CURSOR(c,s) + +/* + * Internal functions. + */ + /* * Delete record pointed to by cur/level. */ @@ -31,9 +57,6 @@ xfs_bmbt_delrec( xfs_fsblock_t bno; /* fs-relative block number */ xfs_buf_t *bp; /* buffer for block */ int error; /* error return value */ -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_delrec"; -#endif int i; /* loop counter */ int j; /* temp state */ xfs_bmbt_key_t key; /* bmap btree key */ @@ -65,7 +88,7 @@ xfs_bmbt_delrec( XFS_BMBT_TRACE_CURSOR(cur, ENTRY); XFS_BMBT_TRACE_ARGI(cur, level); ptr = cur->bc_ptrs[level]; - tcur = (xfs_btree_cur_t *)0; + tcur = NULL; if (ptr == 0) { XFS_BMBT_TRACE_CURSOR(cur, EXIT); *stat = 0; @@ -90,7 +113,7 @@ xfs_bmbt_delrec( pp = XFS_BMAP_PTR_IADDR(block, 1, cur); #ifdef DEBUG for (i = ptr; i < numrecs; i++) { - if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i], ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); goto error0; } @@ -99,7 +122,7 @@ xfs_bmbt_delrec( if (ptr < numrecs) { memmove(&kp[ptr - 1], &kp[ptr], (numrecs - ptr) * sizeof(*kp)); - memmove(&pp[ptr - 1], &pp[ptr], /* INT_: direct copy */ + memmove(&pp[ptr - 1], &pp[ptr], (numrecs - ptr) * sizeof(*pp)); xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs - 1); xfs_bmbt_log_keys(cur, bp, ptr, numrecs - 1); @@ -112,7 +135,8 @@ xfs_bmbt_delrec( xfs_bmbt_log_recs(cur, bp, ptr, numrecs - 1); } if (ptr == 1) { - INT_SET(key.br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(rp)); + key.br_startoff = + cpu_to_be64(xfs_bmbt_disk_get_startoff(rp)); kp = &key; } } @@ -329,7 +353,7 @@ xfs_bmbt_delrec( rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); #ifdef DEBUG for (i = 0; i < numrrecs; i++) { - if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); goto error0; } @@ -345,7 +369,7 @@ xfs_bmbt_delrec( memcpy(lrp, rrp, numrrecs * sizeof(*lrp)); xfs_bmbt_log_recs(cur, lbp, numlrecs + 1, numlrecs + numrrecs); } - be16_add(&left->bb_numrecs, numrrecs); + be16_add_cpu(&left->bb_numrecs, numrrecs); left->bb_rightsib = right->bb_rightsib; xfs_bmbt_log_block(cur, lbp, XFS_BB_RIGHTSIB | XFS_BB_NUMRECS); if (be64_to_cpu(left->bb_rightsib) != NULLDFSBNO) { @@ -406,16 +430,13 @@ xfs_bmbt_insrec( xfs_bmbt_block_t *block; /* bmap btree block */ xfs_buf_t *bp; /* buffer for block */ int error; /* error return value */ -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_insrec"; -#endif int i; /* loop index */ xfs_bmbt_key_t key; /* bmap btree key */ xfs_bmbt_key_t *kp=NULL; /* pointer to bmap btree key */ int logflags; /* inode logging flags */ xfs_fsblock_t nbno; /* new block number */ struct xfs_btree_cur *ncur; /* new btree cursor */ - xfs_bmbt_key_t nkey; /* new btree key value */ + __uint64_t startoff; /* new btree key value */ xfs_bmbt_rec_t nrec; /* new record count */ int optr; /* old key/record index */ xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */ @@ -426,9 +447,8 @@ xfs_bmbt_insrec( ASSERT(level < cur->bc_nlevels); XFS_BMBT_TRACE_CURSOR(cur, ENTRY); XFS_BMBT_TRACE_ARGIFR(cur, level, *bnop, recp); - ncur = (xfs_btree_cur_t *)0; - INT_SET(key.br_startoff, ARCH_CONVERT, - xfs_bmbt_disk_get_startoff(recp)); + ncur = NULL; + key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(recp)); optr = ptr = cur->bc_ptrs[level]; if (ptr == 0) { XFS_BMBT_TRACE_CURSOR(cur, EXIT); @@ -487,7 +507,7 @@ xfs_bmbt_insrec( optr = ptr = cur->bc_ptrs[level]; } else { if ((error = xfs_bmbt_split(cur, level, - &nbno, &nkey, &ncur, + &nbno, &startoff, &ncur, &i))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); @@ -507,7 +527,7 @@ xfs_bmbt_insrec( #endif ptr = cur->bc_ptrs[level]; xfs_bmbt_disk_set_allf(&nrec, - nkey.br_startoff, 0, 0, + startoff, 0, 0, XFS_EXT_NORM); } else { XFS_BMBT_TRACE_CURSOR(cur, @@ -525,7 +545,7 @@ xfs_bmbt_insrec( pp = XFS_BMAP_PTR_IADDR(block, 1, cur); #ifdef DEBUG for (i = numrecs; i >= ptr; i--) { - if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i - 1], ARCH_CONVERT), + if ((error = xfs_btree_check_lptr_disk(cur, pp[i - 1], level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; @@ -534,17 +554,16 @@ xfs_bmbt_insrec( #endif memmove(&kp[ptr], &kp[ptr - 1], (numrecs - ptr + 1) * sizeof(*kp)); - memmove(&pp[ptr], &pp[ptr - 1], /* INT_: direct copy */ + memmove(&pp[ptr], &pp[ptr - 1], (numrecs - ptr + 1) * sizeof(*pp)); #ifdef DEBUG - if ((error = xfs_btree_check_lptr(cur, (xfs_bmbt_ptr_t)*bnop, - level))) { + if ((error = xfs_btree_check_lptr(cur, *bnop, level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } #endif kp[ptr - 1] = key; - INT_SET(pp[ptr - 1], ARCH_CONVERT, *bnop); + pp[ptr - 1] = cpu_to_be64(*bnop); numrecs++; block->bb_numrecs = cpu_to_be16(numrecs); xfs_bmbt_log_keys(cur, bp, ptr, numrecs); @@ -594,9 +613,6 @@ xfs_bmbt_killroot( xfs_bmbt_ptr_t *cpp; #ifdef DEBUG int error; -#endif -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_killroot"; #endif int i; xfs_bmbt_key_t *kp; @@ -620,7 +636,7 @@ xfs_bmbt_killroot( /* * Give up if the root has multiple children. */ - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) != 1) { + if (be16_to_cpu(block->bb_numrecs) != 1) { XFS_BMBT_TRACE_CURSOR(cur, EXIT); return 0; } @@ -631,37 +647,37 @@ xfs_bmbt_killroot( */ cbp = cur->bc_bufs[level - 1]; cblock = XFS_BUF_TO_BMBT_BLOCK(cbp); - if (INT_GET(cblock->bb_numrecs, ARCH_CONVERT) > XFS_BMAP_BLOCK_DMAXRECS(level, cur)) { + if (be16_to_cpu(cblock->bb_numrecs) > XFS_BMAP_BLOCK_DMAXRECS(level, cur)) { XFS_BMBT_TRACE_CURSOR(cur, EXIT); return 0; } - ASSERT(INT_GET(cblock->bb_leftsib, ARCH_CONVERT) == NULLDFSBNO); - ASSERT(INT_GET(cblock->bb_rightsib, ARCH_CONVERT) == NULLDFSBNO); + ASSERT(be64_to_cpu(cblock->bb_leftsib) == NULLDFSBNO); + ASSERT(be64_to_cpu(cblock->bb_rightsib) == NULLDFSBNO); ip = cur->bc_private.b.ip; ifp = XFS_IFORK_PTR(ip, cur->bc_private.b.whichfork); ASSERT(XFS_BMAP_BLOCK_IMAXRECS(level, cur) == XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes)); - i = (int)(INT_GET(cblock->bb_numrecs, ARCH_CONVERT) - XFS_BMAP_BLOCK_IMAXRECS(level, cur)); + i = (int)(be16_to_cpu(cblock->bb_numrecs) - XFS_BMAP_BLOCK_IMAXRECS(level, cur)); if (i) { xfs_iroot_realloc(ip, i, cur->bc_private.b.whichfork); block = ifp->if_broot; } - INT_MOD(block->bb_numrecs, ARCH_CONVERT, i); - ASSERT(INT_GET(block->bb_numrecs, ARCH_CONVERT) == INT_GET(cblock->bb_numrecs, ARCH_CONVERT)); + be16_add_cpu(&block->bb_numrecs, i); + ASSERT(block->bb_numrecs == cblock->bb_numrecs); kp = XFS_BMAP_KEY_IADDR(block, 1, cur); ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur); - memcpy(kp, ckp, INT_GET(block->bb_numrecs, ARCH_CONVERT) * sizeof(*kp)); + memcpy(kp, ckp, be16_to_cpu(block->bb_numrecs) * sizeof(*kp)); pp = XFS_BMAP_PTR_IADDR(block, 1, cur); cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur); #ifdef DEBUG - for (i = 0; i < INT_GET(cblock->bb_numrecs, ARCH_CONVERT); i++) { - if ((error = xfs_btree_check_lptr(cur, INT_GET(cpp[i], ARCH_CONVERT), level - 1))) { + for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { + if ((error = xfs_btree_check_lptr_disk(cur, cpp[i], level - 1))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } } #endif - memcpy(pp, cpp, INT_GET(block->bb_numrecs, ARCH_CONVERT) * sizeof(*pp)); + memcpy(pp, cpp, be16_to_cpu(block->bb_numrecs) * sizeof(*pp)); xfs_bmap_add_free(XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(cbp)), 1, cur->bc_private.b.flist, cur->bc_mp); ip->i_d.di_nblocks--; @@ -669,7 +685,7 @@ xfs_bmbt_killroot( XFS_TRANS_DQ_BCOUNT, -1L); xfs_trans_binval(cur->bc_tp, cbp); cur->bc_bufs[level - 1] = NULL; - INT_MOD(block->bb_level, ARCH_CONVERT, -1); + be16_add_cpu(&block->bb_level, -1); xfs_trans_log_inode(cur->bc_tp, ip, XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork)); cur->bc_nlevels--; @@ -687,9 +703,6 @@ xfs_bmbt_log_keys( int kfirst, int klast) { -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_log_keys"; -#endif xfs_trans_t *tp; XFS_BMBT_TRACE_CURSOR(cur, ENTRY); @@ -726,9 +739,6 @@ xfs_bmbt_log_ptrs( int pfirst, int plast) { -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_log_ptrs"; -#endif xfs_trans_t *tp; XFS_BMBT_TRACE_CURSOR(cur, ENTRY); @@ -769,9 +779,6 @@ xfs_bmbt_lookup( xfs_daddr_t d; xfs_sfiloff_t diff; int error; /* error return value */ -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_lookup"; -#endif xfs_fsblock_t fsbno=0; int high; int i; @@ -799,7 +806,7 @@ xfs_bmbt_lookup( d = XFS_FSB_TO_DADDR(mp, fsbno); bp = cur->bc_bufs[level]; if (bp && XFS_BUF_ADDR(bp) != d) - bp = (xfs_buf_t *)0; + bp = NULL; if (!bp) { if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp, XFS_BMAP_BTREE_REF))) { @@ -837,7 +844,7 @@ xfs_bmbt_lookup( keyno = (low + high) >> 1; if (level > 0) { kkp = kkbase + keyno - 1; - startoff = INT_GET(kkp->br_startoff, ARCH_CONVERT); + startoff = be64_to_cpu(kkp->br_startoff); } else { krp = krbase + keyno - 1; startoff = xfs_bmbt_disk_get_startoff(krp); @@ -856,13 +863,13 @@ xfs_bmbt_lookup( if (diff > 0 && --keyno < 1) keyno = 1; pp = XFS_BMAP_PTR_IADDR(block, keyno, cur); + fsbno = be64_to_cpu(*pp); #ifdef DEBUG - if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr(cur, fsbno, level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } #endif - fsbno = INT_GET(*pp, ARCH_CONVERT); cur->bc_ptrs[level] = keyno; } } @@ -909,9 +916,6 @@ xfs_bmbt_lshift( int *stat) /* success/failure */ { int error; /* error return value */ -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_lshift"; -#endif #ifdef DEBUG int i; /* loop counter */ #endif @@ -980,12 +984,12 @@ xfs_bmbt_lshift( lpp = XFS_BMAP_PTR_IADDR(left, lrecs, cur); rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); #ifdef DEBUG - if ((error = xfs_btree_check_lptr(cur, INT_GET(*rpp, ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr_disk(cur, *rpp, level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } #endif - *lpp = *rpp; /* INT_: direct copy */ + *lpp = *rpp; xfs_bmbt_log_ptrs(cur, lbp, lrecs, lrecs); } else { lrp = XFS_BMAP_REC_IADDR(left, lrecs, cur); @@ -1007,7 +1011,7 @@ xfs_bmbt_lshift( if (level > 0) { #ifdef DEBUG for (i = 0; i < rrecs; i++) { - if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i + 1], ARCH_CONVERT), + if ((error = xfs_btree_check_lptr_disk(cur, rpp[i + 1], level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; @@ -1021,8 +1025,7 @@ xfs_bmbt_lshift( } else { memmove(rrp, rrp + 1, rrecs * sizeof(*rrp)); xfs_bmbt_log_recs(cur, rbp, 1, rrecs); - INT_SET(key.br_startoff, ARCH_CONVERT, - xfs_bmbt_disk_get_startoff(rrp)); + key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp)); rkp = &key; } if ((error = xfs_bmbt_updkey(cur, rkp, level + 1))) { @@ -1046,9 +1049,6 @@ xfs_bmbt_rshift( int *stat) /* success/failure */ { int error; /* error return value */ -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_rshift"; -#endif int i; /* loop counter */ xfs_bmbt_key_t key; /* bmap btree key */ xfs_buf_t *lbp; /* left buffer pointer */ @@ -1112,7 +1112,7 @@ xfs_bmbt_rshift( rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); #ifdef DEBUG for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) { - if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } @@ -1121,13 +1121,13 @@ xfs_bmbt_rshift( memmove(rkp + 1, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp)); memmove(rpp + 1, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp)); #ifdef DEBUG - if ((error = xfs_btree_check_lptr(cur, INT_GET(*lpp, ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr_disk(cur, *lpp, level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } #endif *rkp = *lkp; - *rpp = *lpp; /* INT_: direct copy */ + *rpp = *lpp; xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); } else { @@ -1136,13 +1136,12 @@ xfs_bmbt_rshift( memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); *rrp = *lrp; xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); - INT_SET(key.br_startoff, ARCH_CONVERT, - xfs_bmbt_disk_get_startoff(rrp)); + key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp)); rkp = &key; } - be16_add(&left->bb_numrecs, -1); + be16_add_cpu(&left->bb_numrecs, -1); xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS); - be16_add(&right->bb_numrecs, 1); + be16_add_cpu(&right->bb_numrecs, 1); #ifdef DEBUG if (level > 0) xfs_btree_check_key(XFS_BTNUM_BMAP, rkp, rkp + 1); @@ -1202,15 +1201,12 @@ xfs_bmbt_split( xfs_btree_cur_t *cur, int level, xfs_fsblock_t *bnop, - xfs_bmbt_key_t *keyp, + __uint64_t *startoff, xfs_btree_cur_t **curp, int *stat) /* success/failure */ { xfs_alloc_arg_t args; /* block allocation args */ int error; /* error return value */ -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_split"; -#endif int i; /* loop counter */ xfs_fsblock_t lbno; /* left sibling block number */ xfs_buf_t *lbp; /* left buffer pointer */ @@ -1227,21 +1223,35 @@ xfs_bmbt_split( xfs_bmbt_rec_t *rrp; /* right record pointer */ XFS_BMBT_TRACE_CURSOR(cur, ENTRY); - XFS_BMBT_TRACE_ARGIFK(cur, level, *bnop, keyp); + XFS_BMBT_TRACE_ARGIFK(cur, level, *bnop, *startoff); args.tp = cur->bc_tp; args.mp = cur->bc_mp; lbp = cur->bc_bufs[level]; lbno = XFS_DADDR_TO_FSB(args.mp, XFS_BUF_ADDR(lbp)); left = XFS_BUF_TO_BMBT_BLOCK(lbp); args.fsbno = cur->bc_private.b.firstblock; + args.firstblock = args.fsbno; + args.minleft = 0; if (args.fsbno == NULLFSBLOCK) { args.fsbno = lbno; args.type = XFS_ALLOCTYPE_START_BNO; + /* + * Make sure there is sufficient room left in the AG to + * complete a full tree split for an extent insert. If + * we are converting the middle part of an extent then + * we may need space for two tree splits. + * + * We are relying on the caller to make the correct block + * reservation for this operation to succeed. If the + * reservation amount is insufficient then we may fail a + * block allocation here and corrupt the filesystem. + */ + args.minleft = xfs_trans_get_block_res(args.tp); } else if (cur->bc_private.b.flist->xbf_low) - args.type = XFS_ALLOCTYPE_FIRST_AG; + args.type = XFS_ALLOCTYPE_START_BNO; else args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.mod = args.minleft = args.alignment = args.total = args.isfl = + args.mod = args.alignment = args.total = args.isfl = args.userdata = args.minalignslop = 0; args.minlen = args.maxlen = args.prod = 1; args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; @@ -1253,6 +1263,21 @@ xfs_bmbt_split( XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } + if (args.fsbno == NULLFSBLOCK && args.minleft) { + /* + * Could not find an AG with enough free space to satisfy + * a full btree split. Try again without minleft and if + * successful activate the lowspace algorithm. + */ + args.fsbno = 0; + args.type = XFS_ALLOCTYPE_FIRST_AG; + args.minleft = 0; + if ((error = xfs_alloc_vextent(&args))) { + XFS_BMBT_TRACE_CURSOR(cur, ERROR); + return error; + } + cur->bc_private.b.flist->xbf_low = 1; + } if (args.fsbno == NULLFSBLOCK) { XFS_BMBT_TRACE_CURSOR(cur, EXIT); *stat = 0; @@ -1273,47 +1298,47 @@ xfs_bmbt_split( return error; } #endif - INT_SET(right->bb_magic, ARCH_CONVERT, XFS_BMAP_MAGIC); - right->bb_level = left->bb_level; /* INT_: direct copy */ - INT_SET(right->bb_numrecs, ARCH_CONVERT, (__uint16_t)(INT_GET(left->bb_numrecs, ARCH_CONVERT) / 2)); - if ((INT_GET(left->bb_numrecs, ARCH_CONVERT) & 1) && - cur->bc_ptrs[level] <= INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1) - INT_MOD(right->bb_numrecs, ARCH_CONVERT, +1); - i = INT_GET(left->bb_numrecs, ARCH_CONVERT) - INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1; + right->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC); + right->bb_level = left->bb_level; + right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2); + if ((be16_to_cpu(left->bb_numrecs) & 1) && + cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1) + be16_add_cpu(&right->bb_numrecs, 1); + i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1; if (level > 0) { lkp = XFS_BMAP_KEY_IADDR(left, i, cur); lpp = XFS_BMAP_PTR_IADDR(left, i, cur); rkp = XFS_BMAP_KEY_IADDR(right, 1, cur); rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); #ifdef DEBUG - for (i = 0; i < INT_GET(right->bb_numrecs, ARCH_CONVERT); i++) { - if ((error = xfs_btree_check_lptr(cur, INT_GET(lpp[i], ARCH_CONVERT), level))) { + for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) { + if ((error = xfs_btree_check_lptr_disk(cur, lpp[i], level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } } #endif - memcpy(rkp, lkp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rkp)); - memcpy(rpp, lpp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rpp)); - xfs_bmbt_log_keys(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT)); - xfs_bmbt_log_ptrs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT)); - keyp->br_startoff = INT_GET(rkp->br_startoff, ARCH_CONVERT); + memcpy(rkp, lkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp)); + memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp)); + xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); + xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); + *startoff = be64_to_cpu(rkp->br_startoff); } else { lrp = XFS_BMAP_REC_IADDR(left, i, cur); rrp = XFS_BMAP_REC_IADDR(right, 1, cur); - memcpy(rrp, lrp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rrp)); - xfs_bmbt_log_recs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT)); - keyp->br_startoff = xfs_bmbt_disk_get_startoff(rrp); - } - INT_MOD(left->bb_numrecs, ARCH_CONVERT, -(INT_GET(right->bb_numrecs, ARCH_CONVERT))); - right->bb_rightsib = left->bb_rightsib; /* INT_: direct copy */ - INT_SET(left->bb_rightsib, ARCH_CONVERT, args.fsbno); - INT_SET(right->bb_leftsib, ARCH_CONVERT, lbno); + memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); + xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); + *startoff = xfs_bmbt_disk_get_startoff(rrp); + } + be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); + right->bb_rightsib = left->bb_rightsib; + left->bb_rightsib = cpu_to_be64(args.fsbno); + right->bb_leftsib = cpu_to_be64(lbno); xfs_bmbt_log_block(cur, rbp, XFS_BB_ALL_BITS); xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB); - if (INT_GET(right->bb_rightsib, ARCH_CONVERT) != NULLDFSBNO) { + if (be64_to_cpu(right->bb_rightsib) != NULLDFSBNO) { if ((error = xfs_btree_read_bufl(args.mp, args.tp, - INT_GET(right->bb_rightsib, ARCH_CONVERT), 0, &rrbp, + be64_to_cpu(right->bb_rightsib), 0, &rrbp, XFS_BMAP_BTREE_REF))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; @@ -1323,12 +1348,12 @@ xfs_bmbt_split( XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } - INT_SET(rrblock->bb_leftsib, ARCH_CONVERT, args.fsbno); + rrblock->bb_leftsib = cpu_to_be64(args.fsbno); xfs_bmbt_log_block(cur, rrbp, XFS_BB_LEFTSIB); } - if (cur->bc_ptrs[level] > INT_GET(left->bb_numrecs, ARCH_CONVERT) + 1) { + if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) { xfs_btree_setbuf(cur, level, rbp); - cur->bc_ptrs[level] -= INT_GET(left->bb_numrecs, ARCH_CONVERT); + cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs); } if (level + 1 < cur->bc_nlevels) { if ((error = xfs_btree_dup_cursor(cur, curp))) { @@ -1357,9 +1382,6 @@ xfs_bmbt_updkey( xfs_buf_t *bp; #ifdef DEBUG int error; -#endif -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_updkey"; #endif xfs_bmbt_key_t *kp; int ptr; @@ -1396,9 +1418,9 @@ xfs_bmdr_to_bmbt( { int dmxr; xfs_bmbt_key_t *fkp; - xfs_bmbt_ptr_t *fpp; + __be64 *fpp; xfs_bmbt_key_t *tkp; - xfs_bmbt_ptr_t *tpp; + __be64 *tpp; rblock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC); rblock->bb_level = dblock->bb_level; @@ -1407,13 +1429,13 @@ xfs_bmdr_to_bmbt( rblock->bb_leftsib = cpu_to_be64(NULLDFSBNO); rblock->bb_rightsib = cpu_to_be64(NULLDFSBNO); dmxr = (int)XFS_BTREE_BLOCK_MAXRECS(dblocklen, xfs_bmdr, 0); - fkp = XFS_BTREE_KEY_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr); + fkp = XFS_BTREE_KEY_ADDR(xfs_bmdr, dblock, 1); tkp = XFS_BMAP_BROOT_KEY_ADDR(rblock, 1, rblocklen); - fpp = XFS_BTREE_PTR_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr); + fpp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dblock, 1, dmxr); tpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen); dmxr = be16_to_cpu(dblock->bb_numrecs); memcpy(tkp, fkp, sizeof(*fkp) * dmxr); - memcpy(tpp, fpp, sizeof(*fpp) * dmxr); /* INT_: direct copy */ + memcpy(tpp, fpp, sizeof(*fpp) * dmxr); } /* @@ -1429,9 +1451,6 @@ xfs_bmbt_decrement( xfs_bmbt_block_t *block; xfs_buf_t *bp; int error; /* error return value */ -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_decrement"; -#endif xfs_fsblock_t fsbno; int lev; xfs_mount_t *mp; @@ -1473,7 +1492,7 @@ xfs_bmbt_decrement( tp = cur->bc_tp; mp = cur->bc_mp; for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) { - fsbno = INT_GET(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT); + fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur)); if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp, XFS_BMAP_BTREE_REF))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); @@ -1502,9 +1521,6 @@ xfs_bmbt_delete( int *stat) /* success/failure */ { int error; /* error return value */ -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_delete"; -#endif int i; int level; @@ -1538,7 +1554,7 @@ xfs_bmbt_delete( * xfs_bmbt_get_startblock, xfs_bmbt_get_blockcount and xfs_bmbt_get_state. */ -STATIC __inline__ void +STATIC_INLINE void __xfs_bmbt_get_all( __uint64_t l0, __uint64_t l1, @@ -1579,7 +1595,7 @@ __xfs_bmbt_get_all( void xfs_bmbt_get_all( - xfs_bmbt_rec_t *r, + xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s) { __xfs_bmbt_get_all(r->l0, r->l1, s); @@ -1615,7 +1631,7 @@ xfs_bmbt_get_block( */ xfs_filblks_t xfs_bmbt_get_blockcount( - xfs_bmbt_rec_t *r) + xfs_bmbt_rec_host_t *r) { return (xfs_filblks_t)(r->l1 & XFS_MASK64LO(21)); } @@ -1625,7 +1641,7 @@ xfs_bmbt_get_blockcount( */ xfs_fsblock_t xfs_bmbt_get_startblock( - xfs_bmbt_rec_t *r) + xfs_bmbt_rec_host_t *r) { #if XFS_BIG_BLKNOS return (((xfs_fsblock_t)r->l0 & XFS_MASK64LO(9)) << 43) | @@ -1649,7 +1665,7 @@ xfs_bmbt_get_startblock( */ xfs_fileoff_t xfs_bmbt_get_startoff( - xfs_bmbt_rec_t *r) + xfs_bmbt_rec_host_t *r) { return ((xfs_fileoff_t)r->l0 & XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; @@ -1657,7 +1673,7 @@ xfs_bmbt_get_startoff( xfs_exntst_t xfs_bmbt_get_state( - xfs_bmbt_rec_t *r) + xfs_bmbt_rec_host_t *r) { int ext_flag; @@ -1666,19 +1682,13 @@ xfs_bmbt_get_state( ext_flag); } -#if __BYTE_ORDER != __BIG_ENDIAN /* Endian flipping versions of the bmbt extraction functions */ void xfs_bmbt_disk_get_all( xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s) { - __uint64_t l0, l1; - - l0 = INT_GET(r->l0, ARCH_CONVERT); - l1 = INT_GET(r->l1, ARCH_CONVERT); - - __xfs_bmbt_get_all(l0, l1, s); + __xfs_bmbt_get_all(be64_to_cpu(r->l0), be64_to_cpu(r->l1), s); } /* @@ -1688,31 +1698,7 @@ xfs_filblks_t xfs_bmbt_disk_get_blockcount( xfs_bmbt_rec_t *r) { - return (xfs_filblks_t)(INT_GET(r->l1, ARCH_CONVERT) & XFS_MASK64LO(21)); -} - -/* - * Extract the startblock field from an on disk bmap extent record. - */ -xfs_fsblock_t -xfs_bmbt_disk_get_startblock( - xfs_bmbt_rec_t *r) -{ -#if XFS_BIG_BLKNOS - return (((xfs_fsblock_t)INT_GET(r->l0, ARCH_CONVERT) & XFS_MASK64LO(9)) << 43) | - (((xfs_fsblock_t)INT_GET(r->l1, ARCH_CONVERT)) >> 21); -#else -#ifdef DEBUG - xfs_dfsbno_t b; - - b = (((xfs_dfsbno_t)INT_GET(r->l0, ARCH_CONVERT) & XFS_MASK64LO(9)) << 43) | - (((xfs_dfsbno_t)INT_GET(r->l1, ARCH_CONVERT)) >> 21); - ASSERT((b >> 32) == 0 || ISNULLDSTARTBLOCK(b)); - return (xfs_fsblock_t)b; -#else /* !DEBUG */ - return (xfs_fsblock_t)(((xfs_dfsbno_t)INT_GET(r->l1, ARCH_CONVERT)) >> 21); -#endif /* DEBUG */ -#endif /* XFS_BIG_BLKNOS */ + return (xfs_filblks_t)(be64_to_cpu(r->l1) & XFS_MASK64LO(21)); } /* @@ -1722,23 +1708,10 @@ xfs_fileoff_t xfs_bmbt_disk_get_startoff( xfs_bmbt_rec_t *r) { - return ((xfs_fileoff_t)INT_GET(r->l0, ARCH_CONVERT) & + return ((xfs_fileoff_t)be64_to_cpu(r->l0) & XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; } -xfs_exntst_t -xfs_bmbt_disk_get_state( - xfs_bmbt_rec_t *r) -{ - int ext_flag; - - ext_flag = (int)((INT_GET(r->l0, ARCH_CONVERT)) >> (64 - BMBT_EXNTFLAG_BITLEN)); - return xfs_extent_state(xfs_bmbt_disk_get_blockcount(r), - ext_flag); -} -#endif - - /* * Increment cursor by one record at the level. * For nonzero levels the leaf-ward information is untouched. @@ -1752,9 +1725,6 @@ xfs_bmbt_increment( xfs_bmbt_block_t *block; xfs_buf_t *bp; int error; /* error return value */ -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_increment"; -#endif xfs_fsblock_t fsbno; int lev; xfs_mount_t *mp; @@ -1803,7 +1773,7 @@ xfs_bmbt_increment( tp = cur->bc_tp; mp = cur->bc_mp; for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) { - fsbno = INT_GET(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT); + fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur)); if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp, XFS_BMAP_BTREE_REF))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); @@ -1825,6 +1795,10 @@ xfs_bmbt_increment( /* * Insert the current record at the point referenced by cur. + * + * A multi-level split of the tree on insert will invalidate the original + * cursor. All callers of this function should assume that the cursor is + * no longer valid and revalidate it. */ int /* error */ xfs_bmbt_insert( @@ -1832,9 +1806,6 @@ xfs_bmbt_insert( int *stat) /* success/failure */ { int error; /* error return value */ -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_insert"; -#endif int i; int level; xfs_fsblock_t nbno; @@ -1846,7 +1817,7 @@ xfs_bmbt_insert( level = 0; nbno = NULLFSBLOCK; xfs_bmbt_disk_set_all(&nrec, &cur->bc_rec.b); - ncur = (xfs_btree_cur_t *)0; + ncur = NULL; pcur = cur; do { if ((error = xfs_bmbt_insrec(pcur, level++, &nbno, &nrec, &ncur, @@ -1863,8 +1834,7 @@ xfs_bmbt_insert( pcur->bc_private.b.allocated; pcur->bc_private.b.allocated = 0; ASSERT((cur->bc_private.b.firstblock != NULLFSBLOCK) || - (cur->bc_private.b.ip->i_d.di_flags & - XFS_DIFLAG_REALTIME)); + XFS_IS_REALTIME_INODE(cur->bc_private.b.ip)); cur->bc_private.b.firstblock = pcur->bc_private.b.firstblock; ASSERT(cur->bc_private.b.flist == @@ -1873,7 +1843,7 @@ xfs_bmbt_insert( } if (ncur) { pcur = ncur; - ncur = (xfs_btree_cur_t *)0; + ncur = NULL; } } while (nbno != NULLFSBLOCK); XFS_BMBT_TRACE_CURSOR(cur, EXIT); @@ -1894,9 +1864,6 @@ xfs_bmbt_log_block( int fields) { int first; -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_log_block"; -#endif int last; xfs_trans_t *tp; static const short offsets[] = { @@ -1933,9 +1900,6 @@ xfs_bmbt_log_recs( { xfs_bmbt_block_t *block; int first; -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_log_recs"; -#endif int last; xfs_bmbt_rec_t *rp; xfs_trans_t *tp; @@ -1997,9 +1961,6 @@ xfs_bmbt_newroot( xfs_bmbt_key_t *ckp; /* child key pointer */ xfs_bmbt_ptr_t *cpp; /* child ptr pointer */ int error; /* error return code */ -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_newroot"; -#endif #ifdef DEBUG int i; /* loop counter */ #endif @@ -2021,17 +1982,18 @@ xfs_bmbt_newroot( args.userdata = args.minalignslop = 0; args.minlen = args.maxlen = args.prod = 1; args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; + args.firstblock = args.fsbno; if (args.fsbno == NULLFSBLOCK) { #ifdef DEBUG - if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr_disk(cur, *pp, level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } #endif - args.fsbno = INT_GET(*pp, ARCH_CONVERT); + args.fsbno = be64_to_cpu(*pp); + args.type = XFS_ALLOCTYPE_START_BNO; + } else if (cur->bc_private.b.flist->xbf_low) args.type = XFS_ALLOCTYPE_START_BNO; - } else if (args.wasdel) - args.type = XFS_ALLOCTYPE_FIRST_AG; else args.type = XFS_ALLOCTYPE_NEAR_BNO; if ((error = xfs_alloc_vextent(&args))) { @@ -2052,7 +2014,7 @@ xfs_bmbt_newroot( bp = xfs_btree_get_bufl(args.mp, cur->bc_tp, args.fsbno, 0); cblock = XFS_BUF_TO_BMBT_BLOCK(bp); *cblock = *block; - be16_add(&block->bb_level, 1); + be16_add_cpu(&block->bb_level, 1); block->bb_numrecs = cpu_to_be16(1); cur->bc_nlevels++; cur->bc_ptrs[level + 1] = 1; @@ -2062,7 +2024,7 @@ xfs_bmbt_newroot( cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur); #ifdef DEBUG for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { - if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i], ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } @@ -2070,13 +2032,12 @@ xfs_bmbt_newroot( #endif memcpy(cpp, pp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*pp)); #ifdef DEBUG - if ((error = xfs_btree_check_lptr(cur, (xfs_bmbt_ptr_t)args.fsbno, - level))) { + if ((error = xfs_btree_check_lptr(cur, args.fsbno, level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } #endif - INT_SET(*pp, ARCH_CONVERT, args.fsbno); + *pp = cpu_to_be64(args.fsbno); xfs_iroot_realloc(cur->bc_private.b.ip, 1 - be16_to_cpu(cblock->bb_numrecs), cur->bc_private.b.whichfork); xfs_btree_setbuf(cur, level, bp); @@ -2094,186 +2055,132 @@ xfs_bmbt_newroot( return 0; } -/* - * Set all the fields in a bmap extent record from the uncompressed form. - */ -void -xfs_bmbt_set_all( - xfs_bmbt_rec_t *r, - xfs_bmbt_irec_t *s) -{ - int extent_flag; - - ASSERT((s->br_state == XFS_EXT_NORM) || - (s->br_state == XFS_EXT_UNWRITTEN)); - extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1; - ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0); - ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0); -#if XFS_BIG_BLKNOS - ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0); - r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | - ((xfs_bmbt_rec_base_t)s->br_startoff << 9) | - ((xfs_bmbt_rec_base_t)s->br_startblock >> 43); - r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) | - ((xfs_bmbt_rec_base_t)s->br_blockcount & - (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); -#else /* !XFS_BIG_BLKNOS */ - if (ISNULLSTARTBLOCK(s->br_startblock)) { - r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | - ((xfs_bmbt_rec_base_t)s->br_startoff << 9) | - (xfs_bmbt_rec_base_t)XFS_MASK64LO(9); - r->l1 = XFS_MASK64HI(11) | - ((xfs_bmbt_rec_base_t)s->br_startblock << 21) | - ((xfs_bmbt_rec_base_t)s->br_blockcount & - (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); - } else { - r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | - ((xfs_bmbt_rec_base_t)s->br_startoff << 9); - r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) | - ((xfs_bmbt_rec_base_t)s->br_blockcount & - (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); - } -#endif /* XFS_BIG_BLKNOS */ -} - /* * Set all the fields in a bmap extent record from the arguments. */ void xfs_bmbt_set_allf( - xfs_bmbt_rec_t *r, - xfs_fileoff_t o, - xfs_fsblock_t b, - xfs_filblks_t c, - xfs_exntst_t v) + xfs_bmbt_rec_host_t *r, + xfs_fileoff_t startoff, + xfs_fsblock_t startblock, + xfs_filblks_t blockcount, + xfs_exntst_t state) { - int extent_flag; + int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1; + + ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN); + ASSERT((startoff & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0); + ASSERT((blockcount & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); - ASSERT((v == XFS_EXT_NORM) || (v == XFS_EXT_UNWRITTEN)); - extent_flag = (v == XFS_EXT_NORM) ? 0 : 1; - ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0); - ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); #if XFS_BIG_BLKNOS - ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0); + ASSERT((startblock & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0); + r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | - ((xfs_bmbt_rec_base_t)o << 9) | - ((xfs_bmbt_rec_base_t)b >> 43); - r->l1 = ((xfs_bmbt_rec_base_t)b << 21) | - ((xfs_bmbt_rec_base_t)c & + ((xfs_bmbt_rec_base_t)startoff << 9) | + ((xfs_bmbt_rec_base_t)startblock >> 43); + r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) | + ((xfs_bmbt_rec_base_t)blockcount & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); #else /* !XFS_BIG_BLKNOS */ - if (ISNULLSTARTBLOCK(b)) { + if (ISNULLSTARTBLOCK(startblock)) { r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | - ((xfs_bmbt_rec_base_t)o << 9) | + ((xfs_bmbt_rec_base_t)startoff << 9) | (xfs_bmbt_rec_base_t)XFS_MASK64LO(9); r->l1 = XFS_MASK64HI(11) | - ((xfs_bmbt_rec_base_t)b << 21) | - ((xfs_bmbt_rec_base_t)c & + ((xfs_bmbt_rec_base_t)startblock << 21) | + ((xfs_bmbt_rec_base_t)blockcount & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); } else { r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | - ((xfs_bmbt_rec_base_t)o << 9); - r->l1 = ((xfs_bmbt_rec_base_t)b << 21) | - ((xfs_bmbt_rec_base_t)c & + ((xfs_bmbt_rec_base_t)startoff << 9); + r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) | + ((xfs_bmbt_rec_base_t)blockcount & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); } #endif /* XFS_BIG_BLKNOS */ } -#if __BYTE_ORDER != __BIG_ENDIAN /* * Set all the fields in a bmap extent record from the uncompressed form. */ void -xfs_bmbt_disk_set_all( - xfs_bmbt_rec_t *r, - xfs_bmbt_irec_t *s) +xfs_bmbt_set_all( + xfs_bmbt_rec_host_t *r, + xfs_bmbt_irec_t *s) { - int extent_flag; - - ASSERT((s->br_state == XFS_EXT_NORM) || - (s->br_state == XFS_EXT_UNWRITTEN)); - extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1; - ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0); - ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0); -#if XFS_BIG_BLKNOS - ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0); - INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) | - ((xfs_bmbt_rec_base_t)s->br_startoff << 9) | - ((xfs_bmbt_rec_base_t)s->br_startblock >> 43)); - INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)s->br_startblock << 21) | - ((xfs_bmbt_rec_base_t)s->br_blockcount & - (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); -#else /* !XFS_BIG_BLKNOS */ - if (ISNULLSTARTBLOCK(s->br_startblock)) { - INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) | - ((xfs_bmbt_rec_base_t)s->br_startoff << 9) | - (xfs_bmbt_rec_base_t)XFS_MASK64LO(9)); - INT_SET(r->l1, ARCH_CONVERT, XFS_MASK64HI(11) | - ((xfs_bmbt_rec_base_t)s->br_startblock << 21) | - ((xfs_bmbt_rec_base_t)s->br_blockcount & - (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); - } else { - INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) | - ((xfs_bmbt_rec_base_t)s->br_startoff << 9)); - INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)s->br_startblock << 21) | - ((xfs_bmbt_rec_base_t)s->br_blockcount & - (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); - } -#endif /* XFS_BIG_BLKNOS */ + xfs_bmbt_set_allf(r, s->br_startoff, s->br_startblock, + s->br_blockcount, s->br_state); } + /* * Set all the fields in a disk format bmap extent record from the arguments. */ void xfs_bmbt_disk_set_allf( - xfs_bmbt_rec_t *r, - xfs_fileoff_t o, - xfs_fsblock_t b, - xfs_filblks_t c, - xfs_exntst_t v) + xfs_bmbt_rec_t *r, + xfs_fileoff_t startoff, + xfs_fsblock_t startblock, + xfs_filblks_t blockcount, + xfs_exntst_t state) { - int extent_flag; + int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1; + + ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN); + ASSERT((startoff & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0); + ASSERT((blockcount & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); - ASSERT((v == XFS_EXT_NORM) || (v == XFS_EXT_UNWRITTEN)); - extent_flag = (v == XFS_EXT_NORM) ? 0 : 1; - ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0); - ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); #if XFS_BIG_BLKNOS - ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0); - INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) | - ((xfs_bmbt_rec_base_t)o << 9) | - ((xfs_bmbt_rec_base_t)b >> 43)); - INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)b << 21) | - ((xfs_bmbt_rec_base_t)c & - (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); + ASSERT((startblock & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0); + + r->l0 = cpu_to_be64( + ((xfs_bmbt_rec_base_t)extent_flag << 63) | + ((xfs_bmbt_rec_base_t)startoff << 9) | + ((xfs_bmbt_rec_base_t)startblock >> 43)); + r->l1 = cpu_to_be64( + ((xfs_bmbt_rec_base_t)startblock << 21) | + ((xfs_bmbt_rec_base_t)blockcount & + (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); #else /* !XFS_BIG_BLKNOS */ - if (ISNULLSTARTBLOCK(b)) { - INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) | - ((xfs_bmbt_rec_base_t)o << 9) | - (xfs_bmbt_rec_base_t)XFS_MASK64LO(9)); - INT_SET(r->l1, ARCH_CONVERT, XFS_MASK64HI(11) | - ((xfs_bmbt_rec_base_t)b << 21) | - ((xfs_bmbt_rec_base_t)c & + if (ISNULLSTARTBLOCK(startblock)) { + r->l0 = cpu_to_be64( + ((xfs_bmbt_rec_base_t)extent_flag << 63) | + ((xfs_bmbt_rec_base_t)startoff << 9) | + (xfs_bmbt_rec_base_t)XFS_MASK64LO(9)); + r->l1 = cpu_to_be64(XFS_MASK64HI(11) | + ((xfs_bmbt_rec_base_t)startblock << 21) | + ((xfs_bmbt_rec_base_t)blockcount & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); } else { - INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) | - ((xfs_bmbt_rec_base_t)o << 9)); - INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)b << 21) | - ((xfs_bmbt_rec_base_t)c & - (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); + r->l0 = cpu_to_be64( + ((xfs_bmbt_rec_base_t)extent_flag << 63) | + ((xfs_bmbt_rec_base_t)startoff << 9)); + r->l1 = cpu_to_be64( + ((xfs_bmbt_rec_base_t)startblock << 21) | + ((xfs_bmbt_rec_base_t)blockcount & + (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); } #endif /* XFS_BIG_BLKNOS */ } -#endif + +/* + * Set all the fields in a bmap extent record from the uncompressed form. + */ +void +xfs_bmbt_disk_set_all( + xfs_bmbt_rec_t *r, + xfs_bmbt_irec_t *s) +{ + xfs_bmbt_disk_set_allf(r, s->br_startoff, s->br_startblock, + s->br_blockcount, s->br_state); +} /* * Set the blockcount field in a bmap extent record. */ void xfs_bmbt_set_blockcount( - xfs_bmbt_rec_t *r, + xfs_bmbt_rec_host_t *r, xfs_filblks_t v) { ASSERT((v & XFS_MASK64HI(43)) == 0); @@ -2286,7 +2193,7 @@ xfs_bmbt_set_blockcount( */ void xfs_bmbt_set_startblock( - xfs_bmbt_rec_t *r, + xfs_bmbt_rec_host_t *r, xfs_fsblock_t v) { #if XFS_BIG_BLKNOS @@ -2314,7 +2221,7 @@ xfs_bmbt_set_startblock( */ void xfs_bmbt_set_startoff( - xfs_bmbt_rec_t *r, + xfs_bmbt_rec_host_t *r, xfs_fileoff_t v) { ASSERT((v & XFS_MASK64HI(9)) == 0); @@ -2328,7 +2235,7 @@ xfs_bmbt_set_startoff( */ void xfs_bmbt_set_state( - xfs_bmbt_rec_t *r, + xfs_bmbt_rec_host_t *r, xfs_exntst_t v) { ASSERT(v == XFS_EXT_NORM || v == XFS_EXT_UNWRITTEN); @@ -2350,9 +2257,9 @@ xfs_bmbt_to_bmdr( { int dmxr; xfs_bmbt_key_t *fkp; - xfs_bmbt_ptr_t *fpp; + __be64 *fpp; xfs_bmbt_key_t *tkp; - xfs_bmbt_ptr_t *tpp; + __be64 *tpp; ASSERT(be32_to_cpu(rblock->bb_magic) == XFS_BMAP_MAGIC); ASSERT(be64_to_cpu(rblock->bb_leftsib) == NULLDFSBNO); @@ -2362,12 +2269,12 @@ xfs_bmbt_to_bmdr( dblock->bb_numrecs = rblock->bb_numrecs; dmxr = (int)XFS_BTREE_BLOCK_MAXRECS(dblocklen, xfs_bmdr, 0); fkp = XFS_BMAP_BROOT_KEY_ADDR(rblock, 1, rblocklen); - tkp = XFS_BTREE_KEY_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr); + tkp = XFS_BTREE_KEY_ADDR(xfs_bmdr, dblock, 1); fpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen); - tpp = XFS_BTREE_PTR_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr); + tpp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dblock, 1, dmxr); dmxr = be16_to_cpu(dblock->bb_numrecs); memcpy(tkp, fkp, sizeof(*fkp) * dmxr); - memcpy(tpp, fpp, sizeof(*fpp) * dmxr); /* INT_: direct copy */ + memcpy(tpp, fpp, sizeof(*fpp) * dmxr); } /* @@ -2384,9 +2291,6 @@ xfs_bmbt_update( xfs_bmbt_block_t *block; xfs_buf_t *bp; int error; -#ifdef XFS_BMBT_TRACE - static char fname[] = "xfs_bmbt_update"; -#endif xfs_bmbt_key_t key; int ptr; xfs_bmbt_rec_t *rp; @@ -2409,7 +2313,7 @@ xfs_bmbt_update( XFS_BMBT_TRACE_CURSOR(cur, EXIT); return 0; } - INT_SET(key.br_startoff, ARCH_CONVERT, off); + key.br_startoff = cpu_to_be64(off); if ((error = xfs_bmbt_updkey(cur, &key, 1))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; @@ -2419,7 +2323,7 @@ xfs_bmbt_update( } /* - * Check an extent list, which has just been read, for + * Check extent records, which have just been read, for * any bit in the extent flag field. ASSERT on debug * kernels, as this condition should not occur. * Return an error condition (1) if any flags found, @@ -2428,10 +2332,12 @@ xfs_bmbt_update( int xfs_check_nostate_extents( - xfs_bmbt_rec_t *ep, + xfs_ifork_t *ifp, + xfs_extnum_t idx, xfs_extnum_t num) { - for (; num > 0; num--, ep++) { + for (; num > 0; num--, idx++) { + xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx); if ((ep->l0 >> (64 - BMBT_EXNTFLAG_BITLEN)) != 0) { ASSERT(0); diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c index d6d126fcc..31b12b31c 100644 --- a/libxfs/xfs_btree.c +++ b/libxfs/xfs_btree.c @@ -16,41 +16,20 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -/* - * This file contains common code for the space manager's btree implementations. - */ - #include /* * Cursor allocation zone. */ -xfs_zone_t *xfs_btree_cur_zone; +kmem_zone_t *xfs_btree_cur_zone; /* * Btree magic numbers. */ -const __uint32_t xfs_magics[XFS_BTNUM_MAX] = -{ +const __uint32_t xfs_magics[XFS_BTNUM_MAX] = { XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, XFS_BMAP_MAGIC, XFS_IBT_MAGIC }; -/* - * Prototypes for internal routines. - */ - -/* - * Checking routine: return maxrecs for the block. - */ -STATIC int /* number of records fitting in block */ -xfs_btree_maxrecs( - xfs_btree_cur_t *cur, /* btree cursor */ - xfs_btree_block_t *block);/* generic btree block pointer */ - -/* - * Internal routines. - */ - /* * Checking routine: return maxrecs for the block. */ @@ -135,7 +114,7 @@ xfs_btree_check_key( k1 = ak1; k2 = ak2; - ASSERT(INT_GET(k1->br_startoff, ARCH_CONVERT) < INT_GET(k2->br_startoff, ARCH_CONVERT)); + ASSERT(be64_to_cpu(k1->br_startoff) < be64_to_cpu(k2->br_startoff)); break; } case XFS_BTNUM_INO: { @@ -144,7 +123,7 @@ xfs_btree_check_key( k1 = ak1; k2 = ak2; - ASSERT(INT_GET(k1->ir_startino, ARCH_CONVERT) < INT_GET(k2->ir_startino, ARCH_CONVERT)); + ASSERT(be32_to_cpu(k1->ir_startino) < be32_to_cpu(k2->ir_startino)); break; } default: @@ -259,8 +238,8 @@ xfs_btree_check_rec( r1 = ar1; r2 = ar2; - ASSERT(INT_GET(r1->ir_startino, ARCH_CONVERT) + XFS_INODES_PER_CHUNK <= - INT_GET(r2->ir_startino, ARCH_CONVERT)); + ASSERT(be32_to_cpu(r1->ir_startino) + XFS_INODES_PER_CHUNK <= + be32_to_cpu(r2->ir_startino)); break; } default: @@ -430,40 +409,11 @@ xfs_btree_dup_cursor( return 0; } -/* - * Change the cursor to point to the first record at the given level. - * Other levels are unaffected. - */ -int /* success=1, failure=0 */ -xfs_btree_firstrec( - xfs_btree_cur_t *cur, /* btree cursor */ - int level) /* level to change */ -{ - xfs_btree_block_t *block; /* generic btree block pointer */ - xfs_buf_t *bp; /* buffer containing block */ - - /* - * Get the block pointer for this level. - */ - block = xfs_btree_get_block(cur, level, &bp); - xfs_btree_check_block(cur, block, level, bp); - /* - * It's empty, there is no such record. - */ - if (!block->bb_h.bb_numrecs) - return 0; - /* - * Set the ptr value to 1, that's the first record/key. - */ - cur->bc_ptrs[level] = 1; - return 1; -} - /* * Retrieve the block pointer from the cursor at the given level. * This may be a bmap btree root or from a buffer. */ -xfs_btree_block_t * /* generic btree block pointer */ +STATIC xfs_btree_block_t * /* generic btree block pointer */ xfs_btree_get_block( xfs_btree_cur_t *cur, /* btree cursor */ int level, /* level in btree */ @@ -600,6 +550,13 @@ xfs_btree_init_cursor( cur->bc_private.a.agbp = agbp; cur->bc_private.a.agno = agno; break; + case XFS_BTNUM_INO: + /* + * Inode allocation btree fields. + */ + cur->bc_private.a.agbp = agbp; + cur->bc_private.a.agno = agno; + break; case XFS_BTNUM_BMAP: /* * Bmap btree fields. @@ -612,13 +569,6 @@ xfs_btree_init_cursor( cur->bc_private.b.flags = 0; cur->bc_private.b.whichfork = whichfork; break; - case XFS_BTNUM_INO: - /* - * Inode allocation btree fields. - */ - cur->bc_private.i.agbp = agbp; - cur->bc_private.i.agno = agno; - break; default: ASSERT(0); } @@ -644,6 +594,35 @@ xfs_btree_islastblock( return be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK; } +/* + * Change the cursor to point to the first record at the given level. + * Other levels are unaffected. + */ +int /* success=1, failure=0 */ +xfs_btree_firstrec( + xfs_btree_cur_t *cur, /* btree cursor */ + int level) /* level to change */ +{ + xfs_btree_block_t *block; /* generic btree block pointer */ + xfs_buf_t *bp; /* buffer containing block */ + + /* + * Get the block pointer for this level. + */ + block = xfs_btree_get_block(cur, level, &bp); + xfs_btree_check_block(cur, block, level, bp); + /* + * It's empty, there is no such record. + */ + if (!block->bb_h.bb_numrecs) + return 0; + /* + * Set the ptr value to 1, that's the first record/key. + */ + cur->bc_ptrs[level] = 1; + return 1; +} + /* * Change the cursor to point to the last record in the current block * at the given level. Other levels are unaffected. @@ -826,12 +805,12 @@ xfs_btree_readahead_core( case XFS_BTNUM_INO: i = XFS_BUF_TO_INOBT_BLOCK(cur->bc_bufs[lev]); if ((lr & XFS_BTCUR_LEFTRA) && be32_to_cpu(i->bb_leftsib) != NULLAGBLOCK) { - xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.i.agno, + xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, be32_to_cpu(i->bb_leftsib), 1); rval++; } if ((lr & XFS_BTCUR_RIGHTRA) && be32_to_cpu(i->bb_rightsib) != NULLAGBLOCK) { - xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.i.agno, + xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, be32_to_cpu(i->bb_rightsib), 1); rval++; } diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c index c7777049e..40b52a4e9 100644 --- a/libxfs/xfs_da_btree.c +++ b/libxfs/xfs_da_btree.c @@ -26,6 +26,52 @@ static int xfs_error_level; +/*======================================================================== + * Function prototypes for the kernel. + *========================================================================*/ + +/* + * Routines used for growing the Btree. + */ +STATIC int xfs_da_root_split(xfs_da_state_t *state, + xfs_da_state_blk_t *existing_root, + xfs_da_state_blk_t *new_child); +STATIC int xfs_da_node_split(xfs_da_state_t *state, + xfs_da_state_blk_t *existing_blk, + xfs_da_state_blk_t *split_blk, + xfs_da_state_blk_t *blk_to_add, + int treelevel, + int *result); +STATIC void xfs_da_node_rebalance(xfs_da_state_t *state, + xfs_da_state_blk_t *node_blk_1, + xfs_da_state_blk_t *node_blk_2); +STATIC void xfs_da_node_add(xfs_da_state_t *state, + xfs_da_state_blk_t *old_node_blk, + xfs_da_state_blk_t *new_node_blk); + +/* + * Routines used for shrinking the Btree. + */ +STATIC int xfs_da_root_join(xfs_da_state_t *state, + xfs_da_state_blk_t *root_blk); +STATIC int xfs_da_node_toosmall(xfs_da_state_t *state, int *retval); +STATIC void xfs_da_node_remove(xfs_da_state_t *state, + xfs_da_state_blk_t *drop_blk); +STATIC void xfs_da_node_unbalance(xfs_da_state_t *state, + xfs_da_state_blk_t *src_node_blk, + xfs_da_state_blk_t *dst_node_blk); + +/* + * Utility routines. + */ +STATIC uint xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count); +STATIC int xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp); +STATIC xfs_dabuf_t *xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra); +STATIC int xfs_da_blk_unlink(xfs_da_state_t *state, + xfs_da_state_blk_t *drop_blk, + xfs_da_state_blk_t *save_blk); +STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state); + /*======================================================================== * Routines used for growing the Btree. *========================================================================*/ @@ -50,10 +96,10 @@ xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level, node = bp->data; node->hdr.info.forw = 0; node->hdr.info.back = 0; - INT_SET(node->hdr.info.magic, ARCH_CONVERT, XFS_DA_NODE_MAGIC); + node->hdr.info.magic = cpu_to_be16(XFS_DA_NODE_MAGIC); node->hdr.info.pad = 0; node->hdr.count = 0; - INT_SET(node->hdr.level, ARCH_CONVERT, level); + node->hdr.level = cpu_to_be16(level); xfs_da_log_buf(tp, bp, XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); @@ -83,7 +129,7 @@ xfs_da_split(xfs_da_state_t *state) max = state->path.active - 1; ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH)); ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC || - state->path.blk[max].magic == XFS_DIRX_LEAF_MAGIC(state->mp)); + state->path.blk[max].magic == XFS_DIR2_LEAFN_MAGIC); addblk = &state->path.blk[max]; /* initial dummy value */ for (i = max; (i >= 0) && addblk; state->path.active--, i--) { @@ -123,38 +169,7 @@ xfs_da_split(xfs_da_state_t *state) return(error); /* GROT: attr inconsistent */ addblk = newblk; break; - case XFS_DIR_LEAF_MAGIC: - ASSERT(XFS_DIR_IS_V1(state->mp)); - error = xfs_dir_leaf_split(state, oldblk, newblk); - if ((error != 0) && (error != ENOSPC)) { - return(error); /* GROT: dir is inconsistent */ - } - if (!error) { - addblk = newblk; - break; - } - /* - * Entry wouldn't fit, split the leaf again. - */ - state->extravalid = 1; - if (state->inleaf) { - state->extraafter = 0; /* before newblk */ - error = xfs_dir_leaf_split(state, oldblk, - &state->extrablk); - if (error) - return(error); /* GROT: dir incon. */ - addblk = newblk; - } else { - state->extraafter = 1; /* after newblk */ - error = xfs_dir_leaf_split(state, newblk, - &state->extrablk); - if (error) - return(error); /* GROT: dir incon. */ - addblk = newblk; - } - break; case XFS_DIR2_LEAFN_MAGIC: - ASSERT(XFS_DIR_IS_V2(state->mp)); error = xfs_dir2_leafn_split(state, oldblk, newblk); if (error) return error; @@ -214,28 +229,28 @@ xfs_da_split(xfs_da_state_t *state) node = oldblk->bp->data; if (node->hdr.info.forw) { - if (INT_GET(node->hdr.info.forw, ARCH_CONVERT) == addblk->blkno) { + if (be32_to_cpu(node->hdr.info.forw) == addblk->blkno) { bp = addblk->bp; } else { ASSERT(state->extravalid); bp = state->extrablk.bp; } node = bp->data; - INT_SET(node->hdr.info.back, ARCH_CONVERT, oldblk->blkno); + node->hdr.info.back = cpu_to_be32(oldblk->blkno); xfs_da_log_buf(state->args->trans, bp, XFS_DA_LOGRANGE(node, &node->hdr.info, sizeof(node->hdr.info))); } node = oldblk->bp->data; - if (INT_GET(node->hdr.info.back, ARCH_CONVERT)) { - if (INT_GET(node->hdr.info.back, ARCH_CONVERT) == addblk->blkno) { + if (node->hdr.info.back) { + if (be32_to_cpu(node->hdr.info.back) == addblk->blkno) { bp = addblk->bp; } else { ASSERT(state->extravalid); bp = state->extrablk.bp; } node = bp->data; - INT_SET(node->hdr.info.forw, ARCH_CONVERT, oldblk->blkno); + node->hdr.info.forw = cpu_to_be32(oldblk->blkno); xfs_da_log_buf(state->args->trans, bp, XFS_DA_LOGRANGE(node, &node->hdr.info, sizeof(node->hdr.info))); @@ -283,14 +298,13 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, ASSERT(bp != NULL); node = bp->data; oldroot = blk1->bp->data; - if (INT_GET(oldroot->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) { - size = (int)((char *)&oldroot->btree[INT_GET(oldroot->hdr.count, ARCH_CONVERT)] - + if (be16_to_cpu(oldroot->hdr.info.magic) == XFS_DA_NODE_MAGIC) { + size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] - (char *)oldroot); } else { - ASSERT(XFS_DIR_IS_V2(mp)); - ASSERT(INT_GET(oldroot->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); + ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); leaf = (xfs_dir2_leaf_t *)oldroot; - size = (int)((char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] - + size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] - (char *)leaf); } memcpy(node, oldroot, size); @@ -303,20 +317,19 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, * Set up the new root node. */ error = xfs_da_node_create(args, - args->whichfork == XFS_DATA_FORK && - XFS_DIR_IS_V2(mp) ? mp->m_dirleafblk : 0, - INT_GET(node->hdr.level, ARCH_CONVERT) + 1, &bp, args->whichfork); + (args->whichfork == XFS_DATA_FORK) ? mp->m_dirleafblk : 0, + be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork); if (error) return(error); node = bp->data; - INT_SET(node->btree[0].hashval, ARCH_CONVERT, blk1->hashval); - INT_SET(node->btree[0].before, ARCH_CONVERT, blk1->blkno); - INT_SET(node->btree[1].hashval, ARCH_CONVERT, blk2->hashval); - INT_SET(node->btree[1].before, ARCH_CONVERT, blk2->blkno); - INT_SET(node->hdr.count, ARCH_CONVERT, 2); + node->btree[0].hashval = cpu_to_be32(blk1->hashval); + node->btree[0].before = cpu_to_be32(blk1->blkno); + node->btree[1].hashval = cpu_to_be32(blk2->hashval); + node->btree[1].before = cpu_to_be32(blk2->blkno); + node->hdr.count = cpu_to_be16(2); #ifdef DEBUG - if (INT_GET(oldroot->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC) { + if (be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC) { ASSERT(blk1->blkno >= mp->m_dirleafblk && blk1->blkno < mp->m_dirfreeblk); ASSERT(blk2->blkno >= mp->m_dirleafblk && @@ -348,18 +361,17 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, int useextra; node = oldblk->bp->data; - ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); + ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); /* - * With V2 the extra block is data or freespace. + * With V2 dirs the extra block is data or freespace. */ - useextra = state->extravalid && (XFS_DIR_IS_V1(state->mp) || - state->args->whichfork == XFS_ATTR_FORK); + useextra = state->extravalid && state->args->whichfork == XFS_ATTR_FORK; newcount = 1 + useextra; /* * Do we have to split the node? */ - if ((INT_GET(node->hdr.count, ARCH_CONVERT) + newcount) > state->node_ents) { + if ((be16_to_cpu(node->hdr.count) + newcount) > state->node_ents) { /* * Allocate a new node, add to the doubly linked chain of * nodes, then move some of our excess entries into it. @@ -396,7 +408,7 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, * If we had double-split op below us, then add the extra block too. */ node = oldblk->bp->data; - if (oldblk->index <= INT_GET(node->hdr.count, ARCH_CONVERT)) { + if (oldblk->index <= be16_to_cpu(node->hdr.count)) { oldblk->index++; xfs_da_node_add(state, oldblk, addblk); if (useextra) { @@ -440,17 +452,17 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, * Figure out how many entries need to move, and in which direction. * Swap the nodes around if that makes it simpler. */ - if ((INT_GET(node1->hdr.count, ARCH_CONVERT) > 0) && (INT_GET(node2->hdr.count, ARCH_CONVERT) > 0) && - ((INT_GET(node2->btree[ 0 ].hashval, ARCH_CONVERT) < INT_GET(node1->btree[ 0 ].hashval, ARCH_CONVERT)) || - (INT_GET(node2->btree[ INT_GET(node2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) < - INT_GET(node1->btree[ INT_GET(node1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)))) { + if ((be16_to_cpu(node1->hdr.count) > 0) && (be16_to_cpu(node2->hdr.count) > 0) && + ((be32_to_cpu(node2->btree[0].hashval) < be32_to_cpu(node1->btree[0].hashval)) || + (be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval) < + be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval)))) { tmpnode = node1; node1 = node2; node2 = tmpnode; } - ASSERT(INT_GET(node1->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); - ASSERT(INT_GET(node2->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); - count = (INT_GET(node1->hdr.count, ARCH_CONVERT) - INT_GET(node2->hdr.count, ARCH_CONVERT)) / 2; + ASSERT(be16_to_cpu(node1->hdr.info.magic) == XFS_DA_NODE_MAGIC); + ASSERT(be16_to_cpu(node2->hdr.info.magic) == XFS_DA_NODE_MAGIC); + count = (be16_to_cpu(node1->hdr.count) - be16_to_cpu(node2->hdr.count)) / 2; if (count == 0) return; tp = state->args->trans; @@ -461,7 +473,7 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, /* * Move elements in node2 up to make a hole. */ - if ((tmp = INT_GET(node2->hdr.count, ARCH_CONVERT)) > 0) { + if ((tmp = be16_to_cpu(node2->hdr.count)) > 0) { tmp *= (uint)sizeof(xfs_da_node_entry_t); btree_s = &node2->btree[0]; btree_d = &node2->btree[count]; @@ -472,13 +484,12 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, * Move the req'd B-tree elements from high in node1 to * low in node2. */ - INT_MOD(node2->hdr.count, ARCH_CONVERT, count); + be16_add_cpu(&node2->hdr.count, count); tmp = count * (uint)sizeof(xfs_da_node_entry_t); - btree_s = &node1->btree[INT_GET(node1->hdr.count, ARCH_CONVERT) - count]; + btree_s = &node1->btree[be16_to_cpu(node1->hdr.count) - count]; btree_d = &node2->btree[0]; memcpy(btree_d, btree_s, tmp); - INT_MOD(node1->hdr.count, ARCH_CONVERT, -(count)); - + be16_add_cpu(&node1->hdr.count, -count); } else { /* * Move the req'd B-tree elements from low in node2 to @@ -487,21 +498,21 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, count = -count; tmp = count * (uint)sizeof(xfs_da_node_entry_t); btree_s = &node2->btree[0]; - btree_d = &node1->btree[INT_GET(node1->hdr.count, ARCH_CONVERT)]; + btree_d = &node1->btree[be16_to_cpu(node1->hdr.count)]; memcpy(btree_d, btree_s, tmp); - INT_MOD(node1->hdr.count, ARCH_CONVERT, count); + be16_add_cpu(&node1->hdr.count, count); xfs_da_log_buf(tp, blk1->bp, XFS_DA_LOGRANGE(node1, btree_d, tmp)); /* * Move elements in node2 down to fill the hole. */ - tmp = INT_GET(node2->hdr.count, ARCH_CONVERT) - count; + tmp = be16_to_cpu(node2->hdr.count) - count; tmp *= (uint)sizeof(xfs_da_node_entry_t); btree_s = &node2->btree[count]; btree_d = &node2->btree[0]; memmove(btree_d, btree_s, tmp); - INT_MOD(node2->hdr.count, ARCH_CONVERT, -(count)); + be16_add_cpu(&node2->hdr.count, -count); } /* @@ -512,7 +523,7 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, xfs_da_log_buf(tp, blk2->bp, XFS_DA_LOGRANGE(node2, &node2->hdr, sizeof(node2->hdr) + - sizeof(node2->btree[0]) * INT_GET(node2->hdr.count, ARCH_CONVERT))); + sizeof(node2->btree[0]) * be16_to_cpu(node2->hdr.count))); /* * Record the last hashval from each block for upward propagation. @@ -520,15 +531,15 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, */ node1 = blk1->bp->data; node2 = blk2->bp->data; - blk1->hashval = INT_GET(node1->btree[ INT_GET(node1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); - blk2->hashval = INT_GET(node2->btree[ INT_GET(node2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); + blk1->hashval = be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval); + blk2->hashval = be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval); /* * Adjust the expected index for insertion. */ - if (blk1->index >= INT_GET(node1->hdr.count, ARCH_CONVERT)) { - blk2->index = blk1->index - INT_GET(node1->hdr.count, ARCH_CONVERT); - blk1->index = INT_GET(node1->hdr.count, ARCH_CONVERT) + 1; /* make it invalid */ + if (blk1->index >= be16_to_cpu(node1->hdr.count)) { + blk2->index = blk1->index - be16_to_cpu(node1->hdr.count); + blk1->index = be16_to_cpu(node1->hdr.count) + 1; /* make it invalid */ } } @@ -546,10 +557,10 @@ xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, node = oldblk->bp->data; mp = state->mp; - ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); - ASSERT((oldblk->index >= 0) && (oldblk->index <= INT_GET(node->hdr.count, ARCH_CONVERT))); + ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); + ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count))); ASSERT(newblk->blkno != 0); - if (state->args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) + if (state->args->whichfork == XFS_DATA_FORK) ASSERT(newblk->blkno >= mp->m_dirleafblk && newblk->blkno < mp->m_dirfreeblk); @@ -558,22 +569,22 @@ xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, */ tmp = 0; btree = &node->btree[ oldblk->index ]; - if (oldblk->index < INT_GET(node->hdr.count, ARCH_CONVERT)) { - tmp = (INT_GET(node->hdr.count, ARCH_CONVERT) - oldblk->index) * (uint)sizeof(*btree); + if (oldblk->index < be16_to_cpu(node->hdr.count)) { + tmp = (be16_to_cpu(node->hdr.count) - oldblk->index) * (uint)sizeof(*btree); memmove(btree + 1, btree, tmp); } - INT_SET(btree->hashval, ARCH_CONVERT, newblk->hashval); - INT_SET(btree->before, ARCH_CONVERT, newblk->blkno); + btree->hashval = cpu_to_be32(newblk->hashval); + btree->before = cpu_to_be32(newblk->blkno); xfs_da_log_buf(state->args->trans, oldblk->bp, XFS_DA_LOGRANGE(node, btree, tmp + sizeof(*btree))); - INT_MOD(node->hdr.count, ARCH_CONVERT, +1); + be16_add_cpu(&node->hdr.count, 1); xfs_da_log_buf(state->args->trans, oldblk->bp, XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); /* * Copy the last hash value from the oldblk to propagate upwards. */ - oldblk->hashval = INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); + oldblk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1 ].hashval); } /*======================================================================== @@ -595,7 +606,7 @@ xfs_da_join(xfs_da_state_t *state) save_blk = &state->altpath.blk[ state->path.active-1 ]; ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC); ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC || - drop_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp)); + drop_blk->magic == XFS_DIR2_LEAFN_MAGIC); /* * Walk back up the tree joining/deallocating as necessary. @@ -618,17 +629,7 @@ xfs_da_join(xfs_da_state_t *state) return(0); xfs_attr_leaf_unbalance(state, drop_blk, save_blk); break; - case XFS_DIR_LEAF_MAGIC: - ASSERT(XFS_DIR_IS_V1(state->mp)); - error = xfs_dir_leaf_toosmall(state, &action); - if (error) - return(error); - if (action == 0) - return(0); - xfs_dir_leaf_unbalance(state, drop_blk, save_blk); - break; case XFS_DIR2_LEAFN_MAGIC: - ASSERT(XFS_DIR_IS_V2(state->mp)); error = xfs_dir2_leafn_toosmall(state, &action); if (error) return error; @@ -692,21 +693,21 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk) ASSERT(args != NULL); ASSERT(root_blk->magic == XFS_DA_NODE_MAGIC); oldroot = root_blk->bp->data; - ASSERT(INT_GET(oldroot->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); + ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DA_NODE_MAGIC); ASSERT(!oldroot->hdr.info.forw); ASSERT(!oldroot->hdr.info.back); /* * If the root has more than one child, then don't do anything. */ - if (INT_GET(oldroot->hdr.count, ARCH_CONVERT) > 1) + if (be16_to_cpu(oldroot->hdr.count) > 1) return(0); /* * Read in the (only) child block, then copy those bytes into * the root block's buffer and free the original child block. */ - child = INT_GET(oldroot->btree[ 0 ].before, ARCH_CONVERT); + child = be32_to_cpu(oldroot->btree[0].before); ASSERT(child != 0); error = xfs_da_read_buf(args->trans, args->dp, child, -1, &bp, args->whichfork); @@ -714,11 +715,11 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk) return(error); ASSERT(bp != NULL); blkinfo = bp->data; - if (INT_GET(oldroot->hdr.level, ARCH_CONVERT) == 1) { - ASSERT(INT_GET(blkinfo->magic, ARCH_CONVERT) == XFS_DIRX_LEAF_MAGIC(state->mp) || - INT_GET(blkinfo->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC); + if (be16_to_cpu(oldroot->hdr.level) == 1) { + ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIR2_LEAFN_MAGIC || + be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC); } else { - ASSERT(INT_GET(blkinfo->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); + ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC); } ASSERT(!blkinfo->forw); ASSERT(!blkinfo->back); @@ -754,9 +755,9 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action) */ blk = &state->path.blk[ state->path.active-1 ]; info = blk->bp->data; - ASSERT(INT_GET(info->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); + ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC); node = (xfs_da_intnode_t *)info; - count = INT_GET(node->hdr.count, ARCH_CONVERT); + count = be16_to_cpu(node->hdr.count); if (count > (state->node_ents >> 1)) { *action = 0; /* blk over 50%, don't try to join */ return(0); /* blk over 50%, don't try to join */ @@ -765,7 +766,7 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action) /* * Check for the degenerate case of the block being empty. * If the block is empty, we'll simply delete it, no need to - * coalesce it with a sibling block. We choose (aribtrarily) + * coalesce it with a sibling block. We choose (arbitrarily) * to merge with the forward block unless it is NULL. */ if (count == 0) { @@ -773,7 +774,7 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action) * Make altpath point to the block we want to keep and * path point to the block we want to drop (this one). */ - forward = info->forw; + forward = (info->forw != 0); memcpy(&state->altpath, &state->path, sizeof(state->path)); error = xfs_da_path_shift(state, &state->altpath, forward, 0, &retval); @@ -795,13 +796,12 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action) * to shrink a directory over time. */ /* start with smaller blk num */ - forward = (INT_GET(info->forw, ARCH_CONVERT) - < INT_GET(info->back, ARCH_CONVERT)); + forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back)); for (i = 0; i < 2; forward = !forward, i++) { if (forward) - blkno = INT_GET(info->forw, ARCH_CONVERT); + blkno = be32_to_cpu(info->forw); else - blkno = INT_GET(info->back, ARCH_CONVERT); + blkno = be32_to_cpu(info->back); if (blkno == 0) continue; error = xfs_da_read_buf(state->args->trans, state->args->dp, @@ -813,10 +813,10 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action) node = (xfs_da_intnode_t *)info; count = state->node_ents; count -= state->node_ents >> 2; - count -= INT_GET(node->hdr.count, ARCH_CONVERT); + count -= be16_to_cpu(node->hdr.count); node = bp->data; - ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); - count -= INT_GET(node->hdr.count, ARCH_CONVERT); + ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); + count -= be16_to_cpu(node->hdr.count); xfs_da_brelse(state->args->trans, bp); if (count >= 0) break; /* fits with at least 25% to spare */ @@ -877,14 +877,7 @@ xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path) if (count == 0) return; break; - case XFS_DIR_LEAF_MAGIC: - ASSERT(XFS_DIR_IS_V1(state->mp)); - lasthash = xfs_dir_leaf_lasthash(blk->bp, &count); - if (count == 0) - return; - break; case XFS_DIR2_LEAFN_MAGIC: - ASSERT(XFS_DIR_IS_V2(state->mp)); lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count); if (count == 0) return; @@ -897,16 +890,16 @@ xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path) } for (blk--, level--; level >= 0; blk--, level--) { node = blk->bp->data; - ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); + ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); btree = &node->btree[ blk->index ]; - if (INT_GET(btree->hashval, ARCH_CONVERT) == lasthash) + if (be32_to_cpu(btree->hashval) == lasthash) break; blk->hashval = lasthash; - INT_SET(btree->hashval, ARCH_CONVERT, lasthash); + btree->hashval = cpu_to_be32(lasthash); xfs_da_log_buf(state->args->trans, blk->bp, XFS_DA_LOGRANGE(node, btree, sizeof(*btree))); - lasthash = INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); + lasthash = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval); } } @@ -921,25 +914,25 @@ xfs_da_node_remove(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk) int tmp; node = drop_blk->bp->data; - ASSERT(drop_blk->index < INT_GET(node->hdr.count, ARCH_CONVERT)); + ASSERT(drop_blk->index < be16_to_cpu(node->hdr.count)); ASSERT(drop_blk->index >= 0); /* * Copy over the offending entry, or just zero it out. */ btree = &node->btree[drop_blk->index]; - if (drop_blk->index < (INT_GET(node->hdr.count, ARCH_CONVERT)-1)) { - tmp = INT_GET(node->hdr.count, ARCH_CONVERT) - drop_blk->index - 1; + if (drop_blk->index < (be16_to_cpu(node->hdr.count)-1)) { + tmp = be16_to_cpu(node->hdr.count) - drop_blk->index - 1; tmp *= (uint)sizeof(xfs_da_node_entry_t); memmove(btree, btree + 1, tmp); xfs_da_log_buf(state->args->trans, drop_blk->bp, XFS_DA_LOGRANGE(node, btree, tmp)); - btree = &node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ]; + btree = &node->btree[be16_to_cpu(node->hdr.count)-1]; } memset((char *)btree, 0, sizeof(xfs_da_node_entry_t)); xfs_da_log_buf(state->args->trans, drop_blk->bp, XFS_DA_LOGRANGE(node, btree, sizeof(*btree))); - INT_MOD(node->hdr.count, ARCH_CONVERT, -1); + be16_add_cpu(&node->hdr.count, -1); xfs_da_log_buf(state->args->trans, drop_blk->bp, XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); @@ -947,7 +940,7 @@ xfs_da_node_remove(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk) * Copy the last hash value from the block to propagate upwards. */ btree--; - drop_blk->hashval = INT_GET(btree->hashval, ARCH_CONVERT); + drop_blk->hashval = be32_to_cpu(btree->hashval); } /* @@ -965,40 +958,40 @@ xfs_da_node_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, drop_node = drop_blk->bp->data; save_node = save_blk->bp->data; - ASSERT(INT_GET(drop_node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); - ASSERT(INT_GET(save_node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); + ASSERT(be16_to_cpu(drop_node->hdr.info.magic) == XFS_DA_NODE_MAGIC); + ASSERT(be16_to_cpu(save_node->hdr.info.magic) == XFS_DA_NODE_MAGIC); tp = state->args->trans; /* * If the dying block has lower hashvals, then move all the * elements in the remaining block up to make a hole. */ - if ((INT_GET(drop_node->btree[ 0 ].hashval, ARCH_CONVERT) < INT_GET(save_node->btree[ 0 ].hashval, ARCH_CONVERT)) || - (INT_GET(drop_node->btree[ INT_GET(drop_node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) < - INT_GET(save_node->btree[ INT_GET(save_node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT))) + if ((be32_to_cpu(drop_node->btree[0].hashval) < be32_to_cpu(save_node->btree[ 0 ].hashval)) || + (be32_to_cpu(drop_node->btree[be16_to_cpu(drop_node->hdr.count)-1].hashval) < + be32_to_cpu(save_node->btree[be16_to_cpu(save_node->hdr.count)-1].hashval))) { - btree = &save_node->btree[ INT_GET(drop_node->hdr.count, ARCH_CONVERT) ]; - tmp = INT_GET(save_node->hdr.count, ARCH_CONVERT) * (uint)sizeof(xfs_da_node_entry_t); + btree = &save_node->btree[be16_to_cpu(drop_node->hdr.count)]; + tmp = be16_to_cpu(save_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t); memmove(btree, &save_node->btree[0], tmp); btree = &save_node->btree[0]; xfs_da_log_buf(tp, save_blk->bp, XFS_DA_LOGRANGE(save_node, btree, - (INT_GET(save_node->hdr.count, ARCH_CONVERT) + INT_GET(drop_node->hdr.count, ARCH_CONVERT)) * + (be16_to_cpu(save_node->hdr.count) + be16_to_cpu(drop_node->hdr.count)) * sizeof(xfs_da_node_entry_t))); } else { - btree = &save_node->btree[ INT_GET(save_node->hdr.count, ARCH_CONVERT) ]; + btree = &save_node->btree[be16_to_cpu(save_node->hdr.count)]; xfs_da_log_buf(tp, save_blk->bp, XFS_DA_LOGRANGE(save_node, btree, - INT_GET(drop_node->hdr.count, ARCH_CONVERT) * + be16_to_cpu(drop_node->hdr.count) * sizeof(xfs_da_node_entry_t))); } /* * Move all the B-tree elements from drop_blk to save_blk. */ - tmp = INT_GET(drop_node->hdr.count, ARCH_CONVERT) * (uint)sizeof(xfs_da_node_entry_t); + tmp = be16_to_cpu(drop_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t); memcpy(btree, &drop_node->btree[0], tmp); - INT_MOD(save_node->hdr.count, ARCH_CONVERT, INT_GET(drop_node->hdr.count, ARCH_CONVERT)); + be16_add_cpu(&save_node->hdr.count, be16_to_cpu(drop_node->hdr.count)); xfs_da_log_buf(tp, save_blk->bp, XFS_DA_LOGRANGE(save_node, &save_node->hdr, @@ -1007,7 +1000,7 @@ xfs_da_node_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, /* * Save the last hashval in the remaining block for upward propagation. */ - save_blk->hashval = INT_GET(save_node->btree[ INT_GET(save_node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); + save_blk->hashval = be32_to_cpu(save_node->btree[be16_to_cpu(save_node->hdr.count)-1].hashval); } /*======================================================================== @@ -1034,7 +1027,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) xfs_da_node_entry_t *btree; xfs_dablk_t blkno; int probe, span, max, error, retval; - xfs_dahash_t hashval; + xfs_dahash_t hashval, btreehashval; xfs_da_args_t *args; args = state->args; @@ -1043,10 +1036,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) * Descend thru the B-tree searching each level for the right * node to use, until the right hashval is found. */ - if (args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(state->mp)) - blkno = state->mp->m_dirleafblk; - else - blkno = 0; + blkno = (args->whichfork == XFS_DATA_FORK)? state->mp->m_dirleafblk : 0; for (blk = &state->path.blk[0], state->path.active = 1; state->path.active <= XFS_DA_NODE_MAXDEPTH; blk++, state->path.active++) { @@ -1062,46 +1052,47 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) return(error); } curr = blk->bp->data; - ASSERT(INT_GET(curr->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC || - INT_GET(curr->magic, ARCH_CONVERT) == XFS_DIRX_LEAF_MAGIC(state->mp) || - INT_GET(curr->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC); + blk->magic = be16_to_cpu(curr->magic); + ASSERT(blk->magic == XFS_DA_NODE_MAGIC || + blk->magic == XFS_DIR2_LEAFN_MAGIC || + blk->magic == XFS_ATTR_LEAF_MAGIC); /* * Search an intermediate node for a match. */ - blk->magic = INT_GET(curr->magic, ARCH_CONVERT); - if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) { + if (blk->magic == XFS_DA_NODE_MAGIC) { node = blk->bp->data; - blk->hashval = INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); + max = be16_to_cpu(node->hdr.count); + blk->hashval = be32_to_cpu(node->btree[max-1].hashval); /* * Binary search. (note: small blocks will skip loop) */ - max = INT_GET(node->hdr.count, ARCH_CONVERT); probe = span = max / 2; hashval = args->hashval; for (btree = &node->btree[probe]; span > 4; btree = &node->btree[probe]) { span /= 2; - if (INT_GET(btree->hashval, ARCH_CONVERT) < hashval) + btreehashval = be32_to_cpu(btree->hashval); + if (btreehashval < hashval) probe += span; - else if (INT_GET(btree->hashval, ARCH_CONVERT) > hashval) + else if (btreehashval > hashval) probe -= span; else break; } ASSERT((probe >= 0) && (probe < max)); - ASSERT((span <= 4) || (INT_GET(btree->hashval, ARCH_CONVERT) == hashval)); + ASSERT((span <= 4) || (be32_to_cpu(btree->hashval) == hashval)); /* * Since we may have duplicate hashval's, find the first * matching hashval in the node. */ - while ((probe > 0) && (INT_GET(btree->hashval, ARCH_CONVERT) >= hashval)) { + while ((probe > 0) && (be32_to_cpu(btree->hashval) >= hashval)) { btree--; probe--; } - while ((probe < max) && (INT_GET(btree->hashval, ARCH_CONVERT) < hashval)) { + while ((probe < max) && (be32_to_cpu(btree->hashval) < hashval)) { btree++; probe++; } @@ -1111,21 +1102,15 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) */ if (probe == max) { blk->index = max-1; - blkno = INT_GET(node->btree[ max-1 ].before, ARCH_CONVERT); + blkno = be32_to_cpu(node->btree[max-1].before); } else { blk->index = probe; - blkno = INT_GET(btree->before, ARCH_CONVERT); + blkno = be32_to_cpu(btree->before); } - } - else if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC) { + } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); break; - } - else if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC) { - blk->hashval = xfs_dir_leaf_lasthash(blk->bp, NULL); - break; - } - else if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC) { + } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); break; } @@ -1138,19 +1123,16 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) * next leaf and keep searching. */ for (;;) { - if (blk->magic == XFS_DIR_LEAF_MAGIC) { - ASSERT(XFS_DIR_IS_V1(state->mp)); - retval = xfs_dir_leaf_lookup_int(blk->bp, args, - &blk->index); - } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { - ASSERT(XFS_DIR_IS_V2(state->mp)); + if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { retval = xfs_dir2_leafn_lookup_int(blk->bp, args, &blk->index, state); - } - else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { + } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { retval = xfs_attr_leaf_lookup_int(blk->bp, args); blk->index = args->index; args->blkno = blk->blkno; + } else { + ASSERT(0); + return XFS_ERROR(EFSCORRUPTED); } if (((retval == ENOENT) || (retval == ENOATTR)) && (blk->hashval == args->hashval)) { @@ -1160,8 +1142,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) return(error); if (retval == 0) { continue; - } - else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { + } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { /* path_shift() gives ENOENT */ retval = XFS_ERROR(ENOATTR); } @@ -1196,22 +1177,17 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, old_info = old_blk->bp->data; new_info = new_blk->bp->data; ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC || - old_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) || + old_blk->magic == XFS_DIR2_LEAFN_MAGIC || old_blk->magic == XFS_ATTR_LEAF_MAGIC); - ASSERT(old_blk->magic == INT_GET(old_info->magic, ARCH_CONVERT)); - ASSERT(new_blk->magic == INT_GET(new_info->magic, ARCH_CONVERT)); + ASSERT(old_blk->magic == be16_to_cpu(old_info->magic)); + ASSERT(new_blk->magic == be16_to_cpu(new_info->magic)); ASSERT(old_blk->magic == new_blk->magic); switch (old_blk->magic) { case XFS_ATTR_LEAF_MAGIC: before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp); break; - case XFS_DIR_LEAF_MAGIC: - ASSERT(XFS_DIR_IS_V1(state->mp)); - before = xfs_dir_leaf_order(old_blk->bp, new_blk->bp); - break; case XFS_DIR2_LEAFN_MAGIC: - ASSERT(XFS_DIR_IS_V2(state->mp)); before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp); break; case XFS_DA_NODE_MAGIC: @@ -1226,47 +1202,44 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, /* * Link new block in before existing block. */ - INT_SET(new_info->forw, ARCH_CONVERT, old_blk->blkno); - new_info->back = old_info->back; /* INT_: direct copy */ - if (INT_GET(old_info->back, ARCH_CONVERT)) { + new_info->forw = cpu_to_be32(old_blk->blkno); + new_info->back = old_info->back; + if (old_info->back) { error = xfs_da_read_buf(args->trans, args->dp, - INT_GET(old_info->back, - ARCH_CONVERT), -1, &bp, - args->whichfork); + be32_to_cpu(old_info->back), + -1, &bp, args->whichfork); if (error) return(error); ASSERT(bp != NULL); tmp_info = bp->data; - ASSERT(INT_GET(tmp_info->magic, ARCH_CONVERT) == INT_GET(old_info->magic, ARCH_CONVERT)); - ASSERT(INT_GET(tmp_info->forw, ARCH_CONVERT) == old_blk->blkno); - INT_SET(tmp_info->forw, ARCH_CONVERT, new_blk->blkno); + ASSERT(be16_to_cpu(tmp_info->magic) == be16_to_cpu(old_info->magic)); + ASSERT(be32_to_cpu(tmp_info->forw) == old_blk->blkno); + tmp_info->forw = cpu_to_be32(new_blk->blkno); xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1); xfs_da_buf_done(bp); } - INT_SET(old_info->back, ARCH_CONVERT, new_blk->blkno); + old_info->back = cpu_to_be32(new_blk->blkno); } else { /* * Link new block in after existing block. */ - new_info->forw = old_info->forw; /* INT_: direct copy */ - INT_SET(new_info->back, ARCH_CONVERT, old_blk->blkno); - if (INT_GET(old_info->forw, ARCH_CONVERT)) { + new_info->forw = old_info->forw; + new_info->back = cpu_to_be32(old_blk->blkno); + if (old_info->forw) { error = xfs_da_read_buf(args->trans, args->dp, - INT_GET(old_info->forw, ARCH_CONVERT), -1, &bp, - args->whichfork); + be32_to_cpu(old_info->forw), + -1, &bp, args->whichfork); if (error) return(error); ASSERT(bp != NULL); tmp_info = bp->data; - ASSERT(INT_GET(tmp_info->magic, ARCH_CONVERT) - == INT_GET(old_info->magic, ARCH_CONVERT)); - ASSERT(INT_GET(tmp_info->back, ARCH_CONVERT) - == old_blk->blkno); - INT_SET(tmp_info->back, ARCH_CONVERT, new_blk->blkno); + ASSERT(tmp_info->magic == old_info->magic); + ASSERT(be32_to_cpu(tmp_info->back) == old_blk->blkno); + tmp_info->back = cpu_to_be32(new_blk->blkno); xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1); xfs_da_buf_done(bp); } - INT_SET(old_info->forw, ARCH_CONVERT, new_blk->blkno); + old_info->forw = cpu_to_be32(new_blk->blkno); } xfs_da_log_buf(args->trans, old_blk->bp, 0, sizeof(*tmp_info) - 1); @@ -1284,13 +1257,13 @@ xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp) node1 = node1_bp->data; node2 = node2_bp->data; - ASSERT((INT_GET(node1->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) && - (INT_GET(node2->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC)); - if ((INT_GET(node1->hdr.count, ARCH_CONVERT) > 0) && (INT_GET(node2->hdr.count, ARCH_CONVERT) > 0) && - ((INT_GET(node2->btree[ 0 ].hashval, ARCH_CONVERT) < - INT_GET(node1->btree[ 0 ].hashval, ARCH_CONVERT)) || - (INT_GET(node2->btree[ INT_GET(node2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) < - INT_GET(node1->btree[ INT_GET(node1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)))) { + ASSERT((be16_to_cpu(node1->hdr.info.magic) == XFS_DA_NODE_MAGIC) && + (be16_to_cpu(node2->hdr.info.magic) == XFS_DA_NODE_MAGIC)); + if ((be16_to_cpu(node1->hdr.count) > 0) && (be16_to_cpu(node2->hdr.count) > 0) && + ((be32_to_cpu(node2->btree[0].hashval) < + be32_to_cpu(node1->btree[0].hashval)) || + (be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval) < + be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval)))) { return(1); } return(0); @@ -1305,18 +1278,18 @@ xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count) xfs_da_intnode_t *node; node = bp->data; - ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); + ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); if (count) - *count = INT_GET(node->hdr.count, ARCH_CONVERT); + *count = be16_to_cpu(node->hdr.count); if (!node->hdr.count) return(0); - return(INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)); + return be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval); } /* * Unlink a block from a doubly linked list of blocks. */ -int /* error */ +STATIC int /* error */ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, xfs_da_state_blk_t *save_blk) { @@ -1333,52 +1306,49 @@ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, save_info = save_blk->bp->data; drop_info = drop_blk->bp->data; ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC || - save_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) || + save_blk->magic == XFS_DIR2_LEAFN_MAGIC || save_blk->magic == XFS_ATTR_LEAF_MAGIC); - ASSERT(save_blk->magic == INT_GET(save_info->magic, ARCH_CONVERT)); - ASSERT(drop_blk->magic == INT_GET(drop_info->magic, ARCH_CONVERT)); + ASSERT(save_blk->magic == be16_to_cpu(save_info->magic)); + ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic)); ASSERT(save_blk->magic == drop_blk->magic); - ASSERT((INT_GET(save_info->forw, ARCH_CONVERT) == drop_blk->blkno) || - (INT_GET(save_info->back, ARCH_CONVERT) == drop_blk->blkno)); - ASSERT((INT_GET(drop_info->forw, ARCH_CONVERT) == save_blk->blkno) || - (INT_GET(drop_info->back, ARCH_CONVERT) == save_blk->blkno)); + ASSERT((be32_to_cpu(save_info->forw) == drop_blk->blkno) || + (be32_to_cpu(save_info->back) == drop_blk->blkno)); + ASSERT((be32_to_cpu(drop_info->forw) == save_blk->blkno) || + (be32_to_cpu(drop_info->back) == save_blk->blkno)); /* * Unlink the leaf block from the doubly linked chain of leaves. */ - if (INT_GET(save_info->back, ARCH_CONVERT) == drop_blk->blkno) { - save_info->back = drop_info->back; /* INT_: direct copy */ - if (INT_GET(drop_info->back, ARCH_CONVERT)) { + if (be32_to_cpu(save_info->back) == drop_blk->blkno) { + save_info->back = drop_info->back; + if (drop_info->back) { error = xfs_da_read_buf(args->trans, args->dp, - INT_GET(drop_info->back, - ARCH_CONVERT), -1, &bp, - args->whichfork); + be32_to_cpu(drop_info->back), + -1, &bp, args->whichfork); if (error) return(error); ASSERT(bp != NULL); tmp_info = bp->data; - ASSERT(INT_GET(tmp_info->magic, ARCH_CONVERT) == INT_GET(save_info->magic, ARCH_CONVERT)); - ASSERT(INT_GET(tmp_info->forw, ARCH_CONVERT) == drop_blk->blkno); - INT_SET(tmp_info->forw, ARCH_CONVERT, save_blk->blkno); + ASSERT(tmp_info->magic == save_info->magic); + ASSERT(be32_to_cpu(tmp_info->forw) == drop_blk->blkno); + tmp_info->forw = cpu_to_be32(save_blk->blkno); xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info) - 1); xfs_da_buf_done(bp); } } else { - save_info->forw = drop_info->forw; /* INT_: direct copy */ - if (INT_GET(drop_info->forw, ARCH_CONVERT)) { + save_info->forw = drop_info->forw; + if (drop_info->forw) { error = xfs_da_read_buf(args->trans, args->dp, - INT_GET(drop_info->forw, ARCH_CONVERT), -1, &bp, - args->whichfork); + be32_to_cpu(drop_info->forw), + -1, &bp, args->whichfork); if (error) return(error); ASSERT(bp != NULL); tmp_info = bp->data; - ASSERT(INT_GET(tmp_info->magic, ARCH_CONVERT) - == INT_GET(save_info->magic, ARCH_CONVERT)); - ASSERT(INT_GET(tmp_info->back, ARCH_CONVERT) - == drop_blk->blkno); - INT_SET(tmp_info->back, ARCH_CONVERT, save_blk->blkno); + ASSERT(tmp_info->magic == save_info->magic); + ASSERT(be32_to_cpu(tmp_info->back) == drop_blk->blkno); + tmp_info->back = cpu_to_be32(save_blk->blkno); xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info) - 1); xfs_da_buf_done(bp); @@ -1421,20 +1391,20 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, for (blk = &path->blk[level]; level >= 0; blk--, level--) { ASSERT(blk->bp != NULL); node = blk->bp->data; - ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); - if (forward && (blk->index < INT_GET(node->hdr.count, ARCH_CONVERT)-1)) { + ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); + if (forward && (blk->index < be16_to_cpu(node->hdr.count)-1)) { blk->index++; - blkno = INT_GET(node->btree[ blk->index ].before, ARCH_CONVERT); + blkno = be32_to_cpu(node->btree[blk->index].before); break; } else if (!forward && (blk->index > 0)) { blk->index--; - blkno = INT_GET(node->btree[ blk->index ].before, ARCH_CONVERT); + blkno = be32_to_cpu(node->btree[blk->index].before); break; } } if (level < 0) { *result = XFS_ERROR(ENOENT); /* we're out of our tree */ - ASSERT(args->oknoent); + ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); return(0); } @@ -1460,18 +1430,18 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, return(error); ASSERT(blk->bp != NULL); info = blk->bp->data; - ASSERT(INT_GET(info->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC || - INT_GET(info->magic, ARCH_CONVERT) == XFS_DIRX_LEAF_MAGIC(state->mp) || - INT_GET(info->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC); - blk->magic = INT_GET(info->magic, ARCH_CONVERT); - if (INT_GET(info->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) { + ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC || + be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC || + be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC); + blk->magic = be16_to_cpu(info->magic); + if (blk->magic == XFS_DA_NODE_MAGIC) { node = (xfs_da_intnode_t *)info; - blk->hashval = INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); + blk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval); if (forward) blk->index = 0; else - blk->index = INT_GET(node->hdr.count, ARCH_CONVERT)-1; - blkno = INT_GET(node->btree[ blk->index ].before, ARCH_CONVERT); + blk->index = be16_to_cpu(node->hdr.count)-1; + blkno = be32_to_cpu(node->btree[blk->index].before); } else { ASSERT(level == path->active-1); blk->index = 0; @@ -1480,20 +1450,13 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); break; - case XFS_DIR_LEAF_MAGIC: - ASSERT(XFS_DIR_IS_V1(state->mp)); - blk->hashval = xfs_dir_leaf_lasthash(blk->bp, - NULL); - break; case XFS_DIR2_LEAFN_MAGIC: - ASSERT(XFS_DIR_IS_V2(state->mp)); blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); break; default: ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC || - blk->magic == - XFS_DIRX_LEAF_MAGIC(state->mp)); + blk->magic == XFS_DIR2_LEAFN_MAGIC); break; } } @@ -1541,14 +1504,24 @@ 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) +xfs_da_compname( + struct xfs_da_args *args, + const char *name, + int len) { - return (len1 == len2 && memcmp(name1, name2, len1) == 0) ? + return (args->namelen == len && memcmp(args->name, name, len) == 0) ? 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_da_hashname, + .hashname = xfs_default_hashname, .compname = xfs_da_compname }; @@ -1564,7 +1537,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) xfs_bmbt_irec_t *mapp; xfs_inode_t *dp; int nmap, error, w, count, c, got, i, mapi; - xfs_fsize_t size; xfs_trans_t *tp; xfs_mount_t *mp; @@ -1575,7 +1547,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) /* * For new directories adjust the file offset and block count. */ - if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) { + if (w == XFS_DATA_FORK) { bno = mp->m_dirleafblk; count = mp->m_dirblkfsbs; } else { @@ -1585,10 +1557,9 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) /* * Find a spot in the file space to put the new block. */ - if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) { + if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) return error; - } - if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) + if (w == XFS_DATA_FORK) ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk); /* * Try mapping it in one filesystem block. @@ -1599,7 +1570,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA| XFS_BMAPI_CONTIG, args->firstblock, args->total, &map, &nmap, - args->flist))) { + args->flist, NULL))) { return error; } ASSERT(nmap <= 1); @@ -1620,8 +1591,9 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE| XFS_BMAPI_METADATA, args->firstblock, args->total, - &mapp[mapi], &nmap, args->flist))) { - kmem_free(mapp, sizeof(*mapp) * count); + &mapp[mapi], &nmap, args->flist, + NULL))) { + kmem_free(mapp); return error; } if (nmap < 1) @@ -1643,25 +1615,12 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount != bno + count) { if (mapp != &map) - kmem_free(mapp, sizeof(*mapp) * count); + kmem_free(mapp); return XFS_ERROR(ENOSPC); } if (mapp != &map) - kmem_free(mapp, sizeof(*mapp) * count); + kmem_free(mapp); *new_blkno = (xfs_dablk_t)bno; - /* - * For version 1 directories, adjust the file size if it changed. - */ - if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) { - ASSERT(mapi == 1); - if ((error = xfs_bmap_last_offset(tp, dp, &bno, w))) - return error; - size = XFS_FSB_TO_B(mp, bno); - if (size != dp->i_d.di_size) { - dp->i_d.di_size = size; - xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); - } - } return 0; } @@ -1686,7 +1645,6 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, int error, w, entno, level, dead_level; xfs_da_blkinfo_t *dead_info, *sib_info; xfs_da_intnode_t *par_node, *dead_node; - xfs_dir_leafblock_t *dead_leaf; xfs_dir2_leaf_t *dead_leaf2; xfs_dahash_t dead_hash; @@ -1697,11 +1655,8 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, w = args->whichfork; ASSERT(w == XFS_DATA_FORK); mp = ip->i_mount; - if (XFS_DIR_IS_V2(mp)) { - lastoff = mp->m_dirfreeblk; - error = xfs_bmap_last_before(tp, ip, &lastoff, w); - } else - error = xfs_bmap_last_offset(tp, ip, &lastoff, w); + lastoff = mp->m_dirfreeblk; + error = xfs_bmap_last_before(tp, ip, &lastoff, w); if (error) return error; if (unlikely(lastoff == 0)) { @@ -1724,40 +1679,33 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, /* * Get values from the moved block. */ - if (INT_GET(dead_info->magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC) { - ASSERT(XFS_DIR_IS_V1(mp)); - dead_leaf = (xfs_dir_leafblock_t *)dead_info; - dead_level = 0; - dead_hash = - INT_GET(dead_leaf->entries[INT_GET(dead_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT); - } else if (INT_GET(dead_info->magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC) { - ASSERT(XFS_DIR_IS_V2(mp)); + if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) { dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; dead_level = 0; - dead_hash = INT_GET(dead_leaf2->ents[INT_GET(dead_leaf2->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT); + dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval); } else { - ASSERT(INT_GET(dead_info->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); + ASSERT(be16_to_cpu(dead_info->magic) == XFS_DA_NODE_MAGIC); dead_node = (xfs_da_intnode_t *)dead_info; - dead_level = INT_GET(dead_node->hdr.level, ARCH_CONVERT); - dead_hash = INT_GET(dead_node->btree[INT_GET(dead_node->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT); + dead_level = be16_to_cpu(dead_node->hdr.level); + dead_hash = be32_to_cpu(dead_node->btree[be16_to_cpu(dead_node->hdr.count) - 1].hashval); } sib_buf = par_buf = NULL; /* * If the moved block has a left sibling, fix up the pointers. */ - if ((sib_blkno = INT_GET(dead_info->back, ARCH_CONVERT))) { + if ((sib_blkno = be32_to_cpu(dead_info->back))) { if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w))) goto done; sib_info = sib_buf->data; if (unlikely( - INT_GET(sib_info->forw, ARCH_CONVERT) != last_blkno || - INT_GET(sib_info->magic, ARCH_CONVERT) != INT_GET(dead_info->magic, ARCH_CONVERT))) { + be32_to_cpu(sib_info->forw) != last_blkno || + sib_info->magic != dead_info->magic)) { XFS_ERROR_REPORT("xfs_da_swap_lastblock(2)", XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } - INT_SET(sib_info->forw, ARCH_CONVERT, dead_blkno); + sib_info->forw = cpu_to_be32(dead_blkno); xfs_da_log_buf(tp, sib_buf, XFS_DA_LOGRANGE(sib_info, &sib_info->forw, sizeof(sib_info->forw))); @@ -1767,27 +1715,26 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, /* * If the moved block has a right sibling, fix up the pointers. */ - if ((sib_blkno = INT_GET(dead_info->forw, ARCH_CONVERT))) { + if ((sib_blkno = be32_to_cpu(dead_info->forw))) { if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w))) goto done; sib_info = sib_buf->data; if (unlikely( - INT_GET(sib_info->back, ARCH_CONVERT) != last_blkno - || INT_GET(sib_info->magic, ARCH_CONVERT) - != INT_GET(dead_info->magic, ARCH_CONVERT))) { + be32_to_cpu(sib_info->back) != last_blkno || + sib_info->magic != dead_info->magic)) { XFS_ERROR_REPORT("xfs_da_swap_lastblock(3)", XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } - INT_SET(sib_info->back, ARCH_CONVERT, dead_blkno); + sib_info->back = cpu_to_be32(dead_blkno); xfs_da_log_buf(tp, sib_buf, XFS_DA_LOGRANGE(sib_info, &sib_info->back, sizeof(sib_info->back))); xfs_da_buf_done(sib_buf); sib_buf = NULL; } - par_blkno = XFS_DIR_IS_V1(mp) ? 0 : mp->m_dirleafblk; + par_blkno = mp->m_dirleafblk; level = -1; /* * Walk down the tree looking for the parent of the moved block. @@ -1797,26 +1744,26 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, goto done; par_node = par_buf->data; if (unlikely( - INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC || - (level >= 0 && level != INT_GET(par_node->hdr.level, ARCH_CONVERT) + 1))) { + be16_to_cpu(par_node->hdr.info.magic) != XFS_DA_NODE_MAGIC || + (level >= 0 && level != be16_to_cpu(par_node->hdr.level) + 1))) { XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)", XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } - level = INT_GET(par_node->hdr.level, ARCH_CONVERT); + level = be16_to_cpu(par_node->hdr.level); for (entno = 0; - entno < INT_GET(par_node->hdr.count, ARCH_CONVERT) && - INT_GET(par_node->btree[entno].hashval, ARCH_CONVERT) < dead_hash; + entno < be16_to_cpu(par_node->hdr.count) && + be32_to_cpu(par_node->btree[entno].hashval) < dead_hash; entno++) continue; - if (unlikely(entno == INT_GET(par_node->hdr.count, ARCH_CONVERT))) { + if (unlikely(entno == be16_to_cpu(par_node->hdr.count))) { XFS_ERROR_REPORT("xfs_da_swap_lastblock(5)", XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } - par_blkno = INT_GET(par_node->btree[entno].before, ARCH_CONVERT); + par_blkno = be32_to_cpu(par_node->btree[entno].before); if (level == dead_level + 1) break; xfs_da_brelse(tp, par_buf); @@ -1828,13 +1775,13 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, */ for (;;) { for (; - entno < INT_GET(par_node->hdr.count, ARCH_CONVERT) && - INT_GET(par_node->btree[entno].before, ARCH_CONVERT) != last_blkno; + entno < be16_to_cpu(par_node->hdr.count) && + be32_to_cpu(par_node->btree[entno].before) != last_blkno; entno++) continue; - if (entno < INT_GET(par_node->hdr.count, ARCH_CONVERT)) + if (entno < be16_to_cpu(par_node->hdr.count)) break; - par_blkno = INT_GET(par_node->hdr.info.forw, ARCH_CONVERT); + par_blkno = be32_to_cpu(par_node->hdr.info.forw); xfs_da_brelse(tp, par_buf); par_buf = NULL; if (unlikely(par_blkno == 0)) { @@ -1847,8 +1794,8 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, goto done; par_node = par_buf->data; if (unlikely( - INT_GET(par_node->hdr.level, ARCH_CONVERT) != level || - INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC)) { + be16_to_cpu(par_node->hdr.level) != level || + be16_to_cpu(par_node->hdr.info.magic) != XFS_DA_NODE_MAGIC)) { XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)", XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); @@ -1859,7 +1806,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, /* * Update the parent entry pointing to the moved block. */ - INT_SET(par_node->btree[entno].before, ARCH_CONVERT, dead_blkno); + par_node->btree[entno].before = cpu_to_be32(dead_blkno); xfs_da_log_buf(tp, par_buf, XFS_DA_LOGRANGE(par_node, &par_node->btree[entno].before, sizeof(par_node->btree[entno].before))); @@ -1886,8 +1833,6 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, { xfs_inode_t *dp; int done, error, w, count; - xfs_fileoff_t bno; - xfs_fsize_t size; xfs_trans_t *tp; xfs_mount_t *mp; @@ -1895,7 +1840,7 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, w = args->whichfork; tp = args->trans; mp = dp->i_mount; - if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) + if (w == XFS_DATA_FORK) count = mp->m_dirblkfsbs; else count = 1; @@ -1906,34 +1851,17 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, */ if ((error = xfs_bunmapi(tp, dp, dead_blkno, count, XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA, - 0, args->firstblock, args->flist, + 0, args->firstblock, args->flist, NULL, &done)) == ENOSPC) { if (w != XFS_DATA_FORK) - goto done; + break; if ((error = xfs_da_swap_lastblock(args, &dead_blkno, &dead_buf))) - goto done; - } else if (error) - goto done; - else + break; + } else { break; - } - ASSERT(done); - xfs_da_binval(tp, dead_buf); - /* - * Adjust the directory size for version 1. - */ - if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) { - if ((error = xfs_bmap_last_offset(tp, dp, &bno, w))) - return error; - size = XFS_FSB_TO_B(dp->i_mount, bno); - if (size != dp->i_d.di_size) { - dp->i_d.di_size = size; - xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); } } - return 0; -done: xfs_da_binval(tp, dead_buf); return error; } @@ -1968,8 +1896,10 @@ xfs_da_map_covers_blocks( /* * Make a dabuf. * Used for get_buf, read_buf, read_bufr, and reada_buf. + * + * Note: this requires user-space public scope for libxfs_da_read_bufr */ -STATIC int +int xfs_da_do_buf( xfs_trans_t *trans, xfs_inode_t *dp, @@ -1994,10 +1924,7 @@ xfs_da_do_buf( xfs_dabuf_t *rbp; mp = dp->i_mount; - if (whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) - nfsb = mp->m_dirblkfsbs; - else - nfsb = 1; + nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1; mappedbno = *mappedbnop; /* * Caller doesn't have a mapping. -2 means don't complain @@ -2031,7 +1958,7 @@ xfs_da_do_buf( nfsb, XFS_BMAPI_METADATA | XFS_BMAPI_AFLAG(whichfork), - NULL, 0, mapp, &nmap, NULL))) + NULL, 0, mapp, &nmap, NULL, NULL))) goto exit0; } } else { @@ -2045,7 +1972,6 @@ xfs_da_do_buf( error = mappedbno == -2 ? 0 : XFS_ERROR(EFSCORRUPTED); if (unlikely(error == EFSCORRUPTED)) { if (xfs_error_level >= XFS_ERRLEVEL_LOW) { - int i; cmn_err(CE_ALERT, "xfs_da_do_buf: bno %lld\n", (long long)bno); cmn_err(CE_ALERT, "dir: inode %lld\n", @@ -2139,17 +2065,16 @@ xfs_da_do_buf( info = rbp->data; data = rbp->data; free = rbp->data; - magic = INT_GET(info->magic, ARCH_CONVERT); - magic1 = INT_GET(data->hdr.magic, ARCH_CONVERT); + magic = be16_to_cpu(info->magic); + magic1 = be32_to_cpu(data->hdr.magic); if (unlikely( XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && - (magic != XFS_DIR_LEAF_MAGIC) && (magic != XFS_ATTR_LEAF_MAGIC) && (magic != XFS_DIR2_LEAF1_MAGIC) && (magic != XFS_DIR2_LEAFN_MAGIC) && (magic1 != XFS_DIR2_BLOCK_MAGIC) && (magic1 != XFS_DIR2_DATA_MAGIC) && - (INT_GET(free->hdr.magic, ARCH_CONVERT) != XFS_DIR2_FREE_MAGIC), + (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC), mp, XFS_ERRTAG_DA_READ_BUF, XFS_RANDOM_DA_READ_BUF))) { xfs_buftrace("DA READ ERROR", rbp->bps[0]); @@ -2162,10 +2087,10 @@ xfs_da_do_buf( } } if (bplist) { - kmem_free(bplist, sizeof(*bplist) * nmap); + kmem_free(bplist); } if (mapp != &map) { - kmem_free(mapp, sizeof(*mapp) * nfsb); + kmem_free(mapp); } if (bpp) *bpp = rbp; @@ -2174,11 +2099,11 @@ exit1: if (bplist) { for (i = 0; i < nbplist; i++) xfs_trans_brelse(trans, bplist[i]); - kmem_free(bplist, sizeof(*bplist) * nmap); + kmem_free(bplist); } exit0: if (mapp != &map) - kmem_free(mapp, sizeof(*mapp) * nfsb); + kmem_free(mapp); if (bpp) *bpp = NULL; return error; @@ -2217,22 +2142,27 @@ xfs_da_read_buf( } /* - * Calculate the number of bits needed to hold i different values. + * Readahead the dir/attr block. */ -uint -xfs_da_log2_roundup(uint i) +xfs_daddr_t +xfs_da_reada_buf( + xfs_trans_t *trans, + xfs_inode_t *dp, + xfs_dablk_t bno, + int whichfork) { - uint rval; + xfs_daddr_t rval; - for (rval = 0; rval < NBBY * sizeof(i); rval++) { - if ((1 << rval) >= i) - break; - } - return(rval); + rval = -1; + if (xfs_da_do_buf(trans, dp, bno, &rval, NULL, whichfork, 3, + (inst_t *)__return_address)) + return -1; + else + return rval; } -xfs_zone_t *xfs_da_state_zone; /* anchor for state struct zone */ -xfs_zone_t *xfs_dabuf_zone; /* dabuf zone */ +kmem_zone_t *xfs_da_state_zone; /* anchor for state struct zone */ +kmem_zone_t *xfs_dabuf_zone; /* dabuf zone */ /* * Allocate a dir-state structure. @@ -2247,7 +2177,7 @@ xfs_da_state_alloc(void) /* * Kill the altpath contents of a da-state structure. */ -void +STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state) { int i; @@ -2285,7 +2215,7 @@ xfs_da_state_free(xfs_da_state_t *state) #ifdef XFS_DABUF_DEBUG xfs_dabuf_t *xfs_dabuf_global_list; -lock_t xfs_dabuf_global_lock; +static DEFINE_SPINLOCK(xfs_dabuf_global_lock); #endif /* @@ -2331,10 +2261,9 @@ xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra) } #ifdef XFS_DABUF_DEBUG { - SPLDECL(s); xfs_dabuf_t *p; - s = mutex_spinlock(&xfs_dabuf_global_lock); + spin_lock(&xfs_dabuf_global_lock); for (p = xfs_dabuf_global_list; p; p = p->next) { ASSERT(p->blkno != dabuf->blkno || p->target != dabuf->target); @@ -2344,7 +2273,7 @@ xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra) xfs_dabuf_global_list->prev = dabuf; dabuf->next = xfs_dabuf_global_list; xfs_dabuf_global_list = dabuf; - mutex_spinunlock(&xfs_dabuf_global_lock, s); + spin_unlock(&xfs_dabuf_global_lock); } #endif return dabuf; @@ -2383,26 +2312,24 @@ xfs_da_buf_done(xfs_dabuf_t *dabuf) if (dabuf->dirty) xfs_da_buf_clean(dabuf); if (dabuf->nbuf > 1) - kmem_free(dabuf->data, BBTOB(dabuf->bbcount)); + kmem_free(dabuf->data); #ifdef XFS_DABUF_DEBUG { - SPLDECL(s); - - s = mutex_spinlock(&xfs_dabuf_global_lock); + spin_lock(&xfs_dabuf_global_lock); if (dabuf->prev) dabuf->prev->next = dabuf->next; else xfs_dabuf_global_list = dabuf->next; if (dabuf->next) dabuf->next->prev = dabuf->prev; - mutex_spinunlock(&xfs_dabuf_global_lock, s); + spin_unlock(&xfs_dabuf_global_lock); } memset(dabuf, 0, XFS_DA_BUF_SIZE(dabuf->nbuf)); #endif if (dabuf->nbuf == 1) kmem_zone_free(xfs_dabuf_zone, dabuf); else - kmem_free(dabuf, XFS_DA_BUF_SIZE(dabuf->nbuf)); + kmem_free(dabuf); } /* @@ -2473,7 +2400,7 @@ xfs_da_brelse(xfs_trans_t *tp, xfs_dabuf_t *dabuf) for (i = 0; i < nbuf; i++) xfs_trans_brelse(tp, bplist[i]); if (bplist != &bp) - kmem_free(bplist, nbuf * sizeof(*bplist)); + kmem_free(bplist); } /* @@ -2499,7 +2426,7 @@ xfs_da_binval(xfs_trans_t *tp, xfs_dabuf_t *dabuf) for (i = 0; i < nbuf; i++) xfs_trans_binval(tp, bplist[i]); if (bplist != &bp) - kmem_free(bplist, nbuf * sizeof(*bplist)); + kmem_free(bplist); } /* diff --git a/libxfs/xfs_dir.c b/libxfs/xfs_dir.c deleted file mode 100644 index 47ec569a0..000000000 --- a/libxfs/xfs_dir.c +++ /dev/null @@ -1,618 +0,0 @@ -/* - * Copyright (c) 2000-2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -/* - * xfs_dir.c - * - * Provide the external interfaces to manage directories. - */ - - -xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot; - -/* - * One-time startup routine called from xfs_init(). - */ -void -xfs_dir_startup(void) -{ - xfs_dir_hash_dot = xfs_da_hashname((const uchar_t *) ".", 1); - xfs_dir_hash_dotdot = xfs_da_hashname((const uchar_t *) "..", 2); -} - -/* - * Initialize directory-related fields in the mount structure. - */ -STATIC void -xfs_dir_mount(xfs_mount_t *mp) -{ - uint shortcount, leafcount, count; - - mp->m_dirversion = 1; - if (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) { - shortcount = (mp->m_attroffset - - (uint)sizeof(xfs_dir_sf_hdr_t)) / - (uint)sizeof(xfs_dir_sf_entry_t); - leafcount = (XFS_LBSIZE(mp) - - (uint)sizeof(xfs_dir_leaf_hdr_t)) / - ((uint)sizeof(xfs_dir_leaf_entry_t) + - (uint)sizeof(xfs_dir_leaf_name_t)); - } else { - shortcount = (XFS_BMDR_SPACE_CALC(MINABTPTRS) - - (uint)sizeof(xfs_dir_sf_hdr_t)) / - (uint)sizeof(xfs_dir_sf_entry_t); - leafcount = (XFS_LBSIZE(mp) - - (uint)sizeof(xfs_dir_leaf_hdr_t)) / - ((uint)sizeof(xfs_dir_leaf_entry_t) + - (uint)sizeof(xfs_dir_leaf_name_t)); - } - count = shortcount > leafcount ? shortcount : leafcount; - mp->m_dircook_elog = xfs_da_log2_roundup(count + 1); - ASSERT(mp->m_dircook_elog <= mp->m_sb.sb_blocklog); - mp->m_dir_node_ents = mp->m_attr_node_ents = - (XFS_LBSIZE(mp) - (uint)sizeof(xfs_da_node_hdr_t)) / - (uint)sizeof(xfs_da_node_entry_t); - mp->m_dir_magicpct = (XFS_LBSIZE(mp) * 37) / 100; - mp->m_dirblksize = mp->m_sb.sb_blocksize; - mp->m_dirblkfsbs = 1; -} - -/* - * Initialize a directory with its "." and ".." entries. - */ -STATIC int -xfs_dir_init(xfs_trans_t *trans, xfs_inode_t *dir, xfs_inode_t *parent_dir) -{ - xfs_da_args_t args; - int error; - - memset((char *)&args, 0, sizeof(args)); - args.dp = dir; - args.trans = trans; - - ASSERT((dir->i_d.di_mode & S_IFMT) == S_IFDIR); - if ((error = xfs_dir_ino_validate(trans->t_mountp, parent_dir->i_ino))) - return error; - - return(xfs_dir_shortform_create(&args, parent_dir->i_ino)); -} - -/* - * Generic handler routine to add a name to a directory. - * Transitions directory from shortform to Btree as necessary. - */ -STATIC int /* error */ -xfs_dir_createname(xfs_trans_t *trans, xfs_inode_t *dp, uchar_t *name, - int namelen, xfs_ino_t inum, xfs_fsblock_t *firstblock, - xfs_bmap_free_t *flist, xfs_extlen_t total) -{ - xfs_da_args_t args; - int retval, newsize, done; - - ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); - - if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum))) - return (retval); - - XFS_STATS_INC(xs_dir_create); - /* - * Fill in the arg structure for this request. - */ - args.name = name; - args.namelen = namelen; - args.hashval = xfs_da_hashname(name, namelen); - args.inumber = inum; - args.dp = dp; - args.firstblock = firstblock; - args.flist = flist; - args.total = total; - args.whichfork = XFS_DATA_FORK; - args.trans = trans; - args.justcheck = 0; - args.addname = args.oknoent = 1; - - /* - * Decide on what work routines to call based on the inode size. - */ - done = 0; - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { - newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen); - if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp)) { - retval = xfs_dir_shortform_addname(&args); - done = 1; - } else { - if (total == 0) - return XFS_ERROR(ENOSPC); - retval = xfs_dir_shortform_to_leaf(&args); - done = retval != 0; - } - } - if (!done && xfs_bmap_one_block(dp, XFS_DATA_FORK)) { - retval = xfs_dir_leaf_addname(&args); - done = retval != ENOSPC; - if (!done) { - if (total == 0) - return XFS_ERROR(ENOSPC); - retval = xfs_dir_leaf_to_node(&args); - done = retval != 0; - } - } - if (!done) { - retval = xfs_dir_node_addname(&args); - } - return(retval); -} - -/* - * Generic handler routine to remove a name from a directory. - * Transitions directory from Btree to shortform as necessary. - */ -STATIC int /* error */ -xfs_dir_removename(xfs_trans_t *trans, xfs_inode_t *dp, uchar_t *name, - int namelen, xfs_ino_t ino, xfs_fsblock_t *firstblock, - xfs_bmap_free_t *flist, xfs_extlen_t total) -{ - xfs_da_args_t args; - int count, totallen, newsize, retval; - - ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); - XFS_STATS_INC(xs_dir_remove); - /* - * Fill in the arg structure for this request. - */ - args.name = name; - args.namelen = namelen; - args.hashval = xfs_da_hashname(name, namelen); - args.inumber = ino; - args.dp = dp; - args.firstblock = firstblock; - args.flist = flist; - args.total = total; - args.whichfork = XFS_DATA_FORK; - args.trans = trans; - args.justcheck = args.addname = args.oknoent = 0; - - /* - * Decide on what work routines to call based on the inode size. - */ - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { - retval = xfs_dir_shortform_removename(&args); - } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { - retval = xfs_dir_leaf_removename(&args, &count, &totallen); - if (retval == 0) { - newsize = XFS_DIR_SF_ALLFIT(count, totallen); - if (newsize <= XFS_IFORK_DSIZE(dp)) { - retval = xfs_dir_leaf_to_shortform(&args); - } - } - } else { - retval = xfs_dir_node_removename(&args); - } - return(retval); -} - -STATIC int /* error */ -xfs_dir_lookup(xfs_trans_t *trans, xfs_inode_t *dp, uchar_t *name, int namelen, - xfs_ino_t *inum) -{ - xfs_da_args_t args; - int retval; - - ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); - - XFS_STATS_INC(xs_dir_lookup); - /* - * Fill in the arg structure for this request. - */ - args.name = name; - args.namelen = namelen; - args.hashval = xfs_da_hashname(name, namelen); - args.inumber = 0; - args.dp = dp; - args.firstblock = NULL; - args.flist = NULL; - args.total = 0; - args.whichfork = XFS_DATA_FORK; - args.trans = trans; - args.justcheck = args.addname = 0; - args.oknoent = 1; - - /* - * Decide on what work routines to call based on the inode size. - */ - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { - retval = xfs_dir_shortform_lookup(&args); - } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { - retval = xfs_dir_leaf_lookup(&args); - } else { - retval = xfs_dir_node_lookup(&args); - } - if (retval == EEXIST) - retval = 0; - *inum = args.inumber; - return(retval); -} - -STATIC int /* error */ -xfs_dir_replace(xfs_trans_t *trans, xfs_inode_t *dp, uchar_t *name, int namelen, - xfs_ino_t inum, xfs_fsblock_t *firstblock, - xfs_bmap_free_t *flist, xfs_extlen_t total) -{ - xfs_da_args_t args; - int retval; - - ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); - - if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum))) - return retval; - - /* - * Fill in the arg structure for this request. - */ - args.name = name; - args.namelen = namelen; - args.hashval = xfs_da_hashname(name, namelen); - args.inumber = inum; - args.dp = dp; - args.firstblock = firstblock; - args.flist = flist; - args.total = total; - args.whichfork = XFS_DATA_FORK; - args.trans = trans; - args.justcheck = args.addname = args.oknoent = 0; - - /* - * Decide on what work routines to call based on the inode size. - */ - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { - retval = xfs_dir_shortform_replace(&args); - } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { - retval = xfs_dir_leaf_replace(&args); - } else { - retval = xfs_dir_node_replace(&args); - } - - return(retval); -} - - -/*======================================================================== - * External routines when dirsize == XFS_LBSIZE(dp->i_mount). - *========================================================================*/ - -/* - * Add a name to the leaf directory structure - * This is the external routine. - */ -int -xfs_dir_leaf_addname(xfs_da_args_t *args) -{ - int index, retval; - xfs_dabuf_t *bp; - - retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, - XFS_DATA_FORK); - if (retval) - return(retval); - ASSERT(bp != NULL); - - retval = xfs_dir_leaf_lookup_int(bp, args, &index); - if (retval == ENOENT) - retval = xfs_dir_leaf_add(bp, args, index); - xfs_da_buf_done(bp); - return(retval); -} - -/* - * Remove a name from the leaf directory structure - * This is the external routine. - */ -STATIC int -xfs_dir_leaf_removename(xfs_da_args_t *args, int *count, int *totallen) -{ - xfs_dir_leafblock_t *leaf; - int index, retval; - xfs_dabuf_t *bp; - - retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, - XFS_DATA_FORK); - if (retval) - return(retval); - ASSERT(bp != NULL); - leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - retval = xfs_dir_leaf_lookup_int(bp, args, &index); - if (retval == EEXIST) { - (void)xfs_dir_leaf_remove(args->trans, bp, index); - *count = INT_GET(leaf->hdr.count, ARCH_CONVERT); - *totallen = INT_GET(leaf->hdr.namebytes, ARCH_CONVERT); - retval = 0; - } - xfs_da_buf_done(bp); - return(retval); -} - -/* - * Look up a name in a leaf directory structure. - * This is the external routine. - */ -STATIC int -xfs_dir_leaf_lookup(xfs_da_args_t *args) -{ - int index, retval; - xfs_dabuf_t *bp; - - retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, - XFS_DATA_FORK); - if (retval) - return(retval); - ASSERT(bp != NULL); - retval = xfs_dir_leaf_lookup_int(bp, args, &index); - xfs_da_brelse(args->trans, bp); - return(retval); -} - -/* - * Look up a name in a leaf directory structure, replace the inode number. - * This is the external routine. - */ -STATIC int -xfs_dir_leaf_replace(xfs_da_args_t *args) -{ - int index, retval; - xfs_dabuf_t *bp; - xfs_ino_t inum; - xfs_dir_leafblock_t *leaf; - xfs_dir_leaf_entry_t *entry; - xfs_dir_leaf_name_t *namest; - - inum = args->inumber; - retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, - XFS_DATA_FORK); - if (retval) - return(retval); - ASSERT(bp != NULL); - retval = xfs_dir_leaf_lookup_int(bp, args, &index); - if (retval == EEXIST) { - leaf = bp->data; - entry = &leaf->entries[index]; - namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); - /* XXX - replace assert? */ - XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber); - xfs_da_log_buf(args->trans, bp, - XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber))); - xfs_da_buf_done(bp); - retval = 0; - } else - xfs_da_brelse(args->trans, bp); - return(retval); -} - - -/*======================================================================== - * External routines when dirsize > XFS_LBSIZE(mp). - *========================================================================*/ - -/* - * Add a name to a Btree-format directory. - * - * This will involve walking down the Btree, and may involve splitting - * leaf nodes and even splitting intermediate nodes up to and including - * the root node (a special case of an intermediate node). - */ -STATIC int -xfs_dir_node_addname(xfs_da_args_t *args) -{ - xfs_da_state_t *state; - xfs_da_state_blk_t *blk; - int retval, error; - - /* - * Fill in bucket of arguments/results/context to carry around. - */ - state = xfs_da_state_alloc(); - state->args = args; - state->mp = args->dp->i_mount; - state->blocksize = state->mp->m_sb.sb_blocksize; - state->node_ents = state->mp->m_dir_node_ents; - - /* - * Search to see if name already exists, and get back a pointer - * to where it should go. - */ - error = xfs_da_node_lookup_int(state, &retval); - if (error) - retval = error; - if (retval != ENOENT) - goto error; - blk = &state->path.blk[ state->path.active-1 ]; - ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC); - retval = xfs_dir_leaf_add(blk->bp, args, blk->index); - if (retval == 0) { - /* - * Addition succeeded, update Btree hashvals. - */ - if (!args->justcheck) - xfs_da_fixhashpath(state, &state->path); - } else { - /* - * Addition failed, split as many Btree elements as required. - */ - if (args->total == 0) { - ASSERT(retval == ENOSPC); - goto error; - } - retval = xfs_da_split(state); - } -error: - xfs_da_state_free(state); - - return(retval); -} - -/* - * Remove a name from a B-tree directory. - * - * This will involve walking down the Btree, and may involve joining - * leaf nodes and even joining intermediate nodes up to and including - * the root node (a special case of an intermediate node). - */ -STATIC int -xfs_dir_node_removename(xfs_da_args_t *args) -{ - xfs_da_state_t *state; - xfs_da_state_blk_t *blk; - int retval, error; - - state = xfs_da_state_alloc(); - state->args = args; - state->mp = args->dp->i_mount; - state->blocksize = state->mp->m_sb.sb_blocksize; - state->node_ents = state->mp->m_dir_node_ents; - - /* - * Search to see if name exists, and get back a pointer to it. - */ - error = xfs_da_node_lookup_int(state, &retval); - if (error) - retval = error; - if (retval != EEXIST) { - xfs_da_state_free(state); - return(retval); - } - - /* - * Remove the name and update the hashvals in the tree. - */ - blk = &state->path.blk[ state->path.active-1 ]; - ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC); - retval = xfs_dir_leaf_remove(args->trans, blk->bp, blk->index); - xfs_da_fixhashpath(state, &state->path); - - /* - * Check to see if the tree needs to be collapsed. - */ - error = 0; - if (retval) { - error = xfs_da_join(state); - } - - xfs_da_state_free(state); - if (error) - return(error); - return(0); -} - -/* - * Look up a filename in a int directory. - * Use an internal routine to actually do all the work. - */ -STATIC int -xfs_dir_node_lookup(xfs_da_args_t *args) -{ - xfs_da_state_t *state; - int retval, error, i; - - state = xfs_da_state_alloc(); - state->args = args; - state->mp = args->dp->i_mount; - state->blocksize = state->mp->m_sb.sb_blocksize; - state->node_ents = state->mp->m_dir_node_ents; - - /* - * Search to see if name exists, - * and get back a pointer to it. - */ - error = xfs_da_node_lookup_int(state, &retval); - if (error) { - retval = error; - } - - /* - * If not in a transaction, we have to release all the buffers. - */ - for (i = 0; i < state->path.active; i++) { - xfs_da_brelse(args->trans, state->path.blk[i].bp); - state->path.blk[i].bp = NULL; - } - - xfs_da_state_free(state); - return(retval); -} - -/* - * Look up a filename in an int directory, replace the inode number. - * Use an internal routine to actually do the lookup. - */ -STATIC int -xfs_dir_node_replace(xfs_da_args_t *args) -{ - xfs_da_state_t *state; - xfs_da_state_blk_t *blk; - xfs_dir_leafblock_t *leaf; - xfs_dir_leaf_entry_t *entry; - xfs_dir_leaf_name_t *namest; - xfs_ino_t inum; - int retval, error, i; - xfs_dabuf_t *bp; - - state = xfs_da_state_alloc(); - state->args = args; - state->mp = args->dp->i_mount; - state->blocksize = state->mp->m_sb.sb_blocksize; - state->node_ents = state->mp->m_dir_node_ents; - inum = args->inumber; - - /* - * Search to see if name exists, - * and get back a pointer to it. - */ - error = xfs_da_node_lookup_int(state, &retval); - if (error) { - retval = error; - } - - if (retval == EEXIST) { - blk = &state->path.blk[state->path.active - 1]; - ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC); - bp = blk->bp; - leaf = bp->data; - entry = &leaf->entries[blk->index]; - namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); - /* XXX - replace assert ? */ - XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber); - xfs_da_log_buf(args->trans, bp, - XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber))); - xfs_da_buf_done(bp); - blk->bp = NULL; - retval = 0; - } else { - i = state->path.active - 1; - xfs_da_brelse(args->trans, state->path.blk[i].bp); - state->path.blk[i].bp = NULL; - } - for (i = 0; i < state->path.active - 1; i++) { - xfs_da_brelse(args->trans, state->path.blk[i].bp); - state->path.blk[i].bp = NULL; - } - - xfs_da_state_free(state); - return(retval); -} diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index a436e4f8b..71134f83c 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -16,52 +16,46 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -/* - * XFS v2 directory implmentation. - * Top-level and utility routines. - */ - #include +struct xfs_name xfs_name_dotdot = {"..", 2}; + 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. + * ASCII case-insensitive (ie. A-Z) support for directories that was + * used in IRIX. */ -static xfs_dahash_t +STATIC xfs_dahash_t xfs_ascii_ci_hashname( - const uchar_t *name, - int len) + struct xfs_name *name) { xfs_dahash_t hash; int i; - for (i = 0, hash = 0; i < len; i++) - hash = tolower(name[i]) ^ rol32(hash, 7); + for (i = 0, hash = 0; i < name->len; i++) + hash = tolower(name->name[i]) ^ rol32(hash, 7); return hash; } -static enum xfs_dacmp +STATIC enum xfs_dacmp xfs_ascii_ci_compname( - const uchar_t *name1, - int len1, - const uchar_t *name2, - int len2) + struct xfs_da_args *args, + const char *name, + int len) { enum xfs_dacmp result; int i; - if (len1 != len2) + if (args->namelen != len) return XFS_CMP_DIFFERENT; result = XFS_CMP_EXACT; - for (i = 0; i < len1; i++) { - if (name1[i] == name2[i]) + for (i = 0; i < len; i++) { + if (args->name[i] == name[i]) continue; - if (tolower(name1[i]) != tolower(name2[i])) + if (tolower(args->name[i]) != tolower(name[i])) return XFS_CMP_DIFFERENT; result = XFS_CMP_CASE; } @@ -69,27 +63,23 @@ xfs_ascii_ci_compname( return result; } -static const struct xfs_nameops xfs_ascii_ci_nameops = { +static 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. - */ void -xfs_dir2_mount( - xfs_mount_t *mp) /* filesystem mount point */ +xfs_dir_mount( + xfs_mount_t *mp) { - mp->m_dirversion = 2; + ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb)); ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <= XFS_MAX_BLOCKSIZE); mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog); mp->m_dirblkfsbs = 1 << mp->m_sb.sb_dirblklog; - mp->m_dirdatablk = XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_DATA_FIRSTDB(mp)); - mp->m_dirleafblk = XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_LEAF_FIRSTDB(mp)); - mp->m_dirfreeblk = XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_FREE_FIRSTDB(mp)); + mp->m_dirdatablk = xfs_dir2_db_to_da(mp, XFS_DIR2_DATA_FIRSTDB(mp)); + mp->m_dirleafblk = xfs_dir2_db_to_da(mp, XFS_DIR2_LEAF_FIRSTDB(mp)); + mp->m_dirfreeblk = xfs_dir2_db_to_da(mp, XFS_DIR2_FREE_FIRSTDB(mp)); mp->m_attr_node_ents = (mp->m_sb.sb_blocksize - (uint)sizeof(xfs_da_node_hdr_t)) / (uint)sizeof(xfs_da_node_entry_t); @@ -103,57 +93,105 @@ xfs_dir2_mount( mp->m_dirnameops = &xfs_default_nameops; } +/* + * Return 1 if directory contains only "." and "..". + */ +int +xfs_dir_isempty( + xfs_inode_t *dp) +{ + xfs_dir2_sf_t *sfp; + + ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); + if (dp->i_d.di_size == 0) /* might happen during shutdown. */ + return 1; + if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) + return 0; + sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + return !sfp->hdr.count; +} + +/* + * Validate a given inode number. + */ +int +xfs_dir_ino_validate( + xfs_mount_t *mp, + xfs_ino_t ino) +{ + xfs_agblock_t agblkno; + xfs_agino_t agino; + xfs_agnumber_t agno; + int ino_ok; + int ioff; + + agno = XFS_INO_TO_AGNO(mp, ino); + agblkno = XFS_INO_TO_AGBNO(mp, ino); + ioff = XFS_INO_TO_OFFSET(mp, ino); + agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff); + ino_ok = + agno < mp->m_sb.sb_agcount && + agblkno < mp->m_sb.sb_agblocks && + agblkno != 0 && + ioff < (1 << mp->m_sb.sb_inopblog) && + XFS_AGINO_TO_INO(mp, agno, agino) == ino; + if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE, + XFS_RANDOM_DIR_INO_VALIDATE))) { + xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx", + (unsigned long long) ino); + XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp); + return XFS_ERROR(EFSCORRUPTED); + } + return 0; +} + /* * Initialize a directory with its "." and ".." entries. */ -int /* error */ -xfs_dir2_init( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *dp, /* incore directory inode */ - xfs_inode_t *pdp) /* incore parent directory inode */ +int +xfs_dir_init( + xfs_trans_t *tp, + xfs_inode_t *dp, + xfs_inode_t *pdp) { - xfs_da_args_t args; /* operation arguments */ - int error; /* error return value */ + xfs_da_args_t args; + int error; memset((char *)&args, 0, sizeof(args)); args.dp = dp; args.trans = tp; ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); - if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino))) { + if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino))) return error; - } return xfs_dir2_sf_create(&args, pdp->i_ino); } /* Enter a name in a directory. */ -STATIC int /* error */ -xfs_dir2_createname( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *dp, /* incore directory inode */ - uchar_t *name, /* new entry name */ - int namelen, /* new entry name length */ +int +xfs_dir_createname( + xfs_trans_t *tp, + xfs_inode_t *dp, + struct xfs_name *name, xfs_ino_t inum, /* new entry inode number */ xfs_fsblock_t *first, /* bmap's firstblock */ xfs_bmap_free_t *flist, /* bmap's freeblock list */ xfs_extlen_t total) /* bmap's total block count */ { - xfs_da_args_t args; /* operation arguments */ - int rval; /* return value */ + xfs_da_args_t args; + int rval; int v; /* type-checking value */ ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); - if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) { + if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) return rval; - } XFS_STATS_INC(xs_dir_create); - /* - * Fill in the arg structure for this request. - */ - args.name = name; - args.namelen = namelen; - args.hashval = dp->i_mount->m_dirnameops->hashname(name, namelen); + + memset(&args, 0, sizeof(xfs_da_args_t)); + args.name = name->name; + args.namelen = name->len; + args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = inum; args.dp = dp; args.firstblock = first; @@ -161,107 +199,128 @@ xfs_dir2_createname( args.total = total; args.whichfork = XFS_DATA_FORK; args.trans = tp; - args.justcheck = 0; - args.addname = args.oknoent = 1; - /* - * Decide on what work routines to call based on the inode size. - */ + args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; + if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_addname(&args); - else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { + else if ((rval = xfs_dir2_isblock(tp, dp, &v))) return rval; - } else if (v) + else if (v) rval = xfs_dir2_block_addname(&args); - else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { + else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) return rval; - } else if (v) + else if (v) rval = xfs_dir2_leaf_addname(&args); else rval = xfs_dir2_node_addname(&args); return rval; } +/* + * If doing a CI lookup and case-insensitive match, dup actual name into + * args.value. Return EEXIST for success (ie. name found) or an error. + */ +int +xfs_dir_cilookup_result( + struct xfs_da_args *args, + const char *name, + int len) +{ + if (args->cmpresult == XFS_CMP_DIFFERENT) + return ENOENT; + if (args->cmpresult != XFS_CMP_CASE || + !(args->op_flags & XFS_DA_OP_CILOOKUP)) + return EEXIST; + + args->value = kmem_alloc(len, KM_MAYFAIL); + if (!args->value) + return ENOMEM; + + memcpy(args->value, name, len); + args->valuelen = len; + return EEXIST; +} + /* * Lookup a name in a directory, give back the inode number. + * If ci_name is not NULL, returns the actual name in ci_name if it differs + * to name, or ci_name->name is set to NULL for an exact match. */ -STATIC int /* error */ -xfs_dir2_lookup( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *dp, /* incore directory inode */ - uchar_t *name, /* lookup name */ - int namelen, /* lookup name length */ - xfs_ino_t *inum) /* out: inode number */ + +int +xfs_dir_lookup( + xfs_trans_t *tp, + xfs_inode_t *dp, + struct xfs_name *name, + xfs_ino_t *inum, /* out: inode number */ + struct xfs_name *ci_name) /* out: actual name if CI match */ { - xfs_da_args_t args; /* operation arguments */ - int rval; /* return value */ + xfs_da_args_t args; + int rval; int v; /* type-checking value */ ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); XFS_STATS_INC(xs_dir_lookup); - /* - * Fill in the arg structure for this request. - */ - args.name = name; - args.namelen = namelen; - args.hashval = dp->i_mount->m_dirnameops->hashname(name, namelen); - args.inumber = 0; + memset(&args, 0, sizeof(xfs_da_args_t)); + args.name = name->name; + args.namelen = name->len; + args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.dp = dp; - args.firstblock = NULL; - args.flist = NULL; - args.total = 0; args.whichfork = XFS_DATA_FORK; args.trans = tp; - args.justcheck = args.addname = 0; - args.oknoent = 1; - /* - * Decide on what work routines to call based on the inode size. - */ + args.op_flags = XFS_DA_OP_OKNOENT; + if (ci_name) + args.op_flags |= XFS_DA_OP_CILOOKUP; + if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_lookup(&args); - else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { + else if ((rval = xfs_dir2_isblock(tp, dp, &v))) return rval; - } else if (v) + else if (v) rval = xfs_dir2_block_lookup(&args); - else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { + else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) return rval; - } else if (v) + else if (v) rval = xfs_dir2_leaf_lookup(&args); else rval = xfs_dir2_node_lookup(&args); if (rval == EEXIST) rval = 0; - if (rval == 0) + if (!rval) { *inum = args.inumber; + if (ci_name) { + ci_name->name = args.value; + ci_name->len = args.valuelen; + } + } return rval; } /* * Remove an entry from a directory. */ -STATIC int /* error */ -xfs_dir2_removename( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *dp, /* incore directory inode */ - uchar_t *name, /* name of entry to remove */ - int namelen, /* name length of entry to remove */ - xfs_ino_t ino, /* inode number of entry to remove */ +int +xfs_dir_removename( + xfs_trans_t *tp, + xfs_inode_t *dp, + struct xfs_name *name, + xfs_ino_t ino, xfs_fsblock_t *first, /* bmap's firstblock */ xfs_bmap_free_t *flist, /* bmap's freeblock list */ xfs_extlen_t total) /* bmap's total block count */ { - xfs_da_args_t args; /* operation arguments */ - int rval; /* return value */ + xfs_da_args_t args; + int rval; int v; /* type-checking value */ ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); XFS_STATS_INC(xs_dir_remove); - /* - * Fill in the arg structure for this request. - */ - args.name = name; - args.namelen = namelen; - args.hashval = dp->i_mount->m_dirnameops->hashname(name, namelen); + + memset(&args, 0, sizeof(xfs_da_args_t)); + args.name = name->name; + args.namelen = name->len; + args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = ino; args.dp = dp; args.firstblock = first; @@ -269,19 +328,16 @@ xfs_dir2_removename( args.total = total; args.whichfork = XFS_DATA_FORK; args.trans = tp; - args.justcheck = args.addname = args.oknoent = 0; - /* - * Decide on what work routines to call based on the inode size. - */ + if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_removename(&args); - else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { + else if ((rval = xfs_dir2_isblock(tp, dp, &v))) return rval; - } else if (v) + else if (v) rval = xfs_dir2_block_removename(&args); - else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { + else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) return rval; - } else if (v) + else if (v) rval = xfs_dir2_leaf_removename(&args); else rval = xfs_dir2_node_removename(&args); @@ -291,32 +347,29 @@ xfs_dir2_removename( /* * Replace the inode number of a directory entry. */ -STATIC int /* error */ -xfs_dir2_replace( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *dp, /* incore directory inode */ - uchar_t *name, /* name of entry to replace */ - int namelen, /* name length of entry to replace */ +int +xfs_dir_replace( + xfs_trans_t *tp, + xfs_inode_t *dp, + struct xfs_name *name, /* name of entry to replace */ xfs_ino_t inum, /* new inode number */ xfs_fsblock_t *first, /* bmap's firstblock */ xfs_bmap_free_t *flist, /* bmap's freeblock list */ xfs_extlen_t total) /* bmap's total block count */ { - xfs_da_args_t args; /* operation arguments */ - int rval; /* return value */ + xfs_da_args_t args; + int rval; int v; /* type-checking value */ ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); - if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) { + if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) return rval; - } - /* - * Fill in the arg structure for this request. - */ - args.name = name; - args.namelen = namelen; - args.hashval = dp->i_mount->m_dirnameops->hashname(name, namelen); + + memset(&args, 0, sizeof(xfs_da_args_t)); + args.name = name->name; + args.namelen = name->len; + args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = inum; args.dp = dp; args.firstblock = first; @@ -324,19 +377,16 @@ xfs_dir2_replace( args.total = total; args.whichfork = XFS_DATA_FORK; args.trans = tp; - args.justcheck = args.addname = args.oknoent = 0; - /* - * Decide on what work routines to call based on the inode size. - */ + if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_replace(&args); - else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { + else if ((rval = xfs_dir2_isblock(tp, dp, &v))) return rval; - } else if (v) + else if (v) rval = xfs_dir2_block_replace(&args); - else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { + else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) return rval; - } else if (v) + else if (v) rval = xfs_dir2_leaf_replace(&args); else rval = xfs_dir2_node_replace(&args); @@ -352,24 +402,24 @@ xfs_dir2_replace( * This routine is for data and free blocks, not leaf/node blocks * which are handled by xfs_da_grow_inode. */ -int /* error */ +int xfs_dir2_grow_inode( - xfs_da_args_t *args, /* operation arguments */ + xfs_da_args_t *args, int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */ xfs_dir2_db_t *dbp) /* out: block number added */ { xfs_fileoff_t bno; /* directory offset of new block */ int count; /* count of filesystem blocks */ xfs_inode_t *dp; /* incore directory inode */ - int error; /* error return value */ + int error; int got; /* blocks actually mapped */ - int i; /* temp mapping index */ + int i; xfs_bmbt_irec_t map; /* single structure for bmap */ int mapi; /* mapping index */ xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */ - xfs_mount_t *mp; /* filesystem mount point */ + xfs_mount_t *mp; int nmap; /* number of bmap entries */ - xfs_trans_t *tp; /* transaction pointer */ + xfs_trans_t *tp; xfs_dir2_trace_args_s("grow_inode", args, space); dp = args->dp; @@ -383,9 +433,8 @@ xfs_dir2_grow_inode( /* * Find the first hole for our block. */ - if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK))) { + if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK))) return error; - } nmap = 1; ASSERT(args->firstblock != NULL); /* @@ -394,13 +443,9 @@ xfs_dir2_grow_inode( if ((error = xfs_bmapi(tp, dp, bno, count, XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, args->firstblock, args->total, &map, &nmap, - args->flist))) { + args->flist, NULL))) return error; - } ASSERT(nmap <= 1); - /* - * Got it in 1. - */ if (nmap == 1) { mapp = ↦ mapi = 1; @@ -430,8 +475,9 @@ xfs_dir2_grow_inode( if ((error = xfs_bmapi(tp, dp, b, c, XFS_BMAPI_WRITE|XFS_BMAPI_METADATA, args->firstblock, args->total, - &mapp[mapi], &nmap, args->flist))) { - kmem_free(mapp, sizeof(*mapp) * count); + &mapp[mapi], &nmap, args->flist, + NULL))) { + kmem_free(mapp); return error; } if (nmap < 1) @@ -463,15 +509,15 @@ xfs_dir2_grow_inode( mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount != bno + count) { if (mapp != &map) - kmem_free(mapp, sizeof(*mapp) * count); + kmem_free(mapp); return XFS_ERROR(ENOSPC); } /* * Done with the temporary mapping table. */ if (mapp != &map) - kmem_free(mapp, sizeof(*mapp) * count); - *dbp = XFS_DIR2_DA_TO_DB(mp, (xfs_dablk_t)bno); + kmem_free(mapp); + *dbp = xfs_dir2_da_to_db(mp, (xfs_dablk_t)bno); /* * Update file's size if this is the data space and it grew. */ @@ -490,20 +536,19 @@ xfs_dir2_grow_inode( /* * See if the directory is a single-block form directory. */ -int /* error */ +int xfs_dir2_isblock( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *dp, /* incore directory inode */ + xfs_trans_t *tp, + xfs_inode_t *dp, int *vp) /* out: 1 is block, 0 is not block */ { xfs_fileoff_t last; /* last file offset */ - xfs_mount_t *mp; /* filesystem mount point */ - int rval; /* return value */ + xfs_mount_t *mp; + int rval; mp = dp->i_mount; - if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) { + if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) return rval; - } rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize; ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize); *vp = rval; @@ -513,20 +558,19 @@ xfs_dir2_isblock( /* * See if the directory is a single-leaf form directory. */ -int /* error */ +int xfs_dir2_isleaf( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *dp, /* incore directory inode */ + xfs_trans_t *tp, + xfs_inode_t *dp, int *vp) /* out: 1 is leaf, 0 is not leaf */ { xfs_fileoff_t last; /* last file offset */ - xfs_mount_t *mp; /* filesystem mount point */ - int rval; /* return value */ + xfs_mount_t *mp; + int rval; mp = dp->i_mount; - if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) { + if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) return rval; - } *vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog); return 0; } @@ -538,29 +582,29 @@ xfs_dir2_isleaf( */ int xfs_dir2_shrink_inode( - xfs_da_args_t *args, /* operation arguments */ - xfs_dir2_db_t db, /* directory block number */ - xfs_dabuf_t *bp) /* block's buffer */ + xfs_da_args_t *args, + xfs_dir2_db_t db, + xfs_dabuf_t *bp) { xfs_fileoff_t bno; /* directory file offset */ xfs_dablk_t da; /* directory file offset */ int done; /* bunmap is finished */ - xfs_inode_t *dp; /* incore directory inode */ - int error; /* error return value */ - xfs_mount_t *mp; /* filesystem mount point */ - xfs_trans_t *tp; /* transaction pointer */ + xfs_inode_t *dp; + int error; + xfs_mount_t *mp; + xfs_trans_t *tp; xfs_dir2_trace_args_db("shrink_inode", args, db, bp); dp = args->dp; mp = dp->i_mount; tp = args->trans; - da = XFS_DIR2_DB_TO_DA(mp, db); + da = xfs_dir2_db_to_da(mp, db); /* * Unmap the fsblock(s). */ if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs, XFS_BMAPI_METADATA, 0, args->firstblock, args->flist, - &done))) { + NULL, &done))) { /* * ENOSPC actually can happen if we're in a removename with * no space reservation, and the resulting block removal @@ -590,7 +634,7 @@ xfs_dir2_shrink_inode( /* * If the block isn't the last one in the directory, we're done. */ - if (dp->i_d.di_size > XFS_DIR2_DB_OFF_TO_BYTE(mp, db + 1, 0)) + if (dp->i_d.di_size > xfs_dir2_db_off_to_byte(mp, db + 1, 0)) return 0; bno = da; if ((error = xfs_bmap_last_before(tp, dp, &bno, XFS_DATA_FORK))) { diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c index f7259cd7c..d197b0bf2 100644 --- a/libxfs/xfs_dir2_block.c +++ b/libxfs/xfs_dir2_block.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -16,13 +16,29 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + /* - * xfs_dir2_block.c - * XFS V2 directory implementation, single-block form. - * See xfs_dir2_block.h for the format. + * Local function prototypes. */ +static void xfs_dir2_block_log_leaf(xfs_trans_t *tp, xfs_dabuf_t *bp, int first, + int last); +static void xfs_dir2_block_log_tail(xfs_trans_t *tp, xfs_dabuf_t *bp); +static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **bpp, + int *entno); +static int xfs_dir2_block_sort(const void *a, const void *b); -#include +static xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot; + +/* + * One-time startup routine called from xfs_init(). + */ +void +xfs_dir_startup(void) +{ + xfs_dir_hash_dot = xfs_da_hashname(".", 1); + xfs_dir_hash_dotdot = xfs_da_hashname("..", 2); +} /* * Add an entry to a block directory. @@ -54,7 +70,7 @@ xfs_dir2_block_addname( xfs_mount_t *mp; /* filesystem mount point */ int needlog; /* need to log header */ int needscan; /* need to rescan freespace */ - xfs_dir2_data_off_t *tagp; /* pointer to tag value */ + __be16 *tagp; /* pointer to tag value */ xfs_trans_t *tp; /* transaction structure */ xfs_dir2_trace_args("block_addname", args); @@ -73,20 +89,19 @@ xfs_dir2_block_addname( /* * Check the magic number, corrupted if wrong. */ - if (unlikely(INT_GET(block->hdr.magic, ARCH_CONVERT) - != XFS_DIR2_BLOCK_MAGIC)) { + if (unlikely(be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC)) { XFS_CORRUPTION_ERROR("xfs_dir2_block_addname", XFS_ERRLEVEL_LOW, mp, block); xfs_da_brelse(tp, bp); return XFS_ERROR(EFSCORRUPTED); } - len = XFS_DIR2_DATA_ENTSIZE(args->namelen); + len = xfs_dir2_data_entsize(args->namelen); /* * Set up pointers to parts of the block. */ bf = block->hdr.bestfree; - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); - blp = XFS_DIR2_BLOCK_LEAF_P(btp); + btp = xfs_dir2_block_tail_p(mp, block); + blp = xfs_dir2_block_leaf_p(btp); /* * No stale entries? Need space for entry and new leaf. */ @@ -94,38 +109,38 @@ xfs_dir2_block_addname( /* * Tag just before the first leaf entry. */ - tagp = (xfs_dir2_data_off_t *)blp - 1; + tagp = (__be16 *)blp - 1; /* * Data object just before the first leaf entry. */ - enddup = (xfs_dir2_data_unused_t *)((char *)block + INT_GET(*tagp, ARCH_CONVERT)); + enddup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); /* * If it's not free then can't do this add without cleaning up: * the space before the first leaf entry needs to be free so it * can be expanded to hold the pointer to the new entry. */ - if (INT_GET(enddup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG) + if (be16_to_cpu(enddup->freetag) != XFS_DIR2_DATA_FREE_TAG) dup = enddup = NULL; /* * Check out the biggest freespace and see if it's the same one. */ else { dup = (xfs_dir2_data_unused_t *) - ((char *)block + INT_GET(bf[0].offset, ARCH_CONVERT)); + ((char *)block + be16_to_cpu(bf[0].offset)); if (dup == enddup) { /* * It is the biggest freespace, is it too small * to hold the new leaf too? */ - if (INT_GET(dup->length, ARCH_CONVERT) < len + (uint)sizeof(*blp)) { + if (be16_to_cpu(dup->length) < len + (uint)sizeof(*blp)) { /* * Yes, we use the second-largest * entry instead if it works. */ - if (INT_GET(bf[1].length, ARCH_CONVERT) >= len) + if (be16_to_cpu(bf[1].length) >= len) dup = (xfs_dir2_data_unused_t *) ((char *)block + - INT_GET(bf[1].offset, ARCH_CONVERT)); + be16_to_cpu(bf[1].offset)); else dup = NULL; } @@ -134,7 +149,7 @@ xfs_dir2_block_addname( * Not the same free entry, * just check its length. */ - if (INT_GET(dup->length, ARCH_CONVERT) < len) { + if (be16_to_cpu(dup->length) < len) { dup = NULL; } } @@ -145,9 +160,9 @@ xfs_dir2_block_addname( * If there are stale entries we'll use one for the leaf. * Is the biggest entry enough to avoid compaction? */ - else if (INT_GET(bf[0].length, ARCH_CONVERT) >= len) { + else if (be16_to_cpu(bf[0].length) >= len) { dup = (xfs_dir2_data_unused_t *) - ((char *)block + INT_GET(bf[0].offset, ARCH_CONVERT)); + ((char *)block + be16_to_cpu(bf[0].offset)); compact = 0; } /* @@ -157,20 +172,20 @@ xfs_dir2_block_addname( /* * Tag just before the first leaf entry. */ - tagp = (xfs_dir2_data_off_t *)blp - 1; + tagp = (__be16 *)blp - 1; /* * Data object just before the first leaf entry. */ - dup = (xfs_dir2_data_unused_t *)((char *)block + INT_GET(*tagp, ARCH_CONVERT)); + dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); /* * If it's not free then the data will go where the * leaf data starts now, if it works at all. */ - if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) { - if (INT_GET(dup->length, ARCH_CONVERT) + (INT_GET(btp->stale, ARCH_CONVERT) - 1) * + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { + if (be16_to_cpu(dup->length) + (be32_to_cpu(btp->stale) - 1) * (uint)sizeof(*blp) < len) dup = NULL; - } else if ((INT_GET(btp->stale, ARCH_CONVERT) - 1) * (uint)sizeof(*blp) < len) + } else if ((be32_to_cpu(btp->stale) - 1) * (uint)sizeof(*blp) < len) dup = NULL; else dup = (xfs_dir2_data_unused_t *)blp; @@ -179,7 +194,7 @@ xfs_dir2_block_addname( /* * If this isn't a real add, we're done with the buffer. */ - if (args->justcheck) + if (args->op_flags & XFS_DA_OP_JUSTCHECK) xfs_da_brelse(tp, bp); /* * If we don't have space for the new entry & leaf ... @@ -189,7 +204,7 @@ xfs_dir2_block_addname( * Not trying to actually do anything, or don't have * a space reservation: return no-space. */ - if (args->justcheck || args->total == 0) + if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || args->total == 0) return XFS_ERROR(ENOSPC); /* * Convert to the next larger format. @@ -204,7 +219,7 @@ xfs_dir2_block_addname( /* * Just checking, and it would work, so say so. */ - if (args->justcheck) + if (args->op_flags & XFS_DA_OP_JUSTCHECK) return 0; needlog = needscan = 0; /* @@ -216,11 +231,11 @@ xfs_dir2_block_addname( int fromidx; /* source leaf index */ int toidx; /* target leaf index */ - for (fromidx = toidx = INT_GET(btp->count, ARCH_CONVERT) - 1, + for (fromidx = toidx = be32_to_cpu(btp->count) - 1, highstale = lfloghigh = -1; fromidx >= 0; fromidx--) { - if (INT_GET(blp[fromidx].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) { + if (be32_to_cpu(blp[fromidx].address) == XFS_DIR2_NULL_DATAPTR) { if (highstale == -1) highstale = toidx; else { @@ -233,22 +248,21 @@ xfs_dir2_block_addname( blp[toidx] = blp[fromidx]; toidx--; } - lfloglow = toidx + 1 - (INT_GET(btp->stale, ARCH_CONVERT) - 1); - lfloghigh -= INT_GET(btp->stale, ARCH_CONVERT) - 1; - INT_MOD(btp->count, ARCH_CONVERT, -(INT_GET(btp->stale, ARCH_CONVERT) - 1)); + lfloglow = toidx + 1 - (be32_to_cpu(btp->stale) - 1); + lfloghigh -= be32_to_cpu(btp->stale) - 1; + be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1)); xfs_dir2_data_make_free(tp, bp, (xfs_dir2_data_aoff_t)((char *)blp - (char *)block), - (xfs_dir2_data_aoff_t)((INT_GET(btp->stale, ARCH_CONVERT) - 1) * sizeof(*blp)), + (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)), &needlog, &needscan); - blp += INT_GET(btp->stale, ARCH_CONVERT) - 1; - INT_SET(btp->stale, ARCH_CONVERT, 1); + blp += be32_to_cpu(btp->stale) - 1; + btp->stale = cpu_to_be32(1); /* * If we now need to rebuild the bestfree map, do so. * This needs to happen before the next call to use_free. */ if (needscan) { - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, - &needlog, NULL); + xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); needscan = 0; } } @@ -256,23 +270,23 @@ xfs_dir2_block_addname( * Set leaf logging boundaries to impossible state. * For the no-stale case they're set explicitly. */ - else if (INT_GET(btp->stale, ARCH_CONVERT)) { - lfloglow = INT_GET(btp->count, ARCH_CONVERT); + else if (btp->stale) { + lfloglow = be32_to_cpu(btp->count); lfloghigh = -1; } /* * Find the slot that's first lower than our hash value, -1 if none. */ - for (low = 0, high = INT_GET(btp->count, ARCH_CONVERT) - 1; low <= high; ) { + for (low = 0, high = be32_to_cpu(btp->count) - 1; low <= high; ) { mid = (low + high) >> 1; - if ((hash = INT_GET(blp[mid].hashval, ARCH_CONVERT)) == args->hashval) + if ((hash = be32_to_cpu(blp[mid].hashval)) == args->hashval) break; if (hash < args->hashval) low = mid + 1; else high = mid - 1; } - while (mid >= 0 && INT_GET(blp[mid].hashval, ARCH_CONVERT) >= args->hashval) { + while (mid >= 0 && be32_to_cpu(blp[mid].hashval) >= args->hashval) { mid--; } /* @@ -284,21 +298,21 @@ xfs_dir2_block_addname( */ xfs_dir2_data_use_free(tp, bp, enddup, (xfs_dir2_data_aoff_t) - ((char *)enddup - (char *)block + INT_GET(enddup->length, ARCH_CONVERT) - + ((char *)enddup - (char *)block + be16_to_cpu(enddup->length) - sizeof(*blp)), (xfs_dir2_data_aoff_t)sizeof(*blp), &needlog, &needscan); /* * Update the tail (entry count). */ - INT_MOD(btp->count, ARCH_CONVERT, +1); + be32_add_cpu(&btp->count, 1); /* * If we now need to rebuild the bestfree map, do so. * This needs to happen before the next call to use_free. */ if (needscan) { xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, - &needlog, NULL); + &needlog); needscan = 0; } /* @@ -319,12 +333,12 @@ xfs_dir2_block_addname( else { for (lowstale = mid; lowstale >= 0 && - INT_GET(blp[lowstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR; + be32_to_cpu(blp[lowstale].address) != XFS_DIR2_NULL_DATAPTR; lowstale--) continue; for (highstale = mid + 1; - highstale < INT_GET(btp->count, ARCH_CONVERT) && - INT_GET(blp[highstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR && + highstale < be32_to_cpu(btp->count) && + be32_to_cpu(blp[highstale].address) != XFS_DIR2_NULL_DATAPTR && (lowstale < 0 || mid - lowstale > highstale - mid); highstale++) continue; @@ -332,7 +346,7 @@ xfs_dir2_block_addname( * Move entries toward the low-numbered stale entry. */ if (lowstale >= 0 && - (highstale == INT_GET(btp->count, ARCH_CONVERT) || + (highstale == be32_to_cpu(btp->count) || mid - lowstale <= highstale - mid)) { if (mid - lowstale) memmove(&blp[lowstale], &blp[lowstale + 1], @@ -344,7 +358,7 @@ xfs_dir2_block_addname( * Move entries toward the high-numbered stale entry. */ else { - ASSERT(highstale < INT_GET(btp->count, ARCH_CONVERT)); + ASSERT(highstale < be32_to_cpu(btp->count)); mid++; if (highstale - mid) memmove(&blp[mid + 1], &blp[mid], @@ -352,7 +366,7 @@ xfs_dir2_block_addname( lfloglow = MIN(mid, lfloglow); lfloghigh = MAX(highstale, lfloghigh); } - INT_MOD(btp->stale, ARCH_CONVERT, -1); + be32_add_cpu(&btp->stale, -1); } /* * Point to the new data entry. @@ -361,8 +375,9 @@ xfs_dir2_block_addname( /* * Fill in the leaf entry. */ - INT_SET(blp[mid].hashval, ARCH_CONVERT, args->hashval); - INT_SET(blp[mid].address, ARCH_CONVERT, XFS_DIR2_BYTE_TO_DATAPTR(mp, (char *)dep - (char *)block)); + blp[mid].hashval = cpu_to_be32(args->hashval); + blp[mid].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, + (char *)dep - (char *)block)); xfs_dir2_block_log_leaf(tp, bp, lfloglow, lfloghigh); /* * Mark space for the data entry used. @@ -373,17 +388,16 @@ xfs_dir2_block_addname( /* * Create the new data entry. */ - INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); + dep->inumber = cpu_to_be64(args->inumber); dep->namelen = args->namelen; memcpy(dep->name, args->name, args->namelen); - tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); - INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block)); + tagp = xfs_dir2_data_entry_tag_p(dep); + *tagp = cpu_to_be16((char *)dep - (char *)block); /* * Clean up the bestfree array and log the header, tail, and entry. */ if (needscan) - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog, - NULL); + xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); if (needlog) xfs_dir2_data_log_header(tp, bp); xfs_dir2_block_log_tail(tp, bp); @@ -396,7 +410,7 @@ xfs_dir2_block_addname( /* * Log leaf entries from the block. */ -STATIC void +static void xfs_dir2_block_log_leaf( xfs_trans_t *tp, /* transaction structure */ xfs_dabuf_t *bp, /* block buffer */ @@ -410,8 +424,8 @@ xfs_dir2_block_log_leaf( mp = tp->t_mountp; block = bp->data; - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); - blp = XFS_DIR2_BLOCK_LEAF_P(btp); + btp = xfs_dir2_block_tail_p(mp, block); + blp = xfs_dir2_block_leaf_p(btp); xfs_da_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)block), (uint)((char *)&blp[last + 1] - (char *)block - 1)); } @@ -419,7 +433,7 @@ xfs_dir2_block_log_leaf( /* * Log the block tail. */ -STATIC void +static void xfs_dir2_block_log_tail( xfs_trans_t *tp, /* transaction structure */ xfs_dabuf_t *bp) /* block buffer */ @@ -430,7 +444,7 @@ xfs_dir2_block_log_tail( mp = tp->t_mountp; block = bp->data; - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); + btp = xfs_dir2_block_tail_p(mp, block); xfs_da_log_buf(tp, bp, (uint)((char *)btp - (char *)block), (uint)((char *)(btp + 1) - (char *)block - 1)); } @@ -464,25 +478,26 @@ xfs_dir2_block_lookup( mp = dp->i_mount; block = bp->data; xfs_dir2_data_check(dp, bp); - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); - blp = XFS_DIR2_BLOCK_LEAF_P(btp); + btp = xfs_dir2_block_tail_p(mp, block); + blp = xfs_dir2_block_leaf_p(btp); /* * Get the offset from the leaf entry, to point to the data. */ - dep = (xfs_dir2_data_entry_t *) - ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(blp[ent].address, ARCH_CONVERT))); + dep = (xfs_dir2_data_entry_t *)((char *)block + + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); /* - * Fill in inode number, release the block. + * Fill in inode number, CI name if appropriate, release the block. */ - args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); + args->inumber = be64_to_cpu(dep->inumber); + error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); xfs_da_brelse(args->trans, bp); - return XFS_ERROR(EEXIST); + return XFS_ERROR(error); } /* * Internal block lookup routine. */ -STATIC int /* error */ +static int /* error */ xfs_dir2_block_lookup_int( xfs_da_args_t *args, /* dir lookup arguments */ xfs_dabuf_t **bpp, /* returned block buffer */ @@ -502,6 +517,7 @@ xfs_dir2_block_lookup_int( 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; @@ -516,23 +532,23 @@ xfs_dir2_block_lookup_int( ASSERT(bp != NULL); block = bp->data; xfs_dir2_data_check(dp, bp); - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); - blp = XFS_DIR2_BLOCK_LEAF_P(btp); + btp = xfs_dir2_block_tail_p(mp, block); + blp = xfs_dir2_block_leaf_p(btp); /* * Loop doing a binary search for our hash value. * Find our entry, ENOENT if it's not there. */ - for (low = 0, high = INT_GET(btp->count, ARCH_CONVERT) - 1; ; ) { + for (low = 0, high = be32_to_cpu(btp->count) - 1; ; ) { ASSERT(low <= high); mid = (low + high) >> 1; - if ((hash = INT_GET(blp[mid].hashval, ARCH_CONVERT)) == args->hashval) + if ((hash = be32_to_cpu(blp[mid].hashval)) == args->hashval) break; if (hash < args->hashval) low = mid + 1; else high = mid - 1; if (low > high) { - ASSERT(args->oknoent); + ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); xfs_da_brelse(tp, bp); return XFS_ERROR(ENOENT); } @@ -540,7 +556,7 @@ xfs_dir2_block_lookup_int( /* * Back up to the first one with the right hash value. */ - while (mid > 0 && INT_GET(blp[mid - 1].hashval, ARCH_CONVERT) == args->hashval) { + while (mid > 0 && be32_to_cpu(blp[mid - 1].hashval) == args->hashval) { mid--; } /* @@ -548,28 +564,39 @@ xfs_dir2_block_lookup_int( * right hash value looking for our name. */ do { - if ((addr = INT_GET(blp[mid].address, ARCH_CONVERT)) == XFS_DIR2_NULL_DATAPTR) + if ((addr = be32_to_cpu(blp[mid].address)) == XFS_DIR2_NULL_DATAPTR) continue; /* * Get pointer to the entry from the leaf. */ dep = (xfs_dir2_data_entry_t *) - ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, addr)); + ((char *)block + xfs_dir2_dataptr_to_off(mp, addr)); /* - * Compare, if it's right give back buffer & entry number. + * Compare name and if it's an exact match, return the index + * and buffer. If it's the first case-insensitive match, store + * the index and buffer and continue looking for an exact match. */ - if (dep->namelen == args->namelen && - dep->name[0] == args->name[0] && - memcmp(dep->name, args->name, args->namelen) == 0) { + cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); + if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { + args->cmpresult = cmp; *bpp = bp; *entno = mid; - return 0; + if (cmp == XFS_CMP_EXACT) + return 0; } - } while (++mid < INT_GET(btp->count, ARCH_CONVERT) && INT_GET(blp[mid].hashval, ARCH_CONVERT) == hash); + } while (++mid < be32_to_cpu(btp->count) && + be32_to_cpu(blp[mid].hashval) == hash); + + ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); + /* + * Here, we can only be doing a lookup (not a rename or replace). + * If a case-insensitive match was found earlier, return success. + */ + if (args->cmpresult == XFS_CMP_CASE) + return 0; /* * No match, release the buffer and return ENOENT. */ - ASSERT(args->oknoent); xfs_da_brelse(tp, bp); return XFS_ERROR(ENOENT); } @@ -609,36 +636,35 @@ xfs_dir2_block_removename( tp = args->trans; mp = dp->i_mount; block = bp->data; - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); - blp = XFS_DIR2_BLOCK_LEAF_P(btp); + btp = xfs_dir2_block_tail_p(mp, block); + blp = xfs_dir2_block_leaf_p(btp); /* * Point to the data entry using the leaf entry. */ dep = (xfs_dir2_data_entry_t *) - ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(blp[ent].address, ARCH_CONVERT))); + ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); /* * Mark the data entry's space free. */ needlog = needscan = 0; xfs_dir2_data_make_free(tp, bp, (xfs_dir2_data_aoff_t)((char *)dep - (char *)block), - XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan); + xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); /* * Fix up the block tail. */ - INT_MOD(btp->stale, ARCH_CONVERT, +1); + be32_add_cpu(&btp->stale, 1); xfs_dir2_block_log_tail(tp, bp); /* * Remove the leaf entry by marking it stale. */ - INT_SET(blp[ent].address, ARCH_CONVERT, XFS_DIR2_NULL_DATAPTR); + blp[ent].address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); xfs_dir2_block_log_leaf(tp, bp, ent, ent); /* * Fix up bestfree, log the header if necessary. */ if (needscan) - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog, - NULL); + xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); if (needlog) xfs_dir2_data_log_header(tp, bp); xfs_dir2_data_check(dp, bp); @@ -685,18 +711,18 @@ xfs_dir2_block_replace( dp = args->dp; mp = dp->i_mount; block = bp->data; - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); - blp = XFS_DIR2_BLOCK_LEAF_P(btp); + btp = xfs_dir2_block_tail_p(mp, block); + blp = xfs_dir2_block_leaf_p(btp); /* * Point to the data entry we need to change. */ dep = (xfs_dir2_data_entry_t *) - ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(blp[ent].address, ARCH_CONVERT))); - ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) != args->inumber); + ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); + ASSERT(be64_to_cpu(dep->inumber) != args->inumber); /* * Change the inode number to the new value. */ - INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); + dep->inumber = cpu_to_be64(args->inumber); xfs_dir2_data_log_entry(args->trans, bp, dep); xfs_dir2_data_check(dp, bp); xfs_da_buf_done(bp); @@ -716,8 +742,8 @@ xfs_dir2_block_sort( la = a; lb = b; - return INT_GET(la->hashval, ARCH_CONVERT) < INT_GET(lb->hashval, ARCH_CONVERT) ? -1 : - (INT_GET(la->hashval, ARCH_CONVERT) > INT_GET(lb->hashval, ARCH_CONVERT) ? 1 : 0); + return be32_to_cpu(la->hashval) < be32_to_cpu(lb->hashval) ? -1 : + (be32_to_cpu(la->hashval) > be32_to_cpu(lb->hashval) ? 1 : 0); } /* @@ -729,7 +755,7 @@ xfs_dir2_leaf_to_block( xfs_dabuf_t *lbp, /* leaf buffer */ xfs_dabuf_t *dbp) /* data buffer */ { - xfs_dir2_data_off_t *bestsp; /* leaf bests table */ + __be16 *bestsp; /* leaf bests table */ xfs_dir2_block_t *block; /* block structure */ xfs_dir2_block_tail_t *btp; /* block tail */ xfs_inode_t *dp; /* incore directory inode */ @@ -744,7 +770,7 @@ xfs_dir2_leaf_to_block( int needscan; /* need to scan for bestfree */ xfs_dir2_sf_hdr_t sfh; /* shortform header */ int size; /* bytes used */ - xfs_dir2_data_off_t *tagp; /* end of entry (tag) */ + __be16 *tagp; /* end of entry (tag) */ int to; /* block/leaf to index */ xfs_trans_t *tp; /* transaction pointer */ @@ -753,8 +779,8 @@ xfs_dir2_leaf_to_block( tp = args->trans; mp = dp->i_mount; leaf = lbp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC); - ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); + ltp = xfs_dir2_leaf_tail_p(mp, leaf); /* * If there are data blocks other than the first one, take this * opportunity to remove trailing empty data blocks that may have @@ -762,12 +788,12 @@ xfs_dir2_leaf_to_block( * These will show up in the leaf bests table. */ while (dp->i_d.di_size > mp->m_dirblksize) { - bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); - if (INT_GET(bestsp[INT_GET(ltp->bestcount, ARCH_CONVERT) - 1], ARCH_CONVERT) == + bestsp = xfs_dir2_leaf_bests_p(ltp); + if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) == mp->m_dirblksize - (uint)sizeof(block->hdr)) { if ((error = xfs_dir2_leaf_trim_data(args, lbp, - (xfs_dir2_db_t)(INT_GET(ltp->bestcount, ARCH_CONVERT) - 1)))) + (xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1)))) goto out; } else { error = 0; @@ -783,28 +809,29 @@ xfs_dir2_leaf_to_block( goto out; } block = dbp->data; - ASSERT(INT_GET(block->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC); + ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_DATA_MAGIC); /* * Size of the "leaf" area in the block. */ size = (uint)sizeof(block->tail) + - (uint)sizeof(*lep) * (INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT)); + (uint)sizeof(*lep) * (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); /* * Look at the last data entry. */ - tagp = (xfs_dir2_data_off_t *)((char *)block + mp->m_dirblksize) - 1; - dup = (xfs_dir2_data_unused_t *)((char *)block + INT_GET(*tagp, ARCH_CONVERT)); + tagp = (__be16 *)((char *)block + mp->m_dirblksize) - 1; + dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); /* * If it's not free or is too short we can't do it. */ - if (INT_GET(dup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG || INT_GET(dup->length, ARCH_CONVERT) < size) { + if (be16_to_cpu(dup->freetag) != XFS_DIR2_DATA_FREE_TAG || + be16_to_cpu(dup->length) < size) { error = 0; goto out; } /* * Start converting it to block form. */ - INT_SET(block->hdr.magic, ARCH_CONVERT, XFS_DIR2_BLOCK_MAGIC); + block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); needlog = 1; needscan = 0; /* @@ -815,27 +842,26 @@ xfs_dir2_leaf_to_block( /* * Initialize the block tail. */ - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); - INT_SET(btp->count, ARCH_CONVERT, INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT)); + btp = xfs_dir2_block_tail_p(mp, block); + btp->count = cpu_to_be32(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); btp->stale = 0; xfs_dir2_block_log_tail(tp, dbp); /* * Initialize the block leaf area. We compact out stale entries. */ - lep = XFS_DIR2_BLOCK_LEAF_P(btp); - for (from = to = 0; from < INT_GET(leaf->hdr.count, ARCH_CONVERT); from++) { - if (INT_GET(leaf->ents[from].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) + lep = xfs_dir2_block_leaf_p(btp); + for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) { + if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) continue; lep[to++] = leaf->ents[from]; } - ASSERT(to == INT_GET(btp->count, ARCH_CONVERT)); - xfs_dir2_block_log_leaf(tp, dbp, 0, INT_GET(btp->count, ARCH_CONVERT) - 1); + ASSERT(to == be32_to_cpu(btp->count)); + xfs_dir2_block_log_leaf(tp, dbp, 0, be32_to_cpu(btp->count) - 1); /* * Scan the bestfree if we need it and log the data block header. */ if (needscan) - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog, - NULL); + xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); if (needlog) xfs_dir2_data_log_header(tp, dbp); /* @@ -891,8 +917,9 @@ xfs_dir2_sf_to_block( int offset; /* target block offset */ xfs_dir2_sf_entry_t *sfep; /* sf entry pointer */ xfs_dir2_sf_t *sfp; /* shortform structure */ - xfs_dir2_data_off_t *tagp; /* end of data entry */ + __be16 *tagp; /* end of data entry */ xfs_trans_t *tp; /* transaction pointer */ + struct xfs_name name; xfs_dir2_trace_args("sf_to_block", args); dp = args->dp; @@ -909,7 +936,7 @@ xfs_dir2_sf_to_block( ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); ASSERT(dp->i_df.if_u1.if_data != NULL); sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count)); + ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); /* * Copy the directory into the stack buffer. * Then pitch the incore inode data so we can make extents. @@ -931,7 +958,7 @@ xfs_dir2_sf_to_block( */ error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, &blkno); if (error) { - kmem_free(buf, buf_len); + kmem_free(buf); return error; } /* @@ -939,16 +966,16 @@ xfs_dir2_sf_to_block( */ error = xfs_dir2_data_init(args, blkno, &bp); if (error) { - kmem_free(buf, buf_len); + kmem_free(buf); return error; } block = bp->data; - INT_SET(block->hdr.magic, ARCH_CONVERT, XFS_DIR2_BLOCK_MAGIC); + block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); /* * Compute size of block "tail" area. */ i = (uint)sizeof(*btp) + - (INT_GET(sfp->hdr.count, ARCH_CONVERT) + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t); + (sfp->hdr.count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t); /* * The whole thing is initialized to free by the init routine. * Say we're using the leaf and tail area. @@ -961,51 +988,53 @@ xfs_dir2_sf_to_block( /* * Fill in the tail. */ - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); - INT_SET(btp->count, ARCH_CONVERT, INT_GET(sfp->hdr.count, ARCH_CONVERT) + 2); /* ., .. */ + btp = xfs_dir2_block_tail_p(mp, block); + btp->count = cpu_to_be32(sfp->hdr.count + 2); /* ., .. */ btp->stale = 0; - blp = XFS_DIR2_BLOCK_LEAF_P(btp); + blp = xfs_dir2_block_leaf_p(btp); endoffset = (uint)((char *)blp - (char *)block); /* * Remove the freespace, we'll manage it. */ xfs_dir2_data_use_free(tp, bp, dup, (xfs_dir2_data_aoff_t)((char *)dup - (char *)block), - INT_GET(dup->length, ARCH_CONVERT), &needlog, &needscan); + be16_to_cpu(dup->length), &needlog, &needscan); /* * Create entry for . */ dep = (xfs_dir2_data_entry_t *) ((char *)block + XFS_DIR2_DATA_DOT_OFFSET); - INT_SET(dep->inumber, ARCH_CONVERT, dp->i_ino); + dep->inumber = cpu_to_be64(dp->i_ino); dep->namelen = 1; dep->name[0] = '.'; - tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); - INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block)); + tagp = xfs_dir2_data_entry_tag_p(dep); + *tagp = cpu_to_be16((char *)dep - (char *)block); xfs_dir2_data_log_entry(tp, bp, dep); - INT_SET(blp[0].hashval, ARCH_CONVERT, xfs_dir_hash_dot); - INT_SET(blp[0].address, ARCH_CONVERT, XFS_DIR2_BYTE_TO_DATAPTR(mp, (char *)dep - (char *)block)); + blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot); + blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, + (char *)dep - (char *)block)); /* * Create entry for .. */ dep = (xfs_dir2_data_entry_t *) ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET); - INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent)); + dep->inumber = cpu_to_be64(xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent)); dep->namelen = 2; dep->name[0] = dep->name[1] = '.'; - tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); - INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block)); + tagp = xfs_dir2_data_entry_tag_p(dep); + *tagp = cpu_to_be16((char *)dep - (char *)block); xfs_dir2_data_log_entry(tp, bp, dep); - INT_SET(blp[1].hashval, ARCH_CONVERT, xfs_dir_hash_dotdot); - INT_SET(blp[1].address, ARCH_CONVERT, XFS_DIR2_BYTE_TO_DATAPTR(mp, (char *)dep - (char *)block)); + blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); + blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, + (char *)dep - (char *)block)); offset = XFS_DIR2_DATA_FIRST_OFFSET; /* * Loop over existing entries, stuff them in. */ - if ((i = 0) == INT_GET(sfp->hdr.count, ARCH_CONVERT)) + if ((i = 0) == sfp->hdr.count) sfep = NULL; else - sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); + sfep = xfs_dir2_sf_firstentry(sfp); /* * Need to preserve the existing offset values in the sf directory. * Insert holes (unused entries) where necessary. @@ -1017,57 +1046,58 @@ xfs_dir2_sf_to_block( if (sfep == NULL) newoffset = endoffset; else - newoffset = XFS_DIR2_SF_GET_OFFSET(sfep); + newoffset = xfs_dir2_sf_get_offset(sfep); /* * There should be a hole here, make one. */ if (offset < newoffset) { dup = (xfs_dir2_data_unused_t *) ((char *)block + offset); - INT_SET(dup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG); - INT_SET(dup->length, ARCH_CONVERT, newoffset - offset); - INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT, - (xfs_dir2_data_off_t) + 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 *)block)); xfs_dir2_data_log_unused(tp, bp, dup); (void)xfs_dir2_data_freeinsert((xfs_dir2_data_t *)block, dup, &dummy); - offset += INT_GET(dup->length, ARCH_CONVERT); + offset += be16_to_cpu(dup->length); continue; } /* * Copy a real entry. */ dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset); - INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp, - XFS_DIR2_SF_INUMBERP(sfep))); + dep->inumber = cpu_to_be64(xfs_dir2_sf_get_inumber(sfp, + xfs_dir2_sf_inumberp(sfep))); dep->namelen = sfep->namelen; memcpy(dep->name, sfep->name, dep->namelen); - tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); - INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block)); + tagp = xfs_dir2_data_entry_tag_p(dep); + *tagp = cpu_to_be16((char *)dep - (char *)block); xfs_dir2_data_log_entry(tp, bp, dep); - blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops->hashname( - sfep->name, sfep->namelen)); + 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(mp, (char *)dep - (char *)block)); offset = (int)((char *)(tagp + 1) - (char *)block); - if (++i == INT_GET(sfp->hdr.count, ARCH_CONVERT)) + if (++i == sfp->hdr.count) sfep = NULL; else - sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep); + sfep = xfs_dir2_sf_nextentry(sfp, sfep); } /* Done with the temporary buffer */ - kmem_free(buf, buf_len); + kmem_free(buf); /* * Sort the leaf entries by hash value. */ - xfs_sort(blp, INT_GET(btp->count, ARCH_CONVERT), sizeof(*blp), xfs_dir2_block_sort); + xfs_sort(blp, be32_to_cpu(btp->count), sizeof(*blp), xfs_dir2_block_sort); /* * Log the leaf entry area and tail. * Already logged the header in data_init, ignore needlog. */ ASSERT(needscan == 0); - xfs_dir2_block_log_leaf(tp, bp, 0, INT_GET(btp->count, ARCH_CONVERT) - 1); + xfs_dir2_block_log_leaf(tp, bp, 0, be32_to_cpu(btp->count) - 1); xfs_dir2_block_log_tail(tp, bp); xfs_dir2_data_check(dp, bp); xfs_da_buf_done(bp); diff --git a/libxfs/xfs_dir2_data.c b/libxfs/xfs_dir2_data.c index bd3e8f150..d89b5b1f0 100644 --- a/libxfs/xfs_dir2_data.c +++ b/libxfs/xfs_dir2_data.c @@ -16,12 +16,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -/* - * xfs_dir2_data.c - * Core data block handling routines for XFS V2 directories. - * See xfs_dir2_data.h for data structures. - */ - #include @@ -53,16 +47,17 @@ xfs_dir2_data_check( xfs_mount_t *mp; /* filesystem mount point */ char *p; /* current data position */ int stale; /* count of stale leaves */ + struct xfs_name name; mp = dp->i_mount; d = bp->data; - ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || - INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); + ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || + be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); bf = d->hdr.bestfree; p = (char *)d->u; - if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) { - btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d); - lep = XFS_DIR2_BLOCK_LEAF_P(btp); + if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { + btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); + lep = xfs_dir2_block_leaf_p(btp); endp = (char *)lep; } else endp = (char *)d + mp->m_dirblksize; @@ -82,8 +77,8 @@ xfs_dir2_data_check( ASSERT(!bf[2].offset); freeseen |= 1 << 2; } - ASSERT(INT_GET(bf[0].length, ARCH_CONVERT) >= INT_GET(bf[1].length, ARCH_CONVERT)); - ASSERT(INT_GET(bf[1].length, ARCH_CONVERT) >= INT_GET(bf[2].length, ARCH_CONVERT)); + ASSERT(be16_to_cpu(bf[0].length) >= be16_to_cpu(bf[1].length)); + ASSERT(be16_to_cpu(bf[1].length) >= be16_to_cpu(bf[2].length)); /* * Loop over the data/unused entries. */ @@ -94,18 +89,20 @@ xfs_dir2_data_check( * If we find it, account for that, else make sure it * doesn't need to be there. */ - if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) { + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { ASSERT(lastfree == 0); - ASSERT(INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT) == + ASSERT(be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) == (char *)dup - (char *)d); dfp = xfs_dir2_data_freefind(d, dup); if (dfp) { i = (int)(dfp - bf); ASSERT((freeseen & (1 << i)) == 0); freeseen |= 1 << i; - } else - ASSERT(INT_GET(dup->length, ARCH_CONVERT) <= INT_GET(bf[2].length, ARCH_CONVERT)); - p += INT_GET(dup->length, ARCH_CONVERT); + } else { + ASSERT(be16_to_cpu(dup->length) <= + be16_to_cpu(bf[2].length)); + } + p += be16_to_cpu(dup->length); lastfree = 1; continue; } @@ -117,38 +114,40 @@ xfs_dir2_data_check( */ dep = (xfs_dir2_data_entry_t *)p; ASSERT(dep->namelen != 0); - ASSERT(xfs_dir_ino_validate(mp, INT_GET(dep->inumber, ARCH_CONVERT)) == 0); - ASSERT(INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(dep), ARCH_CONVERT) == + ASSERT(xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)) == 0); + ASSERT(be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) == (char *)dep - (char *)d); count++; lastfree = 0; - if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) { - addr = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, + if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { + addr = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, (xfs_dir2_data_aoff_t) ((char *)dep - (char *)d)); - 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) + name.name = dep->name; + name.len = dep->namelen; + hash = mp->m_dirnameops->hashname(&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) break; } - ASSERT(i < INT_GET(btp->count, ARCH_CONVERT)); + ASSERT(i < be32_to_cpu(btp->count)); } - p += XFS_DIR2_DATA_ENTSIZE(dep->namelen); + p += xfs_dir2_data_entsize(dep->namelen); } /* * Need to have seen all the entries and all the bestfree slots. */ ASSERT(freeseen == 7); - if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) { - for (i = stale = 0; i < INT_GET(btp->count, ARCH_CONVERT); i++) { - if (INT_GET(lep[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) + if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { + for (i = stale = 0; i < be32_to_cpu(btp->count); i++) { + if (be32_to_cpu(lep[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; if (i > 0) - ASSERT(INT_GET(lep[i].hashval, ARCH_CONVERT) >= INT_GET(lep[i - 1].hashval, ARCH_CONVERT)); + ASSERT(be32_to_cpu(lep[i].hashval) >= be32_to_cpu(lep[i - 1].hashval)); } - ASSERT(count == INT_GET(btp->count, ARCH_CONVERT) - INT_GET(btp->stale, ARCH_CONVERT)); - ASSERT(stale == INT_GET(btp->stale, ARCH_CONVERT)); + ASSERT(count == be32_to_cpu(btp->count) - be32_to_cpu(btp->stale)); + ASSERT(stale == be32_to_cpu(btp->stale)); } } #endif @@ -176,8 +175,8 @@ xfs_dir2_data_freefind( * Check order, non-overlapping entries, and if we find the * one we're looking for it has to be exact. */ - ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || - INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); + ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || + be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); for (dfp = &d->hdr.bestfree[0], seenzero = matched = 0; dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT]; dfp++) { @@ -187,23 +186,24 @@ xfs_dir2_data_freefind( continue; } ASSERT(seenzero == 0); - if (INT_GET(dfp->offset, ARCH_CONVERT) == off) { + if (be16_to_cpu(dfp->offset) == off) { matched = 1; - ASSERT(INT_GET(dfp->length, ARCH_CONVERT) == INT_GET(dup->length, ARCH_CONVERT)); - } else if (off < INT_GET(dfp->offset, ARCH_CONVERT)) - ASSERT(off + INT_GET(dup->length, ARCH_CONVERT) <= INT_GET(dfp->offset, ARCH_CONVERT)); + ASSERT(dfp->length == dup->length); + } else if (off < be16_to_cpu(dfp->offset)) + ASSERT(off + be16_to_cpu(dup->length) <= be16_to_cpu(dfp->offset)); else - ASSERT(INT_GET(dfp->offset, ARCH_CONVERT) + INT_GET(dfp->length, ARCH_CONVERT) <= off); - ASSERT(matched || INT_GET(dfp->length, ARCH_CONVERT) >= INT_GET(dup->length, ARCH_CONVERT)); + ASSERT(be16_to_cpu(dfp->offset) + be16_to_cpu(dfp->length) <= off); + ASSERT(matched || be16_to_cpu(dfp->length) >= be16_to_cpu(dup->length)); if (dfp > &d->hdr.bestfree[0]) - ASSERT(INT_GET(dfp[-1].length, ARCH_CONVERT) >= INT_GET(dfp[0].length, ARCH_CONVERT)); + ASSERT(be16_to_cpu(dfp[-1].length) >= be16_to_cpu(dfp[0].length)); } #endif /* * If this is smaller than the smallest bestfree entry, * it can't be there since they're sorted. */ - if (INT_GET(dup->length, ARCH_CONVERT) < INT_GET(d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length, ARCH_CONVERT)) + if (be16_to_cpu(dup->length) < + be16_to_cpu(d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length)) return NULL; /* * Look at the three bestfree entries for our guy. @@ -213,7 +213,7 @@ xfs_dir2_data_freefind( dfp++) { if (!dfp->offset) return NULL; - if (INT_GET(dfp->offset, ARCH_CONVERT) == off) + if (be16_to_cpu(dfp->offset) == off) return dfp; } /* @@ -235,29 +235,29 @@ xfs_dir2_data_freeinsert( xfs_dir2_data_free_t new; /* new bestfree entry */ #ifdef __KERNEL__ - ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || - INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); + ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || + be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); #endif dfp = d->hdr.bestfree; - INT_COPY(new.length, dup->length, ARCH_CONVERT); - INT_SET(new.offset, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dup - (char *)d)); + new.length = dup->length; + new.offset = cpu_to_be16((char *)dup - (char *)d); /* * Insert at position 0, 1, or 2; or not at all. */ - if (INT_GET(new.length, ARCH_CONVERT) > INT_GET(dfp[0].length, ARCH_CONVERT)) { + if (be16_to_cpu(new.length) > be16_to_cpu(dfp[0].length)) { dfp[2] = dfp[1]; dfp[1] = dfp[0]; dfp[0] = new; *loghead = 1; return &dfp[0]; } - if (INT_GET(new.length, ARCH_CONVERT) > INT_GET(dfp[1].length, ARCH_CONVERT)) { + if (be16_to_cpu(new.length) > be16_to_cpu(dfp[1].length)) { dfp[2] = dfp[1]; dfp[1] = new; *loghead = 1; return &dfp[1]; } - if (INT_GET(new.length, ARCH_CONVERT) > INT_GET(dfp[2].length, ARCH_CONVERT)) { + if (be16_to_cpu(new.length) > be16_to_cpu(dfp[2].length)) { dfp[2] = new; *loghead = 1; return &dfp[2]; @@ -268,15 +268,15 @@ xfs_dir2_data_freeinsert( /* * Remove a bestfree entry from the table. */ -void +STATIC void xfs_dir2_data_freeremove( xfs_dir2_data_t *d, /* data block pointer */ xfs_dir2_data_free_t *dfp, /* bestfree entry pointer */ int *loghead) /* out: log data header */ { #ifdef __KERNEL__ - ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || - INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); + ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || + be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); #endif /* * It's the first entry, slide the next 2 up. @@ -310,8 +310,7 @@ void xfs_dir2_data_freescan( xfs_mount_t *mp, /* filesystem mount point */ xfs_dir2_data_t *d, /* data block pointer */ - int *loghead, /* out: log data header */ - char *aendp) /* in: caller's endp */ + int *loghead) /* out: log data header */ { xfs_dir2_block_tail_t *btp; /* block tail */ xfs_dir2_data_entry_t *dep; /* active data entry */ @@ -320,8 +319,8 @@ xfs_dir2_data_freescan( char *p; /* current entry pointer */ #ifdef __KERNEL__ - ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || - INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); + ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || + be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); #endif /* * Start by clearing the table. @@ -332,11 +331,9 @@ xfs_dir2_data_freescan( * Set up pointers. */ p = (char *)d->u; - if (aendp) - endp = aendp; - else if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) { - btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d); - endp = (char *)XFS_DIR2_BLOCK_LEAF_P(btp); + if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { + btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); + endp = (char *)xfs_dir2_block_leaf_p(btp); } else endp = (char *)d + mp->m_dirblksize; /* @@ -347,11 +344,11 @@ xfs_dir2_data_freescan( /* * If it's a free entry, insert it. */ - if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) { + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { ASSERT((char *)dup - (char *)d == - INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT)); + be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); xfs_dir2_data_freeinsert(d, dup, loghead); - p += INT_GET(dup->length, ARCH_CONVERT); + p += be16_to_cpu(dup->length); } /* * For active entries, check their tags and skip them. @@ -359,8 +356,8 @@ xfs_dir2_data_freescan( else { dep = (xfs_dir2_data_entry_t *)p; ASSERT((char *)dep - (char *)d == - INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(dep), ARCH_CONVERT)); - p += XFS_DIR2_DATA_ENTSIZE(dep->namelen); + be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep))); + p += xfs_dir2_data_entsize(dep->namelen); } } } @@ -391,7 +388,7 @@ xfs_dir2_data_init( /* * Get the buffer set up for the block. */ - error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, blkno), -1, &bp, + error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, blkno), -1, &bp, XFS_DATA_FORK); if (error) { return error; @@ -401,8 +398,8 @@ xfs_dir2_data_init( * Initialize the header. */ d = bp->data; - INT_SET(d->hdr.magic, ARCH_CONVERT, XFS_DIR2_DATA_MAGIC); - INT_SET(d->hdr.bestfree[0].offset, ARCH_CONVERT, (xfs_dir2_data_off_t)sizeof(d->hdr)); + d->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); + d->hdr.bestfree[0].offset = cpu_to_be16(sizeof(d->hdr)); for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) { d->hdr.bestfree[i].length = 0; d->hdr.bestfree[i].offset = 0; @@ -411,13 +408,12 @@ xfs_dir2_data_init( * Set up an unused entry for the block's body. */ dup = &d->u[0].unused; - INT_SET(dup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG); + dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); t=mp->m_dirblksize - (uint)sizeof(d->hdr); - INT_SET(d->hdr.bestfree[0].length, ARCH_CONVERT, t); - INT_SET(dup->length, ARCH_CONVERT, t); - INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT, - (xfs_dir2_data_off_t)((char *)dup - (char *)d)); + d->hdr.bestfree[0].length = cpu_to_be16(t); + dup->length = cpu_to_be16(t); + *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)d); /* * Log it and return it. */ @@ -439,10 +435,10 @@ xfs_dir2_data_log_entry( xfs_dir2_data_t *d; /* data block pointer */ d = bp->data; - ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || - INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); + ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || + be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); xfs_da_log_buf(tp, bp, (uint)((char *)dep - (char *)d), - (uint)((char *)(XFS_DIR2_DATA_ENTRY_TAG_P(dep) + 1) - + (uint)((char *)(xfs_dir2_data_entry_tag_p(dep) + 1) - (char *)d - 1)); } @@ -457,8 +453,8 @@ xfs_dir2_data_log_header( xfs_dir2_data_t *d; /* data block pointer */ d = bp->data; - ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || - INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); + ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || + be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); xfs_da_log_buf(tp, bp, (uint)((char *)&d->hdr - (char *)d), (uint)(sizeof(d->hdr) - 1)); } @@ -475,8 +471,8 @@ xfs_dir2_data_log_unused( xfs_dir2_data_t *d; /* data block pointer */ d = bp->data; - ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || - INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); + ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || + be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); /* * Log the first part of the unused entry. */ @@ -487,8 +483,8 @@ xfs_dir2_data_log_unused( * Log the end (tag) of the unused entry. */ xfs_da_log_buf(tp, bp, - (uint)((char *)XFS_DIR2_DATA_UNUSED_TAG_P(dup) - (char *)d), - (uint)((char *)XFS_DIR2_DATA_UNUSED_TAG_P(dup) - (char *)d + + (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)d), + (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)d + sizeof(xfs_dir2_data_off_t) - 1)); } @@ -519,25 +515,25 @@ xfs_dir2_data_make_free( /* * Figure out where the end of the data area is. */ - if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC) + if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC) endptr = (char *)d + mp->m_dirblksize; else { xfs_dir2_block_tail_t *btp; /* block tail */ - ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); - btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d); - endptr = (char *)XFS_DIR2_BLOCK_LEAF_P(btp); + ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); + btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); + endptr = (char *)xfs_dir2_block_leaf_p(btp); } /* * If this isn't the start of the block, then back up to * the previous entry and see if it's free. */ if (offset > sizeof(d->hdr)) { - xfs_dir2_data_off_t *tagp; /* tag just before us */ + __be16 *tagp; /* tag just before us */ - tagp = (xfs_dir2_data_off_t *)((char *)d + offset) - 1; - prevdup = (xfs_dir2_data_unused_t *)((char *)d + INT_GET(*tagp, ARCH_CONVERT)); - if (INT_GET(prevdup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG) + tagp = (__be16 *)((char *)d + offset) - 1; + prevdup = (xfs_dir2_data_unused_t *)((char *)d + be16_to_cpu(*tagp)); + if (be16_to_cpu(prevdup->freetag) != XFS_DIR2_DATA_FREE_TAG) prevdup = NULL; } else prevdup = NULL; @@ -548,7 +544,7 @@ xfs_dir2_data_make_free( if ((char *)d + offset + len < endptr) { postdup = (xfs_dir2_data_unused_t *)((char *)d + offset + len); - if (INT_GET(postdup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG) + if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG) postdup = NULL; } else postdup = NULL; @@ -572,13 +568,13 @@ xfs_dir2_data_make_free( * since the third bestfree is there, there might be more * entries. */ - needscan = d->hdr.bestfree[2].length; + needscan = (d->hdr.bestfree[2].length != 0); /* * Fix up the new big freespace. */ - INT_MOD(prevdup->length, ARCH_CONVERT, len + INT_GET(postdup->length, ARCH_CONVERT)); - INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(prevdup), ARCH_CONVERT, - (xfs_dir2_data_off_t)((char *)prevdup - (char *)d)); + be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length)); + *xfs_dir2_data_unused_tag_p(prevdup) = + cpu_to_be16((char *)prevdup - (char *)d); xfs_dir2_data_log_unused(tp, bp, prevdup); if (!needscan) { /* @@ -600,7 +596,7 @@ xfs_dir2_data_make_free( */ dfp = xfs_dir2_data_freeinsert(d, prevdup, needlogp); ASSERT(dfp == &d->hdr.bestfree[0]); - ASSERT(INT_GET(dfp->length, ARCH_CONVERT) == INT_GET(prevdup->length, ARCH_CONVERT)); + ASSERT(dfp->length == prevdup->length); ASSERT(!dfp[1].length); ASSERT(!dfp[2].length); } @@ -610,9 +606,9 @@ xfs_dir2_data_make_free( */ else if (prevdup) { dfp = xfs_dir2_data_freefind(d, prevdup); - INT_MOD(prevdup->length, ARCH_CONVERT, len); - INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(prevdup), ARCH_CONVERT, - (xfs_dir2_data_off_t)((char *)prevdup - (char *)d)); + be16_add_cpu(&prevdup->length, len); + *xfs_dir2_data_unused_tag_p(prevdup) = + cpu_to_be16((char *)prevdup - (char *)d); xfs_dir2_data_log_unused(tp, bp, prevdup); /* * If the previous entry was in the table, the new entry @@ -626,8 +622,10 @@ xfs_dir2_data_make_free( /* * Otherwise we need a scan if the new entry is big enough. */ - else - needscan = INT_GET(prevdup->length, ARCH_CONVERT) > INT_GET(d->hdr.bestfree[2].length, ARCH_CONVERT); + else { + needscan = be16_to_cpu(prevdup->length) > + be16_to_cpu(d->hdr.bestfree[2].length); + } } /* * The following entry is free, merge with it. @@ -635,10 +633,10 @@ xfs_dir2_data_make_free( else if (postdup) { dfp = xfs_dir2_data_freefind(d, postdup); newdup = (xfs_dir2_data_unused_t *)((char *)d + offset); - INT_SET(newdup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG); - INT_SET(newdup->length, ARCH_CONVERT, len + INT_GET(postdup->length, ARCH_CONVERT)); - INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT, - (xfs_dir2_data_off_t)((char *)newdup - (char *)d)); + newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); + newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length)); + *xfs_dir2_data_unused_tag_p(newdup) = + cpu_to_be16((char *)newdup - (char *)d); xfs_dir2_data_log_unused(tp, bp, newdup); /* * If the following entry was in the table, the new entry @@ -652,18 +650,20 @@ xfs_dir2_data_make_free( /* * Otherwise we need a scan if the new entry is big enough. */ - else - needscan = INT_GET(newdup->length, ARCH_CONVERT) > INT_GET(d->hdr.bestfree[2].length, ARCH_CONVERT); + else { + needscan = be16_to_cpu(newdup->length) > + be16_to_cpu(d->hdr.bestfree[2].length); + } } /* * Neither neighbor is free. Make a new entry. */ else { newdup = (xfs_dir2_data_unused_t *)((char *)d + offset); - INT_SET(newdup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG); - INT_SET(newdup->length, ARCH_CONVERT, len); - INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT, - (xfs_dir2_data_off_t)((char *)newdup - (char *)d)); + newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); + newdup->length = cpu_to_be16(len); + *xfs_dir2_data_unused_tag_p(newdup) = + cpu_to_be16((char *)newdup - (char *)d); xfs_dir2_data_log_unused(tp, bp, newdup); (void)xfs_dir2_data_freeinsert(d, newdup, needlogp); } @@ -693,18 +693,18 @@ xfs_dir2_data_use_free( int oldlen; /* old unused entry's length */ d = bp->data; - ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || - INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); - ASSERT(INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG); + ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || + be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); + ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG); ASSERT(offset >= (char *)dup - (char *)d); - ASSERT(offset + len <= (char *)dup + INT_GET(dup->length, ARCH_CONVERT) - (char *)d); - ASSERT((char *)dup - (char *)d == INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT)); + ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)d); + ASSERT((char *)dup - (char *)d == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); /* * Look up the entry in the bestfree table. */ dfp = xfs_dir2_data_freefind(d, dup); - oldlen = INT_GET(dup->length, ARCH_CONVERT); - ASSERT(dfp || oldlen <= INT_GET(d->hdr.bestfree[2].length, ARCH_CONVERT)); + oldlen = be16_to_cpu(dup->length); + ASSERT(dfp || oldlen <= be16_to_cpu(d->hdr.bestfree[2].length)); /* * Check for alignment with front and back of the entry. */ @@ -718,7 +718,7 @@ xfs_dir2_data_use_free( */ if (matchfront && matchback) { if (dfp) { - needscan = d->hdr.bestfree[2].offset; + needscan = (d->hdr.bestfree[2].offset != 0); if (!needscan) xfs_dir2_data_freeremove(d, dfp, needlogp); } @@ -729,10 +729,10 @@ xfs_dir2_data_use_free( */ else if (matchfront) { newdup = (xfs_dir2_data_unused_t *)((char *)d + offset + len); - INT_SET(newdup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG); - INT_SET(newdup->length, ARCH_CONVERT, oldlen - len); - INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT, - (xfs_dir2_data_off_t)((char *)newdup - (char *)d)); + newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); + newdup->length = cpu_to_be16(oldlen - len); + *xfs_dir2_data_unused_tag_p(newdup) = + cpu_to_be16((char *)newdup - (char *)d); xfs_dir2_data_log_unused(tp, bp, newdup); /* * If it was in the table, remove it and add the new one. @@ -741,8 +741,8 @@ xfs_dir2_data_use_free( xfs_dir2_data_freeremove(d, dfp, needlogp); dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp); ASSERT(dfp != NULL); - ASSERT(INT_GET(dfp->length, ARCH_CONVERT) == INT_GET(newdup->length, ARCH_CONVERT)); - ASSERT(INT_GET(dfp->offset, ARCH_CONVERT) == (char *)newdup - (char *)d); + ASSERT(dfp->length == newdup->length); + ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d); /* * If we got inserted at the last slot, * that means we don't know if there was a better @@ -757,10 +757,9 @@ xfs_dir2_data_use_free( */ else if (matchback) { newdup = dup; - INT_SET(newdup->length, ARCH_CONVERT, (xfs_dir2_data_off_t) - (((char *)d + offset) - (char *)newdup)); - INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT, - (xfs_dir2_data_off_t)((char *)newdup - (char *)d)); + newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup); + *xfs_dir2_data_unused_tag_p(newdup) = + cpu_to_be16((char *)newdup - (char *)d); xfs_dir2_data_log_unused(tp, bp, newdup); /* * If it was in the table, remove it and add the new one. @@ -769,8 +768,8 @@ xfs_dir2_data_use_free( xfs_dir2_data_freeremove(d, dfp, needlogp); dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp); ASSERT(dfp != NULL); - ASSERT(INT_GET(dfp->length, ARCH_CONVERT) == INT_GET(newdup->length, ARCH_CONVERT)); - ASSERT(INT_GET(dfp->offset, ARCH_CONVERT) == (char *)newdup - (char *)d); + ASSERT(dfp->length == newdup->length); + ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d); /* * If we got inserted at the last slot, * that means we don't know if there was a better @@ -785,16 +784,15 @@ xfs_dir2_data_use_free( */ else { newdup = dup; - INT_SET(newdup->length, ARCH_CONVERT, (xfs_dir2_data_off_t) - (((char *)d + offset) - (char *)newdup)); - INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT, - (xfs_dir2_data_off_t)((char *)newdup - (char *)d)); + newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup); + *xfs_dir2_data_unused_tag_p(newdup) = + cpu_to_be16((char *)newdup - (char *)d); xfs_dir2_data_log_unused(tp, bp, newdup); newdup2 = (xfs_dir2_data_unused_t *)((char *)d + offset + len); - INT_SET(newdup2->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG); - INT_SET(newdup2->length, ARCH_CONVERT, oldlen - len - INT_GET(newdup->length, ARCH_CONVERT)); - INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup2), ARCH_CONVERT, - (xfs_dir2_data_off_t)((char *)newdup2 - (char *)d)); + newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); + newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length)); + *xfs_dir2_data_unused_tag_p(newdup2) = + cpu_to_be16((char *)newdup2 - (char *)d); xfs_dir2_data_log_unused(tp, bp, newdup2); /* * If the old entry was in the table, we need to scan @@ -805,7 +803,7 @@ xfs_dir2_data_use_free( * the 2 new will work. */ if (dfp) { - needscan = d->hdr.bestfree[2].length; + needscan = (d->hdr.bestfree[2].length != 0); if (!needscan) { xfs_dir2_data_freeremove(d, dfp, needlogp); (void)xfs_dir2_data_freeinsert(d, newdup, diff --git a/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c index 1348ef2ef..9a1aaceb8 100644 --- a/libxfs/xfs_dir2_leaf.c +++ b/libxfs/xfs_dir2_leaf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -16,18 +16,22 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + /* - * xfs_dir2_leaf.c - * XFS directory version 2 implementation - single leaf form - * see xfs_dir2_leaf.h for data structures. - * These directories have multiple XFS_DIR2_DATA blocks and one - * XFS_DIR2_LEAF1 block containing the hash table and freespace map. + * Local function declarations. */ +#ifdef DEBUG +static void xfs_dir2_leaf_check(xfs_inode_t *dp, xfs_dabuf_t *bp); +#else +#define xfs_dir2_leaf_check(dp, bp) +#endif +static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **lbpp, + int *indexp, xfs_dabuf_t **dbpp); +static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp, + int first, int last); +static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp); -#include - -static void xfs_dir2_leaf_log_bests(xfs_trans_t *, xfs_dabuf_t *, int, int); -static void xfs_dir2_leaf_log_tail(xfs_trans_t *, xfs_dabuf_t *); /* * Convert a block form directory to a leaf form directory. @@ -37,7 +41,7 @@ xfs_dir2_block_to_leaf( xfs_da_args_t *args, /* operation arguments */ xfs_dabuf_t *dbp) /* input block's buffer */ { - xfs_dir2_data_off_t *bestsp; /* leaf's bestsp entries */ + __be16 *bestsp; /* leaf's bestsp entries */ xfs_dablk_t blkno; /* leaf block's bno */ xfs_dir2_block_t *block; /* block structure */ xfs_dir2_leaf_entry_t *blp; /* block's leaf entries */ @@ -65,7 +69,7 @@ xfs_dir2_block_to_leaf( if ((error = xfs_da_grow_inode(args, &blkno))) { return error; } - ldb = XFS_DIR2_DA_TO_DB(mp, blkno); + ldb = xfs_dir2_da_to_db(mp, blkno); ASSERT(ldb == XFS_DIR2_LEAF_FIRSTDB(mp)); /* * Initialize the leaf block, get a buffer for it. @@ -77,19 +81,19 @@ xfs_dir2_block_to_leaf( leaf = lbp->data; block = dbp->data; xfs_dir2_data_check(dp, dbp); - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); - blp = XFS_DIR2_BLOCK_LEAF_P(btp); + btp = xfs_dir2_block_tail_p(mp, block); + blp = xfs_dir2_block_leaf_p(btp); /* * Set the counts in the leaf header. */ - INT_COPY(leaf->hdr.count, btp->count, ARCH_CONVERT); /* INT_: type change */ - INT_COPY(leaf->hdr.stale, btp->stale, ARCH_CONVERT); /* INT_: type change */ + leaf->hdr.count = cpu_to_be16(be32_to_cpu(btp->count)); + leaf->hdr.stale = cpu_to_be16(be32_to_cpu(btp->stale)); /* * Could compact these but I think we always do the conversion * after squeezing out stale entries. */ - memcpy(leaf->ents, blp, INT_GET(btp->count, ARCH_CONVERT) * sizeof(xfs_dir2_leaf_entry_t)); - xfs_dir2_leaf_log_ents(tp, lbp, 0, INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1); + memcpy(leaf->ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t)); + xfs_dir2_leaf_log_ents(tp, lbp, 0, be16_to_cpu(leaf->hdr.count) - 1); needscan = 0; needlog = 1; /* @@ -104,17 +108,16 @@ xfs_dir2_block_to_leaf( /* * Fix up the block header, make it a data block. */ - INT_SET(block->hdr.magic, ARCH_CONVERT, XFS_DIR2_DATA_MAGIC); + block->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); if (needscan) - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog, - NULL); + xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); /* * Set up leaf tail and bests table. */ - ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); - INT_SET(ltp->bestcount, ARCH_CONVERT, 1); - bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); - INT_COPY(bestsp[0], block->hdr.bestfree[0].length, ARCH_CONVERT); + ltp = xfs_dir2_leaf_tail_p(mp, leaf); + ltp->bestcount = cpu_to_be32(1); + bestsp = xfs_dir2_leaf_bests_p(ltp); + bestsp[0] = block->hdr.bestfree[0].length; /* * Log the data header and leaf bests table. */ @@ -134,7 +137,7 @@ int /* error */ xfs_dir2_leaf_addname( xfs_da_args_t *args) /* operation arguments */ { - xfs_dir2_data_off_t *bestsp; /* freespace table in leaf */ + __be16 *bestsp; /* freespace table in leaf */ int compact; /* need to compact leaves */ xfs_dir2_data_t *data; /* data block structure */ xfs_dabuf_t *dbp; /* data block buffer */ @@ -158,7 +161,7 @@ xfs_dir2_leaf_addname( int needbytes; /* leaf block bytes needed */ int needlog; /* need to log data header */ int needscan; /* need to rescan data free */ - xfs_dir2_data_off_t *tagp; /* end of data entry */ + __be16 *tagp; /* end of data entry */ xfs_trans_t *tp; /* transaction pointer */ xfs_dir2_db_t use_block; /* data block number */ @@ -183,9 +186,9 @@ xfs_dir2_leaf_addname( */ index = xfs_dir2_leaf_search_hash(args, lbp); leaf = lbp->data; - ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); - bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); - length = XFS_DIR2_DATA_ENTSIZE(args->namelen); + ltp = xfs_dir2_leaf_tail_p(mp, leaf); + bestsp = xfs_dir2_leaf_bests_p(ltp); + length = xfs_dir2_data_entsize(args->namelen); /* * See if there are any entries with the same hash value * and space in their block for the new entry. @@ -193,14 +196,14 @@ xfs_dir2_leaf_addname( * in a data block, improving the lookup of those entries. */ for (use_block = -1, lep = &leaf->ents[index]; - index < INT_GET(leaf->hdr.count, ARCH_CONVERT) && INT_GET(lep->hashval, ARCH_CONVERT) == args->hashval; + index < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(lep->hashval) == args->hashval; index++, lep++) { - if (INT_GET(lep->address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) + if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) continue; - i = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT)); - ASSERT(i < INT_GET(ltp->bestcount, ARCH_CONVERT)); - ASSERT(INT_GET(bestsp[i], ARCH_CONVERT) != NULLDATAOFF); - if (INT_GET(bestsp[i], ARCH_CONVERT) >= length) { + i = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); + ASSERT(i < be32_to_cpu(ltp->bestcount)); + ASSERT(be16_to_cpu(bestsp[i]) != NULLDATAOFF); + if (be16_to_cpu(bestsp[i]) >= length) { use_block = i; break; } @@ -209,13 +212,13 @@ xfs_dir2_leaf_addname( * Didn't find a block yet, linear search all the data blocks. */ if (use_block == -1) { - for (i = 0; i < INT_GET(ltp->bestcount, ARCH_CONVERT); i++) { + for (i = 0; i < be32_to_cpu(ltp->bestcount); i++) { /* * Remember a block we see that's missing. */ - if (INT_GET(bestsp[i], ARCH_CONVERT) == NULLDATAOFF && use_block == -1) + if (be16_to_cpu(bestsp[i]) == NULLDATAOFF && use_block == -1) use_block = i; - else if (INT_GET(bestsp[i], ARCH_CONVERT) >= length) { + else if (be16_to_cpu(bestsp[i]) >= length) { use_block = i; break; } @@ -231,26 +234,27 @@ xfs_dir2_leaf_addname( * Now kill use_block if it refers to a missing block, so we * can use it as an indication of allocation needed. */ - if (use_block != -1 && INT_GET(bestsp[use_block], ARCH_CONVERT) == NULLDATAOFF) + if (use_block != -1 && be16_to_cpu(bestsp[use_block]) == NULLDATAOFF) use_block = -1; /* * If we don't have enough free bytes but we can make enough * by compacting out stale entries, we'll do that. */ - if ((char *)bestsp - (char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] < needbytes && - INT_GET(leaf->hdr.stale, ARCH_CONVERT) > 1) { + if ((char *)bestsp - (char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] < + needbytes && be16_to_cpu(leaf->hdr.stale) > 1) { compact = 1; } /* * Otherwise if we don't have enough free bytes we need to * convert to node form. */ - else if ((char *)bestsp - (char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] < - needbytes) { + else if ((char *)bestsp - (char *)&leaf->ents[be16_to_cpu( + leaf->hdr.count)] < needbytes) { /* * Just checking or no space reservation, give up. */ - if (args->justcheck || args->total == 0) { + if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || + args->total == 0) { xfs_da_brelse(tp, lbp); return XFS_ERROR(ENOSPC); } @@ -275,7 +279,7 @@ xfs_dir2_leaf_addname( * If just checking, then it will fit unless we needed to allocate * a new data block. */ - if (args->justcheck) { + if (args->op_flags & XFS_DA_OP_JUSTCHECK) { xfs_da_brelse(tp, lbp); return use_block == -1 ? XFS_ERROR(ENOSPC) : 0; } @@ -301,8 +305,8 @@ xfs_dir2_leaf_addname( * There are stale entries, so we'll need log-low and log-high * impossibly bad values later. */ - else if (INT_GET(leaf->hdr.stale, ARCH_CONVERT)) { - lfloglow = INT_GET(leaf->hdr.count, ARCH_CONVERT); + else if (be16_to_cpu(leaf->hdr.stale)) { + lfloglow = be16_to_cpu(leaf->hdr.count); lfloghigh = -1; } /* @@ -329,13 +333,13 @@ xfs_dir2_leaf_addname( * If we're adding a new data block on the end we need to * extend the bests table. Copy it up one entry. */ - if (use_block >= INT_GET(ltp->bestcount, ARCH_CONVERT)) { + if (use_block >= be32_to_cpu(ltp->bestcount)) { bestsp--; memmove(&bestsp[0], &bestsp[1], - INT_GET(ltp->bestcount, ARCH_CONVERT) * sizeof(bestsp[0])); - INT_MOD(ltp->bestcount, ARCH_CONVERT, +1); + be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0])); + be32_add_cpu(<p->bestcount, 1); xfs_dir2_leaf_log_tail(tp, lbp); - xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1); + xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); } /* * If we're filling in a previously empty block just log it. @@ -343,7 +347,7 @@ xfs_dir2_leaf_addname( else xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); data = dbp->data; - INT_COPY(bestsp[use_block], data->hdr.bestfree[0].length, ARCH_CONVERT); + bestsp[use_block] = data->hdr.bestfree[0].length; grown = 1; } /* @@ -352,7 +356,7 @@ xfs_dir2_leaf_addname( */ else { if ((error = - xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, use_block), + xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, use_block), -1, &dbp, XFS_DATA_FORK))) { xfs_da_brelse(tp, lbp); return error; @@ -365,8 +369,8 @@ xfs_dir2_leaf_addname( * Point to the biggest freespace in our data block. */ dup = (xfs_dir2_data_unused_t *) - ((char *)data + INT_GET(data->hdr.bestfree[0].offset, ARCH_CONVERT)); - ASSERT(INT_GET(dup->length, ARCH_CONVERT) >= length); + ((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset)); + ASSERT(be16_to_cpu(dup->length) >= length); needscan = needlog = 0; /* * Mark the initial part of our freespace in use for the new entry. @@ -378,16 +382,16 @@ xfs_dir2_leaf_addname( * Initialize our new entry (at last). */ dep = (xfs_dir2_data_entry_t *)dup; - INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); + dep->inumber = cpu_to_be64(args->inumber); dep->namelen = args->namelen; memcpy(dep->name, args->name, dep->namelen); - tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); - INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)data)); + tagp = xfs_dir2_data_entry_tag_p(dep); + *tagp = cpu_to_be16((char *)dep - (char *)data); /* * Need to scan fix up the bestfree table. */ if (needscan) - xfs_dir2_data_freescan(mp, data, &needlog, NULL); + xfs_dir2_data_freescan(mp, data, &needlog); /* * Need to log the data block's header. */ @@ -398,8 +402,8 @@ xfs_dir2_leaf_addname( * If the bests table needs to be changed, do it. * Log the change unless we've already done that. */ - if (INT_GET(bestsp[use_block], ARCH_CONVERT) != INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT)) { - INT_COPY(bestsp[use_block], data->hdr.bestfree[0].length, ARCH_CONVERT); + if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(data->hdr.bestfree[0].length)) { + bestsp[use_block] = data->hdr.bestfree[0].length; if (!grown) xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); } @@ -411,15 +415,15 @@ xfs_dir2_leaf_addname( /* * lep is still good as the index leaf entry. */ - if (index < INT_GET(leaf->hdr.count, ARCH_CONVERT)) + if (index < be16_to_cpu(leaf->hdr.count)) memmove(lep + 1, lep, - (INT_GET(leaf->hdr.count, ARCH_CONVERT) - index) * sizeof(*lep)); + (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep)); /* * Record low and high logging indices for the leaf. */ lfloglow = index; - lfloghigh = INT_GET(leaf->hdr.count, ARCH_CONVERT); - INT_MOD(leaf->hdr.count, ARCH_CONVERT, +1); + lfloghigh = be16_to_cpu(leaf->hdr.count); + be16_add_cpu(&leaf->hdr.count, 1); } /* * There are stale entries. @@ -439,7 +443,7 @@ xfs_dir2_leaf_addname( */ for (lowstale = index - 1; lowstale >= 0 && - INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) != + be32_to_cpu(leaf->ents[lowstale].address) != XFS_DIR2_NULL_DATAPTR; lowstale--) continue; @@ -449,8 +453,8 @@ xfs_dir2_leaf_addname( * lowstale entry would be better. */ for (highstale = index; - highstale < INT_GET(leaf->hdr.count, ARCH_CONVERT) && - INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) != + highstale < be16_to_cpu(leaf->hdr.count) && + be32_to_cpu(leaf->ents[highstale].address) != XFS_DIR2_NULL_DATAPTR && (lowstale < 0 || index - lowstale - 1 >= highstale - index); @@ -461,10 +465,10 @@ xfs_dir2_leaf_addname( * If the low one is better, use it. */ if (lowstale >= 0 && - (highstale == INT_GET(leaf->hdr.count, ARCH_CONVERT) || + (highstale == be16_to_cpu(leaf->hdr.count) || index - lowstale - 1 < highstale - index)) { ASSERT(index - lowstale - 1 >= 0); - ASSERT(INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) == + ASSERT(be32_to_cpu(leaf->ents[lowstale].address) == XFS_DIR2_NULL_DATAPTR); /* * Copy entries up to cover the stale entry @@ -483,10 +487,10 @@ xfs_dir2_leaf_addname( */ else { ASSERT(highstale - index >= 0); - ASSERT(INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) == + ASSERT(be32_to_cpu(leaf->ents[highstale].address) == XFS_DIR2_NULL_DATAPTR); /* - * Copy entries down to copver the stale entry + * Copy entries down to cover the stale entry * and make room for the new entry. */ if (highstale - index > 0) @@ -497,13 +501,14 @@ xfs_dir2_leaf_addname( lfloglow = MIN(index, lfloglow); lfloghigh = MAX(highstale, lfloghigh); } - INT_MOD(leaf->hdr.stale, ARCH_CONVERT, -1); + be16_add_cpu(&leaf->hdr.stale, -1); } /* * Fill in the new leaf entry. */ - INT_SET(lep->hashval, ARCH_CONVERT, args->hashval); - INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_DB_OFF_TO_DATAPTR(mp, use_block, INT_GET(*tagp, ARCH_CONVERT))); + lep->hashval = cpu_to_be32(args->hashval); + lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, use_block, + be16_to_cpu(*tagp))); /* * Log the leaf fields and give up the buffers. */ @@ -534,30 +539,30 @@ xfs_dir2_leaf_check( leaf = bp->data; mp = dp->i_mount; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); /* * This value is not restrictive enough. * Should factor in the size of the bests table as well. * We can deduce a value for that from di_size. */ - ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) <= XFS_DIR2_MAX_LEAF_ENTS(mp)); - ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); + ASSERT(be16_to_cpu(leaf->hdr.count) <= xfs_dir2_max_leaf_ents(mp)); + ltp = xfs_dir2_leaf_tail_p(mp, leaf); /* * Leaves and bests don't overlap. */ - ASSERT((char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] <= - (char *)XFS_DIR2_LEAF_BESTS_P(ltp)); + ASSERT((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] <= + (char *)xfs_dir2_leaf_bests_p(ltp)); /* * Check hash value order, count stale entries. */ - for (i = stale = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); i++) { - if (i + 1 < INT_GET(leaf->hdr.count, ARCH_CONVERT)) - ASSERT(INT_GET(leaf->ents[i].hashval, ARCH_CONVERT) <= - INT_GET(leaf->ents[i + 1].hashval, ARCH_CONVERT)); - if (INT_GET(leaf->ents[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) + for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { + if (i + 1 < be16_to_cpu(leaf->hdr.count)) + ASSERT(be32_to_cpu(leaf->ents[i].hashval) <= + be32_to_cpu(leaf->ents[i + 1].hashval)); + if (be32_to_cpu(leaf->ents[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; } - ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) == stale); + ASSERT(be16_to_cpu(leaf->hdr.stale) == stale); } #endif /* DEBUG */ @@ -582,8 +587,8 @@ xfs_dir2_leaf_compact( /* * Compress out the stale entries in place. */ - for (from = to = 0, loglow = -1; from < INT_GET(leaf->hdr.count, ARCH_CONVERT); from++) { - if (INT_GET(leaf->ents[from].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) + for (from = to = 0, loglow = -1; from < be16_to_cpu(leaf->hdr.count); from++) { + if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) continue; /* * Only actually copy the entries that are different. @@ -598,8 +603,8 @@ xfs_dir2_leaf_compact( /* * Update and log the header, log the leaf entries. */ - ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) == from - to); - INT_MOD(leaf->hdr.count, ARCH_CONVERT, -(INT_GET(leaf->hdr.stale, ARCH_CONVERT))); + ASSERT(be16_to_cpu(leaf->hdr.stale) == from - to); + be16_add_cpu(&leaf->hdr.count, -(be16_to_cpu(leaf->hdr.stale))); leaf->hdr.stale = 0; xfs_dir2_leaf_log_header(args->trans, bp); if (loglow != -1) @@ -633,14 +638,14 @@ xfs_dir2_leaf_compact_x1( int to; /* destination copy index */ leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) > 1); + ASSERT(be16_to_cpu(leaf->hdr.stale) > 1); index = *indexp; /* * Find the first stale entry before our index, if any. */ for (lowstale = index - 1; lowstale >= 0 && - INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR; + be32_to_cpu(leaf->ents[lowstale].address) != XFS_DIR2_NULL_DATAPTR; lowstale--) continue; /* @@ -648,8 +653,8 @@ xfs_dir2_leaf_compact_x1( * Stop if the answer would be worse than lowstale. */ for (highstale = index; - highstale < INT_GET(leaf->hdr.count, ARCH_CONVERT) && - INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR && + highstale < be16_to_cpu(leaf->hdr.count) && + be32_to_cpu(leaf->ents[highstale].address) != XFS_DIR2_NULL_DATAPTR && (lowstale < 0 || index - lowstale > highstale - index); highstale++) continue; @@ -657,7 +662,7 @@ xfs_dir2_leaf_compact_x1( * Pick the better of lowstale and highstale. */ if (lowstale >= 0 && - (highstale == INT_GET(leaf->hdr.count, ARCH_CONVERT) || + (highstale == be16_to_cpu(leaf->hdr.count) || index - lowstale <= highstale - index)) keepstale = lowstale; else @@ -666,14 +671,14 @@ xfs_dir2_leaf_compact_x1( * Copy the entries in place, removing all the stale entries * except keepstale. */ - for (from = to = 0; from < INT_GET(leaf->hdr.count, ARCH_CONVERT); from++) { + for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) { /* * Notice the new value of index. */ if (index == from) newindex = to; if (from != keepstale && - INT_GET(leaf->ents[from].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) { + be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) { if (from == to) *lowlogp = to; continue; @@ -701,8 +706,8 @@ xfs_dir2_leaf_compact_x1( /* * Adjust the leaf header values. */ - INT_MOD(leaf->hdr.count, ARCH_CONVERT, -(from - to)); - INT_SET(leaf->hdr.stale, ARCH_CONVERT, 1); + be16_add_cpu(&leaf->hdr.count, -(from - to)); + leaf->hdr.stale = cpu_to_be16(1); /* * Remember the low/high stale value only in the "right" * direction. @@ -710,8 +715,8 @@ xfs_dir2_leaf_compact_x1( if (lowstale >= newindex) lowstale = -1; else - highstale = INT_GET(leaf->hdr.count, ARCH_CONVERT); - *highlogp = INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1; + highstale = be16_to_cpu(leaf->hdr.count); + *highlogp = be16_to_cpu(leaf->hdr.count) - 1; *lowstalep = lowstale; *highstalep = highstale; } @@ -743,7 +748,7 @@ xfs_dir2_leaf_init( /* * Get the buffer for the block. */ - error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, bno), -1, &bp, + error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, bno), -1, &bp, XFS_DATA_FORK); if (error) { return error; @@ -753,7 +758,7 @@ xfs_dir2_leaf_init( /* * Initialize the header. */ - INT_SET(leaf->hdr.info.magic, ARCH_CONVERT, magic); + leaf->hdr.info.magic = cpu_to_be16(magic); leaf->hdr.info.forw = 0; leaf->hdr.info.back = 0; leaf->hdr.count = 0; @@ -765,7 +770,7 @@ xfs_dir2_leaf_init( * the block. */ if (magic == XFS_DIR2_LEAF1_MAGIC) { - ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); + ltp = xfs_dir2_leaf_tail_p(mp, leaf); ltp->bestcount = 0; xfs_dir2_leaf_log_tail(tp, bp); } @@ -776,23 +781,23 @@ xfs_dir2_leaf_init( /* * Log the bests entries indicated from a leaf1 block. */ -void +static void xfs_dir2_leaf_log_bests( xfs_trans_t *tp, /* transaction pointer */ xfs_dabuf_t *bp, /* leaf buffer */ int first, /* first entry to log */ int last) /* last entry to log */ { - xfs_dir2_data_off_t *firstb; /* pointer to first entry */ - xfs_dir2_data_off_t *lastb; /* pointer to last entry */ + __be16 *firstb; /* pointer to first entry */ + __be16 *lastb; /* pointer to last entry */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC); - ltp = XFS_DIR2_LEAF_TAIL_P(tp->t_mountp, leaf); - firstb = XFS_DIR2_LEAF_BESTS_P(ltp) + first; - lastb = XFS_DIR2_LEAF_BESTS_P(ltp) + last; + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); + ltp = xfs_dir2_leaf_tail_p(tp->t_mountp, leaf); + firstb = xfs_dir2_leaf_bests_p(ltp) + first; + lastb = xfs_dir2_leaf_bests_p(ltp) + last; xfs_da_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf), (uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1)); } @@ -812,8 +817,8 @@ xfs_dir2_leaf_log_ents( xfs_dir2_leaf_t *leaf; /* leaf structure */ leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC || - INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC || + be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); firstlep = &leaf->ents[first]; lastlep = &leaf->ents[last]; xfs_da_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf), @@ -831,8 +836,8 @@ xfs_dir2_leaf_log_header( xfs_dir2_leaf_t *leaf; /* leaf structure */ leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC || - INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC || + be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); xfs_da_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf), (uint)(sizeof(leaf->hdr) - 1)); } @@ -840,7 +845,7 @@ xfs_dir2_leaf_log_header( /* * Log the tail of the leaf1 block. */ -static void +STATIC void xfs_dir2_leaf_log_tail( xfs_trans_t *tp, /* transaction pointer */ xfs_dabuf_t *bp) /* leaf buffer */ @@ -851,8 +856,8 @@ xfs_dir2_leaf_log_tail( mp = tp->t_mountp; leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC); - ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); + ltp = xfs_dir2_leaf_tail_p(mp, leaf); xfs_da_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf), (uint)(mp->m_dirblksize - 1)); } @@ -896,14 +901,15 @@ xfs_dir2_leaf_lookup( */ dep = (xfs_dir2_data_entry_t *) ((char *)dbp->data + - XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, INT_GET(lep->address, ARCH_CONVERT))); + xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address))); /* - * Return the found inode number. + * Return the found inode number & CI name if appropriate */ - args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); + args->inumber = be64_to_cpu(dep->inumber); + error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); xfs_da_brelse(tp, dbp); xfs_da_brelse(tp, lbp); - return XFS_ERROR(EEXIST); + return XFS_ERROR(error); } /* @@ -912,15 +918,15 @@ xfs_dir2_leaf_lookup( * If not found dbpp will be NULL, and ENOENT comes back. * lbpp will always be filled in with the leaf buffer unless there's an error. */ -STATIC int /* error */ +static int /* error */ xfs_dir2_leaf_lookup_int( xfs_da_args_t *args, /* operation arguments */ xfs_dabuf_t **lbpp, /* out: leaf buffer */ int *indexp, /* out: index in leaf block */ xfs_dabuf_t **dbpp) /* out: data buffer */ { - xfs_dir2_db_t curdb; /* current data block number */ - xfs_dabuf_t *dbp; /* data buffer */ + xfs_dir2_db_t curdb = -1; /* current data block number */ + xfs_dabuf_t *dbp = NULL; /* data buffer */ xfs_dir2_data_entry_t *dep; /* data entry */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return code */ @@ -931,6 +937,8 @@ xfs_dir2_leaf_lookup_int( xfs_mount_t *mp; /* filesystem mount point */ xfs_dir2_db_t newdb; /* new data block number */ xfs_trans_t *tp; /* transaction pointer */ + xfs_dir2_db_t cidb = -1; /* case match data block no. */ + enum xfs_dacmp cmp; /* name compare result */ dp = args->dp; tp = args->trans; @@ -938,11 +946,10 @@ xfs_dir2_leaf_lookup_int( /* * Read the leaf block into the buffer. */ - if ((error = - xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp, - XFS_DATA_FORK))) { + error = xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp, + XFS_DATA_FORK); + if (error) return error; - } *lbpp = lbp; leaf = lbp->data; xfs_dir2_leaf_check(dp, lbp); @@ -954,18 +961,18 @@ xfs_dir2_leaf_lookup_int( * Loop over all the entries with the right hash value * looking to match the name. */ - for (lep = &leaf->ents[index], dbp = NULL, curdb = -1; - index < INT_GET(leaf->hdr.count, ARCH_CONVERT) && INT_GET(lep->hashval, ARCH_CONVERT) == args->hashval; - lep++, index++) { + for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) && + be32_to_cpu(lep->hashval) == args->hashval; + lep++, index++) { /* * Skip over stale leaf entries. */ - if (INT_GET(lep->address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) + if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) continue; /* * Get the new data block number. */ - newdb = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT)); + newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); /* * If it's not the same as the old data block number, * need to pitch the old one and read the new one. @@ -973,10 +980,10 @@ xfs_dir2_leaf_lookup_int( if (newdb != curdb) { if (dbp) xfs_da_brelse(tp, dbp); - if ((error = - xfs_da_read_buf(tp, dp, - XFS_DIR2_DB_TO_DA(mp, newdb), -1, &dbp, - XFS_DATA_FORK))) { + error = xfs_da_read_buf(tp, dp, + xfs_dir2_db_to_da(mp, newdb), + -1, &dbp, XFS_DATA_FORK); + if (error) { xfs_da_brelse(tp, lbp); return error; } @@ -986,24 +993,50 @@ xfs_dir2_leaf_lookup_int( /* * Point to the data entry. */ - dep = (xfs_dir2_data_entry_t *) - ((char *)dbp->data + - XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT))); + dep = (xfs_dir2_data_entry_t *)((char *)dbp->data + + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); /* - * If it matches then return it. + * Compare name and if it's an exact match, return the index + * and buffer. If it's the first case-insensitive match, store + * the index and buffer and continue looking for an exact match. */ - if (dep->namelen == args->namelen && - dep->name[0] == args->name[0] && - memcmp(dep->name, args->name, args->namelen) == 0) { - *dbpp = dbp; + cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); + if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { + args->cmpresult = cmp; *indexp = index; - return 0; + /* case exact match: return the current buffer. */ + if (cmp == XFS_CMP_EXACT) { + *dbpp = dbp; + return 0; + } + cidb = curdb; } } + ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); + /* + * Here, we can only be doing a lookup (not a rename or remove). + * If a case-insensitive match was found earlier, re-read the + * appropriate data block if required and return it. + */ + if (args->cmpresult == XFS_CMP_CASE) { + ASSERT(cidb != -1); + if (cidb != curdb) { + xfs_da_brelse(tp, dbp); + error = xfs_da_read_buf(tp, dp, + xfs_dir2_db_to_da(mp, cidb), + -1, &dbp, XFS_DATA_FORK); + if (error) { + xfs_da_brelse(tp, lbp); + return error; + } + } + *dbpp = dbp; + return 0; + } /* * No match found, return ENOENT. */ - ASSERT(args->oknoent); + ASSERT(cidb == -1); if (dbp) xfs_da_brelse(tp, dbp); xfs_da_brelse(tp, lbp); @@ -1017,7 +1050,7 @@ int /* error */ xfs_dir2_leaf_removename( xfs_da_args_t *args) /* operation arguments */ { - xfs_dir2_data_off_t *bestsp; /* leaf block best freespace */ + __be16 *bestsp; /* leaf block best freespace */ xfs_dir2_data_t *data; /* data block structure */ xfs_dir2_db_t db; /* data block number */ xfs_dabuf_t *dbp; /* data block buffer */ @@ -1053,48 +1086,48 @@ xfs_dir2_leaf_removename( * Point to the leaf entry, use that to point to the data entry. */ lep = &leaf->ents[index]; - db = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT)); + db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); dep = (xfs_dir2_data_entry_t *) - ((char *)data + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT))); + ((char *)data + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); needscan = needlog = 0; - oldbest = INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT); - ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); - bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); - ASSERT(INT_GET(bestsp[db], ARCH_CONVERT) == oldbest); + oldbest = be16_to_cpu(data->hdr.bestfree[0].length); + ltp = xfs_dir2_leaf_tail_p(mp, leaf); + bestsp = xfs_dir2_leaf_bests_p(ltp); + ASSERT(be16_to_cpu(bestsp[db]) == oldbest); /* * Mark the former data entry unused. */ xfs_dir2_data_make_free(tp, dbp, (xfs_dir2_data_aoff_t)((char *)dep - (char *)data), - XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan); + xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); /* * We just mark the leaf entry stale by putting a null in it. */ - INT_MOD(leaf->hdr.stale, ARCH_CONVERT, +1); + be16_add_cpu(&leaf->hdr.stale, 1); xfs_dir2_leaf_log_header(tp, lbp); - INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_NULL_DATAPTR); + lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); xfs_dir2_leaf_log_ents(tp, lbp, index, index); /* * Scan the freespace in the data block again if necessary, * log the data block header if necessary. */ if (needscan) - xfs_dir2_data_freescan(mp, data, &needlog, NULL); + xfs_dir2_data_freescan(mp, data, &needlog); if (needlog) xfs_dir2_data_log_header(tp, dbp); /* * If the longest freespace in the data block has changed, * put the new value in the bests table and log that. */ - if (INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT) != oldbest) { - INT_COPY(bestsp[db], data->hdr.bestfree[0].length, ARCH_CONVERT); + if (be16_to_cpu(data->hdr.bestfree[0].length) != oldbest) { + bestsp[db] = data->hdr.bestfree[0].length; xfs_dir2_leaf_log_bests(tp, lbp, db, db); } xfs_dir2_data_check(dp, dbp); /* * If the data block is now empty then get rid of the data block. */ - if (INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT) == + if (be16_to_cpu(data->hdr.bestfree[0].length) == mp->m_dirblksize - (uint)sizeof(data->hdr)) { ASSERT(db != mp->m_dirdatablk); if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { @@ -1117,12 +1150,12 @@ xfs_dir2_leaf_removename( * If this is the last data block then compact the * bests table by getting rid of entries. */ - if (db == INT_GET(ltp->bestcount, ARCH_CONVERT) - 1) { + if (db == be32_to_cpu(ltp->bestcount) - 1) { /* * Look for the last active entry (i). */ for (i = db - 1; i > 0; i--) { - if (INT_GET(bestsp[i], ARCH_CONVERT) != NULLDATAOFF) + if (be16_to_cpu(bestsp[i]) != NULLDATAOFF) break; } /* @@ -1130,12 +1163,12 @@ xfs_dir2_leaf_removename( * end are removed. */ memmove(&bestsp[db - i], bestsp, - (INT_GET(ltp->bestcount, ARCH_CONVERT) - (db - i)) * sizeof(*bestsp)); - INT_MOD(ltp->bestcount, ARCH_CONVERT, -(db - i)); + (be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp)); + be32_add_cpu(<p->bestcount, -(db - i)); xfs_dir2_leaf_log_tail(tp, lbp); - xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1); + xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); } else - INT_SET(bestsp[db], ARCH_CONVERT, NULLDATAOFF); + bestsp[db] = cpu_to_be16(NULLDATAOFF); } /* * If the data block was not the first one, drop it. @@ -1186,12 +1219,12 @@ xfs_dir2_leaf_replace( */ dep = (xfs_dir2_data_entry_t *) ((char *)dbp->data + - XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, INT_GET(lep->address, ARCH_CONVERT))); - ASSERT(args->inumber != INT_GET(dep->inumber, ARCH_CONVERT)); + xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address))); + ASSERT(args->inumber != be64_to_cpu(dep->inumber)); /* * Put the new inode number in, log it. */ - INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); + dep->inumber = cpu_to_be64(args->inumber); tp = args->trans; xfs_dir2_data_log_entry(tp, dbp, dep); xfs_da_buf_done(dbp); @@ -1227,11 +1260,11 @@ xfs_dir2_leaf_search_hash( * 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 = leaf->ents, low = 0, high = INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1, + for (lep = leaf->ents, low = 0, high = be16_to_cpu(leaf->hdr.count) - 1, hashwant = args->hashval; low <= high; ) { mid = (low + high) >> 1; - if ((hash = INT_GET(lep[mid].hashval, ARCH_CONVERT)) == hashwant) + if ((hash = be32_to_cpu(lep[mid].hashval)) == hashwant) break; if (hash < hashwant) low = mid + 1; @@ -1242,7 +1275,7 @@ xfs_dir2_leaf_search_hash( * Found one, back up through all the equal hash values. */ if (hash == hashwant) { - while (mid > 0 && INT_GET(lep[mid - 1].hashval, ARCH_CONVERT) == hashwant) { + while (mid > 0 && be32_to_cpu(lep[mid - 1].hashval) == hashwant) { mid--; } } @@ -1264,7 +1297,7 @@ xfs_dir2_leaf_trim_data( xfs_dabuf_t *lbp, /* leaf buffer */ xfs_dir2_db_t db) /* data block number */ { - xfs_dir2_data_off_t *bestsp; /* leaf bests table */ + __be16 *bestsp; /* leaf bests table */ #ifdef DEBUG xfs_dir2_data_t *data; /* data block structure */ #endif @@ -1282,13 +1315,13 @@ xfs_dir2_leaf_trim_data( /* * Read the offending data block. We need its buffer. */ - if ((error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, db), -1, &dbp, + if ((error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp, XFS_DATA_FORK))) { return error; } #ifdef DEBUG data = dbp->data; - ASSERT(INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC); + ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC); #endif /* this seems to be an error * data is only valid if DEBUG is defined? @@ -1296,10 +1329,10 @@ xfs_dir2_leaf_trim_data( */ leaf = lbp->data; - ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); - ASSERT(INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT) == + ltp = xfs_dir2_leaf_tail_p(mp, leaf); + ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) == mp->m_dirblksize - (uint)sizeof(data->hdr)); - ASSERT(db == INT_GET(ltp->bestcount, ARCH_CONVERT) - 1); + ASSERT(db == be32_to_cpu(ltp->bestcount) - 1); /* * Get rid of the data block. */ @@ -1311,11 +1344,11 @@ xfs_dir2_leaf_trim_data( /* * Eliminate the last bests entry from the table. */ - bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); - INT_MOD(ltp->bestcount, ARCH_CONVERT, -1); - memmove(&bestsp[1], &bestsp[0], INT_GET(ltp->bestcount, ARCH_CONVERT) * sizeof(*bestsp)); + bestsp = xfs_dir2_leaf_bests_p(ltp); + be32_add_cpu(<p->bestcount, -1); + memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp)); xfs_dir2_leaf_log_tail(tp, lbp); - xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1); + xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); return 0; } @@ -1387,7 +1420,7 @@ xfs_dir2_node_to_leaf( return 0; lbp = state->path.blk[0].bp; leaf = lbp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); /* * Read the freespace block. */ @@ -1396,15 +1429,15 @@ xfs_dir2_node_to_leaf( return error; } free = fbp->data; - ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); + ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); ASSERT(!free->hdr.firstdb); /* * Now see if the leafn and free data will fit in a leaf1. * If not, release the buffer and give up. */ if ((uint)sizeof(leaf->hdr) + - (INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT)) * (uint)sizeof(leaf->ents[0]) + - INT_GET(free->hdr.nvalid, ARCH_CONVERT) * (uint)sizeof(leaf->bests[0]) + + (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)) * (uint)sizeof(leaf->ents[0]) + + be32_to_cpu(free->hdr.nvalid) * (uint)sizeof(leaf->bests[0]) + (uint)sizeof(leaf->tail) > mp->m_dirblksize) { xfs_da_brelse(tp, fbp); @@ -1414,22 +1447,22 @@ xfs_dir2_node_to_leaf( * If the leaf has any stale entries in it, compress them out. * The compact routine will log the header. */ - if (INT_GET(leaf->hdr.stale, ARCH_CONVERT)) + if (be16_to_cpu(leaf->hdr.stale)) xfs_dir2_leaf_compact(args, lbp); else xfs_dir2_leaf_log_header(tp, lbp); - INT_SET(leaf->hdr.info.magic, ARCH_CONVERT, XFS_DIR2_LEAF1_MAGIC); + leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAF1_MAGIC); /* * Set up the leaf tail from the freespace block. */ - ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); - INT_COPY(ltp->bestcount, free->hdr.nvalid, ARCH_CONVERT); + ltp = xfs_dir2_leaf_tail_p(mp, leaf); + ltp->bestcount = free->hdr.nvalid; /* * Set up the leaf bests table. */ - memcpy(XFS_DIR2_LEAF_BESTS_P(ltp), free->bests, - INT_GET(ltp->bestcount, ARCH_CONVERT) * sizeof(leaf->bests[0])); - xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1); + memcpy(xfs_dir2_leaf_bests_p(ltp), free->bests, + be32_to_cpu(ltp->bestcount) * sizeof(leaf->bests[0])); + xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); xfs_dir2_leaf_log_tail(tp, lbp); xfs_dir2_leaf_check(dp, lbp); /* diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c index fbbf7c619..db88adc7b 100644 --- a/libxfs/xfs_dir2_node.c +++ b/libxfs/xfs_dir2_node.c @@ -16,13 +16,29 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + /* - * xfs_dir2_node.c - * XFS directory implementation, version 2, node form files - * See data structures in xfs_dir2_node.h and xfs_da_btree.h. + * Function declarations. */ - -#include +static void xfs_dir2_free_log_header(xfs_trans_t *tp, xfs_dabuf_t *bp); +static int xfs_dir2_leafn_add(xfs_dabuf_t *bp, xfs_da_args_t *args, int index); +#ifdef DEBUG +static void xfs_dir2_leafn_check(xfs_inode_t *dp, xfs_dabuf_t *bp); +#else +#define xfs_dir2_leafn_check(dp, bp) +#endif +static void xfs_dir2_leafn_moveents(xfs_da_args_t *args, xfs_dabuf_t *bp_s, + int start_s, xfs_dabuf_t *bp_d, int start_d, + int count); +static void xfs_dir2_leafn_rebalance(xfs_da_state_t *state, + xfs_da_state_blk_t *blk1, + xfs_da_state_blk_t *blk2); +static int xfs_dir2_leafn_remove(xfs_da_args_t *args, xfs_dabuf_t *bp, + int index, xfs_da_state_blk_t *dblk, + int *rval); +static int xfs_dir2_node_addname_int(xfs_da_args_t *args, + xfs_da_state_blk_t *fblk); /* * Log entries from a freespace block. @@ -37,7 +53,7 @@ xfs_dir2_free_log_bests( xfs_dir2_free_t *free; /* freespace structure */ free = bp->data; - ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); + ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); xfs_da_log_buf(tp, bp, (uint)((char *)&free->bests[first] - (char *)free), (uint)((char *)&free->bests[last] - (char *)free + @@ -55,7 +71,7 @@ xfs_dir2_free_log_header( xfs_dir2_free_t *free; /* freespace structure */ free = bp->data; - ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); + ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); xfs_da_log_buf(tp, bp, (uint)((char *)&free->hdr - (char *)free), (uint)(sizeof(xfs_dir2_free_hdr_t) - 1)); } @@ -75,14 +91,14 @@ xfs_dir2_leaf_to_node( xfs_dabuf_t *fbp; /* freespace buffer */ xfs_dir2_db_t fdb; /* freespace block number */ xfs_dir2_free_t *free; /* freespace structure */ - xfs_dir2_data_off_t *from; /* pointer to freespace entry */ + __be16 *from; /* pointer to freespace entry */ int i; /* leaf freespace index */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ xfs_mount_t *mp; /* filesystem mount point */ int n; /* count of live freespc ents */ xfs_dir2_data_off_t off; /* freespace entry value */ - xfs_dir2_data_off_t *to; /* pointer to freespace entry */ + __be16 *to; /* pointer to freespace entry */ xfs_trans_t *tp; /* transaction pointer */ xfs_dir2_trace_args_b("leaf_to_node", args, lbp); @@ -99,39 +115,39 @@ xfs_dir2_leaf_to_node( /* * Get the buffer for the new freespace block. */ - if ((error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, fdb), -1, &fbp, + if ((error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, fdb), -1, &fbp, XFS_DATA_FORK))) { return error; } ASSERT(fbp != NULL); free = fbp->data; leaf = lbp->data; - ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); + ltp = xfs_dir2_leaf_tail_p(mp, leaf); /* * Initialize the freespace block header. */ - INT_SET(free->hdr.magic, ARCH_CONVERT, XFS_DIR2_FREE_MAGIC); + free->hdr.magic = cpu_to_be32(XFS_DIR2_FREE_MAGIC); free->hdr.firstdb = 0; - ASSERT(INT_GET(ltp->bestcount, ARCH_CONVERT) <= (uint)dp->i_d.di_size / mp->m_dirblksize); - INT_COPY(free->hdr.nvalid, ltp->bestcount, ARCH_CONVERT); + ASSERT(be32_to_cpu(ltp->bestcount) <= (uint)dp->i_d.di_size / mp->m_dirblksize); + free->hdr.nvalid = ltp->bestcount; /* * Copy freespace entries from the leaf block to the new block. * Count active entries. */ - for (i = n = 0, from = XFS_DIR2_LEAF_BESTS_P(ltp), to = free->bests; - i < INT_GET(ltp->bestcount, ARCH_CONVERT); i++, from++, to++) { - if ((off = INT_GET(*from, ARCH_CONVERT)) != NULLDATAOFF) + for (i = n = 0, from = xfs_dir2_leaf_bests_p(ltp), to = free->bests; + i < be32_to_cpu(ltp->bestcount); i++, from++, to++) { + if ((off = be16_to_cpu(*from)) != NULLDATAOFF) n++; - INT_SET(*to, ARCH_CONVERT, off); + *to = cpu_to_be16(off); } - INT_SET(free->hdr.nused, ARCH_CONVERT, n); - INT_SET(leaf->hdr.info.magic, ARCH_CONVERT, XFS_DIR2_LEAFN_MAGIC); + free->hdr.nused = cpu_to_be32(n); + leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAFN_MAGIC); /* * Log everything. */ xfs_dir2_leaf_log_header(tp, lbp); xfs_dir2_free_log_header(tp, fbp); - xfs_dir2_free_log_bests(tp, fbp, 0, INT_GET(free->hdr.nvalid, ARCH_CONVERT) - 1); + xfs_dir2_free_log_bests(tp, fbp, 0, be32_to_cpu(free->hdr.nvalid) - 1); xfs_da_buf_done(fbp); xfs_dir2_leafn_check(dp, lbp); return 0; @@ -178,17 +194,17 @@ xfs_dir2_leafn_add( * a compact. */ - if (INT_GET(leaf->hdr.count, ARCH_CONVERT) == XFS_DIR2_MAX_LEAF_ENTS(mp)) { + if (be16_to_cpu(leaf->hdr.count) == xfs_dir2_max_leaf_ents(mp)) { if (!leaf->hdr.stale) return XFS_ERROR(ENOSPC); - compact = INT_GET(leaf->hdr.stale, ARCH_CONVERT) > 1; + compact = be16_to_cpu(leaf->hdr.stale) > 1; } else compact = 0; - ASSERT(index == 0 || INT_GET(leaf->ents[index - 1].hashval, ARCH_CONVERT) <= args->hashval); - ASSERT(index == INT_GET(leaf->hdr.count, ARCH_CONVERT) || - INT_GET(leaf->ents[index].hashval, ARCH_CONVERT) >= args->hashval); + ASSERT(index == 0 || be32_to_cpu(leaf->ents[index - 1].hashval) <= args->hashval); + ASSERT(index == be16_to_cpu(leaf->hdr.count) || + be32_to_cpu(leaf->ents[index].hashval) >= args->hashval); - if (args->justcheck) + if (args->op_flags & XFS_DA_OP_JUSTCHECK) return 0; /* @@ -203,7 +219,7 @@ xfs_dir2_leafn_add( * Set impossible logging indices for this case. */ else if (leaf->hdr.stale) { - lfloglow = INT_GET(leaf->hdr.count, ARCH_CONVERT); + lfloglow = be16_to_cpu(leaf->hdr.count); lfloghigh = -1; } /* @@ -211,12 +227,12 @@ xfs_dir2_leafn_add( */ if (!leaf->hdr.stale) { lep = &leaf->ents[index]; - if (index < INT_GET(leaf->hdr.count, ARCH_CONVERT)) + if (index < be16_to_cpu(leaf->hdr.count)) memmove(lep + 1, lep, - (INT_GET(leaf->hdr.count, ARCH_CONVERT) - index) * sizeof(*lep)); + (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep)); lfloglow = index; - lfloghigh = INT_GET(leaf->hdr.count, ARCH_CONVERT); - INT_MOD(leaf->hdr.count, ARCH_CONVERT, +1); + lfloghigh = be16_to_cpu(leaf->hdr.count); + be16_add_cpu(&leaf->hdr.count, 1); } /* * There are stale entries. We'll use one for the new entry. @@ -232,7 +248,7 @@ xfs_dir2_leafn_add( */ for (lowstale = index - 1; lowstale >= 0 && - INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) != + be32_to_cpu(leaf->ents[lowstale].address) != XFS_DIR2_NULL_DATAPTR; lowstale--) continue; @@ -242,8 +258,8 @@ xfs_dir2_leafn_add( * lowstale already found. */ for (highstale = index; - highstale < INT_GET(leaf->hdr.count, ARCH_CONVERT) && - INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) != + highstale < be16_to_cpu(leaf->hdr.count) && + be32_to_cpu(leaf->ents[highstale].address) != XFS_DIR2_NULL_DATAPTR && (lowstale < 0 || index - lowstale - 1 >= highstale - index); @@ -255,9 +271,9 @@ xfs_dir2_leafn_add( * Shift entries up toward the stale slot. */ if (lowstale >= 0 && - (highstale == INT_GET(leaf->hdr.count, ARCH_CONVERT) || + (highstale == be16_to_cpu(leaf->hdr.count) || index - lowstale - 1 < highstale - index)) { - ASSERT(INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) == + ASSERT(be32_to_cpu(leaf->ents[lowstale].address) == XFS_DIR2_NULL_DATAPTR); ASSERT(index - lowstale - 1 >= 0); if (index - lowstale - 1 > 0) @@ -273,7 +289,7 @@ xfs_dir2_leafn_add( * Shift entries down toward the stale slot. */ else { - ASSERT(INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) == + ASSERT(be32_to_cpu(leaf->ents[highstale].address) == XFS_DIR2_NULL_DATAPTR); ASSERT(highstale - index >= 0); if (highstale - index > 0) @@ -284,13 +300,14 @@ xfs_dir2_leafn_add( lfloglow = MIN(index, lfloglow); lfloghigh = MAX(highstale, lfloghigh); } - INT_MOD(leaf->hdr.stale, ARCH_CONVERT, -1); + be16_add_cpu(&leaf->hdr.stale, -1); } /* * Insert the new entry, log everything. */ - INT_SET(lep->hashval, ARCH_CONVERT, args->hashval); - INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_DB_OFF_TO_DATAPTR(mp, args->blkno, args->index)); + lep->hashval = cpu_to_be32(args->hashval); + lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, + args->blkno, args->index)); xfs_dir2_leaf_log_header(tp, bp); xfs_dir2_leaf_log_ents(tp, bp, lfloglow, lfloghigh); xfs_dir2_leafn_check(dp, bp); @@ -313,17 +330,17 @@ xfs_dir2_leafn_check( leaf = bp->data; mp = dp->i_mount; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); - ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) <= XFS_DIR2_MAX_LEAF_ENTS(mp)); - for (i = stale = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); i++) { - if (i + 1 < INT_GET(leaf->hdr.count, ARCH_CONVERT)) { - ASSERT(INT_GET(leaf->ents[i].hashval, ARCH_CONVERT) <= - INT_GET(leaf->ents[i + 1].hashval, ARCH_CONVERT)); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.count) <= xfs_dir2_max_leaf_ents(mp)); + for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { + if (i + 1 < be16_to_cpu(leaf->hdr.count)) { + ASSERT(be32_to_cpu(leaf->ents[i].hashval) <= + be32_to_cpu(leaf->ents[i + 1].hashval)); } - if (INT_GET(leaf->ents[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) + if (be32_to_cpu(leaf->ents[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; } - ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) == stale); + ASSERT(be16_to_cpu(leaf->hdr.stale) == stale); } #endif /* DEBUG */ @@ -339,37 +356,35 @@ xfs_dir2_leafn_lasthash( xfs_dir2_leaf_t *leaf; /* leaf structure */ leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); if (count) - *count = INT_GET(leaf->hdr.count, ARCH_CONVERT); + *count = be16_to_cpu(leaf->hdr.count); if (!leaf->hdr.count) return 0; - return INT_GET(leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT); + return be32_to_cpu(leaf->ents[be16_to_cpu(leaf->hdr.count) - 1].hashval); } /* - * Look up a leaf entry in a node-format leaf block. - * If this is an addname then the extrablk in state is a freespace block, - * otherwise it's a data block. + * Look up a leaf entry for space to add a name in a node-format leaf block. + * The extrablk in state is a freespace block. */ -int -xfs_dir2_leafn_lookup_int( +STATIC int +xfs_dir2_leafn_lookup_for_addname( xfs_dabuf_t *bp, /* leaf buffer */ xfs_da_args_t *args, /* operation arguments */ int *indexp, /* out: leaf entry index */ xfs_da_state_t *state) /* state to fill in */ { - xfs_dabuf_t *curbp; /* current data/free buffer */ - xfs_dir2_db_t curdb; /* current data block number */ - xfs_dir2_db_t curfdb; /* current free block number */ - xfs_dir2_data_entry_t *dep; /* data block entry */ + xfs_dabuf_t *curbp = NULL; /* current data/free buffer */ + xfs_dir2_db_t curdb = -1; /* current data block number */ + xfs_dir2_db_t curfdb = -1; /* current free block number */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return value */ int fi; /* free entry index */ - xfs_dir2_free_t *free=NULL; /* free block structure */ + xfs_dir2_free_t *free = NULL; /* free block structure */ int index; /* leaf entry index */ xfs_dir2_leaf_t *leaf; /* leaf structure */ - int length=0; /* length of new data entry */ + int length; /* length of new data entry */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_mount_t *mp; /* filesystem mount point */ xfs_dir2_db_t newdb; /* new data block number */ @@ -380,9 +395,9 @@ xfs_dir2_leafn_lookup_int( tp = args->trans; mp = dp->i_mount; leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); #ifdef __KERNEL__ - ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) > 0); + ASSERT(be16_to_cpu(leaf->hdr.count) > 0); #endif xfs_dir2_leafn_check(dp, bp); /* @@ -392,198 +407,270 @@ xfs_dir2_leafn_lookup_int( /* * Do we have a buffer coming in? */ - if (state->extravalid) + if (state->extravalid) { + /* If so, it's a free block buffer, get the block number. */ curbp = state->extrablk.bp; - else - curbp = NULL; - /* - * For addname, it's a free block buffer, get the block number. - */ - if (args->addname) { - curfdb = curbp ? state->extrablk.blkno : -1; - curdb = -1; - length = XFS_DIR2_DATA_ENTSIZE(args->namelen); - if ((free = (curbp ? curbp->data : NULL))) - ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); - } - /* - * For others, it's a data block buffer, get the block number. - */ - else { - curfdb = -1; - curdb = curbp ? state->extrablk.blkno : -1; + curfdb = state->extrablk.blkno; + free = curbp->data; + ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); } + length = xfs_dir2_data_entsize(args->namelen); /* * Loop over leaf entries with the right hash value. */ - for (lep = &leaf->ents[index]; - index < INT_GET(leaf->hdr.count, ARCH_CONVERT) && INT_GET(lep->hashval, ARCH_CONVERT) == args->hashval; - lep++, index++) { + for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) && + be32_to_cpu(lep->hashval) == args->hashval; + lep++, index++) { /* * Skip stale leaf entries. */ - if (INT_GET(lep->address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) + if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) continue; /* * Pull the data block number from the entry. */ - newdb = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT)); + newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); /* * For addname, we're looking for a place to put the new entry. * We want to use a data block with an entry of equal * hash value to ours if there is one with room. + * + * If this block isn't the data block we already have + * in hand, take a look at it. */ - if (args->addname) { + if (newdb != curdb) { + curdb = newdb; /* - * If this block isn't the data block we already have - * in hand, take a look at it. + * Convert the data block to the free block + * holding its freespace information. */ - if (newdb != curdb) { - curdb = newdb; - /* - * Convert the data block to the free block - * holding its freespace information. - */ - newfdb = XFS_DIR2_DB_TO_FDB(mp, newdb); - /* - * If it's not the one we have in hand, - * read it in. - */ - if (newfdb != curfdb) { - /* - * If we had one before, drop it. - */ - if (curbp) - xfs_da_brelse(tp, curbp); - /* - * Read the free block. - */ - if ((error = xfs_da_read_buf(tp, dp, - XFS_DIR2_DB_TO_DA(mp, - newfdb), - -1, &curbp, - XFS_DATA_FORK))) { - return error; - } - curfdb = newfdb; - free = curbp->data; - ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == - XFS_DIR2_FREE_MAGIC); - ASSERT((INT_GET(free->hdr.firstdb, ARCH_CONVERT) % - XFS_DIR2_MAX_FREE_BESTS(mp)) == - 0); - ASSERT(INT_GET(free->hdr.firstdb, ARCH_CONVERT) <= curdb); - ASSERT(curdb < - INT_GET(free->hdr.firstdb, ARCH_CONVERT) + - INT_GET(free->hdr.nvalid, ARCH_CONVERT)); - } - /* - * Get the index for our entry. - */ - fi = XFS_DIR2_DB_TO_FDINDEX(mp, curdb); - /* - * If it has room, return it. - */ - if (unlikely(INT_GET(free->bests[fi], ARCH_CONVERT) == NULLDATAOFF)) { - XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", - XFS_ERRLEVEL_LOW, mp); - return XFS_ERROR(EFSCORRUPTED); - } - if (INT_GET(free->bests[fi], ARCH_CONVERT) >= length) { - *indexp = index; - state->extravalid = 1; - state->extrablk.bp = curbp; - state->extrablk.blkno = curfdb; - state->extrablk.index = fi; - state->extrablk.magic = - XFS_DIR2_FREE_MAGIC; - ASSERT(args->oknoent); - return XFS_ERROR(ENOENT); - } - } - } - /* - * Not adding a new entry, so we really want to find - * the name given to us. - */ - else { + newfdb = xfs_dir2_db_to_fdb(mp, newdb); /* - * If it's a different data block, go get it. + * If it's not the one we have in hand, read it in. */ - if (newdb != curdb) { + if (newfdb != curfdb) { /* - * If we had a block before, drop it. + * If we had one before, drop it. */ if (curbp) xfs_da_brelse(tp, curbp); /* - * Read the data block. + * Read the free block. */ - if ((error = - xfs_da_read_buf(tp, dp, - XFS_DIR2_DB_TO_DA(mp, newdb), -1, - &curbp, XFS_DATA_FORK))) { + error = xfs_da_read_buf(tp, dp, + xfs_dir2_db_to_da(mp, newfdb), + -1, &curbp, XFS_DATA_FORK); + if (error) return error; - } - xfs_dir2_data_check(dp, curbp); - curdb = newdb; + free = curbp->data; + ASSERT(be32_to_cpu(free->hdr.magic) == + XFS_DIR2_FREE_MAGIC); + ASSERT((be32_to_cpu(free->hdr.firstdb) % + XFS_DIR2_MAX_FREE_BESTS(mp)) == 0); + ASSERT(be32_to_cpu(free->hdr.firstdb) <= curdb); + ASSERT(curdb < be32_to_cpu(free->hdr.firstdb) + + be32_to_cpu(free->hdr.nvalid)); } /* - * Point to the data entry. + * Get the index for our entry. */ - dep = (xfs_dir2_data_entry_t *) - ((char *)curbp->data + - XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT))); + fi = xfs_dir2_db_to_fdindex(mp, curdb); /* - * Compare the entry, return it if it matches. + * If it has room, return it. */ - if (dep->namelen == args->namelen && - dep->name[0] == args->name[0] && - memcmp(dep->name, args->name, args->namelen) == 0) { - args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); - *indexp = index; - state->extravalid = 1; - state->extrablk.bp = curbp; - state->extrablk.blkno = curdb; - state->extrablk.index = - (int)((char *)dep - - (char *)curbp->data); - state->extrablk.magic = XFS_DIR2_DATA_MAGIC; - return XFS_ERROR(EEXIST); + if (unlikely(be16_to_cpu(free->bests[fi]) == NULLDATAOFF)) { + XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", + XFS_ERRLEVEL_LOW, mp); + if (curfdb != newfdb) + xfs_da_brelse(tp, curbp); + return XFS_ERROR(EFSCORRUPTED); } + curfdb = newfdb; + if (be16_to_cpu(free->bests[fi]) >= length) + goto out; } } + /* Didn't find any space */ + fi = -1; +out: + ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); + if (curbp) { + /* Giving back a free block. */ + state->extravalid = 1; + state->extrablk.bp = curbp; + state->extrablk.index = fi; + state->extrablk.blkno = curfdb; + state->extrablk.magic = XFS_DIR2_FREE_MAGIC; + } else { + state->extravalid = 0; + } /* - * Didn't find a match. - * If we are holding a buffer, give it back in case our caller - * finds it useful. + * Return the index, that will be the insertion point. */ - if ((state->extravalid = (curbp != NULL))) { - state->extrablk.bp = curbp; - state->extrablk.index = -1; + *indexp = index; + return XFS_ERROR(ENOENT); +} + +/* + * Look up a leaf entry in a node-format leaf block. + * The extrablk in state a data block. + */ +STATIC int +xfs_dir2_leafn_lookup_for_entry( + xfs_dabuf_t *bp, /* leaf buffer */ + xfs_da_args_t *args, /* operation arguments */ + int *indexp, /* out: leaf entry index */ + xfs_da_state_t *state) /* state to fill in */ +{ + xfs_dabuf_t *curbp = NULL; /* current data/free buffer */ + xfs_dir2_db_t curdb = -1; /* current data block number */ + xfs_dir2_data_entry_t *dep; /* data block entry */ + xfs_inode_t *dp; /* incore directory inode */ + int error; /* error return value */ + int index; /* leaf entry index */ + xfs_dir2_leaf_t *leaf; /* leaf structure */ + xfs_dir2_leaf_entry_t *lep; /* leaf entry */ + xfs_mount_t *mp; /* filesystem mount point */ + xfs_dir2_db_t newdb; /* new data block number */ + xfs_trans_t *tp; /* transaction pointer */ + enum xfs_dacmp cmp; /* comparison result */ + + dp = args->dp; + tp = args->trans; + mp = dp->i_mount; + leaf = bp->data; + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); +#ifdef __KERNEL__ + ASSERT(be16_to_cpu(leaf->hdr.count) > 0); +#endif + xfs_dir2_leafn_check(dp, bp); + /* + * Look up the hash value in the leaf entries. + */ + index = xfs_dir2_leaf_search_hash(args, bp); + /* + * Do we have a buffer coming in? + */ + if (state->extravalid) { + curbp = state->extrablk.bp; + curdb = state->extrablk.blkno; + } + /* + * Loop over leaf entries with the right hash value. + */ + for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) && + be32_to_cpu(lep->hashval) == args->hashval; + lep++, index++) { /* - * For addname, giving back a free block. + * Skip stale leaf entries. */ - if (args->addname) { - state->extrablk.blkno = curfdb; - state->extrablk.magic = XFS_DIR2_FREE_MAGIC; + if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) + continue; + /* + * Pull the data block number from the entry. + */ + newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); + /* + * Not adding a new entry, so we really want to find + * the name given to us. + * + * If it's a different data block, go get it. + */ + if (newdb != curdb) { + /* + * If we had a block before that we aren't saving + * for a CI name, drop it + */ + if (curbp && (args->cmpresult == XFS_CMP_DIFFERENT || + curdb != state->extrablk.blkno)) + xfs_da_brelse(tp, curbp); + /* + * If needing the block that is saved with a CI match, + * use it otherwise read in the new data block. + */ + if (args->cmpresult != XFS_CMP_DIFFERENT && + newdb == state->extrablk.blkno) { + ASSERT(state->extravalid); + curbp = state->extrablk.bp; + } else { + error = xfs_da_read_buf(tp, dp, + xfs_dir2_db_to_da(mp, newdb), + -1, &curbp, XFS_DATA_FORK); + if (error) + return error; + } + xfs_dir2_data_check(dp, curbp); + curdb = newdb; } /* - * For other callers, giving back a data block. + * Point to the data entry. */ - else { + dep = (xfs_dir2_data_entry_t *)((char *)curbp->data + + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); + /* + * Compare the entry and if it's an exact match, return + * 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); + if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { + /* If there is a CI match block, drop it */ + if (args->cmpresult != XFS_CMP_DIFFERENT && + curdb != state->extrablk.blkno) + xfs_da_brelse(tp, state->extrablk.bp); + args->cmpresult = cmp; + args->inumber = be64_to_cpu(dep->inumber); + *indexp = index; + state->extravalid = 1; + state->extrablk.bp = curbp; state->extrablk.blkno = curdb; + state->extrablk.index = (int)((char *)dep - + (char *)curbp->data); state->extrablk.magic = XFS_DIR2_DATA_MAGIC; + if (cmp == XFS_CMP_EXACT) + return XFS_ERROR(EEXIST); } } - /* - * Return the final index, that will be the insertion point. - */ + ASSERT(index == be16_to_cpu(leaf->hdr.count) || + (args->op_flags & XFS_DA_OP_OKNOENT)); + if (curbp) { + if (args->cmpresult == XFS_CMP_DIFFERENT) { + /* Giving back last used data block. */ + state->extravalid = 1; + state->extrablk.bp = curbp; + state->extrablk.index = -1; + state->extrablk.blkno = curdb; + state->extrablk.magic = XFS_DIR2_DATA_MAGIC; + } else { + /* If the curbp is not the CI match block, drop it */ + if (state->extrablk.bp != curbp) + xfs_da_brelse(tp, curbp); + } + } else { + state->extravalid = 0; + } *indexp = index; - ASSERT(index == INT_GET(leaf->hdr.count, ARCH_CONVERT) || args->oknoent); return XFS_ERROR(ENOENT); } +/* + * Look up a leaf entry in a node-format leaf block. + * If this is an addname then the extrablk in state is a freespace block, + * otherwise it's a data block. + */ +int +xfs_dir2_leafn_lookup_int( + xfs_dabuf_t *bp, /* leaf buffer */ + xfs_da_args_t *args, /* operation arguments */ + int *indexp, /* out: leaf entry index */ + xfs_da_state_t *state) /* state to fill in */ +{ + if (args->op_flags & XFS_DA_OP_ADDNAME) + return xfs_dir2_leafn_lookup_for_addname(bp, args, indexp, + state); + return xfs_dir2_leafn_lookup_for_entry(bp, args, indexp, state); +} + /* * Move count leaf entries from source to destination leaf. * Log entries and headers. Stale entries are preserved. @@ -618,12 +705,12 @@ xfs_dir2_leafn_moveents( * destination leaf entries, open up a hole in the destination * to hold the new entries. */ - if (start_d < INT_GET(leaf_d->hdr.count, ARCH_CONVERT)) { + if (start_d < be16_to_cpu(leaf_d->hdr.count)) { memmove(&leaf_d->ents[start_d + count], &leaf_d->ents[start_d], - (INT_GET(leaf_d->hdr.count, ARCH_CONVERT) - start_d) * + (be16_to_cpu(leaf_d->hdr.count) - start_d) * sizeof(xfs_dir2_leaf_entry_t)); xfs_dir2_leaf_log_ents(tp, bp_d, start_d + count, - count + INT_GET(leaf_d->hdr.count, ARCH_CONVERT) - 1); + count + be16_to_cpu(leaf_d->hdr.count) - 1); } /* * If the source has stale leaves, count the ones in the copy range @@ -633,7 +720,7 @@ xfs_dir2_leafn_moveents( int i; /* temp leaf index */ for (i = start_s, stale = 0; i < start_s + count; i++) { - if (INT_GET(leaf_s->ents[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) + if (be32_to_cpu(leaf_s->ents[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; } } else @@ -648,7 +735,7 @@ xfs_dir2_leafn_moveents( * If there are source entries after the ones we copied, * delete the ones we copied by sliding the next ones down. */ - if (start_s + count < INT_GET(leaf_s->hdr.count, ARCH_CONVERT)) { + if (start_s + count < be16_to_cpu(leaf_s->hdr.count)) { memmove(&leaf_s->ents[start_s], &leaf_s->ents[start_s + count], count * sizeof(xfs_dir2_leaf_entry_t)); xfs_dir2_leaf_log_ents(tp, bp_s, start_s, start_s + count - 1); @@ -656,10 +743,10 @@ xfs_dir2_leafn_moveents( /* * Update the headers and log them. */ - INT_MOD(leaf_s->hdr.count, ARCH_CONVERT, -(count)); - INT_MOD(leaf_s->hdr.stale, ARCH_CONVERT, -(stale)); - INT_MOD(leaf_d->hdr.count, ARCH_CONVERT, count); - INT_MOD(leaf_d->hdr.stale, ARCH_CONVERT, stale); + be16_add_cpu(&leaf_s->hdr.count, -(count)); + be16_add_cpu(&leaf_s->hdr.stale, -(stale)); + be16_add_cpu(&leaf_d->hdr.count, count); + be16_add_cpu(&leaf_d->hdr.stale, stale); xfs_dir2_leaf_log_header(tp, bp_s); xfs_dir2_leaf_log_header(tp, bp_d); xfs_dir2_leafn_check(args->dp, bp_s); @@ -680,13 +767,13 @@ xfs_dir2_leafn_order( leaf1 = leaf1_bp->data; leaf2 = leaf2_bp->data; - ASSERT(INT_GET(leaf1->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); - ASSERT(INT_GET(leaf2->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); - if (INT_GET(leaf1->hdr.count, ARCH_CONVERT) > 0 && - INT_GET(leaf2->hdr.count, ARCH_CONVERT) > 0 && - (INT_GET(leaf2->ents[0].hashval, ARCH_CONVERT) < INT_GET(leaf1->ents[0].hashval, ARCH_CONVERT) || - INT_GET(leaf2->ents[INT_GET(leaf2->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT) < - INT_GET(leaf1->ents[INT_GET(leaf1->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT))) + ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); + ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); + if (be16_to_cpu(leaf1->hdr.count) > 0 && + be16_to_cpu(leaf2->hdr.count) > 0 && + (be32_to_cpu(leaf2->ents[0].hashval) < be32_to_cpu(leaf1->ents[0].hashval) || + be32_to_cpu(leaf2->ents[be16_to_cpu(leaf2->hdr.count) - 1].hashval) < + be32_to_cpu(leaf1->ents[be16_to_cpu(leaf1->hdr.count) - 1].hashval))) return 1; return 0; } @@ -729,9 +816,9 @@ xfs_dir2_leafn_rebalance( } leaf1 = blk1->bp->data; leaf2 = blk2->bp->data; - oldsum = INT_GET(leaf1->hdr.count, ARCH_CONVERT) + INT_GET(leaf2->hdr.count, ARCH_CONVERT); + oldsum = be16_to_cpu(leaf1->hdr.count) + be16_to_cpu(leaf2->hdr.count); #ifdef DEBUG - oldstale = INT_GET(leaf1->hdr.stale, ARCH_CONVERT) + INT_GET(leaf2->hdr.stale, ARCH_CONVERT); + oldstale = be16_to_cpu(leaf1->hdr.stale) + be16_to_cpu(leaf2->hdr.stale); #endif mid = oldsum >> 1; /* @@ -741,10 +828,10 @@ xfs_dir2_leafn_rebalance( if (oldsum & 1) { xfs_dahash_t midhash; /* middle entry hash value */ - if (mid >= INT_GET(leaf1->hdr.count, ARCH_CONVERT)) - midhash = INT_GET(leaf2->ents[mid - INT_GET(leaf1->hdr.count, ARCH_CONVERT)].hashval, ARCH_CONVERT); + if (mid >= be16_to_cpu(leaf1->hdr.count)) + midhash = be32_to_cpu(leaf2->ents[mid - be16_to_cpu(leaf1->hdr.count)].hashval); else - midhash = INT_GET(leaf1->ents[mid].hashval, ARCH_CONVERT); + midhash = be32_to_cpu(leaf1->ents[mid].hashval); isleft = args->hashval <= midhash; } /* @@ -758,39 +845,40 @@ xfs_dir2_leafn_rebalance( * Calculate moved entry count. Positive means left-to-right, * negative means right-to-left. Then move the entries. */ - count = INT_GET(leaf1->hdr.count, ARCH_CONVERT) - mid + (isleft == 0); + count = be16_to_cpu(leaf1->hdr.count) - mid + (isleft == 0); if (count > 0) xfs_dir2_leafn_moveents(args, blk1->bp, - INT_GET(leaf1->hdr.count, ARCH_CONVERT) - count, blk2->bp, 0, count); + be16_to_cpu(leaf1->hdr.count) - count, blk2->bp, 0, count); else if (count < 0) xfs_dir2_leafn_moveents(args, blk2->bp, 0, blk1->bp, - INT_GET(leaf1->hdr.count, ARCH_CONVERT), count); - ASSERT(INT_GET(leaf1->hdr.count, ARCH_CONVERT) + INT_GET(leaf2->hdr.count, ARCH_CONVERT) == oldsum); - ASSERT(INT_GET(leaf1->hdr.stale, ARCH_CONVERT) + INT_GET(leaf2->hdr.stale, ARCH_CONVERT) == oldstale); + be16_to_cpu(leaf1->hdr.count), count); + ASSERT(be16_to_cpu(leaf1->hdr.count) + be16_to_cpu(leaf2->hdr.count) == oldsum); + ASSERT(be16_to_cpu(leaf1->hdr.stale) + be16_to_cpu(leaf2->hdr.stale) == oldstale); /* * Mark whether we're inserting into the old or new leaf. */ - if (INT_GET(leaf1->hdr.count, ARCH_CONVERT) < INT_GET(leaf2->hdr.count, ARCH_CONVERT)) + if (be16_to_cpu(leaf1->hdr.count) < be16_to_cpu(leaf2->hdr.count)) state->inleaf = swap; - else if (INT_GET(leaf1->hdr.count, ARCH_CONVERT) > INT_GET(leaf2->hdr.count, ARCH_CONVERT)) + else if (be16_to_cpu(leaf1->hdr.count) > be16_to_cpu(leaf2->hdr.count)) state->inleaf = !swap; else state->inleaf = - swap ^ (blk1->index <= INT_GET(leaf1->hdr.count, ARCH_CONVERT)); + swap ^ (blk1->index <= be16_to_cpu(leaf1->hdr.count)); /* * Adjust the expected index for insertion. */ if (!state->inleaf) - blk2->index = blk1->index - INT_GET(leaf1->hdr.count, ARCH_CONVERT); - - /* - * Finally sanity check just to make sure we are not returning a negative index + blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count); + + /* + * Finally sanity check just to make sure we are not returning a + * negative index */ if(blk2->index < 0) { state->inleaf = 1; blk2->index = 0; cmn_err(CE_ALERT, - "xfs_dir2_leafn_rebalance: picked the wrong leaf? reverting orignal leaf: " + "xfs_dir2_leafn_rebalance: picked the wrong leaf? reverting original leaf: " "blk1->index %d\n", blk1->index); } @@ -801,7 +889,7 @@ xfs_dir2_leafn_rebalance( * This removes the leaf entry and the data entry, * and updates the free block if necessary. */ -STATIC int /* error */ +static int /* error */ xfs_dir2_leafn_remove( xfs_da_args_t *args, /* operation arguments */ xfs_dabuf_t *bp, /* leaf buffer */ @@ -828,7 +916,7 @@ xfs_dir2_leafn_remove( tp = args->trans; mp = dp->i_mount; leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); /* * Point to the entry we're removing. */ @@ -836,17 +924,17 @@ xfs_dir2_leafn_remove( /* * Extract the data block and offset from the entry. */ - db = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT)); + db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); ASSERT(dblk->blkno == db); - off = XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT)); + off = xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)); ASSERT(dblk->index == off); /* * Kill the leaf entry by marking it stale. * Log the leaf block changes. */ - INT_MOD(leaf->hdr.stale, ARCH_CONVERT, +1); + be16_add_cpu(&leaf->hdr.stale, 1); xfs_dir2_leaf_log_header(tp, bp); - INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_NULL_DATAPTR); + lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); xfs_dir2_leaf_log_ents(tp, bp, index, index); /* * Make the data entry free. Keep track of the longest freespace @@ -855,16 +943,16 @@ xfs_dir2_leafn_remove( dbp = dblk->bp; data = dbp->data; dep = (xfs_dir2_data_entry_t *)((char *)data + off); - longest = INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT); + longest = be16_to_cpu(data->hdr.bestfree[0].length); needlog = needscan = 0; xfs_dir2_data_make_free(tp, dbp, off, - XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan); + xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); /* * Rescan the data block freespaces for bestfree. * Log the data block header if needed. */ if (needscan) - xfs_dir2_data_freescan(mp, data, &needlog, NULL); + xfs_dir2_data_freescan(mp, data, &needlog); if (needlog) xfs_dir2_data_log_header(tp, dbp); xfs_dir2_data_check(dp, dbp); @@ -872,7 +960,7 @@ xfs_dir2_leafn_remove( * If the longest data block freespace changes, need to update * the corresponding freeblock entry. */ - if (longest < INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT)) { + if (longest < be16_to_cpu(data->hdr.bestfree[0].length)) { int error; /* error return value */ xfs_dabuf_t *fbp; /* freeblock buffer */ xfs_dir2_db_t fdb; /* freeblock block number */ @@ -884,21 +972,21 @@ xfs_dir2_leafn_remove( * Convert the data block number to a free block, * read in the free block. */ - fdb = XFS_DIR2_DB_TO_FDB(mp, db); - if ((error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, fdb), + fdb = xfs_dir2_db_to_fdb(mp, db); + if ((error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, fdb), -1, &fbp, XFS_DATA_FORK))) { return error; } free = fbp->data; - ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); - ASSERT(INT_GET(free->hdr.firstdb, ARCH_CONVERT) == + ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); + ASSERT(be32_to_cpu(free->hdr.firstdb) == XFS_DIR2_MAX_FREE_BESTS(mp) * (fdb - XFS_DIR2_FREE_FIRSTDB(mp))); /* * Calculate which entry we need to fix. */ - findex = XFS_DIR2_DB_TO_FDINDEX(mp, db); - longest = INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT); + findex = xfs_dir2_db_to_fdindex(mp, db); + longest = be16_to_cpu(data->hdr.bestfree[0].length); /* * If the data block is now empty we can get rid of it * (usually). @@ -930,7 +1018,7 @@ xfs_dir2_leafn_remove( /* * One less used entry in the free table. */ - INT_MOD(free->hdr.nused, ARCH_CONVERT, -1); + be32_add_cpu(&free->hdr.nused, -1); xfs_dir2_free_log_header(tp, fbp); /* * If this was the last entry in the table, we can @@ -938,21 +1026,21 @@ xfs_dir2_leafn_remove( * entries at the end referring to non-existent * data blocks, get those too. */ - if (findex == INT_GET(free->hdr.nvalid, ARCH_CONVERT) - 1) { + if (findex == be32_to_cpu(free->hdr.nvalid) - 1) { int i; /* free entry index */ for (i = findex - 1; - i >= 0 && INT_GET(free->bests[i], ARCH_CONVERT) == NULLDATAOFF; + i >= 0 && be16_to_cpu(free->bests[i]) == NULLDATAOFF; i--) continue; - INT_SET(free->hdr.nvalid, ARCH_CONVERT, i + 1); + free->hdr.nvalid = cpu_to_be32(i + 1); logfree = 0; } /* * Not the last entry, just punch it out. */ else { - INT_SET(free->bests[findex], ARCH_CONVERT, NULLDATAOFF); + free->bests[findex] = cpu_to_be16(NULLDATAOFF); logfree = 1; } /* @@ -978,7 +1066,7 @@ xfs_dir2_leafn_remove( * the new value. */ else { - INT_SET(free->bests[findex], ARCH_CONVERT, longest); + free->bests[findex] = cpu_to_be16(longest); logfree = 1; } /* @@ -1000,7 +1088,7 @@ xfs_dir2_leafn_remove( *rval = ((uint)sizeof(leaf->hdr) + (uint)sizeof(leaf->ents[0]) * - (INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT))) < + (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale))) < mp->m_dir_magicpct; return 0; } @@ -1033,7 +1121,7 @@ xfs_dir2_leafn_split( /* * Initialize the new leaf block. */ - error = xfs_dir2_leaf_init(args, XFS_DIR2_DA_TO_DB(mp, blkno), + error = xfs_dir2_leaf_init(args, xfs_dir2_da_to_db(mp, blkno), &newblk->bp, XFS_DIR2_LEAFN_MAGIC); if (error) { return error; @@ -1099,9 +1187,9 @@ xfs_dir2_leafn_toosmall( */ blk = &state->path.blk[state->path.active - 1]; info = blk->bp->data; - ASSERT(INT_GET(info->magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); + ASSERT(be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC); leaf = (xfs_dir2_leaf_t *)info; - count = INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT); + count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); bytes = (uint)sizeof(leaf->hdr) + count * (uint)sizeof(leaf->ents[0]); if (bytes > (state->blocksize >> 1)) { /* @@ -1121,7 +1209,7 @@ xfs_dir2_leafn_toosmall( * Make altpath point to the block we want to keep and * path point to the block we want to drop (this one). */ - forward = info->forw; + forward = (info->forw != 0); memcpy(&state->altpath, &state->path, sizeof(state->path)); error = xfs_da_path_shift(state, &state->altpath, forward, 0, &rval); @@ -1137,9 +1225,9 @@ xfs_dir2_leafn_toosmall( * We prefer coalescing with the lower numbered sibling so as * to shrink a directory over time. */ - forward = INT_GET(info->forw, ARCH_CONVERT) < INT_GET(info->back, ARCH_CONVERT); + forward = be32_to_cpu(info->forw) < be32_to_cpu(info->back); for (i = 0, bp = NULL; i < 2; forward = !forward, i++) { - blkno = forward ?INT_GET( info->forw, ARCH_CONVERT) : INT_GET(info->back, ARCH_CONVERT); + blkno = forward ? be32_to_cpu(info->forw) : be32_to_cpu(info->back); if (blkno == 0) continue; /* @@ -1155,11 +1243,11 @@ xfs_dir2_leafn_toosmall( * Count bytes in the two blocks combined. */ leaf = (xfs_dir2_leaf_t *)info; - count = INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT); + count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); bytes = state->blocksize - (state->blocksize >> 2); leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); - count += INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT); + ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); + count += be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); bytes -= count * (uint)sizeof(leaf->ents[0]); /* * Fits with at least 25% to spare. @@ -1217,27 +1305,27 @@ xfs_dir2_leafn_unbalance( ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC); drop_leaf = drop_blk->bp->data; save_leaf = save_blk->bp->data; - ASSERT(INT_GET(drop_leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); - ASSERT(INT_GET(save_leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); + ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); + ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); /* * If there are any stale leaf entries, take this opportunity * to purge them. */ - if (INT_GET(drop_leaf->hdr.stale, ARCH_CONVERT)) + if (drop_leaf->hdr.stale) xfs_dir2_leaf_compact(args, drop_blk->bp); - if (INT_GET(save_leaf->hdr.stale, ARCH_CONVERT)) + if (save_leaf->hdr.stale) xfs_dir2_leaf_compact(args, save_blk->bp); /* * Move the entries from drop to the appropriate end of save. */ - drop_blk->hashval = INT_GET(drop_leaf->ents[INT_GET(drop_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT); + drop_blk->hashval = be32_to_cpu(drop_leaf->ents[be16_to_cpu(drop_leaf->hdr.count) - 1].hashval); if (xfs_dir2_leafn_order(save_blk->bp, drop_blk->bp)) xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp, 0, - INT_GET(drop_leaf->hdr.count, ARCH_CONVERT)); + be16_to_cpu(drop_leaf->hdr.count)); else xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp, - INT_GET(save_leaf->hdr.count, ARCH_CONVERT), INT_GET(drop_leaf->hdr.count, ARCH_CONVERT)); - save_blk->hashval = INT_GET(save_leaf->ents[INT_GET(save_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT); + be16_to_cpu(save_leaf->hdr.count), be16_to_cpu(drop_leaf->hdr.count)); + save_blk->hashval = be32_to_cpu(save_leaf->ents[be16_to_cpu(save_leaf->hdr.count) - 1].hashval); xfs_dir2_leafn_check(args->dp, save_blk->bp); } @@ -1291,7 +1379,7 @@ xfs_dir2_node_addname( /* * It worked, fix the hash values up the btree. */ - if (!args->justcheck) + if (!(args->op_flags & XFS_DA_OP_JUSTCHECK)) xfs_da_fixhashpath(state, &state->path); } else { /* @@ -1316,7 +1404,7 @@ done: * The leaf entry is added in xfs_dir2_leafn_add. * We may enter with a freespace block that the lookup found. */ -STATIC int /* error */ +static int /* error */ xfs_dir2_node_addname_int( xfs_da_args_t *args, /* operation arguments */ xfs_da_state_blk_t *fblk) /* optional freespace block */ @@ -1339,13 +1427,13 @@ xfs_dir2_node_addname_int( xfs_mount_t *mp; /* filesystem mount point */ int needlog; /* need to log data header */ int needscan; /* need to rescan data frees */ - xfs_dir2_data_off_t *tagp; /* data entry tag pointer */ + __be16 *tagp; /* data entry tag pointer */ xfs_trans_t *tp; /* transaction pointer */ dp = args->dp; mp = dp->i_mount; tp = args->trans; - length = XFS_DIR2_DATA_ENTSIZE(args->namelen); + length = xfs_dir2_data_entsize(args->namelen); /* * If we came in with a freespace block that means that lookup * found an entry with our hash value. This is the freespace @@ -1358,7 +1446,7 @@ xfs_dir2_node_addname_int( */ ifbno = fblk->blkno; free = fbp->data; - ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); + ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); findex = fblk->index; /* * This means the free entry showed that the data block had @@ -1366,10 +1454,10 @@ xfs_dir2_node_addname_int( * Use that data block. */ if (findex >= 0) { - ASSERT(findex < INT_GET(free->hdr.nvalid, ARCH_CONVERT)); - ASSERT(INT_GET(free->bests[findex], ARCH_CONVERT) != NULLDATAOFF); - ASSERT(INT_GET(free->bests[findex], ARCH_CONVERT) >= length); - dbno = INT_GET(free->hdr.firstdb, ARCH_CONVERT) + findex; + ASSERT(findex < be32_to_cpu(free->hdr.nvalid)); + ASSERT(be16_to_cpu(free->bests[findex]) != NULLDATAOFF); + ASSERT(be16_to_cpu(free->bests[findex]) >= length); + dbno = be32_to_cpu(free->hdr.firstdb) + findex; } /* * The data block looked at didn't have enough room. @@ -1398,7 +1486,7 @@ xfs_dir2_node_addname_int( if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK))) return error; - lastfbno = XFS_DIR2_DA_TO_DB(mp, (xfs_dablk_t)fo); + lastfbno = xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo); fbno = ifbno; } /* @@ -1434,7 +1522,7 @@ xfs_dir2_node_addname_int( * to avoid it. */ if ((error = xfs_da_read_buf(tp, dp, - XFS_DIR2_DB_TO_DA(mp, fbno), -2, &fbp, + xfs_dir2_db_to_da(mp, fbno), -2, &fbp, XFS_DATA_FORK))) { return error; } @@ -1442,20 +1530,20 @@ xfs_dir2_node_addname_int( continue; } free = fbp->data; - ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); + ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); findex = 0; } /* * Look at the current free entry. Is it good enough? */ - if (INT_GET(free->bests[findex], ARCH_CONVERT) != NULLDATAOFF && - INT_GET(free->bests[findex], ARCH_CONVERT) >= length) - dbno = INT_GET(free->hdr.firstdb, ARCH_CONVERT) + findex; + if (be16_to_cpu(free->bests[findex]) != NULLDATAOFF && + be16_to_cpu(free->bests[findex]) >= length) + dbno = be32_to_cpu(free->hdr.firstdb) + findex; else { /* * Are we done with the freeblock? */ - if (++findex == INT_GET(free->hdr.nvalid, ARCH_CONVERT)) { + if (++findex == be32_to_cpu(free->hdr.nvalid)) { /* * Drop the block. */ @@ -1474,7 +1562,8 @@ xfs_dir2_node_addname_int( /* * Not allowed to allocate, return failure. */ - if (args->justcheck || args->total == 0) { + if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || + args->total == 0) { /* * Drop the freespace buffer unless it came from our * caller. @@ -1510,9 +1599,9 @@ xfs_dir2_node_addname_int( * Get the freespace block corresponding to the data block * that was just allocated. */ - fbno = XFS_DIR2_DB_TO_FDB(mp, dbno); + fbno = xfs_dir2_db_to_fdb(mp, dbno); if (unlikely(error = xfs_da_read_buf(tp, dp, - XFS_DIR2_DB_TO_DA(mp, fbno), -2, &fbp, + xfs_dir2_db_to_da(mp, fbno), -2, &fbp, XFS_DATA_FORK))) { xfs_da_buf_done(dbp); return error; @@ -1527,14 +1616,14 @@ xfs_dir2_node_addname_int( return error; } - if (unlikely(XFS_DIR2_DB_TO_FDB(mp, dbno) != fbno)) { + if (unlikely(xfs_dir2_db_to_fdb(mp, dbno) != fbno)) { cmn_err(CE_ALERT, "xfs_dir2_node_addname_int: dir ino " "%llu needed freesp block %lld for\n" " data block %lld, got %lld\n" " ifbno %llu lastfbno %d\n", (unsigned long long)dp->i_ino, - (long long)XFS_DIR2_DB_TO_FDB(mp, dbno), + (long long)xfs_dir2_db_to_fdb(mp, dbno), (long long)dbno, (long long)fbno, (unsigned long long)ifbno, lastfbno); if (fblk) { @@ -1558,7 +1647,7 @@ xfs_dir2_node_addname_int( * Get a buffer for the new block. */ if ((error = xfs_da_get_buf(tp, dp, - XFS_DIR2_DB_TO_DA(mp, fbno), + xfs_dir2_db_to_da(mp, fbno), -1, &fbp, XFS_DATA_FORK))) { return error; } @@ -1569,39 +1658,39 @@ xfs_dir2_node_addname_int( * its first slot as our empty slot. */ free = fbp->data; - INT_SET(free->hdr.magic, ARCH_CONVERT, XFS_DIR2_FREE_MAGIC); - INT_SET(free->hdr.firstdb, ARCH_CONVERT, + free->hdr.magic = cpu_to_be32(XFS_DIR2_FREE_MAGIC); + free->hdr.firstdb = cpu_to_be32( (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) * XFS_DIR2_MAX_FREE_BESTS(mp)); free->hdr.nvalid = 0; free->hdr.nused = 0; } else { free = fbp->data; - ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); + ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); } /* * Set the freespace block index from the data block number. */ - findex = XFS_DIR2_DB_TO_FDINDEX(mp, dbno); + findex = xfs_dir2_db_to_fdindex(mp, dbno); /* * If it's after the end of the current entries in the * freespace block, extend that table. */ - if (findex >= INT_GET(free->hdr.nvalid, ARCH_CONVERT)) { + if (findex >= be32_to_cpu(free->hdr.nvalid)) { ASSERT(findex < XFS_DIR2_MAX_FREE_BESTS(mp)); - INT_SET(free->hdr.nvalid, ARCH_CONVERT, findex + 1); + free->hdr.nvalid = cpu_to_be32(findex + 1); /* * Tag new entry so nused will go up. */ - INT_SET(free->bests[findex], ARCH_CONVERT, NULLDATAOFF); + free->bests[findex] = cpu_to_be16(NULLDATAOFF); } /* * If this entry was for an empty data block * (this should always be true) then update the header. */ - if (INT_GET(free->bests[findex], ARCH_CONVERT) == NULLDATAOFF) { - INT_MOD(free->hdr.nused, ARCH_CONVERT, +1); + if (be16_to_cpu(free->bests[findex]) == NULLDATAOFF) { + be32_add_cpu(&free->hdr.nused, 1); xfs_dir2_free_log_header(tp, fbp); } /* @@ -1610,7 +1699,7 @@ xfs_dir2_node_addname_int( * change again. */ data = dbp->data; - INT_COPY(free->bests[findex], data->hdr.bestfree[0].length, ARCH_CONVERT); + free->bests[findex] = data->hdr.bestfree[0].length; logfree = 1; } /* @@ -1620,7 +1709,7 @@ xfs_dir2_node_addname_int( /* * If just checking, we succeeded. */ - if (args->justcheck) { + if (args->op_flags & XFS_DA_OP_JUSTCHECK) { if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) xfs_da_buf_done(fbp); return 0; @@ -1629,7 +1718,7 @@ xfs_dir2_node_addname_int( * Read the data block in. */ if (unlikely( - error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, dbno), + error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, dbno), -1, &dbp, XFS_DATA_FORK))) { if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) xfs_da_buf_done(fbp); @@ -1638,12 +1727,12 @@ xfs_dir2_node_addname_int( data = dbp->data; logfree = 0; } - ASSERT(INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT) >= length); + ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) >= length); /* * Point to the existing unused space. */ dup = (xfs_dir2_data_unused_t *) - ((char *)data + INT_GET(data->hdr.bestfree[0].offset, ARCH_CONVERT)); + ((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset)); needscan = needlog = 0; /* * Mark the first part of the unused space, inuse for us. @@ -1655,17 +1744,17 @@ xfs_dir2_node_addname_int( * Fill in the new entry and log it. */ dep = (xfs_dir2_data_entry_t *)dup; - INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); + dep->inumber = cpu_to_be64(args->inumber); dep->namelen = args->namelen; memcpy(dep->name, args->name, dep->namelen); - tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); - INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)data)); + tagp = xfs_dir2_data_entry_tag_p(dep); + *tagp = cpu_to_be16((char *)dep - (char *)data); xfs_dir2_data_log_entry(tp, dbp, dep); /* * Rescan the block for bestfree if needed. */ if (needscan) - xfs_dir2_data_freescan(mp, data, &needlog, NULL); + xfs_dir2_data_freescan(mp, data, &needlog); /* * Log the data block header if needed. */ @@ -1674,8 +1763,8 @@ xfs_dir2_node_addname_int( /* * If the freespace entry is now wrong, update it. */ - if (INT_GET(free->bests[findex], ARCH_CONVERT) != INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT)) { - INT_COPY(free->bests[findex], data->hdr.bestfree[0].length, ARCH_CONVERT); + if (be16_to_cpu(free->bests[findex]) != be16_to_cpu(data->hdr.bestfree[0].length)) { + free->bests[findex] = data->hdr.bestfree[0].length; logfree = 1; } /* @@ -1692,7 +1781,7 @@ xfs_dir2_node_addname_int( * Return the data block and offset in args, then drop the data block. */ args->blkno = (xfs_dablk_t)dbno; - args->index = INT_GET(*tagp, ARCH_CONVERT); + args->index = be16_to_cpu(*tagp); xfs_da_buf_done(dbp); return 0; } @@ -1726,6 +1815,14 @@ xfs_dir2_node_lookup( error = xfs_da_node_lookup_int(state, &rval); if (error) rval = error; + else if (rval == ENOENT && args->cmpresult == XFS_CMP_CASE) { + /* If a CI match, dup the actual name and return EEXIST */ + xfs_dir2_data_entry_t *dep; + + dep = (xfs_dir2_data_entry_t *)((char *)state->extrablk.bp-> + data + state->extrablk.index); + rval = xfs_dir_cilookup_result(args, dep->name, dep->namelen); + } /* * Release the btree blocks and leaf block. */ @@ -1769,9 +1866,8 @@ xfs_dir2_node_removename( * Look up the entry we're deleting, set up the cursor. */ error = xfs_da_node_lookup_int(state, &rval); - if (error) { + if (error) rval = error; - } /* * Didn't find it, upper layer screwed up. */ @@ -1788,9 +1884,8 @@ xfs_dir2_node_removename( */ error = xfs_dir2_leafn_remove(args, blk->bp, blk->index, &state->extrablk, &rval); - if (error) { + if (error) return error; - } /* * Fix the hash values up the btree. */ @@ -1861,15 +1956,15 @@ xfs_dir2_node_replace( * Point to the data entry. */ data = state->extrablk.bp->data; - ASSERT(INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC); + ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC); dep = (xfs_dir2_data_entry_t *) ((char *)data + - XFS_DIR2_DATAPTR_TO_OFF(state->mp, INT_GET(lep->address, ARCH_CONVERT))); - ASSERT(inum != INT_GET(dep->inumber, ARCH_CONVERT)); + xfs_dir2_dataptr_to_off(state->mp, be32_to_cpu(lep->address))); + ASSERT(inum != be64_to_cpu(dep->inumber)); /* * Fill in the new inode number and log the entry. */ - INT_SET(dep->inumber, ARCH_CONVERT, inum); + dep->inumber = cpu_to_be64(inum); xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep); rval = 0; } @@ -1927,11 +2022,11 @@ xfs_dir2_node_trim_free( return 0; } free = bp->data; - ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); + ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); /* * If there are used entries, there's nothing to do. */ - if (INT_GET(free->hdr.nused, ARCH_CONVERT) > 0) { + if (be32_to_cpu(free->hdr.nused) > 0) { xfs_da_brelse(tp, bp); *rvalp = 0; return 0; @@ -1940,7 +2035,7 @@ xfs_dir2_node_trim_free( * Blow the block away. */ if ((error = - xfs_dir2_shrink_inode(args, XFS_DIR2_DA_TO_DB(mp, (xfs_dablk_t)fo), + xfs_dir2_shrink_inode(args, xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo), bp))) { /* * Can't fail with ENOSPC since that only happens with no diff --git a/libxfs/xfs_dir2_sf.c b/libxfs/xfs_dir2_sf.c index b00fc5cfb..77f30de0f 100644 --- a/libxfs/xfs_dir2_sf.c +++ b/libxfs/xfs_dir2_sf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -16,13 +16,29 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -/* - * xfs_dir2_sf.c - * Shortform directory implementation for v2 directories. - */ - #include +/* + * Prototypes for internal functions. + */ +static void xfs_dir2_sf_addname_easy(xfs_da_args_t *args, + xfs_dir2_sf_entry_t *sfep, + xfs_dir2_data_aoff_t offset, + int new_isize); +static void xfs_dir2_sf_addname_hard(xfs_da_args_t *args, int objchange, + int new_isize); +static int xfs_dir2_sf_addname_pick(xfs_da_args_t *args, int objchange, + xfs_dir2_sf_entry_t **sfepp, + xfs_dir2_data_aoff_t *offsetp); +#ifdef DEBUG +static void xfs_dir2_sf_check(xfs_da_args_t *args); +#else +#define xfs_dir2_sf_check(args) +#endif /* DEBUG */ +#if XFS_BIG_INUMS +static void xfs_dir2_sf_toino4(xfs_da_args_t *args); +static void xfs_dir2_sf_toino8(xfs_da_args_t *args); +#endif /* XFS_BIG_INUMS */ /* * Given a block directory (dp/block), calculate its size as a shortform (sf) @@ -53,20 +69,20 @@ xfs_dir2_block_sfsize( mp = dp->i_mount; count = i8count = namelen = 0; - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); - blp = XFS_DIR2_BLOCK_LEAF_P(btp); + btp = xfs_dir2_block_tail_p(mp, block); + blp = xfs_dir2_block_leaf_p(btp); /* * Iterate over the block's data entries by using the leaf pointers. */ - for (i = 0; i < INT_GET(btp->count, ARCH_CONVERT); i++) { - if ((addr = INT_GET(blp[i].address, ARCH_CONVERT)) == XFS_DIR2_NULL_DATAPTR) + for (i = 0; i < be32_to_cpu(btp->count); i++) { + if ((addr = be32_to_cpu(blp[i].address)) == XFS_DIR2_NULL_DATAPTR) continue; /* * Calculate the pointer to the entry at hand. */ dep = (xfs_dir2_data_entry_t *) - ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, addr)); + ((char *)block + xfs_dir2_dataptr_to_off(mp, addr)); /* * Detect . and .., so we can special-case them. * . is not included in sf directories. @@ -78,17 +94,17 @@ xfs_dir2_block_sfsize( dep->name[0] == '.' && dep->name[1] == '.'; #if XFS_BIG_INUMS if (!isdot) - i8count += INT_GET(dep->inumber, ARCH_CONVERT) > XFS_DIR2_MAX_SHORT_INUM; + i8count += be64_to_cpu(dep->inumber) > XFS_DIR2_MAX_SHORT_INUM; #endif if (!isdot && !isdotdot) { count++; namelen += dep->namelen; } else if (isdotdot) - parent = INT_GET(dep->inumber, ARCH_CONVERT); + parent = be64_to_cpu(dep->inumber); /* * Calculate the new size, see if we should give up yet. */ - size = XFS_DIR2_SF_HDR_SIZE(i8count) + /* header */ + size = xfs_dir2_sf_hdr_size(i8count) + /* header */ count + /* namelen */ count * (uint)sizeof(xfs_dir2_sf_off_t) + /* offset */ namelen + /* name */ @@ -103,7 +119,7 @@ xfs_dir2_block_sfsize( */ sfhp->count = count; sfhp->i8count = i8count; - XFS_DIR2_SF_PUT_INUMBER((xfs_dir2_sf_t *)sfhp, &parent, &sfhp->parent); + xfs_dir2_sf_put_inumber((xfs_dir2_sf_t *)sfhp, &parent, &sfhp->parent); return size; } @@ -163,15 +179,15 @@ xfs_dir2_block_to_sf( * Copy the header into the newly allocate local space. */ sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - memcpy(sfp, sfhp, XFS_DIR2_SF_HDR_SIZE(sfhp->i8count)); + memcpy(sfp, sfhp, xfs_dir2_sf_hdr_size(sfhp->i8count)); dp->i_d.di_size = size; /* * Set up to loop over the block's entries. */ - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); + btp = xfs_dir2_block_tail_p(mp, block); ptr = (char *)block->u; - endptr = (char *)XFS_DIR2_BLOCK_LEAF_P(btp); - sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); + endptr = (char *)xfs_dir2_block_leaf_p(btp); + sfep = xfs_dir2_sf_firstentry(sfp); /* * Loop over the active and unused entries. * Stop when we reach the leaf/tail portion of the block. @@ -181,8 +197,8 @@ xfs_dir2_block_to_sf( * If it's unused, just skip over it. */ dup = (xfs_dir2_data_unused_t *)ptr; - if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) { - ptr += INT_GET(dup->length, ARCH_CONVERT); + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { + ptr += be16_to_cpu(dup->length); continue; } dep = (xfs_dir2_data_entry_t *)ptr; @@ -190,35 +206,35 @@ xfs_dir2_block_to_sf( * Skip . */ if (dep->namelen == 1 && dep->name[0] == '.') - ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) == dp->i_ino); + ASSERT(be64_to_cpu(dep->inumber) == dp->i_ino); /* * Skip .., but make sure the inode number is right. */ else if (dep->namelen == 2 && dep->name[0] == '.' && dep->name[1] == '.') - ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) == - XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent)); + ASSERT(be64_to_cpu(dep->inumber) == + xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent)); /* * Normal entry, copy it into shortform. */ else { sfep->namelen = dep->namelen; - XFS_DIR2_SF_PUT_OFFSET(sfep, + xfs_dir2_sf_put_offset(sfep, (xfs_dir2_data_aoff_t) ((char *)dep - (char *)block)); memcpy(sfep->name, dep->name, dep->namelen); - temp=INT_GET(dep->inumber, ARCH_CONVERT); - XFS_DIR2_SF_PUT_INUMBER(sfp, &temp, - XFS_DIR2_SF_INUMBERP(sfep)); - sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep); + temp = be64_to_cpu(dep->inumber); + xfs_dir2_sf_put_inumber(sfp, &temp, + xfs_dir2_sf_inumberp(sfep)); + sfep = xfs_dir2_sf_nextentry(sfp, sfep); } - ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen); + ptr += xfs_dir2_data_entsize(dep->namelen); } ASSERT((char *)sfep - (char *)sfp == size); xfs_dir2_sf_check(args); out: xfs_trans_log_inode(args->trans, dp, logflags); - kmem_free(block, mp->m_dirblksize); + kmem_free(block); return error; } @@ -258,11 +274,11 @@ xfs_dir2_sf_addname( ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); ASSERT(dp->i_df.if_u1.if_data != NULL); sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count)); + ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); /* * Compute entry (and change in) size. */ - add_entsize = XFS_DIR2_SF_ENTSIZE_BYNAME(sfp, args->namelen); + add_entsize = xfs_dir2_sf_entsize_byname(sfp, args->namelen); incr_isize = add_entsize; objchange = 0; #if XFS_BIG_INUMS @@ -295,7 +311,7 @@ xfs_dir2_sf_addname( /* * Just checking or no space reservation, it doesn't fit. */ - if (args->justcheck || args->total == 0) + if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || args->total == 0) return XFS_ERROR(ENOSPC); /* * Convert to block form then add the name. @@ -308,7 +324,7 @@ xfs_dir2_sf_addname( /* * Just checking, it fits. */ - if (args->justcheck) + if (args->op_flags & XFS_DA_OP_JUSTCHECK) return 0; /* * Do it the easy way - just add it at the end. @@ -338,7 +354,7 @@ xfs_dir2_sf_addname( * that's already there, and then room to convert to a block directory. * This is already checked by the pick routine. */ -STATIC void +static void xfs_dir2_sf_addname_easy( xfs_da_args_t *args, /* operation arguments */ xfs_dir2_sf_entry_t *sfep, /* pointer to new entry */ @@ -356,7 +372,7 @@ xfs_dir2_sf_addname_easy( /* * Grow the in-inode space. */ - xfs_idata_realloc(dp, XFS_DIR2_SF_ENTSIZE_BYNAME(sfp, args->namelen), + xfs_idata_realloc(dp, xfs_dir2_sf_entsize_byname(sfp, args->namelen), XFS_DATA_FORK); /* * Need to set up again due to realloc of the inode data. @@ -367,10 +383,10 @@ xfs_dir2_sf_addname_easy( * Fill in the new entry. */ sfep->namelen = args->namelen; - XFS_DIR2_SF_PUT_OFFSET(sfep, offset); + xfs_dir2_sf_put_offset(sfep, offset); memcpy(sfep->name, args->name, sfep->namelen); - XFS_DIR2_SF_PUT_INUMBER(sfp, &args->inumber, - XFS_DIR2_SF_INUMBERP(sfep)); + xfs_dir2_sf_put_inumber(sfp, &args->inumber, + xfs_dir2_sf_inumberp(sfep)); /* * Update the header and inode. */ @@ -392,7 +408,7 @@ xfs_dir2_sf_addname_easy( * the entries. */ /* ARGSUSED */ -STATIC void +static void xfs_dir2_sf_addname_hard( xfs_da_args_t *args, /* operation arguments */ int objchange, /* changing inode number size */ @@ -427,14 +443,14 @@ xfs_dir2_sf_addname_hard( * If it's going to end up at the end then oldsfep will point there. */ for (offset = XFS_DIR2_DATA_FIRST_OFFSET, - oldsfep = XFS_DIR2_SF_FIRSTENTRY(oldsfp), - add_datasize = XFS_DIR2_DATA_ENTSIZE(args->namelen), + oldsfep = xfs_dir2_sf_firstentry(oldsfp), + add_datasize = xfs_dir2_data_entsize(args->namelen), eof = (char *)oldsfep == &buf[old_isize]; !eof; - offset = new_offset + XFS_DIR2_DATA_ENTSIZE(oldsfep->namelen), - oldsfep = XFS_DIR2_SF_NEXTENTRY(oldsfp, oldsfep), + offset = new_offset + xfs_dir2_data_entsize(oldsfep->namelen), + oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep), eof = (char *)oldsfep == &buf[old_isize]) { - new_offset = XFS_DIR2_SF_GET_OFFSET(oldsfep); + new_offset = xfs_dir2_sf_get_offset(oldsfep); if (offset + add_datasize <= new_offset) break; } @@ -459,10 +475,10 @@ xfs_dir2_sf_addname_hard( * Fill in the new entry, and update the header counts. */ sfep->namelen = args->namelen; - XFS_DIR2_SF_PUT_OFFSET(sfep, offset); + xfs_dir2_sf_put_offset(sfep, offset); memcpy(sfep->name, args->name, sfep->namelen); - XFS_DIR2_SF_PUT_INUMBER(sfp, &args->inumber, - XFS_DIR2_SF_INUMBERP(sfep)); + xfs_dir2_sf_put_inumber(sfp, &args->inumber, + xfs_dir2_sf_inumberp(sfep)); sfp->hdr.count++; #if XFS_BIG_INUMS if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange) @@ -472,10 +488,10 @@ xfs_dir2_sf_addname_hard( * If there's more left to copy, do that. */ if (!eof) { - sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep); + sfep = xfs_dir2_sf_nextentry(sfp, sfep); memcpy(sfep, oldsfep, old_isize - nbytes); } - kmem_free(buf, old_isize); + kmem_free(buf); dp->i_d.di_size = new_isize; xfs_dir2_sf_check(args); } @@ -487,7 +503,7 @@ xfs_dir2_sf_addname_hard( * Return 0 (won't fit), 1 (easy), 2 (hard). */ /*ARGSUSED*/ -STATIC int /* pick result */ +static int /* pick result */ xfs_dir2_sf_addname_pick( xfs_da_args_t *args, /* operation arguments */ int objchange, /* inode # size changes */ @@ -508,9 +524,9 @@ xfs_dir2_sf_addname_pick( mp = dp->i_mount; sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - size = XFS_DIR2_DATA_ENTSIZE(args->namelen); + size = xfs_dir2_data_entsize(args->namelen); offset = XFS_DIR2_DATA_FIRST_OFFSET; - sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); + sfep = xfs_dir2_sf_firstentry(sfp); holefit = 0; /* * Loop over sf entries. @@ -519,10 +535,10 @@ xfs_dir2_sf_addname_pick( */ for (i = 0; i < sfp->hdr.count; i++) { if (!holefit) - holefit = offset + size <= XFS_DIR2_SF_GET_OFFSET(sfep); - offset = XFS_DIR2_SF_GET_OFFSET(sfep) + - XFS_DIR2_DATA_ENTSIZE(sfep->namelen); - sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep); + holefit = offset + size <= xfs_dir2_sf_get_offset(sfep); + offset = xfs_dir2_sf_get_offset(sfep) + + xfs_dir2_data_entsize(sfep->namelen); + sfep = xfs_dir2_sf_nextentry(sfp, sfep); } /* * Calculate data bytes used excluding the new entry, if this @@ -565,7 +581,7 @@ xfs_dir2_sf_addname_pick( /* * Check consistency of shortform directory, assert if bad. */ -STATIC void +static void xfs_dir2_sf_check( xfs_da_args_t *args) /* operation arguments */ { @@ -581,18 +597,18 @@ xfs_dir2_sf_check( sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; offset = XFS_DIR2_DATA_FIRST_OFFSET; - ino = XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent); + ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); i8count = ino > XFS_DIR2_MAX_SHORT_INUM; - for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); + for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->hdr.count; - i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep)) { - ASSERT(XFS_DIR2_SF_GET_OFFSET(sfep) >= offset); - ino = XFS_DIR2_SF_GET_INUMBER(sfp, XFS_DIR2_SF_INUMBERP(sfep)); + i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { + ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset); + ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); i8count += ino > XFS_DIR2_MAX_SHORT_INUM; offset = - XFS_DIR2_SF_GET_OFFSET(sfep) + - XFS_DIR2_DATA_ENTSIZE(sfep->namelen); + xfs_dir2_sf_get_offset(sfep) + + xfs_dir2_data_entsize(sfep->namelen); } ASSERT(i8count == sfp->hdr.i8count); ASSERT(XFS_BIG_INUMS || i8count == 0); @@ -635,7 +651,7 @@ xfs_dir2_sf_create( ASSERT(dp->i_df.if_flags & XFS_IFINLINE); ASSERT(dp->i_df.if_bytes == 0); i8count = pino > XFS_DIR2_MAX_SHORT_INUM; - size = XFS_DIR2_SF_HDR_SIZE(i8count); + size = xfs_dir2_sf_hdr_size(i8count); /* * Make a buffer for the data. */ @@ -648,7 +664,7 @@ xfs_dir2_sf_create( /* * Now can put in the inode number, since i8count is set. */ - XFS_DIR2_SF_PUT_INUMBER(sfp, &pino, &sfp->hdr.parent); + xfs_dir2_sf_put_inumber(sfp, &pino, &sfp->hdr.parent); sfp->hdr.count = 0; dp->i_d.di_size = size; xfs_dir2_sf_check(args); @@ -666,8 +682,11 @@ xfs_dir2_sf_lookup( { xfs_inode_t *dp; /* incore directory inode */ int i; /* entry index */ + int error; xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ xfs_dir2_sf_t *sfp; /* shortform structure */ + enum xfs_dacmp cmp; /* comparison result */ + xfs_dir2_sf_entry_t *ci_sfep; /* case-insens. entry */ xfs_dir2_trace_args("sf_lookup", args); xfs_dir2_sf_check(args); @@ -684,12 +703,13 @@ xfs_dir2_sf_lookup( ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); ASSERT(dp->i_df.if_u1.if_data != NULL); sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count)); + ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); /* * Special case for . */ if (args->namelen == 1 && args->name[0] == '.') { args->inumber = dp->i_ino; + args->cmpresult = XFS_CMP_EXACT; return XFS_ERROR(EEXIST); } /* @@ -697,29 +717,42 @@ xfs_dir2_sf_lookup( */ if (args->namelen == 2 && args->name[0] == '.' && args->name[1] == '.') { - args->inumber = XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent); + args->inumber = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); + args->cmpresult = XFS_CMP_EXACT; return XFS_ERROR(EEXIST); } /* * Loop over all the entries trying to match ours. */ - for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); - i < sfp->hdr.count; - i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep)) { - if (sfep->namelen == args->namelen && - sfep->name[0] == args->name[0] && - memcmp(args->name, sfep->name, args->namelen) == 0) { - args->inumber = - XFS_DIR2_SF_GET_INUMBER(sfp, - XFS_DIR2_SF_INUMBERP(sfep)); - return XFS_ERROR(EEXIST); + ci_sfep = NULL; + for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->hdr.count; + i++, sfep = xfs_dir2_sf_nextentry(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 + * inode number and continue looking for an exact match. + */ + cmp = dp->i_mount->m_dirnameops->compname(args, sfep->name, + sfep->namelen); + if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { + args->cmpresult = cmp; + args->inumber = xfs_dir2_sf_get_inumber(sfp, + xfs_dir2_sf_inumberp(sfep)); + if (cmp == XFS_CMP_EXACT) + return XFS_ERROR(EEXIST); + ci_sfep = sfep; } } + ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); /* - * Didn't find it. + * Here, we can only be doing a lookup (not a rename or replace). + * If a case-insensitive match was not found, return ENOENT. */ - ASSERT(args->oknoent); - return XFS_ERROR(ENOENT); + if (!ci_sfep) + return XFS_ERROR(ENOENT); + /* otherwise process the CI match as required by the caller */ + error = xfs_dir_cilookup_result(args, ci_sfep->name, ci_sfep->namelen); + return XFS_ERROR(error); } /* @@ -753,34 +786,31 @@ xfs_dir2_sf_removename( ASSERT(dp->i_df.if_bytes == oldsize); ASSERT(dp->i_df.if_u1.if_data != NULL); sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(oldsize >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count)); + ASSERT(oldsize >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); /* * Loop over the old directory entries. * Find the one we're deleting. */ - for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); - i < sfp->hdr.count; - i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep)) { - if (sfep->namelen == args->namelen && - sfep->name[0] == args->name[0] && - memcmp(sfep->name, args->name, args->namelen) == 0) { - ASSERT(XFS_DIR2_SF_GET_INUMBER(sfp, - XFS_DIR2_SF_INUMBERP(sfep)) == - args->inumber); + for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->hdr.count; + i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { + if (xfs_da_compname(args, sfep->name, sfep->namelen) == + XFS_CMP_EXACT) { + ASSERT(xfs_dir2_sf_get_inumber(sfp, + xfs_dir2_sf_inumberp(sfep)) == + args->inumber); break; } } /* * Didn't find it. */ - if (i == sfp->hdr.count) { + if (i == sfp->hdr.count) return XFS_ERROR(ENOENT); - } /* * Calculate sizes. */ byteoff = (int)((char *)sfep - (char *)sfp); - entsize = XFS_DIR2_SF_ENTSIZE_BYNAME(sfp, args->namelen); + entsize = xfs_dir2_sf_entsize_byname(sfp, args->namelen); newsize = oldsize - entsize; /* * Copy the part if any after the removed entry, sliding it down. @@ -846,7 +876,7 @@ xfs_dir2_sf_replace( ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); ASSERT(dp->i_df.if_u1.if_data != NULL); sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count)); + ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); #if XFS_BIG_INUMS /* * New inode number is large, and need to convert to 8-byte inodes. @@ -886,28 +916,27 @@ xfs_dir2_sf_replace( if (args->namelen == 2 && args->name[0] == '.' && args->name[1] == '.') { #if XFS_BIG_INUMS || defined(DEBUG) - ino = XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent); + ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); ASSERT(args->inumber != ino); #endif - XFS_DIR2_SF_PUT_INUMBER(sfp, &args->inumber, &sfp->hdr.parent); + xfs_dir2_sf_put_inumber(sfp, &args->inumber, &sfp->hdr.parent); } /* * Normal entry, look for the name. */ else { - for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); - i < sfp->hdr.count; - i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep)) { - if (sfep->namelen == args->namelen && - sfep->name[0] == args->name[0] && - memcmp(args->name, sfep->name, args->namelen) == 0) { + for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); + i < sfp->hdr.count; + i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { + if (xfs_da_compname(args, sfep->name, sfep->namelen) == + XFS_CMP_EXACT) { #if XFS_BIG_INUMS || defined(DEBUG) - ino = XFS_DIR2_SF_GET_INUMBER(sfp, - XFS_DIR2_SF_INUMBERP(sfep)); + ino = xfs_dir2_sf_get_inumber(sfp, + xfs_dir2_sf_inumberp(sfep)); ASSERT(args->inumber != ino); #endif - XFS_DIR2_SF_PUT_INUMBER(sfp, &args->inumber, - XFS_DIR2_SF_INUMBERP(sfep)); + xfs_dir2_sf_put_inumber(sfp, &args->inumber, + xfs_dir2_sf_inumberp(sfep)); break; } } @@ -915,7 +944,7 @@ xfs_dir2_sf_replace( * Didn't find it. */ if (i == sfp->hdr.count) { - ASSERT(args->oknoent); + ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); #if XFS_BIG_INUMS if (i8elevated) xfs_dir2_sf_toino4(args); @@ -961,7 +990,7 @@ xfs_dir2_sf_replace( * Convert from 8-byte inode numbers to 4-byte inode numbers. * The last 8-byte inode number is gone, but the count is still 1. */ -STATIC void +static void xfs_dir2_sf_toino4( xfs_da_args_t *args) /* operation arguments */ { @@ -1008,27 +1037,27 @@ xfs_dir2_sf_toino4( */ sfp->hdr.count = oldsfp->hdr.count; sfp->hdr.i8count = 0; - ino = XFS_DIR2_SF_GET_INUMBER(oldsfp, &oldsfp->hdr.parent); - XFS_DIR2_SF_PUT_INUMBER(sfp, &ino, &sfp->hdr.parent); + ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); + xfs_dir2_sf_put_inumber(sfp, &ino, &sfp->hdr.parent); /* * Copy the entries field by field. */ - for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp), - oldsfep = XFS_DIR2_SF_FIRSTENTRY(oldsfp); + for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), + oldsfep = xfs_dir2_sf_firstentry(oldsfp); i < sfp->hdr.count; - i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep), - oldsfep = XFS_DIR2_SF_NEXTENTRY(oldsfp, oldsfep)) { + i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep), + oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) { sfep->namelen = oldsfep->namelen; sfep->offset = oldsfep->offset; memcpy(sfep->name, oldsfep->name, sfep->namelen); - ino = XFS_DIR2_SF_GET_INUMBER(oldsfp, - XFS_DIR2_SF_INUMBERP(oldsfep)); - XFS_DIR2_SF_PUT_INUMBER(sfp, &ino, XFS_DIR2_SF_INUMBERP(sfep)); + ino = xfs_dir2_sf_get_inumber(oldsfp, + xfs_dir2_sf_inumberp(oldsfep)); + xfs_dir2_sf_put_inumber(sfp, &ino, xfs_dir2_sf_inumberp(sfep)); } /* * Clean up the inode. */ - kmem_free(buf, oldsize); + kmem_free(buf); dp->i_d.di_size = newsize; xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); } @@ -1038,7 +1067,7 @@ xfs_dir2_sf_toino4( * The new 8-byte inode number is not there yet, we leave with the * count 1 but no corresponding entry. */ -STATIC void +static void xfs_dir2_sf_toino8( xfs_da_args_t *args) /* operation arguments */ { @@ -1085,27 +1114,27 @@ xfs_dir2_sf_toino8( */ sfp->hdr.count = oldsfp->hdr.count; sfp->hdr.i8count = 1; - ino = XFS_DIR2_SF_GET_INUMBER(oldsfp, &oldsfp->hdr.parent); - XFS_DIR2_SF_PUT_INUMBER(sfp, &ino, &sfp->hdr.parent); + ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); + xfs_dir2_sf_put_inumber(sfp, &ino, &sfp->hdr.parent); /* * Copy the entries field by field. */ - for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp), - oldsfep = XFS_DIR2_SF_FIRSTENTRY(oldsfp); + for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), + oldsfep = xfs_dir2_sf_firstentry(oldsfp); i < sfp->hdr.count; - i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep), - oldsfep = XFS_DIR2_SF_NEXTENTRY(oldsfp, oldsfep)) { + i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep), + oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) { sfep->namelen = oldsfep->namelen; sfep->offset = oldsfep->offset; memcpy(sfep->name, oldsfep->name, sfep->namelen); - ino = XFS_DIR2_SF_GET_INUMBER(oldsfp, - XFS_DIR2_SF_INUMBERP(oldsfep)); - XFS_DIR2_SF_PUT_INUMBER(sfp, &ino, XFS_DIR2_SF_INUMBERP(sfep)); + ino = xfs_dir2_sf_get_inumber(oldsfp, + xfs_dir2_sf_inumberp(oldsfep)); + xfs_dir2_sf_put_inumber(sfp, &ino, xfs_dir2_sf_inumberp(sfep)); } /* * Clean up the inode. */ - kmem_free(buf, oldsize); + kmem_free(buf); dp->i_d.di_size = newsize; xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); } diff --git a/libxfs/xfs_dir_leaf.c b/libxfs/xfs_dir_leaf.c deleted file mode 100644 index 4c6ace30b..000000000 --- a/libxfs/xfs_dir_leaf.c +++ /dev/null @@ -1,1676 +0,0 @@ -/* - * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - - -/* - * xfs_dir_leaf.c - * - * Routines to implement leaf blocks of directories as Btrees of hashed names. - */ - -/* - * Validate a given inode number. - */ -int -xfs_dir_ino_validate(xfs_mount_t *mp, xfs_ino_t ino) -{ - xfs_agblock_t agblkno; - xfs_agino_t agino; - xfs_agnumber_t agno; - int ino_ok; - int ioff; - - agno = XFS_INO_TO_AGNO(mp, ino); - agblkno = XFS_INO_TO_AGBNO(mp, ino); - ioff = XFS_INO_TO_OFFSET(mp, ino); - agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff); - ino_ok = - agno < mp->m_sb.sb_agcount && - agblkno < mp->m_sb.sb_agblocks && - agblkno != 0 && - ioff < (1 << mp->m_sb.sb_inopblog) && - XFS_AGINO_TO_INO(mp, agno, agino) == ino; - if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE, - XFS_RANDOM_DIR_INO_VALIDATE))) { - xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx", - (unsigned long long) ino); - XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp); - return XFS_ERROR(EFSCORRUPTED); - } - return 0; -} - -/* - * Create the initial contents of a shortform directory. - */ -int -xfs_dir_shortform_create(xfs_da_args_t *args, xfs_ino_t parent) -{ - xfs_dir_sf_hdr_t *hdr; - xfs_inode_t *dp; - - dp = args->dp; - ASSERT(dp != NULL); - ASSERT(dp->i_d.di_size == 0); - if (dp->i_d.di_format == XFS_DINODE_FMT_EXTENTS) { - dp->i_df.if_flags &= ~XFS_IFEXTENTS; /* just in case */ - dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; - xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE); - dp->i_df.if_flags |= XFS_IFINLINE; - } - ASSERT(dp->i_df.if_flags & XFS_IFINLINE); - ASSERT(dp->i_df.if_bytes == 0); - xfs_idata_realloc(dp, sizeof(*hdr), XFS_DATA_FORK); - hdr = (xfs_dir_sf_hdr_t *)dp->i_df.if_u1.if_data; - XFS_DIR_SF_PUT_DIRINO(&parent, &hdr->parent); - - hdr->count = 0; - dp->i_d.di_size = sizeof(*hdr); - xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); - return(0); -} - -/* - * Add a name to the shortform directory structure. - * Overflow from the inode has already been checked for. - */ -int -xfs_dir_shortform_addname(xfs_da_args_t *args) -{ - xfs_dir_shortform_t *sf; - xfs_dir_sf_entry_t *sfe; - int i, offset, size; - xfs_inode_t *dp; - - dp = args->dp; - ASSERT(dp->i_df.if_flags & XFS_IFINLINE); - /* - * Catch the case where the conversion from shortform to leaf - * failed part way through. - */ - if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { - ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); - return XFS_ERROR(EIO); - } - ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); - ASSERT(dp->i_df.if_u1.if_data != NULL); - sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; - sfe = &sf->list[0]; - for (i = INT_GET(sf->hdr.count, ARCH_CONVERT)-1; i >= 0; i--) { - if (sfe->namelen == args->namelen && - args->name[0] == sfe->name[0] && - memcmp(args->name, sfe->name, args->namelen) == 0) - return(XFS_ERROR(EEXIST)); - sfe = XFS_DIR_SF_NEXTENTRY(sfe); - } - - offset = (int)((char *)sfe - (char *)sf); - size = XFS_DIR_SF_ENTSIZE_BYNAME(args->namelen); - xfs_idata_realloc(dp, size, XFS_DATA_FORK); - sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; - sfe = (xfs_dir_sf_entry_t *)((char *)sf + offset); - - XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber); - sfe->namelen = args->namelen; - memcpy(sfe->name, args->name, sfe->namelen); - INT_MOD(sf->hdr.count, ARCH_CONVERT, +1); - - dp->i_d.di_size += size; - xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); - - return(0); -} - -/* - * Remove a name from the shortform directory structure. - */ -int -xfs_dir_shortform_removename(xfs_da_args_t *args) -{ - xfs_dir_shortform_t *sf; - xfs_dir_sf_entry_t *sfe; - int base, size = 0, i; - xfs_inode_t *dp; - - dp = args->dp; - ASSERT(dp->i_df.if_flags & XFS_IFINLINE); - /* - * Catch the case where the conversion from shortform to leaf - * failed part way through. - */ - if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { - ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); - return XFS_ERROR(EIO); - } - ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); - ASSERT(dp->i_df.if_u1.if_data != NULL); - base = sizeof(xfs_dir_sf_hdr_t); - sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; - sfe = &sf->list[0]; - for (i = INT_GET(sf->hdr.count, ARCH_CONVERT)-1; i >= 0; i--) { - size = XFS_DIR_SF_ENTSIZE_BYENTRY(sfe); - if (sfe->namelen == args->namelen && - sfe->name[0] == args->name[0] && - memcmp(sfe->name, args->name, args->namelen) == 0) - break; - base += size; - sfe = XFS_DIR_SF_NEXTENTRY(sfe); - } - if (i < 0) { - ASSERT(args->oknoent); - return(XFS_ERROR(ENOENT)); - } - - if ((base + size) != dp->i_d.di_size) { - memmove(&((char *)sf)[base], &((char *)sf)[base+size], - dp->i_d.di_size - (base+size)); - } - INT_MOD(sf->hdr.count, ARCH_CONVERT, -1); - - xfs_idata_realloc(dp, -size, XFS_DATA_FORK); - dp->i_d.di_size -= size; - xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); - - return(0); -} - -/* - * Look up a name in a shortform directory structure. - */ -int -xfs_dir_shortform_lookup(xfs_da_args_t *args) -{ - xfs_dir_shortform_t *sf; - xfs_dir_sf_entry_t *sfe; - int i; - xfs_inode_t *dp; - - dp = args->dp; - ASSERT(dp->i_df.if_flags & XFS_IFINLINE); - /* - * Catch the case where the conversion from shortform to leaf - * failed part way through. - */ - if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { - ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); - return XFS_ERROR(EIO); - } - ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); - ASSERT(dp->i_df.if_u1.if_data != NULL); - sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; - if (args->namelen == 2 && - args->name[0] == '.' && args->name[1] == '.') { - XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, &args->inumber); - return(XFS_ERROR(EEXIST)); - } - if (args->namelen == 1 && args->name[0] == '.') { - args->inumber = dp->i_ino; - return(XFS_ERROR(EEXIST)); - } - sfe = &sf->list[0]; - for (i = INT_GET(sf->hdr.count, ARCH_CONVERT)-1; i >= 0; i--) { - if (sfe->namelen == args->namelen && - sfe->name[0] == args->name[0] && - memcmp(args->name, sfe->name, args->namelen) == 0) { - XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &args->inumber); - return(XFS_ERROR(EEXIST)); - } - sfe = XFS_DIR_SF_NEXTENTRY(sfe); - } - ASSERT(args->oknoent); - return(XFS_ERROR(ENOENT)); -} - -/* - * Convert from using the shortform to the leaf. - */ -int -xfs_dir_shortform_to_leaf(xfs_da_args_t *iargs) -{ - xfs_inode_t *dp; - xfs_dir_shortform_t *sf; - xfs_dir_sf_entry_t *sfe; - xfs_da_args_t args; - xfs_ino_t inumber; - char *tmpbuffer; - int retval, i, size; - xfs_dablk_t blkno; - xfs_dabuf_t *bp; - - dp = iargs->dp; - /* - * Catch the case where the conversion from shortform to leaf - * failed part way through. - */ - if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { - ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); - return XFS_ERROR(EIO); - } - ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); - ASSERT(dp->i_df.if_u1.if_data != NULL); - size = dp->i_df.if_bytes; - tmpbuffer = kmem_alloc(size, KM_SLEEP); - ASSERT(tmpbuffer != NULL); - - memcpy(tmpbuffer, dp->i_df.if_u1.if_data, size); - - sf = (xfs_dir_shortform_t *)tmpbuffer; - XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, &inumber); - - xfs_idata_realloc(dp, -size, XFS_DATA_FORK); - dp->i_d.di_size = 0; - xfs_trans_log_inode(iargs->trans, dp, XFS_ILOG_CORE); - retval = xfs_da_grow_inode(iargs, &blkno); - if (retval) - goto out; - - ASSERT(blkno == 0); - retval = xfs_dir_leaf_create(iargs, blkno, &bp); - if (retval) - goto out; - xfs_da_buf_done(bp); - - args.name = (const uchar_t *) "."; - args.namelen = 1; - args.hashval = xfs_dir_hash_dot; - args.inumber = dp->i_ino; - args.dp = dp; - args.firstblock = iargs->firstblock; - args.flist = iargs->flist; - args.total = iargs->total; - args.whichfork = XFS_DATA_FORK; - args.trans = iargs->trans; - args.justcheck = 0; - args.addname = args.oknoent = 1; - retval = xfs_dir_leaf_addname(&args); - if (retval) - goto out; - - args.name = (const uchar_t *) ".."; - args.namelen = 2; - args.hashval = xfs_dir_hash_dotdot; - args.inumber = inumber; - retval = xfs_dir_leaf_addname(&args); - if (retval) - goto out; - - sfe = &sf->list[0]; - for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT); i++) { - args.name = (const uchar_t *)(sfe->name); - args.namelen = sfe->namelen; - args.hashval = xfs_da_hashname((const uchar_t *)(sfe->name), - sfe->namelen); - XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &args.inumber); - retval = xfs_dir_leaf_addname(&args); - if (retval) - goto out; - sfe = XFS_DIR_SF_NEXTENTRY(sfe); - } - retval = 0; - -out: - kmem_free(tmpbuffer, size); - return(retval); -} - -/* - * Look up a name in a shortform directory structure, replace the inode number. - */ -int -xfs_dir_shortform_replace(xfs_da_args_t *args) -{ - xfs_dir_shortform_t *sf; - xfs_dir_sf_entry_t *sfe; - xfs_inode_t *dp; - int i; - - dp = args->dp; - ASSERT(dp->i_df.if_flags & XFS_IFINLINE); - /* - * Catch the case where the conversion from shortform to leaf - * failed part way through. - */ - if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { - ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); - return XFS_ERROR(EIO); - } - ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); - ASSERT(dp->i_df.if_u1.if_data != NULL); - sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; - if (args->namelen == 2 && - args->name[0] == '.' && args->name[1] == '.') { - /* XXX - replace assert? */ - XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sf->hdr.parent); - xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA); - return(0); - } - ASSERT(args->namelen != 1 || args->name[0] != '.'); - sfe = &sf->list[0]; - for (i = INT_GET(sf->hdr.count, ARCH_CONVERT)-1; i >= 0; i--) { - if (sfe->namelen == args->namelen && - sfe->name[0] == args->name[0] && - memcmp(args->name, sfe->name, args->namelen) == 0) { - ASSERT(memcmp((char *)&args->inumber, - (char *)&sfe->inumber, sizeof(xfs_ino_t))); - XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber); - xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA); - return(0); - } - sfe = XFS_DIR_SF_NEXTENTRY(sfe); - } - ASSERT(args->oknoent); - return(XFS_ERROR(ENOENT)); -} - -/* - * Convert a leaf directory to shortform structure - */ -int -xfs_dir_leaf_to_shortform(xfs_da_args_t *iargs) -{ - xfs_dir_leafblock_t *leaf; - xfs_dir_leaf_hdr_t *hdr; - xfs_dir_leaf_entry_t *entry; - xfs_dir_leaf_name_t *namest; - xfs_da_args_t args; - xfs_inode_t *dp; - xfs_ino_t parent = 0; - char *tmpbuffer; - int retval, i; - xfs_dabuf_t *bp; - - dp = iargs->dp; - tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP); - ASSERT(tmpbuffer != NULL); - - retval = xfs_da_read_buf(iargs->trans, iargs->dp, 0, -1, &bp, - XFS_DATA_FORK); - if (retval) - goto out; - ASSERT(bp != NULL); - memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount)); - leaf = (xfs_dir_leafblock_t *)tmpbuffer; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - memset(bp->data, 0, XFS_LBSIZE(dp->i_mount)); - - /* - * Find and special case the parent inode number - */ - hdr = &leaf->hdr; - entry = &leaf->entries[0]; - for (i = INT_GET(hdr->count, ARCH_CONVERT)-1; i >= 0; entry++, i--) { - namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); - if ((entry->namelen == 2) && - (namest->name[0] == '.') && - (namest->name[1] == '.')) { - XFS_DIR_SF_GET_DIRINO(&namest->inumber, &parent); - entry->nameidx = 0; - } else if ((entry->namelen == 1) && (namest->name[0] == '.')) { - entry->nameidx = 0; - } - } - retval = xfs_da_shrink_inode(iargs, 0, bp); - if (retval) - goto out; - retval = xfs_dir_shortform_create(iargs, parent); - if (retval) - goto out; - - /* - * Copy the rest of the filenames - */ - entry = &leaf->entries[0]; - args.dp = dp; - args.firstblock = iargs->firstblock; - args.flist = iargs->flist; - args.total = iargs->total; - args.whichfork = XFS_DATA_FORK; - args.trans = iargs->trans; - args.justcheck = 0; - args.addname = args.oknoent = 1; - for (i = 0; i < INT_GET(hdr->count, ARCH_CONVERT); entry++, i++) { - if (!entry->nameidx) - continue; - namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); - args.name = (const uchar_t *)(namest->name); - args.namelen = entry->namelen; - args.hashval = INT_GET(entry->hashval, ARCH_CONVERT); - XFS_DIR_SF_GET_DIRINO(&namest->inumber, &args.inumber); - xfs_dir_shortform_addname(&args); - } - -out: - kmem_free(tmpbuffer, XFS_LBSIZE(dp->i_mount)); - return(retval); -} - -/* - * Convert from using a single leaf to a root node and a leaf. - */ -int -xfs_dir_leaf_to_node(xfs_da_args_t *args) -{ - xfs_dir_leafblock_t *leaf; - xfs_da_intnode_t *node; - xfs_inode_t *dp; - xfs_dabuf_t *bp1, *bp2; - xfs_dablk_t blkno; - int retval; - - dp = args->dp; - retval = xfs_da_grow_inode(args, &blkno); - ASSERT(blkno == 1); - if (retval) - return(retval); - retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp1, - XFS_DATA_FORK); - if (retval) - return(retval); - ASSERT(bp1 != NULL); - retval = xfs_da_get_buf(args->trans, args->dp, 1, -1, &bp2, - XFS_DATA_FORK); - if (retval) { - xfs_da_buf_done(bp1); - return(retval); - } - ASSERT(bp2 != NULL); - memcpy(bp2->data, bp1->data, XFS_LBSIZE(dp->i_mount)); - xfs_da_buf_done(bp1); - xfs_da_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1); - - /* - * Set up the new root node. - */ - retval = xfs_da_node_create(args, 0, 1, &bp1, XFS_DATA_FORK); - if (retval) { - xfs_da_buf_done(bp2); - return(retval); - } - node = bp1->data; - leaf = bp2->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - INT_SET(node->btree[0].hashval, ARCH_CONVERT, INT_GET(leaf->entries[ INT_GET(leaf->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)); - xfs_da_buf_done(bp2); - INT_SET(node->btree[0].before, ARCH_CONVERT, blkno); - INT_SET(node->hdr.count, ARCH_CONVERT, 1); - xfs_da_log_buf(args->trans, bp1, - XFS_DA_LOGRANGE(node, &node->btree[0], sizeof(node->btree[0]))); - xfs_da_buf_done(bp1); - - return(retval); -} - - -/*======================================================================== - * Routines used for growing the Btree. - *========================================================================*/ - -/* - * Create the initial contents of a leaf directory - * or a leaf in a node directory. - */ -int -xfs_dir_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) -{ - xfs_dir_leafblock_t *leaf; - xfs_dir_leaf_hdr_t *hdr; - xfs_inode_t *dp; - xfs_dabuf_t *bp; - int retval; - - dp = args->dp; - ASSERT(dp != NULL); - retval = xfs_da_get_buf(args->trans, dp, blkno, -1, &bp, XFS_DATA_FORK); - if (retval) - return(retval); - ASSERT(bp != NULL); - leaf = bp->data; - memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount)); - hdr = &leaf->hdr; - INT_SET(hdr->info.magic, ARCH_CONVERT, XFS_DIR_LEAF_MAGIC); - INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount)); - if (!hdr->firstused) - INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount) - 1); - INT_SET(hdr->freemap[0].base, ARCH_CONVERT, sizeof(xfs_dir_leaf_hdr_t)); - INT_SET(hdr->freemap[0].size, ARCH_CONVERT, INT_GET(hdr->firstused, ARCH_CONVERT) - INT_GET(hdr->freemap[0].base, ARCH_CONVERT)); - - xfs_da_log_buf(args->trans, bp, 0, XFS_LBSIZE(dp->i_mount) - 1); - - *bpp = bp; - return(0); -} - -/* - * Split the leaf node, rebalance, then add the new entry. - */ -int -xfs_dir_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, - xfs_da_state_blk_t *newblk) -{ - xfs_dablk_t blkno; - xfs_da_args_t *args; - int error; - - /* - * Allocate space for a new leaf node. - */ - args = state->args; - ASSERT(args != NULL); - ASSERT(oldblk->magic == XFS_DIR_LEAF_MAGIC); - error = xfs_da_grow_inode(args, &blkno); - if (error) - return(error); - error = xfs_dir_leaf_create(args, blkno, &newblk->bp); - if (error) - return(error); - newblk->blkno = blkno; - newblk->magic = XFS_DIR_LEAF_MAGIC; - - /* - * Rebalance the entries across the two leaves. - */ - xfs_dir_leaf_rebalance(state, oldblk, newblk); - error = xfs_da_blk_link(state, oldblk, newblk); - if (error) - return(error); - - /* - * Insert the new entry in the correct block. - */ - if (state->inleaf) { - error = xfs_dir_leaf_add(oldblk->bp, args, oldblk->index); - } else { - error = xfs_dir_leaf_add(newblk->bp, args, newblk->index); - } - - /* - * Update last hashval in each block since we added the name. - */ - oldblk->hashval = xfs_dir_leaf_lasthash(oldblk->bp, NULL); - newblk->hashval = xfs_dir_leaf_lasthash(newblk->bp, NULL); - return(error); -} - -/* - * Add a name to the leaf directory structure. - * - * Must take into account fragmented leaves and leaves where spacemap has - * lost some freespace information (ie: holes). - */ -int -xfs_dir_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args, int index) -{ - xfs_dir_leafblock_t *leaf; - xfs_dir_leaf_hdr_t *hdr; - xfs_dir_leaf_map_t *map; - int tablesize, entsize, sum, i, tmp, error; - - leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - ASSERT((index >= 0) && (index <= INT_GET(leaf->hdr.count, ARCH_CONVERT))); - hdr = &leaf->hdr; - entsize = XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen); - - /* - * Search through freemap for first-fit on new name length. - * (may need to figure in size of entry struct too) - */ - tablesize = (INT_GET(hdr->count, ARCH_CONVERT) + 1) * (uint)sizeof(xfs_dir_leaf_entry_t) - + (uint)sizeof(xfs_dir_leaf_hdr_t); - map = &hdr->freemap[XFS_DIR_LEAF_MAPSIZE-1]; - for (sum = 0, i = XFS_DIR_LEAF_MAPSIZE-1; i >= 0; map--, i--) { - if (tablesize > INT_GET(hdr->firstused, ARCH_CONVERT)) { - sum += INT_GET(map->size, ARCH_CONVERT); - continue; - } - if (!map->size) - continue; /* no space in this map */ - tmp = entsize; - if (INT_GET(map->base, ARCH_CONVERT) < INT_GET(hdr->firstused, ARCH_CONVERT)) - tmp += (uint)sizeof(xfs_dir_leaf_entry_t); - if (INT_GET(map->size, ARCH_CONVERT) >= tmp) { - if (!args->justcheck) - xfs_dir_leaf_add_work(bp, args, index, i); - return(0); - } - sum += INT_GET(map->size, ARCH_CONVERT); - } - - /* - * If there are no holes in the address space of the block, - * and we don't have enough freespace, then compaction will do us - * no good and we should just give up. - */ - if (!hdr->holes && (sum < entsize)) - return(XFS_ERROR(ENOSPC)); - - /* - * Compact the entries to coalesce free space. - * Pass the justcheck flag so the checking pass can return - * an error, without changing anything, if it won't fit. - */ - error = xfs_dir_leaf_compact(args->trans, bp, - args->total == 0 ? - entsize + - (uint)sizeof(xfs_dir_leaf_entry_t) : 0, - args->justcheck); - if (error) - return(error); - /* - * After compaction, the block is guaranteed to have only one - * free region, in freemap[0]. If it is not big enough, give up. - */ - if (INT_GET(hdr->freemap[0].size, ARCH_CONVERT) < - (entsize + (uint)sizeof(xfs_dir_leaf_entry_t))) - return(XFS_ERROR(ENOSPC)); - - if (!args->justcheck) - xfs_dir_leaf_add_work(bp, args, index, 0); - return(0); -} - -/* - * Add a name to a leaf directory structure. - */ -STATIC void -xfs_dir_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int index, - int mapindex) -{ - xfs_dir_leafblock_t *leaf; - xfs_dir_leaf_hdr_t *hdr; - xfs_dir_leaf_entry_t *entry; - xfs_dir_leaf_name_t *namest; - xfs_dir_leaf_map_t *map; - /* REFERENCED */ - xfs_mount_t *mp; - int tmp, i; - - leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - hdr = &leaf->hdr; - ASSERT((mapindex >= 0) && (mapindex < XFS_DIR_LEAF_MAPSIZE)); - ASSERT((index >= 0) && (index <= INT_GET(hdr->count, ARCH_CONVERT))); - - /* - * Force open some space in the entry array and fill it in. - */ - entry = &leaf->entries[index]; - if (index < INT_GET(hdr->count, ARCH_CONVERT)) { - tmp = INT_GET(hdr->count, ARCH_CONVERT) - index; - tmp *= (uint)sizeof(xfs_dir_leaf_entry_t); - memmove(entry + 1, entry, tmp); - xfs_da_log_buf(args->trans, bp, - XFS_DA_LOGRANGE(leaf, entry, tmp + (uint)sizeof(*entry))); - } - INT_MOD(hdr->count, ARCH_CONVERT, +1); - - /* - * Allocate space for the new string (at the end of the run). - */ - map = &hdr->freemap[mapindex]; - mp = args->trans->t_mountp; - ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp)); - ASSERT(INT_GET(map->size, ARCH_CONVERT) >= XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen)); - ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp)); - INT_MOD(map->size, ARCH_CONVERT, -(XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen))); - INT_SET(entry->nameidx, ARCH_CONVERT, INT_GET(map->base, ARCH_CONVERT) + INT_GET(map->size, ARCH_CONVERT)); - INT_SET(entry->hashval, ARCH_CONVERT, args->hashval); - entry->namelen = args->namelen; - xfs_da_log_buf(args->trans, bp, - XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); - - /* - * Copy the string and inode number into the new space. - */ - namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); - XFS_DIR_SF_PUT_DIRINO(&args->inumber, &namest->inumber); - memcpy(namest->name, args->name, args->namelen); - xfs_da_log_buf(args->trans, bp, - XFS_DA_LOGRANGE(leaf, namest, XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry))); - - /* - * Update the control info for this leaf node - */ - if (INT_GET(entry->nameidx, ARCH_CONVERT) < INT_GET(hdr->firstused, ARCH_CONVERT)) - INT_COPY(hdr->firstused, entry->nameidx, ARCH_CONVERT); - ASSERT(INT_GET(hdr->firstused, ARCH_CONVERT) >= ((INT_GET(hdr->count, ARCH_CONVERT)*sizeof(*entry))+sizeof(*hdr))); - tmp = (INT_GET(hdr->count, ARCH_CONVERT)-1) * (uint)sizeof(xfs_dir_leaf_entry_t) - + (uint)sizeof(xfs_dir_leaf_hdr_t); - map = &hdr->freemap[0]; - for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; map++, i++) { - if (INT_GET(map->base, ARCH_CONVERT) == tmp) { - INT_MOD(map->base, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_entry_t)); - INT_MOD(map->size, ARCH_CONVERT, -((uint)sizeof(xfs_dir_leaf_entry_t))); - } - } - INT_MOD(hdr->namebytes, ARCH_CONVERT, args->namelen); - xfs_da_log_buf(args->trans, bp, - XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); -} - -/* - * Garbage collect a leaf directory block by copying it to a new buffer. - */ -STATIC int -xfs_dir_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp, int musthave, - int justcheck) -{ - xfs_dir_leafblock_t *leaf_s, *leaf_d; - xfs_dir_leaf_hdr_t *hdr_s, *hdr_d; - xfs_mount_t *mp; - char *tmpbuffer; - char *tmpbuffer2=NULL; - int rval; - int lbsize; - - mp = trans->t_mountp; - lbsize = XFS_LBSIZE(mp); - tmpbuffer = kmem_alloc(lbsize, KM_SLEEP); - ASSERT(tmpbuffer != NULL); - memcpy(tmpbuffer, bp->data, lbsize); - - /* - * Make a second copy in case xfs_dir_leaf_moveents() - * below destroys the original. - */ - if (musthave || justcheck) { - tmpbuffer2 = kmem_alloc(lbsize, KM_SLEEP); - memcpy(tmpbuffer2, bp->data, lbsize); - } - memset(bp->data, 0, lbsize); - - /* - * Copy basic information - */ - leaf_s = (xfs_dir_leafblock_t *)tmpbuffer; - leaf_d = bp->data; - hdr_s = &leaf_s->hdr; - hdr_d = &leaf_d->hdr; - hdr_d->info = hdr_s->info; /* struct copy */ - INT_SET(hdr_d->firstused, ARCH_CONVERT, lbsize); - if (!hdr_d->firstused) - INT_SET(hdr_d->firstused, ARCH_CONVERT, lbsize - 1); - hdr_d->namebytes = 0; - hdr_d->count = 0; - hdr_d->holes = 0; - INT_SET(hdr_d->freemap[0].base, ARCH_CONVERT, sizeof(xfs_dir_leaf_hdr_t)); - INT_SET(hdr_d->freemap[0].size, ARCH_CONVERT, INT_GET(hdr_d->firstused, ARCH_CONVERT) - INT_GET(hdr_d->freemap[0].base, ARCH_CONVERT)); - - /* - * Copy all entry's in the same (sorted) order, - * but allocate filenames packed and in sequence. - * This changes the source (leaf_s) as well. - */ - xfs_dir_leaf_moveents(leaf_s, 0, leaf_d, 0, (int)INT_GET(hdr_s->count, ARCH_CONVERT), mp); - - if (musthave && INT_GET(hdr_d->freemap[0].size, ARCH_CONVERT) < musthave) - rval = XFS_ERROR(ENOSPC); - else - rval = 0; - - if (justcheck || rval == ENOSPC) { - ASSERT(tmpbuffer2); - memcpy(bp->data, tmpbuffer2, lbsize); - } else { - xfs_da_log_buf(trans, bp, 0, lbsize - 1); - } - - kmem_free(tmpbuffer, lbsize); - if (musthave || justcheck) - kmem_free(tmpbuffer2, lbsize); - return(rval); -} - -/* - * Redistribute the directory entries between two leaf nodes, - * taking into account the size of the new entry. - * - * NOTE: if new block is empty, then it will get the upper half of old block. - */ -STATIC void -xfs_dir_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, - xfs_da_state_blk_t *blk2) -{ - xfs_da_state_blk_t *tmp_blk; - xfs_dir_leafblock_t *leaf1, *leaf2; - xfs_dir_leaf_hdr_t *hdr1, *hdr2; - int count, totallen, max, space, swap; - - /* - * Set up environment. - */ - ASSERT(blk1->magic == XFS_DIR_LEAF_MAGIC); - ASSERT(blk2->magic == XFS_DIR_LEAF_MAGIC); - leaf1 = blk1->bp->data; - leaf2 = blk2->bp->data; - ASSERT(INT_GET(leaf1->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - ASSERT(INT_GET(leaf2->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - - /* - * Check ordering of blocks, reverse if it makes things simpler. - */ - swap = 0; - if (xfs_dir_leaf_order(blk1->bp, blk2->bp)) { - tmp_blk = blk1; - blk1 = blk2; - blk2 = tmp_blk; - leaf1 = blk1->bp->data; - leaf2 = blk2->bp->data; - swap = 1; - } - hdr1 = &leaf1->hdr; - hdr2 = &leaf2->hdr; - - /* - * Examine entries until we reduce the absolute difference in - * byte usage between the two blocks to a minimum. Then get - * the direction to copy and the number of elements to move. - */ - state->inleaf = xfs_dir_leaf_figure_balance(state, blk1, blk2, - &count, &totallen); - if (swap) - state->inleaf = !state->inleaf; - - /* - * Move any entries required from leaf to leaf: - */ - if (count < INT_GET(hdr1->count, ARCH_CONVERT)) { - /* - * Figure the total bytes to be added to the destination leaf. - */ - count = INT_GET(hdr1->count, ARCH_CONVERT) - count; /* number entries being moved */ - space = INT_GET(hdr1->namebytes, ARCH_CONVERT) - totallen; - space += count * ((uint)sizeof(xfs_dir_leaf_name_t)-1); - space += count * (uint)sizeof(xfs_dir_leaf_entry_t); - - /* - * leaf2 is the destination, compact it if it looks tight. - */ - max = INT_GET(hdr2->firstused, ARCH_CONVERT) - (uint)sizeof(xfs_dir_leaf_hdr_t); - max -= INT_GET(hdr2->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t); - if (space > max) { - xfs_dir_leaf_compact(state->args->trans, blk2->bp, - 0, 0); - } - - /* - * Move high entries from leaf1 to low end of leaf2. - */ - xfs_dir_leaf_moveents(leaf1, INT_GET(hdr1->count, ARCH_CONVERT) - count, - leaf2, 0, count, state->mp); - - xfs_da_log_buf(state->args->trans, blk1->bp, 0, - state->blocksize-1); - xfs_da_log_buf(state->args->trans, blk2->bp, 0, - state->blocksize-1); - - } else if (count > INT_GET(hdr1->count, ARCH_CONVERT)) { - /* - * Figure the total bytes to be added to the destination leaf. - */ - count -= INT_GET(hdr1->count, ARCH_CONVERT); /* number entries being moved */ - space = totallen - INT_GET(hdr1->namebytes, ARCH_CONVERT); - space += count * ((uint)sizeof(xfs_dir_leaf_name_t)-1); - space += count * (uint)sizeof(xfs_dir_leaf_entry_t); - - /* - * leaf1 is the destination, compact it if it looks tight. - */ - max = INT_GET(hdr1->firstused, ARCH_CONVERT) - (uint)sizeof(xfs_dir_leaf_hdr_t); - max -= INT_GET(hdr1->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t); - if (space > max) { - xfs_dir_leaf_compact(state->args->trans, blk1->bp, - 0, 0); - } - - /* - * Move low entries from leaf2 to high end of leaf1. - */ - xfs_dir_leaf_moveents(leaf2, 0, leaf1, (int)INT_GET(hdr1->count, ARCH_CONVERT), - count, state->mp); - - xfs_da_log_buf(state->args->trans, blk1->bp, 0, - state->blocksize-1); - xfs_da_log_buf(state->args->trans, blk2->bp, 0, - state->blocksize-1); - } - - /* - * Copy out last hashval in each block for B-tree code. - */ - blk1->hashval = INT_GET(leaf1->entries[ INT_GET(leaf1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); - blk2->hashval = INT_GET(leaf2->entries[ INT_GET(leaf2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); - - /* - * Adjust the expected index for insertion. - * GROT: this doesn't work unless blk2 was originally empty. - */ - if (!state->inleaf) { - blk2->index = blk1->index - INT_GET(leaf1->hdr.count, ARCH_CONVERT); - } -} - -/* - * Examine entries until we reduce the absolute difference in - * byte usage between the two blocks to a minimum. - * GROT: Is this really necessary? With other than a 512 byte blocksize, - * GROT: there will always be enough room in either block for a new entry. - * GROT: Do a double-split for this case? - */ -STATIC int -xfs_dir_leaf_figure_balance(xfs_da_state_t *state, - xfs_da_state_blk_t *blk1, - xfs_da_state_blk_t *blk2, - int *countarg, int *namebytesarg) -{ - xfs_dir_leafblock_t *leaf1, *leaf2; - xfs_dir_leaf_hdr_t *hdr1, *hdr2; - xfs_dir_leaf_entry_t *entry; - int count, max, totallen, half; - int lastdelta, foundit, tmp; - - /* - * Set up environment. - */ - leaf1 = blk1->bp->data; - leaf2 = blk2->bp->data; - hdr1 = &leaf1->hdr; - hdr2 = &leaf2->hdr; - foundit = 0; - totallen = 0; - - /* - * Examine entries until we reduce the absolute difference in - * byte usage between the two blocks to a minimum. - */ - max = INT_GET(hdr1->count, ARCH_CONVERT) + INT_GET(hdr2->count, ARCH_CONVERT); - half = (max+1) * (uint)(sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1); - half += INT_GET(hdr1->namebytes, ARCH_CONVERT) + INT_GET(hdr2->namebytes, ARCH_CONVERT) + state->args->namelen; - half /= 2; - lastdelta = state->blocksize; - entry = &leaf1->entries[0]; - for (count = 0; count < max; entry++, count++) { - -#define XFS_DIR_ABS(A) (((A) < 0) ? -(A) : (A)) - /* - * The new entry is in the first block, account for it. - */ - if (count == blk1->index) { - tmp = totallen + (uint)sizeof(*entry) - + XFS_DIR_LEAF_ENTSIZE_BYNAME(state->args->namelen); - if (XFS_DIR_ABS(half - tmp) > lastdelta) - break; - lastdelta = XFS_DIR_ABS(half - tmp); - totallen = tmp; - foundit = 1; - } - - /* - * Wrap around into the second block if necessary. - */ - if (count == INT_GET(hdr1->count, ARCH_CONVERT)) { - leaf1 = leaf2; - entry = &leaf1->entries[0]; - } - - /* - * Figure out if next leaf entry would be too much. - */ - tmp = totallen + (uint)sizeof(*entry) - + XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry); - if (XFS_DIR_ABS(half - tmp) > lastdelta) - break; - lastdelta = XFS_DIR_ABS(half - tmp); - totallen = tmp; -#undef XFS_DIR_ABS - } - - /* - * Calculate the number of namebytes that will end up in lower block. - * If new entry not in lower block, fix up the count. - */ - totallen -= - count * (uint)(sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1); - if (foundit) { - totallen -= (sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1) + - state->args->namelen; - } - - *countarg = count; - *namebytesarg = totallen; - return(foundit); -} - -/*======================================================================== - * Routines used for shrinking the Btree. - *========================================================================*/ - -/* - * Check a leaf block and its neighbors to see if the block should be - * collapsed into one or the other neighbor. Always keep the block - * with the smaller block number. - * If the current block is over 50% full, don't try to join it, return 0. - * If the block is empty, fill in the state structure and return 2. - * If it can be collapsed, fill in the state structure and return 1. - * If nothing can be done, return 0. - */ -int -xfs_dir_leaf_toosmall(xfs_da_state_t *state, int *action) -{ - xfs_dir_leafblock_t *leaf; - xfs_da_state_blk_t *blk; - xfs_da_blkinfo_t *info; - int count, bytes, forward, error, retval, i; - xfs_dablk_t blkno; - xfs_dabuf_t *bp; - - /* - * Check for the degenerate case of the block being over 50% full. - * If so, it's not worth even looking to see if we might be able - * to coalesce with a sibling. - */ - blk = &state->path.blk[ state->path.active-1 ]; - info = blk->bp->data; - ASSERT(INT_GET(info->magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - leaf = (xfs_dir_leafblock_t *)info; - count = INT_GET(leaf->hdr.count, ARCH_CONVERT); - bytes = (uint)sizeof(xfs_dir_leaf_hdr_t) + - count * (uint)sizeof(xfs_dir_leaf_entry_t) + - count * ((uint)sizeof(xfs_dir_leaf_name_t)-1) + - INT_GET(leaf->hdr.namebytes, ARCH_CONVERT); - if (bytes > (state->blocksize >> 1)) { - *action = 0; /* blk over 50%, don't try to join */ - return(0); - } - - /* - * Check for the degenerate case of the block being empty. - * If the block is empty, we'll simply delete it, no need to - * coalesce it with a sibling block. We choose (aribtrarily) - * to merge with the forward block unless it is NULL. - */ - if (count == 0) { - /* - * Make altpath point to the block we want to keep and - * path point to the block we want to drop (this one). - */ - forward = info->forw; - memcpy(&state->altpath, &state->path, sizeof(state->path)); - error = xfs_da_path_shift(state, &state->altpath, forward, - 0, &retval); - if (error) - return(error); - if (retval) { - *action = 0; - } else { - *action = 2; - } - return(0); - } - - /* - * Examine each sibling block to see if we can coalesce with - * at least 25% free space to spare. We need to figure out - * whether to merge with the forward or the backward block. - * We prefer coalescing with the lower numbered sibling so as - * to shrink a directory over time. - */ - forward = (INT_GET(info->forw, ARCH_CONVERT) < INT_GET(info->back, ARCH_CONVERT)); /* start with smaller blk num */ - for (i = 0; i < 2; forward = !forward, i++) { - if (forward) - blkno = INT_GET(info->forw, ARCH_CONVERT); - else - blkno = INT_GET(info->back, ARCH_CONVERT); - if (blkno == 0) - continue; - error = xfs_da_read_buf(state->args->trans, state->args->dp, - blkno, -1, &bp, - XFS_DATA_FORK); - if (error) - return(error); - ASSERT(bp != NULL); - - leaf = (xfs_dir_leafblock_t *)info; - count = INT_GET(leaf->hdr.count, ARCH_CONVERT); - bytes = state->blocksize - (state->blocksize>>2); - bytes -= INT_GET(leaf->hdr.namebytes, ARCH_CONVERT); - leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - count += INT_GET(leaf->hdr.count, ARCH_CONVERT); - bytes -= INT_GET(leaf->hdr.namebytes, ARCH_CONVERT); - bytes -= count * ((uint)sizeof(xfs_dir_leaf_name_t) - 1); - bytes -= count * (uint)sizeof(xfs_dir_leaf_entry_t); - bytes -= (uint)sizeof(xfs_dir_leaf_hdr_t); - if (bytes >= 0) - break; /* fits with at least 25% to spare */ - - xfs_da_brelse(state->args->trans, bp); - } - if (i >= 2) { - *action = 0; - return(0); - } - xfs_da_buf_done(bp); - - /* - * Make altpath point to the block we want to keep (the lower - * numbered block) and path point to the block we want to drop. - */ - memcpy(&state->altpath, &state->path, sizeof(state->path)); - if (blkno < blk->blkno) { - error = xfs_da_path_shift(state, &state->altpath, forward, - 0, &retval); - } else { - error = xfs_da_path_shift(state, &state->path, forward, - 0, &retval); - } - if (error) - return(error); - if (retval) { - *action = 0; - } else { - *action = 1; - } - return(0); -} - -/* - * Remove a name from the leaf directory structure. - * - * Return 1 if leaf is less than 37% full, 0 if >= 37% full. - * If two leaves are 37% full, when combined they will leave 25% free. - */ -int -xfs_dir_leaf_remove(xfs_trans_t *trans, xfs_dabuf_t *bp, int index) -{ - xfs_dir_leafblock_t *leaf; - xfs_dir_leaf_hdr_t *hdr; - xfs_dir_leaf_map_t *map; - xfs_dir_leaf_entry_t *entry; - xfs_dir_leaf_name_t *namest; - int before, after, smallest, entsize; - int tablesize, tmp, i; - xfs_mount_t *mp; - - leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - hdr = &leaf->hdr; - mp = trans->t_mountp; - ASSERT((INT_GET(hdr->count, ARCH_CONVERT) > 0) && (INT_GET(hdr->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8))); - ASSERT((index >= 0) && (index < INT_GET(hdr->count, ARCH_CONVERT))); - ASSERT(INT_GET(hdr->firstused, ARCH_CONVERT) >= ((INT_GET(hdr->count, ARCH_CONVERT)*sizeof(*entry))+sizeof(*hdr))); - entry = &leaf->entries[index]; - ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) >= INT_GET(hdr->firstused, ARCH_CONVERT)); - ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) < XFS_LBSIZE(mp)); - - /* - * Scan through free region table: - * check for adjacency of free'd entry with an existing one, - * find smallest free region in case we need to replace it, - * adjust any map that borders the entry table, - */ - tablesize = INT_GET(hdr->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t) - + (uint)sizeof(xfs_dir_leaf_hdr_t); - map = &hdr->freemap[0]; - tmp = INT_GET(map->size, ARCH_CONVERT); - before = after = -1; - smallest = XFS_DIR_LEAF_MAPSIZE - 1; - entsize = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry); - for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; map++, i++) { - ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp)); - ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp)); - if (INT_GET(map->base, ARCH_CONVERT) == tablesize) { - INT_MOD(map->base, ARCH_CONVERT, -((uint)sizeof(xfs_dir_leaf_entry_t))); - INT_MOD(map->size, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_entry_t)); - } - - if ((INT_GET(map->base, ARCH_CONVERT) + INT_GET(map->size, ARCH_CONVERT)) == INT_GET(entry->nameidx, ARCH_CONVERT)) { - before = i; - } else if (INT_GET(map->base, ARCH_CONVERT) == (INT_GET(entry->nameidx, ARCH_CONVERT) + entsize)) { - after = i; - } else if (INT_GET(map->size, ARCH_CONVERT) < tmp) { - tmp = INT_GET(map->size, ARCH_CONVERT); - smallest = i; - } - } - - /* - * Coalesce adjacent freemap regions, - * or replace the smallest region. - */ - if ((before >= 0) || (after >= 0)) { - if ((before >= 0) && (after >= 0)) { - map = &hdr->freemap[before]; - INT_MOD(map->size, ARCH_CONVERT, entsize); - INT_MOD(map->size, ARCH_CONVERT, INT_GET(hdr->freemap[after].size, ARCH_CONVERT)); - hdr->freemap[after].base = 0; - hdr->freemap[after].size = 0; - } else if (before >= 0) { - map = &hdr->freemap[before]; - INT_MOD(map->size, ARCH_CONVERT, entsize); - } else { - map = &hdr->freemap[after]; - INT_COPY(map->base, entry->nameidx, ARCH_CONVERT); - INT_MOD(map->size, ARCH_CONVERT, entsize); - } - } else { - /* - * Replace smallest region (if it is smaller than free'd entry) - */ - map = &hdr->freemap[smallest]; - if (INT_GET(map->size, ARCH_CONVERT) < entsize) { - INT_COPY(map->base, entry->nameidx, ARCH_CONVERT); - INT_SET(map->size, ARCH_CONVERT, entsize); - } - } - - /* - * Did we remove the first entry? - */ - if (INT_GET(entry->nameidx, ARCH_CONVERT) == INT_GET(hdr->firstused, ARCH_CONVERT)) - smallest = 1; - else - smallest = 0; - - /* - * Compress the remaining entries and zero out the removed stuff. - */ - namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); - memset((char *)namest, 0, entsize); - xfs_da_log_buf(trans, bp, XFS_DA_LOGRANGE(leaf, namest, entsize)); - - INT_MOD(hdr->namebytes, ARCH_CONVERT, -(entry->namelen)); - tmp = (INT_GET(hdr->count, ARCH_CONVERT) - index) * (uint)sizeof(xfs_dir_leaf_entry_t); - memmove(entry, entry + 1, tmp); - INT_MOD(hdr->count, ARCH_CONVERT, -1); - xfs_da_log_buf(trans, bp, - XFS_DA_LOGRANGE(leaf, entry, tmp + (uint)sizeof(*entry))); - entry = &leaf->entries[INT_GET(hdr->count, ARCH_CONVERT)]; - memset((char *)entry, 0, sizeof(xfs_dir_leaf_entry_t)); - - /* - * If we removed the first entry, re-find the first used byte - * in the name area. Note that if the entry was the "firstused", - * then we don't have a "hole" in our block resulting from - * removing the name. - */ - if (smallest) { - tmp = XFS_LBSIZE(mp); - entry = &leaf->entries[0]; - for (i = INT_GET(hdr->count, ARCH_CONVERT)-1; i >= 0; entry++, i--) { - ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) >= INT_GET(hdr->firstused, ARCH_CONVERT)); - ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) < XFS_LBSIZE(mp)); - if (INT_GET(entry->nameidx, ARCH_CONVERT) < tmp) - tmp = INT_GET(entry->nameidx, ARCH_CONVERT); - } - INT_SET(hdr->firstused, ARCH_CONVERT, tmp); - if (!hdr->firstused) - INT_SET(hdr->firstused, ARCH_CONVERT, tmp - 1); - } else { - hdr->holes = 1; /* mark as needing compaction */ - } - - xfs_da_log_buf(trans, bp, XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); - - /* - * Check if leaf is less than 50% full, caller may want to - * "join" the leaf with a sibling if so. - */ - tmp = (uint)sizeof(xfs_dir_leaf_hdr_t); - tmp += INT_GET(leaf->hdr.count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t); - tmp += INT_GET(leaf->hdr.count, ARCH_CONVERT) * ((uint)sizeof(xfs_dir_leaf_name_t) - 1); - tmp += INT_GET(leaf->hdr.namebytes, ARCH_CONVERT); - if (tmp < mp->m_dir_magicpct) - return(1); /* leaf is < 37% full */ - return(0); -} - -/* - * Move all the directory entries from drop_leaf into save_leaf. - */ -void -xfs_dir_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, - xfs_da_state_blk_t *save_blk) -{ - xfs_dir_leafblock_t *drop_leaf, *save_leaf, *tmp_leaf; - xfs_dir_leaf_hdr_t *drop_hdr, *save_hdr, *tmp_hdr; - xfs_mount_t *mp; - char *tmpbuffer; - - /* - * Set up environment. - */ - mp = state->mp; - ASSERT(drop_blk->magic == XFS_DIR_LEAF_MAGIC); - ASSERT(save_blk->magic == XFS_DIR_LEAF_MAGIC); - drop_leaf = drop_blk->bp->data; - save_leaf = save_blk->bp->data; - ASSERT(INT_GET(drop_leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - ASSERT(INT_GET(save_leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - drop_hdr = &drop_leaf->hdr; - save_hdr = &save_leaf->hdr; - - /* - * Save last hashval from dying block for later Btree fixup. - */ - drop_blk->hashval = INT_GET(drop_leaf->entries[ drop_leaf->hdr.count-1 ].hashval, ARCH_CONVERT); - - /* - * Check if we need a temp buffer, or can we do it in place. - * Note that we don't check "leaf" for holes because we will - * always be dropping it, toosmall() decided that for us already. - */ - if (save_hdr->holes == 0) { - /* - * dest leaf has no holes, so we add there. May need - * to make some room in the entry array. - */ - if (xfs_dir_leaf_order(save_blk->bp, drop_blk->bp)) { - xfs_dir_leaf_moveents(drop_leaf, 0, save_leaf, 0, - (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp); - } else { - xfs_dir_leaf_moveents(drop_leaf, 0, - save_leaf, INT_GET(save_hdr->count, ARCH_CONVERT), - (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp); - } - } else { - /* - * Destination has holes, so we make a temporary copy - * of the leaf and add them both to that. - */ - tmpbuffer = kmem_alloc(state->blocksize, KM_SLEEP); - ASSERT(tmpbuffer != NULL); - memset(tmpbuffer, 0, state->blocksize); - tmp_leaf = (xfs_dir_leafblock_t *)tmpbuffer; - tmp_hdr = &tmp_leaf->hdr; - tmp_hdr->info = save_hdr->info; /* struct copy */ - tmp_hdr->count = 0; - INT_SET(tmp_hdr->firstused, ARCH_CONVERT, state->blocksize); - if (!tmp_hdr->firstused) - INT_SET(tmp_hdr->firstused, ARCH_CONVERT, state->blocksize - 1); - tmp_hdr->namebytes = 0; - if (xfs_dir_leaf_order(save_blk->bp, drop_blk->bp)) { - xfs_dir_leaf_moveents(drop_leaf, 0, tmp_leaf, 0, - (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp); - xfs_dir_leaf_moveents(save_leaf, 0, - tmp_leaf, INT_GET(tmp_leaf->hdr.count, ARCH_CONVERT), - (int)INT_GET(save_hdr->count, ARCH_CONVERT), mp); - } else { - xfs_dir_leaf_moveents(save_leaf, 0, tmp_leaf, 0, - (int)INT_GET(save_hdr->count, ARCH_CONVERT), mp); - xfs_dir_leaf_moveents(drop_leaf, 0, - tmp_leaf, INT_GET(tmp_leaf->hdr.count, ARCH_CONVERT), - (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp); - } - memcpy(save_leaf, tmp_leaf, state->blocksize); - kmem_free(tmpbuffer, state->blocksize); - } - - xfs_da_log_buf(state->args->trans, save_blk->bp, 0, - state->blocksize - 1); - - /* - * Copy out last hashval in each block for B-tree code. - */ - save_blk->hashval = INT_GET(save_leaf->entries[ INT_GET(save_leaf->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); -} - -/*======================================================================== - * Routines used for finding things in the Btree. - *========================================================================*/ - -/* - * Look up a name in a leaf directory structure. - * This is the internal routine, it uses the caller's buffer. - * - * Note that duplicate keys are allowed, but only check within the - * current leaf node. The Btree code must check in adjacent leaf nodes. - * - * Return in *index the index into the entry[] array of either the found - * entry, or where the entry should have been (insert before that entry). - * - * Don't change the args->inumber unless we find the filename. - */ -int -xfs_dir_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args, int *index) -{ - xfs_dir_leafblock_t *leaf; - xfs_dir_leaf_entry_t *entry; - xfs_dir_leaf_name_t *namest; - int probe, span; - xfs_dahash_t hashval; - - leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) < (XFS_LBSIZE(args->dp->i_mount)/8)); - - /* - * Binary search. (note: small blocks will skip this loop) - */ - hashval = args->hashval; - probe = span = INT_GET(leaf->hdr.count, ARCH_CONVERT) / 2; - for (entry = &leaf->entries[probe]; span > 4; - entry = &leaf->entries[probe]) { - span /= 2; - if (INT_GET(entry->hashval, ARCH_CONVERT) < hashval) - probe += span; - else if (INT_GET(entry->hashval, ARCH_CONVERT) > hashval) - probe -= span; - else - break; - } - ASSERT((probe >= 0) && \ - ((!leaf->hdr.count) || (probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)))); - ASSERT((span <= 4) || (INT_GET(entry->hashval, ARCH_CONVERT) == hashval)); - - /* - * Since we may have duplicate hashval's, find the first matching - * hashval in the leaf. - */ - while ((probe > 0) && (INT_GET(entry->hashval, ARCH_CONVERT) >= hashval)) { - entry--; - probe--; - } - while ((probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)) && (INT_GET(entry->hashval, ARCH_CONVERT) < hashval)) { - entry++; - probe++; - } - if ((probe == INT_GET(leaf->hdr.count, ARCH_CONVERT)) || (INT_GET(entry->hashval, ARCH_CONVERT) != hashval)) { - *index = probe; - ASSERT(args->oknoent); - return(XFS_ERROR(ENOENT)); - } - - /* - * Duplicate keys may be present, so search all of them for a match. - */ - while ((probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)) && (INT_GET(entry->hashval, ARCH_CONVERT) == hashval)) { - namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); - if (entry->namelen == args->namelen && - namest->name[0] == args->name[0] && - memcmp(args->name, namest->name, args->namelen) == 0) { - XFS_DIR_SF_GET_DIRINO(&namest->inumber, &args->inumber); - *index = probe; - return(XFS_ERROR(EEXIST)); - } - entry++; - probe++; - } - *index = probe; - ASSERT(probe == INT_GET(leaf->hdr.count, ARCH_CONVERT) || args->oknoent); - return(XFS_ERROR(ENOENT)); -} - -/*======================================================================== - * Utility routines. - *========================================================================*/ - -/* - * Move the indicated entries from one leaf to another. - * NOTE: this routine modifies both source and destination leaves. - */ -/* ARGSUSED */ -STATIC void -xfs_dir_leaf_moveents(xfs_dir_leafblock_t *leaf_s, int start_s, - xfs_dir_leafblock_t *leaf_d, int start_d, - int count, xfs_mount_t *mp) -{ - xfs_dir_leaf_hdr_t *hdr_s, *hdr_d; - xfs_dir_leaf_entry_t *entry_s, *entry_d; - int tmp, i; - - /* - * Check for nothing to do. - */ - if (count == 0) - return; - - /* - * Set up environment. - */ - ASSERT(INT_GET(leaf_s->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - ASSERT(INT_GET(leaf_d->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - hdr_s = &leaf_s->hdr; - hdr_d = &leaf_d->hdr; - ASSERT((INT_GET(hdr_s->count, ARCH_CONVERT) > 0) && (INT_GET(hdr_s->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8))); - ASSERT(INT_GET(hdr_s->firstused, ARCH_CONVERT) >= - ((INT_GET(hdr_s->count, ARCH_CONVERT)*sizeof(*entry_s))+sizeof(*hdr_s))); - ASSERT(INT_GET(hdr_d->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8)); - ASSERT(INT_GET(hdr_d->firstused, ARCH_CONVERT) >= - ((INT_GET(hdr_d->count, ARCH_CONVERT)*sizeof(*entry_d))+sizeof(*hdr_d))); - - ASSERT(start_s < INT_GET(hdr_s->count, ARCH_CONVERT)); - ASSERT(start_d <= INT_GET(hdr_d->count, ARCH_CONVERT)); - ASSERT(count <= INT_GET(hdr_s->count, ARCH_CONVERT)); - - /* - * Move the entries in the destination leaf up to make a hole? - */ - if (start_d < INT_GET(hdr_d->count, ARCH_CONVERT)) { - tmp = INT_GET(hdr_d->count, ARCH_CONVERT) - start_d; - tmp *= (uint)sizeof(xfs_dir_leaf_entry_t); - entry_s = &leaf_d->entries[start_d]; - entry_d = &leaf_d->entries[start_d + count]; - memcpy(entry_d, entry_s, tmp); - } - - /* - * Copy all entry's in the same (sorted) order, - * but allocate filenames packed and in sequence. - */ - entry_s = &leaf_s->entries[start_s]; - entry_d = &leaf_d->entries[start_d]; - for (i = 0; i < count; entry_s++, entry_d++, i++) { - ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) >= INT_GET(hdr_s->firstused, ARCH_CONVERT)); - tmp = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry_s); - INT_MOD(hdr_d->firstused, ARCH_CONVERT, -(tmp)); - entry_d->hashval = entry_s->hashval; /* INT_: direct copy */ - INT_COPY(entry_d->nameidx, hdr_d->firstused, ARCH_CONVERT); - entry_d->namelen = entry_s->namelen; - ASSERT(INT_GET(entry_d->nameidx, ARCH_CONVERT) + tmp <= XFS_LBSIZE(mp)); - memcpy(XFS_DIR_LEAF_NAMESTRUCT(leaf_d, INT_GET(entry_d->nameidx, ARCH_CONVERT)), - XFS_DIR_LEAF_NAMESTRUCT(leaf_s, INT_GET(entry_s->nameidx, ARCH_CONVERT)), tmp); - ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) + tmp <= XFS_LBSIZE(mp)); - memset((char *)XFS_DIR_LEAF_NAMESTRUCT(leaf_s, INT_GET(entry_s->nameidx, ARCH_CONVERT)), - 0, tmp); - INT_MOD(hdr_s->namebytes, ARCH_CONVERT, -(entry_d->namelen)); - INT_MOD(hdr_d->namebytes, ARCH_CONVERT, entry_d->namelen); - INT_MOD(hdr_s->count, ARCH_CONVERT, -1); - INT_MOD(hdr_d->count, ARCH_CONVERT, +1); - tmp = INT_GET(hdr_d->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t) - + (uint)sizeof(xfs_dir_leaf_hdr_t); - ASSERT(INT_GET(hdr_d->firstused, ARCH_CONVERT) >= tmp); - - } - - /* - * Zero out the entries we just copied. - */ - if (start_s == INT_GET(hdr_s->count, ARCH_CONVERT)) { - tmp = count * (uint)sizeof(xfs_dir_leaf_entry_t); - entry_s = &leaf_s->entries[start_s]; - ASSERT((char *)entry_s + tmp <= (char *)leaf_s + XFS_LBSIZE(mp)); - memset((char *)entry_s, 0, tmp); - } else { - /* - * Move the remaining entries down to fill the hole, - * then zero the entries at the top. - */ - tmp = INT_GET(hdr_s->count, ARCH_CONVERT) - count; - tmp *= (uint)sizeof(xfs_dir_leaf_entry_t); - entry_s = &leaf_s->entries[start_s + count]; - entry_d = &leaf_s->entries[start_s]; - memcpy(entry_d, entry_s, tmp); - - tmp = count * (uint)sizeof(xfs_dir_leaf_entry_t); - entry_s = &leaf_s->entries[INT_GET(hdr_s->count, ARCH_CONVERT)]; - ASSERT((char *)entry_s + tmp <= (char *)leaf_s + XFS_LBSIZE(mp)); - memset((char *)entry_s, 0, tmp); - } - - /* - * Fill in the freemap information - */ - INT_SET(hdr_d->freemap[0].base, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_hdr_t)); - INT_MOD(hdr_d->freemap[0].base, ARCH_CONVERT, INT_GET(hdr_d->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t)); - INT_SET(hdr_d->freemap[0].size, ARCH_CONVERT, INT_GET(hdr_d->firstused, ARCH_CONVERT) - INT_GET(hdr_d->freemap[0].base, ARCH_CONVERT)); - INT_SET(hdr_d->freemap[1].base, ARCH_CONVERT, (hdr_d->freemap[2].base = 0)); - INT_SET(hdr_d->freemap[1].size, ARCH_CONVERT, (hdr_d->freemap[2].size = 0)); - hdr_s->holes = 1; /* leaf may not be compact */ -} - -/* - * Compare two leaf blocks "order". - */ -int -xfs_dir_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp) -{ - xfs_dir_leafblock_t *leaf1, *leaf2; - - leaf1 = leaf1_bp->data; - leaf2 = leaf2_bp->data; - ASSERT((INT_GET(leaf1->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC) && - (INT_GET(leaf2->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC)); - if ((INT_GET(leaf1->hdr.count, ARCH_CONVERT) > 0) && (INT_GET(leaf2->hdr.count, ARCH_CONVERT) > 0) && - ((INT_GET(leaf2->entries[ 0 ].hashval, ARCH_CONVERT) < - INT_GET(leaf1->entries[ 0 ].hashval, ARCH_CONVERT)) || - (INT_GET(leaf2->entries[ INT_GET(leaf2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) < - INT_GET(leaf1->entries[ INT_GET(leaf1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)))) { - return(1); - } - return(0); -} - -/* - * Pick up the last hashvalue from a leaf block. - */ -xfs_dahash_t -xfs_dir_leaf_lasthash(xfs_dabuf_t *bp, int *count) -{ - xfs_dir_leafblock_t *leaf; - - leaf = bp->data; - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - if (count) - *count = INT_GET(leaf->hdr.count, ARCH_CONVERT); - if (!leaf->hdr.count) - return(0); - return(INT_GET(leaf->entries[ INT_GET(leaf->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)); -} diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c index a7bd9427b..26d4cc292 100644 --- a/libxfs/xfs_ialloc.c +++ b/libxfs/xfs_ialloc.c @@ -88,6 +88,16 @@ xfs_ialloc_log_di( /* * Allocation group level functions. */ +static inline int +xfs_ialloc_cluster_alignment( + xfs_alloc_arg_t *args) +{ + if (xfs_sb_version_hasalign(&args->mp->m_sb) && + args->mp->m_sb.sb_inoalignmt >= + XFS_B_TO_FSBT(args->mp, XFS_INODE_CLUSTER_SIZE(args->mp))) + return args->mp->m_sb.sb_inoalignmt; + return 1; +} /* * Allocate new inodes in the allocation group specified by agbp. @@ -104,6 +114,7 @@ xfs_ialloc_ag_alloc( int blks_per_cluster; /* fs blocks per inode cluster */ xfs_btree_cur_t *cur; /* inode btree cursor */ xfs_daddr_t d; /* disk addr of buffer */ + xfs_agnumber_t agno; int error; xfs_buf_t *fbuf; /* new free inodes' buffer */ xfs_dinode_t *free; /* new free inode structure */ @@ -115,10 +126,9 @@ xfs_ialloc_ag_alloc( int ninodes; /* num inodes per buf */ xfs_agino_t thisino; /* current inode number, for loop */ int version; /* inode version number to use */ - int isaligned; /* inode allocation at stripe unit */ + int isaligned = 0; /* inode allocation at stripe unit */ /* boundary */ - xfs_dinode_core_t dic; /* a dinode_core to copy to new */ - /* inodes */ + unsigned int gen; args.tp = tp; args.mp = tp->t_mountp; @@ -133,46 +143,84 @@ xfs_ialloc_ag_alloc( return XFS_ERROR(ENOSPC); args.minlen = args.maxlen = XFS_IALLOC_BLOCKS(args.mp); /* - * Set the alignment for the allocation. - * If stripe alignment is turned on then align at stripe unit - * boundary. - * If the cluster size is smaller than a filesystem block - * then we're doing I/O for inodes in filesystem block size pieces, - * so don't need alignment anyway. - */ - isaligned = 0; - if (args.mp->m_sinoalign) { - ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN)); - args.alignment = args.mp->m_dalign; - isaligned = 1; - } else if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) && - args.mp->m_sb.sb_inoalignmt >= - XFS_B_TO_FSBT(args.mp, XFS_INODE_CLUSTER_SIZE(args.mp))) - args.alignment = args.mp->m_sb.sb_inoalignmt; - else - args.alignment = 1; + * First try to allocate inodes contiguous with the last-allocated + * chunk of inodes. If the filesystem is striped, this will fill + * an entire stripe unit with inodes. + */ agi = XFS_BUF_TO_AGI(agbp); - /* - * Need to figure out where to allocate the inode blocks. - * Ideally they should be spaced out through the a.g. - * For now, just allocate blocks up front. - */ - args.agbno = be32_to_cpu(agi->agi_root); - args.fsbno = XFS_AGB_TO_FSB(args.mp, be32_to_cpu(agi->agi_seqno), - args.agbno); - /* - * Allocate a fixed-size extent of inodes. - */ - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.mod = args.total = args.wasdel = args.isfl = args.userdata = - args.minalignslop = 0; - args.prod = 1; - /* - * Allow space for the inode btree to split. - */ - args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1; - if ((error = xfs_alloc_vextent(&args))) - return error; + newino = be32_to_cpu(agi->agi_newino); + args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) + + XFS_IALLOC_BLOCKS(args.mp); + if (likely(newino != NULLAGINO && + (args.agbno < be32_to_cpu(agi->agi_length)))) { + args.fsbno = XFS_AGB_TO_FSB(args.mp, + be32_to_cpu(agi->agi_seqno), args.agbno); + args.type = XFS_ALLOCTYPE_THIS_BNO; + args.mod = args.total = args.wasdel = args.isfl = + args.userdata = args.minalignslop = 0; + args.prod = 1; + + /* + * We need to take into account alignment here to ensure that + * we don't modify the free list if we fail to have an exact + * block. If we don't have an exact match, and every oher + * attempt allocation attempt fails, we'll end up cancelling + * a dirty transaction and shutting down. + * + * For an exact allocation, alignment must be 1, + * however we need to take cluster alignment into account when + * fixing up the freelist. Use the minalignslop field to + * indicate that extra blocks might be required for alignment, + * but not to use them in the actual exact allocation. + */ + args.alignment = 1; + args.minalignslop = xfs_ialloc_cluster_alignment(&args) - 1; + + /* Allow space for the inode btree to split. */ + args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1; + if ((error = xfs_alloc_vextent(&args))) + return error; + } else + args.fsbno = NULLFSBLOCK; + + if (unlikely(args.fsbno == NULLFSBLOCK)) { + /* + * Set the alignment for the allocation. + * If stripe alignment is turned on then align at stripe unit + * boundary. + * If the cluster size is smaller than a filesystem block + * then we're doing I/O for inodes in filesystem block size + * pieces, so don't need alignment anyway. + */ + isaligned = 0; + if (args.mp->m_sinoalign) { + ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN)); + args.alignment = args.mp->m_dalign; + isaligned = 1; + } else + args.alignment = xfs_ialloc_cluster_alignment(&args); + /* + * Need to figure out where to allocate the inode blocks. + * Ideally they should be spaced out through the a.g. + * For now, just allocate blocks up front. + */ + args.agbno = be32_to_cpu(agi->agi_root); + args.fsbno = XFS_AGB_TO_FSB(args.mp, + be32_to_cpu(agi->agi_seqno), args.agbno); + /* + * Allocate a fixed-size extent of inodes. + */ + args.type = XFS_ALLOCTYPE_NEAR_BNO; + args.mod = args.total = args.wasdel = args.isfl = + args.userdata = args.minalignslop = 0; + args.prod = 1; + /* + * Allow space for the inode btree to split. + */ + args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1; + if ((error = xfs_alloc_vextent(&args))) + return error; + } /* * If stripe alignment is turned on, then try again with cluster @@ -183,12 +231,7 @@ xfs_ialloc_ag_alloc( args.agbno = be32_to_cpu(agi->agi_root); args.fsbno = XFS_AGB_TO_FSB(args.mp, be32_to_cpu(agi->agi_seqno), args.agbno); - if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) && - args.mp->m_sb.sb_inoalignmt >= - XFS_B_TO_FSBT(args.mp, XFS_INODE_CLUSTER_SIZE(args.mp))) - args.alignment = args.mp->m_sb.sb_inoalignmt; - else - args.alignment = 1; + args.alignment = xfs_ialloc_cluster_alignment(&args); if ((error = xfs_alloc_vextent(&args))) return error; } @@ -224,15 +267,19 @@ xfs_ialloc_ag_alloc( * use the old version so that old kernels will continue to be * able to use the file system. */ - if (XFS_SB_VERSION_HASNLINK(&args.mp->m_sb)) + if (xfs_sb_version_hasnlink(&args.mp->m_sb)) version = XFS_DINODE_VERSION_2; else version = XFS_DINODE_VERSION_1; - memset(&dic, 0, sizeof(xfs_dinode_core_t)); - INT_SET(dic.di_magic, ARCH_CONVERT, XFS_DINODE_MAGIC); - INT_SET(dic.di_version, ARCH_CONVERT, version); - + /* + * Seed the new inode cluster with a random generation number. This + * prevents short-term reuse of generation numbers if a chunk is + * freed and then immediately reallocated. We use random numbers + * rather than a linear progression to prevent the next generation + * number from being easily guessable. + */ + gen = random32(); for (j = 0; j < nbufs; j++) { /* * Get the block. @@ -245,29 +292,31 @@ xfs_ialloc_ag_alloc( ASSERT(fbuf); ASSERT(!XFS_BUF_GETERROR(fbuf)); /* - * Loop over the inodes in this buffer. + * Set initial values for the inodes in this buffer. */ - + xfs_biozero(fbuf, 0, ninodes << args.mp->m_sb.sb_inodelog); for (i = 0; i < ninodes; i++) { free = XFS_MAKE_IPTR(args.mp, fbuf, i); - memcpy(&(free->di_core), &dic, sizeof(xfs_dinode_core_t)); - INT_SET(free->di_next_unlinked, ARCH_CONVERT, NULLAGINO); + free->di_core.di_magic = cpu_to_be16(XFS_DINODE_MAGIC); + free->di_core.di_version = version; + free->di_core.di_gen = cpu_to_be32(gen); + free->di_next_unlinked = cpu_to_be32(NULLAGINO); xfs_ialloc_log_di(tp, fbuf, i, XFS_DI_CORE_BITS | XFS_DI_NEXT_UNLINKED); } xfs_trans_inode_alloc_buf(tp, fbuf); } - be32_add(&agi->agi_count, newlen); - be32_add(&agi->agi_freecount, newlen); + be32_add_cpu(&agi->agi_count, newlen); + be32_add_cpu(&agi->agi_freecount, newlen); + agno = be32_to_cpu(agi->agi_seqno); down_read(&args.mp->m_peraglock); - args.mp->m_perag[be32_to_cpu(agi->agi_seqno)].pagi_freecount += newlen; + args.mp->m_perag[agno].pagi_freecount += newlen; up_read(&args.mp->m_peraglock); agi->agi_newino = cpu_to_be32(newino); /* * Insert records describing the new inode chunk into the btree. */ - cur = xfs_btree_init_cursor(args.mp, tp, agbp, - be32_to_cpu(agi->agi_seqno), + cur = xfs_btree_init_cursor(args.mp, tp, agbp, agno, XFS_BTNUM_INO, (xfs_inode_t *)0, 0); for (thisino = newino; thisino < newino + newlen; @@ -299,7 +348,7 @@ xfs_ialloc_ag_alloc( return 0; } -STATIC __inline xfs_agnumber_t +STATIC_INLINE xfs_agnumber_t xfs_ialloc_next_ag( xfs_mount_t *mp) { @@ -415,7 +464,7 @@ nextag: */ if (XFS_FORCED_SHUTDOWN(mp)) { up_read(&mp->m_peraglock); - return (xfs_buf_t *)0; + return NULL; } agno++; if (agno >= agcount) @@ -423,7 +472,7 @@ nextag: if (agno == pagno) { if (flags == 0) { up_read(&mp->m_peraglock); - return (xfs_buf_t *)0; + return NULL; } flags = 0; } @@ -486,10 +535,10 @@ xfs_dialloc( int offset; /* index of inode in chunk */ xfs_agino_t pagino; /* parent's a.g. relative inode # */ xfs_agnumber_t pagno; /* parent's allocation group number */ - xfs_inobt_rec_t rec; /* inode allocation record */ + xfs_inobt_rec_incore_t rec; /* inode allocation record */ xfs_agnumber_t tagno; /* testing allocation group number */ xfs_btree_cur_t *tcur; /* temp cursor */ - xfs_inobt_rec_t trec; /* temp inode allocation record */ + xfs_inobt_rec_incore_t trec; /* temp inode allocation record */ if (*IO_agbp == NULL) { @@ -841,7 +890,7 @@ nextag: if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount, rec.ir_free))) goto error0; - be32_add(&agi->agi_freecount, -1); + be32_add_cpu(&agi->agi_freecount, -1); xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); down_read(&mp->m_peraglock); mp->m_perag[tagno].pagi_freecount--; @@ -917,6 +966,9 @@ xfs_dilocate( if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks || ino != XFS_AGINO_TO_INO(mp, agno, agino)) { #ifdef DEBUG + /* no diagnostics for bulkstat, ino comes from userspace */ + if (flags & XFS_IMAP_BULKSTAT) + return XFS_ERROR(EINVAL); if (agno >= mp->m_sb.sb_agcount) { xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: agno (%d) >= " @@ -937,6 +989,7 @@ xfs_dilocate( "(0x%llx)", ino, XFS_AGINO_TO_INO(mp, agno, agino)); } + xfs_stack_trace(); #endif /* DEBUG */ return XFS_ERROR(EINVAL); } @@ -1136,7 +1189,6 @@ xfs_ialloc_read_agi( * we are in the middle of a forced shutdown. */ ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) || - pag->pagi_count == be32_to_cpu(agi->agi_count) || XFS_FORCED_SHUTDOWN(mp)); } @@ -1166,7 +1218,8 @@ xfs_ialloc_pagi_init( xfs_buf_t *bp = NULL; int error; - if ((error = xfs_ialloc_read_agi(mp, tp, agno, &bp))) + error = xfs_ialloc_read_agi(mp, tp, agno, &bp); + if (error) return error; if (bp) xfs_trans_brelse(tp, bp); diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c index beaf5398e..39c39329e 100644 --- a/libxfs/xfs_ialloc_btree.c +++ b/libxfs/xfs_ialloc_btree.c @@ -15,13 +15,19 @@ * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -/* - * Inode allocation management for XFS. - */ - #include +STATIC void xfs_inobt_log_block(xfs_trans_t *, xfs_buf_t *, int); +STATIC void xfs_inobt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int); +STATIC void xfs_inobt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int); +STATIC void xfs_inobt_log_recs(xfs_btree_cur_t *, xfs_buf_t *, int, int); +STATIC int xfs_inobt_lshift(xfs_btree_cur_t *, int, int *); +STATIC int xfs_inobt_newroot(xfs_btree_cur_t *, int *); +STATIC int xfs_inobt_rshift(xfs_btree_cur_t *, int, int *); +STATIC int xfs_inobt_split(xfs_btree_cur_t *, int, xfs_agblock_t *, + xfs_inobt_key_t *, xfs_btree_cur_t **, int *); +STATIC int xfs_inobt_updkey(xfs_btree_cur_t *, xfs_inobt_key_t *, int); + /* * Insert one record/level. Return information to the caller * allowing the next level up to proceed if necessary. @@ -71,7 +77,7 @@ xfs_inobt_insrec( /* * Make a key out of the record data to be inserted, and save it. */ - key.ir_startino = recp->ir_startino; /* INT_: direct copy */ + key.ir_startino = recp->ir_startino; optr = ptr = cur->bc_ptrs[level]; /* * If we're off the left edge, return failure. @@ -103,7 +109,7 @@ xfs_inobt_insrec( } #endif nbno = NULLAGBLOCK; - ncur = (xfs_btree_cur_t *)0; + ncur = NULL; /* * If the block is full, we can't insert the new entry until we * make the block un-full. @@ -144,7 +150,7 @@ xfs_inobt_insrec( return error; #endif ptr = cur->bc_ptrs[level]; - nrec.ir_startino = nkey.ir_startino; /* INT_: direct copy */ + nrec.ir_startino = nkey.ir_startino; } else { /* * Otherwise the insert fails. @@ -184,7 +190,7 @@ xfs_inobt_insrec( if ((error = xfs_btree_check_sptr(cur, *bnop, level))) return error; #endif - kp[ptr - 1] = key; /* INT_: struct copy */ + kp[ptr - 1] = key; pp[ptr - 1] = cpu_to_be32(*bnop); numrecs++; block->bb_numrecs = cpu_to_be16(numrecs); @@ -201,7 +207,7 @@ xfs_inobt_insrec( * Now stuff the new record in, bump numrecs * and log the new data. */ - rp[ptr - 1] = *recp; /* INT_: struct copy */ + rp[ptr - 1] = *recp; numrecs++; block->bb_numrecs = cpu_to_be16(numrecs); xfs_inobt_log_recs(cur, bp, ptr, numrecs); @@ -234,7 +240,7 @@ xfs_inobt_insrec( */ *bnop = nbno; if (nbno != NULLAGBLOCK) { - *recp = nrec; /* INT_: struct copy */ + *recp = nrec; *curp = ncur; } *stat = 1; @@ -357,7 +363,7 @@ xfs_inobt_lookup( { xfs_agi_t *agi; /* a.g. inode header */ - agi = XFS_BUF_TO_AGI(cur->bc_private.i.agbp); + agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp); agno = be32_to_cpu(agi->agi_seqno); agbno = be32_to_cpu(agi->agi_root); } @@ -381,7 +387,7 @@ xfs_inobt_lookup( */ bp = cur->bc_bufs[level]; if (bp && XFS_BUF_ADDR(bp) != d) - bp = (xfs_buf_t *)0; + bp = NULL; if (!bp) { /* * Need to get a new buffer. Read it, then @@ -453,12 +459,12 @@ xfs_inobt_lookup( xfs_inobt_key_t *kkp; kkp = kkbase + keyno - 1; - startino = INT_GET(kkp->ir_startino, ARCH_CONVERT); + startino = be32_to_cpu(kkp->ir_startino); } else { xfs_inobt_rec_t *krp; krp = krbase + keyno - 1; - startino = INT_GET(krp->ir_startino, ARCH_CONVERT); + startino = be32_to_cpu(krp->ir_startino); } /* * Compute difference to get next direction. @@ -592,7 +598,7 @@ xfs_inobt_lshift( * Set up the left neighbor as "left". */ if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp, - cur->bc_private.i.agno, be32_to_cpu(right->bb_leftsib), + cur->bc_private.a.agno, be32_to_cpu(right->bb_leftsib), 0, &lbp, XFS_INO_BTREE_REF))) return error; left = XFS_BUF_TO_INOBT_BLOCK(lbp); @@ -620,7 +626,7 @@ xfs_inobt_lshift( if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level))) return error; #endif - *lpp = *rpp; /* INT_: no-change copy */ + *lpp = *rpp; xfs_inobt_log_ptrs(cur, lbp, nrec, nrec); } /* @@ -635,7 +641,7 @@ xfs_inobt_lshift( /* * Bump and log left's numrecs, decrement and log right's numrecs. */ - be16_add(&left->bb_numrecs, 1); + be16_add_cpu(&left->bb_numrecs, 1); xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS); #ifdef DEBUG if (level > 0) @@ -643,7 +649,7 @@ xfs_inobt_lshift( else xfs_btree_check_rec(cur->bc_btnum, lrp - 1, lrp); #endif - be16_add(&right->bb_numrecs, -1); + be16_add_cpu(&right->bb_numrecs, -1); xfs_inobt_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS); /* * Slide the contents of right down one entry. @@ -663,7 +669,7 @@ xfs_inobt_lshift( } else { memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); - key.ir_startino = rrp->ir_startino; /* INT_: direct copy */ + key.ir_startino = rrp->ir_startino; rkp = &key; } /* @@ -710,10 +716,10 @@ xfs_inobt_newroot( /* * Get a block & a buffer. */ - agi = XFS_BUF_TO_AGI(cur->bc_private.i.agbp); + agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp); args.tp = cur->bc_tp; args.mp = cur->bc_mp; - args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.i.agno, + args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, be32_to_cpu(agi->agi_root)); args.mod = args.minleft = args.alignment = args.total = args.wasdel = args.isfl = args.userdata = args.minalignslop = 0; @@ -735,8 +741,8 @@ xfs_inobt_newroot( * Set the root data in the a.g. inode structure. */ agi->agi_root = cpu_to_be32(args.agbno); - be32_add(&agi->agi_level, 1); - xfs_ialloc_log_agi(args.tp, cur->bc_private.i.agbp, + be32_add_cpu(&agi->agi_level, 1); + xfs_ialloc_log_agi(args.tp, cur->bc_private.a.agbp, XFS_AGI_ROOT | XFS_AGI_LEVEL); /* * At the previous root level there are now two blocks: the old @@ -800,13 +806,13 @@ xfs_inobt_newroot( */ kp = XFS_INOBT_KEY_ADDR(new, 1, cur); if (be16_to_cpu(left->bb_level) > 0) { - kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur); /* INT_: struct copy */ - kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur); /* INT_: struct copy */ + kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur); + kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur); } else { rp = XFS_INOBT_REC_ADDR(left, 1, cur); - INT_COPY(kp[0].ir_startino, rp->ir_startino, ARCH_CONVERT); + kp[0].ir_startino = rp->ir_startino; rp = XFS_INOBT_REC_ADDR(right, 1, cur); - INT_COPY(kp[1].ir_startino, rp->ir_startino, ARCH_CONVERT); + kp[1].ir_startino = rp->ir_startino; } xfs_inobt_log_keys(cur, nbp, 1, 2); /* @@ -879,7 +885,7 @@ xfs_inobt_rshift( * Set up the right neighbor as "right". */ if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp, - cur->bc_private.i.agno, be32_to_cpu(left->bb_rightsib), + cur->bc_private.a.agno, be32_to_cpu(left->bb_rightsib), 0, &rbp, XFS_INO_BTREE_REF))) return error; right = XFS_BUF_TO_INOBT_BLOCK(rbp); @@ -913,8 +919,8 @@ xfs_inobt_rshift( if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level))) return error; #endif - *rkp = *lkp; /* INT_: no change copy */ - *rpp = *lpp; /* INT_: no change copy */ + *rkp = *lkp; + *rpp = *lpp; xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); } else { @@ -923,15 +929,15 @@ xfs_inobt_rshift( memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); *rrp = *lrp; xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); - key.ir_startino = rrp->ir_startino; /* INT_: direct copy */ + key.ir_startino = rrp->ir_startino; rkp = &key; } /* * Decrement and log left's numrecs, bump and log right's numrecs. */ - be16_add(&left->bb_numrecs, -1); + be16_add_cpu(&left->bb_numrecs, -1); xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS); - be16_add(&right->bb_numrecs, 1); + be16_add_cpu(&right->bb_numrecs, 1); #ifdef DEBUG if (level > 0) xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1); @@ -995,7 +1001,7 @@ xfs_inobt_split( * Allocate the new block. * If we can't do it, we're toast. Give up. */ - args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.i.agno, lbno); + args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, lbno); args.mod = args.minleft = args.alignment = args.total = args.wasdel = args.isfl = args.userdata = args.minalignslop = 0; args.minlen = args.maxlen = args.prod = 1; @@ -1032,7 +1038,7 @@ xfs_inobt_split( */ if ((be16_to_cpu(left->bb_numrecs) & 1) && cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1) - be16_add(&right->bb_numrecs, 1); + be16_add_cpu(&right->bb_numrecs, 1); i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1; /* * For non-leaf blocks, copy keys and addresses over to the new block. @@ -1062,13 +1068,13 @@ xfs_inobt_split( rrp = XFS_INOBT_REC_ADDR(right, 1, cur); memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); - keyp->ir_startino = rrp->ir_startino; /* INT_: direct copy */ + keyp->ir_startino = rrp->ir_startino; } /* * Find the left block number by looking in the buffer. * Adjust numrecs, sibling pointers. */ - be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); + be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); right->bb_rightsib = left->bb_rightsib; left->bb_rightsib = cpu_to_be32(args.agbno); right->bb_leftsib = cpu_to_be32(lbno); @@ -1228,7 +1234,7 @@ xfs_inobt_decrement( agbno = be32_to_cpu(*XFS_INOBT_PTR_ADDR(block, cur->bc_ptrs[lev], cur)); if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp, - cur->bc_private.i.agno, agbno, 0, &bp, + cur->bc_private.a.agno, agbno, 0, &bp, XFS_INO_BTREE_REF))) return error; lev--; @@ -1279,9 +1285,9 @@ xfs_inobt_get_rec( * Point to the record and extract its data. */ rec = XFS_INOBT_REC_ADDR(block, ptr, cur); - *ino = INT_GET(rec->ir_startino, ARCH_CONVERT); - *fcnt = INT_GET(rec->ir_freecount, ARCH_CONVERT); - *free = INT_GET(rec->ir_free, ARCH_CONVERT); + *ino = be32_to_cpu(rec->ir_startino); + *fcnt = be32_to_cpu(rec->ir_freecount); + *free = be64_to_cpu(rec->ir_free); *stat = 1; return 0; } @@ -1363,7 +1369,7 @@ xfs_inobt_increment( agbno = be32_to_cpu(*XFS_INOBT_PTR_ADDR(block, cur->bc_ptrs[lev], cur)); if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp, - cur->bc_private.i.agno, agbno, 0, &bp, + cur->bc_private.a.agno, agbno, 0, &bp, XFS_INO_BTREE_REF))) return error; lev--; @@ -1396,10 +1402,10 @@ xfs_inobt_insert( level = 0; nbno = NULLAGBLOCK; - INT_SET(nrec.ir_startino, ARCH_CONVERT, cur->bc_rec.i.ir_startino); - INT_SET(nrec.ir_freecount, ARCH_CONVERT, cur->bc_rec.i.ir_freecount); - INT_SET(nrec.ir_free, ARCH_CONVERT, cur->bc_rec.i.ir_free); - ncur = (xfs_btree_cur_t *)0; + nrec.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino); + nrec.ir_freecount = cpu_to_be32(cur->bc_rec.i.ir_freecount); + nrec.ir_free = cpu_to_be64(cur->bc_rec.i.ir_free); + ncur = NULL; pcur = cur; /* * Loop going up the tree, starting at the leaf level. @@ -1431,7 +1437,7 @@ xfs_inobt_insert( */ if (ncur) { pcur = ncur; - ncur = (xfs_btree_cur_t *)0; + ncur = NULL; } } while (nbno != NULLAGBLOCK); *stat = i; @@ -1526,9 +1532,9 @@ xfs_inobt_update( /* * Fill in the new contents and log them. */ - INT_SET(rp->ir_startino, ARCH_CONVERT, ino); - INT_SET(rp->ir_freecount, ARCH_CONVERT, fcnt); - INT_SET(rp->ir_free, ARCH_CONVERT, free); + rp->ir_startino = cpu_to_be32(ino); + rp->ir_freecount = cpu_to_be32(fcnt); + rp->ir_free = cpu_to_be64(free); xfs_inobt_log_recs(cur, bp, ptr, ptr); /* * Updating first record in leaf. Pass new key value up to our parent. @@ -1536,7 +1542,7 @@ xfs_inobt_update( if (ptr == 1) { xfs_inobt_key_t key; /* key containing [ino] */ - INT_SET(key.ir_startino, ARCH_CONVERT, ino); + key.ir_startino = cpu_to_be32(ino); if ((error = xfs_inobt_updkey(cur, &key, 1))) return error; } diff --git a/libxfs/xfs_inode.c b/libxfs/xfs_inode.c index 844b9baaa..790909fe9 100644 --- a/libxfs/xfs_inode.c +++ b/libxfs/xfs_inode.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -18,10 +18,46 @@ #include -xfs_zone_t *xfs_ifork_zone; -xfs_zone_t *xfs_inode_zone; +kmem_zone_t *xfs_ifork_zone; +kmem_zone_t *xfs_inode_zone; + +STATIC int xfs_iformat_local(xfs_inode_t *, xfs_dinode_t *, int, int); +STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int); +STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int); #ifdef DEBUG +/* + * Make sure that the extents in the given memory buffer + * are valid. + */ +STATIC void +xfs_validate_extents( + xfs_ifork_t *ifp, + int nrecs, + xfs_exntfmt_t fmt) +{ + xfs_bmbt_irec_t irec; + xfs_bmbt_rec_host_t rec; + int i; + + for (i = 0; i < nrecs; i++) { + xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); + rec.l0 = get_unaligned(&ep->l0); + rec.l1 = get_unaligned(&ep->l1); + xfs_bmbt_get_all(&rec, &irec); + if (fmt == XFS_EXTFMT_NOSTATE) + ASSERT(irec.br_state == XFS_EXT_NORM); + } +} +#else /* DEBUG */ +#define xfs_validate_extents(ifp, nrecs, fmt) +#endif /* DEBUG */ + +/* + * Check that none of the inode's in the buffer have a next + * unlinked field of 0. + */ +#if defined(DEBUG) void xfs_inobp_check( xfs_mount_t *mp, @@ -46,6 +82,89 @@ xfs_inobp_check( } #endif +/* + * Find the buffer associated with the given inode map + * We do basic validation checks on the buffer once it has been + * retrieved from disk. + */ +STATIC int +xfs_imap_to_bp( + xfs_mount_t *mp, + xfs_trans_t *tp, + xfs_imap_t *imap, + xfs_buf_t **bpp, + uint buf_flags, + uint imap_flags) +{ + int error; + int i; + int ni; + xfs_buf_t *bp; + + error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno, + (int)imap->im_len, buf_flags, &bp); + if (error) { + if (error != EAGAIN) { + cmn_err(CE_WARN, + "xfs_imap_to_bp: xfs_trans_read_buf()returned " + "an error %d on %s. Returning error.", + error, mp->m_fsname); + } else { + ASSERT(buf_flags & XFS_BUF_TRYLOCK); + } + return error; + } + + /* + * Validate the magic number and version of every inode in the buffer + * (if DEBUG kernel) or the first inode in the buffer, otherwise. + */ +#ifdef DEBUG + ni = BBTOB(imap->im_len) >> mp->m_sb.sb_inodelog; +#else /* usual case */ + ni = 1; +#endif + + for (i = 0; i < ni; i++) { + int di_ok; + xfs_dinode_t *dip; + + dip = (xfs_dinode_t *)xfs_buf_offset(bp, + (i << mp->m_sb.sb_inodelog)); + di_ok = be16_to_cpu(dip->di_core.di_magic) == XFS_DINODE_MAGIC && + XFS_DINODE_GOOD_VERSION(dip->di_core.di_version); + if (unlikely(XFS_TEST_ERROR(!di_ok, mp, + XFS_ERRTAG_ITOBP_INOTOBP, + XFS_RANDOM_ITOBP_INOTOBP))) { + if (imap_flags & XFS_IMAP_BULKSTAT) { + xfs_trans_brelse(tp, bp); + return XFS_ERROR(EINVAL); + } + XFS_CORRUPTION_ERROR("xfs_imap_to_bp", + XFS_ERRLEVEL_HIGH, mp, dip); +#ifdef DEBUG + cmn_err(CE_PANIC, + "Device %s - bad inode magic/vsn " + "daddr %lld #%d (magic=%x)", + XFS_BUFTARG_NAME(mp->m_ddev_targp), + (unsigned long long)imap->im_blkno, i, + be16_to_cpu(dip->di_core.di_magic)); +#endif + xfs_trans_brelse(tp, bp); + return XFS_ERROR(EFSCORRUPTED); + } + } + + xfs_inobp_check(mp, bp); + + /* + * Mark the buffer as an inode buffer now that it looks good + */ + XFS_BUF_SET_VTYPE(bp, B_FS_INO); + + *bpp = bp; + return 0; +} /* * This routine is called to map an inode to the buffer containing @@ -74,47 +193,20 @@ xfs_itobp( xfs_inode_t *ip, xfs_dinode_t **dipp, xfs_buf_t **bpp, - xfs_daddr_t bno) + xfs_daddr_t bno, + uint imap_flags, + uint buf_flags) { + xfs_imap_t imap; xfs_buf_t *bp; int error; - xfs_imap_t imap; -#ifdef __KERNEL__ - int i; - int ni; -#endif if (ip->i_blkno == (xfs_daddr_t)0) { - /* - * Call the space management code to find the location of the - * inode on disk. - */ imap.im_blkno = bno; - error = xfs_imap(mp, tp, ip->i_ino, &imap, XFS_IMAP_LOOKUP); - if (error != 0) { + error = xfs_imap(mp, tp, ip->i_ino, &imap, + XFS_IMAP_LOOKUP | imap_flags); + if (error) return error; - } - - /* - * If the inode number maps to a block outside the bounds - * of the file system then return NULL rather than calling - * read_buf and panicing when we get an error from the - * driver. - */ - if ((imap.im_blkno + imap.im_len) > - XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)) { -#ifdef DEBUG - xfs_fs_cmn_err(CE_ALERT, mp, "xfs_itobp: " - "(imap.im_blkno (0x%llx) " - "+ imap.im_len (0x%llx)) > " - " XFS_FSB_TO_BB(mp, " - "mp->m_sb.sb_dblocks) (0x%llx)", - (unsigned long long) imap.im_blkno, - (unsigned long long) imap.im_len, - XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)); -#endif /* DEBUG */ - return XFS_ERROR(EINVAL); - } /* * Fill in the fields in the inode that will be used to @@ -134,67 +226,17 @@ xfs_itobp( } ASSERT(bno == 0 || bno == imap.im_blkno); - /* - * Read in the buffer. If tp is NULL, xfs_trans_read_buf() will - * default to just a read_buf() call. - */ - error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap.im_blkno, - (int)imap.im_len, XFS_BUF_LOCK, &bp); - - if (error) { -#ifdef DEBUG - xfs_fs_cmn_err(CE_ALERT, mp, "xfs_itobp: " - "xfs_trans_read_buf() returned error %d, " - "imap.im_blkno 0x%llx, imap.im_len 0x%llx", - error, (unsigned long long) imap.im_blkno, - (unsigned long long) imap.im_len); -#endif /* DEBUG */ + error = xfs_imap_to_bp(mp, tp, &imap, &bp, buf_flags, imap_flags); + if (error) return error; - } -#ifdef __KERNEL__ - /* - * Validate the magic number and version of every inode in the buffer - * (if DEBUG kernel) or the first inode in the buffer, otherwise. - */ -#ifdef DEBUG - ni = BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog; -#else - ni = 1; -#endif - for (i = 0; i < ni; i++) { - int di_ok; - xfs_dinode_t *dip; - dip = (xfs_dinode_t *)xfs_buf_offset(bp, - (i << mp->m_sb.sb_inodelog)); - di_ok = INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC && - XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT)); - if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, - XFS_RANDOM_ITOBP_INOTOBP))) { -#ifdef DEBUG - prdev("bad inode magic/vsn daddr %lld #%d (magic=%x)", - mp->m_ddev_targp, - (unsigned long long)imap.im_blkno, i, - INT_GET(dip->di_core.di_magic, ARCH_CONVERT)); -#endif - XFS_CORRUPTION_ERROR("xfs_itobp", XFS_ERRLEVEL_HIGH, - mp, dip); - xfs_trans_brelse(tp, bp); - return XFS_ERROR(EFSCORRUPTED); - } + if (!bp) { + ASSERT(buf_flags & XFS_BUF_TRYLOCK); + ASSERT(tp == NULL); + *bpp = NULL; + return EAGAIN; } -#endif /* __KERNEL__ */ - - xfs_inobp_check(mp, bp); - /* - * Mark the buffer as an inode buffer now that it looks good - */ - XFS_BUF_SET_VTYPE(bp, B_FS_INO); - - /* - * Set *dipp to point to the on-disk inode in the buffer. - */ *dipp = (xfs_dinode_t *)xfs_buf_offset(bp, imap.im_boffset); *bpp = bp; return 0; @@ -208,8 +250,10 @@ xfs_itobp( * pointers. For a file in B-tree format, only the root is immediately * brought in-core. The rest will be in-lined in if_extents when it * is first referenced (see xfs_iread_extents()). + * + * Note: this requires user-space public scope for libxfs_iread */ -STATIC int +int xfs_iformat( xfs_inode_t *ip, xfs_dinode_t *dip) @@ -222,27 +266,26 @@ xfs_iformat( XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); error = 0; - if (unlikely( - INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) + - INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) > - INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT))) { + if (unlikely(be32_to_cpu(dip->di_core.di_nextents) + + be16_to_cpu(dip->di_core.di_anextents) > + be64_to_cpu(dip->di_core.di_nblocks))) { xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.", (unsigned long long)ip->i_ino, - (int)(INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) - + INT_GET(dip->di_core.di_anextents, ARCH_CONVERT)), + (int)(be32_to_cpu(dip->di_core.di_nextents) + + be16_to_cpu(dip->di_core.di_anextents)), (unsigned long long) - INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT)); + be64_to_cpu(dip->di_core.di_nblocks)); XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW, ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } - if (unlikely(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT) > ip->i_mount->m_sb.sb_inodesize)) { + if (unlikely(dip->di_core.di_forkoff > ip->i_mount->m_sb.sb_inodesize)) { xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, "corrupt dinode %Lu, forkoff = 0x%x.", (unsigned long long)ip->i_ino, - (int)(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT))); + dip->di_core.di_forkoff); XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW, ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); @@ -253,24 +296,25 @@ xfs_iformat( case S_IFCHR: case S_IFBLK: case S_IFSOCK: - if (unlikely(INT_GET(dip->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_DEV)) { + if (unlikely(dip->di_core.di_format != XFS_DINODE_FMT_DEV)) { XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW, ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } ip->i_d.di_size = 0; - ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT); + ip->i_size = 0; + ip->i_df.if_u2.if_rdev = be32_to_cpu(dip->di_u.di_dev); break; case S_IFREG: case S_IFLNK: case S_IFDIR: - switch (INT_GET(dip->di_core.di_format, ARCH_CONVERT)) { + switch (dip->di_core.di_format) { case XFS_DINODE_FMT_LOCAL: /* * no local regular files yet */ - if (unlikely((INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & S_IFMT) == S_IFREG)) { + if (unlikely((be16_to_cpu(dip->di_core.di_mode) & S_IFMT) == S_IFREG)) { xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, "corrupt inode %Lu " "(local format for regular file).", @@ -281,7 +325,7 @@ xfs_iformat( return XFS_ERROR(EFSCORRUPTED); } - di_size = INT_GET(dip->di_core.di_size, ARCH_CONVERT); + di_size = be64_to_cpu(dip->di_core.di_size); if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) { xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, "corrupt inode %Lu " @@ -323,10 +367,10 @@ xfs_iformat( ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP); ip->i_afp->if_ext_max = XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); - switch (INT_GET(dip->di_core.di_aformat, ARCH_CONVERT)) { + switch (dip->di_core.di_aformat) { case XFS_DINODE_FMT_LOCAL: atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); - size = (int)INT_GET(atp->hdr.totsize, ARCH_CONVERT); + size = be16_to_cpu(atp->hdr.totsize); error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size); break; case XFS_DINODE_FMT_EXTENTS: @@ -416,10 +460,9 @@ xfs_iformat_extents( xfs_dinode_t *dip, int whichfork) { - xfs_bmbt_rec_t *ep, *dp; + xfs_bmbt_rec_t *dp; xfs_ifork_t *ifp; int nex; - int real_size; int size; int i; @@ -441,34 +484,28 @@ xfs_iformat_extents( return XFS_ERROR(EFSCORRUPTED); } - real_size = 0; + ifp->if_real_bytes = 0; if (nex == 0) ifp->if_u1.if_extents = NULL; else if (nex <= XFS_INLINE_EXTS) ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; - else { - ifp->if_u1.if_extents = kmem_alloc(size, KM_SLEEP); - ASSERT(ifp->if_u1.if_extents != NULL); - real_size = size; - } + else + xfs_iext_add(ifp, 0, nex); + ifp->if_bytes = size; - ifp->if_real_bytes = real_size; if (size) { dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork); - xfs_validate_extents(dp, nex, 1, XFS_EXTFMT_INODE(ip)); - ep = ifp->if_u1.if_extents; - for (i = 0; i < nex; i++, ep++, dp++) { - ep->l0 = INT_GET(get_unaligned((__uint64_t*)&dp->l0), - ARCH_CONVERT); - ep->l1 = INT_GET(get_unaligned((__uint64_t*)&dp->l1), - ARCH_CONVERT); + xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip)); + for (i = 0; i < nex; i++, dp++) { + xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); + ep->l0 = get_unaligned_be64(&dp->l0); + ep->l1 = get_unaligned_be64(&dp->l1); } - xfs_bmap_trace_exlist("xfs_iformat_extents", ip, nex, - whichfork); + XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork); if (whichfork != XFS_DATA_FORK || XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE) if (unlikely(xfs_check_nostate_extents( - ifp->if_u1.if_extents, nex))) { + ifp, 0, nex))) { XFS_ERROR_REPORT("xfs_iformat_extents(2)", XFS_ERRLEVEL_LOW, ip->i_mount); @@ -538,71 +575,74 @@ xfs_iformat_btree( return 0; } -/* - * xfs_xlate_dinode_core - translate an xfs_inode_core_t between ondisk - * and native format - * - * buf = on-disk representation - * dip = native representation - * dir = direction - +ve -> disk to native - * -ve -> native to disk - * arch = on-disk architecture - */ void -xfs_xlate_dinode_core( - xfs_caddr_t buf, - xfs_dinode_core_t *dip, - int dir) +xfs_dinode_from_disk( + xfs_icdinode_t *to, + xfs_dinode_core_t *from) { - xfs_dinode_core_t *buf_core = (xfs_dinode_core_t *)buf; - xfs_dinode_core_t *mem_core = (xfs_dinode_core_t *)dip; - xfs_arch_t arch = ARCH_CONVERT; - - ASSERT(dir); - - INT_XLATE(buf_core->di_magic, mem_core->di_magic, dir, arch); - INT_XLATE(buf_core->di_mode, mem_core->di_mode, dir, arch); - INT_XLATE(buf_core->di_version, mem_core->di_version, dir, arch); - INT_XLATE(buf_core->di_format, mem_core->di_format, dir, arch); - INT_XLATE(buf_core->di_onlink, mem_core->di_onlink, dir, arch); - INT_XLATE(buf_core->di_uid, mem_core->di_uid, dir, arch); - INT_XLATE(buf_core->di_gid, mem_core->di_gid, dir, arch); - INT_XLATE(buf_core->di_nlink, mem_core->di_nlink, dir, arch); - INT_XLATE(buf_core->di_projid, mem_core->di_projid, dir, arch); - - if (dir > 0) { - memcpy(mem_core->di_pad, buf_core->di_pad, - sizeof(buf_core->di_pad)); - } else { - memcpy(buf_core->di_pad, mem_core->di_pad, - sizeof(buf_core->di_pad)); - } - - INT_XLATE(buf_core->di_flushiter, mem_core->di_flushiter, dir, arch); - - INT_XLATE(buf_core->di_atime.t_sec, mem_core->di_atime.t_sec, - dir, arch); - INT_XLATE(buf_core->di_atime.t_nsec, mem_core->di_atime.t_nsec, - dir, arch); - INT_XLATE(buf_core->di_mtime.t_sec, mem_core->di_mtime.t_sec, - dir, arch); - INT_XLATE(buf_core->di_mtime.t_nsec, mem_core->di_mtime.t_nsec, - dir, arch); - INT_XLATE(buf_core->di_ctime.t_sec, mem_core->di_ctime.t_sec, - dir, arch); - INT_XLATE(buf_core->di_ctime.t_nsec, mem_core->di_ctime.t_nsec, - dir, arch); - INT_XLATE(buf_core->di_size, mem_core->di_size, dir, arch); - INT_XLATE(buf_core->di_nblocks, mem_core->di_nblocks, dir, arch); - INT_XLATE(buf_core->di_extsize, mem_core->di_extsize, dir, arch); - INT_XLATE(buf_core->di_nextents, mem_core->di_nextents, dir, arch); - INT_XLATE(buf_core->di_anextents, mem_core->di_anextents, dir, arch); - INT_XLATE(buf_core->di_forkoff, mem_core->di_forkoff, dir, arch); - INT_XLATE(buf_core->di_aformat, mem_core->di_aformat, dir, arch); - INT_XLATE(buf_core->di_dmevmask, mem_core->di_dmevmask, dir, arch); - INT_XLATE(buf_core->di_dmstate, mem_core->di_dmstate, dir, arch); - INT_XLATE(buf_core->di_flags, mem_core->di_flags, dir, arch); - INT_XLATE(buf_core->di_gen, mem_core->di_gen, dir, arch); + to->di_magic = be16_to_cpu(from->di_magic); + to->di_mode = be16_to_cpu(from->di_mode); + to->di_version = from ->di_version; + to->di_format = from->di_format; + to->di_onlink = be16_to_cpu(from->di_onlink); + to->di_uid = be32_to_cpu(from->di_uid); + to->di_gid = be32_to_cpu(from->di_gid); + to->di_nlink = be32_to_cpu(from->di_nlink); + to->di_projid = be16_to_cpu(from->di_projid); + memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); + to->di_flushiter = be16_to_cpu(from->di_flushiter); + to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec); + to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec); + to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec); + to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec); + to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec); + to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec); + to->di_size = be64_to_cpu(from->di_size); + to->di_nblocks = be64_to_cpu(from->di_nblocks); + to->di_extsize = be32_to_cpu(from->di_extsize); + to->di_nextents = be32_to_cpu(from->di_nextents); + to->di_anextents = be16_to_cpu(from->di_anextents); + to->di_forkoff = from->di_forkoff; + to->di_aformat = from->di_aformat; + to->di_dmevmask = be32_to_cpu(from->di_dmevmask); + to->di_dmstate = be16_to_cpu(from->di_dmstate); + to->di_flags = be16_to_cpu(from->di_flags); + to->di_gen = be32_to_cpu(from->di_gen); +} + +void +xfs_dinode_to_disk( + xfs_dinode_core_t *to, + xfs_icdinode_t *from) +{ + to->di_magic = cpu_to_be16(from->di_magic); + to->di_mode = cpu_to_be16(from->di_mode); + to->di_version = from ->di_version; + to->di_format = from->di_format; + to->di_onlink = cpu_to_be16(from->di_onlink); + to->di_uid = cpu_to_be32(from->di_uid); + to->di_gid = cpu_to_be32(from->di_gid); + to->di_nlink = cpu_to_be32(from->di_nlink); + to->di_projid = cpu_to_be16(from->di_projid); + memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); + to->di_flushiter = cpu_to_be16(from->di_flushiter); + to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec); + to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec); + to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec); + to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec); + to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec); + to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec); + to->di_size = cpu_to_be64(from->di_size); + to->di_nblocks = cpu_to_be64(from->di_nblocks); + to->di_extsize = cpu_to_be32(from->di_extsize); + to->di_nextents = cpu_to_be32(from->di_nextents); + to->di_anextents = cpu_to_be16(from->di_anextents); + to->di_forkoff = from->di_forkoff; + to->di_aformat = from->di_aformat; + to->di_dmevmask = cpu_to_be32(from->di_dmevmask); + to->di_dmstate = cpu_to_be16(from->di_dmstate); + to->di_flags = cpu_to_be16(from->di_flags); + to->di_gen = cpu_to_be32(from->di_gen); } /* @@ -617,6 +657,7 @@ xfs_iread_extents( { int error; xfs_ifork_t *ifp; + xfs_extnum_t nextents; size_t size; if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { @@ -624,26 +665,24 @@ xfs_iread_extents( ip->i_mount); return XFS_ERROR(EFSCORRUPTED); } - size = XFS_IFORK_NEXTENTS(ip, whichfork) * (uint)sizeof(xfs_bmbt_rec_t); + nextents = XFS_IFORK_NEXTENTS(ip, whichfork); + size = nextents * sizeof(xfs_bmbt_rec_t); ifp = XFS_IFORK_PTR(ip, whichfork); + /* * We know that the size is valid (it's checked in iformat_btree) */ - ifp->if_u1.if_extents = kmem_alloc(size, KM_SLEEP); - ASSERT(ifp->if_u1.if_extents != NULL); ifp->if_lastex = NULLEXTNUM; - ifp->if_bytes = ifp->if_real_bytes = (int)size; + ifp->if_bytes = ifp->if_real_bytes = 0; ifp->if_flags |= XFS_IFEXTENTS; + xfs_iext_add(ifp, 0, nextents); error = xfs_bmap_read_extents(tp, ip, whichfork); if (error) { - kmem_free(ifp->if_u1.if_extents, size); - ifp->if_u1.if_extents = NULL; - ifp->if_bytes = ifp->if_real_bytes = 0; + xfs_iext_destroy(ifp); ifp->if_flags &= ~XFS_IFEXTENTS; return error; } - xfs_validate_extents((xfs_bmbt_rec_t *)ifp->if_u1.if_extents, - XFS_IFORK_NEXTENTS(ip, whichfork), 0, XFS_EXTFMT_INODE(ip)); + xfs_validate_extents(ifp, nextents, XFS_EXTFMT_INODE(ip)); return 0; } @@ -652,12 +691,12 @@ xfs_iread_extents( * being added or deleted as indicated in rec_diff. Move the records * and pointers in if_broot to fit the new size. When shrinking this * will eliminate holes between the records and pointers created by - * the caller. When growing this will create holes to be filled in + * the caller. When growing this will create holes to be filled in * by the caller. * * The caller must not request to add more records than would fit in * the on-disk inode root. If the if_broot is currently NULL, then - * if we adding records one will be allocated. The caller must also + * if we adding records one will be allocated. The caller must also * not request that the number of records go below zero, although * it can go to zero. * @@ -771,7 +810,7 @@ xfs_iroot_realloc( (int)new_size); memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t)); } - kmem_free(ifp->if_broot, ifp->if_broot_bytes); + kmem_free(ifp->if_broot); ifp->if_broot = new_broot; ifp->if_broot_bytes = (int)new_size; ASSERT(ifp->if_broot_bytes <= @@ -779,91 +818,6 @@ xfs_iroot_realloc( return; } -/* - * This is called when the amount of space needed for if_extents - * is increased or decreased. The change in size is indicated by - * the number of extents that need to be added or deleted in the - * ext_diff parameter. - * - * If the amount of space needed has decreased below the size of the - * inline buffer, then switch to using the inline buffer. Otherwise, - * use kmem_realloc() or kmem_alloc() to adjust the size of the buffer - * to what is needed. - * - * ip -- the inode whose if_extents area is changing - * ext_diff -- the change in the number of extents, positive or negative, - * requested for the if_extents array. - */ -void -xfs_iext_realloc( - xfs_inode_t *ip, - int ext_diff, - int whichfork) -{ - int byte_diff; - xfs_ifork_t *ifp; - int new_size; - uint rnew_size; - - if (ext_diff == 0) { - return; - } - - ifp = XFS_IFORK_PTR(ip, whichfork); - byte_diff = ext_diff * (uint)sizeof(xfs_bmbt_rec_t); - new_size = (int)ifp->if_bytes + byte_diff; - ASSERT(new_size >= 0); - - if (new_size == 0) { - if (ifp->if_u1.if_extents != ifp->if_u2.if_inline_ext) { - ASSERT(ifp->if_real_bytes != 0); - kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes); - } - ifp->if_u1.if_extents = NULL; - rnew_size = 0; - } else if (new_size <= sizeof(ifp->if_u2.if_inline_ext)) { - /* - * If the valid extents can fit in if_inline_ext, - * copy them from the malloc'd vector and free it. - */ - if (ifp->if_u1.if_extents != ifp->if_u2.if_inline_ext) { - /* - * For now, empty files are format EXTENTS, - * so the if_extents pointer is null. - */ - if (ifp->if_u1.if_extents) { - memcpy(ifp->if_u2.if_inline_ext, - ifp->if_u1.if_extents, new_size); - kmem_free(ifp->if_u1.if_extents, - ifp->if_real_bytes); - } - ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; - } - rnew_size = 0; - } else { - rnew_size = new_size; - if ((rnew_size & (rnew_size - 1)) != 0) - rnew_size = xfs_iroundup(rnew_size); - /* - * Stuck with malloc/realloc. - */ - if (ifp->if_u1.if_extents == ifp->if_u2.if_inline_ext) { - ifp->if_u1.if_extents = (xfs_bmbt_rec_t *) - kmem_alloc(rnew_size, KM_SLEEP); - memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext, - sizeof(ifp->if_u2.if_inline_ext)); - } else if (rnew_size != ifp->if_real_bytes) { - ifp->if_u1.if_extents = (xfs_bmbt_rec_t *) - kmem_realloc(ifp->if_u1.if_extents, - rnew_size, - ifp->if_real_bytes, - KM_NOFS); - } - } - ifp->if_real_bytes = rnew_size; - ifp->if_bytes = new_size; -} - /* * This is called when the amount of space needed for if_data @@ -900,7 +854,7 @@ xfs_idata_realloc( if (new_size == 0) { if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { - kmem_free(ifp->if_u1.if_data, ifp->if_real_bytes); + kmem_free(ifp->if_u1.if_data); } ifp->if_u1.if_data = NULL; real_size = 0; @@ -915,7 +869,7 @@ xfs_idata_realloc( ASSERT(ifp->if_real_bytes != 0); memcpy(ifp->if_u2.if_inline_data, ifp->if_u1.if_data, new_size); - kmem_free(ifp->if_u1.if_data, ifp->if_real_bytes); + kmem_free(ifp->if_u1.if_data); ifp->if_u1.if_data = ifp->if_u2.if_inline_data; } real_size = 0; @@ -956,6 +910,8 @@ xfs_idata_realloc( } + + /* * Map inode to disk block and offset. * @@ -983,14 +939,31 @@ xfs_imap( fsbno = imap->im_blkno ? XFS_DADDR_TO_FSB(mp, imap->im_blkno) : NULLFSBLOCK; error = xfs_dilocate(mp, tp, ino, &fsbno, &len, &off, flags); - if (error != 0) { + if (error) return error; - } + imap->im_blkno = XFS_FSB_TO_DADDR(mp, fsbno); imap->im_len = XFS_FSB_TO_BB(mp, len); imap->im_agblkno = XFS_FSB_TO_AGBNO(mp, fsbno); imap->im_ioffset = (ushort)off; imap->im_boffset = (ushort)(off << mp->m_sb.sb_inodelog); + + /* + * If the inode number maps to a block outside the bounds + * of the file system then return NULL rather than calling + * read_buf and panicing when we get an error from the + * driver. + */ + if ((imap->im_blkno + imap->im_len) > + XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)) { + xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " + "(imap->im_blkno (0x%llx) + imap->im_len (0x%llx)) > " + " XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks) (0x%llx)", + (unsigned long long) imap->im_blkno, + (unsigned long long) imap->im_len, + XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)); + return EINVAL; + } return 0; } @@ -1003,7 +976,7 @@ xfs_idestroy_fork( ifp = XFS_IFORK_PTR(ip, whichfork); if (ifp->if_broot != NULL) { - kmem_free(ifp->if_broot, ifp->if_broot_bytes); + kmem_free(ifp->if_broot); ifp->if_broot = NULL; } @@ -1017,17 +990,16 @@ xfs_idestroy_fork( if ((ifp->if_u1.if_data != ifp->if_u2.if_inline_data) && (ifp->if_u1.if_data != NULL)) { ASSERT(ifp->if_real_bytes != 0); - kmem_free(ifp->if_u1.if_data, ifp->if_real_bytes); + kmem_free(ifp->if_u1.if_data); ifp->if_u1.if_data = NULL; ifp->if_real_bytes = 0; } } else if ((ifp->if_flags & XFS_IFEXTENTS) && - (ifp->if_u1.if_extents != NULL) && - (ifp->if_u1.if_extents != ifp->if_u2.if_inline_ext)) { + ((ifp->if_flags & XFS_IFEXTIREC) || + ((ifp->if_u1.if_extents != NULL) && + (ifp->if_u1.if_extents != ifp->if_u2.if_inline_ext)))) { ASSERT(ifp->if_real_bytes != 0); - kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes); - ifp->if_u1.if_extents = NULL; - ifp->if_real_bytes = 0; + xfs_iext_destroy(ifp); } ASSERT(ifp->if_u1.if_extents == NULL || ifp->if_u1.if_extents == ifp->if_u2.if_inline_ext); @@ -1038,32 +1010,6 @@ xfs_idestroy_fork( } } -/* - * xfs_iroundup: round up argument to next power of two - */ -uint -xfs_iroundup( - uint v) -{ - int i; - uint m; - - if ((v & (v - 1)) == 0) - return v; - ASSERT((v & 0x80000000) == 0); - if ((v & (v + 1)) == 0) - return v + 1; - for (i = 0, m = 1; i < 31; i++, m <<= 1) { - if (v & m) - continue; - v |= m; - if ((v & (v + 1)) == 0) - return v + 1; - } - ASSERT(0); - return( 0 ); -} - /* * xfs_iextents_copy() * @@ -1078,26 +1024,21 @@ xfs_iroundup( int xfs_iextents_copy( xfs_inode_t *ip, - xfs_bmbt_rec_t *buffer, + xfs_bmbt_rec_t *dp, int whichfork) { int copied; - xfs_bmbt_rec_t *dest_ep; - xfs_bmbt_rec_t *ep; -#ifdef XFS_BMAP_TRACE - static char fname[] = "xfs_iextents_copy"; -#endif int i; xfs_ifork_t *ifp; int nrecs; xfs_fsblock_t start_block; ifp = XFS_IFORK_PTR(ip, whichfork); - ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS)); + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); ASSERT(ifp->if_bytes > 0); nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - xfs_bmap_trace_exlist(fname, ip, nrecs, whichfork); + XFS_BMAP_TRACE_EXLIST(ip, nrecs, whichfork); ASSERT(nrecs > 0); /* @@ -1106,30 +1047,25 @@ xfs_iextents_copy( * the delayed ones. There must be at least one * non-delayed extent. */ - ep = ifp->if_u1.if_extents; - dest_ep = buffer; copied = 0; for (i = 0; i < nrecs; i++) { + xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); start_block = xfs_bmbt_get_startblock(ep); if (ISNULLSTARTBLOCK(start_block)) { /* * It's a delayed allocation extent, so skip it. */ - ep++; continue; } /* Translate to on disk format */ - put_unaligned(INT_GET(ep->l0, ARCH_CONVERT), - (__uint64_t*)&dest_ep->l0); - put_unaligned(INT_GET(ep->l1, ARCH_CONVERT), - (__uint64_t*)&dest_ep->l1); - dest_ep++; - ep++; + put_unaligned(cpu_to_be64(ep->l0), &dp->l0); + put_unaligned(cpu_to_be64(ep->l1), &dp->l1); + dp++; copied++; } ASSERT(copied != 0); - xfs_validate_extents(buffer, copied, 1, XFS_EXTFMT_INODE(ip)); + xfs_validate_extents(ifp, copied, XFS_EXTFMT_INODE(ip)); return (copied * (uint)sizeof(xfs_bmbt_rec_t)); } @@ -1143,8 +1079,11 @@ xfs_iextents_copy( * changed formats after being modified but before being flushed. * In these cases, the format always takes precedence, because the * format indicates the current state of the fork. + * + * Note: this requires user-space public scope for libxfs_iread */ -STATIC int +/*ARGSUSED*/ +void xfs_iflush_fork( xfs_inode_t *ip, xfs_dinode_t *dip, @@ -1165,16 +1104,16 @@ xfs_iflush_fork( static const short extflag[2] = { XFS_ILOG_DEXT, XFS_ILOG_AEXT }; - if (iip == NULL) - return 0; + if (!iip) + return; ifp = XFS_IFORK_PTR(ip, whichfork); /* * This can happen if we gave up in iformat in an error path, * for the attribute fork. */ - if (ifp == NULL) { + if (!ifp) { ASSERT(whichfork == XFS_ATTR_FORK); - return 0; + return; } cp = XFS_DFORK_PTR(dip, whichfork); mp = ip->i_mount; @@ -1186,20 +1125,15 @@ xfs_iflush_fork( ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes); } - if (whichfork == XFS_DATA_FORK) { - if (unlikely(XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip))) { - XFS_ERROR_REPORT("xfs_iflush_fork", - XFS_ERRLEVEL_LOW, mp); - return XFS_ERROR(EFSCORRUPTED); - } - } break; case XFS_DINODE_FMT_EXTENTS: ASSERT((ifp->if_flags & XFS_IFEXTENTS) || !(iip->ili_format.ilf_fields & extflag[whichfork])); - ASSERT((ifp->if_u1.if_extents != NULL) || (ifp->if_bytes == 0)); - ASSERT((ifp->if_u1.if_extents == NULL) || (ifp->if_bytes > 0)); + ASSERT((xfs_iext_get_ext(ifp, 0) != NULL) || + (ifp->if_bytes == 0)); + ASSERT((xfs_iext_get_ext(ifp, 0) == NULL) || + (ifp->if_bytes > 0)); if ((iip->ili_format.ilf_fields & extflag[whichfork]) && (ifp->if_bytes > 0)) { ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); @@ -1224,7 +1158,7 @@ xfs_iflush_fork( case XFS_DINODE_FMT_DEV: if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) { ASSERT(whichfork == XFS_DATA_FORK); - INT_SET(dip->di_u.di_dev, ARCH_CONVERT, ip->i_df.if_u2.if_rdev); + dip->di_u.di_dev = cpu_to_be32(ip->i_df.if_u2.if_rdev); } break; @@ -1240,6 +1174,1115 @@ xfs_iflush_fork( ASSERT(0); break; } +} - return 0; +/* + * Return a pointer to the extent record at file index idx. + */ +xfs_bmbt_rec_host_t * +xfs_iext_get_ext( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_extnum_t idx) /* index of target extent */ +{ + ASSERT(idx >= 0); + if ((ifp->if_flags & XFS_IFEXTIREC) && (idx == 0)) { + return ifp->if_u1.if_ext_irec->er_extbuf; + } else if (ifp->if_flags & XFS_IFEXTIREC) { + xfs_ext_irec_t *erp; /* irec pointer */ + int erp_idx = 0; /* irec index */ + xfs_extnum_t page_idx = idx; /* ext index in target list */ + + erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0); + return &erp->er_extbuf[page_idx]; + } else if (ifp->if_bytes) { + return &ifp->if_u1.if_extents[idx]; + } else { + return NULL; + } +} + +/* + * Insert new item(s) into the extent records for incore inode + * fork 'ifp'. 'count' new items are inserted at index 'idx'. + */ +void +xfs_iext_insert( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_extnum_t idx, /* starting index of new items */ + xfs_extnum_t count, /* number of inserted items */ + xfs_bmbt_irec_t *new) /* items to insert */ +{ + xfs_extnum_t i; /* extent record index */ + + ASSERT(ifp->if_flags & XFS_IFEXTENTS); + xfs_iext_add(ifp, idx, count); + for (i = idx; i < idx + count; i++, new++) + xfs_bmbt_set_all(xfs_iext_get_ext(ifp, i), new); +} + +/* + * This is called when the amount of space required for incore file + * extents needs to be increased. The ext_diff parameter stores the + * number of new extents being added and the idx parameter contains + * the extent index where the new extents will be added. If the new + * extents are being appended, then we just need to (re)allocate and + * initialize the space. Otherwise, if the new extents are being + * inserted into the middle of the existing entries, a bit more work + * is required to make room for the new extents to be inserted. The + * caller is responsible for filling in the new extent entries upon + * return. + */ +void +xfs_iext_add( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_extnum_t idx, /* index to begin adding exts */ + int ext_diff) /* number of extents to add */ +{ + int byte_diff; /* new bytes being added */ + int new_size; /* size of extents after adding */ + xfs_extnum_t nextents; /* number of extents in file */ + + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + ASSERT((idx >= 0) && (idx <= nextents)); + byte_diff = ext_diff * sizeof(xfs_bmbt_rec_t); + new_size = ifp->if_bytes + byte_diff; + /* + * If the new number of extents (nextents + ext_diff) + * fits inside the inode, then continue to use the inline + * extent buffer. + */ + if (nextents + ext_diff <= XFS_INLINE_EXTS) { + if (idx < nextents) { + memmove(&ifp->if_u2.if_inline_ext[idx + ext_diff], + &ifp->if_u2.if_inline_ext[idx], + (nextents - idx) * sizeof(xfs_bmbt_rec_t)); + memset(&ifp->if_u2.if_inline_ext[idx], 0, byte_diff); + } + ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; + ifp->if_real_bytes = 0; + ifp->if_lastex = nextents + ext_diff; + } + /* + * Otherwise use a linear (direct) extent list. + * If the extents are currently inside the inode, + * xfs_iext_realloc_direct will switch us from + * inline to direct extent allocation mode. + */ + else if (nextents + ext_diff <= XFS_LINEAR_EXTS) { + xfs_iext_realloc_direct(ifp, new_size); + if (idx < nextents) { + memmove(&ifp->if_u1.if_extents[idx + ext_diff], + &ifp->if_u1.if_extents[idx], + (nextents - idx) * sizeof(xfs_bmbt_rec_t)); + memset(&ifp->if_u1.if_extents[idx], 0, byte_diff); + } + } + /* Indirection array */ + else { + xfs_ext_irec_t *erp; + int erp_idx = 0; + int page_idx = idx; + + ASSERT(nextents + ext_diff > XFS_LINEAR_EXTS); + if (ifp->if_flags & XFS_IFEXTIREC) { + erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 1); + } else { + xfs_iext_irec_init(ifp); + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + erp = ifp->if_u1.if_ext_irec; + } + /* Extents fit in target extent page */ + if (erp && erp->er_extcount + ext_diff <= XFS_LINEAR_EXTS) { + if (page_idx < erp->er_extcount) { + memmove(&erp->er_extbuf[page_idx + ext_diff], + &erp->er_extbuf[page_idx], + (erp->er_extcount - page_idx) * + sizeof(xfs_bmbt_rec_t)); + memset(&erp->er_extbuf[page_idx], 0, byte_diff); + } + erp->er_extcount += ext_diff; + xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff); + } + /* Insert a new extent page */ + else if (erp) { + xfs_iext_add_indirect_multi(ifp, + erp_idx, page_idx, ext_diff); + } + /* + * If extent(s) are being appended to the last page in + * the indirection array and the new extent(s) don't fit + * in the page, then erp is NULL and erp_idx is set to + * the next index needed in the indirection array. + */ + else { + int count = ext_diff; + + while (count) { + erp = xfs_iext_irec_new(ifp, erp_idx); + erp->er_extcount = count; + count -= MIN(count, (int)XFS_LINEAR_EXTS); + if (count) { + erp_idx++; + } + } + } + } + ifp->if_bytes = new_size; +} + +/* + * This is called when incore extents are being added to the indirection + * array and the new extents do not fit in the target extent list. The + * erp_idx parameter contains the irec index for the target extent list + * in the indirection array, and the idx parameter contains the extent + * index within the list. The number of extents being added is stored + * in the count parameter. + * + * |-------| |-------| + * | | | | idx - number of extents before idx + * | idx | | count | + * | | | | count - number of extents being inserted at idx + * |-------| |-------| + * | count | | nex2 | nex2 - number of extents after idx + count + * |-------| |-------| + */ +void +xfs_iext_add_indirect_multi( + xfs_ifork_t *ifp, /* inode fork pointer */ + int erp_idx, /* target extent irec index */ + xfs_extnum_t idx, /* index within target list */ + int count) /* new extents being added */ +{ + int byte_diff; /* new bytes being added */ + xfs_ext_irec_t *erp; /* pointer to irec entry */ + xfs_extnum_t ext_diff; /* number of extents to add */ + xfs_extnum_t ext_cnt; /* new extents still needed */ + xfs_extnum_t nex2; /* extents after idx + count */ + xfs_bmbt_rec_t *nex2_ep = NULL; /* temp list for nex2 extents */ + int nlists; /* number of irec's (lists) */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + erp = &ifp->if_u1.if_ext_irec[erp_idx]; + nex2 = erp->er_extcount - idx; + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + + /* + * Save second part of target extent list + * (all extents past */ + if (nex2) { + byte_diff = nex2 * sizeof(xfs_bmbt_rec_t); + nex2_ep = (xfs_bmbt_rec_t *) kmem_alloc(byte_diff, KM_NOFS); + memmove(nex2_ep, &erp->er_extbuf[idx], byte_diff); + erp->er_extcount -= nex2; + xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -nex2); + memset(&erp->er_extbuf[idx], 0, byte_diff); + } + + /* + * Add the new extents to the end of the target + * list, then allocate new irec record(s) and + * extent buffer(s) as needed to store the rest + * of the new extents. + */ + ext_cnt = count; + ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS - erp->er_extcount); + if (ext_diff) { + erp->er_extcount += ext_diff; + xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff); + ext_cnt -= ext_diff; + } + while (ext_cnt) { + erp_idx++; + erp = xfs_iext_irec_new(ifp, erp_idx); + ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS); + erp->er_extcount = ext_diff; + xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff); + ext_cnt -= ext_diff; + } + + /* Add nex2 extents back to indirection array */ + if (nex2) { + xfs_extnum_t ext_avail; + int i; + + byte_diff = nex2 * sizeof(xfs_bmbt_rec_t); + ext_avail = XFS_LINEAR_EXTS - erp->er_extcount; + i = 0; + /* + * If nex2 extents fit in the current page, append + * nex2_ep after the new extents. + */ + if (nex2 <= ext_avail) { + i = erp->er_extcount; + } + /* + * Otherwise, check if space is available in the + * next page. + */ + else if ((erp_idx < nlists - 1) && + (nex2 <= (ext_avail = XFS_LINEAR_EXTS - + ifp->if_u1.if_ext_irec[erp_idx+1].er_extcount))) { + erp_idx++; + erp++; + /* Create a hole for nex2 extents */ + memmove(&erp->er_extbuf[nex2], erp->er_extbuf, + erp->er_extcount * sizeof(xfs_bmbt_rec_t)); + } + /* + * Final choice, create a new extent page for + * nex2 extents. + */ + else { + erp_idx++; + erp = xfs_iext_irec_new(ifp, erp_idx); + } + memmove(&erp->er_extbuf[i], nex2_ep, byte_diff); + kmem_free(nex2_ep); + erp->er_extcount += nex2; + xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, nex2); + } +} + +/* + * This is called when the amount of space required for incore file + * extents needs to be decreased. The ext_diff parameter stores the + * number of extents to be removed and the idx parameter contains + * the extent index where the extents will be removed from. + * + * If the amount of space needed has decreased below the linear + * limit, XFS_IEXT_BUFSZ, then switch to using the contiguous + * extent array. Otherwise, use kmem_realloc() to adjust the + * size to what is needed. + */ +void +xfs_iext_remove( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_extnum_t idx, /* index to begin removing exts */ + int ext_diff) /* number of extents to remove */ +{ + xfs_extnum_t nextents; /* number of extents in file */ + int new_size; /* size of extents after removal */ + + ASSERT(ext_diff > 0); + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + new_size = (nextents - ext_diff) * sizeof(xfs_bmbt_rec_t); + + if (new_size == 0) { + xfs_iext_destroy(ifp); + } else if (ifp->if_flags & XFS_IFEXTIREC) { + xfs_iext_remove_indirect(ifp, idx, ext_diff); + } else if (ifp->if_real_bytes) { + xfs_iext_remove_direct(ifp, idx, ext_diff); + } else { + xfs_iext_remove_inline(ifp, idx, ext_diff); + } + ifp->if_bytes = new_size; +} + +/* + * This removes ext_diff extents from the inline buffer, beginning + * at extent index idx. + */ +void +xfs_iext_remove_inline( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_extnum_t idx, /* index to begin removing exts */ + int ext_diff) /* number of extents to remove */ +{ + int nextents; /* number of extents in file */ + + ASSERT(!(ifp->if_flags & XFS_IFEXTIREC)); + ASSERT(idx < XFS_INLINE_EXTS); + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + ASSERT(((nextents - ext_diff) > 0) && + (nextents - ext_diff) < XFS_INLINE_EXTS); + + if (idx + ext_diff < nextents) { + memmove(&ifp->if_u2.if_inline_ext[idx], + &ifp->if_u2.if_inline_ext[idx + ext_diff], + (nextents - (idx + ext_diff)) * + sizeof(xfs_bmbt_rec_t)); + memset(&ifp->if_u2.if_inline_ext[nextents - ext_diff], + 0, ext_diff * sizeof(xfs_bmbt_rec_t)); + } else { + memset(&ifp->if_u2.if_inline_ext[idx], 0, + ext_diff * sizeof(xfs_bmbt_rec_t)); + } +} + +/* + * This removes ext_diff extents from a linear (direct) extent list, + * beginning at extent index idx. If the extents are being removed + * from the end of the list (ie. truncate) then we just need to re- + * allocate the list to remove the extra space. Otherwise, if the + * extents are being removed from the middle of the existing extent + * entries, then we first need to move the extent records beginning + * at idx + ext_diff up in the list to overwrite the records being + * removed, then remove the extra space via kmem_realloc. + */ +void +xfs_iext_remove_direct( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_extnum_t idx, /* index to begin removing exts */ + int ext_diff) /* number of extents to remove */ +{ + xfs_extnum_t nextents; /* number of extents in file */ + int new_size; /* size of extents after removal */ + + ASSERT(!(ifp->if_flags & XFS_IFEXTIREC)); + new_size = ifp->if_bytes - + (ext_diff * sizeof(xfs_bmbt_rec_t)); + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + + if (new_size == 0) { + xfs_iext_destroy(ifp); + return; + } + /* Move extents up in the list (if needed) */ + if (idx + ext_diff < nextents) { + memmove(&ifp->if_u1.if_extents[idx], + &ifp->if_u1.if_extents[idx + ext_diff], + (nextents - (idx + ext_diff)) * + sizeof(xfs_bmbt_rec_t)); + } + memset(&ifp->if_u1.if_extents[nextents - ext_diff], + 0, ext_diff * sizeof(xfs_bmbt_rec_t)); + /* + * Reallocate the direct extent list. If the extents + * will fit inside the inode then xfs_iext_realloc_direct + * will switch from direct to inline extent allocation + * mode for us. + */ + xfs_iext_realloc_direct(ifp, new_size); + ifp->if_bytes = new_size; +} + +/* + * This is called when incore extents are being removed from the + * indirection array and the extents being removed span multiple extent + * buffers. The idx parameter contains the file extent index where we + * want to begin removing extents, and the count parameter contains + * how many extents need to be removed. + * + * |-------| |-------| + * | nex1 | | | nex1 - number of extents before idx + * |-------| | count | + * | | | | count - number of extents being removed at idx + * | count | |-------| + * | | | nex2 | nex2 - number of extents after idx + count + * |-------| |-------| + */ +void +xfs_iext_remove_indirect( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_extnum_t idx, /* index to begin removing extents */ + int count) /* number of extents to remove */ +{ + xfs_ext_irec_t *erp; /* indirection array pointer */ + int erp_idx = 0; /* indirection array index */ + xfs_extnum_t ext_cnt; /* extents left to remove */ + xfs_extnum_t ext_diff; /* extents to remove in current list */ + xfs_extnum_t nex1; /* number of extents before idx */ + xfs_extnum_t nex2; /* extents after idx + count */ + int nlists; /* entries in indirection array */ + int page_idx = idx; /* index in target extent list */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0); + ASSERT(erp != NULL); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + nex1 = page_idx; + ext_cnt = count; + while (ext_cnt) { + nex2 = MAX((erp->er_extcount - (nex1 + ext_cnt)), 0); + ext_diff = MIN(ext_cnt, (erp->er_extcount - nex1)); + /* + * Check for deletion of entire list; + * xfs_iext_irec_remove() updates extent offsets. + */ + if (ext_diff == erp->er_extcount) { + xfs_iext_irec_remove(ifp, erp_idx); + ext_cnt -= ext_diff; + nex1 = 0; + if (ext_cnt) { + ASSERT(erp_idx < ifp->if_real_bytes / + XFS_IEXT_BUFSZ); + erp = &ifp->if_u1.if_ext_irec[erp_idx]; + nex1 = 0; + continue; + } else { + break; + } + } + /* Move extents up (if needed) */ + if (nex2) { + memmove(&erp->er_extbuf[nex1], + &erp->er_extbuf[nex1 + ext_diff], + nex2 * sizeof(xfs_bmbt_rec_t)); + } + /* Zero out rest of page */ + memset(&erp->er_extbuf[nex1 + nex2], 0, (XFS_IEXT_BUFSZ - + ((nex1 + nex2) * sizeof(xfs_bmbt_rec_t)))); + /* Update remaining counters */ + erp->er_extcount -= ext_diff; + xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -ext_diff); + ext_cnt -= ext_diff; + nex1 = 0; + erp_idx++; + erp++; + } + ifp->if_bytes -= count * sizeof(xfs_bmbt_rec_t); + xfs_iext_irec_compact(ifp); +} + +/* + * Create, destroy, or resize a linear (direct) block of extents. + */ +void +xfs_iext_realloc_direct( + xfs_ifork_t *ifp, /* inode fork pointer */ + int new_size) /* new size of extents */ +{ + int rnew_size; /* real new size of extents */ + + rnew_size = new_size; + + ASSERT(!(ifp->if_flags & XFS_IFEXTIREC) || + ((new_size >= 0) && (new_size <= XFS_IEXT_BUFSZ) && + (new_size != ifp->if_real_bytes))); + + /* Free extent records */ + if (new_size == 0) { + xfs_iext_destroy(ifp); + } + /* Resize direct extent list and zero any new bytes */ + else if (ifp->if_real_bytes) { + /* Check if extents will fit inside the inode */ + if (new_size <= XFS_INLINE_EXTS * sizeof(xfs_bmbt_rec_t)) { + xfs_iext_direct_to_inline(ifp, new_size / + (uint)sizeof(xfs_bmbt_rec_t)); + ifp->if_bytes = new_size; + return; + } + if (!is_power_of_2(new_size)){ + rnew_size = roundup_pow_of_two(new_size); + } + if (rnew_size != ifp->if_real_bytes) { + ifp->if_u1.if_extents = + kmem_realloc(ifp->if_u1.if_extents, + rnew_size, + ifp->if_real_bytes, KM_NOFS); + } + if (rnew_size > ifp->if_real_bytes) { + memset(&ifp->if_u1.if_extents[ifp->if_bytes / + (uint)sizeof(xfs_bmbt_rec_t)], 0, + rnew_size - ifp->if_real_bytes); + } + } + /* + * Switch from the inline extent buffer to a direct + * extent list. Be sure to include the inline extent + * bytes in new_size. + */ + else { + new_size += ifp->if_bytes; + if (!is_power_of_2(new_size)) { + rnew_size = roundup_pow_of_two(new_size); + } + xfs_iext_inline_to_direct(ifp, rnew_size); + } + ifp->if_real_bytes = rnew_size; + ifp->if_bytes = new_size; +} + +/* + * Switch from linear (direct) extent records to inline buffer. + */ +void +xfs_iext_direct_to_inline( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_extnum_t nextents) /* number of extents in file */ +{ + ASSERT(ifp->if_flags & XFS_IFEXTENTS); + ASSERT(nextents <= XFS_INLINE_EXTS); + /* + * The inline buffer was zeroed when we switched + * from inline to direct extent allocation mode, + * so we don't need to clear it here. + */ + memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents, + nextents * sizeof(xfs_bmbt_rec_t)); + kmem_free(ifp->if_u1.if_extents); + ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; + ifp->if_real_bytes = 0; +} + +/* + * Switch from inline buffer to linear (direct) extent records. + * new_size should already be rounded up to the next power of 2 + * by the caller (when appropriate), so use new_size as it is. + * However, since new_size may be rounded up, we can't update + * if_bytes here. It is the caller's responsibility to update + * if_bytes upon return. + */ +void +xfs_iext_inline_to_direct( + xfs_ifork_t *ifp, /* inode fork pointer */ + int new_size) /* number of extents in file */ +{ + ifp->if_u1.if_extents = kmem_alloc(new_size, KM_NOFS); + memset(ifp->if_u1.if_extents, 0, new_size); + if (ifp->if_bytes) { + memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext, + ifp->if_bytes); + memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS * + sizeof(xfs_bmbt_rec_t)); + } + ifp->if_real_bytes = new_size; +} + +/* + * Resize an extent indirection array to new_size bytes. + */ +void +xfs_iext_realloc_indirect( + xfs_ifork_t *ifp, /* inode fork pointer */ + int new_size) /* new indirection array size */ +{ + int nlists; /* number of irec's (ex lists) */ + int size; /* current indirection array size */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + size = nlists * sizeof(xfs_ext_irec_t); + ASSERT(ifp->if_real_bytes); + ASSERT((new_size >= 0) && (new_size != size)); + if (new_size == 0) { + xfs_iext_destroy(ifp); + } else { + ifp->if_u1.if_ext_irec = (xfs_ext_irec_t *) + kmem_realloc(ifp->if_u1.if_ext_irec, + new_size, size, KM_NOFS); + } +} + +/* + * Switch from indirection array to linear (direct) extent allocations. + */ +void +xfs_iext_indirect_to_direct( + xfs_ifork_t *ifp) /* inode fork pointer */ +{ + xfs_bmbt_rec_host_t *ep; /* extent record pointer */ + xfs_extnum_t nextents; /* number of extents in file */ + int size; /* size of file extents */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + ASSERT(nextents <= XFS_LINEAR_EXTS); + size = nextents * sizeof(xfs_bmbt_rec_t); + + xfs_iext_irec_compact_full(ifp); + ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ); + + ep = ifp->if_u1.if_ext_irec->er_extbuf; + kmem_free(ifp->if_u1.if_ext_irec); + ifp->if_flags &= ~XFS_IFEXTIREC; + ifp->if_u1.if_extents = ep; + ifp->if_bytes = size; + if (nextents < XFS_LINEAR_EXTS) { + xfs_iext_realloc_direct(ifp, size); + } +} + +/* + * Free incore file extents. + */ +void +xfs_iext_destroy( + xfs_ifork_t *ifp) /* inode fork pointer */ +{ + if (ifp->if_flags & XFS_IFEXTIREC) { + int erp_idx; + int nlists; + + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + for (erp_idx = nlists - 1; erp_idx >= 0 ; erp_idx--) { + xfs_iext_irec_remove(ifp, erp_idx); + } + ifp->if_flags &= ~XFS_IFEXTIREC; + } else if (ifp->if_real_bytes) { + kmem_free(ifp->if_u1.if_extents); + } else if (ifp->if_bytes) { + memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS * + sizeof(xfs_bmbt_rec_t)); + } + ifp->if_u1.if_extents = NULL; + ifp->if_real_bytes = 0; + ifp->if_bytes = 0; +} + +/* + * Return a pointer to the extent record for file system block bno. + */ +xfs_bmbt_rec_host_t * /* pointer to found extent record */ +xfs_iext_bno_to_ext( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_fileoff_t bno, /* block number to search for */ + xfs_extnum_t *idxp) /* index of target extent */ +{ + xfs_bmbt_rec_host_t *base; /* pointer to first extent */ + xfs_filblks_t blockcount = 0; /* number of blocks in extent */ + xfs_bmbt_rec_host_t *ep = NULL; /* pointer to target extent */ + xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ + int high; /* upper boundary in search */ + xfs_extnum_t idx = 0; /* index of target extent */ + int low; /* lower boundary in search */ + xfs_extnum_t nextents; /* number of file extents */ + xfs_fileoff_t startoff = 0; /* start offset of extent */ + + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + if (nextents == 0) { + *idxp = 0; + return NULL; + } + low = 0; + if (ifp->if_flags & XFS_IFEXTIREC) { + /* Find target extent list */ + int erp_idx = 0; + erp = xfs_iext_bno_to_irec(ifp, bno, &erp_idx); + base = erp->er_extbuf; + high = erp->er_extcount - 1; + } else { + base = ifp->if_u1.if_extents; + high = nextents - 1; + } + /* Binary search extent records */ + while (low <= high) { + idx = (low + high) >> 1; + ep = base + idx; + startoff = xfs_bmbt_get_startoff(ep); + blockcount = xfs_bmbt_get_blockcount(ep); + if (bno < startoff) { + high = idx - 1; + } else if (bno >= startoff + blockcount) { + low = idx + 1; + } else { + /* Convert back to file-based extent index */ + if (ifp->if_flags & XFS_IFEXTIREC) { + idx += erp->er_extoff; + } + *idxp = idx; + return ep; + } + } + /* Convert back to file-based extent index */ + if (ifp->if_flags & XFS_IFEXTIREC) { + idx += erp->er_extoff; + } + if (bno >= startoff + blockcount) { + if (++idx == nextents) { + ep = NULL; + } else { + ep = xfs_iext_get_ext(ifp, idx); + } + } + *idxp = idx; + return ep; +} + +/* + * Return a pointer to the indirection array entry containing the + * extent record for filesystem block bno. Store the index of the + * target irec in *erp_idxp. + */ +xfs_ext_irec_t * /* pointer to found extent record */ +xfs_iext_bno_to_irec( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_fileoff_t bno, /* block number to search for */ + int *erp_idxp) /* irec index of target ext list */ +{ + xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ + xfs_ext_irec_t *erp_next; /* next indirection array entry */ + int erp_idx; /* indirection array index */ + int nlists; /* number of extent irec's (lists) */ + int high; /* binary search upper limit */ + int low; /* binary search lower limit */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + erp_idx = 0; + low = 0; + high = nlists - 1; + while (low <= high) { + erp_idx = (low + high) >> 1; + erp = &ifp->if_u1.if_ext_irec[erp_idx]; + erp_next = erp_idx < nlists - 1 ? erp + 1 : NULL; + if (bno < xfs_bmbt_get_startoff(erp->er_extbuf)) { + high = erp_idx - 1; + } else if (erp_next && bno >= + xfs_bmbt_get_startoff(erp_next->er_extbuf)) { + low = erp_idx + 1; + } else { + break; + } + } + *erp_idxp = erp_idx; + return erp; +} + +/* + * Return a pointer to the indirection array entry containing the + * extent record at file extent index *idxp. Store the index of the + * target irec in *erp_idxp and store the page index of the target + * extent record in *idxp. + */ +xfs_ext_irec_t * +xfs_iext_idx_to_irec( + xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_extnum_t *idxp, /* extent index (file -> page) */ + int *erp_idxp, /* pointer to target irec */ + int realloc) /* new bytes were just added */ +{ + xfs_ext_irec_t *prev; /* pointer to previous irec */ + xfs_ext_irec_t *erp = NULL; /* pointer to current irec */ + int erp_idx; /* indirection array index */ + int nlists; /* number of irec's (ex lists) */ + int high; /* binary search upper limit */ + int low; /* binary search lower limit */ + xfs_extnum_t page_idx = *idxp; /* extent index in target list */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + ASSERT(page_idx >= 0 && page_idx <= + ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + erp_idx = 0; + low = 0; + high = nlists - 1; + + /* Binary search extent irec's */ + while (low <= high) { + erp_idx = (low + high) >> 1; + erp = &ifp->if_u1.if_ext_irec[erp_idx]; + prev = erp_idx > 0 ? erp - 1 : NULL; + if (page_idx < erp->er_extoff || (page_idx == erp->er_extoff && + realloc && prev && prev->er_extcount < XFS_LINEAR_EXTS)) { + high = erp_idx - 1; + } else if (page_idx > erp->er_extoff + erp->er_extcount || + (page_idx == erp->er_extoff + erp->er_extcount && + !realloc)) { + low = erp_idx + 1; + } else if (page_idx == erp->er_extoff + erp->er_extcount && + erp->er_extcount == XFS_LINEAR_EXTS) { + ASSERT(realloc); + page_idx = 0; + erp_idx++; + erp = erp_idx < nlists ? erp + 1 : NULL; + break; + } else { + page_idx -= erp->er_extoff; + break; + } + } + *idxp = page_idx; + *erp_idxp = erp_idx; + return(erp); +} + +/* + * Allocate and initialize an indirection array once the space needed + * for incore extents increases above XFS_IEXT_BUFSZ. + */ +void +xfs_iext_irec_init( + xfs_ifork_t *ifp) /* inode fork pointer */ +{ + xfs_ext_irec_t *erp; /* indirection array pointer */ + xfs_extnum_t nextents; /* number of extents in file */ + + ASSERT(!(ifp->if_flags & XFS_IFEXTIREC)); + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + ASSERT(nextents <= XFS_LINEAR_EXTS); + + erp = kmem_alloc(sizeof(xfs_ext_irec_t), KM_NOFS); + + if (nextents == 0) { + ifp->if_u1.if_extents = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS); + } else if (!ifp->if_real_bytes) { + xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ); + } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) { + xfs_iext_realloc_direct(ifp, XFS_IEXT_BUFSZ); + } + erp->er_extbuf = ifp->if_u1.if_extents; + erp->er_extcount = nextents; + erp->er_extoff = 0; + + ifp->if_flags |= XFS_IFEXTIREC; + ifp->if_real_bytes = XFS_IEXT_BUFSZ; + ifp->if_bytes = nextents * sizeof(xfs_bmbt_rec_t); + ifp->if_u1.if_ext_irec = erp; + + return; +} + +/* + * Allocate and initialize a new entry in the indirection array. + */ +xfs_ext_irec_t * +xfs_iext_irec_new( + xfs_ifork_t *ifp, /* inode fork pointer */ + int erp_idx) /* index for new irec */ +{ + xfs_ext_irec_t *erp; /* indirection array pointer */ + int i; /* loop counter */ + int nlists; /* number of irec's (ex lists) */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + + /* Resize indirection array */ + xfs_iext_realloc_indirect(ifp, ++nlists * + sizeof(xfs_ext_irec_t)); + /* + * Move records down in the array so the + * new page can use erp_idx. + */ + erp = ifp->if_u1.if_ext_irec; + for (i = nlists - 1; i > erp_idx; i--) { + memmove(&erp[i], &erp[i-1], sizeof(xfs_ext_irec_t)); + } + ASSERT(i == erp_idx); + + /* Initialize new extent record */ + erp = ifp->if_u1.if_ext_irec; + erp[erp_idx].er_extbuf = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS); + ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; + memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ); + erp[erp_idx].er_extcount = 0; + erp[erp_idx].er_extoff = erp_idx > 0 ? + erp[erp_idx-1].er_extoff + erp[erp_idx-1].er_extcount : 0; + return (&erp[erp_idx]); +} + +/* + * Remove a record from the indirection array. + */ +void +xfs_iext_irec_remove( + xfs_ifork_t *ifp, /* inode fork pointer */ + int erp_idx) /* irec index to remove */ +{ + xfs_ext_irec_t *erp; /* indirection array pointer */ + int i; /* loop counter */ + int nlists; /* number of irec's (ex lists) */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + erp = &ifp->if_u1.if_ext_irec[erp_idx]; + if (erp->er_extbuf) { + xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, + -erp->er_extcount); + kmem_free(erp->er_extbuf); + } + /* Compact extent records */ + erp = ifp->if_u1.if_ext_irec; + for (i = erp_idx; i < nlists - 1; i++) { + memmove(&erp[i], &erp[i+1], sizeof(xfs_ext_irec_t)); + } + /* + * Manually free the last extent record from the indirection + * array. A call to xfs_iext_realloc_indirect() with a size + * of zero would result in a call to xfs_iext_destroy() which + * would in turn call this function again, creating a nasty + * infinite loop. + */ + if (--nlists) { + xfs_iext_realloc_indirect(ifp, + nlists * sizeof(xfs_ext_irec_t)); + } else { + kmem_free(ifp->if_u1.if_ext_irec); + } + ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; +} + +/* + * This is called to clean up large amounts of unused memory allocated + * by the indirection array. Before compacting anything though, verify + * that the indirection array is still needed and switch back to the + * linear extent list (or even the inline buffer) if possible. The + * compaction policy is as follows: + * + * Full Compaction: Extents fit into a single page (or inline buffer) + * Full Compaction: Extents occupy less than 10% of allocated space + * Partial Compaction: Extents occupy > 10% and < 50% of allocated space + * No Compaction: Extents occupy at least 50% of allocated space + */ +void +xfs_iext_irec_compact( + xfs_ifork_t *ifp) /* inode fork pointer */ +{ + xfs_extnum_t nextents; /* number of extents in file */ + int nlists; /* number of irec's (ex lists) */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + + if (nextents == 0) { + xfs_iext_destroy(ifp); + } else if (nextents <= XFS_INLINE_EXTS) { + xfs_iext_indirect_to_direct(ifp); + xfs_iext_direct_to_inline(ifp, nextents); + } else if (nextents <= XFS_LINEAR_EXTS) { + xfs_iext_indirect_to_direct(ifp); + } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 3) { + xfs_iext_irec_compact_full(ifp); + } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 1) { + xfs_iext_irec_compact_pages(ifp); + } +} + +/* + * Combine extents from neighboring extent pages. + */ +void +xfs_iext_irec_compact_pages( + xfs_ifork_t *ifp) /* inode fork pointer */ +{ + xfs_ext_irec_t *erp, *erp_next;/* pointers to irec entries */ + int erp_idx = 0; /* indirection array index */ + int nlists; /* number of irec's (ex lists) */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + while (erp_idx < nlists - 1) { + erp = &ifp->if_u1.if_ext_irec[erp_idx]; + erp_next = erp + 1; + if (erp_next->er_extcount <= + (XFS_LINEAR_EXTS - erp->er_extcount)) { + memmove(&erp->er_extbuf[erp->er_extcount], + erp_next->er_extbuf, erp_next->er_extcount * + sizeof(xfs_bmbt_rec_t)); + erp->er_extcount += erp_next->er_extcount; + /* + * Free page before removing extent record + * so er_extoffs don't get modified in + * xfs_iext_irec_remove. + */ + kmem_free(erp_next->er_extbuf); + erp_next->er_extbuf = NULL; + xfs_iext_irec_remove(ifp, erp_idx + 1); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + } else { + erp_idx++; + } + } +} + +/* + * Fully compact the extent records managed by the indirection array. + */ +void +xfs_iext_irec_compact_full( + xfs_ifork_t *ifp) /* inode fork pointer */ +{ + xfs_bmbt_rec_host_t *ep, *ep_next; /* extent record pointers */ + xfs_ext_irec_t *erp, *erp_next; /* extent irec pointers */ + int erp_idx = 0; /* extent irec index */ + int ext_avail; /* empty entries in ex list */ + int ext_diff; /* number of exts to add */ + int nlists; /* number of irec's (ex lists) */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + erp = ifp->if_u1.if_ext_irec; + ep = &erp->er_extbuf[erp->er_extcount]; + erp_next = erp + 1; + ep_next = erp_next->er_extbuf; + + while (erp_idx < nlists - 1) { + /* + * Check how many extent records are available in this irec. + * If there is none skip the whole exercise. + */ + ext_avail = XFS_LINEAR_EXTS - erp->er_extcount; + if (ext_avail) { + + /* + * Copy over as many as possible extent records into + * the previous page. + */ + ext_diff = MIN(ext_avail, erp_next->er_extcount); + memcpy(ep, ep_next, ext_diff * sizeof(xfs_bmbt_rec_t)); + erp->er_extcount += ext_diff; + erp_next->er_extcount -= ext_diff; + + /* + * If the next irec is empty now we can simply + * remove it. + */ + if (erp_next->er_extcount == 0) { + /* + * Free page before removing extent record + * so er_extoffs don't get modified in + * xfs_iext_irec_remove. + */ + kmem_free(erp_next->er_extbuf); + erp_next->er_extbuf = NULL; + xfs_iext_irec_remove(ifp, erp_idx + 1); + erp = &ifp->if_u1.if_ext_irec[erp_idx]; + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + + /* + * If the next irec is not empty move up the content + * that has not been copied to the previous page to + * the beggining of this one. + */ + } else { + memmove(erp_next->er_extbuf, &ep_next[ext_diff], + erp_next->er_extcount * + sizeof(xfs_bmbt_rec_t)); + ep_next = erp_next->er_extbuf; + memset(&ep_next[erp_next->er_extcount], 0, + (XFS_LINEAR_EXTS - + erp_next->er_extcount) * + sizeof(xfs_bmbt_rec_t)); + } + } + + if (erp->er_extcount == XFS_LINEAR_EXTS) { + erp_idx++; + if (erp_idx < nlists) + erp = &ifp->if_u1.if_ext_irec[erp_idx]; + else + break; + } + ep = &erp->er_extbuf[erp->er_extcount]; + erp_next = erp + 1; + ep_next = erp_next->er_extbuf; + } +} + +/* + * This is called to update the er_extoff field in the indirection + * array when extents have been added or removed from one of the + * extent lists. erp_idx contains the irec index to begin updating + * at and ext_diff contains the number of extents that were added + * or removed. + */ +void +xfs_iext_irec_update_extoffs( + xfs_ifork_t *ifp, /* inode fork pointer */ + int erp_idx, /* irec index to update */ + int ext_diff) /* number of new extents */ +{ + int i; /* loop counter */ + int nlists; /* number of irec's (ex lists */ + + ASSERT(ifp->if_flags & XFS_IFEXTIREC); + nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; + for (i = erp_idx; i < nlists; i++) { + ifp->if_u1.if_ext_irec[i].er_extoff += ext_diff; + } } diff --git a/libxfs/xfs_mount.c b/libxfs/xfs_mount.c index cb07cd4d7..e28fdede0 100644 --- a/libxfs/xfs_mount.c +++ b/libxfs/xfs_mount.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2006 Silicon Graphics, Inc. + * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -18,120 +18,49 @@ #include -/* - * Mount initialization code establishing various mount - * fields from the superblock associated with the given - * mount structure. - */ -void -xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp) -{ - int i; - - mp->m_agfrotor = mp->m_agirotor = 0; - spinlock_init(&mp->m_agirotor_lock, "m_agirotor_lock"); - mp->m_maxagi = mp->m_sb.sb_agcount; - mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG; - mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT; - mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT; - mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1; - mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog; - mp->m_litino = sbp->sb_inodesize - - ((uint)sizeof(xfs_dinode_core_t) + (uint)sizeof(xfs_agino_t)); - mp->m_blockmask = sbp->sb_blocksize - 1; - mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; - mp->m_blockwmask = mp->m_blockwsize - 1; - INIT_LIST_HEAD(&mp->m_del_inodes); - - /* - * Setup for attributes, in case they get created. - * This value is for inodes getting attributes for the first time, - * the per-inode value is for old attribute values. - */ - ASSERT(sbp->sb_inodesize >= 256 && sbp->sb_inodesize <= 2048); - switch (sbp->sb_inodesize) { - case 256: - mp->m_attroffset = XFS_LITINO(mp) - - XFS_BMDR_SPACE_CALC(MINABTPTRS); - break; - case 512: - case 1024: - case 2048: - mp->m_attroffset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS); - break; - default: - ASSERT(0); - } - ASSERT(mp->m_attroffset < XFS_LITINO(mp)); - - for (i = 0; i < 2; i++) { - mp->m_alloc_mxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize, - xfs_alloc, i == 0); - mp->m_alloc_mnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize, - xfs_alloc, i == 0); - } - for (i = 0; i < 2; i++) { - mp->m_bmap_dmxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize, - xfs_bmbt, i == 0); - mp->m_bmap_dmnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize, - xfs_bmbt, i == 0); - } - for (i = 0; i < 2; i++) { - mp->m_inobt_mxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize, - xfs_inobt, i == 0); - mp->m_inobt_mnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize, - xfs_inobt, i == 0); - } - - mp->m_bsize = XFS_FSB_TO_BB(mp, 1); - mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK, - sbp->sb_inopblock); - mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog; -} - -static struct { - short offset; - short type; /* 0 = integer - * 1 = binary / string (no translation) - */ +static const struct { + short offset; + short type; /* 0 = integer + * 1 = binary / string (no translation) + */ } xfs_sb_info[] = { - { offsetof(xfs_sb_t, sb_magicnum), 0 }, - { offsetof(xfs_sb_t, sb_blocksize), 0 }, - { offsetof(xfs_sb_t, sb_dblocks), 0 }, - { offsetof(xfs_sb_t, sb_rblocks), 0 }, - { offsetof(xfs_sb_t, sb_rextents), 0 }, - { offsetof(xfs_sb_t, sb_uuid), 1 }, - { offsetof(xfs_sb_t, sb_logstart), 0 }, - { offsetof(xfs_sb_t, sb_rootino), 0 }, - { offsetof(xfs_sb_t, sb_rbmino), 0 }, - { offsetof(xfs_sb_t, sb_rsumino), 0 }, - { offsetof(xfs_sb_t, sb_rextsize), 0 }, - { offsetof(xfs_sb_t, sb_agblocks), 0 }, - { offsetof(xfs_sb_t, sb_agcount), 0 }, - { offsetof(xfs_sb_t, sb_rbmblocks), 0 }, - { offsetof(xfs_sb_t, sb_logblocks), 0 }, + { offsetof(xfs_sb_t, sb_magicnum), 0 }, + { offsetof(xfs_sb_t, sb_blocksize), 0 }, + { offsetof(xfs_sb_t, sb_dblocks), 0 }, + { offsetof(xfs_sb_t, sb_rblocks), 0 }, + { offsetof(xfs_sb_t, sb_rextents), 0 }, + { offsetof(xfs_sb_t, sb_uuid), 1 }, + { offsetof(xfs_sb_t, sb_logstart), 0 }, + { offsetof(xfs_sb_t, sb_rootino), 0 }, + { offsetof(xfs_sb_t, sb_rbmino), 0 }, + { offsetof(xfs_sb_t, sb_rsumino), 0 }, + { offsetof(xfs_sb_t, sb_rextsize), 0 }, + { offsetof(xfs_sb_t, sb_agblocks), 0 }, + { offsetof(xfs_sb_t, sb_agcount), 0 }, + { offsetof(xfs_sb_t, sb_rbmblocks), 0 }, + { offsetof(xfs_sb_t, sb_logblocks), 0 }, { offsetof(xfs_sb_t, sb_versionnum), 0 }, - { offsetof(xfs_sb_t, sb_sectsize), 0 }, - { offsetof(xfs_sb_t, sb_inodesize), 0 }, - { offsetof(xfs_sb_t, sb_inopblock), 0 }, - { offsetof(xfs_sb_t, sb_fname[0]), 1 }, - { offsetof(xfs_sb_t, sb_blocklog), 0 }, - { offsetof(xfs_sb_t, sb_sectlog), 0 }, - { offsetof(xfs_sb_t, sb_inodelog), 0 }, - { offsetof(xfs_sb_t, sb_inopblog), 0 }, - { offsetof(xfs_sb_t, sb_agblklog), 0 }, - { offsetof(xfs_sb_t, sb_rextslog), 0 }, + { offsetof(xfs_sb_t, sb_sectsize), 0 }, + { offsetof(xfs_sb_t, sb_inodesize), 0 }, + { offsetof(xfs_sb_t, sb_inopblock), 0 }, + { offsetof(xfs_sb_t, sb_fname[0]), 1 }, + { offsetof(xfs_sb_t, sb_blocklog), 0 }, + { offsetof(xfs_sb_t, sb_sectlog), 0 }, + { offsetof(xfs_sb_t, sb_inodelog), 0 }, + { offsetof(xfs_sb_t, sb_inopblog), 0 }, + { offsetof(xfs_sb_t, sb_agblklog), 0 }, + { offsetof(xfs_sb_t, sb_rextslog), 0 }, { offsetof(xfs_sb_t, sb_inprogress), 0 }, - { offsetof(xfs_sb_t, sb_imax_pct), 0 }, - { offsetof(xfs_sb_t, sb_icount), 0 }, - { offsetof(xfs_sb_t, sb_ifree), 0 }, - { offsetof(xfs_sb_t, sb_fdblocks), 0 }, - { offsetof(xfs_sb_t, sb_frextents), 0 }, - { offsetof(xfs_sb_t, sb_uquotino), 0 }, - { offsetof(xfs_sb_t, sb_gquotino), 0 }, - { offsetof(xfs_sb_t, sb_qflags), 0 }, - { offsetof(xfs_sb_t, sb_flags), 0 }, - { offsetof(xfs_sb_t, sb_shared_vn), 0 }, + { offsetof(xfs_sb_t, sb_imax_pct), 0 }, + { offsetof(xfs_sb_t, sb_icount), 0 }, + { offsetof(xfs_sb_t, sb_ifree), 0 }, + { offsetof(xfs_sb_t, sb_fdblocks), 0 }, + { offsetof(xfs_sb_t, sb_frextents), 0 }, + { offsetof(xfs_sb_t, sb_uquotino), 0 }, + { offsetof(xfs_sb_t, sb_gquotino), 0 }, + { offsetof(xfs_sb_t, sb_qflags), 0 }, + { offsetof(xfs_sb_t, sb_flags), 0 }, + { offsetof(xfs_sb_t, sb_shared_vn), 0 }, { offsetof(xfs_sb_t, sb_inoalignmt), 0 }, { offsetof(xfs_sb_t, sb_unit), 0 }, { offsetof(xfs_sb_t, sb_width), 0 }, @@ -144,117 +73,10 @@ static struct { { sizeof(xfs_sb_t), 0 } }; -/* - * xfs_xlatesb - * data - on disk version of sb - * sb - a superblock - * dir - conversion direction: <0 - convert sb to buf - * >0 - convert buf to sb - * arch - architecture to read/write from/to buf - * fields - which fields to copy (bitmask) - */ -void -xfs_xlatesb( - void *data, - xfs_sb_t *sb, - int dir, - __int64_t fields) -{ - xfs_caddr_t buf_ptr; - xfs_caddr_t mem_ptr; - xfs_sb_field_t f; - int first; - int size; - - ASSERT(dir); - ASSERT(fields); - - if (!fields) - return; - - buf_ptr = (xfs_caddr_t)data; - mem_ptr = (xfs_caddr_t)sb; - - while (fields) { - f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); - first = xfs_sb_info[f].offset; - size = xfs_sb_info[f + 1].offset - first; - - ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); - - if (size == 1 || xfs_sb_info[f].type == 1) { - if (dir > 0) { - memcpy(mem_ptr + first, buf_ptr + first, size); - } else { - memcpy(buf_ptr + first, mem_ptr + first, size); - } - } else { - switch (size) { - case 2: - INT_XLATE(*(__uint16_t*)(buf_ptr+first), - *(__uint16_t*)(mem_ptr+first), - dir, ARCH_CONVERT); - break; - case 4: - INT_XLATE(*(__uint32_t*)(buf_ptr+first), - *(__uint32_t*)(mem_ptr+first), - dir, ARCH_CONVERT); - break; - case 8: - INT_XLATE(*(__uint64_t*)(buf_ptr+first), - *(__uint64_t*)(mem_ptr+first), dir, ARCH_CONVERT); - break; - default: - ASSERT(0); - } - } - - fields &= ~(1LL << f); - } -} - -/* - * xfs_mod_sb() can be used to copy arbitrary changes to the - * in-core superblock into the superblock buffer to be logged. - * It does not provide the higher level of locking that is - * needed to protect the in-core superblock from concurrent - * access. - */ -void -xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) -{ - xfs_buf_t *bp; - int first; - int last; - xfs_mount_t *mp; - xfs_sb_t *sbp; - xfs_sb_field_t f; - - ASSERT(fields); - if (!fields) - return; - mp = tp->t_mountp; - bp = xfs_trans_getsb(tp, mp, 0); - sbp = XFS_BUF_TO_SBP(bp); - first = sizeof(xfs_sb_t); - last = 0; - - /* translate/copy */ - xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), -1, fields); - - /* find modified range */ - f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); - ASSERT((1LL << f) & XFS_SB_MOD_BITS); - first = xfs_sb_info[f].offset; - f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields); - ASSERT((1LL << f) & XFS_SB_MOD_BITS); - last = xfs_sb_info[f + 1].offset - 1; - - xfs_trans_log_buf(tp, bp, first, last); -} - xfs_agnumber_t -xfs_initialize_perag(xfs_mount_t *mp, xfs_agnumber_t agcount) +xfs_initialize_perag( + xfs_mount_t *mp, + xfs_agnumber_t agcount) { xfs_agnumber_t index, max_metadata; xfs_perag_t *pag; @@ -270,7 +92,7 @@ xfs_initialize_perag(xfs_mount_t *mp, xfs_agnumber_t agcount) /* Clear the mount flag if no inode can overflow 32 bits * on this filesystem, or if specifically requested.. */ - if ((mp->m_flags & XFS_MOUNT_32BITINOOPT) && ino > max_inum) { + if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > max_inum) { mp->m_flags |= XFS_MOUNT_32BITINODES; } else { mp->m_flags &= ~XFS_MOUNT_32BITINODES; @@ -299,22 +121,205 @@ xfs_initialize_perag(xfs_mount_t *mp, xfs_agnumber_t agcount) break; } - /* This ag is prefered for inodes */ + /* This ag is preferred for inodes */ pag = &mp->m_perag[index]; pag->pagi_inodeok = 1; if (index < max_metadata) pag->pagf_metadata = 1; + xfs_initialize_perag_icache(pag); } } else { /* Setup default behavior for smaller filesystems */ for (index = 0; index < agcount; index++) { pag = &mp->m_perag[index]; pag->pagi_inodeok = 1; + xfs_initialize_perag_icache(pag); } } return index; } +void +xfs_sb_from_disk( + xfs_sb_t *to, + xfs_dsb_t *from) +{ + to->sb_magicnum = be32_to_cpu(from->sb_magicnum); + to->sb_blocksize = be32_to_cpu(from->sb_blocksize); + to->sb_dblocks = be64_to_cpu(from->sb_dblocks); + to->sb_rblocks = be64_to_cpu(from->sb_rblocks); + to->sb_rextents = be64_to_cpu(from->sb_rextents); + memcpy(&to->sb_uuid, &from->sb_uuid, sizeof(to->sb_uuid)); + to->sb_logstart = be64_to_cpu(from->sb_logstart); + to->sb_rootino = be64_to_cpu(from->sb_rootino); + to->sb_rbmino = be64_to_cpu(from->sb_rbmino); + to->sb_rsumino = be64_to_cpu(from->sb_rsumino); + to->sb_rextsize = be32_to_cpu(from->sb_rextsize); + to->sb_agblocks = be32_to_cpu(from->sb_agblocks); + to->sb_agcount = be32_to_cpu(from->sb_agcount); + to->sb_rbmblocks = be32_to_cpu(from->sb_rbmblocks); + to->sb_logblocks = be32_to_cpu(from->sb_logblocks); + to->sb_versionnum = be16_to_cpu(from->sb_versionnum); + to->sb_sectsize = be16_to_cpu(from->sb_sectsize); + to->sb_inodesize = be16_to_cpu(from->sb_inodesize); + to->sb_inopblock = be16_to_cpu(from->sb_inopblock); + memcpy(&to->sb_fname, &from->sb_fname, sizeof(to->sb_fname)); + to->sb_blocklog = from->sb_blocklog; + to->sb_sectlog = from->sb_sectlog; + to->sb_inodelog = from->sb_inodelog; + to->sb_inopblog = from->sb_inopblog; + to->sb_agblklog = from->sb_agblklog; + to->sb_rextslog = from->sb_rextslog; + to->sb_inprogress = from->sb_inprogress; + to->sb_imax_pct = from->sb_imax_pct; + to->sb_icount = be64_to_cpu(from->sb_icount); + to->sb_ifree = be64_to_cpu(from->sb_ifree); + to->sb_fdblocks = be64_to_cpu(from->sb_fdblocks); + to->sb_frextents = be64_to_cpu(from->sb_frextents); + to->sb_uquotino = be64_to_cpu(from->sb_uquotino); + to->sb_gquotino = be64_to_cpu(from->sb_gquotino); + to->sb_qflags = be16_to_cpu(from->sb_qflags); + to->sb_flags = from->sb_flags; + to->sb_shared_vn = from->sb_shared_vn; + to->sb_inoalignmt = be32_to_cpu(from->sb_inoalignmt); + to->sb_unit = be32_to_cpu(from->sb_unit); + to->sb_width = be32_to_cpu(from->sb_width); + to->sb_dirblklog = from->sb_dirblklog; + to->sb_logsectlog = from->sb_logsectlog; + to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize); + to->sb_logsunit = be32_to_cpu(from->sb_logsunit); + to->sb_features2 = be32_to_cpu(from->sb_features2); + to->sb_bad_features2 = be32_to_cpu(from->sb_bad_features2); +} + +/* + * Copy in core superblock to ondisk one. + * + * The fields argument is mask of superblock fields to copy. + */ +void +xfs_sb_to_disk( + xfs_dsb_t *to, + xfs_sb_t *from, + __int64_t fields) +{ + xfs_caddr_t to_ptr = (xfs_caddr_t)to; + xfs_caddr_t from_ptr = (xfs_caddr_t)from; + xfs_sb_field_t f; + int first; + int size; + + ASSERT(fields); + if (!fields) + return; + + while (fields) { + f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); + first = xfs_sb_info[f].offset; + size = xfs_sb_info[f + 1].offset - first; + + ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); + + if (size == 1 || xfs_sb_info[f].type == 1) { + memcpy(to_ptr + first, from_ptr + first, size); + } else { + switch (size) { + case 2: + *(__be16 *)(to_ptr + first) = + cpu_to_be16(*(__u16 *)(from_ptr + first)); + break; + case 4: + *(__be32 *)(to_ptr + first) = + cpu_to_be32(*(__u32 *)(from_ptr + first)); + break; + case 8: + *(__be64 *)(to_ptr + first) = + cpu_to_be64(*(__u64 *)(from_ptr + first)); + break; + default: + ASSERT(0); + } + } + + fields &= ~(1LL << f); + } +} + +/* + * xfs_mount_common + * + * Mount initialization code establishing various mount + * fields from the superblock associated with the given + * mount structure + * + * Note: this requires user-space public scope for libxfs_mount + */ +void +xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp) +{ + int i; + + mp->m_agfrotor = mp->m_agirotor = 0; + spin_lock_init(&mp->m_agirotor_lock); + mp->m_maxagi = mp->m_sb.sb_agcount; + mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG; + mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT; + mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT; + mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1; + mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog; + mp->m_litino = sbp->sb_inodesize - + ((uint)sizeof(xfs_dinode_core_t) + (uint)sizeof(xfs_agino_t)); + mp->m_blockmask = sbp->sb_blocksize - 1; + mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; + mp->m_blockwmask = mp->m_blockwsize - 1; + INIT_LIST_HEAD(&mp->m_del_inodes); + + /* + * Setup for attributes, in case they get created. + * This value is for inodes getting attributes for the first time, + * the per-inode value is for old attribute values. + */ + ASSERT(sbp->sb_inodesize >= 256 && sbp->sb_inodesize <= 2048); + switch (sbp->sb_inodesize) { + case 256: + mp->m_attroffset = XFS_LITINO(mp) - + XFS_BMDR_SPACE_CALC(MINABTPTRS); + break; + case 512: + case 1024: + case 2048: + mp->m_attroffset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS); + break; + default: + ASSERT(0); + } + ASSERT(mp->m_attroffset < XFS_LITINO(mp)); + + for (i = 0; i < 2; i++) { + mp->m_alloc_mxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize, + xfs_alloc, i == 0); + mp->m_alloc_mnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize, + xfs_alloc, i == 0); + } + for (i = 0; i < 2; i++) { + mp->m_bmap_dmxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize, + xfs_bmbt, i == 0); + mp->m_bmap_dmnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize, + xfs_bmbt, i == 0); + } + for (i = 0; i < 2; i++) { + mp->m_inobt_mxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize, + xfs_inobt, i == 0); + mp->m_inobt_mnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize, + xfs_inobt, i == 0); + } + + mp->m_bsize = XFS_FSB_TO_BB(mp, 1); + mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK, + sbp->sb_inopblock); + mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog; +} + /* * xfs_initialize_perag_data * @@ -322,25 +327,26 @@ xfs_initialize_perag(xfs_mount_t *mp, xfs_agnumber_t agcount) * allocated inodes, free inodes and used filesystem blocks as this * information is no longer persistent in the superblock. Once we have * this information, write it into the in-core superblock structure. + * + * Note: this requires user-space public scope for libxfs_mount */ -STATIC int +int xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount) { xfs_agnumber_t index; xfs_perag_t *pag; xfs_sb_t *sbp = &mp->m_sb; - __uint64_t ifree = 0; - __uint64_t ialloc = 0; - __uint64_t bfree = 0; - __uint64_t bfreelst = 0; - __uint64_t btree = 0; + uint64_t ifree = 0; + uint64_t ialloc = 0; + uint64_t bfree = 0; + uint64_t bfreelst = 0; + uint64_t btree = 0; int error; - int s; for (index = 0; index < agcount; index++) { /* * read the agf, then the agi. This gets us - * all the information we need and populates the + * all the inforamtion we need and populates the * per-ag structures for us. */ error = xfs_alloc_pagf_init(mp, NULL, index, 0); @@ -360,10 +366,55 @@ xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount) /* * Overwrite incore superblock counters with just-read data */ - s = XFS_SB_LOCK(mp); + spin_lock(&mp->m_sb_lock); sbp->sb_ifree = ifree; sbp->sb_icount = ialloc; sbp->sb_fdblocks = bfree + bfreelst + btree; - XFS_SB_UNLOCK(mp, s); + spin_unlock(&mp->m_sb_lock); + + /* Fixup the per-cpu counters as well. */ + xfs_icsb_reinit_counters(mp); + return 0; } + +/* + * xfs_mod_sb() can be used to copy arbitrary changes to the + * in-core superblock into the superblock buffer to be logged. + * It does not provide the higher level of locking that is + * needed to protect the in-core superblock from concurrent + * access. + */ +void +xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) +{ + xfs_buf_t *bp; + int first; + int last; + xfs_mount_t *mp; + xfs_sb_field_t f; + + ASSERT(fields); + if (!fields) + return; + mp = tp->t_mountp; + bp = xfs_trans_getsb(tp, mp, 0); + first = sizeof(xfs_sb_t); + last = 0; + + /* translate/copy */ + + xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields); + + /* find modified range */ + + f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); + ASSERT((1LL << f) & XFS_SB_MOD_BITS); + first = xfs_sb_info[f].offset; + + f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields); + ASSERT((1LL << f) & XFS_SB_MOD_BITS); + last = xfs_sb_info[f + 1].offset - 1; + + xfs_trans_log_buf(tp, bp, first, last); +} diff --git a/libxfs/xfs_rtalloc.c b/libxfs/xfs_rtalloc.c index 22519bf36..6c3da528f 100644 --- a/libxfs/xfs_rtalloc.c +++ b/libxfs/xfs_rtalloc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -16,13 +16,25 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + /* - * Free realtime space allocation for XFS. + * Prototypes for internal functions. */ -#include -extern int xfs_lowbit32(__uint32_t); +STATIC int xfs_rtfind_back(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t, + xfs_rtblock_t, xfs_rtblock_t *); +STATIC int xfs_rtfind_forw(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t, + xfs_rtblock_t, xfs_rtblock_t *); +STATIC int xfs_rtmodify_range(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t, + xfs_extlen_t, int); +STATIC int xfs_rtmodify_summary(xfs_mount_t *, xfs_trans_t *, int, + xfs_rtblock_t, int, xfs_buf_t **, xfs_fsblock_t *); + +/* + * Internal functions. + */ /* * Get a buffer for the bitmap or summary file block specified. @@ -731,10 +743,9 @@ xfs_rtfree_extent( /* * Synchronize by locking the bitmap inode. */ - error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, XFS_ILOCK_EXCL, &ip); - if (error) { + if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, + XFS_ILOCK_EXCL, &ip))) return error; - } #if defined(__KERNEL__) && defined(DEBUG) /* * Check to see that this whole range is currently allocated. @@ -774,52 +785,3 @@ xfs_rtfree_extent( } return 0; } - -/* - * Pick an extent for allocation at the start of a new realtime file. - * Use the sequence number stored in the atime field of the bitmap inode. - * Translate this to a fraction of the rtextents, and return the product - * of rtextents and the fraction. - * The fraction sequence is 0, 1/2, 1/4, 3/4, 1/8, ..., 7/8, 1/16, ... - */ -int /* error */ -xfs_rtpick_extent( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_extlen_t len, /* allocation length (rtextents) */ - xfs_rtblock_t *pick) /* result rt extent */ -{ - xfs_rtblock_t b; /* result block */ - int error; /* error return value */ - xfs_inode_t *ip; /* bitmap incore inode */ - int log2; /* log of sequence number */ - __uint64_t resid; /* residual after log removed */ - __uint64_t seq; /* sequence number of file creation */ - __uint64_t *seqp; /* pointer to seqno in inode */ - - error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, XFS_ILOCK_EXCL, &ip); - if (error) - return error; - ASSERT(ip == mp->m_rbmip); - seqp = (__uint64_t *)&ip->i_d.di_atime; - if (!(ip->i_d.di_flags & XFS_DIFLAG_NEWRTBM)) { - ip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM; - *seqp = 0; - } - seq = *seqp; - if ((log2 = xfs_highbit64(seq)) == -1) - b = 0; - else { - resid = seq - (1ULL << log2); - b = (mp->m_sb.sb_rextents * ((resid << 1) + 1ULL)) >> - (log2 + 1); - if (b >= mp->m_sb.sb_rextents) - b = do_mod(b, mp->m_sb.sb_rextents); - if (b + len > mp->m_sb.sb_rextents) - b = mp->m_sb.sb_rextents - len; - } - *seqp = seq + 1; - xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - *pick = b; - return 0; -} diff --git a/libxfs/xfs_trans.c b/libxfs/xfs_trans.c index d827de221..903699560 100644 --- a/libxfs/xfs_trans.c +++ b/libxfs/xfs_trans.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -18,6 +18,137 @@ #include +/* + * Reservation functions here avoid a huge stack in xfs_trans_init + * due to register overflow from temporaries in the calculations. + */ + +STATIC uint +xfs_calc_write_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_WRITE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); +} + +STATIC uint +xfs_calc_itruncate_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_ITRUNCATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); +} + +STATIC uint +xfs_calc_rename_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_RENAME_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); +} + +STATIC uint +xfs_calc_link_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_LINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); +} + +STATIC uint +xfs_calc_remove_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_REMOVE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); +} + +STATIC uint +xfs_calc_symlink_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_SYMLINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); +} + +STATIC uint +xfs_calc_create_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_CREATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); +} + +STATIC uint +xfs_calc_mkdir_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_MKDIR_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); +} + +STATIC uint +xfs_calc_ifree_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_IFREE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); +} + +STATIC uint +xfs_calc_ichange_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_ICHANGE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); +} + +STATIC uint +xfs_calc_growdata_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_GROWDATA_LOG_RES(mp); +} + +STATIC uint +xfs_calc_growrtalloc_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_GROWRTALLOC_LOG_RES(mp); +} + +STATIC uint +xfs_calc_growrtzero_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_GROWRTZERO_LOG_RES(mp); +} + +STATIC uint +xfs_calc_growrtfree_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_GROWRTFREE_LOG_RES(mp); +} + +STATIC uint +xfs_calc_swrite_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_SWRITE_LOG_RES(mp); +} + +STATIC uint +xfs_calc_writeid_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_WRITEID_LOG_RES(mp); +} + +STATIC uint +xfs_calc_addafork_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_ADDAFORK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); +} + +STATIC uint +xfs_calc_attrinval_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_ATTRINVAL_LOG_RES(mp); +} + +STATIC uint +xfs_calc_attrset_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_ATTRSET_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); +} + +STATIC uint +xfs_calc_attrrm_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_ATTRRM_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); +} + +STATIC uint +xfs_calc_clear_agi_bucket_reservation(xfs_mount_t *mp) +{ + return XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp); +} + /* * Initialize the precomputed transaction reservation values * in the mount structure. @@ -29,37 +160,89 @@ xfs_trans_init( xfs_trans_reservations_t *resp; resp = &(mp->m_reservations); - resp->tr_write = - (uint)(XFS_CALC_WRITE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp)); - resp->tr_itruncate = - (uint)(XFS_CALC_ITRUNCATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp)); - resp->tr_rename = - (uint)(XFS_CALC_RENAME_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp)); - resp->tr_link = (uint)XFS_CALC_LINK_LOG_RES(mp); - resp->tr_remove = - (uint)(XFS_CALC_REMOVE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp)); - resp->tr_symlink = - (uint)(XFS_CALC_SYMLINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp)); - resp->tr_create = - (uint)(XFS_CALC_CREATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp)); - resp->tr_mkdir = - (uint)(XFS_CALC_MKDIR_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp)); - resp->tr_ifree = - (uint)(XFS_CALC_IFREE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp)); - resp->tr_ichange = - (uint)(XFS_CALC_ICHANGE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp)); - resp->tr_growdata = (uint)XFS_CALC_GROWDATA_LOG_RES(mp); - resp->tr_swrite = (uint)XFS_CALC_SWRITE_LOG_RES(mp); - resp->tr_writeid = (uint)XFS_CALC_WRITEID_LOG_RES(mp); - resp->tr_addafork = - (uint)(XFS_CALC_ADDAFORK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp)); - resp->tr_attrinval = (uint)XFS_CALC_ATTRINVAL_LOG_RES(mp); - resp->tr_attrset = - (uint)(XFS_CALC_ATTRSET_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp)); - resp->tr_attrrm = - (uint)(XFS_CALC_ATTRRM_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp)); - resp->tr_clearagi = (uint)XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp); - resp->tr_growrtalloc = (uint)XFS_CALC_GROWRTALLOC_LOG_RES(mp); - resp->tr_growrtzero = (uint)XFS_CALC_GROWRTZERO_LOG_RES(mp); - resp->tr_growrtfree = (uint)XFS_CALC_GROWRTFREE_LOG_RES(mp); + resp->tr_write = xfs_calc_write_reservation(mp); + resp->tr_itruncate = xfs_calc_itruncate_reservation(mp); + resp->tr_rename = xfs_calc_rename_reservation(mp); + resp->tr_link = xfs_calc_link_reservation(mp); + resp->tr_remove = xfs_calc_remove_reservation(mp); + resp->tr_symlink = xfs_calc_symlink_reservation(mp); + resp->tr_create = xfs_calc_create_reservation(mp); + resp->tr_mkdir = xfs_calc_mkdir_reservation(mp); + resp->tr_ifree = xfs_calc_ifree_reservation(mp); + resp->tr_ichange = xfs_calc_ichange_reservation(mp); + resp->tr_growdata = xfs_calc_growdata_reservation(mp); + resp->tr_swrite = xfs_calc_swrite_reservation(mp); + resp->tr_writeid = xfs_calc_writeid_reservation(mp); + resp->tr_addafork = xfs_calc_addafork_reservation(mp); + resp->tr_attrinval = xfs_calc_attrinval_reservation(mp); + resp->tr_attrset = xfs_calc_attrset_reservation(mp); + resp->tr_attrrm = xfs_calc_attrrm_reservation(mp); + resp->tr_clearagi = xfs_calc_clear_agi_bucket_reservation(mp); + resp->tr_growrtalloc = xfs_calc_growrtalloc_reservation(mp); + resp->tr_growrtzero = xfs_calc_growrtzero_reservation(mp); + resp->tr_growrtfree = xfs_calc_growrtfree_reservation(mp); } + +/* + * Roll from one trans in the sequence of PERMANENT transactions to + * the next: permanent transactions are only flushed out when + * committed with XFS_TRANS_RELEASE_LOG_RES, but we still want as soon + * as possible to let chunks of it go to the log. So we commit the + * chunk we've been working on and get a new transaction to continue. + */ +int +xfs_trans_roll( + struct xfs_trans **tpp, + struct xfs_inode *dp) +{ + struct xfs_trans *trans; + unsigned int logres, count; + int error; + + /* + * Ensure that the inode is always logged. + */ + trans = *tpp; + xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE); + + /* + * Copy the critical parameters from one trans to the next. + */ + logres = trans->t_log_res; + count = trans->t_log_count; + *tpp = xfs_trans_dup(trans); + + /* + * Commit the current transaction. + * If this commit failed, then it'd just unlock those items that + * are not marked ihold. That also means that a filesystem shutdown + * is in progress. The caller takes the responsibility to cancel + * the duplicate transaction that gets returned. + */ + error = xfs_trans_commit(trans, 0); + if (error) + return (error); + + trans = *tpp; + + /* + * Reserve space in the log for th next transaction. + * This also pushes items in the "AIL", the list of logged items, + * out to disk if they are taking up space at the tail of the log + * that we want to use. This requires that either nothing be locked + * across this call, or that anything that is locked be logged in + * the prior and the next transactions. + */ + error = xfs_trans_reserve(trans, 0, logres, 0, + XFS_TRANS_PERM_LOG_RES, count); + /* + * Ensure that the inode is in the new transaction and locked. + */ + if (error) + return error; + + xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL); + xfs_trans_ihold(trans, dp); + return 0; +} + diff --git a/libxlog/Makefile b/libxlog/Makefile index 475a9e63e..988d01cd8 100644 --- a/libxlog/Makefile +++ b/libxlog/Makefile @@ -19,7 +19,4 @@ default: $(LTLIBRARY) include $(BUILDRULES) -install: default - -install-dev: default - $(INSTALL_LTLIB_STATIC) +install install-dev install-qa: default diff --git a/libxlog/util.c b/libxlog/util.c index 1410d0581..949b79d6c 100644 --- a/libxlog/util.c +++ b/libxlog/util.c @@ -48,24 +48,24 @@ xlog_header_check_recover(xfs_mount_t *mp, xlog_rec_header_t *head) { if (print_record_header) printf(_("\nLOG REC AT LSN cycle %d block %d (0x%x, 0x%x)\n"), - CYCLE_LSN(INT_GET(head->h_lsn, ARCH_CONVERT)), - BLOCK_LSN(INT_GET(head->h_lsn, ARCH_CONVERT)), - CYCLE_LSN(INT_GET(head->h_lsn, ARCH_CONVERT)), - BLOCK_LSN(INT_GET(head->h_lsn, ARCH_CONVERT))); + CYCLE_LSN(be64_to_cpu(head->h_lsn)), + BLOCK_LSN(be64_to_cpu(head->h_lsn)), + CYCLE_LSN(be64_to_cpu(head->h_lsn)), + BLOCK_LSN(be64_to_cpu(head->h_lsn))); - if (INT_GET(head->h_magicno, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM) { + if (be32_to_cpu(head->h_magicno) != XLOG_HEADER_MAGIC_NUM) { printf(_("* ERROR: bad magic number in log header: 0x%x\n"), - INT_GET(head->h_magicno, ARCH_CONVERT)); + be32_to_cpu(head->h_magicno)); } else if (header_check_uuid(mp, head)) { /* failed - fall through */ - } else if (INT_GET(head->h_fmt, ARCH_CONVERT) != XLOG_FMT) { + } else if (be32_to_cpu(head->h_fmt) != XLOG_FMT) { printf(_("* ERROR: log format incompatible (log=%d, ours=%d)\n"), - INT_GET(head->h_fmt, ARCH_CONVERT), XLOG_FMT); + be32_to_cpu(head->h_fmt), XLOG_FMT); } else { /* everything is ok */ diff --git a/libxlog/xfs_log_recover.c b/libxlog/xfs_log_recover.c index 91a1a50b8..9e0e5678d 100644 --- a/libxlog/xfs_log_recover.c +++ b/libxlog/xfs_log_recover.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -22,6 +22,8 @@ #define xlog_clear_stale_blocks(log, tail_lsn) (0) #define xfs_readonly_buftarg(buftarg) (0) +STATIC void xlog_recover_insert_item_backq(xlog_recover_item_t **q, + xlog_recover_item_t *item); /* * Sector aligned buffer routines for buffer create/read/write/access @@ -124,7 +126,7 @@ xlog_find_cycle_start( if ((error = xlog_bread(log, mid_blk, 1, bp))) return error; offset = xlog_align(log, mid_blk, 1, bp); - mid_cycle = GET_CYCLE(offset, ARCH_CONVERT); + mid_cycle = xlog_get_cycle(offset); if (mid_cycle == cycle) { *last_blk = mid_blk; /* last_half_cycle == mid_cycle */ @@ -184,7 +186,7 @@ xlog_find_verify_cycle( buf = xlog_align(log, i, bcount, bp); for (j = 0; j < bcount; j++) { - cycle = GET_CYCLE(buf, ARCH_CONVERT); + cycle = xlog_get_cycle(buf); if (cycle == stop_on_cycle_no) { *new_blk = i+j; goto out; @@ -260,8 +262,7 @@ xlog_find_verify_log_record( head = (xlog_rec_header_t *)offset; - if (XLOG_HEADER_MAGIC_NUM == - INT_GET(head->h_magicno, ARCH_CONVERT)) + if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(head->h_magicno)) break; if (!smallmem) @@ -292,8 +293,8 @@ xlog_find_verify_log_record( * reset last_blk. Only when last_blk points in the middle of a log * record do we update last_blk. */ - if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { - uint h_size = INT_GET(head->h_size, ARCH_CONVERT); + if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { + uint h_size = be32_to_cpu(head->h_size); xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE; if (h_size % XLOG_HEADER_CYCLE_SIZE) @@ -302,8 +303,8 @@ xlog_find_verify_log_record( xhdrs = 1; } - if (*last_blk - i + extra_bblks - != BTOBB(INT_GET(head->h_len, ARCH_CONVERT)) + xhdrs) + if (*last_blk - i + extra_bblks != + BTOBB(be32_to_cpu(head->h_len)) + xhdrs) *last_blk = i; out: @@ -364,13 +365,13 @@ xlog_find_head( if ((error = xlog_bread(log, 0, 1, bp))) goto bp_err; offset = xlog_align(log, 0, 1, bp); - first_half_cycle = GET_CYCLE(offset, ARCH_CONVERT); + first_half_cycle = xlog_get_cycle(offset); last_blk = head_blk = log_bbnum - 1; /* get cycle # of last block */ if ((error = xlog_bread(log, last_blk, 1, bp))) goto bp_err; offset = xlog_align(log, last_blk, 1, bp); - last_half_cycle = GET_CYCLE(offset, ARCH_CONVERT); + last_half_cycle = xlog_get_cycle(offset); ASSERT(last_half_cycle != 0); /* @@ -395,7 +396,7 @@ xlog_find_head( * x | x ... | x - 1 | x * Another case that fits this picture would be * x | x + 1 | x ... | x - * In this case the head really is somwhere at the end of the + * In this case the head really is somewhere at the end of the * log, as one of the latest writes at the beginning was * incomplete. * One more case is @@ -595,8 +596,7 @@ int xlog_find_tail( xlog_t *log, xfs_daddr_t *head_blk, - xfs_daddr_t *tail_blk, - int readonly) + xfs_daddr_t *tail_blk) { xlog_rec_header_t *rhead; xlog_op_header_t *op_head; @@ -623,7 +623,7 @@ xlog_find_tail( if ((error = xlog_bread(log, 0, 1, bp))) goto bread_err; offset = xlog_align(log, 0, 1, bp); - if (GET_CYCLE(offset, ARCH_CONVERT) == 0) { + if (xlog_get_cycle(offset) == 0) { *tail_blk = 0; /* leave all other log inited values alone */ goto exit; @@ -638,8 +638,7 @@ xlog_find_tail( if ((error = xlog_bread(log, i, 1, bp))) goto bread_err; offset = xlog_align(log, i, 1, bp); - if (XLOG_HEADER_MAGIC_NUM == - INT_GET(*(uint *)offset, ARCH_CONVERT)) { + if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(*(__be32 *)offset)) { found = 1; break; } @@ -656,7 +655,7 @@ xlog_find_tail( goto bread_err; offset = xlog_align(log, i, 1, bp); if (XLOG_HEADER_MAGIC_NUM == - INT_GET(*(uint*)offset, ARCH_CONVERT)) { + be32_to_cpu(*(__be32 *)offset)) { found = 2; break; } @@ -670,7 +669,7 @@ xlog_find_tail( /* find blk_no of tail of log */ rhead = (xlog_rec_header_t *)offset; - *tail_blk = BLOCK_LSN(INT_GET(rhead->h_tail_lsn, ARCH_CONVERT)); + *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn)); /* * Reset log values according to the state of the log when we @@ -684,11 +683,11 @@ xlog_find_tail( */ log->l_prev_block = i; log->l_curr_block = (int)*head_blk; - log->l_curr_cycle = INT_GET(rhead->h_cycle, ARCH_CONVERT); + log->l_curr_cycle = be32_to_cpu(rhead->h_cycle); if (found == 2) log->l_curr_cycle++; - log->l_tail_lsn = INT_GET(rhead->h_tail_lsn, ARCH_CONVERT); - log->l_last_sync_lsn = INT_GET(rhead->h_lsn, ARCH_CONVERT); + log->l_tail_lsn = be64_to_cpu(rhead->h_tail_lsn); + log->l_last_sync_lsn = be64_to_cpu(rhead->h_lsn); log->l_grant_reserve_cycle = log->l_curr_cycle; log->l_grant_reserve_bytes = BBTOB(log->l_curr_block); log->l_grant_write_cycle = log->l_curr_cycle; @@ -705,9 +704,9 @@ xlog_find_tail( * unmount record if there is one, so we pass the lsn of the * unmount record rather than the block after it. */ - if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { - int h_size = INT_GET(rhead->h_size, ARCH_CONVERT); - int h_version = INT_GET(rhead->h_version, ARCH_CONVERT); + if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { + int h_size = be32_to_cpu(rhead->h_size); + int h_version = be32_to_cpu(rhead->h_version); if ((h_version & XLOG_VERSION_2) && (h_size > XLOG_HEADER_CYCLE_SIZE)) { @@ -721,10 +720,10 @@ xlog_find_tail( hblks = 1; } after_umount_blk = (i + hblks + (int) - BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT))) % log->l_logBBsize; + BTOBB(be32_to_cpu(rhead->h_len))) % log->l_logBBsize; tail_lsn = log->l_tail_lsn; if (*head_blk == after_umount_blk && - INT_GET(rhead->h_num_logops, ARCH_CONVERT) == 1) { + be32_to_cpu(rhead->h_num_logops) == 1) { umount_data_blk = (i + hblks) % log->l_logBBsize; if ((error = xlog_bread(log, umount_data_blk, 1, bp))) { goto bread_err; @@ -737,10 +736,12 @@ xlog_find_tail( * log records will point recovery to after the * current unmount record. */ - ASSIGN_ANY_LSN_HOST(log->l_tail_lsn, log->l_curr_cycle, - after_umount_blk); - ASSIGN_ANY_LSN_HOST(log->l_last_sync_lsn, log->l_curr_cycle, - after_umount_blk); + log->l_tail_lsn = + xlog_assign_lsn(log->l_curr_cycle, + after_umount_blk); + log->l_last_sync_lsn = + xlog_assign_lsn(log->l_curr_cycle, + after_umount_blk); *tail_blk = after_umount_blk; /* @@ -813,6 +814,8 @@ xlog_find_zeroed( xfs_daddr_t num_scan_bblks; int error, log_bbnum = log->l_logBBsize; + *blk_no = 0; + /* check totally zeroed log */ bp = xlog_get_bp(log, 1); if (!bp) @@ -820,7 +823,7 @@ xlog_find_zeroed( if ((error = xlog_bread(log, 0, 1, bp))) goto bp_err; offset = xlog_align(log, 0, 1, bp); - first_cycle = GET_CYCLE(offset, ARCH_CONVERT); + first_cycle = xlog_get_cycle(offset); if (first_cycle == 0) { /* completely zeroed log */ *blk_no = 0; xlog_put_bp(bp); @@ -831,7 +834,7 @@ xlog_find_zeroed( if ((error = xlog_bread(log, log_bbnum-1, 1, bp))) goto bp_err; offset = xlog_align(log, log_bbnum-1, 1, bp); - last_cycle = GET_CYCLE(offset, ARCH_CONVERT); + last_cycle = xlog_get_cycle(offset); if (last_cycle != 0) { /* log completely written to */ xlog_put_bp(bp); return 0; @@ -894,38 +897,10 @@ bp_err: return -1; } -STATIC void -xlog_unpack_data( - xlog_rec_header_t *rhead, - xfs_caddr_t dp, - xlog_t *log) -{ - int i, j, k; - xlog_in_core_2_t *xhdr; - - for (i = 0; i < BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)) && - i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) { - *(uint *)dp = *(uint *)&rhead->h_cycle_data[i]; - dp += BBSIZE; - } - - if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { - xhdr = (xlog_in_core_2_t *)rhead; - for ( ; i < BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); i++) { - j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); - k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); - *(uint *)dp = xhdr[j].hic_xheader.xh_cycle_data[k]; - dp += BBSIZE; - } - } - - xlog_unpack_data_checksum(rhead, dp, log); -} - STATIC xlog_recover_t * xlog_recover_find_tid( xlog_recover_t *q, - xlog_tid_t tid) + xlog_tid_t tid) { xlog_recover_t *p = q; @@ -939,119 +914,11 @@ xlog_recover_find_tid( STATIC void xlog_recover_put_hashq( - xlog_recover_t **q, - xlog_recover_t *trans) -{ - trans->r_next = *q; - *q = trans; -} - -STATIC void -xlog_recover_new_tid( - xlog_recover_t **q, - xlog_tid_t tid, - xfs_lsn_t lsn) -{ - xlog_recover_t *trans; - - trans = kmem_zalloc(sizeof(xlog_recover_t), KM_SLEEP); - trans->r_log_tid = tid; - trans->r_lsn = lsn; - xlog_recover_put_hashq(q, trans); -} - -STATIC int -xlog_recover_unlink_tid( xlog_recover_t **q, xlog_recover_t *trans) { - xlog_recover_t *tp; - int found = 0; - - ASSERT(trans != 0); - if (trans == *q) { - *q = (*q)->r_next; - } else { - tp = *q; - while (tp != 0) { - if (tp->r_next == trans) { - found = 1; - break; - } - tp = tp->r_next; - } - if (!found) { - xlog_warn( - "XFS: xlog_recover_unlink_tid: trans not found"); - ASSERT(0); - return XFS_ERROR(EIO); - } - tp->r_next = tp->r_next->r_next; - } - return 0; -} - -/* - * Free up any resources allocated by the transaction - * - * Remember that EFIs, EFDs, and IUNLINKs are handled later. - */ -STATIC void -xlog_recover_free_trans( - xlog_recover_t *trans) -{ - xlog_recover_item_t *first_item, *item, *free_item; - int i; - - item = first_item = trans->r_itemq; - do { - free_item = item; - item = item->ri_next; - /* Free the regions in the item. */ - for (i = 0; i < free_item->ri_cnt; i++) { - kmem_free(free_item->ri_buf[i].i_addr, - free_item->ri_buf[i].i_len); - } - /* Free the item itself */ - kmem_free(free_item->ri_buf, - (free_item->ri_total * sizeof(xfs_log_iovec_t))); - kmem_free(free_item, sizeof(xlog_recover_item_t)); - } while (first_item != item); - /* Free the transaction recover structure */ - kmem_free(trans, sizeof(xlog_recover_t)); -} - -STATIC int -xlog_recover_commit_trans( - xlog_t *log, - xlog_recover_t **q, - xlog_recover_t *trans, - int pass) -{ - int error; - - if ((error = xlog_recover_unlink_tid(q, trans))) - return error; - if ((error = xlog_recover_do_trans(log, trans, pass))) - return error; - xlog_recover_free_trans(trans); /* no error */ - return 0; -} - -STATIC void -xlog_recover_insert_item_backq( - xlog_recover_item_t **q, - xlog_recover_item_t *item) -{ - if (*q == 0) { - item->ri_prev = item->ri_next = item; - *q = item; - } else { - item->ri_next = *q; - item->ri_prev = (*q)->ri_prev; - (*q)->ri_prev = item; - item->ri_prev->ri_next = item; - } + trans->r_next = *q; + *q = trans; } STATIC void @@ -1075,7 +942,7 @@ xlog_recover_add_to_cont_trans( int old_len; item = trans->r_itemq; - if (item == 0) { + if (item == NULL) { /* finish copying rest of trans header */ xlog_recover_add_item(&trans->r_itemq); ptr = (xfs_caddr_t) &trans->r_theader + @@ -1121,7 +988,7 @@ xlog_recover_add_to_trans( if (!len) return 0; item = trans->r_itemq; - if (item == 0) { + if (item == NULL) { ASSERT(*(uint *)dp == XFS_TRANS_HEADER_MAGIC); if (len == sizeof(xfs_trans_header_t)) xlog_recover_add_item(&trans->r_itemq); @@ -1154,9 +1021,115 @@ xlog_recover_add_to_trans( return 0; } +STATIC void +xlog_recover_new_tid( + xlog_recover_t **q, + xlog_tid_t tid, + xfs_lsn_t lsn) +{ + xlog_recover_t *trans; + + trans = kmem_zalloc(sizeof(xlog_recover_t), KM_SLEEP); + trans->r_log_tid = tid; + trans->r_lsn = lsn; + xlog_recover_put_hashq(q, trans); +} + +STATIC int +xlog_recover_unlink_tid( + xlog_recover_t **q, + xlog_recover_t *trans) +{ + xlog_recover_t *tp; + int found = 0; + + ASSERT(trans != NULL); + if (trans == *q) { + *q = (*q)->r_next; + } else { + tp = *q; + while (tp) { + if (tp->r_next == trans) { + found = 1; + break; + } + tp = tp->r_next; + } + if (!found) { + xlog_warn( + "XFS: xlog_recover_unlink_tid: trans not found"); + ASSERT(0); + return XFS_ERROR(EIO); + } + tp->r_next = tp->r_next->r_next; + } + return 0; +} + +STATIC void +xlog_recover_insert_item_backq( + xlog_recover_item_t **q, + xlog_recover_item_t *item) +{ + if (*q == NULL) { + item->ri_prev = item->ri_next = item; + *q = item; + } else { + item->ri_next = *q; + item->ri_prev = (*q)->ri_prev; + (*q)->ri_prev = item; + item->ri_prev->ri_next = item; + } +} + +/* + * Free up any resources allocated by the transaction + * + * Remember that EFIs, EFDs, and IUNLINKs are handled later. + */ +STATIC void +xlog_recover_free_trans( + xlog_recover_t *trans) +{ + xlog_recover_item_t *first_item, *item, *free_item; + int i; + + item = first_item = trans->r_itemq; + do { + free_item = item; + item = item->ri_next; + /* Free the regions in the item. */ + for (i = 0; i < free_item->ri_cnt; i++) { + kmem_free(free_item->ri_buf[i].i_addr); + } + /* Free the item itself */ + kmem_free(free_item->ri_buf); + kmem_free(free_item); + } while (first_item != item); + /* Free the transaction recover structure */ + kmem_free(trans); +} + +STATIC int +xlog_recover_commit_trans( + xlog_t *log, + xlog_recover_t **q, + xlog_recover_t *trans, + int pass) +{ + int error; + + if ((error = xlog_recover_unlink_tid(q, trans))) + return error; + if ((error = xlog_recover_do_trans(log, trans, pass))) + return error; + xlog_recover_free_trans(trans); /* no error */ + return 0; +} + STATIC int xlog_recover_unmount_trans( - xlog_recover_t *trans) + xlog_recover_t *trans) { /* Do nothing now */ xlog_warn("XFS: xlog_recover_unmount_trans: Unmount LR"); @@ -1189,8 +1162,8 @@ xlog_recover_process_data( unsigned long hash; uint flags; - lp = dp + INT_GET(rhead->h_len, ARCH_CONVERT); - num_logops = INT_GET(rhead->h_num_logops, ARCH_CONVERT); + lp = dp + be32_to_cpu(rhead->h_len); + num_logops = be32_to_cpu(rhead->h_num_logops); /* check the log format matches our own - else we can't recover */ if (xlog_header_check_recover(log->l_mp, rhead)) @@ -1207,15 +1180,15 @@ xlog_recover_process_data( ASSERT(0); return (XFS_ERROR(EIO)); } - tid = INT_GET(ohead->oh_tid, ARCH_CONVERT); + tid = be32_to_cpu(ohead->oh_tid); hash = XLOG_RHASH(tid); trans = xlog_recover_find_tid(rhash[hash], tid); if (trans == NULL) { /* not found; add new tid */ if (ohead->oh_flags & XLOG_START_TRANS) xlog_recover_new_tid(&rhash[hash], tid, - INT_GET(rhead->h_lsn, ARCH_CONVERT)); + be64_to_cpu(rhead->h_lsn)); } else { - ASSERT(dp+INT_GET(ohead->oh_len, ARCH_CONVERT) <= lp); + ASSERT(dp + be32_to_cpu(ohead->oh_len) <= lp); flags = ohead->oh_flags & ~XLOG_END_TRANS; if (flags & XLOG_WAS_CONT_TRANS) flags &= ~XLOG_CONTINUE_TRANS; @@ -1229,8 +1202,7 @@ xlog_recover_process_data( break; case XLOG_WAS_CONT_TRANS: error = xlog_recover_add_to_cont_trans(trans, - dp, INT_GET(ohead->oh_len, - ARCH_CONVERT)); + dp, be32_to_cpu(ohead->oh_len)); break; case XLOG_START_TRANS: xlog_warn( @@ -1241,8 +1213,7 @@ xlog_recover_process_data( case 0: case XLOG_CONTINUE_TRANS: error = xlog_recover_add_to_trans(trans, - dp, INT_GET(ohead->oh_len, - ARCH_CONVERT)); + dp, be32_to_cpu(ohead->oh_len)); break; default: xlog_warn( @@ -1254,12 +1225,40 @@ xlog_recover_process_data( if (error) return error; } - dp += INT_GET(ohead->oh_len, ARCH_CONVERT); + dp += be32_to_cpu(ohead->oh_len); num_logops--; } return 0; } +STATIC void +xlog_unpack_data( + xlog_rec_header_t *rhead, + xfs_caddr_t dp, + xlog_t *log) +{ + int i, j, k; + xlog_in_core_2_t *xhdr; + + for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) && + i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) { + *(__be32 *)dp = *(__be32 *)&rhead->h_cycle_data[i]; + dp += BBSIZE; + } + + if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { + xhdr = (xlog_in_core_2_t *)rhead; + for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) { + j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); + k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); + *(__be32 *)dp = xhdr[j].hic_xheader.xh_cycle_data[k]; + dp += BBSIZE; + } + } + + xlog_unpack_data_checksum(rhead, dp, log); +} + STATIC int xlog_valid_rec_header( xlog_t *log, @@ -1268,24 +1267,21 @@ xlog_valid_rec_header( { int hlen; - if (unlikely( - (INT_GET(rhead->h_magicno, ARCH_CONVERT) != - XLOG_HEADER_MAGIC_NUM))) { + if (unlikely(be32_to_cpu(rhead->h_magicno) != XLOG_HEADER_MAGIC_NUM)) { XFS_ERROR_REPORT("xlog_valid_rec_header(1)", XFS_ERRLEVEL_LOW, log->l_mp); return XFS_ERROR(EFSCORRUPTED); } if (unlikely( (!rhead->h_version || - (INT_GET(rhead->h_version, ARCH_CONVERT) & - (~XLOG_VERSION_OKBITS)) != 0))) { + (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) { xlog_warn("XFS: %s: unrecognised log version (%d).", - __FUNCTION__, INT_GET(rhead->h_version, ARCH_CONVERT)); + __func__, be32_to_cpu(rhead->h_version)); return XFS_ERROR(EIO); } /* LR body must have data or it wouldn't have been written */ - hlen = INT_GET(rhead->h_len, ARCH_CONVERT); + hlen = be32_to_cpu(rhead->h_len); if (unlikely( hlen <= 0 || hlen > INT_MAX )) { XFS_ERROR_REPORT("xlog_valid_rec_header(2)", XFS_ERRLEVEL_LOW, log->l_mp); @@ -1329,7 +1325,7 @@ xlog_do_recovery_pass( * Read the header of the tail block and get the iclog buffer size from * h_size. Use this to tell how many sectors make up the log header. */ - if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { + if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { /* * When using variable length iclogs, read first sector of * iclog header and extract the header size from it. Get a @@ -1345,9 +1341,8 @@ xlog_do_recovery_pass( error = xlog_valid_rec_header(log, rhead, tail_blk); if (error) goto bread_err1; - h_size = INT_GET(rhead->h_size, ARCH_CONVERT); - if ((INT_GET(rhead->h_version, ARCH_CONVERT) - & XLOG_VERSION_2) && + h_size = be32_to_cpu(rhead->h_size); + if ((be32_to_cpu(rhead->h_version) & XLOG_VERSION_2) && (h_size > XLOG_HEADER_CYCLE_SIZE)) { hblks = h_size / XLOG_HEADER_CYCLE_SIZE; if (h_size % XLOG_HEADER_CYCLE_SIZE) @@ -1384,7 +1379,7 @@ xlog_do_recovery_pass( goto bread_err2; /* blocks in data section */ - bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); + bblks = (int)BTOBB(be32_to_cpu(rhead->h_len)); error = xlog_bread(log, blk_no + hblks, bblks, dbp); if (error) goto bread_err2; @@ -1440,11 +1435,11 @@ xlog_do_recovery_pass( * _first_, then the log start (LR header end) * - order is important. */ + wrapped_hblks = hblks - split_hblks; bufaddr = XFS_BUF_PTR(hbp); XFS_BUF_SET_PTR(hbp, bufaddr + BBTOB(split_hblks), BBTOB(hblks - split_hblks)); - wrapped_hblks = hblks - split_hblks; error = xlog_bread(log, 0, wrapped_hblks, hbp); if (error) goto bread_err2; @@ -1459,7 +1454,7 @@ xlog_do_recovery_pass( if (error) goto bread_err2; - bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); + bblks = (int)BTOBB(be32_to_cpu(rhead->h_len)); blk_no += hblks; /* Read in data for log record */ @@ -1503,8 +1498,9 @@ xlog_do_recovery_pass( XFS_BUF_SET_PTR(dbp, bufaddr + BBTOB(split_bblks), BBTOB(bblks - split_bblks)); - if ((error = xlog_bread(log, wrapped_hblks, - bblks - split_bblks, dbp))) + error = xlog_bread(log, wrapped_hblks, + bblks - split_bblks, dbp); + if (error) goto bread_err2; XFS_BUF_SET_PTR(dbp, bufaddr, h_size); if (!offset) @@ -1530,7 +1526,7 @@ xlog_do_recovery_pass( error = xlog_valid_rec_header(log, rhead, blk_no); if (error) goto bread_err2; - bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); + bblks = (int)BTOBB(be32_to_cpu(rhead->h_len)); if ((error = xlog_bread(log, blk_no+hblks, bblks, dbp))) goto bread_err2; offset = xlog_align(log, blk_no+hblks, bblks, dbp); diff --git a/logprint/log_dump.c b/logprint/log_dump.c index 0630954b7..8bcd94e5f 100644 --- a/logprint/log_dump.c +++ b/logprint/log_dump.c @@ -50,24 +50,24 @@ xfs_log_dump( break; } - if (CYCLE_LSN(INT_GET(*(xfs_lsn_t *)buf, ARCH_CONVERT)) == + if (CYCLE_LSN(be64_to_cpu(*(__be64 *)buf)) == XLOG_HEADER_MAGIC_NUM && !print_no_data) { printf( "%6lld HEADER Cycle %d tail %d:%06d len %6d ops %d\n", (long long)blkno, - INT_GET(hdr->h_cycle, ARCH_CONVERT), - CYCLE_LSN(INT_GET(hdr->h_tail_lsn, ARCH_CONVERT)), - BLOCK_LSN(INT_GET(hdr->h_tail_lsn, ARCH_CONVERT)), - INT_GET(hdr->h_len, ARCH_CONVERT), - INT_GET(hdr->h_num_logops, ARCH_CONVERT)); + be32_to_cpu(hdr->h_cycle), + CYCLE_LSN(be64_to_cpu(hdr->h_tail_lsn)), + BLOCK_LSN(be64_to_cpu(hdr->h_tail_lsn)), + be32_to_cpu(hdr->h_len), + be32_to_cpu(hdr->h_num_logops)); } - if (GET_CYCLE(buf, ARCH_CONVERT) != last_cycle) { + if (xlog_get_cycle(buf) != last_cycle) { printf( "[%05lld - %05lld] Cycle 0x%08x New Cycle 0x%08x\n", (long long)dupblkno, (long long)blkno, - last_cycle, GET_CYCLE(buf, ARCH_CONVERT)); - last_cycle = GET_CYCLE(buf, ARCH_CONVERT); + last_cycle, xlog_get_cycle(buf)); + last_cycle = xlog_get_cycle(buf); dupblkno = blkno; } } diff --git a/logprint/log_misc.c b/logprint/log_misc.c index 025cd7cc4..6d1428ee6 100644 --- a/logprint/log_misc.c +++ b/logprint/log_misc.c @@ -25,6 +25,8 @@ #define BAD_HEADER (-1) #define NO_ERROR (0) +#define XLOG_SET(f,b) (((f) & (b)) == (b)) + static int logBBsize; char *trans_type[] = { "", @@ -78,7 +80,7 @@ typedef struct xlog_split_item { int si_skip; } xlog_split_item_t; -xlog_split_item_t *split_list = 0; +xlog_split_item_t *split_list = NULL; void print_xlog_op_line(void) @@ -127,8 +129,8 @@ xlog_print_op_header(xlog_op_header_t *op_head, op_head = &hbuf; *ptr += sizeof(xlog_op_header_t); printf("Oper (%d): tid: %x len: %d clientid: %s ", i, - INT_GET(op_head->oh_tid, ARCH_CONVERT), - INT_GET(op_head->oh_len, ARCH_CONVERT), + be32_to_cpu(op_head->oh_tid), + be32_to_cpu(op_head->oh_len), (op_head->oh_clientid == XFS_TRANSACTION ? "TRANS" : (op_head->oh_clientid == XFS_LOG ? "LOG" : "ERROR"))); printf("flags: "); @@ -162,7 +164,7 @@ xlog_print_add_to_trans(xlog_tid_t tid, item->si_tid = tid; item->si_skip = skip; item->si_next = split_list; - item->si_prev = 0; + item->si_prev = NULL; if (split_list) split_list->si_prev = item; split_list = item; @@ -213,7 +215,7 @@ xlog_print_trans_header(xfs_caddr_t *ptr, int len) *ptr += len; - magic=*(__uint32_t*)cptr; /* XXX INT_GET soon */ + magic=*(__uint32_t*)cptr; /* XXX be32_to_cpu soon */ if (len >= 4) { #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -239,18 +241,17 @@ int xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops) { xfs_buf_log_format_t *f; - xfs_buf_log_format_v1_t *old_f; xfs_agi_t *agi; xfs_agf_t *agf; xfs_disk_dquot_t *dq; - xlog_op_header_t *head = 0; + xlog_op_header_t *head = NULL; int num, skip; int super_block = 0; int bucket, col, buckets; __int64_t blkno; xfs_buf_log_format_t lbuf; int size, blen, map_size, struct_size; - long long x, y; + __be64 x, y; ushort flags; /* @@ -261,36 +262,15 @@ xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops) f = &lbuf; *ptr += len; - if (f->blf_type == XFS_LI_BUF) { - blkno = f->blf_blkno; - size = f->blf_size; - blen = f->blf_len; - map_size = f->blf_map_size; - flags = f->blf_flags; - struct_size = sizeof(xfs_buf_log_format_t); - } else { - old_f = (xfs_buf_log_format_v1_t*)f; - blkno = old_f->blf_blkno; - size = old_f->blf_size; - blen = old_f->blf_len; - map_size = old_f->blf_map_size; - flags = f->blf_flags; - struct_size = sizeof(xfs_buf_log_format_v1_t); - } - switch (f->blf_type) { - case XFS_LI_BUF: - printf("BUF: "); - break; - case XFS_LI_6_1_BUF: - printf("6.1 BUF: "); - break; - case XFS_LI_5_3_BUF: - printf("5.3 BUF: "); - break; - default: - printf("UNKNOWN BUF: "); - break; - } + ASSERT(f->blf_type == XFS_LI_BUF); + printf("BUF: "); + blkno = f->blf_blkno; + size = f->blf_size; + blen = f->blf_len; + map_size = f->blf_map_size; + flags = f->blf_flags; + struct_size = sizeof(xfs_buf_log_format_t); + if (len >= struct_size) { ASSERT((len - sizeof(struct_size)) % sizeof(int) == 0); printf("#regs: %d start blkno: %lld (0x%llx) len: %d bmap size: %d flags: 0x%x\n", @@ -317,48 +297,45 @@ xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops) xlog_print_op_header(head, *i, ptr); if (super_block) { printf("SUPER BLOCK Buffer: "); - if (INT_GET(head->oh_len, ARCH_CONVERT) < 4*8) { + if (be32_to_cpu(head->oh_len) < 4*8) { printf("Out of space\n"); } else { printf("\n"); /* * memmove because *ptr may not be 8-byte aligned */ - memmove(&x, *ptr, sizeof(long long)); - memmove(&y, *ptr+8, sizeof(long long)); + memmove(&x, *ptr, sizeof(__be64)); + memmove(&y, *ptr+8, sizeof(__be64)); printf("icount: %lld ifree: %lld ", - INT_GET(x, ARCH_CONVERT), - INT_GET(y, ARCH_CONVERT)); - memmove(&x, *ptr+16, sizeof(long long)); - memmove(&y, *ptr+24, sizeof(long long)); + be64_to_cpu(x), be64_to_cpu(y)); + memmove(&x, *ptr+16, sizeof(__be64)); + memmove(&y, *ptr+24, sizeof(__be64)); printf("fdblks: %lld frext: %lld\n", - INT_GET(x, ARCH_CONVERT), - INT_GET(y, ARCH_CONVERT)); + be64_to_cpu(x), be64_to_cpu(y)); } super_block = 0; - } else if (INT_GET(*(uint *)(*ptr), ARCH_CONVERT) == XFS_AGI_MAGIC) { + } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGI_MAGIC) { agi = (xfs_agi_t *)(*ptr); printf("AGI Buffer: XAGI "); - if (INT_GET(head->oh_len, ARCH_CONVERT) < - sizeof(xfs_agi_t) - - XFS_AGI_UNLINKED_BUCKETS*sizeof(xfs_agino_t)) { + if (be32_to_cpu(head->oh_len) < sizeof(xfs_agi_t) - + XFS_AGI_UNLINKED_BUCKETS*sizeof(xfs_agino_t)) { printf("out of space\n"); } else { printf("\n"); printf("ver: %d ", - INT_GET(agi->agi_versionnum, ARCH_CONVERT)); + be32_to_cpu(agi->agi_versionnum)); printf("seq#: %d len: %d cnt: %d root: %d\n", - INT_GET(agi->agi_seqno, ARCH_CONVERT), - INT_GET(agi->agi_length, ARCH_CONVERT), - INT_GET(agi->agi_count, ARCH_CONVERT), - INT_GET(agi->agi_root, ARCH_CONVERT)); + be32_to_cpu(agi->agi_seqno), + be32_to_cpu(agi->agi_length), + be32_to_cpu(agi->agi_count), + be32_to_cpu(agi->agi_root)); printf("level: %d free#: 0x%x newino: 0x%x\n", - INT_GET(agi->agi_level, ARCH_CONVERT), - INT_GET(agi->agi_freecount, ARCH_CONVERT), - INT_GET(agi->agi_newino, ARCH_CONVERT)); - if (INT_GET(head->oh_len, ARCH_CONVERT) == 128) { + be32_to_cpu(agi->agi_level), + be32_to_cpu(agi->agi_freecount), + be32_to_cpu(agi->agi_newino)); + if (be32_to_cpu(head->oh_len) == 128) { buckets = 17; - } else if (INT_GET(head->oh_len, ARCH_CONVERT) == 256) { + } else if (be32_to_cpu(head->oh_len) == 256) { buckets = 32 + 17; } else { if (head->oh_flags & XLOG_CONTINUE_TRANS) { @@ -373,80 +350,69 @@ xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops) for (col = 0; col < 4; col++, bucket++) { if (bucket < buckets) { printf("0x%x ", - INT_GET(agi->agi_unlinked[bucket], ARCH_CONVERT)); + be32_to_cpu(agi->agi_unlinked[bucket])); } } printf("\n"); } } - } else if (INT_GET(*(uint *)(*ptr), ARCH_CONVERT) == XFS_AGF_MAGIC) { + } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGF_MAGIC) { agf = (xfs_agf_t *)(*ptr); printf("AGF Buffer: XAGF "); - if (INT_GET(head->oh_len, ARCH_CONVERT) < sizeof(xfs_agf_t)) { + if (be32_to_cpu(head->oh_len) < sizeof(xfs_agf_t)) { printf("Out of space\n"); } else { printf("\n"); printf("ver: %d seq#: %d len: %d \n", - INT_GET(agf->agf_versionnum, ARCH_CONVERT), - INT_GET(agf->agf_seqno, ARCH_CONVERT), - INT_GET(agf->agf_length, ARCH_CONVERT)); + be32_to_cpu(agf->agf_versionnum), + be32_to_cpu(agf->agf_seqno), + be32_to_cpu(agf->agf_length)); printf("root BNO: %d CNT: %d\n", - INT_GET(agf->agf_roots[XFS_BTNUM_BNOi], - ARCH_CONVERT), - INT_GET(agf->agf_roots[XFS_BTNUM_CNTi], - ARCH_CONVERT)); + be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNOi]), + be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNTi])); printf("level BNO: %d CNT: %d\n", - INT_GET(agf->agf_levels[XFS_BTNUM_BNOi], - ARCH_CONVERT), - INT_GET(agf->agf_levels[XFS_BTNUM_CNTi], - ARCH_CONVERT)); + be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]), + be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi])); printf("1st: %d last: %d cnt: %d " "freeblks: %d longest: %d\n", - INT_GET(agf->agf_flfirst, ARCH_CONVERT), - INT_GET(agf->agf_fllast, ARCH_CONVERT), - INT_GET(agf->agf_flcount, ARCH_CONVERT), - INT_GET(agf->agf_freeblks, ARCH_CONVERT), - INT_GET(agf->agf_longest, ARCH_CONVERT)); + be32_to_cpu(agf->agf_flfirst), + be32_to_cpu(agf->agf_fllast), + be32_to_cpu(agf->agf_flcount), + be32_to_cpu(agf->agf_freeblks), + be32_to_cpu(agf->agf_longest)); } - } else if (INT_GET(*(uint *)(*ptr), ARCH_CONVERT) == XFS_DQUOT_MAGIC) { + } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_DQUOT_MAGIC) { dq = (xfs_disk_dquot_t *)(*ptr); printf("DQUOT Buffer: DQ "); - if (INT_GET(head->oh_len, ARCH_CONVERT) < + if (be32_to_cpu(head->oh_len) < sizeof(xfs_disk_dquot_t)) { printf("Out of space\n"); } else { printf("\n"); printf("ver: %d flags: 0x%x id: %d \n", - INT_GET(dq->d_version, ARCH_CONVERT), - INT_GET(dq->d_flags, ARCH_CONVERT), - INT_GET(dq->d_id, ARCH_CONVERT)); + dq->d_version, dq->d_flags, + be32_to_cpu(dq->d_id)); printf("blk limits hard: %llu soft: %llu\n", - (unsigned long long) - INT_GET(dq->d_blk_hardlimit, ARCH_CONVERT), - (unsigned long long) - INT_GET(dq->d_blk_softlimit, ARCH_CONVERT)); + be64_to_cpu(dq->d_blk_hardlimit), + be64_to_cpu(dq->d_blk_softlimit)); printf("blk count: %llu warns: %d timer: %d\n", - (unsigned long long) - INT_GET(dq->d_bcount, ARCH_CONVERT), - INT_GET(dq->d_bwarns, ARCH_CONVERT), - INT_GET(dq->d_btimer, ARCH_CONVERT)); + be64_to_cpu(dq->d_bcount), + be16_to_cpu(dq->d_bwarns), + be32_to_cpu(dq->d_btimer)); printf("ino limits hard: %llu soft: %llu\n", - (unsigned long long) - INT_GET(dq->d_ino_hardlimit, ARCH_CONVERT), - (unsigned long long) - INT_GET(dq->d_ino_softlimit, ARCH_CONVERT)); + be64_to_cpu(dq->d_ino_hardlimit), + be64_to_cpu(dq->d_ino_softlimit)); printf("ino count: %llu warns: %d timer: %d\n", - (unsigned long long) - INT_GET(dq->d_icount, ARCH_CONVERT), - INT_GET(dq->d_iwarns, ARCH_CONVERT), - INT_GET(dq->d_itimer, ARCH_CONVERT)); + be64_to_cpu(dq->d_icount), + be16_to_cpu(dq->d_iwarns), + be32_to_cpu(dq->d_itimer)); } } else { printf("BUF DATA\n"); if (print_data) { uint *dp = (uint *)*ptr; - int nums = INT_GET(head->oh_len, ARCH_CONVERT) >> 2; + int nums = be32_to_cpu(head->oh_len) >> 2; int i = 0; while (i < nums) { @@ -461,7 +427,7 @@ xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops) printf("\n"); } } - *ptr += INT_GET(head->oh_len, ARCH_CONVERT); + *ptr += be32_to_cpu(head->oh_len); } if (head && head->oh_flags & XLOG_CONTINUE_TRANS) skip++; @@ -566,7 +532,7 @@ xlog_print_trans_qoff(xfs_caddr_t *ptr, uint len) void -xlog_print_trans_inode_core(xfs_dinode_core_t *ip) +xlog_print_trans_inode_core(xfs_icdinode_t *ip) { printf("INODE CORE\n"); printf("magic 0x%hx mode 0%ho version %d format %d\n", @@ -607,7 +573,7 @@ xlog_print_dir_sf(xfs_dir_shortform_t *sfp, int size) printf("SHORTFORM DIRECTORY size %d count %d\n", size, sfp->hdr.count); memmove(&ino, &(sfp->hdr.parent), sizeof(ino)); - printf(".. ino 0x%llx\n", (unsigned long long)INT_GET(ino, ARCH_CONVERT)); + printf(".. ino 0x%llx\n", be64_to_cpu(*(__be64 *)&ino)); count = (uint)(sfp->hdr.count); sfep = &(sfp->list[0]); @@ -617,14 +583,14 @@ xlog_print_dir_sf(xfs_dir_shortform_t *sfp, int size) namebuf[sfep->namelen] = '\0'; printf("%s ino 0x%llx namelen %d\n", namebuf, (unsigned long long)ino, sfep->namelen); - sfep = XFS_DIR_SF_NEXTENTRY(sfep); + sfep = xfs_dir_sf_nextentry(sfep); } } int xlog_print_trans_inode(xfs_caddr_t *ptr, int len, int *i, int num_ops) { - xfs_dinode_core_t dino; + xfs_icdinode_t dino; xlog_op_header_t *op_head; xfs_inode_log_format_t dst_lbuf; xfs_inode_log_format_64_t src_lbuf; /* buffer of biggest one */ @@ -690,7 +656,7 @@ xlog_print_trans_inode(xfs_caddr_t *ptr, int len, int *i, int num_ops) (*i)++; xlog_print_op_header(op_head, *i, ptr); printf("EXTENTS inode data\n"); - *ptr += INT_GET(op_head->oh_len, ARCH_CONVERT); + *ptr += be32_to_cpu(op_head->oh_len); if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) { return 1; } @@ -701,7 +667,7 @@ xlog_print_trans_inode(xfs_caddr_t *ptr, int len, int *i, int num_ops) (*i)++; xlog_print_op_header(op_head, *i, ptr); printf("BTREE inode data\n"); - *ptr += INT_GET(op_head->oh_len, ARCH_CONVERT); + *ptr += be32_to_cpu(op_head->oh_len); if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) { return 1; } @@ -715,7 +681,7 @@ xlog_print_trans_inode(xfs_caddr_t *ptr, int len, int *i, int num_ops) if (mode == S_IFDIR) { xlog_print_dir_sf((xfs_dir_shortform_t*)*ptr, size); } - *ptr += INT_GET(op_head->oh_len, ARCH_CONVERT); + *ptr += be32_to_cpu(op_head->oh_len); if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) { return 1; } @@ -726,7 +692,7 @@ xlog_print_trans_inode(xfs_caddr_t *ptr, int len, int *i, int num_ops) (*i)++; xlog_print_op_header(op_head, *i, ptr); printf("EXTENTS inode attr\n"); - *ptr += INT_GET(op_head->oh_len, ARCH_CONVERT); + *ptr += be32_to_cpu(op_head->oh_len); if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) { return 1; } @@ -737,7 +703,7 @@ xlog_print_trans_inode(xfs_caddr_t *ptr, int len, int *i, int num_ops) (*i)++; xlog_print_op_header(op_head, *i, ptr); printf("BTREE inode attr\n"); - *ptr += INT_GET(op_head->oh_len, ARCH_CONVERT); + *ptr += be32_to_cpu(op_head->oh_len); if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) { return 1; } @@ -751,7 +717,7 @@ xlog_print_trans_inode(xfs_caddr_t *ptr, int len, int *i, int num_ops) if (mode == S_IFDIR) { xlog_print_dir_sf((xfs_dir_shortform_t*)*ptr, size); } - *ptr += INT_GET(op_head->oh_len, ARCH_CONVERT); + *ptr += be32_to_cpu(op_head->oh_len); if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) { return 1; } @@ -822,12 +788,11 @@ xlog_print_trans_dquot(xfs_caddr_t *ptr, int len, int *i, int num_ops) while (num-- > 0) { head = (xlog_op_header_t *)*ptr; xlog_print_op_header(head, *i, ptr); - ASSERT(INT_GET(head->oh_len, ARCH_CONVERT) == sizeof(xfs_disk_dquot_t)); + ASSERT(be32_to_cpu(head->oh_len) == sizeof(xfs_disk_dquot_t)); memmove(&ddq, *ptr, sizeof(xfs_disk_dquot_t)); printf("DQUOT: magic 0x%hx flags 0%ho\n", - INT_GET(ddq.d_magic, ARCH_CONVERT), - INT_GET(ddq.d_flags, ARCH_CONVERT)); - *ptr += INT_GET(head->oh_len, ARCH_CONVERT); + be16_to_cpu(ddq.d_magic), ddq.d_flags); + *ptr += be32_to_cpu(head->oh_len); } if (head && head->oh_flags & XLOG_CONTINUE_TRANS) skip++; @@ -862,11 +827,10 @@ xlog_print_lseek(xlog_t *log, int fd, xfs_daddr_t blkno, int whence) void print_lsn(xfs_caddr_t string, - xfs_lsn_t *lsn, - xfs_arch_t arch) + __be64 *lsn) { printf("%s: %u,%u", string, - CYCLE_LSN(INT_GET(*lsn, arch)), BLOCK_LSN(INT_GET(*lsn, arch))); + CYCLE_LSN(be64_to_cpu(*lsn)), BLOCK_LSN(be64_to_cpu(*lsn))); } @@ -911,9 +875,9 @@ xlog_print_record(int fd, } /* Did we overflow the end? */ if (*read_type == FULL_READ && - BLOCK_LSN(INT_GET(rhead->h_lsn, ARCH_CONVERT)) + BTOBB(read_len) >= + BLOCK_LSN(be64_to_cpu(rhead->h_lsn)) + BTOBB(read_len) >= logBBsize) { - *read_type = BBTOB(logBBsize - BLOCK_LSN(INT_GET(rhead->h_lsn, ARCH_CONVERT))-1); + *read_type = BBTOB(logBBsize - BLOCK_LSN(be64_to_cpu(rhead->h_lsn))-1); *partial_buf = buf; return PARTIAL_READ; } @@ -937,7 +901,7 @@ xlog_print_record(int fd, xlog_rec_header_t *rechead = (xlog_rec_header_t *)ptr; /* sanity checks */ - if (INT_GET(rechead->h_magicno, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM) { + if (be32_to_cpu(rechead->h_magicno) == XLOG_HEADER_MAGIC_NUM) { /* data should not have magicno as first word * as it should by cycle# */ @@ -947,12 +911,12 @@ xlog_print_record(int fd, /* verify cycle# * FIXME: cycle+1 should be a macro pv#900369 */ - if (INT_GET(rhead->h_cycle, ARCH_CONVERT) != - INT_GET(*(uint *)ptr, ARCH_CONVERT)) { + if (be32_to_cpu(rhead->h_cycle) != + be32_to_cpu(*(__be32 *)ptr)) { if (*read_type == FULL_READ) return -1; - else if (INT_GET(rhead->h_cycle, ARCH_CONVERT) + 1 != - INT_GET(*(uint *)ptr, ARCH_CONVERT)) + else if (be32_to_cpu(rhead->h_cycle) + 1 != + be32_to_cpu(*(__be32 *)ptr)) return -1; } } @@ -960,16 +924,14 @@ xlog_print_record(int fd, /* copy back the data from the header */ if (i < XLOG_HEADER_CYCLE_SIZE / BBSIZE) { /* from 1st header */ - INT_SET(*(uint *)ptr, ARCH_CONVERT, - INT_GET(rhead->h_cycle_data[i], ARCH_CONVERT)); + *(__be32 *)ptr = rhead->h_cycle_data[i]; } else { ASSERT(xhdrs != NULL); /* from extra headers */ j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); - INT_SET(*(uint *)ptr, ARCH_CONVERT, - INT_GET(xhdrs[j-1].xh_cycle_data[k], ARCH_CONVERT)); + *(__be32 *)ptr = xhdrs[j-1].xh_cycle_data[k]; } } @@ -985,59 +947,57 @@ xlog_print_record(int fd, if (print_no_data || ((XLOG_SET(op_head->oh_flags, XLOG_WAS_CONT_TRANS) || XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) && - INT_GET(op_head->oh_len, ARCH_CONVERT) == 0)) { - for (n = 0; n < INT_GET(op_head->oh_len, ARCH_CONVERT); n++) { + be32_to_cpu(op_head->oh_len) == 0)) { + for (n = 0; n < be32_to_cpu(op_head->oh_len); n++) { printf("%c", *ptr); ptr++; } printf("\n"); continue; } - if (xlog_print_find_tid(INT_GET(op_head->oh_tid, ARCH_CONVERT), + if (xlog_print_find_tid(be32_to_cpu(op_head->oh_tid), op_head->oh_flags & XLOG_WAS_CONT_TRANS)) { printf("Left over region from split log item\n"); - ptr += INT_GET(op_head->oh_len, ARCH_CONVERT); + ptr += be32_to_cpu(op_head->oh_len); continue; } - if (INT_GET(op_head->oh_len, ARCH_CONVERT) != 0) { + if (be32_to_cpu(op_head->oh_len) != 0) { if (*(uint *)ptr == XFS_TRANS_HEADER_MAGIC) { skip = xlog_print_trans_header(&ptr, - INT_GET(op_head->oh_len, ARCH_CONVERT)); + be32_to_cpu(op_head->oh_len)); } else { switch (*(unsigned short *)ptr) { - case XFS_LI_5_3_BUF: - case XFS_LI_6_1_BUF: case XFS_LI_BUF: { skip = xlog_print_trans_buffer(&ptr, - INT_GET(op_head->oh_len, ARCH_CONVERT), + be32_to_cpu(op_head->oh_len), &i, num_ops); break; } case XFS_LI_INODE: { skip = xlog_print_trans_inode(&ptr, - INT_GET(op_head->oh_len, ARCH_CONVERT), + be32_to_cpu(op_head->oh_len), &i, num_ops); break; } case XFS_LI_DQUOT: { skip = xlog_print_trans_dquot(&ptr, - INT_GET(op_head->oh_len, ARCH_CONVERT), + be32_to_cpu(op_head->oh_len), &i, num_ops); break; } case XFS_LI_EFI: { skip = xlog_print_trans_efi(&ptr, - INT_GET(op_head->oh_len, ARCH_CONVERT)); + be32_to_cpu(op_head->oh_len)); break; } case XFS_LI_EFD: { skip = xlog_print_trans_efd(&ptr, - INT_GET(op_head->oh_len, ARCH_CONVERT)); + be32_to_cpu(op_head->oh_len)); break; } case XFS_LI_QUOTAOFF: { skip = xlog_print_trans_qoff(&ptr, - INT_GET(op_head->oh_len, ARCH_CONVERT)); + be32_to_cpu(op_head->oh_len)); break; } case XLOG_UNMOUNT_TYPE: { @@ -1053,12 +1013,12 @@ xlog_print_record(int fd, return BAD_HEADER; } skip = 0; - ptr += INT_GET(op_head->oh_len, ARCH_CONVERT); + ptr += be32_to_cpu(op_head->oh_len); } } /* switch */ } /* else */ if (skip != 0) - xlog_print_add_to_trans(INT_GET(op_head->oh_tid, ARCH_CONVERT), skip); + xlog_print_add_to_trans(be32_to_cpu(op_head->oh_tid), skip); } } printf("\n"); @@ -1075,14 +1035,14 @@ xlog_print_rec_head(xlog_rec_header_t *head, int *len) int datalen,bbs; if (print_no_print) - return INT_GET(head->h_num_logops, ARCH_CONVERT); + return be32_to_cpu(head->h_num_logops); if (!head->h_magicno) return ZEROED_LOG; - if (INT_GET(head->h_magicno, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM) { + if (be32_to_cpu(head->h_magicno) != XLOG_HEADER_MAGIC_NUM) { printf("Header 0x%x wanted 0x%x\n", - INT_GET(head->h_magicno, ARCH_CONVERT), + be32_to_cpu(head->h_magicno), XLOG_HEADER_MAGIC_NUM); return BAD_HEADER; } @@ -1092,32 +1052,32 @@ xlog_print_rec_head(xlog_rec_header_t *head, int *len) !head->h_num_logops && !head->h_size) return CLEARED_BLKS; - datalen=INT_GET(head->h_len, ARCH_CONVERT); + datalen=be32_to_cpu(head->h_len); bbs=BTOBB(datalen); printf("cycle: %d version: %d ", - INT_GET(head->h_cycle, ARCH_CONVERT), - INT_GET(head->h_version, ARCH_CONVERT)); - print_lsn(" lsn", &head->h_lsn, ARCH_CONVERT); - print_lsn(" tail_lsn", &head->h_tail_lsn, ARCH_CONVERT); + be32_to_cpu(head->h_cycle), + be32_to_cpu(head->h_version)); + print_lsn(" lsn", &head->h_lsn); + print_lsn(" tail_lsn", &head->h_tail_lsn); printf("\n"); printf("length of Log Record: %d prev offset: %d num ops: %d\n", datalen, - INT_GET(head->h_prev_block, ARCH_CONVERT), - INT_GET(head->h_num_logops, ARCH_CONVERT)); + be32_to_cpu(head->h_prev_block), + be32_to_cpu(head->h_num_logops)); if (print_overwrite) { printf("cycle num overwrites: "); for (i=0; i< MIN(bbs, XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) printf("%d - 0x%x ", i, - INT_GET(head->h_cycle_data[i], ARCH_CONVERT)); + be32_to_cpu(head->h_cycle_data[i])); printf("\n"); } platform_uuid_unparse(&head->h_fs_uuid, uub); printf("uuid: %s format: ", uub); - switch (INT_GET(head->h_fmt, ARCH_CONVERT)) { + switch (be32_to_cpu(head->h_fmt)) { case XLOG_FMT_UNKNOWN: printf("unknown\n"); break; @@ -1131,13 +1091,13 @@ xlog_print_rec_head(xlog_rec_header_t *head, int *len) printf("big endian irix\n"); break; default: - printf("? (%d)\n", INT_GET(head->h_fmt, ARCH_CONVERT)); + printf("? (%d)\n", be32_to_cpu(head->h_fmt)); break; } - printf("h_size: %d\n", INT_GET(head->h_size, ARCH_CONVERT)); + printf("h_size: %d\n", be32_to_cpu(head->h_size)); - *len = INT_GET(head->h_len, ARCH_CONVERT); - return(INT_GET(head->h_num_logops, ARCH_CONVERT)); + *len = be32_to_cpu(head->h_len); + return(be32_to_cpu(head->h_num_logops)); } /* xlog_print_rec_head */ void @@ -1146,14 +1106,14 @@ xlog_print_rec_xhead(xlog_rec_ext_header_t *head, int coverage) int i; print_xlog_xhdr_line(); - printf("extended-header: cycle: %d\n", INT_GET(head->xh_cycle, ARCH_CONVERT)); + printf("extended-header: cycle: %d\n", be32_to_cpu(head->xh_cycle)); if (print_overwrite) { printf("cycle num overwrites: "); for (i = 0; i < coverage; i++) printf("%d - 0x%x ", i, - INT_GET(head->xh_cycle_data[i], ARCH_CONVERT)); + be32_to_cpu(head->xh_cycle_data[i])); printf("\n"); } } /* xlog_print_rec_xhead */ @@ -1174,7 +1134,7 @@ print_xlog_bad_header(xfs_daddr_t blkno, xfs_caddr_t buf) { print_stars(); printf("* ERROR: header cycle=%-11d block=%-21lld *\n", - GET_CYCLE(buf, ARCH_CONVERT), (long long)blkno); + xlog_get_cycle(buf), (long long)blkno); print_stars(); if (print_exit) xlog_exit("Bad log record header"); @@ -1234,7 +1194,7 @@ xlog_print_extended_headers( xlog_rec_ext_header_t *x; num_required = howmany(len, XLOG_HEADER_CYCLE_SIZE); - num_hdrs = INT_GET(hdr->h_size, ARCH_CONVERT) / XLOG_HEADER_CYCLE_SIZE; + num_hdrs = be32_to_cpu(hdr->h_size) / XLOG_HEADER_CYCLE_SIZE; if (num_required > num_hdrs) { print_xlog_bad_reqd_hdrs((*blkno)-1, num_required, num_hdrs); @@ -1374,7 +1334,7 @@ void xfs_log_print(xlog_t *log, goto loop; } - if (INT_GET(hdr->h_version, ARCH_CONVERT) == 2) { + if (be32_to_cpu(hdr->h_version) == 2) { if (xlog_print_extended_headers(fd, len, &blkno, hdr, &num_hdrs, &xhdrs) != 0) break; } @@ -1472,7 +1432,7 @@ loop: continue; } - if (INT_GET(hdr->h_version, ARCH_CONVERT) == 2) { + if (be32_to_cpu(hdr->h_version) == 2) { if (xlog_print_extended_headers(fd, len, &blkno, hdr, &num_hdrs, &xhdrs) != 0) break; } diff --git a/logprint/log_print_all.c b/logprint/log_print_all.c index 6238bd43e..955d942e6 100644 --- a/logprint/log_print_all.c +++ b/logprint/log_print_all.c @@ -37,10 +37,10 @@ xlog_print_find_oldest( first_blk = 0; /* read first block */ bp = xlog_get_bp(log, 1); xlog_bread(log, 0, 1, bp); - first_half_cycle = GET_CYCLE(XFS_BUF_PTR(bp), ARCH_CONVERT); + first_half_cycle = xlog_get_cycle(XFS_BUF_PTR(bp)); *last_blk = log->l_logBBsize-1; /* read last block */ xlog_bread(log, *last_blk, 1, bp); - last_half_cycle = GET_CYCLE(XFS_BUF_PTR(bp), ARCH_CONVERT); + last_half_cycle = xlog_get_cycle(XFS_BUF_PTR(bp)); ASSERT(last_half_cycle != 0); if (first_half_cycle == last_half_cycle) { /* all cycle nos are same */ @@ -85,7 +85,6 @@ xlog_recover_print_buffer( { xfs_agi_t *agi; xfs_agf_t *agf; - xfs_buf_log_format_v1_t *old_f; xfs_buf_log_format_t *f; xfs_caddr_t p; int len, num, i; @@ -93,30 +92,12 @@ xlog_recover_print_buffer( xfs_disk_dquot_t *ddq; f = (xfs_buf_log_format_t *)item->ri_buf[0].i_addr; - old_f = (xfs_buf_log_format_v1_t *)f; len = item->ri_buf[0].i_len; printf(" "); - switch (f->blf_type) { - case XFS_LI_BUF: - printf("BUF: "); - break; - case XFS_LI_6_1_BUF: - printf("6.1 BUF: "); - break; - case XFS_LI_5_3_BUF: - printf("5.3 BUF: "); - break; - } - if (f->blf_type == XFS_LI_BUF) { - printf("#regs:%d start blkno:0x%llx len:%d bmap size:%d flags:0x%x\n", - f->blf_size, (long long)f->blf_blkno, f->blf_len, f->blf_map_size, f->blf_flags); - blkno = (xfs_daddr_t)f->blf_blkno; - } else { - printf("#regs:%d start blkno:0x%x len:%d bmap size:%d\n", - old_f->blf_size, old_f->blf_blkno, old_f->blf_len, - old_f->blf_map_size); - blkno = (xfs_daddr_t)old_f->blf_blkno; - } + ASSERT(f->blf_type == XFS_LI_BUF); + printf("BUF: #regs:%d start blkno:0x%llx len:%d bmap size:%d flags:0x%x\n", + f->blf_size, (long long)f->blf_blkno, f->blf_len, f->blf_map_size, f->blf_flags); + blkno = (xfs_daddr_t)f->blf_blkno; num = f->blf_size-1; i = 1; while (num-- > 0) { @@ -125,63 +106,63 @@ xlog_recover_print_buffer( i++; if (blkno == 0) { /* super block */ printf(" SUPER Block Buffer:\n"); - if (!print_buffer) continue; + if (!print_buffer) + continue; printf(" icount:%Ld ifree:%Ld ", - INT_GET(*(long long *)(p), ARCH_CONVERT), - INT_GET(*(long long *)(p+8), ARCH_CONVERT)); + be64_to_cpu(*(__be64 *)(p)), + be64_to_cpu(*(__be64 *)(p+8))); printf("fdblks:%Ld frext:%Ld\n", - INT_GET(*(long long *)(p+16), ARCH_CONVERT), - INT_GET(*(long long *)(p+24), ARCH_CONVERT)); + be64_to_cpu(*(__be64 *)(p+16)), + be64_to_cpu(*(__be64 *)(p+24))); printf(" sunit:%u swidth:%u\n", - INT_GET(*(uint *)(p+56), ARCH_CONVERT), - INT_GET(*(uint *)(p+60), ARCH_CONVERT)); - } else if (INT_GET(*(uint *)p, ARCH_CONVERT) == XFS_AGI_MAGIC) { + be32_to_cpu(*(__be32 *)(p+56)), + be32_to_cpu(*(__be32 *)(p+60))); + } else if (be32_to_cpu(*(__be32 *)p) == XFS_AGI_MAGIC) { agi = (xfs_agi_t *)p; printf(" AGI Buffer: (XAGI)\n"); - if (!print_buffer) continue; + if (!print_buffer) + continue; printf(" ver:%d ", - INT_GET(agi->agi_versionnum, ARCH_CONVERT)); + be32_to_cpu(agi->agi_versionnum)); printf("seq#:%d len:%d cnt:%d root:%d\n", - INT_GET(agi->agi_seqno, ARCH_CONVERT), - INT_GET(agi->agi_length, ARCH_CONVERT), - INT_GET(agi->agi_count, ARCH_CONVERT), - INT_GET(agi->agi_root, ARCH_CONVERT)); + be32_to_cpu(agi->agi_seqno), + be32_to_cpu(agi->agi_length), + be32_to_cpu(agi->agi_count), + be32_to_cpu(agi->agi_root)); printf(" level:%d free#:0x%x newino:0x%x\n", - INT_GET(agi->agi_level, ARCH_CONVERT), - INT_GET(agi->agi_freecount, ARCH_CONVERT), - INT_GET(agi->agi_newino, ARCH_CONVERT)); - } else if (INT_GET(*(uint *)p, ARCH_CONVERT) == XFS_AGF_MAGIC) { + be32_to_cpu(agi->agi_level), + be32_to_cpu(agi->agi_freecount), + be32_to_cpu(agi->agi_newino)); + } else if (be32_to_cpu(*(__be32 *)p) == XFS_AGF_MAGIC) { agf = (xfs_agf_t *)p; printf(" AGF Buffer: (XAGF)\n"); - if (!print_buffer) continue; + if (!print_buffer) + continue; printf(" ver:%d seq#:%d len:%d \n", - INT_GET(agf->agf_versionnum, ARCH_CONVERT), - INT_GET(agf->agf_seqno, ARCH_CONVERT), - INT_GET(agf->agf_length, ARCH_CONVERT)); + be32_to_cpu(agf->agf_versionnum), + be32_to_cpu(agf->agf_seqno), + be32_to_cpu(agf->agf_length)); printf(" root BNO:%d CNT:%d\n", - INT_GET(agf->agf_roots[XFS_BTNUM_BNOi], - ARCH_CONVERT), - INT_GET(agf->agf_roots[XFS_BTNUM_CNTi], - ARCH_CONVERT)); + be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNOi]), + be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNTi])); printf(" level BNO:%d CNT:%d\n", - INT_GET(agf->agf_levels[XFS_BTNUM_BNOi], - ARCH_CONVERT), - INT_GET(agf->agf_levels[XFS_BTNUM_CNTi], - ARCH_CONVERT)); + be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]), + be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi])); printf(" 1st:%d last:%d cnt:%d " "freeblks:%d longest:%d\n", - INT_GET(agf->agf_flfirst, ARCH_CONVERT), - INT_GET(agf->agf_fllast, ARCH_CONVERT), - INT_GET(agf->agf_flcount, ARCH_CONVERT), - INT_GET(agf->agf_freeblks, ARCH_CONVERT), - INT_GET(agf->agf_longest, ARCH_CONVERT)); + be32_to_cpu(agf->agf_flfirst), + be32_to_cpu(agf->agf_fllast), + be32_to_cpu(agf->agf_flcount), + be32_to_cpu(agf->agf_freeblks), + be32_to_cpu(agf->agf_longest)); } else if (*(uint *)p == XFS_DQUOT_MAGIC) { ddq = (xfs_disk_dquot_t *)p; printf(" DQUOT Buffer:\n"); - if (!print_buffer) continue; + if (!print_buffer) + continue; printf(" UIDs 0x%lx-0x%lx\n", - (unsigned long)INT_GET(ddq->d_id, ARCH_CONVERT), - (unsigned long)INT_GET(ddq->d_id, ARCH_CONVERT) + + (unsigned long)be32_to_cpu(ddq->d_id), + (unsigned long)be32_to_cpu(ddq->d_id) + (BBTOB(f->blf_len) / sizeof(xfs_dqblk_t)) - 1); } else { printf(" BUF DATA\n"); @@ -226,29 +207,29 @@ xlog_recover_print_dquot( if (!print_quota) return; printf("\t\tmagic 0x%x\tversion 0x%x\tID 0x%x (%d)\t\n", - INT_GET(d->d_magic, ARCH_CONVERT), - INT_GET(d->d_version, ARCH_CONVERT), - INT_GET(d->d_id, ARCH_CONVERT), - INT_GET(d->d_id, ARCH_CONVERT)); + be16_to_cpu(d->d_magic), + d->d_version, + be32_to_cpu(d->d_id), + be32_to_cpu(d->d_id)); printf("\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x" "\tino_soft 0x%x\n", - (int)INT_GET(d->d_blk_hardlimit, ARCH_CONVERT), - (int)INT_GET(d->d_blk_softlimit, ARCH_CONVERT), - (int)INT_GET(d->d_ino_hardlimit, ARCH_CONVERT), - (int)INT_GET(d->d_ino_softlimit, ARCH_CONVERT)); + (int)be64_to_cpu(d->d_blk_hardlimit), + (int)be64_to_cpu(d->d_blk_softlimit), + (int)be64_to_cpu(d->d_ino_hardlimit), + (int)be64_to_cpu(d->d_ino_softlimit)); printf("\t\tbcount 0x%x (%d) icount 0x%x (%d)\n", - (int)INT_GET(d->d_bcount, ARCH_CONVERT), - (int)INT_GET(d->d_bcount, ARCH_CONVERT), - (int)INT_GET(d->d_icount, ARCH_CONVERT), - (int)INT_GET(d->d_icount, ARCH_CONVERT)); + (int)be64_to_cpu(d->d_bcount), + (int)be64_to_cpu(d->d_bcount), + (int)be64_to_cpu(d->d_icount), + (int)be64_to_cpu(d->d_icount)); printf("\t\tbtimer 0x%x itimer 0x%x \n", - (int)INT_GET(d->d_btimer, ARCH_CONVERT), - (int)INT_GET(d->d_itimer, ARCH_CONVERT)); + (int)be32_to_cpu(d->d_btimer), + (int)be32_to_cpu(d->d_itimer)); } STATIC void xlog_recover_print_inode_core( - xfs_dinode_core_t *di) + xfs_icdinode_t *di) { printf(" CORE inode:\n"); if (!print_inode) @@ -291,8 +272,8 @@ xlog_recover_print_inode( f->ilf_dsize); /* core inode comes 2nd */ - ASSERT(item->ri_buf[1].i_len == sizeof(xfs_dinode_core_t)); - xlog_recover_print_inode_core((xfs_dinode_core_t *) + ASSERT(item->ri_buf[1].i_len == sizeof(xfs_icdinode_t)); + xlog_recover_print_inode_core((xfs_icdinode_t *) item->ri_buf[1].i_addr); hasdata = (f->ilf_fields & XFS_ILOG_DFORK) != 0; @@ -436,13 +417,9 @@ xlog_recover_print_logitem( { switch (ITEM_TYPE(item)) { case XFS_LI_BUF: - case XFS_LI_6_1_BUF: - case XFS_LI_5_3_BUF: xlog_recover_print_buffer(item); break; case XFS_LI_INODE: - case XFS_LI_6_1_INODE: - case XFS_LI_5_3_INODE: xlog_recover_print_inode(item); break; case XFS_LI_EFD: @@ -482,18 +459,6 @@ xlog_recover_print_item( case XFS_LI_EFI: printf("EFI"); break; - case XFS_LI_6_1_BUF: - printf("6.1 BUF"); - break; - case XFS_LI_5_3_BUF: - printf("5.3 BUF"); - break; - case XFS_LI_6_1_INODE: - printf("6.1 INO"); - break; - case XFS_LI_5_3_INODE: - printf("5.3 INO"); - break; case XFS_LI_DQUOT: printf("DQ "); break; diff --git a/logprint/log_print_trans.c b/logprint/log_print_trans.c index bc55c54d2..d0f948133 100644 --- a/logprint/log_print_trans.c +++ b/logprint/log_print_trans.c @@ -46,7 +46,8 @@ xfs_log_print_trans( xfs_daddr_t head_blk, tail_blk; int error; - if ((error = xlog_find_tail(log, &head_blk, &tail_blk, 0))) { + error = xlog_find_tail(log, &head_blk, &tail_blk); + if (error) { fprintf(stderr, "%s: failed to find head and tail, error: %d\n", progname, error); exit(1); diff --git a/logprint/logprint.c b/logprint/logprint.c index 29de24136..8af0943ca 100644 --- a/logprint/logprint.c +++ b/logprint/logprint.c @@ -87,8 +87,8 @@ logstat(xfs_mount_t *mp) /* * Conjure up a mount structure */ - libxfs_xlate_sb(buf, &(mp->m_sb), 1, XFS_SB_ALL_BITS); - sb = &(mp->m_sb); + sb = &mp->m_sb; + libxfs_sb_from_disk(sb, (xfs_dsb_t *)buf); mp->m_blkbb_log = sb->sb_blocklog - BBSHIFT; x.logBBsize = XFS_FSB_TO_BB(mp, sb->sb_logblocks); diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c index 983657eb7..509a3ed16 100644 --- a/mdrestore/xfs_mdrestore.c +++ b/mdrestore/xfs_mdrestore.c @@ -62,6 +62,7 @@ perform_restore( int block_size; int max_indicies; int cur_index; + int mb_count; xfs_metablock_t tmb; xfs_sb_t sb; __int64_t bytes_read; @@ -85,11 +86,9 @@ perform_restore( if (metablock == NULL) fatal("memory allocation failure\n"); - metablock->mb_count = be16_to_cpu(tmb.mb_count); - metablock->mb_blocklog = tmb.mb_blocklog; - - if (metablock->mb_count == 0 || metablock->mb_count > max_indicies) - fatal("bad block count: %u\n", metablock->mb_count); + mb_count = be16_to_cpu(tmb.mb_count); + if (mb_count == 0 || mb_count > max_indicies) + fatal("bad block count: %u\n", mb_count); block_index = (__be64 *)((char *)metablock + sizeof(xfs_metablock_t)); block_buffer = (char *)metablock + block_size; @@ -101,16 +100,16 @@ perform_restore( fatal("first block is not the primary superblock\n"); - if (fread(block_buffer, metablock->mb_count << metablock->mb_blocklog, + if (fread(block_buffer, mb_count << tmb.mb_blocklog, 1, src_f) != 1) fatal("error reading from file: %s\n", strerror(errno)); - libxfs_xlate_sb(block_buffer, &sb, 1, XFS_SB_ALL_BITS); + libxfs_sb_from_disk(&sb, (xfs_dsb_t *)block_buffer); if (sb.sb_magicnum != XFS_SB_MAGIC) fatal("bad magic number for primary superblock\n"); - ((xfs_sb_t*)block_buffer)->sb_inprogress = 1; + ((xfs_dsb_t*)block_buffer)->sb_inprogress = 1; if (is_target_file) { /* ensure regular files are correctly sized */ @@ -121,7 +120,7 @@ perform_restore( } else { /* ensure device is sufficiently large enough */ - char *lb[XFS_MAX_SECTORSIZE] = { 0 }; + char *lb[XFS_MAX_SECTORSIZE] = { NULL }; off64_t off; off = sb.sb_dblocks * sb.sb_blocksize - sizeof(lb); @@ -136,31 +135,29 @@ perform_restore( if (show_progress && (bytes_read & ((1 << 20) - 1)) == 0) print_progress("%lld MB read\n", bytes_read >> 20); - for (cur_index = 0; cur_index < metablock->mb_count; cur_index++) { + for (cur_index = 0; cur_index < mb_count; cur_index++) { if (pwrite64(dst_fd, &block_buffer[cur_index << - metablock->mb_blocklog], - block_size, + tmb.mb_blocklog], block_size, be64_to_cpu(block_index[cur_index]) << BBSHIFT) < 0) fatal("error writing block %llu: %s\n", be64_to_cpu(block_index[cur_index]) << BBSHIFT, strerror(errno)); } - if (metablock->mb_count < max_indicies) + if (mb_count < max_indicies) break; if (fread(metablock, block_size, 1, src_f) != 1) fatal("error reading from file: %s\n", strerror(errno)); - if (metablock->mb_count == 0) + mb_count = be16_to_cpu(metablock->mb_count); + if (mb_count == 0) break; + if (mb_count > max_indicies) + fatal("bad block count: %u\n", mb_count); - metablock->mb_count = be16_to_cpu(metablock->mb_count); - if (metablock->mb_count > max_indicies) - fatal("bad block count: %u\n", metablock->mb_count); - - if (fread(block_buffer, metablock->mb_count << - metablock->mb_blocklog, 1, src_f) != 1) + if (fread(block_buffer, mb_count << tmb.mb_blocklog, + 1, src_f) != 1) fatal("error reading from file: %s\n", strerror(errno)); bytes_read += block_size; @@ -171,7 +168,7 @@ perform_restore( memset(block_buffer, 0, sb.sb_sectsize); sb.sb_inprogress = 0; - libxfs_xlate_sb(block_buffer, &sb, 0, XFS_SB_ALL_BITS); + libxfs_sb_to_disk((xfs_dsb_t *)block_buffer, &sb, XFS_SB_ALL_BITS); if (pwrite(dst_fd, block_buffer, sb.sb_sectsize, 0) < 0) fatal("error writing primary superblock: %s\n", strerror(errno)); diff --git a/mkfs/proto.c b/mkfs/proto.c index 4dec1a673..8fc8c4c47 100644 --- a/mkfs/proto.c +++ b/mkfs/proto.c @@ -206,7 +206,7 @@ rsvfile( ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC; libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - libxfs_trans_commit(tp, 0, NULL); + libxfs_trans_commit(tp, 0); } static int @@ -232,7 +232,7 @@ newfile( flags = 0; mp = ip->i_mount; if (dolocal && len <= XFS_IFORK_DSIZE(ip)) { - libxfs_idata_realloc(ip, len, XFS_DATA_FORK); + xfs_idata_realloc(ip, len, XFS_DATA_FORK); if (buf) memmove(ip->i_df.if_u1.if_data, buf, len); ip->i_d.di_size = len; @@ -244,7 +244,7 @@ newfile( nb = XFS_B_TO_FSB(mp, len); nmap = 1; error = libxfs_bmapi(tp, ip, 0, nb, XFS_BMAPI_WRITE, first, nb, - &map, &nmap, flist); + &map, &nmap, flist, NULL); if (error) { fail(_("error allocating space for a file"), error); } @@ -303,8 +303,7 @@ newdirent( xfs_mount_t *mp, xfs_trans_t *tp, xfs_inode_t *pip, - char *name, - int namelen, + struct xfs_name *name, xfs_ino_t inum, xfs_fsblock_t *first, xfs_bmap_free_t *flist, @@ -312,12 +311,7 @@ newdirent( { int error; - if (XFS_SB_VERSION_HASDIRV2(&mp->m_sb)) - error = libxfs_dir2_createname(tp, pip, (uchar_t*)name, namelen, - inum, first, flist, total); - else - error = libxfs_dir_createname(tp, pip, (uchar_t*)name, namelen, - inum, first, flist, total); + error = libxfs_dir_createname(tp, pip, name, inum, first, flist, total); if (error) fail(_("directory createname error"), error); } @@ -331,10 +325,7 @@ newdirectory( { int error; - if (XFS_SB_VERSION_HASDIRV2(&mp->m_sb)) - error = libxfs_dir2_init(tp, dp, pdp); - else - error = libxfs_dir_init(tp, dp, pdp); + error = libxfs_dir_init(tp, dp, pdp); if (error) fail(_("directory create error"), error); } @@ -375,6 +366,7 @@ parseproto( int isroot = 0; cred_t creds; char *value; + struct xfs_name xname; memset(&creds, 0, sizeof(creds)); mstr = getstr(pp); @@ -440,6 +432,8 @@ parseproto( mode |= val; creds.cr_uid = (int)getnum(pp); creds.cr_gid = (int)getnum(pp); + xname.name = name; + xname.len = name ? strlen(name) : 0; tp = libxfs_trans_alloc(mp, 0); flags = XFS_ILOG_CORE; XFS_BMAP_INIT(&flist, &first); @@ -455,8 +449,7 @@ parseproto( if (buf) free(buf); libxfs_trans_ijoin(tp, pip, 0); - i = strlen(name); - newdirent(mp, tp, pip, name, i, ip->i_ino, &first, &flist, 1); + newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); libxfs_trans_ihold(tp, pip); break; @@ -472,15 +465,14 @@ parseproto( libxfs_trans_ijoin(tp, pip, 0); - i = strlen(name); - newdirent(mp, tp, pip, name, i, ip->i_ino, &first, &flist, 1); + newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); libxfs_trans_ihold(tp, pip); libxfs_trans_log_inode(tp, ip, flags); - error = libxfs_bmap_finish(&tp, &flist, first, &committed); + error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) fail(_("Pre-allocated file creation failed"), error); - libxfs_trans_commit(tp, 0, NULL); + libxfs_trans_commit(tp, 0); rsvfile(mp, ip, llen); return; @@ -494,8 +486,7 @@ parseproto( fail(_("Inode allocation failed"), error); } libxfs_trans_ijoin(tp, pip, 0); - i = strlen(name); - newdirent(mp, tp, pip, name, i, ip->i_ino, &first, &flist, 1); + newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); libxfs_trans_ihold(tp, pip); flags |= XFS_ILOG_DEV; break; @@ -509,8 +500,7 @@ parseproto( if (error) fail(_("Inode allocation failed"), error); libxfs_trans_ijoin(tp, pip, 0); - i = strlen(name); - newdirent(mp, tp, pip, name, i, ip->i_ino, &first, &flist, 1); + newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); libxfs_trans_ihold(tp, pip); flags |= XFS_ILOG_DEV; break; @@ -522,8 +512,7 @@ parseproto( if (error) fail(_("Inode allocation failed"), error); libxfs_trans_ijoin(tp, pip, 0); - i = strlen(name); - newdirent(mp, tp, pip, name, i, ip->i_ino, &first, &flist, 1); + newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); libxfs_trans_ihold(tp, pip); break; case IF_SYMLINK: @@ -536,8 +525,7 @@ parseproto( fail(_("Inode allocation failed"), error); flags |= newfile(tp, ip, &flist, &first, 1, 1, buf, len); libxfs_trans_ijoin(tp, pip, 0); - i = strlen(name); - newdirent(mp, tp, pip, name, i, ip->i_ino, &first, &flist, 1); + newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); libxfs_trans_ihold(tp, pip); break; case IF_DIRECTORY: @@ -555,8 +543,7 @@ parseproto( isroot = 1; } else { libxfs_trans_ijoin(tp, pip, 0); - i = strlen(name); - newdirent(mp, tp, pip, name, i, ip->i_ino, + newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); pip->i_d.di_nlink++; libxfs_trans_ihold(tp, pip); @@ -564,11 +551,11 @@ parseproto( } newdirectory(mp, tp, ip, pip); libxfs_trans_log_inode(tp, ip, flags); - error = libxfs_bmap_finish(&tp, &flist, first, &committed); + error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) fail(_("Directory creation failed"), error); libxfs_trans_ihold(tp, ip); - libxfs_trans_commit(tp, 0, NULL); + libxfs_trans_commit(tp, 0); /* * RT initialization. Do this here to ensure that * the RT inodes get placed after the root inode. @@ -588,12 +575,12 @@ parseproto( return; } libxfs_trans_log_inode(tp, ip, flags); - error = libxfs_bmap_finish(&tp, &flist, first, &committed); + error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) { fail(_("Error encountered creating file from prototype file"), error); } - libxfs_trans_commit(tp, 0, NULL); + libxfs_trans_commit(tp, 0); } void @@ -665,7 +652,7 @@ rtinit( libxfs_trans_log_inode(tp, rsumip, XFS_ILOG_CORE); libxfs_mod_sb(tp, XFS_SB_RSUMINO); libxfs_trans_ihold(tp, rsumip); - libxfs_trans_commit(tp, 0, NULL); + libxfs_trans_commit(tp, 0); mp->m_rsumip = rsumip; /* * Next, give the bitmap file some zero-filled blocks. @@ -683,7 +670,7 @@ rtinit( error = libxfs_bmapi(tp, rbmip, bno, (xfs_extlen_t)(mp->m_sb.sb_rbmblocks - bno), XFS_BMAPI_WRITE, &first, mp->m_sb.sb_rbmblocks, - map, &nmap, &flist); + map, &nmap, &flist, NULL); if (error) { fail(_("Allocation of the realtime bitmap failed"), error); @@ -696,11 +683,11 @@ rtinit( } } - error = libxfs_bmap_finish(&tp, &flist, first, &committed); + error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) { fail(_("Completion of the realtime bitmap failed"), error); } - libxfs_trans_commit(tp, 0, NULL); + libxfs_trans_commit(tp, 0); /* * Give the summary file some zero-filled blocks. @@ -720,7 +707,7 @@ rtinit( error = libxfs_bmapi(tp, rsumip, bno, (xfs_extlen_t)(nsumblocks - bno), XFS_BMAPI_WRITE, &first, nsumblocks, - map, &nmap, &flist); + map, &nmap, &flist, NULL); if (error) { fail(_("Allocation of the realtime summary failed"), error); @@ -732,11 +719,11 @@ rtinit( bno += ep->br_blockcount; } } - error = libxfs_bmap_finish(&tp, &flist, first, &committed); + error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) { fail(_("Completion of the realtime summary failed"), error); } - libxfs_trans_commit(tp, 0, NULL); + libxfs_trans_commit(tp, 0); /* * Free the whole area using transactions. @@ -754,11 +741,11 @@ rtinit( fail(_("Error initializing the realtime space"), error); } - error = libxfs_bmap_finish(&tp, &flist, first, &committed); + error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) { fail(_("Error completing the realtime space"), error); } - libxfs_trans_commit(tp, 0, NULL); + libxfs_trans_commit(tp, 0); } } diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 0bd480523..11ee8d553 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -567,7 +567,7 @@ zero_old_xfs_structures( free(buf); return; } - libxfs_xlate_sb(buf, &sb, 1, XFS_SB_ALL_BITS); + libxfs_sb_from_disk(&sb, buf); /* * perform same basic superblock validation to make sure we @@ -1258,7 +1258,7 @@ main( break; case 'p': if (protofile) - respec('p', 0, 0); + respec('p', NULL, 0); protofile = optarg; break; case 'q': @@ -2121,7 +2121,7 @@ an AG size that is one stripe unit smaller, for example %llu.\n"), /* OK, now write the superblock */ buf = libxfs_getbuf(xi.ddev, XFS_SB_DADDR, XFS_FSS_TO_BB(mp, 1)); memset(XFS_BUF_PTR(buf), 0, sectorsize); - libxfs_xlate_sb(XFS_BUF_PTR(buf), sbp, -1, XFS_SB_ALL_BITS); + libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp, XFS_SB_ALL_BITS); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* @@ -2173,7 +2173,7 @@ an AG size that is one stripe unit smaller, for example %llu.\n"), XFS_AG_DADDR(mp, agno, XFS_SB_DADDR), XFS_FSS_TO_BB(mp, 1)); memset(XFS_BUF_PTR(buf), 0, sectorsize); - libxfs_xlate_sb(XFS_BUF_PTR(buf), sbp, -1, XFS_SB_ALL_BITS); + libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp, XFS_SB_ALL_BITS); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* @@ -2186,25 +2186,23 @@ an AG size that is one stripe unit smaller, for example %llu.\n"), memset(agf, 0, sectorsize); if (agno == agcount - 1) agsize = dblocks - (xfs_drfsbno_t)(agno * agsize); - INT_SET(agf->agf_magicnum, ARCH_CONVERT, XFS_AGF_MAGIC); - INT_SET(agf->agf_versionnum, ARCH_CONVERT, XFS_AGF_VERSION); - INT_SET(agf->agf_seqno, ARCH_CONVERT, agno); - INT_SET(agf->agf_length, ARCH_CONVERT, (xfs_agblock_t)agsize); - INT_SET(agf->agf_roots[XFS_BTNUM_BNOi], ARCH_CONVERT, - XFS_BNO_BLOCK(mp)); - INT_SET(agf->agf_roots[XFS_BTNUM_CNTi], ARCH_CONVERT, - XFS_CNT_BLOCK(mp)); - INT_SET(agf->agf_levels[XFS_BTNUM_BNOi], ARCH_CONVERT, 1); - INT_SET(agf->agf_levels[XFS_BTNUM_CNTi], ARCH_CONVERT, 1); - INT_SET(agf->agf_flfirst, ARCH_CONVERT, 0); - INT_SET(agf->agf_fllast, ARCH_CONVERT, XFS_AGFL_SIZE(mp) - 1); - INT_SET(agf->agf_flcount, ARCH_CONVERT, 0); + agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC); + agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION); + agf->agf_seqno = cpu_to_be32(agno); + agf->agf_length = cpu_to_be32(agsize); + agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp)); + agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp)); + agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1); + agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1); + agf->agf_flfirst = 0; + agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1); + agf->agf_flcount = 0; nbmblocks = (xfs_extlen_t)(agsize - XFS_PREALLOC_BLOCKS(mp)); - INT_SET(agf->agf_freeblks, ARCH_CONVERT, nbmblocks); - INT_SET(agf->agf_longest, ARCH_CONVERT, nbmblocks); + agf->agf_freeblks = cpu_to_be32(nbmblocks); + agf->agf_longest = cpu_to_be32(nbmblocks); if (loginternal && agno == logagno) { - INT_MOD(agf->agf_freeblks, ARCH_CONVERT, -logblocks); - INT_SET(agf->agf_longest, ARCH_CONVERT, agsize - + be32_add_cpu(&agf->agf_freeblks, -logblocks); + agf->agf_longest = cpu_to_be32(agsize - XFS_FSB_TO_AGBNO(mp, logstart) - logblocks); } if (XFS_MIN_FREELIST(agf, mp) > worst_freelist) @@ -2219,18 +2217,18 @@ an AG size that is one stripe unit smaller, for example %llu.\n"), XFS_FSS_TO_BB(mp, 1)); agi = XFS_BUF_TO_AGI(buf); memset(agi, 0, sectorsize); - INT_SET(agi->agi_magicnum, ARCH_CONVERT, XFS_AGI_MAGIC); - INT_SET(agi->agi_versionnum, ARCH_CONVERT, XFS_AGI_VERSION); - INT_SET(agi->agi_seqno, ARCH_CONVERT, agno); - INT_SET(agi->agi_length, ARCH_CONVERT, (xfs_agblock_t)agsize); - INT_SET(agi->agi_count, ARCH_CONVERT, 0); - INT_SET(agi->agi_root, ARCH_CONVERT, XFS_IBT_BLOCK(mp)); - INT_SET(agi->agi_level, ARCH_CONVERT, 1); - INT_SET(agi->agi_freecount, ARCH_CONVERT, 0); - INT_SET(agi->agi_newino, ARCH_CONVERT, NULLAGINO); - INT_SET(agi->agi_dirino, ARCH_CONVERT, NULLAGINO); + agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); + agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION); + agi->agi_seqno = cpu_to_be32(agno); + agi->agi_length = cpu_to_be32((xfs_agblock_t)agsize); + agi->agi_count = 0; + agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp)); + agi->agi_level = cpu_to_be32(1); + agi->agi_freecount = 0; + agi->agi_newino = cpu_to_be32(NULLAGINO); + agi->agi_dirino = cpu_to_be32(NULLAGINO); for (c = 0; c < XFS_AGI_UNLINKED_BUCKETS; c++) - INT_SET(agi->agi_unlinked[c], ARCH_CONVERT, NULLAGINO); + agi->agi_unlinked[c] = cpu_to_be32(NULLAGINO); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* @@ -2241,46 +2239,39 @@ an AG size that is one stripe unit smaller, for example %llu.\n"), bsize); block = XFS_BUF_TO_SBLOCK(buf); memset(block, 0, blocksize); - INT_SET(block->bb_magic, ARCH_CONVERT, XFS_ABTB_MAGIC); - INT_SET(block->bb_level, ARCH_CONVERT, 0); - INT_SET(block->bb_numrecs, ARCH_CONVERT, 1); - INT_SET(block->bb_leftsib, ARCH_CONVERT, NULLAGBLOCK); - INT_SET(block->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK); - arec = XFS_BTREE_REC_ADDR(blocksize, xfs_alloc, block, 1, - XFS_BTREE_BLOCK_MAXRECS(blocksize, xfs_alloc, 1)); - INT_SET(arec->ar_startblock, ARCH_CONVERT, - XFS_PREALLOC_BLOCKS(mp)); + block->bb_magic = cpu_to_be32(XFS_ABTB_MAGIC); + block->bb_level = 0; + block->bb_numrecs = cpu_to_be16(1); + block->bb_leftsib = cpu_to_be32(NULLAGBLOCK); + block->bb_rightsib = cpu_to_be32(NULLAGBLOCK); + arec = XFS_BTREE_REC_ADDR(xfs_alloc, block, 1); + arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp)); if (loginternal && agno == logagno) { if (lalign) { /* * Have to insert two records * Insert pad record for stripe align of log */ - INT_SET(arec->ar_blockcount, ARCH_CONVERT, - (xfs_extlen_t)(XFS_FSB_TO_AGBNO( - mp, logstart) - - (INT_GET(arec->ar_startblock, - ARCH_CONVERT)))); + arec->ar_blockcount = cpu_to_be32( + XFS_FSB_TO_AGBNO(mp, logstart) - + be32_to_cpu(arec->ar_startblock)); nrec = arec + 1; /* * Insert record at start of internal log */ - INT_SET(nrec->ar_startblock, ARCH_CONVERT, - INT_GET(arec->ar_startblock, - ARCH_CONVERT) + - INT_GET(arec->ar_blockcount, - ARCH_CONVERT)); + nrec->ar_startblock = cpu_to_be32( + be32_to_cpu(arec->ar_startblock) + + be32_to_cpu(arec->ar_blockcount)); arec = nrec; - INT_MOD(block->bb_numrecs, ARCH_CONVERT, 1); + be16_add_cpu(&block->bb_numrecs, 1); } /* * Change record start to after the internal log */ - INT_MOD(arec->ar_startblock, ARCH_CONVERT, logblocks); + be32_add_cpu(&arec->ar_startblock, logblocks); } - INT_SET(arec->ar_blockcount, ARCH_CONVERT, - (xfs_extlen_t)(agsize - - INT_GET(arec->ar_startblock, ARCH_CONVERT))); + arec->ar_blockcount = cpu_to_be32(agsize - + be32_to_cpu(arec->ar_startblock)); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* @@ -2291,33 +2282,29 @@ an AG size that is one stripe unit smaller, for example %llu.\n"), bsize); block = XFS_BUF_TO_SBLOCK(buf); memset(block, 0, blocksize); - INT_SET(block->bb_magic, ARCH_CONVERT, XFS_ABTC_MAGIC); - INT_SET(block->bb_level, ARCH_CONVERT, 0); - INT_SET(block->bb_numrecs, ARCH_CONVERT, 1); - INT_SET(block->bb_leftsib, ARCH_CONVERT, NULLAGBLOCK); - INT_SET(block->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK); - arec = XFS_BTREE_REC_ADDR(blocksize, xfs_alloc, block, 1, - XFS_BTREE_BLOCK_MAXRECS(blocksize, xfs_alloc, 1)); - INT_SET(arec->ar_startblock, ARCH_CONVERT, - XFS_PREALLOC_BLOCKS(mp)); + block->bb_magic = cpu_to_be32(XFS_ABTC_MAGIC); + block->bb_level = 0; + block->bb_numrecs = cpu_to_be16(1); + block->bb_leftsib = cpu_to_be32(NULLAGBLOCK); + block->bb_rightsib = cpu_to_be32(NULLAGBLOCK); + arec = XFS_BTREE_REC_ADDR(xfs_alloc, block, 1); + arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp)); if (loginternal && agno == logagno) { if (lalign) { - INT_SET(arec->ar_blockcount, ARCH_CONVERT, - (xfs_extlen_t)( XFS_FSB_TO_AGBNO( - mp, logstart) - (INT_GET( - arec->ar_startblock, ARCH_CONVERT)) ) - ); + arec->ar_blockcount = cpu_to_be32( + XFS_FSB_TO_AGBNO(mp, logstart) - + be32_to_cpu(arec->ar_startblock)); nrec = arec + 1; - INT_SET(nrec->ar_startblock, ARCH_CONVERT, - INT_GET(arec->ar_startblock, ARCH_CONVERT) + - INT_GET(arec->ar_blockcount, ARCH_CONVERT)); + nrec->ar_startblock = cpu_to_be32( + be32_to_cpu(arec->ar_startblock) + + be32_to_cpu(arec->ar_blockcount)); arec = nrec; - INT_MOD(block->bb_numrecs, ARCH_CONVERT, 1); + be16_add_cpu(&block->bb_numrecs, 1); } - INT_MOD(arec->ar_startblock, ARCH_CONVERT, logblocks); + be32_add_cpu(&arec->ar_startblock, logblocks); } - INT_SET(arec->ar_blockcount, ARCH_CONVERT, (xfs_extlen_t) - (agsize - INT_GET(arec->ar_startblock, ARCH_CONVERT))); + arec->ar_blockcount = cpu_to_be32(agsize - + be32_to_cpu(arec->ar_startblock)); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* @@ -2328,11 +2315,11 @@ an AG size that is one stripe unit smaller, for example %llu.\n"), bsize); block = XFS_BUF_TO_SBLOCK(buf); memset(block, 0, blocksize); - INT_SET(block->bb_magic, ARCH_CONVERT, XFS_IBT_MAGIC); - INT_SET(block->bb_level, ARCH_CONVERT, 0); - INT_SET(block->bb_numrecs, ARCH_CONVERT, 0); - INT_SET(block->bb_leftsib, ARCH_CONVERT, NULLAGBLOCK); - INT_SET(block->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK); + block->bb_magic = cpu_to_be32(XFS_IBT_MAGIC); + block->bb_level = 0; + block->bb_numrecs = 0; + block->bb_leftsib = cpu_to_be32(NULLAGBLOCK); + block->bb_rightsib = cpu_to_be32(NULLAGBLOCK); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); } @@ -2370,7 +2357,7 @@ an AG size that is one stripe unit smaller, for example %llu.\n"), if ((c = libxfs_trans_reserve(tp, worst_freelist, 0, 0, 0, 0))) res_failed(c); libxfs_alloc_fix_freelist(&args, 0); - libxfs_trans_commit(tp, 0, NULL); + libxfs_trans_commit(tp, 0); } /* @@ -2401,8 +2388,8 @@ an AG size that is one stripe unit smaller, for example %llu.\n"), XFS_SB_DADDR), XFS_FSS_TO_BB(mp, 1), LIBXFS_EXIT_ON_FAILURE); - INT_SET((XFS_BUF_TO_SBP(buf))->sb_rootino, - ARCH_CONVERT, mp->m_sb.sb_rootino); + XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64( + mp->m_sb.sb_rootino); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* * and one in the middle for luck @@ -2413,8 +2400,8 @@ an AG size that is one stripe unit smaller, for example %llu.\n"), XFS_SB_DADDR), XFS_FSS_TO_BB(mp, 1), LIBXFS_EXIT_ON_FAILURE); - INT_SET((XFS_BUF_TO_SBP(buf))->sb_rootino, - ARCH_CONVERT, mp->m_sb.sb_rootino); + XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64( + mp->m_sb.sb_rootino); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); } } diff --git a/po/Makefile b/po/Makefile index c4e7c063a..c6ccf6058 100644 --- a/po/Makefile +++ b/po/Makefile @@ -13,6 +13,7 @@ LDIRT = $(POTHEAD) # TODO: db/ logprint/ XGETTEXTFILES = \ $(TOPDIR)/copy/xfs_copy.c \ + $(TOPDIR)/estimate/xfs_estimate.c \ $(TOPDIR)/growfs/xfs_growfs.c \ $(TOPDIR)/io/attr.c \ $(TOPDIR)/io/bmap.c \ diff --git a/quota/quot.c b/quota/quot.c index f970b640e..09d349fc0 100644 --- a/quota/quot.c +++ b/quota/quot.c @@ -107,7 +107,7 @@ quot_bulkstat_add( for (dp = *hp; dp; dp = dp->next) if (dp->id == id) break; - if (dp == 0) { + if (dp == NULL) { if (ndu[i] >= NDU) return; dp = &du[i][(ndu[i]++)]; @@ -153,7 +153,7 @@ quot_bulkstat_mount( overflow = 0; for (i = 0; i < 3; i++) for (dp = duhash[i]; dp < &duhash[i][DUHASH]; dp++) - *dp = 0; + *dp = NULL; ndu[0] = ndu[1] = ndu[2] = 0; fsfd = open(fsdir, O_RDONLY); @@ -275,7 +275,7 @@ quot_report( fs_cursor_t cursor; fs_path_t *mount; - now = time(0); + now = time(NULL); fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor); while ((mount = fs_cursor_next_entry(&cursor))) { quot_bulkstat_mount(mount->fs_dir, flags); diff --git a/repair/agheader.c b/repair/agheader.c index 21d3c4601..afac5c586 100644 --- a/repair/agheader.c +++ b/repair/agheader.c @@ -30,56 +30,54 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i) /* check common fields */ - if (INT_GET(agf->agf_magicnum, ARCH_CONVERT) != XFS_AGF_MAGIC) { + if (be32_to_cpu(agf->agf_magicnum) != XFS_AGF_MAGIC) { retval = XR_AG_AGF; do_warn(_("bad magic # 0x%x for agf %d\n"), - INT_GET(agf->agf_magicnum, ARCH_CONVERT), i); + be32_to_cpu(agf->agf_magicnum), i); if (!no_modify) - INT_SET(agf->agf_magicnum, ARCH_CONVERT, XFS_AGF_MAGIC); + agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC); } - if (!XFS_AGF_GOOD_VERSION(INT_GET(agf->agf_versionnum, ARCH_CONVERT))) { + if (!XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum))) { retval = XR_AG_AGF; do_warn(_("bad version # %d for agf %d\n"), - INT_GET(agf->agf_versionnum, ARCH_CONVERT), i); + be32_to_cpu(agf->agf_versionnum), i); if (!no_modify) - INT_SET(agf->agf_versionnum, ARCH_CONVERT, - XFS_AGF_VERSION); + agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION); } - if (INT_GET(agf->agf_seqno, ARCH_CONVERT) != i) { + if (be32_to_cpu(agf->agf_seqno) != i) { retval = XR_AG_AGF; do_warn(_("bad sequence # %d for agf %d\n"), - INT_GET(agf->agf_seqno, ARCH_CONVERT), i); + be32_to_cpu(agf->agf_seqno), i); if (!no_modify) - INT_SET(agf->agf_seqno, ARCH_CONVERT, i); + agf->agf_seqno = cpu_to_be32(i); } - if (INT_GET(agf->agf_length, ARCH_CONVERT) != mp->m_sb.sb_agblocks) { + if (be32_to_cpu(agf->agf_length) != mp->m_sb.sb_agblocks) { if (i != mp->m_sb.sb_agcount - 1) { retval = XR_AG_AGF; do_warn(_("bad length %d for agf %d, should be %d\n"), - INT_GET(agf->agf_length, ARCH_CONVERT), i, + be32_to_cpu(agf->agf_length), i, mp->m_sb.sb_agblocks); if (!no_modify) - INT_SET(agf->agf_length, ARCH_CONVERT, - mp->m_sb.sb_agblocks); + agf->agf_length = + cpu_to_be32(mp->m_sb.sb_agblocks); } else { agblocks = mp->m_sb.sb_dblocks - (xfs_drfsbno_t) mp->m_sb.sb_agblocks * i; - if (INT_GET(agf->agf_length, ARCH_CONVERT) != agblocks) { + if (be32_to_cpu(agf->agf_length) != agblocks) { retval = XR_AG_AGF; do_warn( _("bad length %d for agf %d, should be %llu\n"), - INT_GET(agf->agf_length, ARCH_CONVERT), + be32_to_cpu(agf->agf_length), i, agblocks); if (!no_modify) - INT_SET(agf->agf_length, ARCH_CONVERT, - (xfs_agblock_t) agblocks); + agf->agf_length = cpu_to_be32(agblocks); } } } @@ -88,20 +86,18 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i) * check first/last AGF fields. if need be, lose the free * space in the AGFL, we'll reclaim it later. */ - if (INT_GET(agf->agf_flfirst, ARCH_CONVERT) >= XFS_AGFL_SIZE(mp)) { + if (be32_to_cpu(agf->agf_flfirst) >= XFS_AGFL_SIZE(mp)) { do_warn(_("flfirst %d in agf %d too large (max = %d)\n"), - INT_GET(agf->agf_flfirst, ARCH_CONVERT), - i, XFS_AGFL_SIZE(mp)); + be32_to_cpu(agf->agf_flfirst), i, XFS_AGFL_SIZE(mp)); if (!no_modify) - agf->agf_flfirst = 0; + agf->agf_flfirst = cpu_to_be32(0); } - if (INT_GET(agf->agf_fllast, ARCH_CONVERT) >= XFS_AGFL_SIZE(mp)) { + if (be32_to_cpu(agf->agf_fllast) >= XFS_AGFL_SIZE(mp)) { do_warn(_("fllast %d in agf %d too large (max = %d)\n"), - INT_GET(agf->agf_fllast, ARCH_CONVERT), - i, XFS_AGFL_SIZE(mp)); + be32_to_cpu(agf->agf_fllast), i, XFS_AGFL_SIZE(mp)); if (!no_modify) - agf->agf_fllast = 0; + agf->agf_fllast = cpu_to_be32(0); } /* don't check freespace btrees -- will be checked by caller */ @@ -110,63 +106,61 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i) } int -verify_set_agi(xfs_mount_t *mp, xfs_agi_t *agi, xfs_agnumber_t i) +verify_set_agi(xfs_mount_t *mp, xfs_agi_t *agi, xfs_agnumber_t agno) { xfs_drfsbno_t agblocks; int retval = 0; /* check common fields */ - if (INT_GET(agi->agi_magicnum, ARCH_CONVERT) != XFS_AGI_MAGIC) { + if (be32_to_cpu(agi->agi_magicnum) != XFS_AGI_MAGIC) { retval = XR_AG_AGI; do_warn(_("bad magic # 0x%x for agi %d\n"), - INT_GET(agi->agi_magicnum, ARCH_CONVERT), i); + be32_to_cpu(agi->agi_magicnum), agno); if (!no_modify) - INT_SET(agi->agi_magicnum, ARCH_CONVERT, XFS_AGI_MAGIC); + agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); } - if (!XFS_AGI_GOOD_VERSION(INT_GET(agi->agi_versionnum, ARCH_CONVERT))) { + if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum))) { retval = XR_AG_AGI; do_warn(_("bad version # %d for agi %d\n"), - INT_GET(agi->agi_versionnum, ARCH_CONVERT), i); + be32_to_cpu(agi->agi_versionnum), agno); if (!no_modify) - INT_SET(agi->agi_versionnum, ARCH_CONVERT, - XFS_AGI_VERSION); + agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION); } - if (INT_GET(agi->agi_seqno, ARCH_CONVERT) != i) { + if (be32_to_cpu(agi->agi_seqno) != agno) { retval = XR_AG_AGI; do_warn(_("bad sequence # %d for agi %d\n"), - INT_GET(agi->agi_seqno, ARCH_CONVERT), i); + be32_to_cpu(agi->agi_seqno), agno); if (!no_modify) - INT_SET(agi->agi_seqno, ARCH_CONVERT, i); + agi->agi_seqno = cpu_to_be32(agno); } - if (INT_GET(agi->agi_length, ARCH_CONVERT) != mp->m_sb.sb_agblocks) { - if (i != mp->m_sb.sb_agcount - 1) { + if (be32_to_cpu(agi->agi_length) != mp->m_sb.sb_agblocks) { + if (agno != mp->m_sb.sb_agcount - 1) { retval = XR_AG_AGI; do_warn(_("bad length # %d for agi %d, should be %d\n"), - INT_GET(agi->agi_length, ARCH_CONVERT), i, + be32_to_cpu(agi->agi_length), agno, mp->m_sb.sb_agblocks); if (!no_modify) - INT_SET(agi->agi_length, ARCH_CONVERT, - mp->m_sb.sb_agblocks); + agi->agi_length = + cpu_to_be32(mp->m_sb.sb_agblocks); } else { agblocks = mp->m_sb.sb_dblocks - - (xfs_drfsbno_t) mp->m_sb.sb_agblocks * i; + (xfs_drfsbno_t) mp->m_sb.sb_agblocks * agno; - if (INT_GET(agi->agi_length, ARCH_CONVERT) != agblocks) { + if (be32_to_cpu(agi->agi_length) != agblocks) { retval = XR_AG_AGI; do_warn( _("bad length # %d for agi %d, should be %llu\n"), - INT_GET(agi->agi_length, ARCH_CONVERT), - i, agblocks); + be32_to_cpu(agi->agi_length), + agno, agblocks); if (!no_modify) - INT_SET(agi->agi_length, ARCH_CONVERT, - (xfs_agblock_t) agblocks); + agi->agi_length = cpu_to_be32(agblocks); } } } @@ -245,16 +239,16 @@ secondary_sb_wack(xfs_mount_t *mp, xfs_buf_t *sbuf, xfs_sb_t *sb, * work against older filesystems when the superblock * gets rev'ed again with new fields appended. */ - if (XFS_SB_VERSION_HASMOREBITS(sb)) + if (xfs_sb_version_hasmorebits(sb)) size = (__psint_t)&sb->sb_features2 + sizeof(sb->sb_features2) - (__psint_t)sb; - else if (XFS_SB_VERSION_HASLOGV2(sb)) + else if (xfs_sb_version_haslogv2(sb)) size = (__psint_t)&sb->sb_logsunit + sizeof(sb->sb_logsunit) - (__psint_t)sb; - else if (XFS_SB_VERSION_HASSECTOR(sb)) + else if (xfs_sb_version_hassector(sb)) size = (__psint_t)&sb->sb_logsectsize + sizeof(sb->sb_logsectsize) - (__psint_t)sb; - else if (XFS_SB_VERSION_HASDIRV2(sb)) + else if (xfs_sb_version_hasdirv2(sb)) size = (__psint_t)&sb->sb_dirblklog + sizeof(sb->sb_dirblklog) - (__psint_t)sb; else @@ -352,7 +346,7 @@ secondary_sb_wack(xfs_mount_t *mp, xfs_buf_t *sbuf, xfs_sb_t *sb, * written at mkfs time (and the corresponding sb version bits * are set). */ - if (!XFS_SB_VERSION_HASSHARED(sb) && sb->sb_shared_vn != 0) { + if (!xfs_sb_version_hasshared(sb) && sb->sb_shared_vn != 0) { if (!no_modify) sb->sb_shared_vn = 0; if (sb->sb_versionnum & XR_PART_SECSB_VNMASK || !do_bzero) { @@ -364,7 +358,7 @@ secondary_sb_wack(xfs_mount_t *mp, xfs_buf_t *sbuf, xfs_sb_t *sb, rval |= XR_AG_SB_SEC; } - if (!XFS_SB_VERSION_HASALIGN(sb) && sb->sb_inoalignmt != 0) { + if (!xfs_sb_version_hasalign(sb) && sb->sb_inoalignmt != 0) { if (!no_modify) sb->sb_inoalignmt = 0; if (sb->sb_versionnum & XR_PART_SECSB_VNMASK || !do_bzero) { @@ -376,7 +370,7 @@ secondary_sb_wack(xfs_mount_t *mp, xfs_buf_t *sbuf, xfs_sb_t *sb, rval |= XR_AG_SB_SEC; } - if (!XFS_SB_VERSION_HASDALIGN(sb) && + if (!xfs_sb_version_hasdalign(sb) && (sb->sb_unit != 0 || sb->sb_width != 0)) { if (!no_modify) sb->sb_unit = sb->sb_width = 0; @@ -389,7 +383,7 @@ secondary_sb_wack(xfs_mount_t *mp, xfs_buf_t *sbuf, xfs_sb_t *sb, rval |= XR_AG_SB_SEC; } - if (!XFS_SB_VERSION_HASSECTOR(sb) && + if (!xfs_sb_version_hassector(sb) && (sb->sb_sectsize != BBSIZE || sb->sb_sectlog != BBSHIFT || sb->sb_logsectsize != 0 || sb->sb_logsectlog != 0)) { if (!no_modify) { diff --git a/repair/attr_repair.c b/repair/attr_repair.c index 1e0da7171..dbddf797a 100644 --- a/repair/attr_repair.c +++ b/repair/attr_repair.c @@ -25,7 +25,7 @@ #include "bmap.h" #include "protos.h" -static int xfs_acl_valid(xfs_acl_t *aclp); +static int xfs_acl_valid(xfs_acl_disk_t *daclp); static int xfs_mac_valid(xfs_mac_label_t *lp); @@ -50,7 +50,7 @@ static int xfs_mac_valid(xfs_mac_label_t *lp); * if it remains large enough to still be a leaf block attribute. Otherwise, * it may have to be converted to shortform. How to convert this and when * is an issue. This call is happening in Phase3. Phase5 will capture empty - * blocks, but Phase6 allows you to use the simulation library which knows + * blocks, but Phase6 allows you to use the libxfs library which knows * how to handle attributes in the kernel for converting formats. What we * could do is mark an attribute to be cleared now, but in phase6 somehow * have it cleared for real and then the format changed to shortform if @@ -100,7 +100,7 @@ valuecheck(char *namevalue, char *value, int namelen, int valuelen) } else valuep = value; - if (xfs_acl_valid((xfs_acl_t *) valuep) != 0) { /* 0 is valid */ + if (xfs_acl_valid((xfs_acl_disk_t *)valuep) != 0) { clearit = 1; do_warn( _("entry contains illegal value in attribute named SGI_ACL_FILE " @@ -164,16 +164,16 @@ process_shortform_attr( /* Assumption: hdr.totsize is less than a leaf block and was checked * by lclinode for valid sizes. Check the count though. */ - if (INT_GET(asf->hdr.count, ARCH_CONVERT) == 0) + if (asf->hdr.count == 0) /* then the total size should just be the header length */ - if (INT_GET(asf->hdr.totsize, ARCH_CONVERT) != sizeof(xfs_attr_sf_hdr_t)) { + if (be16_to_cpu(asf->hdr.totsize) != sizeof(xfs_attr_sf_hdr_t)) { /* whoops there's a discrepancy. Clear the hdr */ if (!no_modify) { do_warn( _("there are no attributes in the fork for inode %llu\n"), ino); - INT_SET(asf->hdr.totsize, ARCH_CONVERT, - sizeof(xfs_attr_sf_hdr_t)); + asf->hdr.totsize = + cpu_to_be16(sizeof(xfs_attr_sf_hdr_t)); *repair = 1; return(1); } else { @@ -185,19 +185,19 @@ process_shortform_attr( } currentsize = sizeof(xfs_attr_sf_hdr_t); - remainingspace = INT_GET(asf->hdr.totsize, ARCH_CONVERT) - currentsize; + remainingspace = be16_to_cpu(asf->hdr.totsize) - currentsize; nextentry = &asf->list[0]; - for (i = 0; i < INT_GET(asf->hdr.count, ARCH_CONVERT); i++) { + for (i = 0; i < asf->hdr.count; i++) { currententry = nextentry; junkit = 0; /* don't go off the end if the hdr.count was off */ if ((currentsize + (sizeof(xfs_attr_sf_entry_t) - 1)) > - INT_GET(asf->hdr.totsize, ARCH_CONVERT)) + be16_to_cpu(asf->hdr.totsize)) break; /* get out and reset count and totSize */ /* if the namelen is 0, can't get to the rest of the entries */ - if (INT_GET(currententry->namelen, ARCH_CONVERT) == 0) { + if (currententry->namelen == 0) { do_warn(_("zero length name entry in attribute fork,")); if (!no_modify) { do_warn( @@ -214,11 +214,9 @@ process_shortform_attr( * rough check to make sure we haven't gone outside of * totsize. */ - if ((remainingspace < - INT_GET(currententry->namelen, ARCH_CONVERT)) || - ((remainingspace - - INT_GET(currententry->namelen, ARCH_CONVERT)) < - INT_GET(currententry->valuelen, ARCH_CONVERT))) { + if (remainingspace < currententry->namelen || + ((remainingspace - currententry-> + namelen) < currententry->valuelen)) { do_warn( _("name or value attribute lengths are too large,\n")); if (!no_modify) { @@ -240,27 +238,26 @@ process_shortform_attr( * attributes names currently follow the same rules. */ if (namecheck((char *)¤tentry->nameval[0], - INT_GET(currententry->namelen, ARCH_CONVERT))) { + currententry->namelen)) { do_warn( _("entry contains illegal character in shortform attribute name\n")); junkit = 1; } - if (INT_GET(currententry->flags, ARCH_CONVERT) & XFS_ATTR_INCOMPLETE) { + if (currententry->flags & XFS_ATTR_INCOMPLETE) { do_warn( _("entry has INCOMPLETE flag on in shortform attribute\n")); junkit = 1; } /* Only check values for root security attributes */ - if (INT_GET(currententry->flags, ARCH_CONVERT) & XFS_ATTR_ROOT) + if (currententry->flags & XFS_ATTR_ROOT) junkit = valuecheck((char *)¤tentry->nameval[0], - NULL, - INT_GET(currententry->namelen, ARCH_CONVERT), - INT_GET(currententry->valuelen, ARCH_CONVERT)); + NULL, currententry->namelen, + currententry->valuelen); remainingspace = remainingspace - - XFS_ATTR_SF_ENTSIZE(currententry); + XFS_ATTR_SF_ENTSIZE(currententry); if (junkit) { if (!no_modify) { @@ -272,7 +269,7 @@ process_shortform_attr( ((__psint_t) currententry + XFS_ATTR_SF_ENTSIZE(currententry)); memmove(currententry,tempentry,remainingspace); - INT_MOD(asf->hdr.count, ARCH_CONVERT, -1); + asf->hdr.count -= 1; i--; /* no worries, it will wrap back to 0 */ *repair = 1; continue; /* go back up now */ @@ -284,40 +281,39 @@ process_shortform_attr( } /* Let's get ready for the next entry... */ - nextentry = (xfs_attr_sf_entry_t *) - ((__psint_t) nextentry + - XFS_ATTR_SF_ENTSIZE(currententry)); + nextentry = (xfs_attr_sf_entry_t *)((__psint_t) nextentry + + XFS_ATTR_SF_ENTSIZE(currententry)); currentsize = currentsize + XFS_ATTR_SF_ENTSIZE(currententry); } /* end the loop */ - if (INT_GET(asf->hdr.count, ARCH_CONVERT) != i) { + if (asf->hdr.count != i) { if (no_modify) { do_warn(_("would have corrected attribute entry count " "in inode %llu from %d to %d\n"), - ino, INT_GET(asf->hdr.count, ARCH_CONVERT), i); + ino, asf->hdr.count, i); } else { do_warn(_("corrected attribute entry count in inode " "%llu, was %d, now %d\n"), - ino, INT_GET(asf->hdr.count, ARCH_CONVERT), i); - INT_SET(asf->hdr.count, ARCH_CONVERT, i); + ino, asf->hdr.count, i); + asf->hdr.count = i; *repair = 1; } } /* ASSUMPTION: currentsize <= totsize */ - if (INT_GET(asf->hdr.totsize, ARCH_CONVERT) != currentsize) { + if (be16_to_cpu(asf->hdr.totsize) != currentsize) { if (no_modify) { do_warn(_("would have corrected attribute totsize in " "inode %llu from %d to %d\n"), - ino, INT_GET(asf->hdr.totsize, ARCH_CONVERT), + ino, be16_to_cpu(asf->hdr.totsize), currentsize); } else { do_warn(_("corrected attribute entry totsize in " "inode %llu, was %d, now %d\n"), - ino, INT_GET(asf->hdr.totsize, ARCH_CONVERT), + ino, be16_to_cpu(asf->hdr.totsize), currentsize); - INT_SET(asf->hdr.totsize, ARCH_CONVERT, currentsize); + asf->hdr.totsize = cpu_to_be16(currentsize); *repair = 1; } } @@ -381,6 +377,115 @@ size_t ts_attr_freemap_size = sizeof(da_freemap_t) * DA_BMAP_SIZE; * be changed. */ +static int +process_leaf_attr_local( + xfs_attr_leafblock_t *leaf, + int i, + xfs_attr_leaf_entry_t *entry, + xfs_dahash_t last_hashval, + xfs_dablk_t da_bno, + xfs_ino_t ino) +{ + xfs_attr_leaf_name_local_t *local; + + local = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); + if (local->namelen == 0 || namecheck((char *)&local->nameval[0], + local->namelen)) { + do_warn(_("attribute entry %d in attr block %u, inode %llu " + "has bad name (namelen = %d)\n"), + i, da_bno, ino, local->namelen); + return -1; + } + + /* Check on the hash value. Checking order of values + * is not necessary, since one wrong clears the whole + * fork. If the ordering's wrong, it's caught here or + * the kernel code has a bug with transaction logging + * or attributes itself. Being paranoid, let's check + * ordering anyway in case both the name value and the + * hashvalue were wrong but matched. Unlikely, however. + */ + if (be32_to_cpu(entry->hashval) != libxfs_da_hashname( + &local->nameval[0], local->namelen) || + be32_to_cpu(entry->hashval) < last_hashval) { + do_warn(_("bad hashvalue for attribute entry %d in " + "attr block %u, inode %llu\n"), i, da_bno, ino); + return -1; + } + + /* Only check values for root security attributes */ + if (entry->flags & XFS_ATTR_ROOT) { + if (valuecheck((char *)&local->nameval[0], NULL, + local->namelen, be16_to_cpu(local->valuelen))) { + do_warn(_("bad security value for attribute entry %d " + "in attr block %u, inode %llu\n"), + i, da_bno, ino); + return -1; + } + } + return XFS_ATTR_LEAF_ENTSIZE_LOCAL(local->namelen, + be16_to_cpu(local->valuelen)); +} + +static int +process_leaf_attr_remote( + xfs_attr_leafblock_t *leaf, + int i, + xfs_attr_leaf_entry_t *entry, + xfs_dahash_t last_hashval, + xfs_dablk_t da_bno, + xfs_ino_t ino, + xfs_mount_t *mp, + blkmap_t *blkmap) +{ + xfs_attr_leaf_name_remote_t *remotep; + char* value; + + remotep = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i); + + if (remotep->namelen == 0 || namecheck((char *)&remotep->name[0], + remotep->namelen) || + be32_to_cpu(entry->hashval) != + libxfs_da_hashname((uchar_t *)&remotep->name[0], + remotep->namelen) || + be32_to_cpu(entry->hashval) < last_hashval || + be32_to_cpu(remotep->valueblk) == 0) { + do_warn(_("inconsistent remote attribute entry %d in " + "attr block %u, ino %llu\n"), i, da_bno, ino); + return -1; + } + + if (!(entry->flags & XFS_ATTR_ROOT)) + goto out; + + value = malloc(be32_to_cpu(remotep->valuelen)); + if (value == NULL) { + do_warn(_("cannot malloc enough for remotevalue attribute " + "for inode %llu\n"), ino); + do_warn(_("SKIPPING this remote attribute\n")); + goto out; + } + if (rmtval_get(mp, ino, blkmap, be32_to_cpu(remotep->valueblk), + be32_to_cpu(remotep->valuelen), value)) { + do_warn(_("remote attribute get failed for entry %d, " + "inode %llu\n"), i, ino); + goto bad_free_out; + } + if (valuecheck((char *)&remotep->name[0], value, remotep->namelen, + be32_to_cpu(remotep->valuelen))) { + do_warn(_("remote attribute value check failed for entry %d, " + "inode %llu\n"), i, ino); + goto bad_free_out; + } + free(value); +out: + return XFS_ATTR_LEAF_ENTSIZE_REMOTE(remotep->namelen); + +bad_free_out: + free(value); + return -1; +} + int process_leaf_attr_block( xfs_mount_t *mp, @@ -393,8 +498,6 @@ process_leaf_attr_block( int *repair) { xfs_attr_leaf_entry_t *entry; - xfs_attr_leaf_name_local_t *local; - xfs_attr_leaf_name_remote_t *remotep; int i, start, stop, clearit, usedbs, firstb, thissize; da_freemap_t *attr_freemap = ts_attr_freemap(); @@ -404,14 +507,11 @@ process_leaf_attr_block( stop = sizeof(xfs_attr_leaf_hdr_t); /* does the count look sorta valid? */ - if (INT_GET(leaf->hdr.count, ARCH_CONVERT) - * sizeof(xfs_attr_leaf_entry_t) - + sizeof(xfs_attr_leaf_hdr_t) - > XFS_LBSIZE(mp)) { + if (be16_to_cpu(leaf->hdr.count) * sizeof(xfs_attr_leaf_entry_t) + + sizeof(xfs_attr_leaf_hdr_t) > XFS_LBSIZE(mp)) { do_warn( _("bad attribute count %d in attr block %u, inode %llu\n"), - (int) INT_GET(leaf->hdr.count, ARCH_CONVERT), - da_bno, ino); + be16_to_cpu(leaf->hdr.count), da_bno, ino); return (1); } @@ -419,21 +519,19 @@ process_leaf_attr_block( (void) set_da_freemap(mp, attr_freemap, 0, stop); /* go thru each entry checking for problems */ - for (i = 0, entry = &leaf->entries[0]; - i < INT_GET(leaf->hdr.count, ARCH_CONVERT); - i++, entry++) { + for (i = 0, entry = &leaf->entries[0]; + i < be16_to_cpu(leaf->hdr.count); i++, entry++) { /* check if index is within some boundary. */ - if (INT_GET(entry->nameidx, ARCH_CONVERT) > XFS_LBSIZE(mp)) { + if (be16_to_cpu(entry->nameidx) > XFS_LBSIZE(mp)) { do_warn( _("bad attribute nameidx %d in attr block %u, inode %llu\n"), - (int)INT_GET(entry->nameidx, ARCH_CONVERT), - da_bno,ino); + be16_to_cpu(entry->nameidx), da_bno, ino); clearit = 1; break; } - if (INT_GET(entry->flags, ARCH_CONVERT) & XFS_ATTR_INCOMPLETE) { + if (entry->flags & XFS_ATTR_INCOMPLETE) { /* we are inconsistent state. get rid of us */ do_warn( _("attribute entry #%d in attr block %u, inode %llu is INCOMPLETE\n"), @@ -454,130 +552,22 @@ process_leaf_attr_block( break; /* got an overlap */ } - if (INT_GET(entry->flags, ARCH_CONVERT) & XFS_ATTR_LOCAL) { - - local = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); - if ((INT_GET(local->namelen, ARCH_CONVERT) == 0) || - (namecheck((char *)&local->nameval[0], - INT_GET(local->namelen, ARCH_CONVERT)))) { - do_warn( - _("attribute entry %d in attr block %u, inode %llu " - "has bad name (namelen = %d)\n"), - i, da_bno, ino, (int) - INT_GET(local->namelen, ARCH_CONVERT)); - clearit = 1; - break; - } - - /* Check on the hash value. Checking order of values - * is not necessary, since one wrong clears the whole - * fork. If the ordering's wrong, it's caught here or - * the kernel code has a bug with transaction logging - * or attributes itself. Being paranoid, let's check - * ordering anyway in case both the name value and the - * hashvalue were wrong but matched. Unlikely, however. - */ - if (INT_GET(entry->hashval, ARCH_CONVERT) != - libxfs_da_hashname((uchar_t *)&local->nameval[0], - INT_GET(local->namelen, - ARCH_CONVERT)) || - (INT_GET(entry->hashval, ARCH_CONVERT) < - last_hashval)) { - do_warn( - _("bad hashvalue for attribute entry %d in " - "attr block %u, inode %llu\n"), - i, da_bno, ino); - clearit = 1; - break; - } - - /* Only check values for root security attributes */ - if (INT_GET(entry->flags, ARCH_CONVERT) & XFS_ATTR_ROOT) - if (valuecheck((char *)&local->nameval[0], NULL, - INT_GET(local->namelen, ARCH_CONVERT), - INT_GET(local->valuelen, ARCH_CONVERT))) { - do_warn( - _("bad security value for attribute entry %d in " - "attr block %u, inode %llu\n"), - i, da_bno, ino); - clearit = 1; - break; - } - - thissize = XFS_ATTR_LEAF_ENTSIZE_LOCAL( - INT_GET(local->namelen, ARCH_CONVERT), - INT_GET(local->valuelen, ARCH_CONVERT)); - - } else { - /* do the remote case */ - remotep = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i); - thissize = XFS_ATTR_LEAF_ENTSIZE_REMOTE( - INT_GET(remotep->namelen, ARCH_CONVERT)); - - if ((INT_GET(remotep->namelen, ARCH_CONVERT) == 0) || - (namecheck((char *)&remotep->name[0], - INT_GET(remotep->namelen, ARCH_CONVERT))) || - (INT_GET(entry->hashval, ARCH_CONVERT) - != libxfs_da_hashname( - (uchar_t *)&remotep->name[0], - INT_GET(remotep->namelen, ARCH_CONVERT))) || - (INT_GET(entry->hashval, ARCH_CONVERT) - < last_hashval) || - (INT_GET(remotep->valueblk, ARCH_CONVERT) == 0)) { - do_warn( - _("inconsistent remote attribute entry %d in " - "attr block %u, ino %llu\n"), - i, da_bno, ino); - clearit = 1; - break; - } - - if (INT_GET(entry->flags, ARCH_CONVERT) & XFS_ATTR_ROOT) { - char* value; - - if ((value = malloc(INT_GET(remotep->valuelen, - ARCH_CONVERT))) == NULL) { - do_warn( - _("cannot malloc enough for remotevalue attribute for inode %llu\n"), - ino); - do_warn( - _("SKIPPING this remote attribute\n")); - continue; - } - if (rmtval_get(mp, ino, blkmap, - INT_GET(remotep->valueblk, - ARCH_CONVERT), - INT_GET(remotep->valuelen, - ARCH_CONVERT), value)) { - do_warn( - _("remote attribute get failed for entry %d, inode %llu\n"), i, ino); - clearit = 1; - free(value); - break; - } - if (valuecheck((char *)&remotep->name[0], value, - INT_GET(remotep->namelen, - ARCH_CONVERT), - INT_GET(remotep->valuelen, - ARCH_CONVERT))) { - do_warn( - _("remote attribute value check failed for entry %d, inode %llu\n"), - i, ino); - clearit = 1; - free(value); - break; - } - free(value); - } + if (entry->flags & XFS_ATTR_LOCAL) + thissize = process_leaf_attr_local(leaf, i, entry, + last_hashval, da_bno, ino); + else + thissize = process_leaf_attr_remote(leaf, i, entry, + last_hashval, da_bno, ino, + mp, blkmap); + if (thissize < 0) { + clearit = 1; + break; } - *current_hashval = last_hashval - = INT_GET(entry->hashval, ARCH_CONVERT); + *current_hashval = last_hashval = be32_to_cpu(entry->hashval); - if (set_da_freemap(mp, attr_freemap, - INT_GET(entry->nameidx, ARCH_CONVERT), - INT_GET(entry->nameidx, ARCH_CONVERT) + - thissize)) { + if (set_da_freemap(mp, attr_freemap, be16_to_cpu(entry->nameidx), + be16_to_cpu(entry->nameidx) + thissize)) { do_warn(_("attribute entry %d in attr block %u, " "inode %llu claims used space\n"), i, da_bno, ino); @@ -585,8 +575,8 @@ process_leaf_attr_block( break; /* got an overlap */ } usedbs += thissize; - if (INT_GET(entry->nameidx, ARCH_CONVERT) < firstb) - firstb = INT_GET(entry->nameidx, ARCH_CONVERT); + if (be16_to_cpu(entry->nameidx) < firstb) + firstb = be16_to_cpu(entry->nameidx); } /* end the loop */ @@ -598,45 +588,41 @@ process_leaf_attr_block( * since the block will get compacted anyhow by the kernel. */ - if ( (INT_GET(leaf->hdr.holes, ARCH_CONVERT) == 0 - && firstb != INT_GET(leaf->hdr.firstused, ARCH_CONVERT)) - || INT_GET(leaf->hdr.firstused, ARCH_CONVERT) > firstb) { + if ((leaf->hdr.holes == 0 && + firstb != be16_to_cpu(leaf->hdr.firstused)) || + be16_to_cpu(leaf->hdr.firstused) > firstb) { if (!no_modify) { do_warn( _("- resetting first used heap value from %d to %d in " "block %u of attribute fork of inode %llu\n"), - (int)INT_GET(leaf->hdr.firstused, - ARCH_CONVERT), firstb, - da_bno, ino); - INT_SET(leaf->hdr.firstused, - ARCH_CONVERT, firstb); + be16_to_cpu(leaf->hdr.firstused), + firstb, da_bno, ino); + leaf->hdr.firstused = cpu_to_be16(firstb); *repair = 1; } else { do_warn( _("- would reset first used value from %d to %d in " "block %u of attribute fork of inode %llu\n"), - (int)INT_GET(leaf->hdr.firstused, - ARCH_CONVERT), firstb, - da_bno, ino); + be16_to_cpu(leaf->hdr.firstused), + firstb, da_bno, ino); } } - if (usedbs != INT_GET(leaf->hdr.usedbytes, ARCH_CONVERT)) { + if (usedbs != be16_to_cpu(leaf->hdr.usedbytes)) { if (!no_modify) { do_warn( _("- resetting usedbytes cnt from %d to %d in " "block %u of attribute fork of inode %llu\n"), - (int)INT_GET(leaf->hdr.usedbytes, - ARCH_CONVERT), usedbs, da_bno, ino); - INT_SET(leaf->hdr.usedbytes, - ARCH_CONVERT, usedbs); + be16_to_cpu(leaf->hdr.usedbytes), + usedbs, da_bno, ino); + leaf->hdr.usedbytes = cpu_to_be16(usedbs); *repair = 1; } else { do_warn( _("- would reset usedbytes cnt from %d to %d in " "block %u of attribute fork of %llu\n"), - (int)INT_GET(leaf->hdr.usedbytes, - ARCH_CONVERT), usedbs,da_bno,ino); + be16_to_cpu(leaf->hdr.usedbytes), + usedbs, da_bno, ino); } } @@ -699,8 +685,7 @@ process_leaf_attr_level(xfs_mount_t *mp, leaf = (xfs_attr_leafblock_t *)XFS_BUF_PTR(bp); /* check magic number for leaf directory btree block */ - if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) - != XFS_ATTR_LEAF_MAGIC) { + if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) { do_warn(_("bad attribute leaf magic %#x " "for inode %llu\n"), leaf->hdr.info.magic, ino); @@ -728,11 +713,10 @@ process_leaf_attr_level(xfs_mount_t *mp, da_cursor->level[0].hashval = greatest_hashval; da_cursor->level[0].bp = bp; da_cursor->level[0].bno = da_bno; - da_cursor->level[0].index - = INT_GET(leaf->hdr.count, ARCH_CONVERT); + da_cursor->level[0].index = be16_to_cpu(leaf->hdr.count); da_cursor->level[0].dirty = repair; - if (INT_GET(leaf->hdr.info.back, ARCH_CONVERT) != prev_bno) { + if (be32_to_cpu(leaf->hdr.info.back) != prev_bno) { do_warn(_("bad sibling back pointer for block %u in " "attribute fork for inode %llu\n"), da_bno, ino); @@ -741,7 +725,7 @@ process_leaf_attr_level(xfs_mount_t *mp, } prev_bno = da_bno; - da_bno = INT_GET(leaf->hdr.info.forw, ARCH_CONVERT); + da_bno = be32_to_cpu(leaf->hdr.info.forw); if (da_bno != 0 && verify_da_path(mp, da_cursor, 0)) { libxfs_putbuf(bp); @@ -750,12 +734,10 @@ process_leaf_attr_level(xfs_mount_t *mp, current_hashval = greatest_hashval; - if (repair && !no_modify) { + if (repair && !no_modify) libxfs_writebuf(bp, 0); - } - else { + else libxfs_putbuf(bp); - } } while (da_bno != 0); if (verify_final_da_path(mp, da_cursor, 0)) { @@ -858,15 +840,12 @@ process_longform_attr( bno = blkmap_get(blkmap, 0); if ( bno == NULLDFSBNO ) { - if (INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) == 0 && - dip->di_core.di_aformat == XFS_DINODE_FMT_EXTENTS ) - /* it's okay the kernel can handle this state */ - return(0); - else { - do_warn(_("block 0 of inode %llu attribute fork" - " is missing\n"), ino); - return(1); - } + if (dip->di_core.di_aformat == XFS_DINODE_FMT_EXTENTS && + be16_to_cpu(dip->di_core.di_anextents) == 0) + return(0); /* the kernel can handle this state */ + do_warn(_("block 0 of inode %llu attribute fork is missing\n"), + ino); + return(1); } /* FIX FOR bug 653709 -- EKN */ if (mp->m_sb.sb_agcount < XFS_FSB_TO_AGNO(mp, bno)) { @@ -889,14 +868,14 @@ process_longform_attr( /* check sibling pointers in leaf block or root block 0 before * we have to release the btree block */ - if ( INT_GET(leaf->hdr.info.forw, ARCH_CONVERT) != 0 - || INT_GET(leaf->hdr.info.back, ARCH_CONVERT) != 0) { + if (be32_to_cpu(leaf->hdr.info.forw) != 0 || + be32_to_cpu(leaf->hdr.info.back) != 0) { if (!no_modify) { do_warn(_("clearing forw/back pointers in block 0 " "for attributes in inode %llu\n"), ino); repairlinks = 1; - INT_SET(leaf->hdr.info.forw, ARCH_CONVERT, 0); - INT_SET(leaf->hdr.info.back, ARCH_CONVERT, 0); + leaf->hdr.info.forw = cpu_to_be32(0); + leaf->hdr.info.back = cpu_to_be32(0); } else { do_warn(_("would clear forw/back pointers in block 0 " "for attributes in inode %llu\n"), ino); @@ -908,7 +887,7 @@ process_longform_attr( * it's possible to have a node or leaf attribute in either an * extent format or btree format attribute fork. */ - switch (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT)) { + switch (be16_to_cpu(leaf->hdr.info.magic)) { case XFS_ATTR_LEAF_MAGIC: /* leaf-form attribute */ if (process_leaf_attr_block(mp, leaf, 0, ino, blkmap, 0, &next_hashval, repair)) { @@ -929,7 +908,7 @@ process_longform_attr( return (process_node_attr(mp, ino, dip, blkmap)); /* + repair */ default: do_warn(_("bad attribute leaf magic # %#x for dir ino %llu\n"), - INT_GET(leaf->hdr.info.magic, ARCH_CONVERT), ino); + be16_to_cpu(leaf->hdr.info.magic), ino); libxfs_putbuf(bp); return(1); } @@ -943,18 +922,27 @@ process_longform_attr( } -static void -xfs_acl_get_endian(xfs_acl_t *aclp) +static xfs_acl_t * +xfs_acl_from_disk(xfs_acl_disk_t *dacl) { - xfs_acl_entry_t *ace, *end; - - INT_SET(aclp->acl_cnt, ARCH_CONVERT, aclp->acl_cnt); - end = &aclp->acl_entry[0]+aclp->acl_cnt; - for (ace = &aclp->acl_entry[0]; ace < end; ace++) { - INT_SET(ace->ae_tag, ARCH_CONVERT, ace->ae_tag); - INT_SET(ace->ae_id, ARCH_CONVERT, ace->ae_id); - INT_SET(ace->ae_perm, ARCH_CONVERT, ace->ae_perm); + int count; + xfs_acl_t *acl; + xfs_acl_entry_t *ace; + xfs_acl_entry_disk_t *dace, *end; + + count = be32_to_cpu(dacl->acl_cnt); + end = &dacl->acl_entry[0] + count; + acl = malloc((int)((char *)end - (char *)dacl)); + if (!acl) + return NULL; + acl->acl_cnt = count; + ace = &acl->acl_entry[0]; + for (dace = &dacl->acl_entry[0]; dace < end; ace++, dace++) { + ace->ae_tag = be32_to_cpu(dace->ae_tag); + ace->ae_id = be32_to_cpu(dace->ae_id); + ace->ae_perm = be16_to_cpu(dace->ae_perm); } + return acl; } /* @@ -969,27 +957,25 @@ process_attributes( blkmap_t *blkmap, int *repair) /* returned if we did repair */ { - int err; - xfs_dinode_core_t *dinoc; - /* REFERENCED */ + int err; + __u8 aformat = dip->di_core.di_aformat; xfs_attr_shortform_t *asf; - dinoc = &dip->di_core; asf = (xfs_attr_shortform_t *) XFS_DFORK_APTR(dip); - if (dinoc->di_aformat == XFS_DINODE_FMT_LOCAL) { - ASSERT(INT_GET(asf->hdr.totsize, ARCH_CONVERT) <= + if (aformat == XFS_DINODE_FMT_LOCAL) { + ASSERT(be16_to_cpu(asf->hdr.totsize) <= XFS_DFORK_ASIZE(dip, mp)); err = process_shortform_attr(ino, dip, repair); - } else if (dinoc->di_aformat == XFS_DINODE_FMT_EXTENTS || - dinoc->di_aformat == XFS_DINODE_FMT_BTREE) { + } else if (aformat == XFS_DINODE_FMT_EXTENTS || + aformat == XFS_DINODE_FMT_BTREE) { err = process_longform_attr(mp, ino, dip, blkmap, repair); /* if err, convert this to shortform and clear it */ /* if repair and no error, it's taken care of */ } else { do_warn(_("illegal attribute format %d, ino %llu\n"), - dinoc->di_aformat, ino); + aformat, ino); err = 1; } return (err); /* and repair */ @@ -999,16 +985,22 @@ process_attributes( * Validate an ACL */ static int -xfs_acl_valid(xfs_acl_t *aclp) +xfs_acl_valid(xfs_acl_disk_t *daclp) { + xfs_acl_t *aclp; xfs_acl_entry_t *entry, *e; int user = 0, group = 0, other = 0, mask = 0, mask_required = 0; int i, j; - if (aclp == NULL) + if (daclp == NULL) goto acl_invalid; - xfs_acl_get_endian(aclp); + aclp = xfs_acl_from_disk(daclp); + if (aclp == NULL) { + do_warn(_("cannot malloc enough for ACL attribute\n")); + do_warn(_("SKIPPING this ACL\n")); + return 0; + } if (aclp->acl_cnt > XFS_ACL_MAX_ENTRIES) goto acl_invalid; @@ -1050,9 +1042,10 @@ xfs_acl_valid(xfs_acl_t *aclp) } if (!user || !group || !other || (mask_required && !mask)) goto acl_invalid; - else - return 0; + free(aclp); + return 0; acl_invalid: + free(aclp); errno = EINVAL; return (-1); } diff --git a/repair/attr_repair.h b/repair/attr_repair.h index 0dcfe5c3e..f42536a5e 100644 --- a/repair/attr_repair.h +++ b/repair/attr_repair.h @@ -49,6 +49,18 @@ typedef struct xfs_acl { xfs_acl_entry_t acl_entry[XFS_ACL_MAX_ENTRIES]; } xfs_acl_t; +typedef struct xfs_acl_entry_disk { + __be32 ae_tag; + __be32 ae_id; + __be16 ae_perm; +} xfs_acl_entry_disk_t; + +typedef struct xfs_acl_disk { + __be32 acl_cnt; + xfs_acl_entry_disk_t acl_entry[XFS_ACL_MAX_ENTRIES]; +} xfs_acl_disk_t; + + #define SGI_ACL_FILE "SGI_ACL_FILE" #define SGI_ACL_DEFAULT "SGI_ACL_DEFAULT" #define SGI_ACL_FILE_SIZE (sizeof(SGI_ACL_FILE)-1) diff --git a/repair/dinode.c b/repair/dinode.c index 9dc9d7653..10cca11f5 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -56,13 +56,15 @@ calc_attr_offset(xfs_mount_t *mp, xfs_dinode_t *dino) offset += sizeof(xfs_dev_t); break; case XFS_DINODE_FMT_LOCAL: - offset += INT_GET(dinoc->di_size, ARCH_CONVERT); + offset += be64_to_cpu(dinoc->di_size); break; case XFS_DINODE_FMT_EXTENTS: - offset += INT_GET(dinoc->di_nextents, ARCH_CONVERT) * sizeof(xfs_bmbt_rec_32_t); + offset += be32_to_cpu(dinoc->di_nextents) * + sizeof(xfs_bmbt_rec_t); break; case XFS_DINODE_FMT_BTREE: - offset += INT_GET(dino->di_u.di_bmbt.bb_numrecs, ARCH_CONVERT) * sizeof(xfs_bmbt_rec_32_t); + offset += be16_to_cpu(dino->di_u.di_bmbt.bb_numrecs) * + sizeof(xfs_bmbt_rec_t); break; default: do_error(_("Unknown inode format.\n")); @@ -88,10 +90,10 @@ clear_dinode_attr(xfs_mount_t *mp, xfs_dinode_t *dino, xfs_ino_t ino_num) fprintf(stderr, _("would have cleared inode %llu attributes\n"), (unsigned long long)ino_num); - if (INT_GET(dinoc->di_anextents, ARCH_CONVERT) != 0) { + if (be16_to_cpu(dinoc->di_anextents) != 0) { if (no_modify) return(1); - dinoc->di_anextents = 0; + dinoc->di_anextents = cpu_to_be16(0); } if (dinoc->di_aformat != XFS_DINODE_FMT_EXTENTS) { @@ -114,9 +116,8 @@ clear_dinode_attr(xfs_mount_t *mp, xfs_dinode_t *dino, xfs_ino_t ino_num) if (!no_modify) { xfs_attr_shortform_t *asf = (xfs_attr_shortform_t *) XFS_DFORK_APTR(dino); - INT_SET(asf->hdr.totsize, ARCH_CONVERT, - sizeof(xfs_attr_sf_hdr_t)); - INT_SET(asf->hdr.count, ARCH_CONVERT, 0); + asf->hdr.totsize = cpu_to_be16(sizeof(xfs_attr_sf_hdr_t)); + asf->hdr.count = 0; dinoc->di_forkoff = 0; /* got to do this after asf is set */ } @@ -132,13 +133,13 @@ clear_dinode_core(xfs_dinode_core_t *dinoc, xfs_ino_t ino_num) { int dirty = 0; - if (INT_GET(dinoc->di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC) { + if (be16_to_cpu(dinoc->di_magic) != XFS_DINODE_MAGIC) { dirty = 1; if (no_modify) return(1); - INT_SET(dinoc->di_magic, ARCH_CONVERT, XFS_DINODE_MAGIC); + dinoc->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); } if (!XFS_DINODE_GOOD_VERSION(dinoc->di_version) || @@ -152,7 +153,7 @@ clear_dinode_core(xfs_dinode_core_t *dinoc, xfs_ino_t ino_num) : XFS_DINODE_VERSION_1; } - if (INT_GET(dinoc->di_mode, ARCH_CONVERT) != 0) { + if (be16_to_cpu(dinoc->di_mode) != 0) { dirty = 1; if (no_modify) @@ -161,7 +162,7 @@ clear_dinode_core(xfs_dinode_core_t *dinoc, xfs_ino_t ino_num) dinoc->di_mode = 0; } - if (INT_GET(dinoc->di_flags, ARCH_CONVERT) != 0) { + if (be16_to_cpu(dinoc->di_flags) != 0) { dirty = 1; if (no_modify) @@ -170,7 +171,7 @@ clear_dinode_core(xfs_dinode_core_t *dinoc, xfs_ino_t ino_num) dinoc->di_flags = 0; } - if (INT_GET(dinoc->di_dmevmask, ARCH_CONVERT) != 0) { + if (be32_to_cpu(dinoc->di_dmevmask) != 0) { dirty = 1; if (no_modify) @@ -206,7 +207,7 @@ clear_dinode_core(xfs_dinode_core_t *dinoc, xfs_ino_t ino_num) dinoc->di_aformat = XFS_DINODE_FMT_EXTENTS; } - if (INT_GET(dinoc->di_size, ARCH_CONVERT) != 0) { + if (be64_to_cpu(dinoc->di_size) != 0) { dirty = 1; if (no_modify) @@ -215,7 +216,7 @@ clear_dinode_core(xfs_dinode_core_t *dinoc, xfs_ino_t ino_num) dinoc->di_size = 0; } - if (INT_GET(dinoc->di_nblocks, ARCH_CONVERT) != 0) { + if (be64_to_cpu(dinoc->di_nblocks) != 0) { dirty = 1; if (no_modify) @@ -224,7 +225,7 @@ clear_dinode_core(xfs_dinode_core_t *dinoc, xfs_ino_t ino_num) dinoc->di_nblocks = 0; } - if (INT_GET(dinoc->di_onlink, ARCH_CONVERT) != 0) { + if (be16_to_cpu(dinoc->di_onlink) != 0) { dirty = 1; if (no_modify) @@ -233,7 +234,7 @@ clear_dinode_core(xfs_dinode_core_t *dinoc, xfs_ino_t ino_num) dinoc->di_onlink = 0; } - if (INT_GET(dinoc->di_nextents, ARCH_CONVERT) != 0) { + if (be32_to_cpu(dinoc->di_nextents) != 0) { dirty = 1; if (no_modify) @@ -242,7 +243,7 @@ clear_dinode_core(xfs_dinode_core_t *dinoc, xfs_ino_t ino_num) dinoc->di_nextents = 0; } - if (INT_GET(dinoc->di_anextents, ARCH_CONVERT) != 0) { + if (be16_to_cpu(dinoc->di_anextents) != 0) { dirty = 1; if (no_modify) @@ -252,7 +253,7 @@ clear_dinode_core(xfs_dinode_core_t *dinoc, xfs_ino_t ino_num) } if (dinoc->di_version > XFS_DINODE_VERSION_1 && - INT_GET(dinoc->di_nlink, ARCH_CONVERT) != 0) { + be32_to_cpu(dinoc->di_nlink) != 0) { dirty = 1; if (no_modify) @@ -269,9 +270,9 @@ int clear_dinode_unlinked(xfs_mount_t *mp, xfs_dinode_t *dino) { - if (dino->di_next_unlinked != NULLAGINO) { + if (be32_to_cpu(dino->di_next_unlinked) != NULLAGINO) { if (!no_modify) - dino->di_next_unlinked = NULLAGINO; + dino->di_next_unlinked = cpu_to_be32(NULLAGINO); return(1); } @@ -307,28 +308,19 @@ clear_dinode(xfs_mount_t *mp, xfs_dinode_t *dino, xfs_ino_t ino_num) /* * verify_ag_bno is heavily used. In the common case, it * performs just two number of compares + * Returns 1 for bad ag/bno pair or 0 if it's valid. */ static __inline int verify_ag_bno(xfs_sb_t *sbp, xfs_agnumber_t agno, xfs_agblock_t agbno) { - if (agno < (sbp->sb_agcount - 1)) { - if (agbno >= sbp->sb_agblocks) { - return 1; /* bad */ - } - return 0; /* good */ - } - if (agno == (sbp->sb_agcount - 1)) { - if (agbno >= - (sbp->sb_dblocks - - (sbp->sb_agcount-1) * - sbp->sb_agblocks)) { - return 1; /* bad */ - } - return 0; /* good */ - } - return 1; /* bad */ + if (agno < (sbp->sb_agcount - 1)) + return (agbno >= sbp->sb_agblocks); + if (agno == (sbp->sb_agcount - 1)) + return (agbno >= (sbp->sb_dblocks - + ((sbp->sb_agcount - 1) * sbp->sb_agblocks))); + return 1; } /* @@ -470,13 +462,12 @@ get_bmbt_reclist( int i; xfs_bmbt_irec_t irec; - for (i = 0; i < numrecs; i++, rp++) { - libxfs_bmbt_disk_get_all(rp, &irec); + for (i = 0; i < numrecs; i++) { + libxfs_bmbt_disk_get_all(rp + i, &irec); if (irec.br_startoff >= fblock && irec.br_startoff + irec.br_blockcount < fblock) return (irec.br_startblock + fblock - irec.br_startoff); } - return(NULLDFSBNO); } @@ -521,7 +512,7 @@ process_rt_rec( * verify that the blocks listed in the record * are multiples of an extent */ - if (XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb) == 0 && + if (xfs_sb_version_hasextflgbit(&mp->m_sb) == 0 && (irec->br_startblock % mp->m_sb.sb_rextsize != 0 || irec->br_blockcount % mp->m_sb.sb_rextsize != 0)) { do_warn(_("malformed rt inode extent [%llu %llu] (fs rtext " @@ -536,7 +527,7 @@ process_rt_rec( for (b = irec->br_startblock; b < irec->br_startblock + irec->br_blockcount; b += mp->m_sb.sb_rextsize) { ext = (xfs_drtbno_t) b / mp->m_sb.sb_rextsize; - pwe = XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb) && + pwe = xfs_sb_version_hasextflgbit(&mp->m_sb) && irec->br_state == XFS_EXT_UNWRITTEN && (b % mp->m_sb.sb_rextsize != 0); @@ -645,8 +636,8 @@ process_bmbt_reclist_int( else ftype = _("regular"); - for (i = 0; i < numrecs; i++, rp++) { - libxfs_bmbt_disk_get_all(rp, &irec); + for (i = 0; i < numrecs; i++) { + libxfs_bmbt_disk_get_all(rp + i, &irec); if (i == 0) *last_key = *first_key = irec.br_startoff; else @@ -831,7 +822,7 @@ done: int process_bmbt_reclist( xfs_mount_t *mp, - xfs_bmbt_rec_32_t *rp, + xfs_bmbt_rec_t *rp, int numrecs, int type, xfs_ino_t ino, @@ -841,9 +832,8 @@ process_bmbt_reclist( xfs_dfiloff_t *last_key, int whichfork) { - return(process_bmbt_reclist_int(mp, (xfs_bmbt_rec_t *)rp, numrecs, type, - ino, tot, blkmapp, first_key, last_key, - 0, whichfork)); + return process_bmbt_reclist_int(mp, rp, numrecs, type, ino, tot, + blkmapp, first_key, last_key, 0, whichfork); } /* @@ -853,7 +843,7 @@ process_bmbt_reclist( int scan_bmbt_reclist( xfs_mount_t *mp, - xfs_bmbt_rec_32_t *rp, + xfs_bmbt_rec_t *rp, int numrecs, int type, xfs_ino_t ino, @@ -863,9 +853,8 @@ scan_bmbt_reclist( xfs_dfiloff_t first_key = 0; xfs_dfiloff_t last_key = 0; - return(process_bmbt_reclist_int(mp, (xfs_bmbt_rec_t *)rp, numrecs, type, - ino, tot, NULL, &first_key, &last_key, - 1, whichfork)); + return process_bmbt_reclist_int(mp, rp, numrecs, type, ino, tot, + NULL, &first_key, &last_key, 1, whichfork); } /* @@ -913,8 +902,9 @@ get_agino_buf(xfs_mount_t *mp, * * the next routines are utility routines for the third * routine, get_bmapi(). + * + * NOTE: getfunc_extlist only used by dirv1 checking code */ -/* ARGSUSED */ xfs_dfsbno_t getfunc_extlist(xfs_mount_t *mp, xfs_ino_t ino, @@ -941,6 +931,9 @@ getfunc_extlist(xfs_mount_t *mp, return(final_fsbno); } +/* + * NOTE: getfunc_btree only used by dirv1 checking code... + */ xfs_dfsbno_t getfunc_btree(xfs_mount_t *mp, xfs_ino_t ino, @@ -953,6 +946,7 @@ getfunc_btree(xfs_mount_t *mp, int prev_level; #endif int found; + int numrecs; xfs_bmbt_rec_t *rec; xfs_bmbt_irec_t irec; xfs_bmbt_ptr_t *pp; @@ -964,7 +958,7 @@ getfunc_btree(xfs_mount_t *mp, xfs_dfsbno_t final_fsbno = NULLDFSBNO; xfs_bmbt_block_t *block; xfs_bmdr_block_t *rootblock = (xfs_bmdr_block_t *) - XFS_DFORK_PTR(dip, whichfork); + XFS_DFORK_PTR(dip, whichfork); ASSERT(rootblock->bb_level != 0); /* @@ -973,31 +967,24 @@ getfunc_btree(xfs_mount_t *mp, * a btree should have at least 2 levels otherwise it * would be an extent list. */ - rkey = XFS_BTREE_KEY_ADDR( - XFS_DFORK_SIZE(dip, mp, whichfork), - xfs_bmdr, rootblock, 1, - XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_SIZE(dip, - mp, whichfork), - xfs_bmdr, 1)); - rp = XFS_BTREE_PTR_ADDR( - XFS_DFORK_SIZE(dip, mp, whichfork), - xfs_bmdr, rootblock, 1, - XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_SIZE(dip, - mp, whichfork), - xfs_bmdr, 1)); - for (found = -1, i = 0; i < rootblock->bb_numrecs - 1; i++) { - if (rkey[i].br_startoff <= bno - && bno < rkey[i+1].br_startoff) { + rkey = XFS_BTREE_KEY_ADDR(xfs_bmdr, rootblock, 1); + rp = XFS_BTREE_PTR_ADDR(xfs_bmdr, rootblock, 1, XFS_BTREE_BLOCK_MAXRECS( + XFS_DFORK_SIZE(dip, mp, whichfork), xfs_bmdr, 1)); + found = -1; + for (i = 0; i < be16_to_cpu(rootblock->bb_numrecs) - 1; i++) { + if (be64_to_cpu(rkey[i].br_startoff) <= bno && + bno < be64_to_cpu(rkey[i + 1].br_startoff)) { found = i; break; } } - if (i == rootblock->bb_numrecs - 1 && bno >= rkey[i].br_startoff) + if (i == be16_to_cpu(rootblock->bb_numrecs) - 1 && + bno >= be64_to_cpu(rkey[i].br_startoff)) found = i; ASSERT(found != -1); - fsbno = INT_GET(rp[found], ARCH_CONVERT); + fsbno = be64_to_cpu(rp[found]); ASSERT(verify_dfsbno(mp, fsbno)); @@ -1008,56 +995,48 @@ getfunc_btree(xfs_mount_t *mp, return(NULLDFSBNO); } block = XFS_BUF_TO_BMBT_BLOCK(bp); + numrecs = be16_to_cpu(block->bb_numrecs); /* * ok, now traverse any interior btree nodes */ #ifdef DEBUG - prev_level = INT_GET(block->bb_level, ARCH_CONVERT); + prev_level = be16_to_cpu(block->bb_level); #endif - while (INT_GET(block->bb_level, ARCH_CONVERT) > 0) { + while (be16_to_cpu(block->bb_level) > 0) { #ifdef DEBUG - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) < prev_level); + ASSERT(be16_to_cpu(block->bb_level) < prev_level); - prev_level = INT_GET(block->bb_level, ARCH_CONVERT); + prev_level = be16_to_cpu(block->bb_level); #endif - - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > - mp->m_bmap_dmxr[1]) { + if (numrecs > mp->m_bmap_dmxr[1]) { do_warn(_("# of bmap records in inode %llu exceeds max " "(%u, max - %u)\n"), - ino, INT_GET(block->bb_numrecs, ARCH_CONVERT), + ino, numrecs, mp->m_bmap_dmxr[1]); libxfs_putbuf(bp); return(NULLDFSBNO); } - if (verbose && INT_GET(block->bb_numrecs, ARCH_CONVERT) < - mp->m_bmap_dmnr[1]) { + if (verbose && numrecs < mp->m_bmap_dmnr[1]) { do_warn(_("- # of bmap records in inode %llu less than " "minimum (%u, min - %u), proceeding ...\n"), - ino, INT_GET(block->bb_numrecs, ARCH_CONVERT), - mp->m_bmap_dmnr[1]); + ino, numrecs, mp->m_bmap_dmnr[1]); } - key = XFS_BTREE_KEY_ADDR(mp->m_sb.sb_blocksize, - xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]); - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, - xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]); - for ( found = -1, i = 0; - i < INT_GET(block->bb_numrecs, ARCH_CONVERT) - 1; - i++) { - if (INT_GET(key[i].br_startoff, ARCH_CONVERT) <= bno && - bno < INT_GET(key[i+1].br_startoff, ARCH_CONVERT)) { + key = XFS_BTREE_KEY_ADDR(xfs_bmbt, block, 1); + pp = XFS_BTREE_PTR_ADDR(xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]); + for (found = -1, i = 0; i < numrecs - 1; i++) { + if (be64_to_cpu(key[i].br_startoff) <= bno && bno < + be64_to_cpu(key[i + 1].br_startoff)) { found = i; break; } } - if (i == INT_GET(block->bb_numrecs, ARCH_CONVERT) - 1 && - bno >= INT_GET(key[i].br_startoff, ARCH_CONVERT)) + if (i == numrecs - 1 && bno >= be64_to_cpu(key[i].br_startoff)) found = i; ASSERT(found != -1); - fsbno = INT_GET(pp[found], ARCH_CONVERT); + fsbno = be64_to_cpu(pp[found]); ASSERT(verify_dfsbno(mp, fsbno)); @@ -1073,34 +1052,32 @@ getfunc_btree(xfs_mount_t *mp, return(NULLDFSBNO); } block = XFS_BUF_TO_BMBT_BLOCK(bp); + numrecs = be16_to_cpu(block->bb_numrecs); } /* * current block must be a leaf block */ - ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) == 0); - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_bmap_dmxr[0]) { + ASSERT(be16_to_cpu(block->bb_level) == 0); + if (numrecs > mp->m_bmap_dmxr[0]) { do_warn(_("# of bmap records in inode %llu greater than " "maximum (%u, max - %u)\n"), - ino, INT_GET(block->bb_numrecs, ARCH_CONVERT), - mp->m_bmap_dmxr[0]); + ino, numrecs, mp->m_bmap_dmxr[0]); libxfs_putbuf(bp); return(NULLDFSBNO); } - if (verbose && INT_GET(block->bb_numrecs, ARCH_CONVERT) < - mp->m_bmap_dmnr[0]) + if (verbose && numrecs < mp->m_bmap_dmnr[0]) do_warn(_("- # of bmap records in inode %llu less than minimum " "(%u, min - %u), continuing...\n"), - ino, INT_GET(block->bb_numrecs, ARCH_CONVERT), - mp->m_bmap_dmnr[0]); + ino, numrecs, mp->m_bmap_dmnr[0]); - rec = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, 1, - mp->m_bmap_dmxr[0]); - for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) { + rec = XFS_BTREE_REC_ADDR(xfs_bmbt, block, 1); + for (i = 0; i < numrecs; i++) { libxfs_bmbt_disk_get_all(rec + i, &irec); if (irec.br_startoff <= bno && bno < irec.br_startoff + irec.br_blockcount) { - final_fsbno = bno - irec.br_startoff + irec.br_startblock; + final_fsbno = bno - irec.br_startoff + + irec.br_startblock; break; } } @@ -1124,6 +1101,8 @@ getfunc_btree(xfs_mount_t *mp, * * caller is responsible for checking doubly referenced blocks * and references to holes + * + * NOTE: get_bmapi only used by dirv1 checking code */ xfs_dfsbno_t get_bmapi(xfs_mount_t *mp, xfs_dinode_t *dino_p, @@ -1199,8 +1178,8 @@ process_btinode( else forkname = _("attr"); - level = INT_GET(dib->bb_level, ARCH_CONVERT); - numrecs = INT_GET(dib->bb_numrecs, ARCH_CONVERT); + level = be16_to_cpu(dib->bb_level); + numrecs = be16_to_cpu(dib->bb_numrecs); if ((level == 0) || (level > XFS_BM_MAXLEVELS(mp, whichfork))) { /* @@ -1223,9 +1202,7 @@ process_btinode( /* * use bmdr/dfork_dsize since the root block is in the data fork */ - if (XFS_BMDR_SPACE_CALC(numrecs) > ((whichfork == XFS_DATA_FORK) ? - XFS_DFORK_DSIZE(dip, mp) : - XFS_DFORK_ASIZE(dip, mp))) { + if (XFS_BMDR_SPACE_CALC(numrecs) > XFS_DFORK_SIZE(dip, mp, whichfork)) { do_warn( _("indicated size of %s btree root (%d bytes) greater than space in " "inode %llu %s fork\n"), @@ -1235,19 +1212,9 @@ process_btinode( init_bm_cursor(&cursor, level + 1); - pp = XFS_BTREE_PTR_ADDR( - XFS_DFORK_SIZE(dip, mp, whichfork), - xfs_bmdr, dib, 1, - XFS_BTREE_BLOCK_MAXRECS( - XFS_DFORK_SIZE(dip, mp, whichfork), - xfs_bmdr, 0)); - pkey = XFS_BTREE_KEY_ADDR( - XFS_DFORK_SIZE(dip, mp, whichfork), - xfs_bmdr, dib, 1, - XFS_BTREE_BLOCK_MAXRECS( - XFS_DFORK_SIZE(dip, mp, whichfork), - xfs_bmdr, 0)); - + pp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dib, 1, XFS_BTREE_BLOCK_MAXRECS( + XFS_DFORK_SIZE(dip, mp, whichfork), xfs_bmdr, 0)); + pkey = XFS_BTREE_KEY_ADDR(xfs_bmdr, dib, 1); last_key = NULLDFILOFF; for (i = 0; i < numrecs; i++) { @@ -1256,16 +1223,15 @@ process_btinode( * btree, we'd do it right here. For now, if there's a * problem, we'll bail out and presumably clear the inode. */ - if (!verify_dfsbno(mp, INT_GET(pp[i], ARCH_CONVERT))) { + if (!verify_dfsbno(mp, be64_to_cpu(pp[i]))) { do_warn(_("bad bmap btree ptr 0x%llx in ino %llu\n"), - INT_GET(pp[i], ARCH_CONVERT), lino); + be64_to_cpu(pp[i]), lino); return(1); } - if (scan_lbtree((xfs_dfsbno_t)INT_GET(pp[i], ARCH_CONVERT), - level, scanfunc_bmap, type, whichfork, - lino, tot, nex, blkmapp, &cursor, - 1, check_dups)) + if (scan_lbtree(be64_to_cpu(pp[i]), level, scanfunc_bmap, type, + whichfork, lino, tot, nex, blkmapp, &cursor, + 1, check_dups)) return(1); /* * fix key (offset) mismatches between the keys in root @@ -1273,27 +1239,24 @@ process_btinode( * fixes cases where entries have been shifted between * blocks but the parent hasn't been updated */ - if (check_dups == 0 && - cursor.level[level-1].first_key != - INT_GET(pkey[i].br_startoff, ARCH_CONVERT)) { + if (!check_dups && cursor.level[level-1].first_key != + be64_to_cpu(pkey[i].br_startoff)) { if (!no_modify) { do_warn( _("correcting key in bmbt root (was %llu, now %llu) in inode " "%llu %s fork\n"), - INT_GET(pkey[i].br_startoff, - ARCH_CONVERT), + be64_to_cpu(pkey[i].br_startoff), cursor.level[level-1].first_key, XFS_AGINO_TO_INO(mp, agno, ino), forkname); *dirty = 1; - INT_SET(pkey[i].br_startoff, ARCH_CONVERT, + pkey[i].br_startoff = cpu_to_be64( cursor.level[level-1].first_key); } else { do_warn( _("bad key in bmbt root (is %llu, would reset to %llu) in inode " "%llu %s fork\n"), - INT_GET(pkey[i].br_startoff, - ARCH_CONVERT), + be64_to_cpu(pkey[i].br_startoff), cursor.level[level-1].first_key, XFS_AGINO_TO_INO(mp, agno, ino), forkname); @@ -1354,12 +1317,12 @@ process_exinode( int check_dups) { xfs_ino_t lino; - xfs_bmbt_rec_32_t *rp; + xfs_bmbt_rec_t *rp; xfs_dfiloff_t first_key; xfs_dfiloff_t last_key; lino = XFS_AGINO_TO_INO(mp, agno, ino); - rp = (xfs_bmbt_rec_32_t *)XFS_DFORK_PTR(dip, whichfork); + rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork); *tot = 0; *nex = XFS_DFORK_NEXTENTS(dip, whichfork); /* @@ -1379,54 +1342,38 @@ process_exinode( /* * return 1 if inode should be cleared, 0 otherwise */ -/* ARGSUSED */ -int +static int process_lclinode( xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agino_t ino, xfs_dinode_t *dip, - int type, - int *dirty, - xfs_drfsbno_t *tot, - __uint64_t *nex, - blkmap_t **blkmapp, - int whichfork, - int check_dups) + int whichfork) { xfs_attr_shortform_t *asf; - xfs_dinode_core_t *dic; xfs_ino_t lino; - *tot = 0; - *nex = 0; /* local inodes have 0 extents */ - - dic = &dip->di_core; lino = XFS_AGINO_TO_INO(mp, agno, ino); - if (whichfork == XFS_DATA_FORK && - INT_GET(dic->di_size, ARCH_CONVERT) > - XFS_DFORK_DSIZE(dip, mp)) { + if (whichfork == XFS_DATA_FORK && be64_to_cpu(dip->di_core.di_size) > + XFS_DFORK_DSIZE(dip, mp)) { do_warn( _("local inode %llu data fork is too large (size = %lld, max = %d)\n"), - lino, INT_GET(dic->di_size, ARCH_CONVERT), + lino, be64_to_cpu(dip->di_core.di_size), XFS_DFORK_DSIZE(dip, mp)); return(1); } else if (whichfork == XFS_ATTR_FORK) { - asf = (xfs_attr_shortform_t *) - XFS_DFORK_APTR(dip); - if (INT_GET(asf->hdr.totsize, ARCH_CONVERT) > - XFS_DFORK_ASIZE(dip, mp)) { + asf = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); + if (be16_to_cpu(asf->hdr.totsize) > XFS_DFORK_ASIZE(dip, mp)) { do_warn( _("local inode %llu attr fork too large (size %d, max = %d)\n"), - lino, INT_GET(asf->hdr.totsize, ARCH_CONVERT), + lino, be16_to_cpu(asf->hdr.totsize), XFS_DFORK_ASIZE(dip, mp)); return(1); } - if (INT_GET(asf->hdr.totsize, ARCH_CONVERT) < - sizeof(xfs_attr_sf_hdr_t)) { + if (be16_to_cpu(asf->hdr.totsize) < sizeof(xfs_attr_sf_hdr_t)) { do_warn( _("local inode %llu attr too small (size = %d, min size = %d)\n"), - lino, INT_GET(asf->hdr.totsize, ARCH_CONVERT), + lino, be16_to_cpu(asf->hdr.totsize), sizeof(xfs_attr_sf_hdr_t)); return(1); } @@ -1444,31 +1391,24 @@ process_symlink_extlist(xfs_mount_t *mp, xfs_ino_t lino, xfs_dinode_t *dino) int numrecs; int i; int max_blocks; - int whichfork = XFS_DATA_FORK; - if (INT_GET(dino->di_core.di_size, ARCH_CONVERT) <= - XFS_DFORK_SIZE(dino, mp, whichfork)) { - if (dino->di_core.di_format == XFS_DINODE_FMT_LOCAL) { - return(0); - } else { - do_warn( - _("mismatch between format (%d) and size (%lld) in symlink ino %llu\n"), - dino->di_core.di_format, - INT_GET(dino->di_core.di_size, ARCH_CONVERT), - lino); - return(1); - } - } else if (dino->di_core.di_format == XFS_DINODE_FMT_LOCAL) { - do_warn( - _("mismatch between format (%d) and size (%lld) in symlink inode %llu\n"), - dino->di_core.di_format, - INT_GET(dino->di_core.di_size, ARCH_CONVERT), - lino); - return(1); + if (be64_to_cpu(dino->di_core.di_size) <= XFS_DFORK_DSIZE(dino, mp)) { + if (dino->di_core.di_format == XFS_DINODE_FMT_LOCAL) + return 0; + do_warn(_("mismatch between format (%d) and size (%lld) in " + "symlink ino %llu\n"), dino->di_core.di_format, + be64_to_cpu(dino->di_core.di_size), lino); + return 1; + } + if (dino->di_core.di_format == XFS_DINODE_FMT_LOCAL) { + do_warn(_("mismatch between format (%d) and size (%lld) in " + "symlink inode %llu\n"), dino->di_core.di_format, + be64_to_cpu(dino->di_core.di_size), lino); + return 1; } - rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dino, whichfork); - numrecs = XFS_DFORK_NEXTENTS(dino, whichfork); + rp = (xfs_bmbt_rec_t *)XFS_DFORK_DPTR(dino); + numrecs = be32_to_cpu(dino->di_core.di_nextents); /* * the max # of extents in a symlink inode is equal to the @@ -1484,8 +1424,8 @@ process_symlink_extlist(xfs_mount_t *mp, xfs_ino_t lino, xfs_dinode_t *dino) max_blocks = max_symlink_blocks; expected_offset = 0; - for (i = 0; numrecs > 0; i++, numrecs--) { - libxfs_bmbt_disk_get_all(rp, &irec); + for (i = 0; i < numrecs; i++) { + libxfs_bmbt_disk_get_all(rp + i, &irec); if (irec.br_startoff != expected_offset) { do_warn( @@ -1550,9 +1490,9 @@ process_symlink( * the inode is structurally ok so we don't have to check * for that */ - if (INT_GET(dinoc->di_size, ARCH_CONVERT) >= MAXPATHLEN) { + if (be64_to_cpu(dinoc->di_size) >= MAXPATHLEN) { do_warn(_("symlink in inode %llu too long (%lld chars)\n"), - lino, INT_GET(dinoc->di_size, ARCH_CONVERT)); + lino, be64_to_cpu(dinoc->di_size)); return(1); } @@ -1561,14 +1501,13 @@ process_symlink( * get symlink contents into data area */ symlink = &data[0]; - if (INT_GET(dinoc->di_size, ARCH_CONVERT) - <= XFS_DFORK_DSIZE(dino, mp)) { + if (be64_to_cpu(dinoc->di_size) <= XFS_DFORK_DSIZE(dino, mp)) { /* * local symlink, just copy the symlink out of the * inode into the data area */ - memmove(symlink, (char *)XFS_DFORK_DPTR(dino), - INT_GET(dinoc->di_size, ARCH_CONVERT)); + memmove(symlink, XFS_DFORK_DPTR(dino), + be64_to_cpu(dinoc->di_size)); } else { /* * stored in a meta-data file, have to bmap one block @@ -1577,7 +1516,7 @@ process_symlink( i = size = amountdone = 0; cptr = symlink; - while (amountdone < INT_GET(dinoc->di_size, ARCH_CONVERT)) { + while (amountdone < be64_to_cpu(dinoc->di_size)) { fsbno = blkmap_get(blkmap, i); if (fsbno != NULLDFSBNO) bp = libxfs_readbuf(mp->m_dev, @@ -1591,8 +1530,8 @@ process_symlink( } buf_data = (char *)XFS_BUF_PTR(bp); - size = MIN(INT_GET(dinoc->di_size, ARCH_CONVERT) - - amountdone, (int)XFS_FSB_TO_BB(mp, 1)*BBSIZE); + size = MIN(be64_to_cpu(dinoc->di_size) - amountdone, + XFS_FSB_TO_BB(mp, 1) * BBSIZE); memmove(cptr, buf_data, size); cptr += size; amountdone += size; @@ -1600,12 +1539,12 @@ process_symlink( libxfs_putbuf(bp); } } - data[INT_GET(dinoc->di_size, ARCH_CONVERT)] = '\0'; + data[be64_to_cpu(dinoc->di_size)] = '\0'; /* * check for nulls */ - if (null_check(symlink, (int) INT_GET(dinoc->di_size, ARCH_CONVERT))) { + if (null_check(symlink, be64_to_cpu(dinoc->di_size))) { do_warn( _("found illegal null character in symlink inode %llu\n"), lino); @@ -1615,7 +1554,7 @@ process_symlink( /* * check for any component being too long */ - if (INT_GET(dinoc->di_size, ARCH_CONVERT) >= MAXNAMELEN) { + if (be64_to_cpu(dinoc->di_size) >= MAXNAMELEN) { cptr = strchr(symlink, '/'); while (cptr != NULL) { @@ -1697,7 +1636,7 @@ process_misc_ino_types(xfs_mount_t *mp, return(0); } -static __inline int +static int process_misc_ino_types_blocks(xfs_drfsbno_t totblocks, xfs_ino_t lino, int type) { /* @@ -1764,7 +1703,7 @@ static int check_dinode_mode_format( xfs_dinode_core_t *dinoc) { - if ((uchar_t)dinoc->di_format >= XFS_DINODE_FMT_UUID) + if (dinoc->di_format >= XFS_DINODE_FMT_UUID) return -1; /* FMT_UUID is not used */ switch (dinode_fmt(dinoc)) { @@ -2094,8 +2033,7 @@ process_inode_data_fork( int err = 0; *nextents = be32_to_cpu(dinoc->di_nextents); - if (*nextents > be64_to_cpu(dinoc->di_nblocks) || - *nextents > XFS_MAX_INCORE_EXTENTS) + if (*nextents > be64_to_cpu(dinoc->di_nblocks)) *nextents = 1; if (dinoc->di_format != XFS_DINODE_FMT_LOCAL && type != XR_INO_RTDATA) @@ -2104,9 +2042,8 @@ process_inode_data_fork( switch (dinoc->di_format) { case XFS_DINODE_FMT_LOCAL: - err = process_lclinode(mp, agno, ino, dino, type, dirty, - totblocks, nextents, dblkmap, XFS_DATA_FORK, - check_dups); + err = process_lclinode(mp, agno, ino, dino, XFS_DATA_FORK); + *totblocks = 0; break; case XFS_DINODE_FMT_EXTENTS: err = process_exinode(mp, agno, ino, dino, type, dirty, @@ -2143,9 +2080,8 @@ process_inode_data_fork( */ switch (dinoc->di_format) { case XFS_DINODE_FMT_LOCAL: - err = process_lclinode(mp, agno, ino, dino, type, - dirty, totblocks, nextents, dblkmap, - XFS_DATA_FORK, 0); + err = process_lclinode(mp, agno, ino, dino, + XFS_DATA_FORK); break; case XFS_DINODE_FMT_EXTENTS: err = process_exinode(mp, agno, ino, dino, type, @@ -2213,16 +2149,14 @@ process_inode_attr_fork( } *anextents = be16_to_cpu(dinoc->di_anextents); - if (*anextents > be64_to_cpu(dinoc->di_nblocks) || - *anextents > XFS_MAX_INCORE_EXTENTS) + if (*anextents > be64_to_cpu(dinoc->di_nblocks)) *anextents = 1; switch (dinoc->di_aformat) { case XFS_DINODE_FMT_LOCAL: *anextents = 0; - err = process_lclinode(mp, agno, ino, dino, type, dirty, - atotblocks, anextents, &ablkmap, - XFS_ATTR_FORK, check_dups); + *atotblocks = 0; + err = process_lclinode(mp, agno, ino, dino, XFS_ATTR_FORK); break; case XFS_DINODE_FMT_EXTENTS: ablkmap = blkmap_alloc(*anextents); @@ -2281,9 +2215,8 @@ process_inode_attr_fork( if (check_dups) { switch (dinoc->di_aformat) { case XFS_DINODE_FMT_LOCAL: - err = process_lclinode(mp, agno, ino, dino, - type, dirty, atotblocks, anextents, - &ablkmap, XFS_ATTR_FORK, 0); + err = process_lclinode(mp, agno, ino, dino, + XFS_ATTR_FORK); break; case XFS_DINODE_FMT_EXTENTS: err = process_exinode(mp, agno, ino, dino, @@ -2526,7 +2459,7 @@ process_dinode_int(xfs_mount_t *mp, retval = 1; if (!uncertain) do_warn(_("bad version number 0x%x on inode %llu%c"), - dinoc->di_version, lino, + (__s8)dinoc->di_version, lino, verify_mode ? '\n' : ','); if (!verify_mode) { if (!no_modify) { diff --git a/repair/dinode.h b/repair/dinode.h index 7dfd11d42..dcc75f291 100644 --- a/repair/dinode.h +++ b/repair/dinode.h @@ -33,7 +33,7 @@ verify_dfsbno(xfs_mount_t *mp, void convert_extent( - xfs_bmbt_rec_32_t *rp, + xfs_bmbt_rec_t *rp, xfs_dfiloff_t *op, /* starting offset (blockno in file) */ xfs_dfsbno_t *sp, /* starting block (fs blockno) */ xfs_dfilblks_t *cp, /* blockcount */ @@ -41,7 +41,7 @@ convert_extent( int process_bmbt_reclist(xfs_mount_t *mp, - xfs_bmbt_rec_32_t *rp, + xfs_bmbt_rec_t *rp, int numrecs, int type, xfs_ino_t ino, @@ -54,7 +54,7 @@ process_bmbt_reclist(xfs_mount_t *mp, int scan_bmbt_reclist( xfs_mount_t *mp, - xfs_bmbt_rec_32_t *rp, + xfs_bmbt_rec_t *rp, int numrecs, int type, xfs_ino_t ino, diff --git a/repair/dir.c b/repair/dir.c index f7e62a51c..80a28522f 100644 --- a/repair/dir.c +++ b/repair/dir.c @@ -104,11 +104,10 @@ process_shortform_dir( fprintf(stderr, "process_shortform_dir - inode %llu\n", ino); #endif - sf = &dip->di_u.di_dirsf; - + sf = (xfs_dir_shortform_t *)XFS_DFORK_DPTR(dip); max_size = XFS_DFORK_DSIZE(dip, mp); - num_entries = INT_GET(sf->hdr.count, ARCH_CONVERT); - ino_dir_size = INT_GET(dip->di_core.di_size, ARCH_CONVERT); + num_entries = sf->hdr.count; + ino_dir_size = be64_to_cpu(dip->di_core.di_size); *repair = 0; ASSERT(ino_dir_size <= max_size); @@ -131,7 +130,7 @@ process_shortform_dir( sf_entry = next_sfe; junkit = 0; bad_sfnamelen = 0; - XFS_DIR_SF_GET_DIRINO(&sf_entry->inumber, &lino); + xfs_dir_sf_get_dirino(&sf_entry->inumber, &lino); /* * if entry points to self, junk it since only '.' or '..' @@ -259,7 +258,7 @@ process_shortform_dir( break; } } else if ((__psint_t) sf_entry - (__psint_t) sf + - + XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry) + + xfs_dir_sf_entsize_byentry(sf_entry) > ino_dir_size) { bad_sfnamelen = 1; @@ -338,9 +337,8 @@ process_shortform_dir( name[namelen] = '\0'; if (!no_modify) { - tmp_elen = XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry); - INT_MOD(dip->di_core.di_size, - ARCH_CONVERT, -(tmp_elen)); + tmp_elen = xfs_dir_sf_entsize_byentry(sf_entry); + be64_add_cpu(&dip->di_core.di_size, -tmp_elen); ino_dir_size -= tmp_elen; tmp_sfe = (xfs_dir_sf_entry_t *) @@ -350,10 +348,10 @@ process_shortform_dir( memmove(sf_entry, tmp_sfe, tmp_len); - INT_MOD(sf->hdr.count, ARCH_CONVERT, -1); + sf->hdr.count -= 1; num_entries--; - memset((void *) ((__psint_t) sf_entry + tmp_len), 0, - tmp_elen); + memset((void *)((__psint_t)sf_entry + tmp_len), + 0, tmp_elen); /* * reset the tmp value to the current @@ -392,7 +390,7 @@ process_shortform_dir( next_sfe = (tmp_sfe == NULL) ? (xfs_dir_sf_entry_t *) ((__psint_t) sf_entry + ((!bad_sfnamelen) - ? XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry) + ? xfs_dir_sf_entsize_byentry(sf_entry) : sizeof(xfs_dir_sf_entry_t) - 1 + namelen)) : tmp_sfe; @@ -400,16 +398,16 @@ process_shortform_dir( /* sync up sizes and entry counts */ - if (INT_GET(sf->hdr.count, ARCH_CONVERT) != i) { + if (sf->hdr.count != i) { if (no_modify) { do_warn( _("would have corrected entry count in directory %llu from %d to %d\n"), - ino, INT_GET(sf->hdr.count, ARCH_CONVERT), i); + ino, sf->hdr.count, i); } else { do_warn( _("corrected entry count in directory %llu, was %d, now %d\n"), - ino, INT_GET(sf->hdr.count, ARCH_CONVERT), i); - INT_SET(sf->hdr.count, ARCH_CONVERT, i); + ino, sf->hdr.count, i); + sf->hdr.count = i; *dino_dirty = 1; *repair = 1; } @@ -427,9 +425,8 @@ process_shortform_dir( ino, (__int64_t) ino_dir_size, (__int64_t)((__psint_t) next_sfe - (__psint_t) sf)); - INT_SET(dip->di_core.di_size, - ARCH_CONVERT, (xfs_fsize_t) - ((__psint_t) next_sfe - (__psint_t) sf)); + dip->di_core.di_size = cpu_to_be64((__psint_t)next_sfe + - (__psint_t)sf); *dino_dirty = 1; *repair = 1; } @@ -437,7 +434,7 @@ process_shortform_dir( /* * check parent (..) entry */ - XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, parent); + xfs_dir_sf_get_dirino(&sf->hdr.parent, parent); /* * if parent entry is bogus, null it out. we'll fix it later . @@ -451,7 +448,7 @@ process_shortform_dir( if (!no_modify) { do_warn(_("clearing inode number\n")); - XFS_DIR_SF_PUT_DIRINO(parent, &sf->hdr.parent); + xfs_dir_sf_put_dirino(parent, &sf->hdr.parent); *dino_dirty = 1; *repair = 1; } else { @@ -466,7 +463,7 @@ process_shortform_dir( _("corrected root directory %llu .. entry, was %llu, now %llu\n"), ino, *parent, ino); *parent = ino; - XFS_DIR_SF_PUT_DIRINO(parent, &sf->hdr.parent); + xfs_dir_sf_put_dirino(parent, &sf->hdr.parent); *dino_dirty = 1; *repair = 1; } else { @@ -485,7 +482,7 @@ process_shortform_dir( if (!no_modify) { do_warn(_("clearing inode number\n")); - XFS_DIR_SF_PUT_DIRINO(parent, &sf->hdr.parent); + xfs_dir_sf_put_dirino(parent, &sf->hdr.parent); *dino_dirty = 1; *repair = 1; } else { @@ -805,19 +802,19 @@ traverse_int_dablock(xfs_mount_t *mp, node = (xfs_da_intnode_t *)XFS_BUF_PTR(bp); - if (INT_GET(node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC) { + if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) { do_warn(_("bad dir/attr magic number in inode %llu, " "file bno = %u, fsbno = %llu\n"), da_cursor->ino, bno, fsbno); libxfs_putbuf(bp); goto error_out; } - if (INT_GET(node->hdr.count, ARCH_CONVERT) > + if (be16_to_cpu(node->hdr.count) > mp->m_dir_node_ents) { do_warn(_("bad record count in inode %llu, " "count = %d, max = %d\n"), da_cursor->ino, - INT_GET(node->hdr.count, ARCH_CONVERT), + be16_to_cpu(node->hdr.count), mp->m_dir_node_ents); libxfs_putbuf(bp); goto error_out; @@ -827,9 +824,9 @@ traverse_int_dablock(xfs_mount_t *mp, * maintain level counter */ if (i == -1) - i = da_cursor->active = INT_GET(node->hdr.level, ARCH_CONVERT); + i = da_cursor->active = be16_to_cpu(node->hdr.level); else { - if (INT_GET(node->hdr.level, ARCH_CONVERT) == i - 1) { + if (be16_to_cpu(node->hdr.level) == i - 1) { i--; } else { if (whichfork == XFS_DATA_FORK) @@ -845,8 +842,8 @@ traverse_int_dablock(xfs_mount_t *mp, } } - da_cursor->level[i].hashval = - INT_GET(node->btree[0].hashval, ARCH_CONVERT); + da_cursor->level[i].hashval = be32_to_cpu( + node->btree[0].hashval); da_cursor->level[i].bp = bp; da_cursor->level[i].bno = bno; da_cursor->level[i].index = 0; @@ -857,8 +854,8 @@ traverse_int_dablock(xfs_mount_t *mp, /* * set up new bno for next level down */ - bno = INT_GET(node->btree[0].before, ARCH_CONVERT); - } while(node != NULL && i > 1); + bno = be32_to_cpu(node->btree[0].before); + } while (node != NULL && i > 1); /* * now return block number and get out @@ -957,7 +954,7 @@ get_first_dblock_fsbno(xfs_mount_t *mp, return(fsbno); } - if (INT_GET(dino->di_core.di_size, ARCH_CONVERT) <= XFS_LBSIZE(mp)) + if (be64_to_cpu(dino->di_core.di_size) <= XFS_LBSIZE(mp)) return(fsbno); do { @@ -980,7 +977,7 @@ get_first_dblock_fsbno(xfs_mount_t *mp, node = (xfs_da_intnode_t *)XFS_BUF_PTR(bp); if (XFS_DA_NODE_MAGIC != - INT_GET(node->hdr.info.magic, ARCH_CONVERT)) { + be16_to_cpu(node->hdr.info.magic)) { do_warn(_("bad dir/attr magic number in inode %llu, " "file bno = %u, fsbno = %llu\n"), ino, bno, fsbno); @@ -989,8 +986,8 @@ get_first_dblock_fsbno(xfs_mount_t *mp, } if (i == -1) - i = INT_GET(node->hdr.level, ARCH_CONVERT); - bno = INT_GET(node->btree[0].before, ARCH_CONVERT); + i = be16_to_cpu(node->hdr.level); + bno = be32_to_cpu(node->btree[0].before); libxfs_putbuf(bp); @@ -1042,27 +1039,27 @@ verify_final_da_path(xfs_mount_t *mp, * that all entries are used, encountered and expected hashvals * match, etc. */ - if (entry != INT_GET(node->hdr.count, ARCH_CONVERT) - 1) { + if (entry != be16_to_cpu(node->hdr.count) - 1) { do_warn(_("directory/attribute block used/count " "inconsistency - %d/%hu\n"), - entry, INT_GET(node->hdr.count, ARCH_CONVERT)); + entry, be16_to_cpu(node->hdr.count)); bad++; } /* * hash values monotonically increasing ??? */ - if (cursor->level[this_level].hashval >= - INT_GET(node->btree[entry].hashval, ARCH_CONVERT)) { + if (cursor->level[this_level].hashval >= + be32_to_cpu(node->btree[entry].hashval)) { do_warn(_("directory/attribute block hashvalue inconsistency, " "expected > %u / saw %u\n"), cursor->level[this_level].hashval, - INT_GET(node->btree[entry].hashval, ARCH_CONVERT)); + be32_to_cpu(node->btree[entry].hashval)); bad++; } - if (INT_GET(node->hdr.info.forw, ARCH_CONVERT) != 0) { + if (be32_to_cpu(node->hdr.info.forw) != 0) { do_warn(_("bad directory/attribute forward block pointer, " "expected 0, saw %u\n"), - INT_GET(node->hdr.info.forw, ARCH_CONVERT)); + be32_to_cpu(node->hdr.info.forw)); bad++; } if (bad) { @@ -1080,12 +1077,12 @@ verify_final_da_path(xfs_mount_t *mp, /* * ok, now check descendant block number against this level */ - if (cursor->level[p_level].bno != - INT_GET(node->btree[entry].before, ARCH_CONVERT)) { + if (cursor->level[p_level].bno != be32_to_cpu( + node->btree[entry].before)) { #ifdef XR_DIR_TRACE fprintf(stderr, "bad directory btree pointer, child bno should " "be %d, block bno is %d, hashval is %u\n", - INT_GET(node->btree[entry].before, ARCH_CONVERT), + be16_to_cpu(node->btree[entry].before), cursor->level[p_level].bno, cursor->level[p_level].hashval); fprintf(stderr, "verify_final_da_path returns 1 (bad) #1a\n"); @@ -1093,15 +1090,15 @@ verify_final_da_path(xfs_mount_t *mp, return(1); } - if (cursor->level[p_level].hashval != - INT_GET(node->btree[entry].hashval, ARCH_CONVERT)) { + if (cursor->level[p_level].hashval != be32_to_cpu( + node->btree[entry].hashval)) { if (!no_modify) { do_warn(_("correcting bad hashval in non-leaf " "dir/attr block\n\tin (level %d) in " "inode %llu.\n"), this_level, cursor->ino); - INT_SET(node->btree[entry].hashval, ARCH_CONVERT, - cursor->level[p_level].hashval); + node->btree[entry].hashval = cpu_to_be32( + cursor->level[p_level].hashval); cursor->level[this_level].dirty++; } else { do_warn(_("would correct bad hashval in non-leaf " @@ -1115,7 +1112,7 @@ verify_final_da_path(xfs_mount_t *mp, * Note: squirrel hashval away _before_ releasing the * buffer, preventing a use-after-free problem. */ - hashval = INT_GET(node->btree[entry].hashval, ARCH_CONVERT); + hashval = be32_to_cpu(node->btree[entry].hashval); /* * release/write buffer @@ -1212,14 +1209,14 @@ verify_da_path(xfs_mount_t *mp, * block and move on to the next block. * and update cursor value for said level */ - if (entry >= INT_GET(node->hdr.count, ARCH_CONVERT)) { + if (entry >= be16_to_cpu(node->hdr.count)) { /* * update the hash value for this level before * validating it. bno value should be ok since * it was set when the block was first read in. */ cursor->level[this_level].hashval = - INT_GET(node->btree[entry - 1].hashval, ARCH_CONVERT); + be32_to_cpu(node->btree[entry - 1].hashval); /* * keep track of greatest block # -- that gets @@ -1237,7 +1234,7 @@ verify_da_path(xfs_mount_t *mp, /* * ok, now get the next buffer and check sibling pointers */ - dabno = INT_GET(node->hdr.info.forw, ARCH_CONVERT); + dabno = be32_to_cpu(node->hdr.info.forw); ASSERT(dabno != 0); fsbno = blkmap_get(cursor->blkmap, dabno); @@ -1263,33 +1260,31 @@ verify_da_path(xfs_mount_t *mp, * entry count, verify level */ bad = 0; - if (XFS_DA_NODE_MAGIC != - INT_GET(newnode->hdr.info.magic, ARCH_CONVERT)) { + if (XFS_DA_NODE_MAGIC != be16_to_cpu(newnode->hdr.info.magic)) { do_warn(_("bad magic number %x in block %u (%llu) " "for directory inode %llu\n"), - INT_GET(newnode->hdr.info.magic, ARCH_CONVERT), + be16_to_cpu(newnode->hdr.info.magic), dabno, fsbno, cursor->ino); bad++; } - if (INT_GET(newnode->hdr.info.back, ARCH_CONVERT) != - cursor->level[this_level].bno) { + if (be32_to_cpu(newnode->hdr.info.back) != + cursor->level[this_level].bno) { do_warn(_("bad back pointer in block %u (%llu) " "for directory inode %llu\n"), dabno, fsbno, cursor->ino); bad++; } - if (INT_GET(newnode->hdr.count, ARCH_CONVERT) > - mp->m_dir_node_ents) { + if (be16_to_cpu(newnode->hdr.count) > mp->m_dir_node_ents) { do_warn(_("entry count %d too large in block %u (%llu) " "for directory inode %llu\n"), - INT_GET(newnode->hdr.count, ARCH_CONVERT), + be16_to_cpu(newnode->hdr.count), dabno, fsbno, cursor->ino); bad++; } - if (INT_GET(newnode->hdr.level, ARCH_CONVERT) != this_level) { + if (be16_to_cpu(newnode->hdr.level) != this_level) { do_warn(_("bad level %d in block %u (%llu) " "for directory inode %llu\n"), - INT_GET(newnode->hdr.level, ARCH_CONVERT), + be16_to_cpu(newnode->hdr.level), dabno, fsbno, cursor->ino); bad++; } @@ -1315,7 +1310,7 @@ verify_da_path(xfs_mount_t *mp, cursor->level[this_level].dirty = 0; cursor->level[this_level].bno = dabno; cursor->level[this_level].hashval = - INT_GET(newnode->btree[0].hashval, ARCH_CONVERT); + be32_to_cpu(newnode->btree[0].hashval); #ifdef XR_DIR_TRACE cursor->level[this_level].n = newnode; #endif @@ -1327,11 +1322,11 @@ verify_da_path(xfs_mount_t *mp, * ditto for block numbers */ if (cursor->level[p_level].bno != - INT_GET(node->btree[entry].before, ARCH_CONVERT)) { + be32_to_cpu(node->btree[entry].before)) { #ifdef XR_DIR_TRACE fprintf(stderr, "bad directory btree pointer, child bno " "should be %d, block bno is %d, hashval is %u\n", - INT_GET(node->btree[entry].before, ARCH_CONVERT), + be32_to_cpu(node->btree[entry].before), cursor->level[p_level].bno, cursor->level[p_level].hashval); fprintf(stderr, "verify_da_path returns 1 (bad) #1a\n"); @@ -1343,14 +1338,14 @@ verify_da_path(xfs_mount_t *mp, * block against the hashval in the current entry */ if (cursor->level[p_level].hashval != - INT_GET(node->btree[entry].hashval, ARCH_CONVERT)) { + be32_to_cpu(node->btree[entry].hashval)) { if (!no_modify) { do_warn(_("correcting bad hashval in interior " "dir/attr block\n\tin (level %d) in " "inode %llu.\n"), this_level, cursor->ino); - INT_SET(node->btree[entry].hashval, ARCH_CONVERT, - cursor->level[p_level].hashval); + node->btree[entry].hashval = cpu_to_be32( + cursor->level[p_level].hashval); cursor->level[this_level].dirty++; } else { do_warn(_("would correct bad hashval in interior " @@ -1370,286 +1365,6 @@ verify_da_path(xfs_mount_t *mp, return(0); } -#if 0 -/* - * handles junking directory leaf block entries that have zero lengths - * buf_dirty is an in/out, set to 1 if the leaf was modified. - * we do NOT initialize it to zero if nothing happened because it - * may be already set by the caller. Assumes that the block - * has been compacted before calling this routine. - */ -void -junk_zerolen_dir_leaf_entries( - xfs_mount_t *mp, - xfs_dir_leafblock_t *leaf, - xfs_ino_t ino, - int *buf_dirty) -{ - xfs_dir_leaf_entry_t *entry; - xfs_dir_leaf_name_t *namest; - xfs_dir_leaf_hdr_t *hdr; - xfs_dir_leaf_map_t *map; - xfs_ino_t tmp_ino; - int bytes; - int tmp_bytes; - int current_hole = 0; - int i; - int j; - int tmp; - int start; - int before; - int after; - int smallest; - int tablesize; - - entry = &leaf->entries[0]; - hdr = &leaf->hdr; - - /* - * we can convert the entries to one character entries - * as long as we have space. Once we run out, then - * we have to delete really delete (copy over) an entry. - * however, that frees up some space that we could use ... - * - * so the idea is, we'll use up space from all the holes, - * potentially leaving each hole too small to do any good. - * then if need to, we'll delete entries and use that space - * up from the top-most byte down. that may leave a 4th hole - * but we can represent that by correctly setting the value - * of firstused. that leaves any hole between the end of - * the entry list and firstused so it doesn't have to be - * recorded in the hole map. - */ - - for (bytes = i = 0; i < INT_GET(hdr->count, ARCH_CONVERT); entry++, i++) { - /* - * skip over entries that are good or already converted - */ - if (entry->namelen != 0) - continue; - - *buf_dirty = 1; -#if 0 - /* - * try and use up existing holes first until they get - * too small, then set bytes to the # of bytes between - * the current heap beginning and the last used byte - * in the entry table. - */ - if (bytes < sizeof(xfs_dir_leaf_name_t) && - current_hole < XFS_DIR_LEAF_MAPSIZE) { - /* - * skip over holes that are too small - */ - while (current_hole < XFS_DIR_LEAF_MAPSIZE && - INT_GET(hdr->freemap[current_hole].size, ARCH_CONVERT) < - sizeof(xfs_dir_leaf_name_t)) { - current_hole++; - } - - if (current_hole < XFS_DIR_LEAF_MAPSIZE) - bytes = INT_GET(hdr->freemap[current_hole].size, ARCH_CONVERT); - else - bytes = (int) INT_GET(hdr->firstused, ARCH_CONVERT) - - ((__psint_t) &leaf->entries[INT_GET(hdr->count, ARCH_CONVERT)] - - (__psint_t) leaf); - } -#endif - current_hole = 0; - - for (map = &hdr->freemap[0]; - current_hole < XFS_DIR_LEAF_MAPSIZE && - INT_GET(map->size, ARCH_CONVERT) < sizeof(xfs_dir_leaf_name_t); - map++) { - current_hole++; - } - - /* - * if we can use an existing hole, do it. otherwise, - * delete entries until the deletions create a big enough - * hole to convert another entry. then use up those bytes - * bytes until you run low. then delete entries again ... - */ - if (current_hole < XFS_DIR_LEAF_MAPSIZE) { - ASSERT(sizeof(xfs_dir_leaf_name_t) <= bytes); - - do_warn(_("marking bad entry in directory inode %llu\n"), - ino); - - entry->namelen = 1; - INT_SET(entry->nameidx, ARCH_CONVERT, INT_GET(hdr->freemap[current_hole].base, ARCH_CONVERT) + - bytes - sizeof(xfs_dir_leaf_name_t)); - - namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); - tmp_ino = NULLFSINO; - XFS_DIR_SF_PUT_DIRINO(&tmp_ino, &namest->inumber); - namest->name[0] = '/'; - - if (INT_GET(entry->nameidx, ARCH_CONVERT) < INT_GET(hdr->firstused, ARCH_CONVERT)) - INT_SET(hdr->firstused, ARCH_CONVERT, INT_GET(entry->nameidx, ARCH_CONVERT)); - INT_MOD(hdr->freemap[current_hole].size, ARCH_CONVERT, -(sizeof(xfs_dir_leaf_name_t))); - INT_MOD(hdr->namebytes, ARCH_CONVERT, +1); - } else { - /* - * delete the table entry and try and account for the - * space in the holemap. don't have to update namebytes - * or firstused since we're not actually deleting any - * bytes from the heap. following code swiped from - * xfs_dir_leaf_remove() in xfs_dir_leaf.c - */ - INT_MOD(hdr->count, ARCH_CONVERT, -1); - do_warn( - _("deleting zero length entry in directory inode %llu\n"), - ino); - /* - * overwrite the bad entry unless it's the - * last entry in the list (highly unlikely). - * zero out the free'd bytes. - */ - if (INT_GET(hdr->count, ARCH_CONVERT) - i > 0) { - memmove(entry, entry + 1, (INT_GET(hdr->count, ARCH_CONVERT) - i) * - sizeof(xfs_dir_leaf_entry_t)); - } - memset((void *) ((__psint_t) entry + - (INT_GET(leaf->hdr.count, ARCH_CONVERT) - i - 1) * - sizeof(xfs_dir_leaf_entry_t)), 0, - sizeof(xfs_dir_leaf_entry_t)); - - start = (__psint_t) &leaf->entries[INT_GET(hdr->count, ARCH_CONVERT)] - - (__psint_t) &leaf; - tablesize = sizeof(xfs_dir_leaf_entry_t) * - (INT_GET(hdr->count, ARCH_CONVERT) + 1) + sizeof(xfs_dir_leaf_hdr_t); - map = &hdr->freemap[0]; - tmp = INT_GET(map->size, ARCH_CONVERT); - before = after = -1; - smallest = XFS_DIR_LEAF_MAPSIZE - 1; - for (j = 0; j < XFS_DIR_LEAF_MAPSIZE; map++, j++) { - ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp)); - ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp)); - if (INT_GET(map->base, ARCH_CONVERT) == tablesize) { - INT_MOD(map->base, ARCH_CONVERT, -(sizeof(xfs_dir_leaf_entry_t))); - INT_MOD(map->size, ARCH_CONVERT, sizeof(xfs_dir_leaf_entry_t)); - } - - if ((INT_GET(map->base, ARCH_CONVERT) + INT_GET(map->size, ARCH_CONVERT)) == start) { - before = j; - } else if (INT_GET(map->base, ARCH_CONVERT) == start + - sizeof(xfs_dir_leaf_entry_t)) { - after = j; - } else if (INT_GET(map->size, ARCH_CONVERT) < tmp) { - tmp = INT_GET(map->size, ARCH_CONVERT); - smallest = j; - } - } - - /* - * Coalesce adjacent freemap regions, - * or replace the smallest region. - */ - if ((before >= 0) || (after >= 0)) { - if ((before >= 0) && (after >= 0)) { - map = &hdr->freemap[before]; - INT_MOD(map->size, ARCH_CONVERT, sizeof(xfs_dir_leaf_entry_t)); - INT_MOD(map->size, ARCH_CONVERT, INT_GET(hdr->freemap[after].size, ARCH_CONVERT)); - hdr->freemap[after].base = 0; - hdr->freemap[after].size = 0; - } else if (before >= 0) { - map = &hdr->freemap[before]; - INT_MOD(map->size, ARCH_CONVERT, sizeof(xfs_dir_leaf_entry_t)); - } else { - map = &hdr->freemap[after]; - INT_SET(map->base, ARCH_CONVERT, start); - INT_MOD(map->size, ARCH_CONVERT, sizeof(xfs_dir_leaf_entry_t)); - } - } else { - /* - * Replace smallest region - * (if it is smaller than free'd entry) - */ - map = &hdr->freemap[smallest]; - if (INT_GET(map->size, ARCH_CONVERT) < sizeof(xfs_dir_leaf_entry_t)) { - INT_SET(map->base, ARCH_CONVERT, start); - INT_SET(map->size, ARCH_CONVERT, sizeof(xfs_dir_leaf_entry_t)); - } - /* - * mark as needing compaction - */ - hdr->holes = 1; - } -#if 0 - /* - * do we have to delete stuff or is there - * room for deletions? - */ - ASSERT(current_hole == XFS_DIR_LEAF_MAPSIZE); - - /* - * here, bytes == number of unused bytes from - * end of list to top (beginning) of heap - * (firstused). It's ok to leave extra - * unused bytes in that region because they - * wind up before firstused (which we reset - * appropriately - */ - if (bytes < sizeof(xfs_dir_leaf_name_t)) { - /* - * have to delete an entry because - * we have no room to convert it to - * a bad entry - */ - do_warn( - _("deleting entry in directory inode %llu\n"), - ino); - /* - * overwrite the bad entry unless it's the - * last entry in the list (highly unlikely). - */ - if (INT_GET(leaf->hdr.count, ARCH_CONVERT) - i - 1> 0) { - memmove(entry, entry + 1, - (INT_GET(leaf->hdr.count, ARCH_CONVERT) - i - 1) * - sizeof(xfs_dir_leaf_entry_t)); - } - memset((void *) ((__psint_t) entry + - (INT_GET(leaf->hdr.count, ARCH_CONVERT) - i - 1) * - sizeof(xfs_dir_leaf_entry_t)), 0, - sizeof(xfs_dir_leaf_entry_t)); - - /* - * bump up free byte count, drop other - * index vars since the table just - * shrank by one entry and we don't - * want to miss any as we walk the table - */ - bytes += sizeof(xfs_dir_leaf_entry_t); - INT_MOD(leaf->hdr.count, ARCH_CONVERT, -1); - entry--; - i--; - } else { - /* - * convert entry using the bytes in between - * the end of the entry table and the heap - */ - entry->namelen = 1; - INT_MOD(leaf->hdr.firstused, ARCH_CONVERT, -(sizeof(xfs_dir_leaf_name_t))); - INT_SET(entry->nameidx, ARCH_CONVERT, INT_GET(leaf->hdr.firstused, ARCH_CONVERT)); - - namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, - INT_GET(entry->nameidx, ARCH_CONVERT)); - tmp_ino = NULLFSINO; - XFS_DIR_SF_PUT_DIRINO(&tmp_ino, - &namest->inumber); - namest->name[0] = '/'; - - bytes -= sizeof(xfs_dir_leaf_entry_t); - } -#endif - } - } - - return; -} -#endif - size_t ts_dirbuf_size = 64*1024; /* @@ -1759,29 +1474,26 @@ _("directory block header conflicts with used space in directory inode %llu\n"), * inodes on a later pass. */ for (i = 0, entry = &leaf->entries[0]; - i < INT_GET(leaf->hdr.count, ARCH_CONVERT); + i < be16_to_cpu(leaf->hdr.count); i++, entry++) { /* * check that the name index isn't out of bounds * if it is, delete the entry since we can't * grab the inode #. */ - if (INT_GET(entry->nameidx, ARCH_CONVERT) >= + if (be16_to_cpu(entry->nameidx) >= mp->m_sb.sb_blocksize) { if (!no_modify) { *buf_dirty = 1; - if (INT_GET(leaf->hdr.count, ARCH_CONVERT) > 1) { + if (be16_to_cpu(leaf->hdr.count) > 1) { do_warn( _("nameidx %d for entry #%d, bno %d, ino %llu > fs blocksize, deleting entry\n"), - INT_GET(entry->nameidx, - ARCH_CONVERT), + be16_to_cpu(entry->nameidx), i, da_bno, ino); - ASSERT(INT_GET(leaf->hdr.count, - ARCH_CONVERT) > i); + ASSERT(be16_to_cpu(leaf->hdr.count) > i); - bytes = (INT_GET(leaf->hdr.count, - ARCH_CONVERT) - i) * + bytes = (be16_to_cpu(leaf->hdr.count) - i) * sizeof(xfs_dir_leaf_entry_t); /* @@ -1808,30 +1520,28 @@ _("nameidx %d for entry #%d, bno %d, ino %llu > fs blocksize, deleting entry\n") * map since we haven't set it for * this entry yet. */ - INT_MOD(leaf->hdr.count, ARCH_CONVERT, -1); + be16_add_cpu(&leaf->hdr.count, -1); i--; entry--; } else { do_warn( _("nameidx %d, entry #%d, bno %d, ino %llu > fs blocksize, marking entry bad\n"), - INT_GET(entry->nameidx, - ARCH_CONVERT), + be16_to_cpu(entry->nameidx), i, da_bno, ino); - INT_SET(entry->nameidx, ARCH_CONVERT, + entry->nameidx = cpu_to_be16( mp->m_sb.sb_blocksize - sizeof(xfs_dir_leaf_name_t)); - namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, - INT_GET(entry->nameidx, - ARCH_CONVERT)); + namest = xfs_dir_leaf_namestruct(leaf, + be16_to_cpu(entry->nameidx)); lino = NULLFSINO; - XFS_DIR_SF_PUT_DIRINO(&lino, + xfs_dir_sf_put_dirino(&lino, &namest->inumber); namest->name[0] = '/'; } } else { do_warn( _("nameidx %d, entry #%d, bno %d, ino %llu > fs blocksize, would delete entry\n"), - INT_GET(entry->nameidx, ARCH_CONVERT), + be16_to_cpu(entry->nameidx), i, da_bno, ino); } continue; @@ -1843,9 +1553,9 @@ _("nameidx %d, entry #%d, bno %d, ino %llu > fs blocksize, would delete entry\n" * we can still try for the inode as long as nameidx * is ok. */ - namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, - INT_GET(entry->nameidx, ARCH_CONVERT)); - XFS_DIR_SF_GET_DIRINO(&namest->inumber, &lino); + namest = xfs_dir_leaf_namestruct(leaf, + be16_to_cpu(entry->nameidx)); + xfs_dir_sf_get_dirino(&namest->inumber, &lino); /* * we may have to blow out an entry because of bad @@ -1874,7 +1584,7 @@ _("nameidx %d, entry #%d, bno %d, ino %llu > fs blocksize, would delete entry\n" _("\tclearing ino number in entry %d...\n"), i); lino = NULLFSINO; - XFS_DIR_SF_PUT_DIRINO(&lino, &namest->inumber); + xfs_dir_sf_put_dirino(&lino, &namest->inumber); *buf_dirty = 1; } else { do_warn( @@ -1891,7 +1601,7 @@ _("entry #%d, bno %d in directory %llu references realtime bitmap inode %llu\n") i); lino = NULLFSINO; - XFS_DIR_SF_PUT_DIRINO(&lino, &namest->inumber); + xfs_dir_sf_put_dirino(&lino, &namest->inumber); *buf_dirty = 1; } else { do_warn( @@ -1907,7 +1617,7 @@ _("entry #%d, bno %d in directory %llu references realtime summary inode %llu\n" _("\tclearing ino number in entry %d...\n"), i); lino = NULLFSINO; - XFS_DIR_SF_PUT_DIRINO(&lino, &namest->inumber); + xfs_dir_sf_put_dirino(&lino, &namest->inumber); *buf_dirty = 1; } else { do_warn( @@ -1924,7 +1634,7 @@ _("entry #%d, bno %d in directory %llu references user quota inode %llu\n"), i); lino = NULLFSINO; - XFS_DIR_SF_PUT_DIRINO(&lino, &namest->inumber); + xfs_dir_sf_put_dirino(&lino, &namest->inumber); *buf_dirty = 1; } else { do_warn( @@ -1941,7 +1651,7 @@ _("entry #%d, bno %d in directory %llu references group quota inode %llu\n"), i); lino = NULLFSINO; - XFS_DIR_SF_PUT_DIRINO(&lino, &namest->inumber); + xfs_dir_sf_put_dirino(&lino, &namest->inumber); *buf_dirty = 1; } else { do_warn( @@ -1973,7 +1683,7 @@ _("entry #%d, bno %d in directory %llu references group quota inode %llu\n"), _("entry references free inode %llu in directory %llu, will clear entry\n"), lino, ino); lino = NULLFSINO; - XFS_DIR_SF_PUT_DIRINO(&lino, + xfs_dir_sf_put_dirino(&lino, &namest->inumber); *buf_dirty = 1; } else { @@ -1991,7 +1701,7 @@ _("entry references free inode %llu in directory %llu, would clear entry\n"), if (!no_modify) { do_warn(_("clearing inode number...\n")); lino = NULLFSINO; - XFS_DIR_SF_PUT_DIRINO(&lino, &namest->inumber); + xfs_dir_sf_put_dirino(&lino, &namest->inumber); *buf_dirty = 1; } else { do_warn(_("would clear inode number...\n")); @@ -2012,15 +1722,14 @@ _("entry references free inode %llu in directory %llu, would clear entry\n"), if (entry->namelen == 0) { *buf_dirty = 1; - if (INT_GET(leaf->hdr.count, ARCH_CONVERT) > 1) { + if (be16_to_cpu(leaf->hdr.count) > 1) { do_warn( _("entry #%d, dir inode %llu, has zero-len name, deleting entry\n"), i, ino); - ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) > i); + ASSERT(be16_to_cpu(leaf->hdr.count) > i); - bytes = (INT_GET(leaf->hdr.count, - ARCH_CONVERT) - i) * - sizeof(xfs_dir_leaf_entry_t); + bytes = (be16_to_cpu(leaf->hdr.count) - i) * + sizeof(xfs_dir_leaf_entry_t); /* * compress table unless we're @@ -2030,8 +1739,8 @@ _("entry references free inode %llu in directory %llu, would clear entry\n"), */ if (bytes > sizeof(xfs_dir_leaf_entry_t)) { memmove(entry, entry + 1, bytes); - memset((void *) - ((__psint_t) entry + bytes), 0, + memset((void *)((__psint_t) entry + + bytes), 0, sizeof(xfs_dir_leaf_entry_t)); } else { memset(entry, 0, @@ -2044,7 +1753,7 @@ _("entry references free inode %llu in directory %llu, would clear entry\n"), * map since we haven't set it for * this entry yet. */ - INT_MOD(leaf->hdr.count, ARCH_CONVERT, -1); + be16_add_cpu(&leaf->hdr.count, -1); i--; entry--; } else { @@ -2055,17 +1764,16 @@ _("entry references free inode %llu in directory %llu, would clear entry\n"), do_warn( _("entry #%d, dir inode %llu, has zero-len name, marking entry bad\n"), i, ino); - INT_SET(entry->nameidx, ARCH_CONVERT, - mp->m_sb.sb_blocksize - + entry->nameidx = cpu_to_be16( + mp->m_sb.sb_blocksize - sizeof(xfs_dir_leaf_name_t)); - namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, - INT_GET(entry->nameidx, - ARCH_CONVERT)); - XFS_DIR_SF_PUT_DIRINO(&lino, &namest->inumber); + namest = xfs_dir_leaf_namestruct(leaf, + be16_to_cpu(entry->nameidx)); + xfs_dir_sf_put_dirino(&lino, &namest->inumber); namest->name[0] = '/'; } - } else if (INT_GET(entry->nameidx, ARCH_CONVERT) + - entry->namelen > XFS_LBSIZE(mp)) { + } else if (be16_to_cpu(entry->nameidx) + entry->namelen > + XFS_LBSIZE(mp)) { do_warn( _("bad size, entry #%d in dir inode %llu, block %u -- entry overflows block\n"), i, ino, da_bno); @@ -2127,7 +1835,7 @@ _("illegal name \"%s\" in directory inode %llu, entry would be cleared\n"), fname, ino); } } else if (!nm_illegal && - INT_GET(entry->hashval, ARCH_CONVERT) != hashval) { + be32_to_cpu(entry->hashval) != hashval) { /* * try resetting the hashvalue to the correct * value for the string, if the string has been @@ -2139,7 +1847,7 @@ _("illegal name \"%s\" in directory inode %llu, entry would be cleared\n"), do_warn( _("\t\tin directory inode %llu. resetting hash value.\n"), ino); - INT_SET(entry->hashval, ARCH_CONVERT, hashval); + entry->hashval = cpu_to_be32(hashval); *buf_dirty = 1; } else { do_warn( @@ -2161,7 +1869,7 @@ _("illegal name \"%s\" in directory inode %llu, entry would be cleared\n"), * marked for deletion, the hash value ordering must * be maintained. */ - if (INT_GET(entry->hashval, ARCH_CONVERT) < last_hashval) { + if (be32_to_cpu(entry->hashval) < last_hashval) { /* * blow out the entry -- set hashval to sane value * and set the first character in the string to @@ -2179,8 +1887,7 @@ _("illegal name \"%s\" in directory inode %llu, entry would be cleared\n"), do_warn( _("\t\tin directory inode %llu. will clear entry\n"), ino); - INT_SET(entry->hashval, ARCH_CONVERT, - last_hashval); + entry->hashval = cpu_to_be32(last_hashval); namest->name[0] = '/'; *buf_dirty = 1; } else { @@ -2190,17 +1897,16 @@ _("illegal name \"%s\" in directory inode %llu, entry would be cleared\n"), } } - *next_hashval = last_hashval = INT_GET(entry->hashval, ARCH_CONVERT); + *next_hashval = last_hashval = be32_to_cpu(entry->hashval); /* * if heap data conflicts with something, * blow it out and skip the rest of the loop */ - if (set_da_freemap(mp, dir_freemap, - INT_GET(entry->nameidx, ARCH_CONVERT), - INT_GET(entry->nameidx, ARCH_CONVERT) - + sizeof(xfs_dir_leaf_name_t) - + entry->namelen - 1)) { + if (set_da_freemap(mp, dir_freemap, be16_to_cpu(entry->nameidx), + be16_to_cpu(entry->nameidx) + + sizeof(xfs_dir_leaf_name_t) + + entry->namelen - 1)) { do_warn( _("name \"%s\" (block %u, slot %d) conflicts with used space in dir inode %llu\n"), fname, da_bno, i, ino); @@ -2222,8 +1928,8 @@ _("name \"%s\" (block %u, slot %d) conflicts with used space in dir inode %llu\n /* * keep track of heap stats (first byte used, total bytes used) */ - if (INT_GET(entry->nameidx, ARCH_CONVERT) < first_used) - first_used = INT_GET(entry->nameidx, ARCH_CONVERT); + if (be16_to_cpu(entry->nameidx) < first_used) + first_used = be16_to_cpu(entry->nameidx); bytes_used += entry->namelen; /* @@ -2270,7 +1976,7 @@ _("name \"%s\" (block %u, slot %d) conflicts with used space in dir inode %llu\n do_warn( _("correcting .. entry in root inode %llu, was %llu\n"), ino, *parent); - XFS_DIR_SF_PUT_DIRINO( + xfs_dir_sf_put_dirino( &ino, &namest->inumber); *buf_dirty = 1; } else { @@ -2313,7 +2019,7 @@ _("multiple .. entries in directory inode %llu, would clear second entry\n"), do_warn( _(". in directory inode %llu has wrong value (%llu), fixing entry...\n"), ino, lino); - XFS_DIR_SF_PUT_DIRINO(&ino, + xfs_dir_sf_put_dirino(&ino, &namest->inumber); *buf_dirty = 1; } else { @@ -2366,44 +2072,40 @@ _(". in directory inode %llu has wrong value (%llu), fixing entry...\n"), * pointing to used bytes. we're being conservative here * since the block will get compacted anyhow by the kernel. */ - if ((leaf->hdr.holes == 0 && - first_used != INT_GET(leaf->hdr.firstused, ARCH_CONVERT)) || - INT_GET(leaf->hdr.firstused, ARCH_CONVERT) > first_used) { + if ((leaf->hdr.holes == 0 && + first_used != be16_to_cpu(leaf->hdr.firstused)) || + be16_to_cpu(leaf->hdr.firstused) > first_used) { if (!no_modify) { if (verbose) do_warn( _("- resetting first used heap value from %d to %d in block %u of dir ino %llu\n"), - (int) INT_GET(leaf->hdr.firstused, - ARCH_CONVERT), + be16_to_cpu(leaf->hdr.firstused), first_used, da_bno, ino); - INT_SET(leaf->hdr.firstused, ARCH_CONVERT, first_used); + leaf->hdr.firstused = cpu_to_be16(first_used); *buf_dirty = 1; } else { if (verbose) do_warn( _("- would reset first used value from %d to %d in block %u of dir ino %llu\n"), - (int) INT_GET(leaf->hdr.firstused, - ARCH_CONVERT), + be16_to_cpu(leaf->hdr.firstused), first_used, da_bno, ino); } } - if (bytes_used != INT_GET(leaf->hdr.namebytes, ARCH_CONVERT)) { + if (bytes_used != be16_to_cpu(leaf->hdr.namebytes)) { if (!no_modify) { if (verbose) do_warn( _("- resetting namebytes cnt from %d to %d in block %u of dir inode %llu\n"), - (int) INT_GET(leaf->hdr.namebytes, - ARCH_CONVERT), + be16_to_cpu(leaf->hdr.namebytes), bytes_used, da_bno, ino); - INT_SET(leaf->hdr.namebytes, ARCH_CONVERT, bytes_used); + leaf->hdr.namebytes = cpu_to_be16(bytes_used); *buf_dirty = 1; } else { if (verbose) do_warn( _("- would reset namebytes cnt from %d to %d in block %u of dir inode %llu\n"), - (int) INT_GET(leaf->hdr.namebytes, - ARCH_CONVERT), + be16_to_cpu(leaf->hdr.namebytes), bytes_used, da_bno, ino); } } @@ -2419,8 +2121,8 @@ _("- would reset namebytes cnt from %d to %d in block %u of dir inode %llu\n"), bholemap.lost_holes = leaf->hdr.holes; for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; i++) { - bholemap.hentries[i].base = INT_GET(leaf->hdr.freemap[i].base, ARCH_CONVERT); - bholemap.hentries[i].size = INT_GET(leaf->hdr.freemap[i].size, ARCH_CONVERT); + bholemap.hentries[i].base = be16_to_cpu(leaf->hdr.freemap[i].base); + bholemap.hentries[i].size = be16_to_cpu(leaf->hdr.freemap[i].size); } /* @@ -2503,7 +2205,7 @@ _("- existing hole info for block %d, dir inode %llu (base, size) - \n"), */ for (i = 0, s_entry = &leaf->entries[0], d_entry = &new_leaf->entries[0]; - i < INT_GET(leaf->hdr.count, ARCH_CONVERT); + i < be16_to_cpu(leaf->hdr.count); i++, s_entry++) { /* * skip zero-length entries @@ -2526,13 +2228,13 @@ _("- existing hole info for block %d, dir inode %llu (base, size) - \n"), first_used -= bytes; first_byte -= bytes; - INT_SET(d_entry->nameidx, ARCH_CONVERT, first_used); - INT_SET(d_entry->hashval, ARCH_CONVERT, INT_GET(s_entry->hashval, ARCH_CONVERT)); + d_entry->nameidx = cpu_to_be16(first_used); + d_entry->hashval = s_entry->hashval; d_entry->namelen = s_entry->namelen; d_entry->pad2 = 0; - memmove(first_byte, (char *) leaf + INT_GET(s_entry->nameidx, ARCH_CONVERT), - bytes); + memmove(first_byte, (char *)leaf + + be16_to_cpu(s_entry->nameidx), bytes); num_entries++; d_entry++; @@ -2550,27 +2252,27 @@ _("- existing hole info for block %d, dir inode %llu (base, size) - \n"), /* * reset header info */ - if (num_entries != INT_GET(new_leaf->hdr.count, ARCH_CONVERT)) - INT_SET(new_leaf->hdr.count, ARCH_CONVERT, num_entries); + if (num_entries != be16_to_cpu(new_leaf->hdr.count)) + new_leaf->hdr.count = cpu_to_be16(num_entries); - INT_SET(new_leaf->hdr.firstused, ARCH_CONVERT, first_used); + new_leaf->hdr.firstused = cpu_to_be16(first_used); new_leaf->hdr.holes = 0; new_leaf->hdr.pad1 = 0; - INT_SET(new_leaf->hdr.freemap[0].base, ARCH_CONVERT, (__psint_t) d_entry - - (__psint_t) new_leaf); - INT_SET(new_leaf->hdr.freemap[0].size, ARCH_CONVERT, (__psint_t) first_byte - - (__psint_t) d_entry); + new_leaf->hdr.freemap[0].base = cpu_to_be16( + (__psint_t) d_entry - (__psint_t) new_leaf); + new_leaf->hdr.freemap[0].size = cpu_to_be16( + (__psint_t) first_byte - (__psint_t) d_entry); - ASSERT(INT_GET(new_leaf->hdr.freemap[0].base, ARCH_CONVERT) < first_used); - ASSERT(INT_GET(new_leaf->hdr.freemap[0].base, ARCH_CONVERT) == + ASSERT(be16_to_cpu(new_leaf->hdr.freemap[0].base) < first_used); + ASSERT(be16_to_cpu(new_leaf->hdr.freemap[0].base) == (__psint_t) (&new_leaf->entries[0]) - (__psint_t) new_leaf + i * sizeof(xfs_dir_leaf_entry_t)); - ASSERT(INT_GET(new_leaf->hdr.freemap[0].base, ARCH_CONVERT) < XFS_LBSIZE(mp)); - ASSERT(INT_GET(new_leaf->hdr.freemap[0].size, ARCH_CONVERT) < XFS_LBSIZE(mp)); - ASSERT(INT_GET(new_leaf->hdr.freemap[0].base, ARCH_CONVERT) + - INT_GET(new_leaf->hdr.freemap[0].size, ARCH_CONVERT) == first_used); + ASSERT(be16_to_cpu(new_leaf->hdr.freemap[0].base) < XFS_LBSIZE(mp)); + ASSERT(be16_to_cpu(new_leaf->hdr.freemap[0].size) < XFS_LBSIZE(mp)); + ASSERT(be16_to_cpu(new_leaf->hdr.freemap[0].base) + + be16_to_cpu(new_leaf->hdr.freemap[0].size) == first_used); new_leaf->hdr.freemap[1].base = 0; new_leaf->hdr.freemap[1].size = 0; @@ -2671,10 +2373,10 @@ process_leaf_dir_level(xfs_mount_t *mp, * check magic number for leaf directory btree block */ if (XFS_DIR_LEAF_MAGIC != - INT_GET(leaf->hdr.info.magic, ARCH_CONVERT)) { + be16_to_cpu(leaf->hdr.info.magic)) { do_warn( _("bad directory leaf magic # %#x for dir ino %llu\n"), - INT_GET(leaf->hdr.info.magic, ARCH_CONVERT), + be16_to_cpu(leaf->hdr.info.magic), ino); libxfs_putbuf(bp); goto error_out; @@ -2708,10 +2410,10 @@ process_leaf_dir_level(xfs_mount_t *mp, da_cursor->level[0].hashval = greatest_hashval; da_cursor->level[0].bp = bp; da_cursor->level[0].bno = da_bno; - da_cursor->level[0].index = INT_GET(leaf->hdr.count, ARCH_CONVERT); + da_cursor->level[0].index = be16_to_cpu(leaf->hdr.count); da_cursor->level[0].dirty = buf_dirty; - if (INT_GET(leaf->hdr.info.back, ARCH_CONVERT) != prev_bno) { + if (be32_to_cpu(leaf->hdr.info.back) != prev_bno) { do_warn(_("bad sibling back pointer for directory " "block %u in directory inode %llu\n"), da_bno, ino); @@ -2720,7 +2422,7 @@ process_leaf_dir_level(xfs_mount_t *mp, } prev_bno = da_bno; - da_bno = INT_GET(leaf->hdr.info.forw, ARCH_CONVERT); + da_bno = be32_to_cpu(leaf->hdr.info.forw); if (da_bno != 0) if (verify_da_path(mp, da_cursor, 0)) { @@ -2849,7 +2551,7 @@ process_node_dir( /* * sanity check inode size */ - if (INT_GET(dip->di_core.di_size, ARCH_CONVERT) < + if (be64_to_cpu(dip->di_core.di_size) < (da_cursor.greatest_bno + 1) * mp->m_sb.sb_blocksize) { if ((xfs_fsize_t) da_cursor.greatest_bno * mp->m_sb.sb_blocksize > UINT_MAX) { @@ -2861,13 +2563,12 @@ process_node_dir( do_warn( _("setting directory inode (%llu) size to %llu bytes, was %lld bytes\n"), - ino, - (xfs_dfiloff_t) (da_cursor.greatest_bno + 1) + ino, (xfs_dfiloff_t) (da_cursor.greatest_bno + 1) * mp->m_sb.sb_blocksize, - INT_GET(dip->di_core.di_size, ARCH_CONVERT)); + be64_to_cpu(dip->di_core.di_size)); - INT_SET(dip->di_core.di_size, ARCH_CONVERT, (xfs_fsize_t) - (da_cursor.greatest_bno + 1) * mp->m_sb.sb_blocksize); + dip->di_core.di_size = cpu_to_be64((da_cursor.greatest_bno + 1) + * mp->m_sb.sb_blocksize); } return(0); } @@ -2934,9 +2635,9 @@ process_leaf_dir( /* * check magic number for leaf directory btree block */ - if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR_LEAF_MAGIC) { + if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) { do_warn(_("bad directory leaf magic # %#x for dir ino %llu\n"), - INT_GET(leaf->hdr.info.magic, ARCH_CONVERT), ino); + be16_to_cpu(leaf->hdr.info.magic), ino); libxfs_putbuf(bp); return(1); } @@ -2956,8 +2657,7 @@ process_leaf_dir( /* * check sibling pointers in leaf block (above doesn't do it) */ - if (INT_GET(leaf->hdr.info.forw, ARCH_CONVERT) != 0 || - INT_GET(leaf->hdr.info.back, ARCH_CONVERT) != 0) { + if (leaf->hdr.info.forw || leaf->hdr.info.back) { if (!no_modify) { do_warn(_("clearing forw/back pointers for " "directory inode %llu\n"), ino); @@ -3009,34 +2709,28 @@ process_dir( * is only called ONCE so all the subordinate routines will * fix '.' and junk '..' if they're bogus. */ - if (INT_GET(dip->di_core.di_size, ARCH_CONVERT) <= - XFS_DFORK_DSIZE(dip, mp)) { + if (be64_to_cpu(dip->di_core.di_size) <= XFS_DFORK_DSIZE(dip, mp)) { dot = 1; dotdot = 1; if (process_shortform_dir(mp, ino, dip, ino_discovery, - dino_dirty, parent, dirname, &repair)) { + dino_dirty, parent, dirname, &repair)) res = 1; - } - } else if (INT_GET(dip->di_core.di_size, ARCH_CONVERT) <= - XFS_LBSIZE(mp)) { + } else if (be64_to_cpu(dip->di_core.di_size) <= XFS_LBSIZE(mp)) { if (process_leaf_dir(mp, ino, dip, ino_discovery, dino_dirty, blkmap, &dot, &dotdot, - parent, dirname, &repair)) { + parent, dirname, &repair)) res = 1; - } } else { if (process_node_dir(mp, ino, dip, ino_discovery, blkmap, &dot, &dotdot, - parent, dirname, &repair)) { + parent, dirname, &repair)) res = 1; - } } /* * bad . entries in all directories will be fixed up in phase 6 */ - if (dot == 0) { + if (dot == 0) do_warn(_("no . entry for directory %llu\n"), ino); - } /* * shortform dirs always have a .. entry. .. for all longform diff --git a/repair/dir2.c b/repair/dir2.c index 3aacc9a0d..9575fb1c9 100644 --- a/repair/dir2.c +++ b/repair/dir2.c @@ -249,7 +249,8 @@ da_brelse( da_buf_done(dabuf); for (i = 0; i < nbuf; i++) { #ifdef XR_PF_TRACE - pftrace("putbuf %p (%llu)", bplist[i], (long long)XFS_BUF_ADDR(bplist[i])); + pftrace("putbuf %p (%llu)", bplist[i], + (long long)XFS_BUF_ADDR(bplist[i])); #endif libxfs_putbuf(bplist[i]); } @@ -309,8 +310,7 @@ traverse_int_dir2block(xfs_mount_t *mp, info = bp->data; - if (INT_GET(info->magic, ARCH_CONVERT) == - XFS_DIR2_LEAFN_MAGIC) { + if (be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC) { if ( i != -1 ) { do_warn(_("found non-root LEAFN node in inode " "%llu bno = %u\n"), @@ -319,22 +319,20 @@ traverse_int_dir2block(xfs_mount_t *mp, *rbno = 0; da_brelse(bp); return(1); - } else if (INT_GET(info->magic, ARCH_CONVERT) != - XFS_DA_NODE_MAGIC) { + } else if (be16_to_cpu(info->magic) != XFS_DA_NODE_MAGIC) { da_brelse(bp); do_warn(_("bad dir magic number 0x%x in inode %llu " "bno = %u\n"), - INT_GET(info->magic, ARCH_CONVERT), + be16_to_cpu(info->magic), da_cursor->ino, bno); goto error_out; } node = (xfs_da_intnode_t*)info; - if (INT_GET(node->hdr.count, ARCH_CONVERT) > - mp->m_dir_node_ents) { + if (be16_to_cpu(node->hdr.count) > mp->m_dir_node_ents) { da_brelse(bp); do_warn(_("bad record count in inode %llu, count = %d, " "max = %d\n"), da_cursor->ino, - INT_GET(node->hdr.count, ARCH_CONVERT), + be16_to_cpu(node->hdr.count), mp->m_dir_node_ents); goto error_out; } @@ -342,10 +340,9 @@ traverse_int_dir2block(xfs_mount_t *mp, * maintain level counter */ if (i == -1) - i = da_cursor->active = - INT_GET(node->hdr.level, ARCH_CONVERT); + i = da_cursor->active = be16_to_cpu(node->hdr.level); else { - if (INT_GET(node->hdr.level, ARCH_CONVERT) == i - 1) { + if (be16_to_cpu(node->hdr.level) == i - 1) { i--; } else { do_warn(_("bad directory btree for directory " @@ -357,7 +354,7 @@ traverse_int_dir2block(xfs_mount_t *mp, } da_cursor->level[i].hashval = - INT_GET(node->btree[0].hashval, ARCH_CONVERT); + be32_to_cpu(node->btree[0].hashval); da_cursor->level[i].bp = bp; da_cursor->level[i].bno = bno; da_cursor->level[i].index = 0; @@ -365,7 +362,7 @@ traverse_int_dir2block(xfs_mount_t *mp, /* * set up new bno for next level down */ - bno = INT_GET(node->btree[0].before, ARCH_CONVERT); + bno = be32_to_cpu(node->btree[0].before); } while (info != NULL && i > 1); /* @@ -460,27 +457,27 @@ verify_final_dir2_path(xfs_mount_t *mp, * that all entries are used, encountered and expected hashvals * match, etc. */ - if (entry != INT_GET(node->hdr.count, ARCH_CONVERT) - 1) { + if (entry != be16_to_cpu(node->hdr.count) - 1) { do_warn( _("directory block used/count inconsistency - %d / %hu\n"), - entry, INT_GET(node->hdr.count, ARCH_CONVERT)); + entry, be16_to_cpu(node->hdr.count)); bad++; } /* * hash values monotonically increasing ??? */ if (cursor->level[this_level].hashval >= - INT_GET(node->btree[entry].hashval, ARCH_CONVERT)) { + be32_to_cpu(node->btree[entry].hashval)) { do_warn(_("directory/attribute block hashvalue inconsistency, " "expected > %u / saw %u\n"), cursor->level[this_level].hashval, - INT_GET(node->btree[entry].hashval, ARCH_CONVERT)); + be32_to_cpu(node->btree[entry].hashval)); bad++; } - if (INT_GET(node->hdr.info.forw, ARCH_CONVERT) != 0) { + if (be32_to_cpu(node->hdr.info.forw) != 0) { do_warn(_("bad directory/attribute forward block pointer, " "expected 0, saw %u\n"), - INT_GET(node->hdr.info.forw, ARCH_CONVERT)); + be32_to_cpu(node->hdr.info.forw)); bad++; } if (bad) { @@ -498,18 +495,17 @@ verify_final_dir2_path(xfs_mount_t *mp, * ok, now check descendant block number against this level */ if (cursor->level[p_level].bno != - INT_GET(node->btree[entry].before, ARCH_CONVERT)) { + be32_to_cpu(node->btree[entry].before)) return(1); - } if (cursor->level[p_level].hashval != - INT_GET(node->btree[entry].hashval, ARCH_CONVERT)) { + be32_to_cpu(node->btree[entry].hashval)) { if (!no_modify) { do_warn(_("correcting bad hashval in non-leaf dir " "block\n\tin (level %d) in inode %llu.\n"), this_level, cursor->ino); - INT_SET(node->btree[entry].hashval, ARCH_CONVERT, - cursor->level[p_level].hashval); + node->btree[entry].hashval = cpu_to_be32( + cursor->level[p_level].hashval); cursor->level[this_level].dirty++; } else { do_warn(_("would correct bad hashval in non-leaf dir " @@ -534,15 +530,14 @@ verify_final_dir2_path(xfs_mount_t *mp, /* * bail out if this is the root block (top of tree) */ - if (this_level >= cursor->active) { + if (this_level >= cursor->active) return(0); - } /* * set hashvalue to correctl reflect the now-validated * last entry in this block and continue upwards validation */ cursor->level[this_level].hashval = - INT_GET(node->btree[entry].hashval, ARCH_CONVERT); + be32_to_cpu(node->btree[entry].hashval); return(verify_final_dir2_path(mp, cursor, this_level)); } @@ -614,14 +609,14 @@ verify_dir2_path(xfs_mount_t *mp, * block and move on to the next block. * and update cursor value for said level */ - if (entry >= INT_GET(node->hdr.count, ARCH_CONVERT)) { + if (entry >= be16_to_cpu(node->hdr.count)) { /* * update the hash value for this level before * validating it. bno value should be ok since * it was set when the block was first read in. */ cursor->level[this_level].hashval = - INT_GET(node->btree[entry - 1].hashval, ARCH_CONVERT); + be32_to_cpu(node->btree[entry - 1].hashval); /* * keep track of greatest block # -- that gets @@ -639,7 +634,7 @@ verify_dir2_path(xfs_mount_t *mp, /* * ok, now get the next buffer and check sibling pointers */ - dabno = INT_GET(node->hdr.info.forw, ARCH_CONVERT); + dabno = be32_to_cpu(node->hdr.info.forw); ASSERT(dabno != 0); nex = blkmap_getn(cursor->blkmap, dabno, mp->m_dirblkfsbs, &bmp, &lbmp); @@ -667,33 +662,31 @@ verify_dir2_path(xfs_mount_t *mp, * entry count, verify level */ bad = 0; - if (XFS_DA_NODE_MAGIC != - INT_GET(newnode->hdr.info.magic, ARCH_CONVERT)) { + if (XFS_DA_NODE_MAGIC != be16_to_cpu(newnode->hdr.info.magic)) { do_warn(_("bad magic number %x in block %u for " "directory inode %llu\n"), - INT_GET(newnode->hdr.info.magic, ARCH_CONVERT), + be16_to_cpu(newnode->hdr.info.magic), dabno, cursor->ino); bad++; } - if (INT_GET(newnode->hdr.info.back, ARCH_CONVERT) != - cursor->level[this_level].bno) { + if (be32_to_cpu(newnode->hdr.info.back) != + cursor->level[this_level].bno) { do_warn(_("bad back pointer in block %u for directory " "inode %llu\n"), dabno, cursor->ino); bad++; } - if (INT_GET(newnode->hdr.count, ARCH_CONVERT) > - mp->m_dir_node_ents) { + if (be16_to_cpu(newnode->hdr.count) > mp->m_dir_node_ents) { do_warn(_("entry count %d too large in block %u for " "directory inode %llu\n"), - INT_GET(newnode->hdr.count, ARCH_CONVERT), + be16_to_cpu(newnode->hdr.count), dabno, cursor->ino); bad++; } - if (INT_GET(newnode->hdr.level, ARCH_CONVERT) != this_level) { + if (be16_to_cpu(newnode->hdr.level) != this_level) { do_warn(_("bad level %d in block %u for directory " "inode %llu\n"), - INT_GET(newnode->hdr.level, ARCH_CONVERT), + be16_to_cpu(newnode->hdr.level), dabno, cursor->ino); bad++; } @@ -716,7 +709,7 @@ verify_dir2_path(xfs_mount_t *mp, cursor->level[this_level].dirty = 0; cursor->level[this_level].bno = dabno; cursor->level[this_level].hashval = - INT_GET(newnode->btree[0].hashval, ARCH_CONVERT); + be32_to_cpu(newnode->btree[0].hashval); node = newnode; entry = cursor->level[this_level].index = 0; @@ -725,21 +718,20 @@ verify_dir2_path(xfs_mount_t *mp, * ditto for block numbers */ if (cursor->level[p_level].bno != - INT_GET(node->btree[entry].before, ARCH_CONVERT)) { + be32_to_cpu(node->btree[entry].before)) return(1); - } /* * ok, now validate last hashvalue in the descendant * block against the hashval in the current entry */ if (cursor->level[p_level].hashval != - INT_GET(node->btree[entry].hashval, ARCH_CONVERT)) { + be32_to_cpu(node->btree[entry].hashval)) { if (!no_modify) { do_warn(_("correcting bad hashval in interior dir " "block\n\tin (level %d) in inode %llu.\n"), this_level, cursor->ino); - INT_SET(node->btree[entry].hashval, ARCH_CONVERT, - cursor->level[p_level].hashval); + node->btree[entry].hashval = cpu_to_be32( + cursor->level[p_level].hashval); cursor->level[this_level].dirty++; } else { do_warn(_("would correct bad hashval in interior dir " @@ -780,24 +772,23 @@ process_sf_dir2_fixi8( exit(1); } memmove(oldsfp, newsfp, oldsize); - INT_SET(newsfp->hdr.count, ARCH_CONVERT, - INT_GET(oldsfp->hdr.count, ARCH_CONVERT)); + newsfp->hdr.count = oldsfp->hdr.count; newsfp->hdr.i8count = 0; - ino = XFS_DIR2_SF_GET_INUMBER(oldsfp, &oldsfp->hdr.parent); - XFS_DIR2_SF_PUT_INUMBER(newsfp, &ino, &newsfp->hdr.parent); - oldsfep = XFS_DIR2_SF_FIRSTENTRY(oldsfp); - newsfep = XFS_DIR2_SF_FIRSTENTRY(newsfp); + ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); + xfs_dir2_sf_put_inumber(newsfp, &ino, &newsfp->hdr.parent); + oldsfep = xfs_dir2_sf_firstentry(oldsfp); + newsfep = xfs_dir2_sf_firstentry(newsfp); while ((int)((char *)oldsfep - (char *)oldsfp) < oldsize) { newsfep->namelen = oldsfep->namelen; - XFS_DIR2_SF_PUT_OFFSET(newsfep, - XFS_DIR2_SF_GET_OFFSET(oldsfep)); + xfs_dir2_sf_put_offset(newsfep, + xfs_dir2_sf_get_offset(oldsfep)); memmove(newsfep->name, oldsfep->name, newsfep->namelen); - ino = XFS_DIR2_SF_GET_INUMBER(oldsfp, - XFS_DIR2_SF_INUMBERP(oldsfep)); - XFS_DIR2_SF_PUT_INUMBER(newsfp, &ino, - XFS_DIR2_SF_INUMBERP(newsfep)); - oldsfep = XFS_DIR2_SF_NEXTENTRY(oldsfp, oldsfep); - newsfep = XFS_DIR2_SF_NEXTENTRY(newsfp, newsfep); + ino = xfs_dir2_sf_get_inumber(oldsfp, + xfs_dir2_sf_inumberp(oldsfep)); + xfs_dir2_sf_put_inumber(newsfp, &ino, + xfs_dir2_sf_inumberp(newsfep)); + oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep); + newsfep = xfs_dir2_sf_nextentry(newsfp, newsfep); } *next_sfep = newsfep; free(oldsfp); @@ -815,13 +806,14 @@ process_sf_dir2_fixoff( xfs_dir2_sf_entry_t *sfep; xfs_dir2_sf_t *sfp; - for (i = 0, sfp = &dip->di_u.di_dir2sf, - sfep = XFS_DIR2_SF_FIRSTENTRY(sfp), - offset = XFS_DIR2_DATA_FIRST_OFFSET; - i < INT_GET(sfp->hdr.count, ARCH_CONVERT); - i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep)) { - XFS_DIR2_SF_PUT_OFFSET(sfep, offset); - offset += XFS_DIR2_DATA_ENTSIZE(sfep->namelen); + sfp = &dip->di_u.di_dir2sf; + sfep = xfs_dir2_sf_firstentry(sfp); + offset = XFS_DIR2_DATA_FIRST_OFFSET; + + for (i = 0; i < sfp->hdr.count; i++) { + xfs_dir2_sf_put_offset(sfep, offset); + offset += xfs_dir2_data_entsize(sfep->namelen); + sfep = xfs_dir2_sf_nextentry(sfp, sfep); } } @@ -869,7 +861,7 @@ process_sf_dir2( sfp = &dip->di_u.di_dir2sf; max_size = XFS_DFORK_DSIZE(dip, mp); num_entries = sfp->hdr.count; - ino_dir_size = INT_GET(dip->di_core.di_size, ARCH_CONVERT); + ino_dir_size = be64_to_cpu(dip->di_core.di_size); offset = XFS_DIR2_DATA_FIRST_OFFSET; bad_offset = *repair = 0; @@ -878,22 +870,21 @@ process_sf_dir2( /* * Initialize i8 based on size of parent inode number. */ - i8 = (XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent) + i8 = (xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent) > XFS_DIR2_MAX_SHORT_INUM); /* * check for bad entry count */ - if (num_entries * XFS_DIR2_SF_ENTSIZE_BYNAME(sfp, 1) + - XFS_DIR2_SF_HDR_SIZE(0) > max_size || - num_entries == 0) + if (num_entries * xfs_dir2_sf_entsize_byname(sfp, 1) + + xfs_dir2_sf_hdr_size(0) > max_size || num_entries == 0) num_entries = 0xFF; /* * run through entries, stop at first bad entry, don't need * to check for .. since that's encoded in its own field */ - sfep = next_sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); + sfep = next_sfep = xfs_dir2_sf_firstentry(sfp); for (i = 0; i < num_entries && ino_dir_size > (char *)next_sfep - (char *)sfp; i++) { @@ -901,8 +892,7 @@ process_sf_dir2( sfep = next_sfep; junkit = 0; bad_sfnamelen = 0; - lino = XFS_DIR2_SF_GET_INUMBER(sfp, - XFS_DIR2_SF_INUMBERP(sfep)); + lino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); /* * if entry points to self, junk it since only '.' or '..' * should do that and shortform dirs don't contain either @@ -1017,8 +1007,8 @@ process_sf_dir2( break; } } else if ((__psint_t) sfep - (__psint_t) sfp + - + XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp, sfep) - > ino_dir_size) { + xfs_dir2_sf_entsize_byentry(sfp, sfep) + > ino_dir_size) { bad_sfnamelen = 1; if (i == num_entries - 1) { @@ -1081,14 +1071,14 @@ process_sf_dir2( junkit = 1; } - if (XFS_DIR2_SF_GET_OFFSET(sfep) < offset) { + if (xfs_dir2_sf_get_offset(sfep) < offset) { do_warn(_("entry contains offset out of order in " "shortform dir %llu\n"), ino); bad_offset = 1; } - offset = XFS_DIR2_SF_GET_OFFSET(sfep) + - XFS_DIR2_DATA_ENTSIZE(namelen); + offset = xfs_dir2_sf_get_offset(sfep) + + xfs_dir2_data_entsize(namelen); /* * junk the entry by copying up the rest of the @@ -1106,9 +1096,8 @@ process_sf_dir2( if (!no_modify) { tmp_elen = - XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp, sfep); - INT_MOD(dip->di_core.di_size, ARCH_CONVERT, - -(tmp_elen)); + xfs_dir2_sf_entsize_byentry(sfp, sfep); + be64_add_cpu(&dip->di_core.di_size, -tmp_elen); ino_dir_size -= tmp_elen; tmp_sfep = (xfs_dir2_sf_entry_t *) @@ -1118,7 +1107,7 @@ process_sf_dir2( memmove(sfep, tmp_sfep, tmp_len); - INT_MOD(sfp->hdr.count, ARCH_CONVERT, -1); + sfp->hdr.count -= 1; num_entries--; memset((void *) ((__psint_t) sfep + tmp_len), 0, tmp_elen); @@ -1160,25 +1149,25 @@ process_sf_dir2( next_sfep = (tmp_sfep == NULL) ? (xfs_dir2_sf_entry_t *) ((__psint_t) sfep + ((!bad_sfnamelen) - ? XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp, + ? xfs_dir2_sf_entsize_byentry(sfp, sfep) - : XFS_DIR2_SF_ENTSIZE_BYNAME(sfp, + : xfs_dir2_sf_entsize_byname(sfp, namelen))) : tmp_sfep; } /* sync up sizes and entry counts */ - if (INT_GET(sfp->hdr.count, ARCH_CONVERT) != i) { + if (sfp->hdr.count != i) { if (no_modify) { do_warn(_("would have corrected entry count " "in directory %llu from %d to %d\n"), - ino, INT_GET(sfp->hdr.count, ARCH_CONVERT), i); + ino, sfp->hdr.count, i); } else { do_warn(_("corrected entry count in directory %llu, " "was %d, now %d\n"), - ino, INT_GET(sfp->hdr.count, ARCH_CONVERT), i); - INT_SET(sfp->hdr.count, ARCH_CONVERT, i); + ino, sfp->hdr.count, i); + sfp->hdr.count = i; *dino_dirty = 1; *repair = 1; } @@ -1216,17 +1205,14 @@ process_sf_dir2( (__int64_t)((__psint_t)next_sfep - (__psint_t)sfp)); - INT_SET(dip->di_core.di_size, ARCH_CONVERT, - (xfs_fsize_t)((__psint_t)next_sfep - - (__psint_t)sfp)); + dip->di_core.di_size = cpu_to_be64( + (__psint_t)next_sfep - (__psint_t)sfp); *dino_dirty = 1; *repair = 1; } } - if (offset + - (INT_GET(sfp->hdr.count, ARCH_CONVERT) + 2) * - sizeof(xfs_dir2_leaf_entry_t) + - sizeof(xfs_dir2_block_tail_t) > mp->m_dirblksize) { + if (offset + (sfp->hdr.count + 2) * sizeof(xfs_dir2_leaf_entry_t) + + sizeof(xfs_dir2_block_tail_t) > mp->m_dirblksize) { do_warn(_("directory %llu offsets too high\n"), ino); bad_offset = 1; } @@ -1248,7 +1234,7 @@ process_sf_dir2( /* * check parent (..) entry */ - *parent = XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent); + *parent = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); /* * if parent entry is bogus, null it out. we'll fix it later . @@ -1262,7 +1248,7 @@ process_sf_dir2( if (!no_modify) { do_warn(_("clearing inode number\n")); - XFS_DIR2_SF_PUT_INUMBER(sfp, &zero, &sfp->hdr.parent); + xfs_dir2_sf_put_inumber(sfp, &zero, &sfp->hdr.parent); *dino_dirty = 1; *repair = 1; } else { @@ -1277,7 +1263,7 @@ process_sf_dir2( "was %llu, now %llu\n"), ino, *parent, ino); *parent = ino; - XFS_DIR2_SF_PUT_INUMBER(sfp, parent, &sfp->hdr.parent); + xfs_dir2_sf_put_inumber(sfp, parent, &sfp->hdr.parent); *dino_dirty = 1; *repair = 1; } else { @@ -1297,7 +1283,7 @@ process_sf_dir2( if (!no_modify) { do_warn(_("clearing inode number\n")); - XFS_DIR2_SF_PUT_INUMBER(sfp, &zero, &sfp->hdr.parent); + xfs_dir2_sf_put_inumber(sfp, &zero, &sfp->hdr.parent); *dino_dirty = 1; *repair = 1; } else { @@ -1342,25 +1328,26 @@ process_dir2_data( int lastfree; int nm_illegal; char *ptr; + xfs_ino_t ent_ino; d = bp->data; bf = d->hdr.bestfree; ptr = (char *)d->u; badbest = lastfree = freeseen = 0; - if (INT_GET(bf[0].length, ARCH_CONVERT) == 0) { - badbest |= INT_GET(bf[0].offset, ARCH_CONVERT) != 0; + if (be16_to_cpu(bf[0].length) == 0) { + badbest |= be16_to_cpu(bf[0].offset) != 0; freeseen |= 1 << 0; } - if (INT_GET(bf[1].length, ARCH_CONVERT) == 0) { - badbest |= INT_GET(bf[1].offset, ARCH_CONVERT) != 0; + if (be16_to_cpu(bf[1].length) == 0) { + badbest |= be16_to_cpu(bf[1].offset) != 0; freeseen |= 1 << 1; } - if (INT_GET(bf[2].length, ARCH_CONVERT) == 0) { - badbest |= INT_GET(bf[2].offset, ARCH_CONVERT) != 0; + if (be16_to_cpu(bf[2].length) == 0) { + badbest |= be16_to_cpu(bf[2].offset) != 0; freeseen |= 1 << 2; } - badbest |= INT_GET(bf[0].length, ARCH_CONVERT) < INT_GET(bf[1].length, ARCH_CONVERT); - badbest |= INT_GET(bf[1].length, ARCH_CONVERT) < INT_GET(bf[2].length, ARCH_CONVERT); + badbest |= be16_to_cpu(bf[0].length) < be16_to_cpu(bf[1].length); + badbest |= be16_to_cpu(bf[1].length) < be16_to_cpu(bf[2].length); while (ptr < endptr) { dup = (xfs_dir2_data_unused_t *)ptr; /* @@ -1368,13 +1355,13 @@ process_dir2_data( * If we find it, account for that, else make sure it doesn't * need to be there. */ - if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) { - if (ptr + INT_GET(dup->length, ARCH_CONVERT) > endptr || - INT_GET(dup->length, ARCH_CONVERT) == 0 || - (INT_GET(dup->length, ARCH_CONVERT) & (XFS_DIR2_DATA_ALIGN - 1))) + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { + if (ptr + be16_to_cpu(dup->length) > endptr || + be16_to_cpu(dup->length) == 0 || + (be16_to_cpu(dup->length) & (XFS_DIR2_DATA_ALIGN - 1))) break; - if (INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), - ARCH_CONVERT) != (char *)dup - (char *)d) + if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) != + (char *)dup - (char *)d) break; badbest |= lastfree != 0; dfp = xfs_dir2_data_freefind(d, dup); @@ -1383,19 +1370,19 @@ process_dir2_data( badbest |= (freeseen & (1 << i)) != 0; freeseen |= 1 << i; } else - badbest |= INT_GET(dup->length, ARCH_CONVERT) > - INT_GET(bf[2].length, ARCH_CONVERT); - ptr += INT_GET(dup->length, ARCH_CONVERT); + badbest |= be16_to_cpu(dup->length) > + be16_to_cpu(bf[2].length); + ptr += be16_to_cpu(dup->length); lastfree = 1; continue; } dep = (xfs_dir2_data_entry_t *)ptr; - if (ptr + XFS_DIR2_DATA_ENTSIZE(dep->namelen) > endptr) + if (ptr + xfs_dir2_data_entsize(dep->namelen) > endptr) break; - if (INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(dep), ARCH_CONVERT) != - (char *)dep - (char *)d) + if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) != + (char *)dep - (char *)d) break; - ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen); + ptr += xfs_dir2_data_entsize(dep->namelen); lastfree = 0; } /* @@ -1417,83 +1404,85 @@ process_dir2_data( */ while (ptr < endptr) { dup = (xfs_dir2_data_unused_t *)ptr; - if (INT_GET(dup->freetag, ARCH_CONVERT) == - XFS_DIR2_DATA_FREE_TAG) { - ptr += INT_GET(dup->length, ARCH_CONVERT); + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { + ptr += be16_to_cpu(dup->length); continue; } dep = (xfs_dir2_data_entry_t *)ptr; + ent_ino = be64_to_cpu(dep->inumber); + clearino = 1; + clearreason = NULL; /* * We may have to blow out an entry because of bad inode * numbers. Do NOT touch the name until after we've computed * the hashvalue and done a namecheck() on the name. + * + * Conditions must either set clearino to zero or set + * clearreason why it's being cleared. */ - if (!ino_discovery && - INT_GET(dep->inumber, ARCH_CONVERT) == BADFSINO) { + if (!ino_discovery && ent_ino == BADFSINO) { /* * Don't do a damned thing. We already found this * (or did it ourselves) during phase 3. */ clearino = 0; - } else if (verify_inum(mp, INT_GET(dep->inumber, ARCH_CONVERT))) { + } else if (verify_inum(mp, ent_ino)) { /* * Bad inode number. Clear the inode number and the * entry will get removed later. We don't trash the * directory since it's still structurally intact. */ - clearino = 1; clearreason = _("invalid"); - } else if (INT_GET(dep->inumber, ARCH_CONVERT) == mp->m_sb.sb_rbmino) { - clearino = 1; + } else if (ent_ino == mp->m_sb.sb_rbmino) { clearreason = _("realtime bitmap"); - } else if (INT_GET(dep->inumber, ARCH_CONVERT) == mp->m_sb.sb_rsumino) { - clearino = 1; + } else if (ent_ino == mp->m_sb.sb_rsumino) { clearreason = _("realtime summary"); - } else if (INT_GET(dep->inumber, ARCH_CONVERT) == mp->m_sb.sb_uquotino) { - clearino = 1; + } else if (ent_ino == mp->m_sb.sb_uquotino) { clearreason = _("user quota"); - } else if (INT_GET(dep->inumber, ARCH_CONVERT) == mp->m_sb.sb_gquotino) { - clearino = 1; + } else if (ent_ino == mp->m_sb.sb_gquotino) { clearreason = _("group quota"); - } else if ((irec_p = find_inode_rec( - XFS_INO_TO_AGNO(mp, INT_GET(dep->inumber, - ARCH_CONVERT)), - XFS_INO_TO_AGINO(mp, INT_GET(dep->inumber, - ARCH_CONVERT)))) != NULL) { - /* - * Inode recs should have only confirmed inodes in them. - */ - ino_off = XFS_INO_TO_AGINO(mp, INT_GET(dep->inumber, - ARCH_CONVERT)) - irec_p->ino_startnum; - ASSERT(is_inode_confirmed(irec_p, ino_off)); - /* - * If inode is marked free and we're in inode discovery - * mode, leave the entry alone for now. If the inode - * turns out to be used, we'll figure that out when we - * scan it. If the inode really is free, we'll hit this - * code again in phase 4 after we've finished inode - * discovery and blow out the entry then. - */ - if (!ino_discovery && is_inode_free(irec_p, ino_off)) { - clearino = 1; - clearreason = _("free"); - } else - clearino = 0; - } else if (ino_discovery) { - add_inode_uncertain(mp, INT_GET(dep->inumber, ARCH_CONVERT), 0); - clearino = 0; } else { - clearino = 1; - clearreason = _("non-existent"); + irec_p = find_inode_rec(XFS_INO_TO_AGNO(mp, ent_ino), + XFS_INO_TO_AGINO(mp, ent_ino)); + if (irec_p == NULL) { + if (ino_discovery) { + add_inode_uncertain(mp, ent_ino, 0); + clearino = 0; + } else + clearreason = _("non-existent"); + } else { + /* + * Inode recs should have only confirmed + * inodes in them. + */ + ino_off = XFS_INO_TO_AGINO(mp, ent_ino) + - irec_p->ino_startnum; + ASSERT(is_inode_confirmed(irec_p, ino_off)); + /* + * If inode is marked free and we're in inode + * discovery mode, leave the entry alone for + * now. If the inode turns out to be used, + * we'll figure that out when we scan it. + * If the inode really is free, we'll hit this + * code again in phase 4 after we've finished + * inode discovery and blow out the entry then. + */ + if (!ino_discovery && is_inode_free(irec_p, + ino_off)) + clearreason = _("free"); + else + clearino = 0; + } } + ASSERT((clearino == 0 && clearreason == NULL) || + (clearino != 0 && clearreason != NULL)); if (clearino) do_warn(_("entry \"%*.*s\" at block %u offset %d in " "directory inode %llu references %s inode " "%llu\n"), dep->namelen, dep->namelen, dep->name, da_bno, (char *)ptr - (char *)d, ino, - clearreason, - INT_GET(dep->inumber, ARCH_CONVERT)); + clearreason, ent_ino); /* * If the name length is 0 (illegal) make it 1 and blast * the entry. @@ -1514,7 +1503,8 @@ process_dir2_data( do_warn(_("\tclearing inode number in entry at " "offset %d...\n"), (char *)ptr - (char *)d); - INT_SET(dep->inumber, ARCH_CONVERT, BADFSINO); + dep->inumber = cpu_to_be64(BADFSINO); + ent_ino = BADFSINO; bp->dirty = 1; } else { do_warn(_("\twould clear inode number in entry " @@ -1527,7 +1517,7 @@ process_dir2_data( * discovery is turned on). Otherwise, we'd complain a lot * during phase 4. */ - junkit = INT_GET(dep->inumber, ARCH_CONVERT) == BADFSINO; + junkit = ent_ino == BADFSINO; nm_illegal = namecheck((char *)dep->name, dep->namelen); if (ino_discovery && nm_illegal) { do_warn(_("entry at block %u offset %d in directory " @@ -1539,8 +1529,7 @@ process_dir2_data( /* * Now we can mark entries with BADFSINO's bad. */ - if (!no_modify && - INT_GET(dep->inumber, ARCH_CONVERT) == BADFSINO) { + if (!no_modify && ent_ino == BADFSINO) { dep->name[0] = '/'; bp->dirty = 1; junkit = 0; @@ -1552,14 +1541,14 @@ process_dir2_data( dep->name[0] == '.' && dep->name[1] == '.') { if (!*dotdot) { (*dotdot)++; - *parent = INT_GET(dep->inumber, ARCH_CONVERT); + *parent = ent_ino; /* * What if .. == .? Legal only in the root * inode. Blow out entry and set parent to * NULLFSINO otherwise. */ - if (ino == INT_GET(dep->inumber, ARCH_CONVERT) && - ino != mp->m_sb.sb_rootino) { + if (ino == ent_ino && + ino != mp->m_sb.sb_rootino) { *parent = NULLFSINO; do_warn(_("bad .. entry in directory " "inode %llu, points to self: "), @@ -1570,15 +1559,15 @@ process_dir2_data( * We have to make sure that . == .. in the * root inode. */ - else if (ino != INT_GET(dep->inumber, ARCH_CONVERT) && - ino == mp->m_sb.sb_rootino) { + else if (ino != ent_ino && + ino == mp->m_sb.sb_rootino) { do_warn(_("bad .. entry in root " "directory inode %llu, was " "%llu: "), - ino, INT_GET(dep->inumber, ARCH_CONVERT)); + ino, ent_ino); if (!no_modify) { do_warn(_("correcting\n")); - INT_SET(dep->inumber, ARCH_CONVERT, ino); + dep->inumber = cpu_to_be64(ino); bp->dirty = 1; } else { do_warn(_("would correct\n")); @@ -1604,13 +1593,13 @@ process_dir2_data( else if (dep->namelen == 1 && dep->name[0] == '.') { if (!*dot) { (*dot)++; - if (INT_GET(dep->inumber, ARCH_CONVERT) != ino) { + if (ent_ino != ino) { do_warn(_("bad . entry in directory " "inode %llu, was %llu: "), - ino, INT_GET(dep->inumber, ARCH_CONVERT)); + ino, ent_ino); if (!no_modify) { do_warn(_("correcting\n")); - INT_SET(dep->inumber, ARCH_CONVERT, ino); + dep->inumber = cpu_to_be64(ino); bp->dirty = 1; } else { do_warn(_("would correct\n")); @@ -1626,7 +1615,7 @@ process_dir2_data( /* * All other entries -- make sure only . references self. */ - else if (INT_GET(dep->inumber, ARCH_CONVERT) == ino) { + else if (ent_ino == ino) { do_warn(_("entry \"%*.*s\" in directory inode %llu " "points to self: "), dep->namelen, dep->namelen, dep->name, ino); @@ -1647,18 +1636,17 @@ process_dir2_data( /* * Advance to the next entry. */ - ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen); + ptr += xfs_dir2_data_entsize(dep->namelen); } /* * Check the bestfree table. */ if (freeseen != 7 || badbest) { do_warn(_("bad bestfree table in block %u in directory inode " - "%llu: "), - da_bno, ino); + "%llu: "), da_bno, ino); if (!no_modify) { do_warn(_("repairing table\n")); - libxfs_dir2_data_freescan(mp, d, &i, endptr); + libxfs_dir2_data_freescan(mp, d, &i); bp->dirty = 1; } else { do_warn(_("would repair table\n")); @@ -1714,17 +1702,16 @@ process_block_dir2( * Verify the block */ block = bp->data; - if (INT_GET(block->hdr.magic, ARCH_CONVERT) != XFS_DIR2_BLOCK_MAGIC) + if (be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC) do_warn(_("bad directory block magic # %#x in block %u for " "directory inode %llu\n"), - INT_GET(block->hdr.magic, ARCH_CONVERT), - mp->m_dirdatablk, ino); + be32_to_cpu(block->hdr.magic), mp->m_dirdatablk, ino); /* * process the data area * this also checks & fixes the bestfree */ - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); - blp = XFS_DIR2_BLOCK_LEAF_P(btp); + btp = xfs_dir2_block_tail_p(mp, block); + blp = xfs_dir2_block_leaf_p(btp); /* * Don't let this go past the end of the block. */ @@ -1758,27 +1745,25 @@ process_leaf_block_dir2( int i; int stale; - for (i = stale = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); i++) { + for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { if ((char *)&leaf->ents[i] >= (char *)leaf + mp->m_dirblksize) { do_warn(_("bad entry count in block %u of directory " "inode %llu\n"), da_bno, ino); return 1; } - if (INT_GET(leaf->ents[i].address, ARCH_CONVERT) == - XFS_DIR2_NULL_DATAPTR) + if (be32_to_cpu(leaf->ents[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; - else if (INT_GET(leaf->ents[i].hashval, ARCH_CONVERT) < - last_hashval) { + else if (be32_to_cpu(leaf->ents[i].hashval) < last_hashval) { do_warn(_("bad hash ordering in block %u of directory " "inode %llu\n"), da_bno, ino); return 1; } *next_hashval = last_hashval = - INT_GET(leaf->ents[i].hashval, ARCH_CONVERT); + be32_to_cpu(leaf->ents[i].hashval); } - if (stale != INT_GET(leaf->hdr.stale, ARCH_CONVERT)) { + if (stale != be16_to_cpu(leaf->hdr.stale)) { do_warn(_("bad stale count in block %u of directory " "inode %llu\n"), da_bno, ino); @@ -1846,11 +1831,11 @@ process_leaf_level_dir2( /* * Check magic number for leaf directory btree block. */ - if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != + if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAFN_MAGIC) { do_warn(_("bad directory leaf magic # %#x for " "directory inode %llu block %u\n"), - INT_GET(leaf->hdr.info.magic, ARCH_CONVERT), + be16_to_cpu(leaf->hdr.info.magic), ino, da_bno); da_brelse(bp); goto error_out; @@ -1874,10 +1859,10 @@ process_leaf_level_dir2( da_cursor->level[0].bp = bp; da_cursor->level[0].bno = da_bno; da_cursor->level[0].index = - INT_GET(leaf->hdr.count, ARCH_CONVERT); + be16_to_cpu(leaf->hdr.count); da_cursor->level[0].dirty = buf_dirty; - if (INT_GET(leaf->hdr.info.back, ARCH_CONVERT) != prev_bno) { + if (be32_to_cpu(leaf->hdr.info.back) != prev_bno) { do_warn(_("bad sibling back pointer for block %u in " "directory inode %llu\n"), da_bno, ino); @@ -1885,7 +1870,7 @@ process_leaf_level_dir2( goto error_out; } prev_bno = da_bno; - da_bno = INT_GET(leaf->hdr.info.forw, ARCH_CONVERT); + da_bno = be32_to_cpu(leaf->hdr.info.forw); if (da_bno != 0) { if (verify_dir2_path(mp, da_cursor, 0)) { da_brelse(bp); @@ -2023,12 +2008,10 @@ process_leaf_node_dir2( continue; } data = bp->data; - if (INT_GET(data->hdr.magic, ARCH_CONVERT) != - XFS_DIR2_DATA_MAGIC) + if (be32_to_cpu(data->hdr.magic) != XFS_DIR2_DATA_MAGIC) do_warn(_("bad directory block magic # %#x in block " "%llu for directory inode %llu\n"), - INT_GET(data->hdr.magic, ARCH_CONVERT), - dbno, ino); + be32_to_cpu(data->hdr.magic), dbno, ino); i = process_dir2_data(mp, ino, dip, ino_discovery, dirname, parent, bp, dot, dotdot, (xfs_dablk_t)dbno, (char *)data + mp->m_dirblksize); @@ -2086,21 +2069,20 @@ process_dir2( */ if (blkmap) last = blkmap_last_off(blkmap); - if (INT_GET(dip->di_core.di_size, ARCH_CONVERT) <= - XFS_DFORK_DSIZE(dip, mp) && - dip->di_core.di_format == XFS_DINODE_FMT_LOCAL) { + if (be64_to_cpu(dip->di_core.di_size) <= XFS_DFORK_DSIZE(dip, mp) && + dip->di_core.di_format == XFS_DINODE_FMT_LOCAL) { dot = dotdot = 1; res = process_sf_dir2(mp, ino, dip, ino_discovery, dino_dirty, dirname, parent, &repair); } else if (last == mp->m_dirblkfsbs && - (dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS || - dip->di_core.di_format == XFS_DINODE_FMT_BTREE)) { + (dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS || + dip->di_core.di_format == XFS_DINODE_FMT_BTREE)) { res = process_block_dir2(mp, ino, dip, ino_discovery, dino_dirty, dirname, parent, blkmap, &dot, &dotdot, &repair); } else if (last >= mp->m_dirleafblk + mp->m_dirblkfsbs && - (dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS || - dip->di_core.di_format == XFS_DINODE_FMT_BTREE)) { + (dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS || + dip->di_core.di_format == XFS_DINODE_FMT_BTREE)) { res = process_leaf_node_dir2(mp, ino, dip, ino_discovery, dirname, parent, blkmap, &dot, &dotdot, &repair, last > mp->m_dirleafblk + mp->m_dirblkfsbs); diff --git a/repair/phase2.c b/repair/phase2.c index d4ceceafa..170a1953f 100644 --- a/repair/phase2.c +++ b/repair/phase2.c @@ -50,18 +50,18 @@ zero_log(xfs_mount_t *mp) log.l_logBBsize = x.logBBsize; log.l_logBBstart = x.logBBstart; log.l_mp = mp; - if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb)) { + if (xfs_sb_version_hassector(&mp->m_sb)) { log.l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT; ASSERT(log.l_sectbb_log <= mp->m_sectbb_log); /* for larger sector sizes, must have v2 or external log */ ASSERT(log.l_sectbb_log == 0 || log.l_logBBstart == 0 || - XFS_SB_VERSION_HASLOGV2(&mp->m_sb)); + xfs_sb_version_haslogv2(&mp->m_sb)); ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT); } log.l_sectbb_mask = (1 << log.l_sectbb_log) - 1; - if ((error = xlog_find_tail(&log, &head_blk, &tail_blk, 0))) { + if ((error = xlog_find_tail(&log, &head_blk, &tail_blk))) { do_warn(_("zero_log: cannot find log head/tail " "(xlog_find_tail=%d), zeroing it anyway\n"), error); @@ -92,7 +92,7 @@ zero_log(xfs_mount_t *mp) XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), &mp->m_sb.sb_uuid, - XFS_SB_VERSION_HASLOGV2(&mp->m_sb) ? 2 : 1, + xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, mp->m_sb.sb_logsunit, XLOG_FMT); } diff --git a/repair/phase3.c b/repair/phase3.c index 016beb723..c36a1c56a 100644 --- a/repair/phase3.c +++ b/repair/phase3.c @@ -91,7 +91,7 @@ walk_unlinked_list(xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agino_t start_ino) } pthread_mutex_unlock(&ag_locks[agno]); } - current_ino = dip->di_next_unlinked; + current_ino = be32_to_cpu(dip->di_next_unlinked); } else { current_ino = NULLAGINO;; } @@ -119,18 +119,17 @@ process_agi_unlinked(xfs_mount_t *mp, xfs_agnumber_t agno) agip = XFS_BUF_TO_AGI(bp); - ASSERT(no_modify || INT_GET(agip->agi_seqno, ARCH_CONVERT) == agno); + ASSERT(no_modify || be32_to_cpu(agip->agi_seqno) == agno); for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) { - if (INT_GET(agip->agi_unlinked[i], ARCH_CONVERT) != NULLAGINO) { - err += walk_unlinked_list(mp, agno, INT_GET( - agip->agi_unlinked[i], ARCH_CONVERT)); + if (be32_to_cpu(agip->agi_unlinked[i]) != NULLAGINO) { + err += walk_unlinked_list(mp, agno, + be32_to_cpu(agip->agi_unlinked[i])); /* * clear the list */ if (!no_modify) { - INT_SET(agip->agi_unlinked[i], ARCH_CONVERT, - NULLAGINO); + agip->agi_unlinked[i] = cpu_to_be32(NULLAGINO); agi_dirty = 1; } } diff --git a/repair/phase5.c b/repair/phase5.c index f54c4686c..69314f546 100644 --- a/repair/phase5.c +++ b/repair/phase5.c @@ -646,7 +646,7 @@ prop_freespace_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, lptr = &btree_curs->level[level]; bt_hdr = XFS_BUF_TO_ALLOC_BLOCK(lptr->buf_p); - if (INT_GET(bt_hdr->bb_numrecs, ARCH_CONVERT) == 0) { + if (be16_to_cpu(bt_hdr->bb_numrecs) == 0) { /* * only happens once when initializing the * left-hand side of the tree. @@ -655,8 +655,8 @@ prop_freespace_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, blockcount, level, magic); } - if (INT_GET(bt_hdr->bb_numrecs, ARCH_CONVERT) == - lptr->num_recs_pb + (lptr->modulo > 0)) { + if (be16_to_cpu(bt_hdr->bb_numrecs) == + lptr->num_recs_pb + (lptr->modulo > 0)) { /* * write out current prev block, grab us a new block, * and set the rightsib pointer of current block @@ -672,7 +672,7 @@ prop_freespace_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, lptr->prev_buf_p = lptr->buf_p; agbno = get_next_blockaddr(agno, level, btree_curs); - INT_SET(bt_hdr->bb_rightsib, ARCH_CONVERT, agbno); + bt_hdr->bb_rightsib = cpu_to_be32(agbno); lptr->buf_p = libxfs_getbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, agbno), @@ -688,10 +688,10 @@ prop_freespace_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_hdr = XFS_BUF_TO_ALLOC_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); - INT_SET(bt_hdr->bb_magic, ARCH_CONVERT, magic); - INT_SET(bt_hdr->bb_level, ARCH_CONVERT, level); - INT_SET(bt_hdr->bb_leftsib, ARCH_CONVERT, lptr->prev_agbno); - INT_SET(bt_hdr->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK); + bt_hdr->bb_magic = cpu_to_be32(magic); + bt_hdr->bb_level = cpu_to_be16(level); + bt_hdr->bb_leftsib = cpu_to_be32(lptr->prev_agbno); + bt_hdr->bb_rightsib = cpu_to_be32(NULLAGBLOCK); bt_hdr->bb_numrecs = 0; /* @@ -703,16 +703,14 @@ prop_freespace_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, /* * add extent info to current block */ - INT_MOD(bt_hdr->bb_numrecs, ARCH_CONVERT, +1); + be16_add_cpu(&bt_hdr->bb_numrecs, 1); - bt_key = XR_ALLOC_KEY_ADDR(mp, bt_hdr, - INT_GET(bt_hdr->bb_numrecs, ARCH_CONVERT)); - bt_ptr = XR_ALLOC_PTR_ADDR(mp, bt_hdr, - INT_GET(bt_hdr->bb_numrecs, ARCH_CONVERT)); + bt_key = XR_ALLOC_KEY_ADDR(mp, bt_hdr, be16_to_cpu(bt_hdr->bb_numrecs)); + bt_ptr = XR_ALLOC_PTR_ADDR(mp, bt_hdr, be16_to_cpu(bt_hdr->bb_numrecs)); - INT_SET(bt_key->ar_startblock, ARCH_CONVERT, startblock); - INT_SET(bt_key->ar_blockcount, ARCH_CONVERT, blockcount); - INT_SET(*bt_ptr, ARCH_CONVERT, btree_curs->level[level-1].agbno); + bt_key->ar_startblock = cpu_to_be32(startblock); + bt_key->ar_blockcount = cpu_to_be32(blockcount); + *bt_ptr = cpu_to_be32(btree_curs->level[level-1].agbno); } /* @@ -765,10 +763,10 @@ build_freespace_tree(xfs_mount_t *mp, xfs_agnumber_t agno, bt_hdr = XFS_BUF_TO_ALLOC_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); - INT_SET(bt_hdr->bb_magic, ARCH_CONVERT, magic); - INT_SET(bt_hdr->bb_level, ARCH_CONVERT, i); - INT_SET(bt_hdr->bb_leftsib, ARCH_CONVERT, - bt_hdr->bb_rightsib = NULLAGBLOCK); + bt_hdr->bb_magic = cpu_to_be32(magic); + bt_hdr->bb_level = cpu_to_be16(i); + bt_hdr->bb_leftsib = cpu_to_be32(NULLAGBLOCK); + bt_hdr->bb_rightsib = cpu_to_be32(NULLAGBLOCK); bt_hdr->bb_numrecs = 0; } /* @@ -796,15 +794,15 @@ build_freespace_tree(xfs_mount_t *mp, xfs_agnumber_t agno, bt_hdr = XFS_BUF_TO_ALLOC_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); - INT_SET(bt_hdr->bb_magic, ARCH_CONVERT, magic); + bt_hdr->bb_magic = cpu_to_be32(magic); bt_hdr->bb_level = 0; - INT_SET(bt_hdr->bb_leftsib, ARCH_CONVERT, lptr->prev_agbno); - INT_SET(bt_hdr->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK); - INT_SET(bt_hdr->bb_numrecs, ARCH_CONVERT, - lptr->num_recs_pb + (lptr->modulo > 0)); + bt_hdr->bb_leftsib = cpu_to_be32(lptr->prev_agbno); + bt_hdr->bb_rightsib = cpu_to_be32(NULLAGBLOCK); + bt_hdr->bb_numrecs = cpu_to_be16(lptr->num_recs_pb + + (lptr->modulo > 0)); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "bft, bb_numrecs = %d\n", - INT_GET(bt_hdr->bb_numrecs, ARCH_CONVERT)); + be16_to_cpu(bt_hdr->bb_numrecs)); #endif if (lptr->modulo > 0) @@ -822,12 +820,12 @@ build_freespace_tree(xfs_mount_t *mp, xfs_agnumber_t agno, bt_rec = (xfs_alloc_rec_t *) ((char *) bt_hdr + sizeof(xfs_alloc_block_t)); - for (j = 0; j < INT_GET(bt_hdr->bb_numrecs,ARCH_CONVERT); j++) { + for (j = 0; j < be16_to_cpu(bt_hdr->bb_numrecs); j++) { ASSERT(ext_ptr != NULL); - INT_SET(bt_rec[j].ar_startblock, ARCH_CONVERT, - ext_ptr->ex_startblock); - INT_SET(bt_rec[j].ar_blockcount, ARCH_CONVERT, - ext_ptr->ex_blockcount); + bt_rec[j].ar_startblock = cpu_to_be32( + ext_ptr->ex_startblock); + bt_rec[j].ar_blockcount = cpu_to_be32( + ext_ptr->ex_blockcount); freeblks += ext_ptr->ex_blockcount; if (magic == XFS_ABTB_MAGIC) ext_ptr = findnext_bno_extent(ext_ptr); @@ -861,9 +859,8 @@ build_freespace_tree(xfs_mount_t *mp, xfs_agnumber_t agno, } lptr->prev_buf_p = lptr->buf_p; lptr->prev_agbno = lptr->agbno; - - INT_SET(bt_hdr->bb_rightsib, ARCH_CONVERT, lptr->agbno = - get_next_blockaddr(agno, 0, btree_curs)); + lptr->agbno = get_next_blockaddr(agno, 0, btree_curs); + bt_hdr->bb_rightsib = cpu_to_be32(lptr->agbno); lptr->buf_p = libxfs_getbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, lptr->agbno), @@ -1003,7 +1000,7 @@ prop_ino_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, lptr = &btree_curs->level[level]; bt_hdr = XFS_BUF_TO_INOBT_BLOCK(lptr->buf_p); - if (INT_GET(bt_hdr->bb_numrecs, ARCH_CONVERT) == 0) { + if (be16_to_cpu(bt_hdr->bb_numrecs) == 0) { /* * this only happens once to initialize the * first path up the left side of the tree @@ -1012,7 +1009,7 @@ prop_ino_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, prop_ino_cursor(mp, agno, btree_curs, startino, level); } - if (INT_GET(bt_hdr->bb_numrecs, ARCH_CONVERT) == + if (be16_to_cpu(bt_hdr->bb_numrecs) == lptr->num_recs_pb + (lptr->modulo > 0)) { /* * write out current prev block, grab us a new block, @@ -1029,7 +1026,7 @@ prop_ino_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, lptr->prev_buf_p = lptr->buf_p; agbno = get_next_blockaddr(agno, level, btree_curs); - INT_SET(bt_hdr->bb_rightsib, ARCH_CONVERT, agbno); + bt_hdr->bb_rightsib = cpu_to_be32(agbno); lptr->buf_p = libxfs_getbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, agbno), @@ -1045,10 +1042,10 @@ prop_ino_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, bt_hdr = XFS_BUF_TO_INOBT_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); - INT_SET(bt_hdr->bb_magic, ARCH_CONVERT, XFS_IBT_MAGIC); - INT_SET(bt_hdr->bb_level, ARCH_CONVERT, level); - INT_SET(bt_hdr->bb_leftsib, ARCH_CONVERT, lptr->prev_agbno); - INT_SET(bt_hdr->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK); + bt_hdr->bb_magic = cpu_to_be32(XFS_IBT_MAGIC); + bt_hdr->bb_level = cpu_to_be16(level); + bt_hdr->bb_leftsib = cpu_to_be32(lptr->prev_agbno); + bt_hdr->bb_rightsib = cpu_to_be32(NULLAGBLOCK); bt_hdr->bb_numrecs = 0; /* * propagate extent record for first extent in new block up @@ -1058,15 +1055,13 @@ prop_ino_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, /* * add inode info to current block */ - INT_MOD(bt_hdr->bb_numrecs, ARCH_CONVERT, +1); + be16_add_cpu(&bt_hdr->bb_numrecs, 1); - bt_key = XR_INOBT_KEY_ADDR(mp, bt_hdr, - INT_GET(bt_hdr->bb_numrecs, ARCH_CONVERT)); - bt_ptr = XR_INOBT_PTR_ADDR(mp, bt_hdr, - INT_GET(bt_hdr->bb_numrecs, ARCH_CONVERT)); + bt_key = XR_INOBT_KEY_ADDR(mp, bt_hdr, be16_to_cpu(bt_hdr->bb_numrecs)); + bt_ptr = XR_INOBT_PTR_ADDR(mp, bt_hdr, be16_to_cpu(bt_hdr->bb_numrecs)); - INT_SET(bt_key->ir_startino, ARCH_CONVERT, startino); - INT_SET(*bt_ptr, ARCH_CONVERT, btree_curs->level[level-1].agbno); + bt_key->ir_startino = cpu_to_be32(startino); + *bt_ptr = cpu_to_be32(btree_curs->level[level-1].agbno); } void @@ -1084,24 +1079,23 @@ build_agi(xfs_mount_t *mp, xfs_agnumber_t agno, agi = XFS_BUF_TO_AGI(agi_buf); memset(agi, 0, mp->m_sb.sb_sectsize); - INT_SET(agi->agi_magicnum, ARCH_CONVERT, XFS_AGI_MAGIC); - INT_SET(agi->agi_versionnum, ARCH_CONVERT, XFS_AGI_VERSION); - INT_SET(agi->agi_seqno, ARCH_CONVERT, agno); + agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); + agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION); + agi->agi_seqno = cpu_to_be32(agno); if (agno < mp->m_sb.sb_agcount - 1) - INT_SET(agi->agi_length, ARCH_CONVERT, mp->m_sb.sb_agblocks); + agi->agi_length = cpu_to_be32(mp->m_sb.sb_agblocks); else - INT_SET(agi->agi_length, ARCH_CONVERT, mp->m_sb.sb_dblocks - + agi->agi_length = cpu_to_be32(mp->m_sb.sb_dblocks - (xfs_drfsbno_t) mp->m_sb.sb_agblocks * agno); - INT_SET(agi->agi_count, ARCH_CONVERT, count); - INT_SET(agi->agi_root, ARCH_CONVERT, btree_curs->root); - INT_SET(agi->agi_level, ARCH_CONVERT, btree_curs->num_levels); - INT_SET(agi->agi_freecount, ARCH_CONVERT, freecount); - INT_SET(agi->agi_newino, ARCH_CONVERT, first_agino); - INT_SET(agi->agi_dirino, ARCH_CONVERT, NULLAGINO); - - for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) { - INT_SET(agi->agi_unlinked[i], ARCH_CONVERT, NULLAGINO); - } + agi->agi_count = cpu_to_be32(count); + agi->agi_root = cpu_to_be32(btree_curs->root); + agi->agi_level = cpu_to_be32(btree_curs->num_levels); + agi->agi_freecount = cpu_to_be32(freecount); + agi->agi_newino = cpu_to_be32(first_agino); + agi->agi_dirino = cpu_to_be32(NULLAGINO); + + for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) + agi->agi_unlinked[i] = cpu_to_be32(NULLAGINO); libxfs_writebuf(agi_buf, 0); } @@ -1148,10 +1142,10 @@ build_ino_tree(xfs_mount_t *mp, xfs_agnumber_t agno, bt_hdr = XFS_BUF_TO_INOBT_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); - INT_SET(bt_hdr->bb_magic, ARCH_CONVERT, XFS_IBT_MAGIC); - INT_SET(bt_hdr->bb_level, ARCH_CONVERT, i); - INT_SET(bt_hdr->bb_leftsib, ARCH_CONVERT, - bt_hdr->bb_rightsib = NULLAGBLOCK); + bt_hdr->bb_magic = cpu_to_be32(XFS_IBT_MAGIC); + bt_hdr->bb_level = cpu_to_be16(i); + bt_hdr->bb_leftsib = cpu_to_be32(NULLAGBLOCK); + bt_hdr->bb_rightsib = cpu_to_be32(NULLAGBLOCK); bt_hdr->bb_numrecs = 0; } /* @@ -1176,12 +1170,12 @@ build_ino_tree(xfs_mount_t *mp, xfs_agnumber_t agno, bt_hdr = XFS_BUF_TO_INOBT_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); - INT_SET(bt_hdr->bb_magic, ARCH_CONVERT, XFS_IBT_MAGIC); + bt_hdr->bb_magic = cpu_to_be32(XFS_IBT_MAGIC); bt_hdr->bb_level = 0; - INT_SET(bt_hdr->bb_leftsib, ARCH_CONVERT, lptr->prev_agbno); - INT_SET(bt_hdr->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK); - INT_SET(bt_hdr->bb_numrecs, ARCH_CONVERT, - lptr->num_recs_pb + (lptr->modulo > 0)); + bt_hdr->bb_leftsib = cpu_to_be32(lptr->prev_agbno); + bt_hdr->bb_rightsib = cpu_to_be32(NULLAGBLOCK); + bt_hdr->bb_numrecs = cpu_to_be16(lptr->num_recs_pb + + (lptr->modulo > 0)); if (lptr->modulo > 0) lptr->modulo--; @@ -1192,12 +1186,11 @@ build_ino_tree(xfs_mount_t *mp, xfs_agnumber_t agno, bt_rec = (xfs_inobt_rec_t *) ((char *) bt_hdr + sizeof(xfs_inobt_block_t)); - for (j = 0; j < INT_GET(bt_hdr->bb_numrecs,ARCH_CONVERT); j++) { + for (j = 0; j < be16_to_cpu(bt_hdr->bb_numrecs); j++) { ASSERT(ino_rec != NULL); - INT_SET(bt_rec[j].ir_startino, ARCH_CONVERT, - ino_rec->ino_startnum); - INT_SET(bt_rec[j].ir_free, ARCH_CONVERT, - ino_rec->ir_free); + bt_rec[j].ir_startino = + cpu_to_be32(ino_rec->ino_startnum); + bt_rec[j].ir_free = cpu_to_be64(ino_rec->ir_free); inocnt = 0; for (k = 0; k < sizeof(xfs_inofree_t)*NBBY; k++) { @@ -1205,7 +1198,7 @@ build_ino_tree(xfs_mount_t *mp, xfs_agnumber_t agno, inocnt += is_inode_free(ino_rec, k); } - INT_SET(bt_rec[j].ir_freecount, ARCH_CONVERT, inocnt); + bt_rec[j].ir_freecount = cpu_to_be32(inocnt); freecount += inocnt; count += XFS_INODES_PER_CHUNK; ino_rec = next_ino_rec(ino_rec); @@ -1225,9 +1218,8 @@ build_ino_tree(xfs_mount_t *mp, xfs_agnumber_t agno, } lptr->prev_buf_p = lptr->buf_p; lptr->prev_agbno = lptr->agbno; - - INT_SET(bt_hdr->bb_rightsib, ARCH_CONVERT, lptr->agbno= - get_next_blockaddr(agno, 0, btree_curs)); + lptr->agbno = get_next_blockaddr(agno, 0, btree_curs); + bt_hdr->bb_rightsib = cpu_to_be32(lptr->agbno); lptr->buf_p = libxfs_getbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, lptr->agbno), @@ -1271,46 +1263,44 @@ build_agf_agfl(xfs_mount_t *mp, /* * set up fixed part of agf */ - INT_SET(agf->agf_magicnum, ARCH_CONVERT, XFS_AGF_MAGIC); - INT_SET(agf->agf_versionnum, ARCH_CONVERT, XFS_AGF_VERSION); - INT_SET(agf->agf_seqno, ARCH_CONVERT, agno); + agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC); + agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION); + agf->agf_seqno = cpu_to_be32(agno); if (agno < mp->m_sb.sb_agcount - 1) - INT_SET(agf->agf_length, ARCH_CONVERT, mp->m_sb.sb_agblocks); + agf->agf_length = cpu_to_be32(mp->m_sb.sb_agblocks); else - INT_SET(agf->agf_length, ARCH_CONVERT, mp->m_sb.sb_dblocks - + agf->agf_length = cpu_to_be32(mp->m_sb.sb_dblocks - (xfs_drfsbno_t) mp->m_sb.sb_agblocks * agno); - INT_SET(agf->agf_roots[XFS_BTNUM_BNO], ARCH_CONVERT, bno_bt->root); - INT_SET(agf->agf_levels[XFS_BTNUM_BNO], ARCH_CONVERT, - bno_bt->num_levels); - INT_SET(agf->agf_roots[XFS_BTNUM_CNT], ARCH_CONVERT, bcnt_bt->root); - INT_SET(agf->agf_levels[XFS_BTNUM_CNT], ARCH_CONVERT, - bcnt_bt->num_levels); - INT_SET(agf->agf_freeblks, ARCH_CONVERT, freeblks); + agf->agf_roots[XFS_BTNUM_BNO] = cpu_to_be32(bno_bt->root); + agf->agf_levels[XFS_BTNUM_BNO] = cpu_to_be32(bno_bt->num_levels); + agf->agf_roots[XFS_BTNUM_CNT] = cpu_to_be32(bcnt_bt->root); + agf->agf_levels[XFS_BTNUM_CNT] = cpu_to_be32(bcnt_bt->num_levels); + agf->agf_freeblks = cpu_to_be32(freeblks); /* * Count and record the number of btree blocks consumed if required. */ - if (XFS_SB_VERSION_LAZYSBCOUNT(&mp->m_sb)) { + if (xfs_sb_version_haslazysbcount(&mp->m_sb)) { /* * Don't count the root blocks as they are already * accounted for. */ - INT_SET(agf->agf_btreeblks, ARCH_CONVERT, + agf->agf_btreeblks = cpu_to_be32( (bno_bt->num_tot_blocks - bno_bt->num_free_blocks) + (bcnt_bt->num_tot_blocks - bcnt_bt->num_free_blocks) - 2); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "agf->agf_btreeblks = %u\n", - INT_GET(agf->agf_btreeblks, ARCH_CONVERT)); + be32_to_cpu(agf->agf_btreeblks)); #endif } #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "bno root = %u, bcnt root = %u, indices = %u %u\n", - INT_GET(agf->agf_roots[XFS_BTNUM_BNO], ARCH_CONVERT), - INT_GET(agf->agf_roots[XFS_BTNUM_CNT], ARCH_CONVERT), + be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]), + be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]), XFS_BTNUM_BNO, XFS_BTNUM_CNT); #endif @@ -1333,14 +1323,14 @@ build_agf_agfl(xfs_mount_t *mp, */ i = j = 0; while (bno_bt->num_free_blocks > 0 && i < XFS_AGFL_SIZE(mp)) { - INT_SET(agfl->agfl_bno[i], ARCH_CONVERT, - get_next_blockaddr(agno, 0, bno_bt)); + agfl->agfl_bno[i] = cpu_to_be32( + get_next_blockaddr(agno, 0, bno_bt)); i++; } while (bcnt_bt->num_free_blocks > 0 && i < XFS_AGFL_SIZE(mp)) { - INT_SET(agfl->agfl_bno[i], ARCH_CONVERT, - get_next_blockaddr(agno, 0, bcnt_bt)); + agfl->agfl_bno[i] = cpu_to_be32( + get_next_blockaddr(agno, 0, bcnt_bt)); i++; } /* @@ -1367,8 +1357,8 @@ build_agf_agfl(xfs_mount_t *mp, } agf->agf_flfirst = 0; - INT_SET(agf->agf_fllast, ARCH_CONVERT, i - 1); - INT_SET(agf->agf_flcount, ARCH_CONVERT, i); + agf->agf_fllast = cpu_to_be32(i - 1); + agf->agf_flcount = cpu_to_be32(i); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "writing agfl for ag %u\n", agno); @@ -1377,16 +1367,16 @@ build_agf_agfl(xfs_mount_t *mp, libxfs_writebuf(agfl_buf, 0); } else { agf->agf_flfirst = 0; - INT_SET(agf->agf_fllast, ARCH_CONVERT, XFS_AGFL_SIZE(mp) - 1); + agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1); agf->agf_flcount = 0; } ext_ptr = findbiggest_bcnt_extent(agno); - INT_SET(agf->agf_longest, ARCH_CONVERT, - (ext_ptr != NULL) ? ext_ptr->ex_blockcount : 0); + agf->agf_longest = cpu_to_be32((ext_ptr != NULL) ? + ext_ptr->ex_blockcount : 0); - ASSERT(INT_GET(agf->agf_roots[XFS_BTNUM_BNOi], ARCH_CONVERT) != - INT_GET(agf->agf_roots[XFS_BTNUM_CNTi], ARCH_CONVERT)); + ASSERT(be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNOi]) != + be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNTi])); libxfs_writebuf(agf_buf, 0); @@ -1403,15 +1393,12 @@ build_agf_agfl(xfs_mount_t *mp, void sync_sb(xfs_mount_t *mp) { - xfs_sb_t *sbp; xfs_buf_t *bp; bp = libxfs_getsb(mp, 0); if (!bp) do_error(_("couldn't get superblock\n")); - sbp = XFS_BUF_TO_SBP(bp); - mp->m_sb.sb_icount = sb_icount; mp->m_sb.sb_ifree = sb_ifree; mp->m_sb.sb_fdblocks = sb_fdblocks; @@ -1419,8 +1406,7 @@ sync_sb(xfs_mount_t *mp) update_sb_version(mp); - *sbp = mp->m_sb; - libxfs_xlate_sb(XFS_BUF_PTR(bp), sbp, -1, XFS_SB_ALL_BITS); + libxfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, XFS_SB_ALL_BITS); libxfs_writebuf(bp, 0); } diff --git a/repair/phase6.c b/repair/phase6.c index 8fe1c9c7a..c9c8e138f 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -35,6 +35,8 @@ static struct cred zerocr; static struct fsxattr zerofsx; static xfs_ino_t orphanage_ino; +static struct xfs_name xfs_name_dot = {".", 1}; + /* * Data structures used to keep track of directories where the ".." * entries are updated. These must be rebuilt after the initial pass @@ -83,8 +85,7 @@ typedef struct dir_hash_ent { xfs_ino_t inum; /* inode num of entry */ short junkit; /* name starts with / */ short seen; /* have seen leaf entry */ - int namelen; /* length of name */ - uchar_t *name; /* pointer to name (no NULL) */ + struct xfs_name name; } dir_hash_ent_t; typedef struct dir_hash_tab { @@ -132,7 +133,7 @@ dir_hash_add( __uint32_t addr, xfs_ino_t inum, int namelen, - uchar_t *name) + char *name) { xfs_dahash_t hash = 0; int byaddr; @@ -140,23 +141,27 @@ dir_hash_add( dir_hash_ent_t *p; int dup; short junk; + struct xfs_name xname; ASSERT(!hashtab->names_duped); + xname.name = name; + xname.len = namelen; + junk = name[0] == '/'; byaddr = DIR_HASH_FUNC(hashtab, addr); dup = 0; if (!junk) { - hash = mp->m_dirnameops->hashname(name, namelen); + hash = mp->m_dirnameops->hashname(&xname); byhash = DIR_HASH_FUNC(hashtab, hash); /* * search hash bucket for existing name. */ for (p = hashtab->byhash[byhash]; p; p = p->nextbyhash) { - if (p->hashval == hash && p->namelen == namelen) { - if (memcmp(p->name, name, namelen) == 0) { + if (p->hashval == hash && p->name.len == namelen) { + if (memcmp(p->name.name, name, namelen) == 0) { dup = 1; junk = 1; break; @@ -186,8 +191,7 @@ dir_hash_add( p->address = addr; p->inum = inum; p->seen = 0; - p->namelen = namelen; - p->name = name; + p->name = xname; return !dup; } @@ -255,7 +259,7 @@ dir_hash_done( for (p = hashtab->byaddr[i]; p; p = n) { n = p->nextbyaddr; if (hashtab->names_duped) - free(p->name); + free((void *)p->name.name); free(p); } } @@ -323,11 +327,12 @@ dir_hash_see_all( int rval; for (i = j = 0; i < count; i++) { - if (INT_GET(ents[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) { + if (be32_to_cpu(ents[i].address) == XFS_DIR2_NULL_DATAPTR) { j++; continue; } - rval = dir_hash_see(hashtab, INT_GET(ents[i].hashval, ARCH_CONVERT), INT_GET(ents[i].address, ARCH_CONVERT)); + rval = dir_hash_see(hashtab, be32_to_cpu(ents[i].hashval), + be32_to_cpu(ents[i].address)); if (rval != DIR_HASH_CK_OK) return rval; } @@ -341,87 +346,61 @@ dir_hash_see_all( static void dir_hash_dup_names(dir_hash_tab_t *hashtab) { - uchar_t *name; + char *name; dir_hash_ent_t *p; if (hashtab->names_duped) return; for (p = hashtab->first; p; p = p->nextbyorder) { - name = malloc(p->namelen); - memcpy(name, p->name, p->namelen); - p->name = name; + name = malloc(p->name.len); + memcpy(name, p->name.name, p->name.len); + p->name.name = name; } hashtab->names_duped = 1; } /* - * Version 1 or 2 directory routine wrappers -*/ -static void -dir_init(xfs_mount_t *mp, xfs_trans_t *tp, xfs_inode_t *dp, xfs_inode_t *pdp) -{ - if (XFS_SB_VERSION_HASDIRV2(&mp->m_sb)) - libxfs_dir2_init(tp, dp, pdp); - else - libxfs_dir_init(tp, dp, pdp); -} - -static int -dir_createname(xfs_mount_t *mp, xfs_trans_t *tp, xfs_inode_t *pip, - char *name, int namelen, xfs_ino_t inum, xfs_fsblock_t *first, - xfs_bmap_free_t *flist, xfs_extlen_t total) -{ - if (XFS_SB_VERSION_HASDIRV2(&mp->m_sb)) - return libxfs_dir2_createname(tp, pip, - (uchar_t *)name, namelen, - inum, first, flist, total); - else - return libxfs_dir_createname(tp, pip, - (uchar_t *)name, namelen, - inum, first, flist, total); -} - -static int -dir_lookup(xfs_mount_t *mp, xfs_trans_t *tp, xfs_inode_t *dp, char *name, - int namelen, xfs_ino_t *inum) -{ - if (XFS_SB_VERSION_HASDIRV2(&mp->m_sb)) - return libxfs_dir2_lookup(tp, dp, - (uchar_t *)name, namelen, inum); - else - return libxfs_dir_lookup(tp, dp, - (uchar_t *)name, namelen, inum); -} - -static int -dir_replace(xfs_mount_t *mp, xfs_trans_t *tp, xfs_inode_t *dp, char *name, - int namelen, xfs_ino_t inum, xfs_fsblock_t *firstblock, - xfs_bmap_free_t *flist, xfs_extlen_t total) -{ - if (XFS_SB_VERSION_HASDIRV2(&mp->m_sb)) - return libxfs_dir2_replace(tp, dp, - (uchar_t *)name, namelen, inum, - firstblock, flist, total); - else - return libxfs_dir_replace(tp, dp, - (uchar_t *)name, namelen, inum, - firstblock, flist, total); -} - + * Given a block number in a fork, return the next valid block number + * (not a hole). + * If this is the last block number then NULLFILEOFF is returned. + * + * This was originally in the kernel, but only used in xfs_repair. + */ static int -dir_bogus_removename(xfs_mount_t *mp, xfs_trans_t *tp, xfs_inode_t *dp, - char *name, xfs_fsblock_t *firstblock, xfs_bmap_free_t *flist, - xfs_extlen_t total, xfs_dahash_t hashval, int namelen) +bmap_next_offset( + xfs_trans_t *tp, /* transaction pointer */ + xfs_inode_t *ip, /* incore inode */ + xfs_fileoff_t *bnop, /* current block */ + int whichfork) /* data or attr fork */ { - if (XFS_SB_VERSION_HASDIRV2(&mp->m_sb)) - return libxfs_dir2_bogus_removename(tp, dp, - (uchar_t *)name, firstblock, - flist, total, hashval, namelen); + xfs_fileoff_t bno; /* current block */ + int eof; /* hit end of file */ + int error; /* error return value */ + xfs_bmbt_irec_t got; /* current extent value */ + xfs_ifork_t *ifp; /* inode fork pointer */ + xfs_extnum_t lastx; /* last extent used */ + xfs_bmbt_irec_t prev; /* previous extent value */ + + if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && + XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && + XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) + return EIO; + if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { + *bnop = NULLFILEOFF; + return 0; + } + ifp = XFS_IFORK_PTR(ip, whichfork); + if (!(ifp->if_flags & XFS_IFEXTENTS) && + (error = xfs_iread_extents(tp, ip, whichfork))) + return error; + bno = *bnop + 1; + xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); + if (eof) + *bnop = NULLFILEOFF; else - return libxfs_dir_bogus_removename(tp, dp, - (uchar_t *)name, firstblock, - flist, total, hashval, namelen); + *bnop = got.br_startoff < bno ? bno : got.br_startoff; + return 0; } @@ -489,7 +468,7 @@ mk_rbmino(xfs_mount_t *mp) */ libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); libxfs_trans_ihold(tp, ip); - libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, NULL); + libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); /* * then allocate blocks for file and fill with zeroes (stolen @@ -508,7 +487,7 @@ mk_rbmino(xfs_mount_t *mp) error = libxfs_bmapi(tp, ip, bno, (xfs_extlen_t)(mp->m_sb.sb_rbmblocks - bno), XFS_BMAPI_WRITE, &first, mp->m_sb.sb_rbmblocks, - map, &nmap, &flist); + map, &nmap, &flist, NULL); if (error) { do_error( _("couldn't allocate realtime bitmap, error = %d\n"), @@ -521,13 +500,13 @@ mk_rbmino(xfs_mount_t *mp) bno += ep->br_blockcount; } } - error = libxfs_bmap_finish(&tp, &flist, first, &committed); + error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) { do_error( _("allocation of the realtime bitmap failed, error = %d\n"), error); } - libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, 0); + libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); } int @@ -564,7 +543,7 @@ fill_rbmino(xfs_mount_t *mp) */ nmap = 1; error = libxfs_bmapi(tp, ip, bno, 1, XFS_BMAPI_WRITE, - &first, 1, &map, &nmap, NULL); + &first, 1, &map, &nmap, NULL, NULL); if (error || nmap != 1) { do_error( _("couldn't map realtime bitmap block %llu, error = %d\n"), @@ -593,7 +572,7 @@ _("can't access block %llu (fsbno %llu) of realtime bitmap inode %llu\n"), bno++; } - libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, 0); + libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); return(0); } @@ -633,7 +612,7 @@ fill_rsumino(xfs_mount_t *mp) */ nmap = 1; error = libxfs_bmapi(tp, ip, bno, 1, XFS_BMAPI_WRITE, - &first, 1, &map, &nmap, NULL); + &first, 1, &map, &nmap, NULL, NULL); if (error || nmap != 1) { do_error( _("couldn't map realtime summary inode block %llu, error = %d\n"), @@ -662,7 +641,7 @@ _("can't access block %llu (fsbno %llu) of realtime summary inode %llu\n"), bno++; } - libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, 0); + libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); return(0); } @@ -722,7 +701,7 @@ mk_rsumino(xfs_mount_t *mp) */ libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); libxfs_trans_ihold(tp, ip); - libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, 0); + libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); /* * then allocate blocks for file and fill with zeroes (stolen @@ -747,7 +726,7 @@ mk_rsumino(xfs_mount_t *mp) error = libxfs_bmapi(tp, ip, bno, (xfs_extlen_t)(nsumblocks - bno), XFS_BMAPI_WRITE, &first, nsumblocks, - map, &nmap, &flist); + map, &nmap, &flist, NULL); if (error) { do_error( _("couldn't allocate realtime summary inode, error = %d\n"), @@ -760,13 +739,13 @@ mk_rsumino(xfs_mount_t *mp) bno += ep->br_blockcount; } } - error = libxfs_bmap_finish(&tp, &flist, first, &committed); + error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) { do_error( _("allocation of the realtime summary ino failed, error = %d\n"), error); } - libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, 0); + libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); } /* @@ -782,6 +761,8 @@ mk_root_dir(xfs_mount_t *mp) const mode_t mode = 0755; ino_tree_node_t *irec; + ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb)); + tp = libxfs_trans_alloc(mp, 0); ip = NULL; @@ -821,9 +802,9 @@ mk_root_dir(xfs_mount_t *mp) /* * initialize the directory */ - dir_init(mp, tp, ip, ip); + libxfs_dir_init(tp, ip, ip); - libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, 0); + libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); irec = find_inode_rec(XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino), XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino)); @@ -848,6 +829,9 @@ mk_orphanage(xfs_mount_t *mp) xfs_bmap_free_t flist; const int mode = 0755; int nres; + struct xfs_name xname; + + ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb)); /* * check for an existing lost+found first, if it exists, return @@ -859,8 +843,9 @@ mk_orphanage(xfs_mount_t *mp) do_error(_("%d - couldn't iget root inode to obtain %s\n"), i, ORPHANAGE); - if (dir_lookup(mp, NULL, pip, ORPHANAGE, strlen(ORPHANAGE), - &ino) == 0) + xname.name = ORPHANAGE; + xname.len = strlen(ORPHANAGE); + if (libxfs_dir_lookup(NULL, pip, &xname, &ino, NULL) == 0) return ino; /* @@ -870,7 +855,7 @@ mk_orphanage(xfs_mount_t *mp) tp = libxfs_trans_alloc(mp, 0); XFS_BMAP_INIT(&flist, &first); - nres = XFS_MKDIR_SPACE_RES(mp, strlen(ORPHANAGE)); + nres = XFS_MKDIR_SPACE_RES(mp, xname.len); if ((i = libxfs_trans_reserve(tp, nres, XFS_MKDIR_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT))) res_failed(i); @@ -900,12 +885,12 @@ mk_orphanage(xfs_mount_t *mp) /* * create the actual entry */ - if ((error = dir_createname(mp, tp, pip, ORPHANAGE, - strlen(ORPHANAGE), ip->i_ino, &first, &flist, nres))) { + error = libxfs_dir_createname(tp, pip, &xname, ip->i_ino, &first, + &flist, nres); + if (error) do_error( _("can't make %s, createname error %d\n"), ORPHANAGE, error); - } /* * bump up the link count in the root directory to account @@ -917,10 +902,10 @@ mk_orphanage(xfs_mount_t *mp) libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE); - dir_init(mp, tp, ip, pip); + libxfs_dir_init(tp, ip, pip); libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - error = libxfs_bmap_finish(&tp, &flist, first, &committed); + error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) { do_error(_("%s directory creation failed -- bmapf error %d\n"), ORPHANAGE, error); @@ -928,7 +913,7 @@ mk_orphanage(xfs_mount_t *mp) ino = ip->i_ino; - libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, 0); + libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); return(ino); } @@ -951,14 +936,17 @@ mv_orphanage( int err; int committed; char fname[MAXPATHLEN + 1]; - int fnamelen; int nres; int incr; ino_tree_node_t *irec; int ino_offset = 0; + struct xfs_name xname; + + ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb)); - fnamelen = snprintf(fname, sizeof(fname), "%llu", - (unsigned long long)ino); + xname.name = fname; + xname.len = snprintf(fname, sizeof(fname), "%llu", + (unsigned long long)ino); err = libxfs_iget(mp, NULL, orphanage_ino, 0, &orphanage_ip, 0); if (err) @@ -967,11 +955,10 @@ mv_orphanage( * Make sure the filename is unique in the lost+found */ incr = 0; - while (dir_lookup(mp, NULL, orphanage_ip, fname, fnamelen, - &entry_ino_num) == 0) { - fnamelen = snprintf(fname, sizeof(fname), "%llu.%d", - (unsigned long long)ino, ++incr); - } + while (libxfs_dir_lookup(NULL, orphanage_ip, &xname, &entry_ino_num, + NULL) == 0) + xname.len = snprintf(fname, sizeof(fname), "%llu.%d", + (unsigned long long)ino, ++incr); tp = libxfs_trans_alloc(mp, 0); @@ -986,7 +973,8 @@ mv_orphanage( irec->ino_startnum; nres = XFS_DIRENTER_SPACE_RES(mp, fnamelen) + XFS_DIRENTER_SPACE_RES(mp, 2); - err = dir_lookup(mp, tp, ino_p, "..", 2, &entry_ino_num); + err = libxfs_dir_lookup(tp, ino_p, &xfs_name_dotdot, + &entry_ino_num, NULL); if (err) { ASSERT(err == ENOENT); @@ -1002,9 +990,9 @@ mv_orphanage( libxfs_trans_ijoin(tp, ino_p, 0); XFS_BMAP_INIT(&flist, &first); - if ((err = dir_createname(mp, tp, orphanage_ip, fname, - fnamelen, ino, &first, - &flist, nres))) + err = libxfs_dir_createname(tp, orphanage_ip, &xname, + ino, &first, &flist, nres); + if (err) do_error( _("name create failed in %s (%d), filesystem may be out of space\n"), ORPHANAGE, err); @@ -1015,8 +1003,9 @@ mv_orphanage( orphanage_ip->i_d.di_nlink++; libxfs_trans_log_inode(tp, orphanage_ip, XFS_ILOG_CORE); - if ((err = dir_createname(mp, tp, ino_p, "..", 2, - orphanage_ino, &first, &flist, nres))) + err = libxfs_dir_createname(tp, ino_p, &xfs_name_dotdot, + orphanage_ino, &first, &flist, nres); + if (err) do_error( _("creation of .. entry failed (%d), filesystem may be out of space\n"), err); @@ -1024,13 +1013,14 @@ mv_orphanage( ino_p->i_d.di_nlink++; libxfs_trans_log_inode(tp, ino_p, XFS_ILOG_CORE); - if ((err = libxfs_bmap_finish(&tp, &flist, first, &committed))) + err = libxfs_bmap_finish(&tp, &flist, &committed); + if (err) do_error( _("bmap finish failed (err - %d), filesystem may be out of space\n"), err); libxfs_trans_commit(tp, - XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, 0); + XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); } else { if ((err = libxfs_trans_reserve(tp, nres, XFS_RENAME_LOG_RES(mp), 0, @@ -1045,9 +1035,9 @@ mv_orphanage( XFS_BMAP_INIT(&flist, &first); - if ((err = dir_createname(mp, tp, orphanage_ip, fname, - fnamelen, ino, &first, - &flist, nres))) + err = libxfs_dir_createname(tp, orphanage_ip, &xname, + ino, &first, &flist, nres); + if (err) do_error( _("name create failed in %s (%d), filesystem may be out of space\n"), ORPHANAGE, err); @@ -1063,22 +1053,23 @@ mv_orphanage( * to us. that'll pop a libxfs/kernel ASSERT. */ if (entry_ino_num != orphanage_ino) { - if ((err = dir_replace(mp, tp, ino_p, "..", - 2, orphanage_ino, &first, - &flist, nres))) + err = libxfs_dir_replace(tp, ino_p, + &xfs_name_dotdot, orphanage_ino, + &first, &flist, nres); + if (err) do_error( _("name replace op failed (%d), filesystem may be out of space\n"), err); } - if ((err = libxfs_bmap_finish(&tp, &flist, first, - &committed))) + err = libxfs_bmap_finish(&tp, &flist, &committed); + if (err) do_error( _("bmap finish failed (%d), filesystem may be out of space\n"), err); libxfs_trans_commit(tp, - XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, 0); + XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); } } else { @@ -1088,9 +1079,10 @@ mv_orphanage( * links, we're not doing the inode allocation * also accounted for in the create */ - nres = XFS_DIRENTER_SPACE_RES(mp, fnamelen); - if ((err = libxfs_trans_reserve(tp, nres, XFS_REMOVE_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT))) + nres = XFS_DIRENTER_SPACE_RES(mp, xname.len); + err = libxfs_trans_reserve(tp, nres, XFS_REMOVE_LOG_RES(mp), 0, + XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT); + if (err) do_error( _("space reservation failed (%d), filesystem may be out of space\n"), err); @@ -1099,8 +1091,9 @@ mv_orphanage( libxfs_trans_ijoin(tp, ino_p, 0); XFS_BMAP_INIT(&flist, &first); - if ((err = dir_createname(mp, tp, orphanage_ip, fname, - fnamelen, ino, &first, &flist, nres))) + err = libxfs_dir_createname(tp, orphanage_ip, &xname, ino, + &first, &flist, nres); + if (err) do_error( _("name create failed in %s (%d), filesystem may be out of space\n"), ORPHANAGE, err); @@ -1109,12 +1102,13 @@ mv_orphanage( ino_p->i_d.di_nlink = 1; libxfs_trans_log_inode(tp, ino_p, XFS_ILOG_CORE); - if ((err = libxfs_bmap_finish(&tp, &flist, first, &committed))) + err = libxfs_bmap_finish(&tp, &flist, &committed); + if (err) do_error( _("bmap finish failed (%d), filesystem may be out of space\n"), err); - libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, 0); + libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); } } @@ -1156,8 +1150,8 @@ map_first_dblock_fsbno(xfs_mount_t *mp, nmap = 1; error = libxfs_bmapi(NULL, ip, (xfs_fileoff_t) da_bno, 1, - XFS_BMAPI_METADATA, &fblock, 0, - &map, &nmap, NULL); + XFS_BMAPI_METADATA, &fblock, 0, + &map, &nmap, NULL, NULL); if (error || nmap != 1) { if (!no_modify) do_error( @@ -1185,7 +1179,7 @@ _("can't map block %d in %s inode %llu, xfs_bmapi returns %d, nmap = %d\n"), if (ip->i_d.di_size <= XFS_LBSIZE(mp)) return(fsbno); - if (XFS_SB_VERSION_HASDIRV2(&mp->m_sb)) + if (xfs_sb_version_hasdirv2(&mp->m_sb)) return(fsbno); do { @@ -1208,7 +1202,7 @@ _("can't map block %d in %s inode %llu, xfs_bmapi returns %d, nmap = %d\n"), node = (xfs_da_intnode_t *)XFS_BUF_PTR(bp); - if (INT_GET(node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC) { + if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) { libxfs_putbuf(bp); do_warn( _("bad dir/attr magic number in inode %llu, file bno = %u, fsbno = %llu\n"), @@ -1217,9 +1211,9 @@ _("bad dir/attr magic number in inode %llu, file bno = %u, fsbno = %llu\n"), } if (i == -1) - i = INT_GET(node->hdr.level, ARCH_CONVERT); + i = be16_to_cpu(node->hdr.level); - da_bno = INT_GET(node->btree[0].before, ARCH_CONVERT); + da_bno = be32_to_cpu(node->btree[0].before); libxfs_putbuf(bp); bp = NULL; @@ -1227,7 +1221,7 @@ _("bad dir/attr magic number in inode %llu, file bno = %u, fsbno = %llu\n"), nmap = 1; error = libxfs_bmapi(NULL, ip, (xfs_fileoff_t) da_bno, 1, XFS_BMAPI_METADATA, &fblock, 0, - &map, &nmap, NULL); + &map, &nmap, NULL, NULL); if (error || nmap != 1) { if (!no_modify) do_error( @@ -1260,189 +1254,6 @@ _("can't map block %d in %s ino %llu, xfs_bmapi returns %d, nmap = %d\n"), return(fsbno); } -/* - * scan longform directory and prune first bad entry. returns 1 if - * it had to remove something, 0 if it made it all the way through - * the directory. prune_lf_dir_entry does all the necessary bmap calls. - * - * hashval is an in/out -- starting hashvalue in, hashvalue of the - * deleted entry (if there was one) out - * - * this routine can NOT be called if running in no modify mode - */ -static int -prune_lf_dir_entry(xfs_mount_t *mp, xfs_ino_t ino, xfs_inode_t *ip, - xfs_dahash_t *hashval) -{ - xfs_dfsbno_t fsbno; - int i; - int index; - int error; - int namelen; - xfs_bmap_free_t free_list; - xfs_fsblock_t first_block; - xfs_buf_t *bp; - xfs_dir_leaf_name_t *namest; - xfs_dir_leafblock_t *leaf; - xfs_dir_leaf_entry_t *entry; - xfs_trans_t *tp; - xfs_dablk_t da_bno; - xfs_fsblock_t fblock; - int committed; - int nmap; - xfs_bmbt_irec_t map; - char fname[MAXNAMELEN + 1]; - char *ftype; - int nres; - - /* - * ok, this is kind of a schizoid routine. we use our - * internal bmapi routines to walk the directory. when - * we find a bogus entry, we release the buffer so - * the simulation code doesn't deadlock and use the - * sim code to remove the entry. That will cause an - * extra bmap traversal to map the block but I think - * that's preferable to hacking the bogus removename - * function to be really different and then trying to - * maintain both versions as time goes on. - * - * first, grab the dinode and find the right leaf block. - */ - - ftype = _("dir"); - da_bno = 0; - bp = NULL; - namest = NULL; - fblock = NULLFSBLOCK; - - fsbno = map_first_dblock_fsbno(mp, ino, ip, &da_bno); - - /* - * now go foward along the leaves of the btree looking - * for an entry beginning with '/' - */ - do { - bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), - XFS_FSB_TO_BB(mp, 1), 0); - - if (!bp) { - do_error( - _("can't read directory inode %llu (leaf) block %u (fsbno %llu)\n"), - ino, da_bno, fsbno); - /* NOTREACHED */ - } - - leaf = (xfs_dir_leafblock_t *)XFS_BUF_PTR(bp); - ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC); - entry = &leaf->entries[0]; - - for (index = -1, i = 0; - i < INT_GET(leaf->hdr.count, ARCH_CONVERT) && index == -1; - i++) { - namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); - if (namest->name[0] != '/') - entry++; - else - index = i; - } - - /* - * if we got a bogus entry, exit loop with a pointer to - * the leaf block buffer. otherwise, keep trying blocks - */ - da_bno = INT_GET(leaf->hdr.info.forw, ARCH_CONVERT); - - if (index == -1) { - if (bp != NULL) { - libxfs_putbuf(bp); - bp = NULL; - } - - /* - * map next leaf block unless we've run out - */ - if (da_bno != 0) { - nmap = 1; - error = libxfs_bmapi(NULL, ip, - (xfs_fileoff_t) da_bno, 1, - XFS_BMAPI_METADATA, &fblock, 0, - &map, &nmap, NULL); - if (error || nmap != 1) - do_error( -_("can't map block %d in directory %llu, xfs_bmapi returns %d, nmap = %d\n"), - da_bno, ino, error, nmap); - if ((fsbno = map.br_startblock) - == HOLESTARTBLOCK) { - do_error( - _("%s ino %llu block %d doesn't exist\n"), - ftype, ino, da_bno); - } - } - } - } while (da_bno != 0 && index == -1); - - /* - * if we hit the edge of the tree with no bad entries, we're done - * and the buffer was released. - */ - if (da_bno == 0 && index == -1) - return(0); - - ASSERT(index >= 0); - ASSERT(entry == &leaf->entries[index]); - ASSERT(namest == XFS_DIR_LEAF_NAMESTRUCT(leaf, - INT_GET(entry->nameidx, ARCH_CONVERT))); - - /* - * snag the info we need out of the directory then release all buffers - */ - memmove(fname, namest->name, entry->namelen); - fname[entry->namelen] = '\0'; - *hashval = INT_GET(entry->hashval, ARCH_CONVERT); - namelen = entry->namelen; - - libxfs_putbuf(bp); - - /* - * ok, now the hard part, blow away the index'th entry in this block - * - * allocate a remove transaction for it. that's not quite true since - * we're only messing with one inode, not two but... - */ - - tp = libxfs_trans_alloc(mp, XFS_TRANS_REMOVE); - - nres = XFS_REMOVE_SPACE_RES(mp); - error = libxfs_trans_reserve(tp, nres, XFS_REMOVE_LOG_RES(mp), - 0, XFS_TRANS_PERM_LOG_RES, - XFS_REMOVE_LOG_COUNT); - if (error) - res_failed(error); - - libxfs_trans_ijoin(tp, ip, 0); - libxfs_trans_ihold(tp, ip); - - XFS_BMAP_INIT(&free_list, &first_block); - - error = dir_bogus_removename(mp, tp, ip, fname, - &first_block, &free_list, nres, *hashval, namelen); - - if (error) { - do_error( -_("couldn't remove bogus entry \"%s\" in\n\tdirectory inode %llu, errno = %d\n"), - fname, ino, error); - /* NOTREACHED */ - } - - error = libxfs_bmap_finish(&tp, &free_list, first_block, &committed); - - ASSERT(error == 0); - - libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, 0); - - return(1); -} - static int entry_junked( const char *msg, @@ -1506,12 +1317,13 @@ lf_block_dir_entry_check(xfs_mount_t *mp, * * return */ - for (i = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); entry++, i++) { + for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { /* * snag inode #, update link counts, and make sure * this isn't a loop if the child is a directory */ - namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); + namest = xfs_dir_leaf_namestruct(leaf, + be16_to_cpu(entry->nameidx)); /* * skip bogus entries (leading '/'). they'll be deleted @@ -1524,7 +1336,7 @@ lf_block_dir_entry_check(xfs_mount_t *mp, junkit = 0; - XFS_DIR_SF_GET_DIRINO(&namest->inumber, &lino); + xfs_dir_sf_get_dirino(&namest->inumber, &lino); memmove(fname, namest->name, entry->namelen); fname[entry->namelen] = '\0'; @@ -1624,9 +1436,9 @@ lf_block_dir_entry_check(xfs_mount_t *mp, /* * check for duplicate names in directory. */ - if (!dir_hash_add(mp, hashtab, (da_bno << mp->m_sb.sb_blocklog) + - entry->nameidx, lino, entry->namelen, - namest->name)) { + if (!dir_hash_add(mp, hashtab, (da_bno << mp->m_sb.sb_blocklog) + + be16_to_cpu(entry->nameidx), lino, + entry->namelen, (char *)namest->name)) { nbad++; if (entry_junked(_("entry \"%s\" (ino %llu) in dir " "%llu is a duplicate name"), @@ -1758,13 +1570,11 @@ longform_dir_entry_check(xfs_mount_t *mp, leaf = (xfs_dir_leafblock_t *)XFS_BUF_PTR(bp); - if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != - XFS_DIR_LEAF_MAGIC) { + if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) { if (!no_modify) { do_error( _("bad magic # (0x%x) for dir ino %llu leaf block (bno %u fsbno %llu)\n"), - INT_GET(leaf->hdr.info.magic, - ARCH_CONVERT), + be16_to_cpu(leaf->hdr.info.magic), ino, da_bno, fsbno); /* NOTREACHED */ } else { @@ -1782,7 +1592,7 @@ _("bad magic # (0x%x) for dir ino %llu leaf block (bno %u fsbno %llu)\n"), num_illegal, need_dot, irec, ino_offset, hashtab, da_bno); - da_bno = INT_GET(leaf->hdr.info.forw, ARCH_CONVERT); + da_bno = be32_to_cpu(leaf->hdr.info.forw); ASSERT(dirty == 0 || (dirty && !no_modify)); @@ -1796,7 +1606,7 @@ _("bad magic # (0x%x) for dir ino %llu leaf block (bno %u fsbno %llu)\n"), nmap = 1; error = libxfs_bmapi(NULL, ip, (xfs_fileoff_t)da_bno, 1, XFS_BMAPI_METADATA, &fblock, 0, - &map, &nmap, NULL); + &map, &nmap, NULL, NULL); if (error || nmap != 1) { if (!no_modify) do_error( @@ -1809,7 +1619,8 @@ _("can't map leaf block %d in dir %llu, xfs_bmapi returns %d, nmap = %d\n"), return; } } - if ((fsbno = map.br_startblock) == HOLESTARTBLOCK) { + fsbno = map.br_startblock; + if (fsbno == HOLESTARTBLOCK) { if (!no_modify) do_error( _("block %d in %s ino %llu doesn't exist\n"), @@ -1861,7 +1672,7 @@ longform_dir2_rebuild( * first attempt to locate the parent inode, if it can't be * found, set it to the root inode and it'll be moved to the * orphanage later (the inode number here needs to be valid - * for the libxfs_dir2_init() call). + * for the libxfs_dir_init() call). */ pip.i_ino = get_inode_parent(irec, ino_offset); if (pip.i_ino == NULLFSINO) @@ -1884,10 +1695,9 @@ longform_dir2_rebuild( error); /* free all data, leaf, node and freespace blocks */ - - if ((error = libxfs_bunmapi(tp, ip, 0, lastblock, - XFS_BMAPI_METADATA, 0, &firstblock, &flist, - &done))) { + error = libxfs_bunmapi(tp, ip, 0, lastblock, XFS_BMAPI_METADATA, 0, + &firstblock, &flist, NULL, &done); + if (error) { do_warn(_("xfs_bunmapi failed -- error - %d\n"), error); libxfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); @@ -1896,26 +1706,26 @@ longform_dir2_rebuild( ASSERT(done); - libxfs_dir2_init(tp, ip, &pip); + libxfs_dir_init(tp, ip, &pip); - error = libxfs_bmap_finish(&tp, &flist, firstblock, &committed); + error = libxfs_bmap_finish(&tp, &flist, &committed); - libxfs_trans_commit(tp, - XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, 0); + libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); /* go through the hash list and re-add the inodes */ for (p = hashtab->first; p; p = p->nextbyorder) { - if (p->name[0] == '/' || (p->name[0] == '.' && (p->namelen == 1 - || (p->namelen == 2 && p->name[1] == '.')))) + if (p->name.name[0] == '/' || (p->name.name[0] == '.' && + (p->name.len == 1 || (p->name.len == 2 && + p->name.name[1] == '.')))) continue; tp = libxfs_trans_alloc(mp, 0); - nres = XFS_CREATE_SPACE_RES(mp, p->namelen); - if ((error = libxfs_trans_reserve(tp, nres, - XFS_CREATE_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT))) { + nres = XFS_CREATE_SPACE_RES(mp, p->name.len); + error = libxfs_trans_reserve(tp, nres, XFS_CREATE_LOG_RES(mp), + 0, XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT); + if (error) { do_warn( _("space reservation failed (%d), filesystem may be out of space\n"), error); @@ -1926,9 +1736,9 @@ longform_dir2_rebuild( libxfs_trans_ihold(tp, ip); XFS_BMAP_INIT(&flist, &firstblock); - if ((error = libxfs_dir2_createname(tp, ip, (uchar_t *)p->name, - p->namelen, p->inum, &firstblock, &flist, - nres))) { + error = libxfs_dir_createname(tp, ip, &p->name, p->inum, + &firstblock, &flist, nres); + if (error) { do_warn( _("name create failed in ino %llu (%d), filesystem may be out of space\n"), ino, error); @@ -1937,8 +1747,8 @@ _("name create failed in ino %llu (%d), filesystem may be out of space\n"), break; } - if ((error = libxfs_bmap_finish(&tp, &flist, firstblock, - &committed))) { + error = libxfs_bmap_finish(&tp, &flist, &committed); + if (error) { do_warn( _("bmap finish failed (%d), filesystem may be out of space\n"), error); @@ -1948,9 +1758,8 @@ _("name create failed in ino %llu (%d), filesystem may be out of space\n"), break; } - libxfs_trans_commit(tp, - XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, 0); + XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); } } @@ -1994,12 +1803,12 @@ dir2_kill_block( error = libxfs_da_shrink_inode(&args, da_bno, bp); else error = libxfs_dir2_shrink_inode(&args, - XFS_DIR2_DA_TO_DB(mp, da_bno), bp); + xfs_dir2_da_to_db(mp, da_bno), bp); if (error) do_error(_("shrink_inode failed inode %llu block %u\n"), ip->i_ino, da_bno); - libxfs_bmap_finish(&tp, &flist, firstblock, &committed); - libxfs_trans_commit(tp, 0, 0); + libxfs_bmap_finish(&tp, &flist, &committed); + libxfs_trans_commit(tp, 0); } /* @@ -2058,8 +1867,8 @@ longform_dir2_entry_check_data( junkit = 0; freetab = *freetabp; if (isblock) { - btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d); - blp = XFS_DIR2_BLOCK_LEAF_P(btp); + btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); + blp = xfs_dir2_block_leaf_p(btp); endptr = (char *)blp; if (endptr > (char *)btp) endptr = (char *)btp; @@ -2068,7 +1877,7 @@ longform_dir2_entry_check_data( endptr = (char *)d + mp->m_dirblksize; wantmagic = XFS_DIR2_DATA_MAGIC; } - db = XFS_DIR2_DA_TO_DB(mp, da_bno); + db = xfs_dir2_da_to_db(mp, da_bno); /* check for data block beyond expected end */ if (freetab->naents <= db) { @@ -2092,44 +1901,42 @@ longform_dir2_entry_check_data( /* check for freespace */ dup = (xfs_dir2_data_unused_t *)ptr; - if (XFS_DIR2_DATA_FREE_TAG == - INT_GET(dup->freetag, ARCH_CONVERT)) { + if (XFS_DIR2_DATA_FREE_TAG == be16_to_cpu(dup->freetag)) { /* check for invalid freespace length */ - if (ptr + INT_GET(dup->length, ARCH_CONVERT) > endptr || - INT_GET(dup->length, ARCH_CONVERT) == 0 || - (INT_GET(dup->length, ARCH_CONVERT) & - (XFS_DIR2_DATA_ALIGN - 1))) + if (ptr + be16_to_cpu(dup->length) > endptr || + be16_to_cpu(dup->length) == 0 || + (be16_to_cpu(dup->length) & + (XFS_DIR2_DATA_ALIGN - 1))) break; /* check for invalid tag */ - if (INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), - ARCH_CONVERT) != (char *)dup - (char *)d) + if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) != + (char *)dup - (char *)d) break; /* check for block with no data entries */ - if ((ptr == (char *)d->u) && - (ptr + INT_GET(dup->length, ARCH_CONVERT) >= - endptr)) { + if ((ptr == (char *)d->u) && (ptr + + be16_to_cpu(dup->length) >= endptr)) { junkit = 1; *num_illegal += 1; break; } /* continue at the end of the freespace */ - ptr += INT_GET(dup->length, ARCH_CONVERT); + ptr += be16_to_cpu(dup->length); if (ptr >= endptr) break; } /* validate data entry size */ dep = (xfs_dir2_data_entry_t *)ptr; - if (ptr + XFS_DIR2_DATA_ENTSIZE(dep->namelen) > endptr) + if (ptr + xfs_dir2_data_entsize(dep->namelen) > endptr) break; - if (INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(dep), ARCH_CONVERT) != - (char *)dep - (char *)d) + if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) != + (char *)dep - (char *)d) break; - ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen); + ptr += xfs_dir2_data_entsize(dep->namelen); } /* did we find an empty or corrupt block? */ @@ -2168,13 +1975,13 @@ longform_dir2_entry_check_data( libxfs_da_bjoin(tp, bp); libxfs_da_bhold(tp, bp); XFS_BMAP_INIT(&flist, &firstblock); - if (INT_GET(d->hdr.magic, ARCH_CONVERT) != wantmagic) { + if (be32_to_cpu(d->hdr.magic) != wantmagic) { do_warn(_("bad directory block magic # %#x for directory inode " "%llu block %d: "), - INT_GET(d->hdr.magic, ARCH_CONVERT), ip->i_ino, da_bno); + be32_to_cpu(d->hdr.magic), ip->i_ino, da_bno); if (!no_modify) { do_warn(_("fixing magic # to %#x\n"), wantmagic); - INT_SET(d->hdr.magic, ARCH_CONVERT, wantmagic); + d->hdr.magic = cpu_to_be32(wantmagic); needlog = 1; } else do_warn(_("would fix magic # to %#x\n"), wantmagic); @@ -2195,15 +2002,14 @@ longform_dir2_entry_check_data( */ while (ptr < endptr) { dup = (xfs_dir2_data_unused_t *)ptr; - if (INT_GET(dup->freetag, ARCH_CONVERT) == - XFS_DIR2_DATA_FREE_TAG) { + if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { if (lastfree) { do_warn(_("directory inode %llu block %u has " "consecutive free entries: "), ip->i_ino, da_bno); if (!no_modify) { do_warn(_("joining together\n")); - len = INT_GET(dup->length, ARCH_CONVERT); + len = be16_to_cpu(dup->length); libxfs_dir2_data_use_free(tp, bp, dup, ptr - (char *)d, len, &needlog, &needscan); @@ -2213,14 +2019,14 @@ longform_dir2_entry_check_data( } else do_warn(_("would join together\n")); } - ptr += INT_GET(dup->length, ARCH_CONVERT); + ptr += be16_to_cpu(dup->length); lastfree = 1; continue; } - addr = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, db, ptr - (char *)d); + addr = xfs_dir2_db_off_to_dataptr(mp, db, ptr - (char *)d); dep = (xfs_dir2_data_entry_t *)ptr; - ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen); - inum = INT_GET(dep->inumber, ARCH_CONVERT); + ptr += xfs_dir2_data_entsize(dep->namelen); + inum = be64_to_cpu(dep->inumber); lastfree = 0; /* * skip bogus entries (leading '/'). they'll be deleted @@ -2296,7 +2102,7 @@ longform_dir2_entry_check_data( * check for duplicate names in directory. */ if (!dir_hash_add(mp, hashtab, addr, inum, dep->namelen, - dep->name)) { + (char *)dep->name)) { nbad++; if (entry_junked(_("entry \"%s\" (ino %llu) in dir " "%llu is a duplicate name"), @@ -2433,12 +2239,12 @@ _("entry \"%s\" in dir inode %llu inconsistent with .. value (%llu) in ino %llu\ } *num_illegal += nbad; if (needscan) - libxfs_dir2_data_freescan(mp, d, &needlog, NULL); + libxfs_dir2_data_freescan(mp, d, &needlog); if (needlog) libxfs_dir2_data_log_header(tp, bp); - libxfs_bmap_finish(&tp, &flist, firstblock, &committed); - libxfs_trans_commit(tp, 0, 0); - freetab->ents[db].v = INT_GET(d->hdr.bestfree[0].length, ARCH_CONVERT); + libxfs_bmap_finish(&tp, &flist, &committed); + libxfs_trans_commit(tp, 0); + freetab->ents[db].v = be16_to_cpu(d->hdr.bestfree[0].length); freetab->ents[db].s = 0; } @@ -2453,7 +2259,7 @@ longform_dir2_check_leaf( freetab_t *freetab) { int badtail; - xfs_dir2_data_off_t *bestsp; + __be16 *bestsp; xfs_dabuf_t *bp; xfs_dablk_t da_bno; int i; @@ -2468,18 +2274,17 @@ longform_dir2_check_leaf( /* NOTREACHED */ } leaf = bp->data; - ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); - bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); - if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != - XFS_DIR2_LEAF1_MAGIC || - INT_GET(leaf->hdr.info.forw, ARCH_CONVERT) || - INT_GET(leaf->hdr.info.back, ARCH_CONVERT) || - INT_GET(leaf->hdr.count, ARCH_CONVERT) < - INT_GET(leaf->hdr.stale, ARCH_CONVERT) || - INT_GET(leaf->hdr.count, ARCH_CONVERT) > - XFS_DIR2_MAX_LEAF_ENTS(mp) || - (char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] > - (char *)bestsp) { + ltp = xfs_dir2_leaf_tail_p(mp, leaf); + bestsp = xfs_dir2_leaf_bests_p(ltp); + if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAF1_MAGIC || + be32_to_cpu(leaf->hdr.info.forw) || + be32_to_cpu(leaf->hdr.info.back) || + be16_to_cpu(leaf->hdr.count) < + be16_to_cpu(leaf->hdr.stale) || + be16_to_cpu(leaf->hdr.count) > + xfs_dir2_max_leaf_ents(mp) || + (char *)&leaf->ents[be16_to_cpu( + leaf->hdr.count)] > (char *)bestsp) { do_warn( _("leaf block %u for directory inode %llu bad header\n"), da_bno, ip->i_ino); @@ -2487,16 +2292,16 @@ longform_dir2_check_leaf( return 1; } seeval = dir_hash_see_all(hashtab, leaf->ents, - INT_GET(leaf->hdr.count, ARCH_CONVERT), - INT_GET(leaf->hdr.stale, ARCH_CONVERT)); + be16_to_cpu(leaf->hdr.count), + be16_to_cpu(leaf->hdr.stale)); if (dir_hash_check(hashtab, ip, seeval)) { libxfs_da_brelse(NULL, bp); return 1; } - badtail = freetab->nents != INT_GET(ltp->bestcount, ARCH_CONVERT); - for (i = 0; !badtail && i < INT_GET(ltp->bestcount, ARCH_CONVERT); i++) { + badtail = freetab->nents != be32_to_cpu(ltp->bestcount); + for (i = 0; !badtail && i < be32_to_cpu(ltp->bestcount); i++) { freetab->ents[i].s = 1; - badtail = freetab->ents[i].v != INT_GET(bestsp[i], ARCH_CONVERT); + badtail = freetab->ents[i].v != be16_to_cpu(bestsp[i]); } if (badtail) { do_warn(_("leaf block %u for directory inode %llu bad tail\n"), @@ -2530,10 +2335,10 @@ longform_dir2_check_node( int used; for (da_bno = mp->m_dirleafblk, next_da_bno = 0; - next_da_bno != NULLFILEOFF && da_bno < mp->m_dirfreeblk; - da_bno = (xfs_dablk_t)next_da_bno) { + next_da_bno != NULLFILEOFF && da_bno < mp->m_dirfreeblk; + da_bno = (xfs_dablk_t)next_da_bno) { next_da_bno = da_bno + mp->m_dirblkfsbs - 1; - if (libxfs_bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK)) + if (bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK)) break; if (libxfs_da_read_bufr(NULL, ip, da_bno, -1, &bp, XFS_DATA_FORK)) { @@ -2543,32 +2348,31 @@ longform_dir2_check_node( return 1; } leaf = bp->data; - if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != - XFS_DIR2_LEAFN_MAGIC) { - if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == - XFS_DA_NODE_MAGIC) { + if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAFN_MAGIC) { + if (be16_to_cpu(leaf->hdr.info.magic) == + XFS_DA_NODE_MAGIC) { libxfs_da_brelse(NULL, bp); continue; } do_warn(_("unknown magic number %#x for block %u in " "directory inode %llu\n"), - INT_GET(leaf->hdr.info.magic, ARCH_CONVERT), + be16_to_cpu(leaf->hdr.info.magic), da_bno, ip->i_ino); libxfs_da_brelse(NULL, bp); return 1; } - if (INT_GET(leaf->hdr.count, ARCH_CONVERT) < - INT_GET(leaf->hdr.stale, ARCH_CONVERT) || - INT_GET(leaf->hdr.count, ARCH_CONVERT) > - XFS_DIR2_MAX_LEAF_ENTS(mp)) { + if (be16_to_cpu(leaf->hdr.count) > xfs_dir2_max_leaf_ents(mp) || + be16_to_cpu(leaf->hdr.count) < + be16_to_cpu(leaf->hdr.stale)) { do_warn(_("leaf block %u for directory inode %llu bad " "header\n"), da_bno, ip->i_ino); libxfs_da_brelse(NULL, bp); return 1; } - seeval = dir_hash_see_all(hashtab, leaf->ents, INT_GET(leaf->hdr.count, ARCH_CONVERT), - INT_GET(leaf->hdr.stale, ARCH_CONVERT)); + seeval = dir_hash_see_all(hashtab, leaf->ents, + be16_to_cpu(leaf->hdr.count), + be16_to_cpu(leaf->hdr.stale)); libxfs_da_brelse(NULL, bp); if (seeval != DIR_HASH_CK_OK) return 1; @@ -2580,7 +2384,7 @@ longform_dir2_check_node( next_da_bno != NULLFILEOFF; da_bno = (xfs_dablk_t)next_da_bno) { next_da_bno = da_bno + mp->m_dirblkfsbs - 1; - if (libxfs_bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK)) + if (bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK)) break; if (libxfs_da_read_bufr(NULL, ip, da_bno, -1, &bp, XFS_DATA_FORK)) { @@ -2590,36 +2394,35 @@ longform_dir2_check_node( return 1; } free = bp->data; - fdb = XFS_DIR2_DA_TO_DB(mp, da_bno); - if (INT_GET(free->hdr.magic, ARCH_CONVERT) != - XFS_DIR2_FREE_MAGIC || - INT_GET(free->hdr.firstdb, ARCH_CONVERT) != - (fdb - XFS_DIR2_FREE_FIRSTDB(mp)) * - XFS_DIR2_MAX_FREE_BESTS(mp) || - INT_GET(free->hdr.nvalid, ARCH_CONVERT) < - INT_GET(free->hdr.nused, ARCH_CONVERT)) { + fdb = xfs_dir2_da_to_db(mp, da_bno); + if (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC || + be32_to_cpu(free->hdr.firstdb) != + (fdb - XFS_DIR2_FREE_FIRSTDB(mp)) * + XFS_DIR2_MAX_FREE_BESTS(mp) || + be32_to_cpu(free->hdr.nvalid) < + be32_to_cpu(free->hdr.nused)) { do_warn(_("free block %u for directory inode %llu bad " "header\n"), da_bno, ip->i_ino); libxfs_da_brelse(NULL, bp); return 1; } - for (i = used = 0; i < INT_GET(free->hdr.nvalid, ARCH_CONVERT); i++) { - if (i + INT_GET(free->hdr.firstdb, ARCH_CONVERT) >= - freetab->nents || - freetab->ents[i + INT_GET(free->hdr.firstdb, - ARCH_CONVERT)].v != - INT_GET(free->bests[i], ARCH_CONVERT)) { + for (i = used = 0; i < be32_to_cpu(free->hdr.nvalid); i++) { + if (i + be32_to_cpu(free->hdr.firstdb) >= + freetab->nents || + freetab->ents[i + be32_to_cpu( + free->hdr.firstdb)].v != + be16_to_cpu(free->bests[i])) { do_warn( _("free block %u entry %i for directory ino %llu bad\n"), da_bno, i, ip->i_ino); libxfs_da_brelse(NULL, bp); return 1; } - used += INT_GET(free->bests[i], ARCH_CONVERT) != NULLDATAOFF; - freetab->ents[i + INT_GET(free->hdr.firstdb, ARCH_CONVERT)].s = 1; + used += be16_to_cpu(free->bests[i]) != NULLDATAOFF; + freetab->ents[i + be32_to_cpu(free->hdr.firstdb)].s = 1; } - if (used != INT_GET(free->hdr.nused, ARCH_CONVERT)) { + if (used != be32_to_cpu(free->hdr.nused)) { do_warn(_("free block %u for directory inode %llu bad " "nused\n"), da_bno, ip->i_ino); @@ -2693,9 +2496,9 @@ longform_dir2_entry_check(xfs_mount_t *mp, next_da_bno != NULLFILEOFF && da_bno < mp->m_dirleafblk; da_bno = (xfs_dablk_t)next_da_bno) { next_da_bno = da_bno + mp->m_dirblkfsbs - 1; - if (libxfs_bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK)) + if (bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK)) break; - db = XFS_DIR2_DA_TO_DB(mp, da_bno); + db = xfs_dir2_da_to_db(mp, da_bno); if (db >= num_bps) { /* more data blocks than expected */ num_bps = db + 1; @@ -2726,8 +2529,8 @@ longform_dir2_entry_check(xfs_mount_t *mp, xfs_dir2_leaf_entry_t *blp; block = bplist[0]->data; - btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); - blp = XFS_DIR2_BLOCK_LEAF_P(btp); + btp = xfs_dir2_block_tail_p(mp, block); + blp = xfs_dir2_block_leaf_p(btp); seeval = dir_hash_see_all(hashtab, blp, be32_to_cpu(btp->count), be32_to_cpu(btp->stale)); @@ -2818,14 +2621,14 @@ shortform_dir_entry_check(xfs_mount_t *mp, } else { - for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT) && max_size > - (__psint_t)next_sfe - (__psint_t)sf; + for (i = 0; i < sf->hdr.count && max_size > + (__psint_t)next_sfe - (__psint_t)sf; sf_entry = next_sfe, i++) { junkit = 0; bad_sfnamelen = 0; tmp_sfe = NULL; - XFS_DIR_SF_GET_DIRINO(&sf_entry->inumber, &lino); + xfs_dir_sf_get_dirino(&sf_entry->inumber, &lino); namelen = sf_entry->namelen; @@ -2842,7 +2645,7 @@ shortform_dir_entry_check(xfs_mount_t *mp, */ bad_sfnamelen = 1; - if (i == INT_GET(sf->hdr.count, ARCH_CONVERT) - 1) { + if (i == sf->hdr.count - 1) { namelen = ip->i_d.di_size - ((__psint_t) &sf_entry->name[0] - (__psint_t) sf); @@ -2854,11 +2657,11 @@ shortform_dir_entry_check(xfs_mount_t *mp, break; } } else if (no_modify && (__psint_t) sf_entry - (__psint_t) sf + - + XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry) + + xfs_dir_sf_entsize_byentry(sf_entry) > ip->i_d.di_size) { bad_sfnamelen = 1; - if (i == INT_GET(sf->hdr.count, ARCH_CONVERT) - 1) { + if (i == sf->hdr.count - 1) { namelen = ip->i_d.di_size - ((__psint_t) &sf_entry->name[0] - (__psint_t) sf); @@ -2919,9 +2722,9 @@ shortform_dir_entry_check(xfs_mount_t *mp, /* * check for duplicate names in directory. */ - if (!dir_hash_add(mp, hashtab, - (xfs_dir2_dataptr_t)(sf_entry - &sf->list[0]), - lino, sf_entry->namelen, sf_entry->name)) { + if (!dir_hash_add(mp, hashtab, (xfs_dir2_dataptr_t) + (sf_entry - &sf->list[0]), lino, + sf_entry->namelen, (char *)sf_entry->name)) { do_warn(_("entry \"%s\" (ino %llu) in dir %llu is a " "duplicate name"), fname, lino, ino); goto do_junkit; @@ -2933,9 +2736,8 @@ shortform_dir_entry_check(xfs_mount_t *mp, */ add_inode_reached(irec, ino_offset); - next_sfe = (xfs_dir_sf_entry_t *) - ((__psint_t) sf_entry + - XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry)); + next_sfe = (xfs_dir_sf_entry_t *)((__psint_t)sf_entry + + xfs_dir_sf_entsize_byentry(sf_entry)); continue; } else { parent = get_inode_parent(irec, ino_offset); @@ -2975,7 +2777,7 @@ do_junkit: if (lino == orphanage_ino) orphanage_ino = 0; if (!no_modify) { - tmp_elen = XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry); + tmp_elen = xfs_dir_sf_entsize_byentry(sf_entry); tmp_sfe = (xfs_dir_sf_entry_t *) ((__psint_t) sf_entry + tmp_elen); tmp_len = max_size - ((__psint_t) tmp_sfe @@ -2985,9 +2787,9 @@ do_junkit: memmove(sf_entry, tmp_sfe, tmp_len); - INT_MOD(sf->hdr.count, ARCH_CONVERT, -1); - memset((void *) ((__psint_t) sf_entry + tmp_len), 0, - tmp_elen); + sf->hdr.count -= 1; + memset((void *)((__psint_t)sf_entry + tmp_len), + 0, tmp_elen); /* * set the tmp value to the current @@ -3026,7 +2828,7 @@ do_junkit: next_sfe = (tmp_sfe == NULL) ? (xfs_dir_sf_entry_t *) ((__psint_t) sf_entry + ((!bad_sfnamelen) - ? XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry) + ? xfs_dir_sf_entsize_byentry(sf_entry) : sizeof(xfs_dir_sf_entry_t) - 1 + namelen)) : tmp_sfe; @@ -3055,100 +2857,6 @@ do_junkit: } } -/* ARGSUSED */ -static void -prune_sf_dir_entry(xfs_mount_t *mp, xfs_ino_t ino, xfs_inode_t *ip) -{ - /* REFERENCED */ - xfs_ino_t lino; - xfs_dir_shortform_t *sf; - xfs_dir_sf_entry_t *sf_entry, *next_sfe, *tmp_sfe; - xfs_ifork_t *ifp; - int max_size; - int i; - int tmp_len; - int tmp_elen; - int bytes_deleted; - char fname[MAXNAMELEN + 1]; - - ifp = &ip->i_df; - sf = (xfs_dir_shortform_t *) ifp->if_u1.if_data; - bytes_deleted = 0; - - max_size = ifp->if_bytes; - ASSERT(ip->i_d.di_size <= ifp->if_bytes); - - /* - * now run through entries and delete every bad entry - */ - sf_entry = next_sfe = &sf->list[0]; - - for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT) && max_size > - (__psint_t)next_sfe - (__psint_t)sf; - sf_entry = next_sfe, i++) { - tmp_sfe = NULL; - - XFS_DIR_SF_GET_DIRINO(&sf_entry->inumber, &lino); - - memmove(fname, sf_entry->name, sf_entry->namelen); - fname[sf_entry->namelen] = '\0'; - - if (sf_entry->name[0] == '/') { - if (!no_modify) { - tmp_elen = XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry); - tmp_sfe = (xfs_dir_sf_entry_t *) - ((__psint_t) sf_entry + tmp_elen); - tmp_len = max_size - ((__psint_t) tmp_sfe - - (__psint_t) sf); - max_size -= tmp_elen; - bytes_deleted += tmp_elen; - - memmove(sf_entry, tmp_sfe, tmp_len); - - INT_MOD(sf->hdr.count, ARCH_CONVERT, -1); - memset((void *) ((__psint_t) sf_entry + tmp_len), 0, - tmp_elen); - - /* - * set the tmp value to the current - * pointer so we'll process the entry - * we just moved up - */ - tmp_sfe = sf_entry; - - /* - * WARNING: drop the index i by one - * so it matches the decremented count for - * accurate comparisons in the loop test - */ - i--; - } - } - next_sfe = (tmp_sfe == NULL) - ? (xfs_dir_sf_entry_t *) ((__psint_t) sf_entry + - XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry)) - : tmp_sfe; - } - - /* - * sync up sizes if required - */ - if (bytes_deleted > 0) { - libxfs_idata_realloc(ip, -bytes_deleted, XFS_DATA_FORK); - ip->i_d.di_size -= bytes_deleted; - } - - if (ip->i_d.di_size != ip->i_df.if_bytes) { - ASSERT(ip->i_df.if_bytes == (xfs_fsize_t) - ((__psint_t) next_sfe - (__psint_t) sf)); - ip->i_d.di_size = (xfs_fsize_t) - ((__psint_t) next_sfe - (__psint_t) sf); - do_warn( - _("setting size to %lld bytes to reflect junked entries\n"), - ip->i_d.di_size); - } -} - /* * shortform directory v2 processing routines -- entry verification and * bad entry deletion (pruning). @@ -3199,7 +2907,7 @@ shortform_dir2_entry_check(xfs_mount_t *mp, } else { do_warn(_("setting .. in sf dir inode %llu to %llu\n"), ino, parent); - XFS_DIR2_SF_PUT_INUMBER(sfp, &parent, &sfp->hdr.parent); + xfs_dir2_sf_put_inumber(sfp, &parent, &sfp->hdr.parent); *ino_dirty = 1; } return; @@ -3216,7 +2924,7 @@ shortform_dir2_entry_check(xfs_mount_t *mp, /* * Initialise i8 counter -- the parent inode number counts as well. */ - i8 = (XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent) > + i8 = (xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent) > XFS_DIR2_MAX_SHORT_INUM); /* @@ -3224,16 +2932,16 @@ shortform_dir2_entry_check(xfs_mount_t *mp, * to skip over '..' since that's encoded in its own field and * no need to worry about '.' since it doesn't exist. */ - sfep = next_sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); + sfep = next_sfep = xfs_dir2_sf_firstentry(sfp); - for (i = 0; i < INT_GET(sfp->hdr.count, ARCH_CONVERT) && max_size > + for (i = 0; i < sfp->hdr.count && max_size > (__psint_t)next_sfep - (__psint_t)sfp; sfep = next_sfep, i++) { junkit = 0; bad_sfnamelen = 0; tmp_sfep = NULL; - lino = XFS_DIR2_SF_GET_INUMBER(sfp, XFS_DIR2_SF_INUMBERP(sfep)); + lino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); namelen = sfep->namelen; @@ -3250,7 +2958,7 @@ shortform_dir2_entry_check(xfs_mount_t *mp, */ bad_sfnamelen = 1; - if (i == INT_GET(sfp->hdr.count, ARCH_CONVERT) - 1) { + if (i == sfp->hdr.count - 1) { namelen = ip->i_d.di_size - ((__psint_t) &sfep->name[0] - (__psint_t) sfp); @@ -3262,11 +2970,11 @@ shortform_dir2_entry_check(xfs_mount_t *mp, break; } } else if (no_modify && (__psint_t) sfep - (__psint_t) sfp + - + XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp, sfep) + + xfs_dir2_sf_entsize_byentry(sfp, sfep) > ip->i_d.di_size) { bad_sfnamelen = 1; - if (i == INT_GET(sfp->hdr.count, ARCH_CONVERT) - 1) { + if (i == sfp->hdr.count - 1) { namelen = ip->i_d.di_size - ((__psint_t) &sfep->name[0] - (__psint_t) sfp); @@ -3291,9 +2999,8 @@ shortform_dir2_entry_check(xfs_mount_t *mp, */ if (no_modify && verify_inum(mp, lino)) { - next_sfep = (xfs_dir2_sf_entry_t *) - ((__psint_t) sfep + - XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp, sfep)); + next_sfep = (xfs_dir2_sf_entry_t *)((__psint_t)sfep + + xfs_dir2_sf_entsize_byentry(sfp, sfep)); continue; } @@ -3343,8 +3050,8 @@ shortform_dir2_entry_check(xfs_mount_t *mp, * check for duplicate names in directory. */ if (!dir_hash_add(mp, hashtab, (xfs_dir2_dataptr_t) - (sfep - XFS_DIR2_SF_FIRSTENTRY(sfp)), - lino, sfep->namelen, sfep->name)) { + (sfep - xfs_dir2_sf_firstentry(sfp)), + lino, sfep->namelen, (char *)sfep->name)) { do_warn(_("entry \"%s\" (ino %llu) in dir %llu is a " "duplicate name"), fname, lino, ino); goto do_junkit; @@ -3398,7 +3105,7 @@ do_junkit: if (lino == orphanage_ino) orphanage_ino = 0; if (!no_modify) { - tmp_elen = XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp, sfep); + tmp_elen = xfs_dir2_sf_entsize_byentry(sfp, sfep); tmp_sfep = (xfs_dir2_sf_entry_t *) ((__psint_t) sfep + tmp_elen); tmp_len = max_size - ((__psint_t) tmp_sfep @@ -3408,8 +3115,8 @@ do_junkit: memmove(sfep, tmp_sfep, tmp_len); - INT_MOD(sfp->hdr.count, ARCH_CONVERT, -1); - memset((void *) ((__psint_t) sfep + tmp_len), 0, + sfp->hdr.count -= 1; + memset((void *)((__psint_t)sfep + tmp_len), 0, tmp_elen); /* @@ -3450,8 +3157,8 @@ do_junkit: next_sfep = (tmp_sfep == NULL) ? (xfs_dir2_sf_entry_t *) ((__psint_t) sfep + ((!bad_sfnamelen) - ? XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp, sfep) - : XFS_DIR2_SF_ENTSIZE_BYNAME(sfp, namelen))) + ? xfs_dir2_sf_entsize_byentry(sfp, sfep) + : xfs_dir2_sf_entsize_byname(sfp, namelen))) : tmp_sfep; } @@ -3579,7 +3286,7 @@ process_dir_inode( * the directory is connected to lost+found. but * we need to create '.' entries here. */ - if (XFS_SB_VERSION_HASDIRV2(&mp->m_sb)) + if (xfs_sb_version_hasdirv2(&mp->m_sb)) longform_dir2_entry_check(mp, ino, ip, &num_illegal, &need_dot, irec, ino_offset, @@ -3610,7 +3317,7 @@ process_dir_inode( libxfs_trans_ijoin(tp, ip, 0); libxfs_trans_ihold(tp, ip); - if (XFS_SB_VERSION_HASDIRV2(&mp->m_sb)) + if (xfs_sb_version_hasdirv2(&mp->m_sb)) shortform_dir2_entry_check(mp, ino, ip, &dirty, irec, ino_offset, hashtab); @@ -3625,7 +3332,7 @@ process_dir_inode( XFS_ILOG_CORE | XFS_ILOG_DDATA); libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES | - XFS_TRANS_SYNC, 0); + XFS_TRANS_SYNC); } else { libxfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES); @@ -3639,6 +3346,30 @@ process_dir_inode( hashval = 0; + /* + * We don't support repairing of v1 dir anymore, report errors and exit + */ + if (!xfs_sb_version_hasdirv2(&mp->m_sb)) { + if (need_root_dotdot && ino == mp->m_sb.sb_rootino) + do_warn(_("missing root directory .. entry, cannot " + "fix in V1 dir filesystem\n")); + + if (num_illegal > 0) { + ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_LOCAL); + + do_warn(_("%d bad entries found in dir inode %llu, " + "cannot fix in V1 dir filesystem\n"), + num_illegal, ino); + } + if (need_dot) { + add_inode_ref(irec, ino_offset); + + do_warn(_("missing \".\" entry in dir ino %llu, " + "cannot in fix V1 dir filesystem\n"), ino); + } + goto out; + } + /* * if we have to create a .. for /, do it now *before* * we delete the bogus entries, otherwise the directory @@ -3668,78 +3399,24 @@ process_dir_inode( XFS_BMAP_INIT(&flist, &first); - error = dir_createname(mp, tp, ip, "..", 2, ip->i_ino, &first, - &flist, nres); + error = libxfs_dir_createname(tp, ip, &xfs_name_dotdot, + ip->i_ino, &first, &flist, nres); if (error) do_error(_("can't make \"..\" entry in root inode " "%llu, createname error %d\n"), ino, error); libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - error = libxfs_bmap_finish(&tp, &flist, first, &committed); + error = libxfs_bmap_finish(&tp, &flist, &committed); ASSERT(error == 0); libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES | - XFS_TRANS_SYNC, 0); + XFS_TRANS_SYNC); need_root_dotdot = 0; } else if (need_root_dotdot && ino == mp->m_sb.sb_rootino) { do_warn(_("would recreate root directory .. entry\n")); } - /* - * delete any illegal entries -- which should only exist - * if the directory is a longform directory. bogus - * shortform directory entries were deleted in phase 4. - */ - if (!no_modify && num_illegal > 0) { - ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_LOCAL); - ASSERT(!XFS_SB_VERSION_HASDIRV2(&mp->m_sb)); - - while (num_illegal > 0 && ip->i_d.di_format != - XFS_DINODE_FMT_LOCAL) { - prune_lf_dir_entry(mp, ino, ip, &hashval); - num_illegal--; - } - - /* - * handle case where we've deleted so many - * entries that the directory has changed from - * a longform to a shortform directory. have - * to allocate a transaction since we're working - * with the incore data fork. - */ - if (num_illegal > 0) { - ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_LOCAL); - tp = libxfs_trans_alloc(mp, 0); - /* - * using the remove reservation is overkill - * since at most we'll only need to log the - * inode but it's easier than wedging a - * new define in ourselves. 10 block fs - * space reservation is also overkill but - * what the heck... - */ - nres = XFS_REMOVE_SPACE_RES(mp); - error = libxfs_trans_reserve(tp, nres, - XFS_REMOVE_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, - XFS_REMOVE_LOG_COUNT); - if (error) - res_failed(error); - - libxfs_trans_ijoin(tp, ip, 0); - libxfs_trans_ihold(tp, ip); - - prune_sf_dir_entry(mp, ino, ip); - - libxfs_trans_log_inode(tp, ip, - XFS_ILOG_CORE | XFS_ILOG_DDATA); - ASSERT(error == 0); - libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES - |XFS_TRANS_SYNC, 0); - } - } - /* * if we need to create the '.' entry, do so only if * the directory is a longform dir. it it's been @@ -3787,23 +3464,22 @@ process_dir_inode( XFS_BMAP_INIT(&flist, &first); - if ((error = dir_createname(mp, tp, ip, ".", - 1, ip->i_ino, &first, &flist, - nres))) + error = libxfs_dir_createname(tp, ip, &xfs_name_dot, + ip->i_ino, &first, &flist, nres); + if (error) do_error(_("can't make \".\" entry in dir ino " "%llu, createname error %d\n"), ino, error); libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - error = libxfs_bmap_finish(&tp, &flist, first, - &committed); + error = libxfs_bmap_finish(&tp, &flist, &committed); ASSERT(error == 0); libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES - |XFS_TRANS_SYNC, 0); + |XFS_TRANS_SYNC); } } - +out: libxfs_iput(ip, 0); } @@ -3884,7 +3560,9 @@ check_for_orphaned_inodes( do_warn(_("disconnected dir inode %llu, "), ino); else do_warn(_("disconnected inode %llu, "), ino); - if (!no_modify) { + if (!xfs_sb_version_hasdirv2(&mp->m_sb)) + do_warn(_("cannot fix in V1 dir filesystem\n")); + else if (!no_modify) { if (!orphanage_ino) orphanage_ino = mk_orphanage(mp); do_warn(_("moving to %s\n"), ORPHANAGE); @@ -3999,7 +3677,10 @@ phase6(xfs_mount_t *mp) * inodes in its chunk if a new chunk was created) are ok */ if (need_root_inode) { - if (!no_modify) { + if (!xfs_sb_version_hasdirv2(&mp->m_sb)) + do_warn(_("need to reinitialize root directory, " + "but not supported on V1 dir filesystem\n")); + else if (!no_modify) { do_warn(_("reinitializing root directory\n")); mk_root_dir(mp); need_root_inode = 0; diff --git a/repair/phase7.c b/repair/phase7.c index 09b426cc7..3452eb690 100644 --- a/repair/phase7.c +++ b/repair/phase7.c @@ -30,7 +30,7 @@ /* dinoc is a pointer to the IN-CORE dinode core */ static void set_nlinks( - xfs_dinode_core_t *dinoc, + xfs_icdinode_t *dinoc, xfs_ino_t ino, __uint32_t nrefs, int *dirty) @@ -108,7 +108,7 @@ update_inode_nlinks( */ ASSERT(error == 0); error = libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES | - XFS_TRANS_SYNC, NULL); + XFS_TRANS_SYNC); ASSERT(error == 0); } diff --git a/repair/prefetch.c b/repair/prefetch.c index e8a492fa6..6d293aa63 100644 --- a/repair/prefetch.c +++ b/repair/prefetch.c @@ -16,7 +16,11 @@ #include "progress.h" #include "radix-tree.h" +#ifdef HAVE_PTHREAD_H int do_prefetch = 1; +#else +int do_prefetch = 0; +#endif /* * Performs prefetching by priming the libxfs cache by using a dedicate thread @@ -173,8 +177,8 @@ pf_read_bmbt_reclist( xfs_dfilblks_t cp = 0; /* prev count */ xfs_dfiloff_t op = 0; /* prev offset */ - for (i = 0; i < numrecs; i++, rp++) { - libxfs_bmbt_disk_get_all(rp, &irec); + for (i = 0; i < numrecs; i++) { + libxfs_bmbt_disk_get_all(rp + i, &irec); if (((i > 0) && (op + cp > irec.br_startoff)) || (irec.br_blockcount == 0) || @@ -246,7 +250,6 @@ pf_scanfunc_bmap( int isadir, prefetch_args_t *args) { - xfs_bmbt_rec_t *rp; xfs_bmbt_ptr_t *pp; int numrecs; int i; @@ -264,18 +267,14 @@ pf_scanfunc_bmap( if (level == 0) { if (numrecs > mp->m_bmap_dmxr[0] || !isadir) return 0; - - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, - block, 1, mp->m_bmap_dmxr[0]); - - return pf_read_bmbt_reclist(args, rp, numrecs); + return pf_read_bmbt_reclist(args, + XFS_BTREE_REC_ADDR(xfs_bmbt, block, 1), numrecs); } if (numrecs > mp->m_bmap_dmxr[1]) return 0; - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, 1, - mp->m_bmap_dmxr[1]); + pp = XFS_BTREE_PTR_ADDR(xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]); for (i = 0; i < numrecs; i++) { dbno = be64_to_cpu(pp[i]); @@ -317,8 +316,8 @@ pf_read_btinode( return; dsize = XFS_DFORK_DSIZE(dino, mp); - pp = XFS_BTREE_PTR_ADDR(dsize, xfs_bmdr, dib, 1, - XFS_BTREE_BLOCK_MAXRECS(dsize, xfs_bmdr, 0)); + pp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dib, 1, + XFS_BTREE_BLOCK_MAXRECS(dsize, xfs_bmdr, 0)); for (i = 0; i < numrecs; i++) { dbno = be64_to_cpu(pp[i]); @@ -763,9 +762,12 @@ start_inode_prefetch( INIT_RADIX_TREE(&args->primary_io_queue, 0); INIT_RADIX_TREE(&args->secondary_io_queue, 0); - pthread_mutex_init(&args->lock, NULL); - pthread_cond_init(&args->start_reading, NULL); - pthread_cond_init(&args->start_processing, NULL); + if (pthread_mutex_init(&args->lock, NULL) != 0) + do_error(_("failed to initialize prefetch mutex\n")); + if (pthread_cond_init(&args->start_reading, NULL) != 0) + do_error(_("failed to initialize prefetch cond var\n")); + if (pthread_cond_init(&args->start_processing, NULL) != 0) + do_error(_("failed to initialize prefetch cond var\n")); args->agno = agno; args->dirs_only = dirs_only; diff --git a/repair/rt.c b/repair/rt.c index 587157507..7036aa2b2 100644 --- a/repair/rt.c +++ b/repair/rt.c @@ -193,7 +193,8 @@ process_rtbitmap(xfs_mount_t *mp, extno = 0; error = 0; - end_bmbno = howmany(INT_GET(dino->di_core.di_size, ARCH_CONVERT), mp->m_sb.sb_blocksize); + end_bmbno = howmany(be64_to_cpu(dino->di_core.di_size), + mp->m_sb.sb_blocksize); for (bmbno = 0; bmbno < end_bmbno; bmbno++) { bno = blkmap_get(blkmap, bmbno); diff --git a/repair/sb.c b/repair/sb.c index 589e32589..c963f3aad 100644 --- a/repair/sb.c +++ b/repair/sb.c @@ -65,10 +65,10 @@ copy_sb(xfs_sb_t *source, xfs_sb_t *dest) * secondaries and cannot be changed at run time in * the primary superblock */ - if (XFS_SB_VERSION_HASDALIGN(source)) - XFS_SB_VERSION_ADDDALIGN(dest); - if (XFS_SB_VERSION_HASEXTFLGBIT(source)) - XFS_SB_VERSION_ADDEXTFLGBIT(dest); + if (xfs_sb_version_hasdalign(source)) + dest->sb_versionnum |= XFS_SB_VERSION_DALIGNBIT; + if (xfs_sb_version_hasextflgbit(source)) + dest->sb_versionnum |= XFS_SB_VERSION_EXTFLGBIT; /* * these are all supposed to be zero or will get reset anyway @@ -133,8 +133,8 @@ find_secondary_sb(xfs_sb_t *rsb) * we don't know how big the sectors really are. */ for (i = 0; !done && i < bsize; i += BBSIZE) { - c_bufsb = (char *) sb + i; - libxfs_xlate_sb(c_bufsb, &bufsb, 1, XFS_SB_ALL_BITS); + c_bufsb = (char *)sb + i; + libxfs_sb_from_disk(&bufsb, (xfs_dsb_t *)c_bufsb); if (verify_sb(&bufsb, 0) != XR_OK) continue; @@ -233,7 +233,7 @@ verify_sb(xfs_sb_t *sb, int is_primary_sb) if (sb->sb_magicnum != XFS_SB_MAGIC) return(XR_BAD_MAGIC); - if (!XFS_SB_GOOD_VERSION(sb)) + if (!xfs_sb_good_version(sb)) return(XR_BAD_VERSION); /* does sb think mkfs really finished ? */ @@ -298,7 +298,7 @@ verify_sb(xfs_sb_t *sb, int is_primary_sb) if (i != sb->sb_sectlog) return(XR_BAD_SECT_SIZE_DATA); - if (XFS_SB_VERSION_HASSECTOR(sb)) { + if (xfs_sb_version_hassector(sb)) { /* check to make sure log sector is legal 2^N, 9 <= N <= 15 */ @@ -361,7 +361,7 @@ verify_sb(xfs_sb_t *sb, int is_primary_sb) /* * verify correctness of inode alignment if it's there */ - if (XFS_SB_VERSION_HASALIGN(sb)) { + if (xfs_sb_version_hasalign(sb)) { align = calc_ino_align(sb); if (align != sb->sb_inoalignmt) @@ -377,7 +377,7 @@ verify_sb(xfs_sb_t *sb, int is_primary_sb) /* * verify stripe alignment fields if present */ - if (XFS_SB_VERSION_HASDALIGN(sb)) { + if (xfs_sb_version_hasdalign(sb)) { if ((!sb->sb_unit && sb->sb_width) || (sb->sb_unit && sb->sb_agblocks % sb->sb_unit)) return(XR_BAD_SB_UNIT); @@ -389,7 +389,7 @@ verify_sb(xfs_sb_t *sb, int is_primary_sb) /* * if shared bit is set, verify that the version number is sane */ - if (XFS_SB_VERSION_HASSHARED(sb)) { + if (xfs_sb_version_hasshared(sb)) { if (sb->sb_shared_vn > XFS_SB_MAX_SHARED_VN) return(XR_BAD_SVN); } @@ -414,9 +414,9 @@ verify_sb(xfs_sb_t *sb, int is_primary_sb) * shared version # and inode alignment fields * should be valid */ - if (sb->sb_shared_vn && !XFS_SB_VERSION_HASSHARED(sb)) + if (sb->sb_shared_vn && !xfs_sb_version_hasshared(sb)) return(XR_BAD_SVN); - if (sb->sb_inoalignmt && !XFS_SB_VERSION_HASALIGN(sb)) + if (sb->sb_inoalignmt && !xfs_sb_version_hasalign(sb)) return(XR_BAD_INO_ALIGN); } if ((!pre_65_beta && @@ -426,9 +426,9 @@ verify_sb(xfs_sb_t *sb, int is_primary_sb) /* * stripe alignment values should be valid */ - if (sb->sb_unit && !XFS_SB_VERSION_HASDALIGN(sb)) + if (sb->sb_unit && !xfs_sb_version_hasdalign(sb)) return(XR_BAD_SB_UNIT); - if (sb->sb_width && !XFS_SB_VERSION_HASDALIGN(sb)) + if (sb->sb_width && !xfs_sb_version_hasdalign(sb)) return(XR_BAD_SB_WIDTH); } @@ -447,12 +447,13 @@ verify_sb(xfs_sb_t *sb, int is_primary_sb) void write_primary_sb(xfs_sb_t *sbp, int size) { - void *buf; + xfs_dsb_t *buf; if (no_modify) return; - if ((buf = memalign(libxfs_device_alignment(), size)) == NULL) { + buf = memalign(libxfs_device_alignment(), size); + if (buf == NULL) { do_error(_("failed to memalign superblock buffer\n")); return; } @@ -463,7 +464,8 @@ write_primary_sb(xfs_sb_t *sbp, int size) do_error(_("couldn't seek to offset 0 in filesystem\n")); } - libxfs_xlate_sb(buf, sbp, -1, XFS_SB_ALL_BITS); + + libxfs_sb_to_disk(buf, sbp, XFS_SB_ALL_BITS); if (write(x.dfd, buf, size) != size) { free(buf); @@ -480,9 +482,10 @@ int get_sb(xfs_sb_t *sbp, xfs_off_t off, int size, xfs_agnumber_t agno) { int error, rval; - void *buf; + xfs_dsb_t *buf; - if ((buf = memalign(libxfs_device_alignment(), size)) == NULL) { + buf = memalign(libxfs_device_alignment(), size); + if (buf == NULL) { do_error( _("error reading superblock %u -- failed to memalign buffer\n"), agno, off); @@ -506,7 +509,7 @@ get_sb(xfs_sb_t *sbp, xfs_off_t off, int size, xfs_agnumber_t agno) off, size, agno, rval); do_error("%s\n", strerror(error)); } - libxfs_xlate_sb(buf, sbp, 1, XFS_SB_ALL_BITS); + libxfs_sb_from_disk(sbp, buf); free(buf); return (verify_sb(sbp, 0)); @@ -597,17 +600,17 @@ get_sb_geometry(fs_geometry_t *geo, xfs_sb_t *sbp) geo->sb_sectsize = sbp->sb_sectsize; geo->sb_inodesize = sbp->sb_inodesize; - if (XFS_SB_VERSION_HASALIGN(sbp)) + if (xfs_sb_version_hasalign(sbp)) geo->sb_ialignbit = 1; - if (XFS_SB_VERSION_HASSHARED(sbp) || + if (xfs_sb_version_hasshared(sbp) || sbp->sb_versionnum & XR_PART_SECSB_VNMASK) geo->sb_sharedbit = 1; - if (XFS_SB_VERSION_HASDALIGN(sbp)) + if (xfs_sb_version_hasdalign(sbp)) geo->sb_salignbit = 1; - if (XFS_SB_VERSION_HASEXTFLGBIT(sbp)) + if (xfs_sb_version_hasextflgbit(sbp)) geo->sb_extflgbit = 1; /* @@ -629,7 +632,7 @@ get_sb_geometry(fs_geometry_t *geo, xfs_sb_t *sbp) geo->sb_inoalignmt = sbp->sb_inoalignmt; if ((!pre_65_beta && (sbp->sb_versionnum & XR_GOOD_SECSB_VNMASK)) || - (pre_65_beta && XFS_SB_VERSION_HASDALIGN(sbp))) { + (pre_65_beta && xfs_sb_version_hasdalign(sbp))) { geo->sb_unit = sbp->sb_unit; geo->sb_width = sbp->sb_width; } diff --git a/repair/scan.c b/repair/scan.c index b9f7bc9d3..44381b11a 100644 --- a/repair/scan.c +++ b/repair/scan.c @@ -145,10 +145,11 @@ scanfunc_bmap( int err; xfs_bmbt_ptr_t *pp; xfs_bmbt_key_t *pkey; - xfs_bmbt_rec_32_t *rp; + xfs_bmbt_rec_t *rp; xfs_dfiloff_t first_key; xfs_dfiloff_t last_key; char *forkname; + int numrecs; if (whichfork == XFS_DATA_FORK) forkname = _("data"); @@ -162,18 +163,16 @@ scanfunc_bmap( * another inode are claiming the same block but that's * highly unlikely. */ - if (INT_GET(block->bb_magic, ARCH_CONVERT) != XFS_BMAP_MAGIC) { - do_warn( - _("bad magic # %#x in inode %llu (%s fork) bmbt block %llu\n"), - INT_GET(block->bb_magic, ARCH_CONVERT), + if (be32_to_cpu(block->bb_magic) != XFS_BMAP_MAGIC) { + do_warn(_("bad magic # %#x in inode %llu (%s fork) bmbt " + "block %llu\n"), be32_to_cpu(block->bb_magic), ino, forkname, bno); return(1); } - if (INT_GET(block->bb_level, ARCH_CONVERT) != level) { - do_warn( -_("expected level %d got %d in inode %llu, (%s fork) bmbt block %llu\n"), - level, INT_GET(block->bb_level, ARCH_CONVERT), - ino, forkname, bno); + if (be16_to_cpu(block->bb_level) != level) { + do_warn(_("expected level %d got %d in inode %llu, (%s fork) " + "bmbt block %llu\n"), level, + be16_to_cpu(block->bb_level), ino, forkname, bno); return(1); } @@ -198,13 +197,12 @@ _("bad fwd (right) sibling pointer (saw %llu parent block says %llu)\n" bm_cursor->level[level].fsbno); return(1); } - if (INT_GET(block->bb_leftsib, ARCH_CONVERT) != + if (be64_to_cpu(block->bb_leftsib) != bm_cursor->level[level].fsbno) { do_warn( _("bad back (left) sibling pointer (saw %llu parent block says %llu)\n" "\tin inode %llu (%s fork) bmap btree block %llu\n"), - INT_GET(block->bb_leftsib, - ARCH_CONVERT), + be64_to_cpu(block->bb_leftsib), bm_cursor->level[level].fsbno, ino, forkname, bno); return(1); @@ -214,13 +212,11 @@ _("bad back (left) sibling pointer (saw %llu parent block says %llu)\n" * This is the first or only block on this level. * Check that the left sibling pointer is NULL */ - if (INT_GET(block->bb_leftsib, ARCH_CONVERT) != - NULLDFSBNO) { + if (be64_to_cpu(block->bb_leftsib) != NULLDFSBNO) { do_warn( _("bad back (left) sibling pointer (saw %llu should be NULL (0))\n" "\tin inode %llu (%s fork) bmap btree block %llu\n"), - INT_GET(block->bb_leftsib, - ARCH_CONVERT), + be64_to_cpu(block->bb_leftsib), ino, forkname, bno); return(1); } @@ -231,9 +227,9 @@ _("bad back (left) sibling pointer (saw %llu should be NULL (0))\n" */ bm_cursor->level[level].fsbno = bno; bm_cursor->level[level].left_fsbno = - INT_GET(block->bb_leftsib, ARCH_CONVERT); + be64_to_cpu(block->bb_leftsib); bm_cursor->level[level].right_fsbno = - INT_GET(block->bb_rightsib, ARCH_CONVERT); + be64_to_cpu(block->bb_rightsib); switch (get_fsbno_state(mp, bno)) { case XR_E_UNKNOWN: @@ -297,30 +293,26 @@ _("bad back (left) sibling pointer (saw %llu should be NULL (0))\n" } } (*tot)++; + numrecs = be16_to_cpu(block->bb_numrecs); + if (level == 0) { - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > - mp->m_bmap_dmxr[0] || - (isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < - mp->m_bmap_dmnr[0])) { + if (numrecs > mp->m_bmap_dmxr[0] || (isroot == 0 && numrecs < + mp->m_bmap_dmnr[0])) { do_warn( _("inode 0x%llx bad # of bmap records (%u, min - %u, max - %u)\n"), - ino, INT_GET(block->bb_numrecs, ARCH_CONVERT), - mp->m_bmap_dmnr[0], mp->m_bmap_dmxr[0]); + ino, numrecs, mp->m_bmap_dmnr[0], + mp->m_bmap_dmxr[0]); return(1); } - rp = (xfs_bmbt_rec_32_t *) - XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, - block, 1, mp->m_bmap_dmxr[0]); - *nex += INT_GET(block->bb_numrecs, ARCH_CONVERT); + rp = XFS_BTREE_REC_ADDR(xfs_bmbt, block, 1); + *nex += numrecs; /* * XXX - if we were going to fix up the btree record, * we'd do it right here. For now, if there's a problem, * we'll bail out and presumably clear the inode. */ if (check_dups == 0) { - err = process_bmbt_reclist(mp, rp, - INT_GET(block->bb_numrecs, - ARCH_CONVERT), + err = process_bmbt_reclist(mp, rp, numrecs, type, ino, tot, blkmapp, &first_key, &last_key, whichfork); @@ -351,41 +343,36 @@ _("out-of-order bmap key (file offset) in inode %llu, %s fork, fsbno %llu\n"), return(0); } else - return(scan_bmbt_reclist(mp, rp, INT_GET(block->bb_numrecs, ARCH_CONVERT), + return(scan_bmbt_reclist(mp, rp, numrecs, type, ino, tot, whichfork)); } - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_bmap_dmxr[1] || - (isroot == 0 && - INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_bmap_dmnr[1])) { + if (numrecs > mp->m_bmap_dmxr[1] || (isroot == 0 && numrecs < + mp->m_bmap_dmnr[1])) { do_warn( _("inode 0x%llx bad # of bmap records (%u, min - %u, max - %u)\n"), - ino, INT_GET(block->bb_numrecs, ARCH_CONVERT), - mp->m_bmap_dmnr[1], mp->m_bmap_dmxr[1]); + ino, numrecs, mp->m_bmap_dmnr[1], mp->m_bmap_dmxr[1]); return(1); } - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, 1, - mp->m_bmap_dmxr[1]); - pkey = XFS_BTREE_KEY_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, 1, - mp->m_bmap_dmxr[1]); + pp = XFS_BTREE_PTR_ADDR(xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]); + pkey = XFS_BTREE_KEY_ADDR(xfs_bmbt, block, 1); last_key = NULLDFILOFF; - for (i = 0, err = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) { + for (i = 0, err = 0; i < numrecs; i++) { /* * XXX - if we were going to fix up the interior btree nodes, * we'd do it right here. For now, if there's a problem, * we'll bail out and presumably clear the inode. */ - if (!verify_dfsbno(mp, INT_GET(pp[i], ARCH_CONVERT))) { + if (!verify_dfsbno(mp, be64_to_cpu(pp[i]))) { do_warn(_("bad bmap btree ptr 0x%llx in ino %llu\n"), - INT_GET(pp[i], ARCH_CONVERT), ino); + be64_to_cpu(pp[i]), ino); return(1); } - err = scan_lbtree(INT_GET(pp[i], ARCH_CONVERT), - level, scanfunc_bmap, type, whichfork, - ino, tot, nex, blkmapp, bm_cursor, 0, - check_dups); + err = scan_lbtree(be64_to_cpu(pp[i]), level, scanfunc_bmap, + type, whichfork, ino, tot, nex, blkmapp, + bm_cursor, 0, check_dups); if (err) return(1); @@ -401,30 +388,26 @@ _("out-of-order bmap key (file offset) in inode %llu, %s fork, fsbno %llu\n"), * our child and those are guaranteed to be set by the * call to scan_lbtree() above. */ - if (check_dups == 0 && - INT_GET(pkey[i].br_startoff, ARCH_CONVERT) != + if (check_dups == 0 && be64_to_cpu(pkey[i].br_startoff) != bm_cursor->level[level-1].first_key) { if (!no_modify) { do_warn( _("correcting bt key (was %llu, now %llu) in inode %llu\n" "\t\t%s fork, btree block %llu\n"), - INT_GET(pkey[i].br_startoff, - ARCH_CONVERT), + be64_to_cpu(pkey[i].br_startoff), bm_cursor->level[level-1].first_key, ino, forkname, bno); *dirty = 1; - INT_SET(pkey[i].br_startoff, ARCH_CONVERT, + pkey[i].br_startoff = cpu_to_be64( bm_cursor->level[level-1].first_key); } else { do_warn( _("bad btree key (is %llu, should be %llu) in inode %llu\n" "\t\t%s fork, btree block %llu\n"), - INT_GET(pkey[i].br_startoff, - ARCH_CONVERT), + be64_to_cpu(pkey[i].br_startoff), bm_cursor->level[level-1].first_key, - ino, - forkname, bno); + ino, forkname, bno); } } } @@ -434,14 +417,13 @@ _("out-of-order bmap key (file offset) in inode %llu, %s fork, fsbno %llu\n"), * block's forward sibling pointer is NULL. */ if (check_dups == 0 && - bm_cursor->level[level].right_fsbno == NULLDFSBNO && - bm_cursor->level[level - 1].right_fsbno != NULLDFSBNO) { + bm_cursor->level[level].right_fsbno == NULLDFSBNO && + bm_cursor->level[level - 1].right_fsbno != NULLDFSBNO) { do_warn( _("bad fwd (right) sibling pointer (saw %llu should be NULLDFSBNO)\n" "\tin inode %llu (%s fork) bmap btree block %llu\n"), bm_cursor->level[level - 1].right_fsbno, - ino, forkname, - bm_cursor->level[level - 1].fsbno); + ino, forkname, bm_cursor->level[level - 1].fsbno); return(1); } @@ -450,10 +432,9 @@ _("out-of-order bmap key (file offset) in inode %llu, %s fork, fsbno %llu\n"), */ if (check_dups == 0) { bm_cursor->level[level].first_key = - INT_GET(pkey[0].br_startoff, ARCH_CONVERT); - i = INT_GET(block->bb_numrecs, ARCH_CONVERT) - 1; + be64_to_cpu(pkey[0].br_startoff); bm_cursor->level[level].last_key = - INT_GET(pkey[i].br_startoff, ARCH_CONVERT); + be64_to_cpu(pkey[numrecs - 1].br_startoff); } return(0); @@ -478,17 +459,16 @@ scanfunc_bno( int numrecs; int state; - if (INT_GET(block->bb_magic, ARCH_CONVERT) != XFS_ABTB_MAGIC) { + if (be32_to_cpu(block->bb_magic) != XFS_ABTB_MAGIC) { do_warn(_("bad magic # %#x in btbno block %d/%d\n"), - INT_GET(block->bb_magic, ARCH_CONVERT), agno, bno); + be32_to_cpu(block->bb_magic), agno, bno); hdr_errors++; if (suspect) return; } - if (INT_GET(block->bb_level, ARCH_CONVERT) != level) { + if (be16_to_cpu(block->bb_level) != level) { do_warn(_("expected level %d got %d in btbno block %d/%d\n"), - level, INT_GET(block->bb_level, ARCH_CONVERT), - agno, bno); + level, be16_to_cpu(block->bb_level), agno, bno); hdr_errors++; if (suspect) return; @@ -511,16 +491,15 @@ _("bno freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n") return; } + numrecs = be16_to_cpu(block->bb_numrecs); + if (level == 0) { - numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT); - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > - mp->m_alloc_mxr[0]) { + if (numrecs > mp->m_alloc_mxr[0]) { numrecs = mp->m_alloc_mxr[0]; hdr_errors++; } - if (isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < - mp->m_alloc_mnr[0]) { + if (isroot == 0 && numrecs < mp->m_alloc_mnr[0]) { numrecs = mp->m_alloc_mnr[0]; hdr_errors++; } @@ -528,22 +507,21 @@ _("bno freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n") if (hdr_errors) suspect++; - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, - 1, mp->m_alloc_mxr[0]); + rp = XFS_BTREE_REC_ADDR(xfs_alloc, block, 1); for (i = 0; i < numrecs; i++) { - if (INT_GET(rp[i].ar_blockcount, ARCH_CONVERT) == 0 || - INT_GET(rp[i].ar_startblock, ARCH_CONVERT) == 0 || + if (be32_to_cpu(rp[i].ar_blockcount) == 0 || + be32_to_cpu(rp[i].ar_startblock) == 0 || !verify_agbno(mp, agno, - INT_GET(rp[i].ar_startblock, ARCH_CONVERT)) || - INT_GET(rp[i].ar_blockcount, ARCH_CONVERT) > + be32_to_cpu(rp[i].ar_startblock)) || + be32_to_cpu(rp[i].ar_blockcount) > MAXEXTLEN) continue; - e = INT_GET(rp[i].ar_startblock, ARCH_CONVERT) + - INT_GET(rp[i].ar_blockcount, ARCH_CONVERT); + e = be32_to_cpu(rp[i].ar_startblock) + + be32_to_cpu(rp[i].ar_blockcount); if (!verify_agbno(mp, agno, e - 1)) continue; - for (b = INT_GET(rp[i].ar_startblock, ARCH_CONVERT); + for (b = be32_to_cpu(rp[i].ar_startblock); b < e; b++) { if (get_agbno_state(mp, agno, b) == XR_E_UNKNOWN) @@ -563,16 +541,13 @@ _("bno freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n") /* * interior record */ - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, 1, - mp->m_alloc_mxr[1]); + pp = XFS_BTREE_PTR_ADDR(xfs_alloc, block, 1, mp->m_alloc_mxr[1]); - numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT); - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_alloc_mxr[1]) { + if (numrecs > mp->m_alloc_mxr[1]) { numrecs = mp->m_alloc_mxr[1]; hdr_errors++; } - if (isroot == 0 && - INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_alloc_mnr[1]) { + if (isroot == 0 && numrecs < mp->m_alloc_mnr[1]) { numrecs = mp->m_alloc_mnr[1]; hdr_errors++; } @@ -601,10 +576,10 @@ _("bno freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n") * pointer mismatch, try and extract as much data * as possible. */ - if (INT_GET(pp[i], ARCH_CONVERT) != 0 && - verify_agbno(mp, agno, INT_GET(pp[i], ARCH_CONVERT))) - scan_sbtree(INT_GET(pp[i], ARCH_CONVERT), - level, agno, suspect, scanfunc_bno, 0); + if (be32_to_cpu(pp[i]) != 0 && verify_agbno(mp, agno, + be32_to_cpu(pp[i]))) + scan_sbtree(be32_to_cpu(pp[i]), level, agno, + suspect, scanfunc_bno, 0); } } @@ -630,17 +605,16 @@ scanfunc_cnt( block = (xfs_alloc_block_t *)ablock; hdr_errors = 0; - if (INT_GET(block->bb_magic, ARCH_CONVERT) != XFS_ABTC_MAGIC) { + if (be32_to_cpu(block->bb_magic) != XFS_ABTC_MAGIC) { do_warn(_("bad magic # %#x in btcnt block %d/%d\n"), - INT_GET(block->bb_magic, ARCH_CONVERT), agno, bno); + be32_to_cpu(block->bb_magic), agno, bno); hdr_errors++; if (suspect) return; } - if (INT_GET(block->bb_level, ARCH_CONVERT) != level) { + if (be16_to_cpu(block->bb_level) != level) { do_warn(_("expected level %d got %d in btcnt block %d/%d\n"), - level, INT_GET(block->bb_level, ARCH_CONVERT), - agno, bno); + level, be16_to_cpu(block->bb_level), agno, bno); hdr_errors++; if (suspect) return; @@ -663,16 +637,14 @@ _("bcnt freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n" return; } - if (level == 0) { - numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT); + numrecs = be16_to_cpu(block->bb_numrecs); - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > - mp->m_alloc_mxr[0]) { + if (level == 0) { + if (numrecs > mp->m_alloc_mxr[0]) { numrecs = mp->m_alloc_mxr[0]; hdr_errors++; } - if (isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < - mp->m_alloc_mnr[0]) { + if (isroot == 0 && numrecs < mp->m_alloc_mnr[0]) { numrecs = mp->m_alloc_mnr[0]; hdr_errors++; } @@ -680,23 +652,21 @@ _("bcnt freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n" if (hdr_errors) suspect++; - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, - 1, mp->m_alloc_mxr[0]); + rp = XFS_BTREE_REC_ADDR(xfs_alloc, block, 1); for (i = 0; i < numrecs; i++) { - if (INT_GET(rp[i].ar_blockcount, ARCH_CONVERT) == 0 || - INT_GET(rp[i].ar_startblock, ARCH_CONVERT) == 0 || - !verify_agbno(mp, agno, - INT_GET(rp[i].ar_startblock, ARCH_CONVERT)) || - INT_GET(rp[i].ar_blockcount, ARCH_CONVERT) > - MAXEXTLEN) + if (be32_to_cpu(rp[i].ar_blockcount) == 0 || + be32_to_cpu(rp[i].ar_startblock) == 0 || + !verify_agbno(mp, agno, be32_to_cpu( + rp[i].ar_startblock)) || + be32_to_cpu(rp[i].ar_blockcount) > + MAXEXTLEN) continue; - e = INT_GET(rp[i].ar_startblock, ARCH_CONVERT) + - INT_GET(rp[i].ar_blockcount, ARCH_CONVERT); + e = be32_to_cpu(rp[i].ar_startblock) + + be32_to_cpu(rp[i].ar_blockcount); if (!verify_agbno(mp, agno, e - 1)) continue; - for (b = INT_GET(rp[i].ar_startblock, ARCH_CONVERT); - b < e; b++) { + for (b = be32_to_cpu(rp[i].ar_startblock); b < e; b++) { state = get_agbno_state(mp, agno, b); /* * no warning messages -- we'll catch @@ -724,16 +694,13 @@ _("bcnt freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n" /* * interior record */ - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, 1, - mp->m_alloc_mxr[1]); + pp = XFS_BTREE_PTR_ADDR(xfs_alloc, block, 1, mp->m_alloc_mxr[1]); - numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT); - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_alloc_mxr[1]) { + if (numrecs > mp->m_alloc_mxr[1]) { numrecs = mp->m_alloc_mxr[1]; hdr_errors++; } - if (isroot == 0 && - INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_alloc_mnr[1]) { + if (isroot == 0 && numrecs < mp->m_alloc_mnr[1]) { numrecs = mp->m_alloc_mnr[1]; hdr_errors++; } @@ -752,11 +719,12 @@ _("bcnt freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n" else suspect++; } - for (i = 0; i < numrecs; i++) - if (INT_GET(pp[i], ARCH_CONVERT) != 0 && - verify_agbno(mp, agno, INT_GET(pp[i], ARCH_CONVERT))) - scan_sbtree(INT_GET(pp[i], ARCH_CONVERT), level, agno, - suspect, scanfunc_cnt, 0); + for (i = 0; i < numrecs; i++) { + if (be32_to_cpu(pp[i]) != 0 && verify_agbno(mp, agno, + be32_to_cpu(pp[i]))) + scan_sbtree(be32_to_cpu(pp[i]), level, agno, + suspect, scanfunc_cnt, 0); + } } /* @@ -803,18 +771,17 @@ scanfunc_ino( block = (xfs_inobt_block_t *)ablock; hdr_errors = 0; - if (INT_GET(block->bb_magic, ARCH_CONVERT) != XFS_IBT_MAGIC) { + if (be32_to_cpu(block->bb_magic) != XFS_IBT_MAGIC) { do_warn(_("bad magic # %#x in inobt block %d/%d\n"), - INT_GET(block->bb_magic, ARCH_CONVERT), agno, bno); + be32_to_cpu(block->bb_magic), agno, bno); hdr_errors++; bad_ino_btree = 1; if (suspect) return; } - if (INT_GET(block->bb_level, ARCH_CONVERT) != level) { + if (be16_to_cpu(block->bb_level) != level) { do_warn(_("expected level %d got %d in inobt block %d/%d\n"), - level, INT_GET(block->bb_level, ARCH_CONVERT), - agno, bno); + level, be16_to_cpu(block->bb_level), agno, bno); hdr_errors++; bad_ino_btree = 1; if (suspect) @@ -840,7 +807,7 @@ _("inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), state, agno, bno, suspect); } - numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT); + numrecs = be16_to_cpu(block->bb_numrecs); /* * leaf record in btree @@ -848,13 +815,11 @@ _("inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), if (level == 0) { /* check for trashed btree block */ - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > - mp->m_inobt_mxr[0]) { + if (numrecs > mp->m_inobt_mxr[0]) { numrecs = mp->m_inobt_mxr[0]; hdr_errors++; } - if (isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < - mp->m_inobt_mnr[0]) { + if (isroot == 0 && numrecs < mp->m_inobt_mnr[0]) { numrecs = mp->m_inobt_mnr[0]; hdr_errors++; } @@ -866,8 +831,7 @@ _("inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), suspect++; } - rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_inobt, block, - 1, mp->m_inobt_mxr[0]); + rp = XFS_BTREE_REC_ADDR(xfs_inobt, block, 1); /* * step through the records, each record points to @@ -878,7 +842,7 @@ _("inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), * the block. skip processing of bogus records. */ for (i = 0; i < numrecs; i++) { - ino = INT_GET(rp[i].ir_startino, ARCH_CONVERT); + ino = be32_to_cpu(rp[i].ir_startino); off = XFS_AGINO_TO_OFFSET(mp, ino); agbno = XFS_AGINO_TO_AGBNO(mp, ino); lino = XFS_AGINO_TO_INO(mp, agno, ino); @@ -1029,11 +993,11 @@ _("inode rec for ino %llu (%d/%d) overlaps existing rec (start %d/%d)\n"), } } - if (nfree != INT_GET(rp[i].ir_freecount, ARCH_CONVERT)) { - do_warn( -_("ir_freecount/free mismatch, inode chunk %d/%d, freecount %d nfree %d\n"), - agno, ino, INT_GET(rp[i].ir_freecount, - ARCH_CONVERT), nfree); + if (nfree != be32_to_cpu(rp[i].ir_freecount)) { + do_warn(_("ir_freecount/free mismatch, inode " + "chunk %d/%d, freecount %d nfree %d\n"), + agno, ino, + be32_to_cpu(rp[i].ir_freecount), nfree); } } @@ -1046,18 +1010,16 @@ _("ir_freecount/free mismatch, inode chunk %d/%d, freecount %d nfree %d\n"), /* * interior record, continue on */ - if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_inobt_mxr[1]) { + if (numrecs > mp->m_inobt_mxr[1]) { numrecs = mp->m_inobt_mxr[1]; hdr_errors++; } - if (isroot == 0 && - INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_inobt_mnr[1]) { + if (isroot == 0 && numrecs < mp->m_inobt_mnr[1]) { numrecs = mp->m_inobt_mnr[1]; hdr_errors++; } - pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_inobt, block, 1, - mp->m_inobt_mxr[1]); + pp = XFS_BTREE_PTR_ADDR(xfs_inobt, block, 1, mp->m_inobt_mxr[1]); /* * don't pass bogus tree flag down further if this block @@ -1075,10 +1037,10 @@ _("ir_freecount/free mismatch, inode chunk %d/%d, freecount %d nfree %d\n"), } for (i = 0; i < numrecs; i++) { - if (INT_GET(pp[i], ARCH_CONVERT) != 0 && - verify_agbno(mp, agno, INT_GET(pp[i], ARCH_CONVERT))) - scan_sbtree(INT_GET(pp[i], ARCH_CONVERT), level, - agno, suspect, scanfunc_ino, 0); + if (be32_to_cpu(pp[i]) != 0 && verify_agbno(mp, agno, + be32_to_cpu(pp[i]))) + scan_sbtree(be32_to_cpu(pp[i]), level, agno, + suspect, scanfunc_ino, 0); } } @@ -1093,42 +1055,41 @@ scan_freelist( int i; if (XFS_SB_BLOCK(mp) != XFS_AGFL_BLOCK(mp) && - XFS_AGF_BLOCK(mp) != XFS_AGFL_BLOCK(mp) && - XFS_AGI_BLOCK(mp) != XFS_AGFL_BLOCK(mp)) - set_agbno_state(mp, INT_GET(agf->agf_seqno, ARCH_CONVERT), - XFS_AGFL_BLOCK(mp), XR_E_FS_MAP); - if (INT_GET(agf->agf_flcount, ARCH_CONVERT) == 0) + XFS_AGF_BLOCK(mp) != XFS_AGFL_BLOCK(mp) && + XFS_AGI_BLOCK(mp) != XFS_AGFL_BLOCK(mp)) + set_agbno_state(mp, be32_to_cpu(agf->agf_seqno), + XFS_AGFL_BLOCK(mp), XR_E_FS_MAP); + if (be32_to_cpu(agf->agf_flcount) == 0) return; - agflbuf = libxfs_readbuf(mp->m_dev, - XFS_AG_DADDR(mp, INT_GET(agf->agf_seqno, ARCH_CONVERT), + agflbuf = libxfs_readbuf(mp->m_dev, XFS_AG_DADDR(mp, + be32_to_cpu(agf->agf_seqno), XFS_AGFL_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), 0); if (!agflbuf) { do_abort(_("can't read agfl block for ag %d\n"), - INT_GET(agf->agf_seqno, ARCH_CONVERT)); + be32_to_cpu(agf->agf_seqno)); return; } agfl = XFS_BUF_TO_AGFL(agflbuf); - i = INT_GET(agf->agf_flfirst, ARCH_CONVERT); + i = be32_to_cpu(agf->agf_flfirst); count = 0; for (;;) { - bno = INT_GET(agfl->agfl_bno[i], ARCH_CONVERT); - if (verify_agbno(mp, INT_GET(agf->agf_seqno,ARCH_CONVERT), bno)) - set_agbno_state(mp, - INT_GET(agf->agf_seqno, ARCH_CONVERT), - bno, XR_E_FREE); + bno = be32_to_cpu(agfl->agfl_bno[i]); + if (verify_agbno(mp, be32_to_cpu(agf->agf_seqno), bno)) + set_agbno_state(mp, be32_to_cpu(agf->agf_seqno), + bno, XR_E_FREE); else do_warn(_("bad agbno %u in agfl, agno %d\n"), - bno, INT_GET(agf->agf_seqno, ARCH_CONVERT)); + bno, be32_to_cpu(agf->agf_seqno)); count++; - if (i == INT_GET(agf->agf_fllast, ARCH_CONVERT)) + if (i == be32_to_cpu(agf->agf_fllast)) break; if (++i == XFS_AGFL_SIZE(mp)) i = 0; } - if (count != INT_GET(agf->agf_flcount, ARCH_CONVERT)) { + if (count != be32_to_cpu(agf->agf_flcount)) { do_warn(_("freeblk count %d != flcount %d in ag %d\n"), count, - INT_GET(agf->agf_flcount, ARCH_CONVERT), - INT_GET(agf->agf_seqno, ARCH_CONVERT)); + be32_to_cpu(agf->agf_flcount), + be32_to_cpu(agf->agf_seqno)); } libxfs_putbuf(agflbuf); } @@ -1163,7 +1124,7 @@ scan_ag( libxfs_putbuf(sbbuf); return; } - libxfs_xlate_sb(XFS_BUF_TO_SBP(sbbuf), sb, 1, XFS_SB_ALL_BITS); + libxfs_sb_from_disk(sb, XFS_BUF_TO_SBP(sbbuf)); agfbuf = libxfs_readbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), @@ -1241,39 +1202,33 @@ scan_ag( scan_freelist(agf); - if (INT_GET(agf->agf_roots[XFS_BTNUM_BNO], ARCH_CONVERT) != 0 && - verify_agbno(mp, agno, - INT_GET(agf->agf_roots[XFS_BTNUM_BNO], ARCH_CONVERT))) - scan_sbtree( - INT_GET(agf->agf_roots[XFS_BTNUM_BNO], ARCH_CONVERT), - INT_GET(agf->agf_levels[XFS_BTNUM_BNO], ARCH_CONVERT), - agno, 0, scanfunc_bno, 1); + if (be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]) != 0 && verify_agbno(mp, + agno, be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]))) + scan_sbtree(be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]), + be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]), + agno, 0, scanfunc_bno, 1); else do_warn(_("bad agbno %u for btbno root, agno %d\n"), - INT_GET(agf->agf_roots[XFS_BTNUM_BNO], ARCH_CONVERT), + be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]), agno); - if (INT_GET(agf->agf_roots[XFS_BTNUM_CNT], ARCH_CONVERT) != 0 && - verify_agbno(mp, agno, - INT_GET(agf->agf_roots[XFS_BTNUM_CNT], ARCH_CONVERT))) - scan_sbtree( - INT_GET(agf->agf_roots[XFS_BTNUM_CNT], ARCH_CONVERT), - INT_GET(agf->agf_levels[XFS_BTNUM_CNT], ARCH_CONVERT), - agno, 0, scanfunc_cnt, 1); + if (be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]) != 0 && verify_agbno(mp, + agno, be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]))) + scan_sbtree(be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]), + be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]), + agno, 0, scanfunc_cnt, 1); else do_warn(_("bad agbno %u for btbcnt root, agno %d\n"), - INT_GET(agf->agf_roots[XFS_BTNUM_CNT], ARCH_CONVERT), + be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]), agno); - if (INT_GET(agi->agi_root, ARCH_CONVERT) != 0 && - verify_agbno(mp, agno, INT_GET(agi->agi_root, ARCH_CONVERT))) - scan_sbtree( - INT_GET(agi->agi_root, ARCH_CONVERT), - INT_GET(agi->agi_level, ARCH_CONVERT), - agno, 0, scanfunc_ino, 1); + if (be32_to_cpu(agi->agi_root) != 0 && verify_agbno(mp, agno, + be32_to_cpu(agi->agi_root))) + scan_sbtree(be32_to_cpu(agi->agi_root), + be32_to_cpu(agi->agi_level), agno, 0, scanfunc_ino, 1); else do_warn(_("bad agbno %u for inobt root, agno %d\n"), - INT_GET(agi->agi_root, ARCH_CONVERT), agno); + be32_to_cpu(agi->agi_root), agno); ASSERT(agi_dirty == 0 || (agi_dirty && !no_modify)); @@ -1294,7 +1249,7 @@ scan_ag( if (sb_dirty && !no_modify) { if (agno == 0) memcpy(&mp->m_sb, sb, sizeof(xfs_sb_t)); - libxfs_xlate_sb(XFS_BUF_PTR(sbbuf), sb, -1, XFS_SB_ALL_BITS); + libxfs_sb_to_disk(XFS_BUF_TO_SBP(sbbuf), sb, XFS_SB_ALL_BITS); libxfs_writebuf(sbbuf, 0); } else libxfs_putbuf(sbbuf); diff --git a/repair/versions.c b/repair/versions.c index acfd58c52..957766a60 100644 --- a/repair/versions.c +++ b/repair/versions.c @@ -32,28 +32,19 @@ update_sb_version(xfs_mount_t *mp) sb = &mp->m_sb; - if (fs_attributes) { - if (!XFS_SB_VERSION_HASATTR(sb)) { - ASSERT(fs_attributes_allowed); - - XFS_SB_VERSION_ADDATTR(sb); - } + if (fs_attributes && !xfs_sb_version_hasattr(sb)) { + ASSERT(fs_attributes_allowed); + xfs_sb_version_addattr(sb); } - if (fs_attributes2) { - if (!XFS_SB_VERSION_HASATTR2(sb)) { - ASSERT(fs_attributes2_allowed); - - XFS_SB_VERSION_ADDATTR2(sb); - } + if (fs_attributes2 && !xfs_sb_version_hasattr2(sb)) { + ASSERT(fs_attributes2_allowed); + xfs_sb_version_addattr2(sb); } - if (fs_inode_nlink) { - if (!XFS_SB_VERSION_HASNLINK(sb)) { - ASSERT(fs_inode_nlink_allowed); - - XFS_SB_VERSION_ADDNLINK(sb); - } + if (fs_inode_nlink && !xfs_sb_version_hasnlink(sb)) { + ASSERT(fs_inode_nlink_allowed); + xfs_sb_version_addnlink(sb); } /* @@ -62,10 +53,9 @@ update_sb_version(xfs_mount_t *mp) * have quotas. */ if (fs_quotas) { - if (!XFS_SB_VERSION_HASQUOTA(sb)) { + if (!xfs_sb_version_hasquota(sb)) { ASSERT(fs_quotas_allowed); - - XFS_SB_VERSION_ADDQUOTA(sb); + xfs_sb_version_addquota(sb); } /* @@ -100,25 +90,21 @@ update_sb_version(xfs_mount_t *mp) } else { sb->sb_qflags = 0; - if (XFS_SB_VERSION_HASQUOTA(sb)) { + if (xfs_sb_version_hasquota(sb)) { lost_quotas = 1; vn = sb->sb_versionnum; vn &= ~XFS_SB_VERSION_QUOTABIT; if (!(vn & XFS_SB_VERSION_ALLFBITS)) - vn = XFS_SB_VERSION_TOOLD(vn); + vn = xfs_sb_version_toold(vn); ASSERT(vn != 0); sb->sb_versionnum = vn; } } - if (!fs_aligned_inodes) { - if (XFS_SB_VERSION_HASALIGN(sb)) { - if (XFS_SB_VERSION_NUM(sb) == XFS_SB_VERSION_4) - XFS_SB_VERSION_SUBALIGN(sb); - } - } + if (!fs_aligned_inodes && xfs_sb_version_hasalign(sb)) + sb->sb_versionnum &= ~XFS_SB_VERSION_ALIGNBIT; } /* @@ -147,7 +133,7 @@ parse_sb_version(xfs_sb_t *sb) * ok, check to make sure that the sb isn't newer * than we are */ - if (XFS_SB_VERSION_HASEXTFLGBIT(sb)) { + if (xfs_sb_version_hasextflgbit(sb)) { fs_has_extflgbit = 1; if (!fs_has_extflgbit_allowed) { issue_warning = 1; @@ -156,7 +142,7 @@ parse_sb_version(xfs_sb_t *sb) } } - if (XFS_SB_VERSION_HASSHARED(sb)) { + if (xfs_sb_version_hasshared(sb)) { fs_shared = 1; if (!fs_shared_allowed) { issue_warning = 1; @@ -171,7 +157,7 @@ _("This filesystem uses feature(s) not yet supported in this release.\n" return(1); } - if (!XFS_SB_GOOD_VERSION(sb)) { + if (!xfs_sb_good_version(sb)) { do_warn(_("WARNING: unknown superblock version %d\n"), XFS_SB_VERSION_NUM(sb)); do_warn( @@ -198,7 +184,7 @@ _("WARNING: you have disallowed superblock-feature-bits-allowed\n" } } - if (XFS_SB_VERSION_HASATTR(sb)) { + if (xfs_sb_version_hasattr(sb)) { if (!fs_attributes_allowed) { if (!no_modify) { do_warn( @@ -216,7 +202,7 @@ _("WARNING: you have disallowed attributes but this filesystem\n" } } - if (XFS_SB_VERSION_HASATTR2(sb)) { + if (xfs_sb_version_hasattr2(sb)) { if (!fs_attributes2_allowed) { if (!no_modify) { do_warn( @@ -234,7 +220,7 @@ _("WARNING: you have disallowed attr2 attributes but this filesystem\n" } } - if (XFS_SB_VERSION_HASNLINK(sb)) { + if (xfs_sb_version_hasnlink(sb)) { if (!fs_inode_nlink_allowed) { if (!no_modify) { do_warn( @@ -254,7 +240,7 @@ _("WARNING: you have disallowed version 2 inodes but this filesystem\n" } } - if (XFS_SB_VERSION_HASQUOTA(sb)) { + if (xfs_sb_version_hasquota(sb)) { if (!fs_quotas_allowed) { if (!no_modify) { do_warn( @@ -280,7 +266,7 @@ _("WARNING: you have disallowed quotas but this filesystem\n" } } - if (XFS_SB_VERSION_HASALIGN(sb)) { + if (xfs_sb_version_hasalign(sb)) { if (fs_aligned_inodes_allowed) { fs_aligned_inodes = 1; fs_ino_alignment = sb->sb_inoalignmt; diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index 530a253c2..d51c9b19d 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -245,18 +245,18 @@ process_args(int argc, char **argv) pre_65_beta = 1; break; case IHASH_SIZE: - libxfs_ihash_size = (int) strtol(val, 0, 0); + libxfs_ihash_size = (int)strtol(val, NULL, 0); ihash_option_used = 1; break; case BHASH_SIZE: if (max_mem_specified) do_abort( _("-o bhash option cannot be used with -m option\n")); - libxfs_bhash_size = (int) strtol(val, 0, 0); + libxfs_bhash_size = (int)strtol(val, NULL, 0); bhash_option_used = 1; break; case AG_STRIDE: - ag_stride = (int) strtol(val, 0, 0); + ag_stride = (int)strtol(val, NULL, 0); break; default: unknown('o', val); @@ -271,7 +271,7 @@ process_args(int argc, char **argv) switch (getsubopt(&p, (constpp)c_opts, &val)) { case CONVERT_LAZY_COUNT: - lazy_count = (int)strtol(val, 0, 0); + lazy_count = (int)strtol(val, NULL, 0); convert_lazy_count = 1; break; default: @@ -295,7 +295,7 @@ process_args(int argc, char **argv) if (bhash_option_used) do_abort(_("-m option cannot be used with " "-o bhash option\n")); - max_mem_specified = strtol(optarg, 0, 0); + max_mem_specified = strtol(optarg, NULL, 0); break; case 'L': zap_log = 1; @@ -316,7 +316,7 @@ process_args(int argc, char **argv) do_prefetch = 0; break; case 't': - report_interval = (int) strtol(optarg, 0, 0); + report_interval = (int)strtol(optarg, NULL, 0); break; case '?': usage(); @@ -411,10 +411,10 @@ calc_mkfs(xfs_mount_t *mp) /* * ditto the location of the first inode chunks in the fs ('/') */ - if (XFS_SB_VERSION_HASDALIGN(&mp->m_sb) && do_inoalign) { + if (xfs_sb_version_hasdalign(&mp->m_sb) && do_inoalign) { first_prealloc_ino = XFS_OFFBNO_TO_AGINO(mp, roundup(fino_bno, mp->m_sb.sb_unit), 0); - } else if (XFS_SB_VERSION_HASALIGN(&mp->m_sb) && + } else if (xfs_sb_version_hasalign(&mp->m_sb) && mp->m_sb.sb_inoalignmt > 1) { first_prealloc_ino = XFS_OFFBNO_TO_AGINO(mp, roundup(fino_bno, @@ -510,7 +510,7 @@ main(int argc, char **argv) { xfs_mount_t *temp_mp; xfs_mount_t *mp; - xfs_sb_t *sb; + xfs_dsb_t *dsb; xfs_buf_t *sbp; xfs_mount_t xfs_m; char *msgbuf; @@ -551,10 +551,9 @@ main(int argc, char **argv) sbp = libxfs_readbuf(x.ddev, XFS_SB_DADDR, 1 << (XFS_MAX_SECTORSIZE_LOG - BBSHIFT), 0); memset(&xfs_m, 0, sizeof(xfs_mount_t)); - sb = &xfs_m.m_sb; - libxfs_xlate_sb(XFS_BUF_PTR(sbp), sb, 1, XFS_SB_ALL_BITS); + libxfs_sb_from_disk(&xfs_m.m_sb, XFS_BUF_TO_SBP(sbp)); - mp = libxfs_mount(&xfs_m, sb, x.ddev, x.logdev, x.rtdev, 0); + mp = libxfs_mount(&xfs_m, &xfs_m.m_sb, x.ddev, x.logdev, x.rtdev, 0); if (!mp) { fprintf(stderr, @@ -794,21 +793,22 @@ _("Warning: project quota information would be cleared.\n" if (!sbp) do_error(_("couldn't get superblock\n")); - sb = XFS_BUF_TO_SBP(sbp); + dsb = XFS_BUF_TO_SBP(sbp); - if (sb->sb_qflags & (XFS_UQUOTA_CHKD|XFS_OQUOTA_CHKD)) { - do_warn( - _("Note - quota info will be regenerated on next quota mount.\n")); - sb->sb_qflags &= ~(XFS_UQUOTA_CHKD|XFS_OQUOTA_CHKD); + if (be16_to_cpu(dsb->sb_qflags) & (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)) { + do_warn(_("Note - quota info will be regenerated on next " + "quota mount.\n")); + dsb->sb_qflags &= cpu_to_be16(~(XFS_UQUOTA_CHKD | + XFS_OQUOTA_CHKD)); } if (clear_sunit) { do_warn( _("Note - stripe unit (%d) and width (%d) fields have been reset.\n" "Please set with mount -o sunit=,swidth=\n"), - sb->sb_unit, sb->sb_width); - sb->sb_unit = 0; - sb->sb_width = 0; + be32_to_cpu(dsb->sb_unit), be32_to_cpu(dsb->sb_width)); + dsb->sb_unit = 0; + dsb->sb_width = 0; } libxfs_writebuf(sbp, 0);