Commit 37183a5f authored by Stephen Lord's avatar Stephen Lord Committed by Christoph Hellwig

XFS: Switch to native endian internal representation for extents

Switch xfs from using a big endian internal representation for
the in memory copy of extents to a host byte order representation.
The internal extents are read in once, then modified seperately
from the on disk ones. Since we search and manipulate the extents
multiple times, it is cheaper to convert them to host byte order
once and then keep them in that format. Worth about 5 to 10%
reduction in cpu time for some loads. Complicated by the fact
that the in memory extents are written out to the log sometimes,
and when expanding extents are used to write out the initial
block of extents.

Modid: 2.5.x-xfs:slinx:129646a
parent 1598e9c3
...@@ -3174,7 +3174,7 @@ xfs_bmap_extents_to_btree( ...@@ -3174,7 +3174,7 @@ xfs_bmap_extents_to_btree(
xfs_btree_cur_t *cur; /* bmap btree cursor */ xfs_btree_cur_t *cur; /* bmap btree cursor */
xfs_bmbt_rec_t *ep; /* extent list pointer */ xfs_bmbt_rec_t *ep; /* extent list pointer */
int error; /* error return value */ int error; /* error return value */
xfs_extnum_t i; /* extent list index */ xfs_extnum_t i, cnt; /* extent list index */
xfs_ifork_t *ifp; /* inode fork pointer */ xfs_ifork_t *ifp; /* inode fork pointer */
xfs_bmbt_key_t *kp; /* root block key pointer */ xfs_bmbt_key_t *kp; /* root block key pointer */
xfs_mount_t *mp; /* mount structure */ xfs_mount_t *mp; /* mount structure */
...@@ -3256,24 +3256,25 @@ xfs_bmap_extents_to_btree( ...@@ -3256,24 +3256,25 @@ xfs_bmap_extents_to_btree(
ablock = XFS_BUF_TO_BMBT_BLOCK(abp); ablock = XFS_BUF_TO_BMBT_BLOCK(abp);
INT_SET(ablock->bb_magic, ARCH_CONVERT, XFS_BMAP_MAGIC); INT_SET(ablock->bb_magic, ARCH_CONVERT, XFS_BMAP_MAGIC);
INT_ZERO(ablock->bb_level, ARCH_CONVERT); INT_ZERO(ablock->bb_level, ARCH_CONVERT);
INT_ZERO(ablock->bb_numrecs, ARCH_CONVERT);
INT_SET(ablock->bb_leftsib, ARCH_CONVERT, NULLDFSBNO); INT_SET(ablock->bb_leftsib, ARCH_CONVERT, NULLDFSBNO);
INT_SET(ablock->bb_rightsib, ARCH_CONVERT, NULLDFSBNO); INT_SET(ablock->bb_rightsib, ARCH_CONVERT, NULLDFSBNO);
arp = XFS_BMAP_REC_IADDR(ablock, 1, cur); arp = XFS_BMAP_REC_IADDR(ablock, 1, cur);
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
for (ep = ifp->if_u1.if_extents, i = 0; i < nextents; i++, ep++) { for (ep = ifp->if_u1.if_extents, cnt = i = 0; i < nextents; i++, ep++) {
if (!ISNULLSTARTBLOCK(xfs_bmbt_get_startblock(ep))) { if (!ISNULLSTARTBLOCK(xfs_bmbt_get_startblock(ep))) {
*arp++ = *ep; arp->l0 = INT_GET(ep->l0, ARCH_CONVERT);
INT_MOD(ablock->bb_numrecs, ARCH_CONVERT, +1); arp->l1 = INT_GET(ep->l1, ARCH_CONVERT);
arp++; cnt++;
} }
} }
INT_SET(ablock->bb_numrecs, ARCH_CONVERT, cnt);
ASSERT(INT_GET(ablock->bb_numrecs, ARCH_CONVERT) == XFS_IFORK_NEXTENTS(ip, whichfork)); ASSERT(INT_GET(ablock->bb_numrecs, ARCH_CONVERT) == XFS_IFORK_NEXTENTS(ip, whichfork));
/* /*
* Fill in the root key and pointer. * Fill in the root key and pointer.
*/ */
kp = XFS_BMAP_KEY_IADDR(block, 1, cur); kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
arp = XFS_BMAP_REC_IADDR(ablock, 1, cur); arp = XFS_BMAP_REC_IADDR(ablock, 1, cur);
INT_SET(kp->br_startoff, ARCH_CONVERT, xfs_bmbt_get_startoff(arp)); INT_SET(kp->br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(arp));
pp = XFS_BMAP_PTR_IADDR(block, 1, cur); pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
INT_SET(*pp, ARCH_CONVERT, args.fsbno); INT_SET(*pp, ARCH_CONVERT, args.fsbno);
/* /*
...@@ -4332,7 +4333,7 @@ xfs_bmap_read_extents( ...@@ -4332,7 +4333,7 @@ xfs_bmap_read_extents(
#ifdef XFS_BMAP_TRACE #ifdef XFS_BMAP_TRACE
static char fname[] = "xfs_bmap_read_extents"; static char fname[] = "xfs_bmap_read_extents";
#endif #endif
xfs_extnum_t i; /* index into the extents list */ xfs_extnum_t i, j; /* index into the extents list */
xfs_ifork_t *ifp; /* fork structure */ xfs_ifork_t *ifp; /* fork structure */
int level; /* btree level, for checking */ int level; /* btree level, for checking */
xfs_mount_t *mp; /* file system mount structure */ xfs_mount_t *mp; /* file system mount structure */
...@@ -4389,7 +4390,7 @@ xfs_bmap_read_extents( ...@@ -4389,7 +4390,7 @@ xfs_bmap_read_extents(
* Loop over all leaf nodes. Copy information to the extent list. * Loop over all leaf nodes. Copy information to the extent list.
*/ */
for (;;) { for (;;) {
xfs_bmbt_rec_t *frp; xfs_bmbt_rec_t *frp, *temp;
xfs_fsblock_t nextbno; xfs_fsblock_t nextbno;
xfs_extnum_t num_recs; xfs_extnum_t num_recs;
...@@ -4417,18 +4418,21 @@ xfs_bmap_read_extents( ...@@ -4417,18 +4418,21 @@ xfs_bmap_read_extents(
*/ */
frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt,
block, 1, mp->m_bmap_dmxr[0]); block, 1, mp->m_bmap_dmxr[0]);
memcpy(trp, frp, num_recs * sizeof(*frp)); 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);
}
if (exntf == XFS_EXTFMT_NOSTATE) { if (exntf == XFS_EXTFMT_NOSTATE) {
/* /*
* Check all attribute bmap btree records and * Check all attribute bmap btree records and
* any "older" data bmap btree records for a * any "older" data bmap btree records for a
* set bit in the "extent flag" position. * set bit in the "extent flag" position.
*/ */
if (xfs_check_nostate_extents(trp, num_recs)) { if (xfs_check_nostate_extents(temp, num_recs)) {
goto error0; goto error0;
} }
} }
trp += num_recs;
i += num_recs; i += num_recs;
xfs_trans_brelse(tp, bp); xfs_trans_brelse(tp, bp);
bno = nextbno; bno = nextbno;
...@@ -6257,7 +6261,7 @@ xfs_bmap_count_leaves( ...@@ -6257,7 +6261,7 @@ xfs_bmap_count_leaves(
int b; int b;
for ( b = 1; b <= numrecs; b++, frp++) for ( b = 1; b <= numrecs; b++, frp++)
*count += xfs_bmbt_get_blockcount(frp); *count += xfs_bmbt_disk_get_blockcount(frp);
return 0; return 0;
} }
This diff is collapsed.
...@@ -509,6 +509,41 @@ xfs_exntst_t ...@@ -509,6 +509,41 @@ xfs_exntst_t
xfs_bmbt_get_state( xfs_bmbt_get_state(
xfs_bmbt_rec_t *r); xfs_bmbt_rec_t *r);
#if ARCH_CONVERT != ARCH_NOCONVERT
void
xfs_bmbt_disk_get_all(
xfs_bmbt_rec_t *r,
xfs_bmbt_irec_t *s);
xfs_exntst_t
xfs_bmbt_disk_get_state(
xfs_bmbt_rec_t *r);
xfs_filblks_t
xfs_bmbt_disk_get_blockcount(
xfs_bmbt_rec_t *r);
xfs_fsblock_t
xfs_bmbt_disk_get_startblock(
xfs_bmbt_rec_t *r);
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
int int
xfs_bmbt_increment( xfs_bmbt_increment(
struct xfs_btree_cur *, struct xfs_btree_cur *,
...@@ -607,6 +642,26 @@ xfs_bmbt_set_state( ...@@ -607,6 +642,26 @@ xfs_bmbt_set_state(
xfs_bmbt_rec_t *r, xfs_bmbt_rec_t *r,
xfs_exntst_t v); xfs_exntst_t v);
#if ARCH_CONVERT != ARCH_NOCONVERT
void
xfs_bmbt_disk_set_all(
xfs_bmbt_rec_t *r,
xfs_bmbt_irec_t *s);
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, 0, b, c, v) \
xfs_bmbt_set_allf(r, 0, b, c, v)
#endif
void void
xfs_bmbt_to_bmdr( xfs_bmbt_to_bmdr(
xfs_bmbt_block_t *, xfs_bmbt_block_t *,
......
...@@ -261,9 +261,9 @@ xfs_btree_check_rec( ...@@ -261,9 +261,9 @@ xfs_btree_check_rec(
r1 = ar1; r1 = ar1;
r2 = ar2; r2 = ar2;
ASSERT(xfs_bmbt_get_startoff(r1) + ASSERT(xfs_bmbt_disk_get_startoff(r1) +
xfs_bmbt_get_blockcount(r1) <= xfs_bmbt_disk_get_blockcount(r1) <=
xfs_bmbt_get_startoff(r2)); xfs_bmbt_disk_get_startoff(r2));
break; break;
} }
case XFS_BTNUM_INO: { case XFS_BTNUM_INO: {
......
...@@ -56,8 +56,9 @@ STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int); ...@@ -56,8 +56,9 @@ STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int);
*/ */
STATIC void STATIC void
xfs_validate_extents( xfs_validate_extents(
xfs_bmbt_rec_32_t *ep, xfs_bmbt_rec_t *ep,
int nrecs, int nrecs,
int disk,
xfs_exntfmt_t fmt) xfs_exntfmt_t fmt)
{ {
xfs_bmbt_irec_t irec; xfs_bmbt_irec_t irec;
...@@ -66,14 +67,17 @@ xfs_validate_extents( ...@@ -66,14 +67,17 @@ xfs_validate_extents(
for (i = 0; i < nrecs; i++) { for (i = 0; i < nrecs; i++) {
memcpy(&rec, ep, sizeof(rec)); memcpy(&rec, ep, sizeof(rec));
xfs_bmbt_get_all(&rec, &irec); if (disk)
xfs_bmbt_disk_get_all(&rec, &irec);
else
xfs_bmbt_get_all(&rec, &irec);
if (fmt == XFS_EXTFMT_NOSTATE) if (fmt == XFS_EXTFMT_NOSTATE)
ASSERT(irec.br_state == XFS_EXT_NORM); ASSERT(irec.br_state == XFS_EXT_NORM);
ep++; ep++;
} }
} }
#else /* DEBUG */ #else /* DEBUG */
#define xfs_validate_extents(ep, nrecs, fmt) #define xfs_validate_extents(ep, nrecs, disk, fmt)
#endif /* DEBUG */ #endif /* DEBUG */
/* /*
...@@ -598,9 +602,10 @@ xfs_iformat_extents( ...@@ -598,9 +602,10 @@ xfs_iformat_extents(
int whichfork) int whichfork)
{ {
xfs_ifork_t *ifp; xfs_ifork_t *ifp;
int nex; int nex, i;
int real_size; int real_size;
int size; int size;
xfs_bmbt_rec_t *ep, *dp;
ifp = XFS_IFORK_PTR(ip, whichfork); ifp = XFS_IFORK_PTR(ip, whichfork);
nex = XFS_DFORK_NEXTENTS_ARCH(dip, whichfork, ARCH_CONVERT); nex = XFS_DFORK_NEXTENTS_ARCH(dip, whichfork, ARCH_CONVERT);
...@@ -633,10 +638,18 @@ xfs_iformat_extents( ...@@ -633,10 +638,18 @@ xfs_iformat_extents(
ifp->if_real_bytes = real_size; ifp->if_real_bytes = real_size;
if (size) { if (size) {
xfs_validate_extents( xfs_validate_extents(
(xfs_bmbt_rec_32_t *)XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_CONVERT), (xfs_bmbt_rec_t *)XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_CONVERT),
nex, XFS_EXTFMT_INODE(ip)); nex, 1, XFS_EXTFMT_INODE(ip));
memcpy(ifp->if_u1.if_extents, dp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_CONVERT);
XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_CONVERT), size); ep = ifp->if_u1.if_extents;
#if ARCH_CONVERT != ARCH_NOCONVERT
for (i = 0; i < nex; i++, ep++, dp++) {
ep->l0 = INT_GET(dp->l0, ARCH_CONVERT);
ep->l1 = INT_GET(dp->l1, ARCH_CONVERT);
}
#else
memcpy(ep, dp, size);
#endif
xfs_bmap_trace_exlist("xfs_iformat_extents", ip, nex, xfs_bmap_trace_exlist("xfs_iformat_extents", ip, nex,
whichfork); whichfork);
if (whichfork != XFS_DATA_FORK || if (whichfork != XFS_DATA_FORK ||
...@@ -979,8 +992,8 @@ xfs_iread_extents( ...@@ -979,8 +992,8 @@ xfs_iread_extents(
ifp->if_flags &= ~XFS_IFEXTENTS; ifp->if_flags &= ~XFS_IFEXTENTS;
return error; return error;
} }
xfs_validate_extents((xfs_bmbt_rec_32_t *)ifp->if_u1.if_extents, xfs_validate_extents((xfs_bmbt_rec_t *)ifp->if_u1.if_extents,
XFS_IFORK_NEXTENTS(ip, whichfork), XFS_EXTFMT_INODE(ip)); XFS_IFORK_NEXTENTS(ip, whichfork), 0, XFS_EXTFMT_INODE(ip));
return 0; return 0;
} }
...@@ -2617,11 +2630,11 @@ xfs_iunpin_wait( ...@@ -2617,11 +2630,11 @@ xfs_iunpin_wait(
int int
xfs_iextents_copy( xfs_iextents_copy(
xfs_inode_t *ip, xfs_inode_t *ip,
xfs_bmbt_rec_32_t *buffer, xfs_bmbt_rec_t *buffer,
int whichfork) int whichfork)
{ {
int copied; int copied;
xfs_bmbt_rec_32_t *dest_ep; xfs_bmbt_rec_t *dest_ep;
xfs_bmbt_rec_t *ep; xfs_bmbt_rec_t *ep;
#ifdef XFS_BMAP_TRACE #ifdef XFS_BMAP_TRACE
static char fname[] = "xfs_iextents_copy"; static char fname[] = "xfs_iextents_copy";
...@@ -2638,28 +2651,13 @@ xfs_iextents_copy( ...@@ -2638,28 +2651,13 @@ xfs_iextents_copy(
nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
xfs_bmap_trace_exlist(fname, ip, nrecs, whichfork); xfs_bmap_trace_exlist(fname, ip, nrecs, whichfork);
ASSERT(nrecs > 0); ASSERT(nrecs > 0);
if (nrecs == XFS_IFORK_NEXTENTS(ip, whichfork)) {
/*
* There are no delayed allocation extents,
* so just copy everything.
*/
ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
ASSERT(ifp->if_bytes ==
(XFS_IFORK_NEXTENTS(ip, whichfork) *
(uint)sizeof(xfs_bmbt_rec_t)));
memcpy(buffer, ifp->if_u1.if_extents, ifp->if_bytes);
xfs_validate_extents(buffer, nrecs, XFS_EXTFMT_INODE(ip));
return ifp->if_bytes;
}
ASSERT(whichfork == XFS_DATA_FORK);
/* /*
* There are some delayed allocation extents in the * There are some delayed allocation extents in the
* inode, so copy the extents one at a time and skip * inode, so copy the extents one at a time and skip
* the delayed ones. There must be at least one * the delayed ones. There must be at least one
* non-delayed extent. * non-delayed extent.
*/ */
ASSERT(nrecs > ip->i_d.di_nextents);
ep = ifp->if_u1.if_extents; ep = ifp->if_u1.if_extents;
dest_ep = buffer; dest_ep = buffer;
copied = 0; copied = 0;
...@@ -2673,15 +2671,19 @@ xfs_iextents_copy( ...@@ -2673,15 +2671,19 @@ xfs_iextents_copy(
continue; continue;
} }
*dest_ep = *(xfs_bmbt_rec_32_t *)ep; #if ARCH_CONVERT != ARCH_NOCONVERT
/* Translate to on disk format */
dest_ep->l0 = INT_GET(ep->l0, ARCH_CONVERT);
dest_ep->l1 = INT_GET(ep->l1, ARCH_CONVERT);
#else
*dest_ep = *ep;
#endif
dest_ep++; dest_ep++;
ep++; ep++;
copied++; copied++;
} }
ASSERT(copied != 0); ASSERT(copied != 0);
ASSERT(copied == ip->i_d.di_nextents); xfs_validate_extents(buffer, copied, 1, XFS_EXTFMT_INODE(ip));
ASSERT((copied * (uint)sizeof(xfs_bmbt_rec_t)) <= XFS_IFORK_DSIZE(ip));
xfs_validate_extents(buffer, copied, XFS_EXTFMT_INODE(ip));
return (copied * (uint)sizeof(xfs_bmbt_rec_t)); return (copied * (uint)sizeof(xfs_bmbt_rec_t));
} }
...@@ -2754,7 +2756,7 @@ xfs_iflush_fork( ...@@ -2754,7 +2756,7 @@ xfs_iflush_fork(
if ((iip->ili_format.ilf_fields & extflag[whichfork]) && if ((iip->ili_format.ilf_fields & extflag[whichfork]) &&
(ifp->if_bytes > 0)) { (ifp->if_bytes > 0)) {
ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0);
(void)xfs_iextents_copy(ip, (xfs_bmbt_rec_32_t *)cp, (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp,
whichfork); whichfork);
} }
break; break;
......
...@@ -520,7 +520,7 @@ void xfs_iext_realloc(xfs_inode_t *, int, int); ...@@ -520,7 +520,7 @@ void xfs_iext_realloc(xfs_inode_t *, int, int);
void xfs_iroot_realloc(xfs_inode_t *, int, int); void xfs_iroot_realloc(xfs_inode_t *, int, int);
void xfs_ipin(xfs_inode_t *); void xfs_ipin(xfs_inode_t *);
void xfs_iunpin(xfs_inode_t *); void xfs_iunpin(xfs_inode_t *);
int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_32_t *, int); int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int);
int xfs_iflush(xfs_inode_t *, uint); int xfs_iflush(xfs_inode_t *, uint);
int xfs_iflush_all(struct xfs_mount *, int); int xfs_iflush_all(struct xfs_mount *, int);
int xfs_ibusy_check(xfs_inode_t *, int); int xfs_ibusy_check(xfs_inode_t *, int);
......
...@@ -214,7 +214,7 @@ xfs_inode_item_format( ...@@ -214,7 +214,7 @@ xfs_inode_item_format(
xfs_log_iovec_t *vecp; xfs_log_iovec_t *vecp;
xfs_inode_t *ip; xfs_inode_t *ip;
size_t data_bytes; size_t data_bytes;
xfs_bmbt_rec_32_t *ext_buffer; xfs_bmbt_rec_t *ext_buffer;
int nrecs; int nrecs;
xfs_mount_t *mp; xfs_mount_t *mp;
...@@ -314,6 +314,7 @@ xfs_inode_item_format( ...@@ -314,6 +314,7 @@ xfs_inode_item_format(
nrecs = ip->i_df.if_bytes / nrecs = ip->i_df.if_bytes /
(uint)sizeof(xfs_bmbt_rec_t); (uint)sizeof(xfs_bmbt_rec_t);
ASSERT(nrecs > 0); ASSERT(nrecs > 0);
#if ARCH_CONVERT == ARCH_NOCONVERT
if (nrecs == ip->i_d.di_nextents) { if (nrecs == ip->i_d.di_nextents) {
/* /*
* There are no delayed allocation * There are no delayed allocation
...@@ -323,10 +324,14 @@ xfs_inode_item_format( ...@@ -323,10 +324,14 @@ xfs_inode_item_format(
vecp->i_addr = vecp->i_addr =
(char *)(ip->i_df.if_u1.if_extents); (char *)(ip->i_df.if_u1.if_extents);
vecp->i_len = ip->i_df.if_bytes; vecp->i_len = ip->i_df.if_bytes;
} else { } else
#endif
{
/* /*
* There are delayed allocation extents * There are delayed allocation extents
* in the inode. Use xfs_iextents_copy() * in the inode, or we need to convert
* the extents to on disk format.
* Use xfs_iextents_copy()
* to copy only the real extents into * to copy only the real extents into
* a separate buffer. We'll free the * a separate buffer. We'll free the
* buffer in the unlock routine. * buffer in the unlock routine.
...@@ -336,7 +341,7 @@ xfs_inode_item_format( ...@@ -336,7 +341,7 @@ xfs_inode_item_format(
iip->ili_extents_buf = ext_buffer; iip->ili_extents_buf = ext_buffer;
vecp->i_addr = (xfs_caddr_t)ext_buffer; vecp->i_addr = (xfs_caddr_t)ext_buffer;
vecp->i_len = xfs_iextents_copy(ip, ext_buffer, vecp->i_len = xfs_iextents_copy(ip, ext_buffer,
XFS_DATA_FORK); XFS_DATA_FORK);
} }
ASSERT(vecp->i_len <= ip->i_df.if_bytes); ASSERT(vecp->i_len <= ip->i_df.if_bytes);
iip->ili_format.ilf_dsize = vecp->i_len; iip->ili_format.ilf_dsize = vecp->i_len;
...@@ -428,6 +433,7 @@ xfs_inode_item_format( ...@@ -428,6 +433,7 @@ xfs_inode_item_format(
ASSERT(!(iip->ili_format.ilf_fields & ASSERT(!(iip->ili_format.ilf_fields &
(XFS_ILOG_ADATA | XFS_ILOG_ABROOT))); (XFS_ILOG_ADATA | XFS_ILOG_ABROOT)));
if (iip->ili_format.ilf_fields & XFS_ILOG_AEXT) { if (iip->ili_format.ilf_fields & XFS_ILOG_AEXT) {
ASSERT(!(iip->ili_format.ilf_fields & XFS_ILOG_DEXT));
ASSERT(ip->i_afp->if_bytes > 0); ASSERT(ip->i_afp->if_bytes > 0);
ASSERT(ip->i_afp->if_u1.if_extents != NULL); ASSERT(ip->i_afp->if_u1.if_extents != NULL);
ASSERT(ip->i_d.di_anextents > 0); ASSERT(ip->i_d.di_anextents > 0);
...@@ -437,12 +443,25 @@ xfs_inode_item_format( ...@@ -437,12 +443,25 @@ xfs_inode_item_format(
#endif #endif
ASSERT(nrecs > 0); ASSERT(nrecs > 0);
ASSERT(nrecs == ip->i_d.di_anextents); ASSERT(nrecs == ip->i_d.di_anextents);
#if ARCH_CONVERT == ARCH_NOCONVERT
/* /*
* There are not delayed allocation extents * There are not delayed allocation extents
* for attributes, so just point at the array. * for attributes, so just point at the array.
*/ */
vecp->i_addr = (char *)(ip->i_afp->if_u1.if_extents); vecp->i_addr = (char *)(ip->i_afp->if_u1.if_extents);
vecp->i_len = ip->i_afp->if_bytes; vecp->i_len = ip->i_afp->if_bytes;
#else
ASSERT(iip->ili_aextents_buf == NULL);
/*
* Need to endian flip before logging
*/
ext_buffer = kmem_alloc(ip->i_df.if_bytes,
KM_SLEEP);
iip->ili_aextents_buf = ext_buffer;
vecp->i_addr = (xfs_caddr_t)ext_buffer;
vecp->i_len = xfs_iextents_copy(ip, ext_buffer,
XFS_ATTR_FORK);
#endif
iip->ili_format.ilf_asize = vecp->i_len; iip->ili_format.ilf_asize = vecp->i_len;
vecp++; vecp++;
nvecs++; nvecs++;
...@@ -630,7 +649,6 @@ xfs_inode_item_unlock( ...@@ -630,7 +649,6 @@ xfs_inode_item_unlock(
* If the inode needed a separate buffer with which to log * If the inode needed a separate buffer with which to log
* its extents, then free it now. * its extents, then free it now.
*/ */
/* FIXME */
if (iip->ili_extents_buf != NULL) { if (iip->ili_extents_buf != NULL) {
ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS); ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS);
ASSERT(ip->i_d.di_nextents > 0); ASSERT(ip->i_d.di_nextents > 0);
...@@ -639,6 +657,14 @@ xfs_inode_item_unlock( ...@@ -639,6 +657,14 @@ xfs_inode_item_unlock(
kmem_free(iip->ili_extents_buf, ip->i_df.if_bytes); kmem_free(iip->ili_extents_buf, ip->i_df.if_bytes);
iip->ili_extents_buf = NULL; iip->ili_extents_buf = NULL;
} }
if (iip->ili_aextents_buf != NULL) {
ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS);
ASSERT(ip->i_d.di_anextents > 0);
ASSERT(iip->ili_format.ilf_fields & XFS_ILOG_AEXT);
ASSERT(ip->i_afp->if_bytes > 0);
kmem_free(iip->ili_aextents_buf, ip->i_afp->if_bytes);
iip->ili_aextents_buf = NULL;
}
/* /*
* Figure out if we should unlock the inode or not. * Figure out if we should unlock the inode or not.
......
...@@ -141,7 +141,10 @@ typedef struct xfs_inode_log_item { ...@@ -141,7 +141,10 @@ typedef struct xfs_inode_log_item {
unsigned short ili_flags; /* misc flags */ unsigned short ili_flags; /* misc flags */
unsigned short ili_logged; /* flushed logged data */ unsigned short ili_logged; /* flushed logged data */
unsigned int ili_last_fields; /* fields when flushed */ unsigned int ili_last_fields; /* fields when flushed */
struct xfs_bmbt_rec_32 *ili_extents_buf; /* array of logged exts */ struct xfs_bmbt_rec_32 *ili_extents_buf; /* array of logged
data exts */
struct xfs_bmbt_rec_32 *ili_aextents_buf; /* array of logged
attr exts */
unsigned int ili_pushbuf_flag; /* one bit used in push_ail */ unsigned int ili_pushbuf_flag; /* one bit used in push_ail */
#ifdef DEBUG #ifdef DEBUG
......
...@@ -2364,7 +2364,7 @@ xfs_btbmap(xfs_bmbt_block_t *bt, int bsz) ...@@ -2364,7 +2364,7 @@ xfs_btbmap(xfs_bmbt_block_t *bt, int bsz)
r = (xfs_bmbt_rec_t *)XFS_BTREE_REC_ADDR(bsz, r = (xfs_bmbt_rec_t *)XFS_BTREE_REC_ADDR(bsz,
xfs_bmbt, bt, i, 0); xfs_bmbt, bt, i, 0);
xfs_bmbt_get_all((xfs_bmbt_rec_t *)r, &irec); xfs_bmbt_disk_get_all((xfs_bmbt_rec_t *)r, &irec);
kdb_printf("rec %d startoff %Ld startblock %Lx blockcount %Ld flag %d\n", kdb_printf("rec %d startoff %Ld startblock %Lx blockcount %Ld flag %d\n",
i, irec.br_startoff, i, irec.br_startoff,
(__uint64_t)irec.br_startblock, (__uint64_t)irec.br_startblock,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment