Merge of master-melb:xfs-cmds:32070a by kenmcd.
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)
install-dev: default
$(SUBDIRS_MAKERULE)
+install-qa: install
+ $(SUBDIRS_MAKERULE)
+
realclean distclean: clean
rm -f $(LDIRT) $(CONFIGURE)
rm -rf autom4te.cache Logs
#
# 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
}
void
-handler()
+handler(int sig)
{
pid_t pid = getpid();
int status, i;
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);
}
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) {
}
}
} else {
- char *lb[XFS_MAX_SECTORSIZE] = { 0 };
+ char *lb[XFS_MAX_SECTORSIZE] = { NULL };
off64_t off;
/* ensure device files are sufficiently large */
/* 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 */
/* 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 */
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 */
/* 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(
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;
* 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 <<BBSHIFT, wbuf_miniosize);
if (size > 0) {
/* copy extent */
/* 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 */
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);
}
/*
}
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);
* 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 */
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*/
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
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;
}
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;
}
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;
}
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];
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;
}
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;
}
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));
}
}
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*/
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*/
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*/
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*/
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;
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;
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;
}
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)) {
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();
}
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]);
}
{ 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 },
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
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));
}
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
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));
}
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
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));
}
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
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));
}
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
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));
}
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
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));
}
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
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));
}
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
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));
}
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
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));
}
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
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));
}
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
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));
}
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
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));
}
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
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));
}
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
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);
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;
}
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++;
}
}
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;
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",
char *endptr;
int freeseen;
freetab_t *freetab;
- xfs_dahash_t hash;
int i;
int lastfree;
int lastfree_err;
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;
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) {
}
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",
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;
}
(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",
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",
(*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++;
}
}
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) {
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;
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
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;
}
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;
}
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);
{
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;
"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;
/*
* 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;
}
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:
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);
}
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);
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)
{
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++;
}
}
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)
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++;
}
}
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++;
}
}
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;
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) {
(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 "
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;
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;
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++;
}
}
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;
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",
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) {
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;
(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();
}
process_rtbitmap(
blkmap_t *blkmap)
{
-#define xfs_highbit64 libxfs_highbit64 /* for XFS_RTBLOCKLOG macro */
int bit;
int bitsperblock;
xfs_fileoff_t bmbno;
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,
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);
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);
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) {
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);
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;
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)
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) {
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],
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) &&
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));
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;
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],
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++;
}
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],
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
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
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
{
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;
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) &&
}
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,
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
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*/
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));
}
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*/
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));
}
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*/
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));
}
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*/
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
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;
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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));
}
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*/
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));
}
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;
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));
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
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
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
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;
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
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));
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;
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));
}
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*/
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;
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));
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));
}
}
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*/
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*/
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*/
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));
}
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*/
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*/
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*/
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));
}
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*/
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*/
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
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*/
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
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));
}
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));
}
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
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));
}
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));
}
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);
}
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
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);
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 ||
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();
}
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),
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
{
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;
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],
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);
}
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();
}
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;
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),
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
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
}
/* 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;
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*/
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));
}
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*/
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));
}
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*/
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));
}
};
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 }
};
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
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
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
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:
{
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:
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
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
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
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
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
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
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
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:
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
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;
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)
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;
{
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)
(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++) {
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 "
(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));
}
}
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",
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;
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;
}
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) {
(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;
{
int i;
xfs_bmbt_ptr_t *pp;
- xfs_bmbt_rec_t *rp;
int nrecs;
nrecs = be16_to_cpu(bthdr->bb_numrecs);
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]) {
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;
xfs_bmdr_block_t *dib;
int i;
xfs_bmbt_ptr_t *pp;
- xfs_bmbt_rec_t *rp;
int level;
int nrecs;
int maxrecs;
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);
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;
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);
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);
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:
}
clear_nametable();
}
-
- /* restore the core back to it's original endianess */
- memcpy(&dip->di_core, &odic, sizeof(xfs_dinode_core_t));
-
return success;
}
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)",
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;
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)
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;
}
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;
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;
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;
}
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;
}
/* 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;
}
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];
}
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);
}
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;
}
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;
}
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
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
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 {
+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.
--- /dev/null
+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.
--- /dev/null
+#
+# 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:
--- /dev/null
+/*
+ * 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 <xfs/libxfs.h>
+#include <sys/stat.h>
+#include <ftw.h>
+
+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;
+}
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")
$(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)
--- /dev/null
+#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
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)
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)
$(_FORCE):
-.PHONY : depend
+.PHONY : depend install-qa
DEPENDSCRIPT := $(MAKEDEPEND) $(DEPENDFLAGS) -f - -- $(CFLAGS) -- $(CFILES) | \
$(SED) \
#define __BYTE_ORDER BYTE_ORDER
#define __BIG_ENDIAN BIG_ENDIAN
#define __LITTLE_ENDIAN LITTLE_ENDIAN
-#include <xfs/swab.h>
#include <sys/syscall.h>
# ifndef SYS_fsctl
#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
#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
--- /dev/null
+/*
+ * 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
* 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__
#include <xfs/platform_defs.h>
-#include <pthread.h>
#include <xfs/list.h>
#include <xfs/cache.h>
+#include <xfs/bitops.h>
+#include <xfs/kmem.h>
+#include <xfs/swab.h>
#include <xfs/xfs_fs.h>
#include <xfs/xfs_types.h>
* 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 */
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 */
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 *);
/*
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);
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
*/
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 */
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);
uint, xfs_inode_t **, xfs_daddr_t);
extern void libxfs_iput (xfs_inode_t *, uint);
-
-/*
- * Directory interface
- */
-#include <xfs/xfs_dir_leaf.h>
+#include <xfs/xfs_dir_leaf.h> /* dirv1 support in db & repair */
#include <xfs/xfs_dir2_data.h>
#include <xfs/xfs_dir2_leaf.h>
#include <xfs/xfs_dir2_block.h>
#include <xfs/xfs_dir2_node.h>
-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 };
#include <xfs/xfs_log.h>
#include <xfs/xfs_log_priv.h>
+#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__ */
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;
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 */
#include <malloc.h>
#include <getopt.h>
#include <endian.h>
-#include <xfs/swab.h>
static __inline__ int xfsctl(const char *path, int fd, int cmd, void *p)
{
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
+#include <stdint.h>
#include <unistd.h>
+#include <pthread.h>
+#include <ctype.h>
#include <sys/types.h>
#undef HAVE___U32
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 <xfs/linux.h>
#include <locale.h>
#ifdef DEBUG
-# define ASSERT assert
+# define ASSERT(EX) assert(EX)
#else
# define ASSERT(EX) ((void) 0)
#endif
--- /dev/null
+#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 */
#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;
/*
{
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 */
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)
* 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.
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;
/*
#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.
*/
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__ */
/*
* 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])
* 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.
/*
- * 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
#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? */
((__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) ? \
) \
)
-/* 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.
* 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]))
(di).i[6] = (((from) & 0x000000000000ff00ULL) >> 8); \
(di).i[7] = ((from) & 0x00000000000000ffULL); \
} while (0)
-
+
#endif /* __XFS_ARCH_H__ */
struct attrlist;
struct attrlist_cursor_kern;
-struct attrnames;
+struct xfs_attr_list_context;
struct xfs_dabuf;
struct xfs_da_args;
struct xfs_da_state;
#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 {
#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)
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) \
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)];
}
/*
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.
*/
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__ */
*/
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) */
#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)
/*
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)
}
/* 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);
/*
- * 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
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.
/*
* 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
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
*/
*/
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.
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
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.
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 */
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__ */
/*
* 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
} 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.
*/
* 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)
/*
* 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), \
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)))
/*
* 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)
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 *);
*/
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__ */
struct xfs_mount;
struct xfs_trans;
+extern kmem_zone_t *xfs_btree_cur_zone;
+
/*
* This nonsense is to make -wlint happy.
*/
* 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)))
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 # */
__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 */
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;
#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.
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.
*/
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 && \
#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 {
* 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;
/*
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.
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
* 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.
*========================================================================*/
/*
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);
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__ */
*/
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__ */
* 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
* 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;
/*
* 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))
#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)
#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 | \
+++ /dev/null
-/*
- * 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__ */
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;
/*
/*
* 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__ */
#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;
/*
/*
* 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)
{
/*
* 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);
#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)
#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.
* 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;
/*
* 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;
* 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;
/*
* 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 {
/*
* 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) + \
/*
* 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));
}
/*
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,
#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.
*/
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;
/*
* 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)) /
/*
* 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)
{
/*
* 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)
{
/*
* 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)
{
/*
* 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)
{
/*
* 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)
{
/*
* 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)
/*
* 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)
{
/*
* 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)
{
/*
* 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);
}
/*
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,
#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;
/*
* 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)
{
/*
* 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)
{
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) - \
((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)
{
(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)
{
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) - \
((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)
{
((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)));
}
/*
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);
#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,
* 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.
*========================================================================*/
* 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 {
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__ */
*/
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 {
* 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__ */
* 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
#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 {
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;
*/
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 */
} 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
/*
* 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
#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
/*
}
-#ifdef __KERNEL__
/*
* Allocate an inode on disk.
* Mode is used to tell whether the new inode will need space, and whether
struct xfs_trans *tp, /* transaction pointer */
xfs_agnumber_t agno); /* allocation group number */
-#endif /* __KERNEL__ */
-
#endif /* __XFS_IALLOC_H__ */
/*
* 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 */
#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) \
* 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)))
/*
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__ */
#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 */
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 */
} 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;
__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 */
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 */
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
#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.
#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()
#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().
#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);
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);
/*
* 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 */
#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__ */
#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;
} 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 *);
#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)<CYCLE_LSN(lsn2))? -999 : 999;
* Macros, structures, prototypes for interface to the log manager.
*/
-/*
- * Flags to xfs_log_mount
- */
-#define XFS_LOG_RECOVER 0x1
-
/*
* Flags to xfs_log_done()
*/
#define XFS_LOG_REL_PERM_RESERV 0x1
-
/*
* Flags to xfs_log_reserve()
*
#define XFS_LOG_SLEEP 0x0
#define XFS_LOG_NOSLEEP 0x1
#define XFS_LOG_PERM_RESERV 0x2
-#define XFS_LOG_RESV_ALL (XFS_LOG_NOSLEEP|XFS_LOG_PERM_RESERV)
-
/*
* Flags to xfs_log_force()
/* Region types for iovec's i_type */
-#if defined(XFS_LOG_RES_DEBUG)
#define XLOG_REG_TYPE_BFORMAT 1
#define XLOG_REG_TYPE_BCHUNK 2
#define XLOG_REG_TYPE_EFI_FORMAT 3
#define XLOG_REG_TYPE_COMMIT 18
#define XLOG_REG_TYPE_TRANSHDR 19
#define XLOG_REG_TYPE_MAX 19
-#endif
-#if defined(XFS_LOG_RES_DEBUG)
#define XLOG_VEC_SET_TYPE(vecp, t) ((vecp)->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;
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,
*/
#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) / \
#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__
*
* 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)
#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__
/*
/* 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
* 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 */
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;
#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__
* 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.
* - 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 {
/*
* 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
* 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;
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);
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__ */
#ifndef __XFS_MOUNT_H__
#define __XFS_MOUNT_H__
+
typedef struct xfs_trans_reservations {
uint tr_write; /* extent alloc trans */
uint tr_itruncate; /* truncate trans */
} 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 {
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)
/*
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 *);
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;
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 */
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 */
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 */
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 */
#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 */
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 */
/* 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 */
/*
/*
* 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.
#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
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__ */
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 ...
*/
#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)
#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
#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
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)
/*
} 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)
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__ */
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 */
/*
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.
*/
#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 | \
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 | \
* 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 */
__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.
*/
#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)
/*
#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)
{
}
#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) ? \
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)) ? \
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) || \
((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) ? \
(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) || \
((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 ? \
((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) && \
(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) && \
* 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 = \
((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, \
* 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.
#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
/*
* 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
#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
* 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;
* 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;
* 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)
{
(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.
((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)
#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.
#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)
/*
* 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 *,
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 *);
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__ */
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) \
#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))
* 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 */
*/
#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;
XFS_BTNUM_MAX
} xfs_btnum_t;
+struct xfs_name {
+ const char *name;
+ int len;
+};
+
#endif /* __XFS_TYPES_H__ */
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));
install-dev: default
$(INSTALL_LTLIB_STATIC)
+
+install-qa: install-dev
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 */
io_error:
close(fd);
- return 0;
+ return NULL;
}
install-dev: default
$(INSTALL_LTLIB_DEV)
+
+install-qa: install-dev
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 ))
include $(BUILDRULES)
-install: default
-
-install-dev: default
- $(INSTALL_LTLIB_STATIC)
+install install-dev install-qa: default
}
void
-setprent()
+setprent(void)
{
setprfiles();
projects = fopen(projid_file, "r");
}
void
-setprpathent()
+setprpathent(void)
{
setprfiles();
project_paths = fopen(projects_file, "r");
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
install: default
install-dev: default
- $(INSTALL_LTLIB_STATIC)
+
+install-qa: default
+++ /dev/null
-/*
- * 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 <xfs.h>
-
-/*
- * 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
-}
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <xfs/libxfs.h>
+#include <xfs.h>
#include <sys/stat.h>
#include "init.h"
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:
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();
}
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,
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
/*
* 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;
}
/*
* 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;
* 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;
}
/* 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;
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.
* 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);
--- /dev/null
+
+
+#include <xfs/libxfs.h>
+
+/*
+ * 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;
+}
+
#include <xfs.h>
-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
* 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.
lidp->lid_size = 0;
lip->li_desc = lidp;
lip->li_mountp = tp->t_mountp;
- return (lidp);
+ return lidp;
}
/*
*/
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);
* 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;
}
/*
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++;
* 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;
}
}
{
ASSERT(lip->li_desc != NULL);
- return (lip->li_desc);
+ return lip->li_desc;
}
/*
/*
* 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;
* 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;
}
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,
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,
* 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,
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;
/*
* 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,
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
} 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));
{
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;
* 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));
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);
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},
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)
};
-/*
- * 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)
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
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;
}
}
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
* Transaction commital code follows (i.e. write to disk in libxfs)
*/
-STATIC void
+static void
inode_item_done(
xfs_inode_log_item_t *iip)
{
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;
/*
* 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);
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);
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)
* 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);
}
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)
{
bip->bli_flags &= ~XFS_BLI_HOLD;
}
-STATIC void
+static void
inode_item_unlock(
xfs_inode_log_item_t *iip)
{
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;
*/
if (!(freeing_chunk) &&
(!(lidp->lid_flags & XFS_LID_DIRTY) || abort)) {
- XFS_LIC_RELSE(licp, i);
+ xfs_lic_relse(licp, i);
freed++;
}
}
int
libxfs_trans_commit(
xfs_trans_t *tp,
- uint flags,
- xfs_lsn_t *commit_lsn_p)
+ uint flags)
{
xfs_sb_t *sbp;
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
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;
*
* 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(
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;
}
* 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,
* 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 */
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.
*/
}
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;
(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);
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);
/* 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) ||
}
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
* 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
* 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,
* 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.
* 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 */
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 */
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;
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);
}
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"),
* 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;
}
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;
#include <xfs/libxfs.h>
+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
#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)
#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 *);
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 *);
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
/*
- * 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
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include <xfs.h>
#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 */
}
*resbno = bno;
*reslen = len;
- return len >= minlen;
}
/*
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.
*/
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);
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;
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 */
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 */
*/
int dofirst; /* set to do first algorithm */
- dofirst = random() & 1;
+ dofirst = random32() & 1;
#endif
/*
* Get a cursor for the by-size btree.
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);
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;
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;
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 */
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)))
/*
* Can't allocate from the freelist for some reason.
*/
- else
+ else {
+ fbno = NULLAGBLOCK;
flen = 0;
+ }
/*
* Can't do the allocation, give up.
*/
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 */
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(
/*
* 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(
&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.
&agbp)))
return error;
if (agbp == NULL) {
+ ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK);
+ ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
args->agbp = NULL;
return 0;
}
*/
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.
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;
* 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;
}
}
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 */
/*
* 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;
}
{
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 */
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,
{
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;
* 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);
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;
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 */
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.
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;
#include <xfs.h>
+/*
+ * 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.
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 */
/*
* 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;
}
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);
}
}
/*
*/
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
/*
* 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
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;
}
/*
* 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
* 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;
* 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;
}
* 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;
}
/*
* 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
*/
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
/*
* 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.
*/
/*
* 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
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 */
*/
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);
}
#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.
*/
* 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
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;
*/
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
*/
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
*/
*bnop = nbno;
if (nbno != NULLAGBLOCK) {
- *recp = nrec; /* INT_: struct copy */
- *curp = ncur; /* INT_: struct copy */
+ *recp = nrec;
+ *curp = ncur;
}
*stat = 1;
return 0;
*/
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
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);
}
/*
* 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.
/*
* 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.
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,
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 */
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);
/*
* 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
* 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;
*/
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.
* 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);
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.
*/
if (ncur) {
pcur = ncur;
- ncur = (xfs_btree_cur_t *)0;
+ ncur = NULL;
}
} while (nbno != NULLAGBLOCK);
*stat = i;
/*
- * 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
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.
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.
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);
}
* 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);
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.
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);
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) ||
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);
/*
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);
* 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;
}
* 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);
/*
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;
* 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;
/*
* 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;
}
* 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);
/*
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
* 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;
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;
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);
* 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);
/*
* 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);
/*
* 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.
if (!error) {
error = xfs_bmap_finish(&args->trans,
args->flist,
- *args->firstblock,
&committed);
}
if (error) {
/*
* 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) {
/*
/* 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);
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).
*========================================================================*/
} 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;
if (!error) {
error = xfs_bmap_finish(&args->trans,
args->flist,
- *args->firstblock,
&committed);
}
if (error) {
* 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;
error = xfs_da_split(state);
if (!error) {
error = xfs_bmap_finish(&args->trans, args->flist,
- *args->firstblock, &committed);
+ &committed);
}
if (error) {
ASSERT(committed);
* 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;
/*
* 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.
if (!error) {
error = xfs_bmap_finish(&args->trans,
args->flist,
- *args->firstblock,
&committed);
}
if (error) {
/*
* 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) {
error = xfs_da_join(state);
if (!error) {
error = xfs_bmap_finish(&args->trans, args->flist,
- *args->firstblock, &committed);
+ &committed);
}
if (error) {
ASSERT(committed);
/*
* 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;
}
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))) {
if (!error) {
error = xfs_bmap_finish(&args->trans,
args->flist,
- *args->firstblock,
&committed);
}
if (error) {
* 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)
/*
* 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
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.
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
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);
/*
* 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);
}
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);
}
args->rmtblkcnt,
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
args->firstblock, 0, &map, &nmap,
- args->flist);
+ args->flist, NULL);
if (error) {
return(error);
}
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);
/*
* 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);
* 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).
*========================================================================*/
/*
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 */
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 */
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);
}
}
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);
}
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
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);
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);
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;
}
* 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
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 =
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));
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);
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);
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)
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))
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));
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));
/*
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
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);
}
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:
return(error);
}
+
/*========================================================================
* Routines used for growing the Btree.
*========================================================================*/
* 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;
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);
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);
* 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);
}
/*
* 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));
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)) {
}
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.
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;
/*
* 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);
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);
}
/*
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;
/*
/*
* 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);
}
/*
* 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.
* 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);
}
* 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);
/*
* 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.
* 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;
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;
}
* 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];
/*
* 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;
*/
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);
/*
* 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) {
* 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);
* 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,
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);
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:
* 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;
}
}
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;
* 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));
/*
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 {
* "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 */
}
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.
*/
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 {
/*
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,
/*
* 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);
}
/*========================================================================
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));
}
/*
* 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.
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));
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));
}
}
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.
/*
* 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];
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
/*
*/
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 */
/*
* 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) <=
* 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);
/*
* 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;
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);
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);
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);
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 */
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)));
}
/*
* 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);
}
/*
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 ];
/*
* 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);
}
/*
}
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 ];
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 */
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)));
}
/*
* 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);
-
-}
/*
- * 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
#include <xfs.h>
-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 */
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) {
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);
}
/*
- * 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 */
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 */
{
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 */
* 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)) {
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.
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;
}
/*
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 */
/*
* 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
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);
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;
}
}
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.
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,
* 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);
* 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,
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,
* 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)
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 +
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):
* 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 {
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 +
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):
* 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 {
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 +
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):
* 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)
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):
* 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)
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 +
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):
* 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)
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) {
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):
* 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;
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 +
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):
* 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)
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) {
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:
* 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)
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) {
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.
*/
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) {
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):
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;
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 */
/* 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,
*/
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) ?
* 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,
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,
* 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)
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):
* 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;
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):
* 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;
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):
* 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)
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):
* 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)
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,
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):
* 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)
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,
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):
* 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)
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,
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):
* 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)
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,
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:
* 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)
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):
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;
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,
((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));
}
/*
/*
* 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):
* 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):
* 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:
* 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
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,
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));
}
/*
left.br_blockcount + new->br_blockcount +
right.br_blockcount <= MAXEXTLEN));
+ error = 0;
/*
* Select which case we're in here, and implement it.
*/
/*
* 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):
/*
* 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):
/*
* 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:
/*
* 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(
#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.
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 */
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);
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;
}
/*
- * 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 */
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 */
{
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 */
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 */
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;
/*
* 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;
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 {
/*
* 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;
}
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);
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;
* 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;
* 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;
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.
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,
}
}
}
- 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;
}
*/
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;
/*
* 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 */
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.
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);
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);
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++;
}
}
*/
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.
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(
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) /
{
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 */
/*
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.
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,
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;
}
* *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;
}
/*
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 */
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) {
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:
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);
* 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];
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 */
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.
/*
* 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(
{
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 */
/*
* 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(
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 */
*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;
}
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;
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;
}
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;
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.
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);
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) {
/*
* 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;
/*
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);
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 */
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 */
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 */
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
* 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;
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
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
* 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) {
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);
}
/*
* 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;
}
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) {
/* 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;
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;
* 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;
* 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);
}
* 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 =
} else {
*mval = got;
if (ISNULLSTARTBLOCK(mval->br_startblock)) {
- ASSERT(!wr || delay);
+ ASSERT(!wr || (flags & XFS_BMAPI_DELAY));
mval->br_startblock = DELAYSTARTBLOCK;
}
}
}
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);
/*
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;
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;
/*
* 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;
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)
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(
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 */
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;
}
if (got.br_startoff > bno) {
if (--lastx < 0)
break;
- ep--;
+ ep = xfs_iext_get_ext(ifp, lastx);
xfs_bmbt_get_all(ep, &got);
}
/*
* 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.
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;
}
}
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;
} 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.
* 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 ==
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;
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;
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);
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;
* 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);
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)
* 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 */
{
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);
/*
* 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)
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include <xfs.h>
+/*
+ * 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.
*/
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 */
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;
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;
}
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);
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;
}
}
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;
}
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) {
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 */
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);
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);
#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,
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;
#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);
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;
/*
* 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;
}
*/
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--;
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--;
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);
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);
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;
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))) {
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);
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;
}
}
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
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);
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;
} 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))) {
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 */
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;
}
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 {
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);
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 */
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;
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;
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;
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))) {
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;
{
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;
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);
}
/*
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;
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);
int *stat) /* success/failure */
{
int error; /* error return value */
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_delete";
-#endif
int i;
int level;
* 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,
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);
*/
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));
}
*/
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) |
*/
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;
xfs_exntst_t
xfs_bmbt_get_state(
- xfs_bmbt_rec_t *r)
+ xfs_bmbt_rec_host_t *r)
{
int ext_flag;
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);
}
/*
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));
}
/*
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.
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;
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);
/*
* 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(
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;
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,
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 ==
}
if (ncur) {
pcur = ncur;
- ncur = (xfs_btree_cur_t *)0;
+ ncur = NULL;
}
} while (nbno != NULLFSBLOCK);
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
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[] = {
{
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;
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
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))) {
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;
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;
}
#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);
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);
*/
void
xfs_bmbt_set_startblock(
- xfs_bmbt_rec_t *r,
+ xfs_bmbt_rec_host_t *r,
xfs_fsblock_t v)
{
#if XFS_BIG_BLKNOS
*/
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);
*/
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);
{
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);
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);
}
/*
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;
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;
}
/*
- * 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,
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);
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/*
- * This file contains common code for the space manager's btree implementations.
- */
-
#include <xfs.h>
/*
* 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.
*/
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: {
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:
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:
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 */
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.
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);
}
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.
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++;
}
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.
*========================================================================*/
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)));
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--) {
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;
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)));
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);
* 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 &&
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.
* 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) {
* 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;
/*
* 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];
* 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
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);
}
/*
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.
*/
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 */
}
}
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);
*/
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);
}
/*========================================================================
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.
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;
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);
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);
*/
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 */
/*
* 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) {
* 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);
* 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,
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 */
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;
}
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);
}
}
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)));
* 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);
}
/*
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,
/*
* 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);
}
/*========================================================================
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;
* 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++) {
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++;
}
*/
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;
}
* 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)) {
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);
}
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:
/*
* 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);
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);
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)
{
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);
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);
}
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;
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;
}
}
}
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
};
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;
/*
* 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 {
/*
* 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.
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);
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)
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;
}
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;
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)) {
/*
* 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)));
/*
* 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.
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);
*/
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)) {
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);
/*
* 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)));
{
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;
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;
*/
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;
}
/*
* 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,
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
nfsb,
XFS_BMAPI_METADATA |
XFS_BMAPI_AFLAG(whichfork),
- NULL, 0, mapp, &nmap, NULL)))
+ NULL, 0, mapp, &nmap, NULL, NULL)))
goto exit0;
}
} else {
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",
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]);
}
}
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;
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;
}
/*
- * 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.
/*
* Kill the altpath contents of a da-state structure.
*/
-void
+STATIC void
xfs_da_state_kill_altpath(xfs_da_state_t *state)
{
int i;
#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
/*
}
#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);
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;
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);
}
/*
for (i = 0; i < nbuf; i++)
xfs_trans_brelse(tp, bplist[i]);
if (bplist != &bp)
- kmem_free(bplist, nbuf * sizeof(*bplist));
+ kmem_free(bplist);
}
/*
for (i = 0; i < nbuf; i++)
xfs_trans_binval(tp, bplist[i]);
if (bplist != &bp)
- kmem_free(bplist, nbuf * sizeof(*bplist));
+ kmem_free(bplist);
}
/*
+++ /dev/null
-/*
- * 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.h>
-
-/*
- * 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);
-}
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/*
- * XFS v2 directory implmentation.
- * Top-level and utility routines.
- */
-
#include <xfs.h>
+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;
}
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);
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;
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;
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);
/*
* 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;
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);
* 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;
/*
* 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);
/*
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;
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)
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.
*/
/*
* 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;
/*
* 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;
}
*/
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
/*
* 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))) {
/*
- * 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
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <xfs.h>
+
/*
- * 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 <xfs.h>
+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.
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);
/*
* 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.
*/
/*
* 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;
}
* 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;
}
}
* 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;
}
/*
/*
* 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;
/*
* 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 ...
* 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.
/*
* 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;
/*
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 {
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;
}
}
* 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--;
}
/*
*/
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;
}
/*
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;
* 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],
* 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],
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.
/*
* 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.
/*
* 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);
/*
* 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 */
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));
}
/*
* 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 */
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));
}
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 */
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;
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);
}
/*
* 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--;
}
/*
* 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);
}
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);
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);
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);
}
/*
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 */
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 */
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
* 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;
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;
/*
/*
* 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);
/*
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;
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.
*/
error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, &blkno);
if (error) {
- kmem_free(buf, buf_len);
+ kmem_free(buf);
return error;
}
/*
*/
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.
/*
* 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.
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);
* 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 <xfs.h>
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;
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.
*/
* 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;
}
*/
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
* 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++) {
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.
dfp++) {
if (!dfp->offset)
return NULL;
- if (INT_GET(dfp->offset, ARCH_CONVERT) == off)
+ if (be16_to_cpu(dfp->offset) == off)
return dfp;
}
/*
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];
/*
* 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.
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 */
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.
* 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;
/*
/*
* 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.
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);
}
}
}
/*
* 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;
* 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;
* 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.
*/
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));
}
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));
}
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.
*/
* 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));
}
/*
* 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;
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;
* 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) {
/*
*/
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);
}
*/
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
/*
* 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.
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
/*
* 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);
}
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.
*/
*/
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);
}
*/
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.
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
*/
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.
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
*/
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
* 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,
/*
- * 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
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <xfs.h>
+
/*
- * 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 <xfs.h>
-
-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.
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 */
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.
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;
/*
/*
* 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.
*/
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 */
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 */
*/
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.
* 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;
}
* 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;
}
* 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);
}
* 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;
}
* 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;
}
/*
* 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.
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;
}
/*
*/
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;
* 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.
* 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.
*/
* 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);
}
/*
* 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.
*/
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;
* 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);
* 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
*/
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)
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.
*/
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 */
/*
* 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.
/*
* 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)
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;
/*
* 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;
* 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
* 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;
/*
* 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.
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;
}
/*
* 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;
/*
* 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;
* 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);
}
/*
* 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));
}
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),
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));
}
/*
* 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 */
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));
}
*/
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);
}
/*
* 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 */
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;
/*
* 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);
* 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.
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;
}
/*
* 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);
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 */
* 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))) {
* 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;
}
/*
* 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.
*/
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);
* 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;
* 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--;
}
}
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
/*
* 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?
*/
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.
*/
/*
* 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;
}
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.
*/
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);
* 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);
/*
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <xfs.h>
+
/*
- * 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 <xfs.h>
+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.
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 +
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));
}
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);
/*
* 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;
* 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;
/*
* 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;
}
/*
*/
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.
*/
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;
* 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);
* 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)
* 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)
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);
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 */
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 */
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);
/*
/*
* 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.
* 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
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
* 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);
/*
* 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);
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;
}
}
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;
/*
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;
}
/*
* 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);
}
* 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 */
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.
*/
/*
* 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
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);
* 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 */
* 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).
/*
* 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
* 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;
}
/*
* the new value.
*/
else {
- INT_SET(free->bests[findex], ARCH_CONVERT, longest);
+ free->bests[findex] = cpu_to_be16(longest);
logfree = 1;
}
/*
*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;
}
/*
* 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;
*/
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)) {
/*
* 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);
* 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;
/*
* 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.
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);
}
/*
* 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 {
/*
* 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 */
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
*/
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
* 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.
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;
}
/*
* 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;
}
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.
*/
/*
* 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.
* 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;
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) {
* 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;
}
* 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);
}
/*
* 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;
}
/*
/*
* 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;
* 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);
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.
* 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.
*/
/*
* 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;
}
/*
* 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;
}
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.
*/
* 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.
*/
*/
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.
*/
* 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;
}
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;
* 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
/*
- * 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
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/*
- * xfs_dir2_sf.c
- * Shortform directory implementation for v2 directories.
- */
-
#include <xfs.h>
+/*
+ * 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)
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.
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 */
*/
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;
}
* 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.
* 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;
* 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;
}
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
/*
* 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.
/*
* 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.
* 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 */
/*
* 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.
* 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.
*/
* 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 */
* 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;
}
* 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)
* 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);
}
* 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 */
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.
*/
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
/*
* Check consistency of shortform directory, assert if bad.
*/
-STATIC void
+static void
xfs_dir2_sf_check(
xfs_da_args_t *args) /* operation arguments */
{
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);
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.
*/
/*
* 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);
{
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);
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);
}
/*
*/
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);
}
/*
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.
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.
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;
}
}
* 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);
* 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 */
{
*/
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);
}
* 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 */
{
*/
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);
}
+++ /dev/null
-/*
- * 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.h>
-
-
-/*
- * 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));
-}
/*
* 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.
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 */
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;
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
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;
}
* 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.
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;
return 0;
}
-STATIC __inline xfs_agnumber_t
+STATIC_INLINE xfs_agnumber_t
xfs_ialloc_next_ag(
xfs_mount_t *mp)
{
*/
if (XFS_FORCED_SHUTDOWN(mp)) {
up_read(&mp->m_peraglock);
- return (xfs_buf_t *)0;
+ return NULL;
}
agno++;
if (agno >= agcount)
if (agno == pagno) {
if (flags == 0) {
up_read(&mp->m_peraglock);
- return (xfs_buf_t *)0;
+ return NULL;
}
flags = 0;
}
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) {
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--;
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) >= "
"(0x%llx)",
ino, XFS_AGINO_TO_INO(mp, agno, agino));
}
+ xfs_stack_trace();
#endif /* DEBUG */
return XFS_ERROR(EINVAL);
}
* 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));
}
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);
* 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 <xfs.h>
+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.
/*
* 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.
}
#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.
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.
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);
* 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);
*/
*bnop = nbno;
if (nbno != NULLAGBLOCK) {
- *recp = nrec; /* INT_: struct copy */
+ *recp = nrec;
*curp = ncur;
}
*stat = 1;
{
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);
}
*/
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
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.
* 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);
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);
}
/*
/*
* 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)
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.
} 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;
}
/*
/*
* 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;
* 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
*/
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);
/*
* 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);
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 {
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);
* 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;
*/
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.
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);
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--;
* 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;
}
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--;
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.
*/
if (ncur) {
pcur = ncur;
- ncur = (xfs_btree_cur_t *)0;
+ ncur = NULL;
}
} while (nbno != NULLAGBLOCK);
*stat = i;
/*
* 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.
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;
}
/*
- * 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
#include <xfs.h>
-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,
}
#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
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
}
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;
* 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)
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);
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).",
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 "
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:
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;
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);
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);
}
/*
{
int error;
xfs_ifork_t *ifp;
+ xfs_extnum_t nextents;
size_t size;
if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) {
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;
}
* 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.
*
(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 <=
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
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;
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;
}
+
+
/*
* Map inode to disk block and offset.
*
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;
}
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;
}
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);
}
}
-/*
- * 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()
*
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);
/*
* 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));
}
* 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,
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;
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);
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;
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;
+ }
}
/*
- * 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
#include <xfs.h>
-/*
- * 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 },
{ 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;
/* 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;
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
*
* 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);
/*
* 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);
+}
/*
- * 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
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <xfs.h>
+
/*
- * Free realtime space allocation for XFS.
+ * Prototypes for internal functions.
*/
-#include <xfs.h>
-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.
/*
* 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.
}
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;
-}
/*
- * 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
#include <xfs.h>
+/*
+ * 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.
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;
+}
+
include $(BUILDRULES)
-install: default
-
-install-dev: default
- $(INSTALL_LTLIB_STATIC)
+install install-dev install-qa: default
{
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 */
/*
- * 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
#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
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 */
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;
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)
* 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)
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:
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);
/*
* 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
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;
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;
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;
}
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;
}
/* 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
*/
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;
* 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)) {
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;
* 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;
/*
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)
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);
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;
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;
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
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 +
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);
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");
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))
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;
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(
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(
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,
{
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);
* 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
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)
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;
* _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;
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 */
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)
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);
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;
}
}
#define BAD_HEADER (-1)
#define NO_ERROR (0)
+#define XLOG_SET(f,b) (((f) & (b)) == (b))
+
static int logBBsize;
char *trans_type[] = {
"",
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)
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: ");
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;
*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
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;
/*
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",
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) {
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) {
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++;
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",
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]);
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 */
(*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;
}
(*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;
}
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;
}
(*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;
}
(*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;
}
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;
}
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++;
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)));
}
}
/* 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;
}
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#
*/
/* 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;
}
}
/* 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];
}
}
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: {
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");
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;
}
!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;
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
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 */
{
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");
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);
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;
}
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;
}
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 */
{
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;
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) {
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");
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)
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;
{
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:
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;
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);
/*
* 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);
int block_size;
int max_indicies;
int cur_index;
+ int mb_count;
xfs_metablock_t tmb;
xfs_sb_t sb;
__int64_t bytes_read;
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;
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 */
} 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);
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;
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));
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
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;
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);
}
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,
{
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);
}
{
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);
}
int isroot = 0;
cred_t creds;
char *value;
+ struct xfs_name xname;
memset(&creds, 0, sizeof(creds));
mstr = getstr(pp);
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);
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;
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;
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;
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;
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:
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:
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);
}
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.
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
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.
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);
}
}
- 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.
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);
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.
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);
}
}
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
break;
case 'p':
if (protofile)
- respec('p', 0, 0);
+ respec('p', NULL, 0);
protofile = optarg;
break;
case 'q':
/* 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);
/*
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);
/*
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)
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);
/*
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);
/*
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);
/*
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);
}
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);
}
/*
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
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);
}
}
# 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 \
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]++)];
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);
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);
/* 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);
}
}
}
* 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 */
}
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);
}
}
}
* 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
* 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) {
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) {
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;
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) {
#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);
* 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
} 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 "
/* 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 {
}
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(
* 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) {
* 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) {
((__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 */
}
/* 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;
}
}
* 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,
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();
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);
}
(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"),
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);
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 */
* 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);
}
}
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);
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);
}
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);
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)) {
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)) {
/* 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);
* 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)) {
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);
}
}
-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;
}
/*
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 */
* 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;
}
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);
}
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)
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"));
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) {
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 */
}
{
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) ||
: 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)
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)
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)
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)
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)
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)
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)
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)
}
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)
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);
}
/*
* 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;
}
/*
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);
}
* 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 "
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);
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
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,
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);
}
/*
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,
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);
}
/*
*
* 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,
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,
int prev_level;
#endif
int found;
+ int numrecs;
xfs_bmbt_rec_t *rec;
xfs_bmbt_irec_t irec;
xfs_bmbt_ptr_t *pp;
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);
/*
* 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));
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));
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;
}
}
*
* 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,
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))) {
/*
/*
* 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"),
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++) {
* 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
* 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);
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);
/*
/*
* 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);
}
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
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(
* 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);
}
* 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
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,
}
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;
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);
/*
* 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) {
return(0);
}
-static __inline int
+static int
process_misc_ino_types_blocks(xfs_drfsbno_t totblocks, xfs_ino_t lino, int type)
{
/*
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)) {
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)
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,
*/
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,
}
*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);
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,
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) {
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 */
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,
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,
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);
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 '..'
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;
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 *)
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
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;
/* 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;
}
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;
}
/*
* 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 .
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 {
_("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 {
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 {
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;
* 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)
}
}
- 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;
/*
* 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
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 {
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);
}
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);
* 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) {
/*
* 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");
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 "
* 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
* 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
/*
* 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);
* 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++;
}
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
* 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");
* 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 "
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;
/*
* 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);
/*
* 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;
* 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
_("\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(
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(
_("\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(
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(
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(
_("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 {
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"));
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
*/
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,
* 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(
_("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);
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
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(
* 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
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 {
}
}
- *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);
/*
* 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;
/*
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 {
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 {
* 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);
}
}
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);
}
/*
*/
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
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++;
/*
* 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;
* 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;
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);
}
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)) {
/*
* 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) {
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);
}
/*
* 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);
}
/*
* 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);
* 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
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]);
}
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"),
*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;
}
* 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 "
}
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;
/*
* 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);
/*
* 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) {
* 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 "
/*
* 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));
}
* 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
/*
* 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);
* 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++;
}
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;
* 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 "
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);
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);
}
}
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;
/*
* 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++) {
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
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) {
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
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 *)
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);
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;
}
(__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;
}
/*
* 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 .
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 {
"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 {
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 {
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;
/*
* 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);
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;
}
/*
*/
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.
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 "
* 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 "
/*
* 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;
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: "),
* 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"));
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"));
/*
* 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);
/*
* 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"));
* 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.
*/
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);
/*
* 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;
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);
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);
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);
*/
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);
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);
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);
}
}
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;;
}
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;
}
}
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.
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
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),
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;
/*
/*
* 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);
}
/*
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;
}
/*
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)
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);
}
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),
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
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,
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),
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
/*
* 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
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);
}
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;
}
/*
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--;
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++) {
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);
}
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),
/*
* 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
*/
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++;
}
/*
}
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);
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);
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;
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);
}
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
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 {
__uint32_t addr,
xfs_ino_t inum,
int namelen,
- uchar_t *name)
+ char *name)
{
xfs_dahash_t hash = 0;
int byaddr;
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;
p->address = addr;
p->inum = inum;
p->seen = 0;
- p->namelen = namelen;
- p->name = name;
+ p->name = xname;
return !dup;
}
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);
}
}
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;
}
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;
}
*/
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
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"),
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
*/
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"),
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);
}
*/
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"),
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);
}
*/
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
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"),
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);
}
/*
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;
/*
* 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));
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
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;
/*
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);
/*
* 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
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);
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);
}
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)
* 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);
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);
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);
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);
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,
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);
* 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 {
* 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);
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);
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);
}
}
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(
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 {
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"),
}
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;
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(
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,
*
* 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
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';
/*
* 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"),
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 {
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));
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(
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"),
* 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)
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);
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);
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);
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);
break;
}
-
libxfs_trans_commit(tp,
- XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, 0);
+ XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC);
}
}
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);
}
/*
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;
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) {
/* 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? */
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);
*/
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);
} 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
* 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"),
}
*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;
}
freetab_t *freetab)
{
int badtail;
- xfs_dir2_data_off_t *bestsp;
+ __be16 *bestsp;
xfs_dabuf_t *bp;
xfs_dablk_t da_bno;
int i;
/* 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);
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"),
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)) {
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;
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)) {
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);
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;
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));
}
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;
*/
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);
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);
/*
* 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;
*/
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);
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
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
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;
}
}
-/* 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).
} 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;
/*
* 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);
/*
* 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;
*/
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);
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);
*/
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;
}
* 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;
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
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);
/*
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;
}
* 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,
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);
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);
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
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
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);
}
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);
* 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;
/* 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)
*/
ASSERT(error == 0);
error = libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES |
- XFS_TRANS_SYNC, NULL);
+ XFS_TRANS_SYNC);
ASSERT(error == 0);
}
#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
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) ||
int isadir,
prefetch_args_t *args)
{
- xfs_bmbt_rec_t *rp;
xfs_bmbt_ptr_t *pp;
int numrecs;
int i;
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]);
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]);
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;
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);
* 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
* 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;
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 ? */
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 */
/*
* 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)
/*
* 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);
/*
* 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);
}
* 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 &&
/*
* 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);
}
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;
}
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);
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);
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));
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;
/*
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;
}
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");
* 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);
}
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);
* 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);
}
*/
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:
}
}
(*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);
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);
* 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);
}
}
}
* 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);
}
*/
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);
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;
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++;
}
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)
/*
* 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++;
}
* 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);
}
}
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;
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++;
}
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
/*
* 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++;
}
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);
+ }
}
/*
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)
state, agno, bno, suspect);
}
- numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+ numrecs = be16_to_cpu(block->bb_numrecs);
/*
* leaf record in btree
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++;
}
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
* 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);
}
}
- 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);
}
}
/*
* 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
}
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);
}
}
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);
}
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)),
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));
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);
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);
}
/*
* 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);
}
/*
} 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;
}
/*
* 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;
}
}
- if (XFS_SB_VERSION_HASSHARED(sb)) {
+ if (xfs_sb_version_hasshared(sb)) {
fs_shared = 1;
if (!fs_shared_allowed) {
issue_warning = 1;
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(
}
}
- if (XFS_SB_VERSION_HASATTR(sb)) {
+ if (xfs_sb_version_hasattr(sb)) {
if (!fs_attributes_allowed) {
if (!no_modify) {
do_warn(
}
}
- if (XFS_SB_VERSION_HASATTR2(sb)) {
+ if (xfs_sb_version_hasattr2(sb)) {
if (!fs_attributes2_allowed) {
if (!no_modify) {
do_warn(
}
}
- if (XFS_SB_VERSION_HASNLINK(sb)) {
+ if (xfs_sb_version_hasnlink(sb)) {
if (!fs_inode_nlink_allowed) {
if (!no_modify) {
do_warn(
}
}
- if (XFS_SB_VERSION_HASQUOTA(sb)) {
+ if (xfs_sb_version_hasquota(sb)) {
if (!fs_quotas_allowed) {
if (!no_modify) {
do_warn(
}
}
- 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;
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);
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:
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;
do_prefetch = 0;
break;
case 't':
- report_interval = (int) strtol(optarg, 0, 0);
+ report_interval = (int)strtol(optarg, NULL, 0);
break;
case '?':
usage();
/*
* 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,
{
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;
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,
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=<value>,swidth=<value>\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);