Merge branch 'xfs-da-geom' into for-next
This commit is contained in:
Коммит
8612c7e594
|
@ -88,6 +88,7 @@ xfs_attr_args_init(
|
|||
return EINVAL;
|
||||
|
||||
memset(args, 0, sizeof(*args));
|
||||
args->geo = dp->i_mount->m_attr_geo;
|
||||
args->whichfork = XFS_ATTR_FORK;
|
||||
args->dp = dp;
|
||||
args->flags = flags;
|
||||
|
@ -173,12 +174,10 @@ xfs_attr_calc_size(
|
|||
* Determine space new attribute will use, and if it would be
|
||||
* "local" or "remote" (note: local != inline).
|
||||
*/
|
||||
size = xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
|
||||
mp->m_sb.sb_blocksize, local);
|
||||
|
||||
size = xfs_attr_leaf_newentsize(args, local);
|
||||
nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
|
||||
if (*local) {
|
||||
if (size > (mp->m_sb.sb_blocksize >> 1)) {
|
||||
if (size > (args->geo->blksize / 2)) {
|
||||
/* Double split possible */
|
||||
nblks *= 2;
|
||||
}
|
||||
|
@ -864,7 +863,7 @@ xfs_attr_leaf_get(xfs_da_args_t *args)
|
|||
}
|
||||
|
||||
/*========================================================================
|
||||
* External routines when attribute list size > XFS_LBSIZE(mp).
|
||||
* External routines when attribute list size > geo->blksize
|
||||
*========================================================================*/
|
||||
|
||||
/*
|
||||
|
@ -897,8 +896,6 @@ restart:
|
|||
state = xfs_da_state_alloc();
|
||||
state->args = args;
|
||||
state->mp = mp;
|
||||
state->blocksize = state->mp->m_sb.sb_blocksize;
|
||||
state->node_ents = state->mp->m_attr_node_ents;
|
||||
|
||||
/*
|
||||
* Search to see if name already exists, and get back a pointer
|
||||
|
@ -1076,8 +1073,6 @@ restart:
|
|||
state = xfs_da_state_alloc();
|
||||
state->args = args;
|
||||
state->mp = mp;
|
||||
state->blocksize = state->mp->m_sb.sb_blocksize;
|
||||
state->node_ents = state->mp->m_attr_node_ents;
|
||||
state->inleaf = 0;
|
||||
error = xfs_da3_node_lookup_int(state, &retval);
|
||||
if (error)
|
||||
|
@ -1168,8 +1163,6 @@ xfs_attr_node_removename(xfs_da_args_t *args)
|
|||
state = xfs_da_state_alloc();
|
||||
state->args = args;
|
||||
state->mp = 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.
|
||||
|
@ -1431,8 +1424,6 @@ xfs_attr_node_get(xfs_da_args_t *args)
|
|||
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.
|
||||
|
|
|
@ -80,11 +80,12 @@ STATIC int xfs_attr3_leaf_figure_balance(xfs_da_state_t *state,
|
|||
/*
|
||||
* Utility routines.
|
||||
*/
|
||||
STATIC void xfs_attr3_leaf_moveents(struct xfs_attr_leafblock *src_leaf,
|
||||
STATIC void xfs_attr3_leaf_moveents(struct xfs_da_args *args,
|
||||
struct xfs_attr_leafblock *src_leaf,
|
||||
struct xfs_attr3_icleaf_hdr *src_ichdr, int src_start,
|
||||
struct xfs_attr_leafblock *dst_leaf,
|
||||
struct xfs_attr3_icleaf_hdr *dst_ichdr, int dst_start,
|
||||
int move_count, struct xfs_mount *mp);
|
||||
int move_count);
|
||||
STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
|
||||
|
||||
void
|
||||
|
@ -711,6 +712,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
|
|||
|
||||
memset((char *)&nargs, 0, sizeof(nargs));
|
||||
nargs.dp = dp;
|
||||
nargs.geo = args->geo;
|
||||
nargs.firstblock = args->firstblock;
|
||||
nargs.flist = args->flist;
|
||||
nargs.total = args->total;
|
||||
|
@ -805,18 +807,18 @@ xfs_attr3_leaf_to_shortform(
|
|||
|
||||
trace_xfs_attr_leaf_to_sf(args);
|
||||
|
||||
tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP);
|
||||
tmpbuffer = kmem_alloc(args->geo->blksize, KM_SLEEP);
|
||||
if (!tmpbuffer)
|
||||
return ENOMEM;
|
||||
|
||||
memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(dp->i_mount));
|
||||
memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
|
||||
|
||||
leaf = (xfs_attr_leafblock_t *)tmpbuffer;
|
||||
xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
|
||||
entry = xfs_attr3_leaf_entryp(leaf);
|
||||
|
||||
/* XXX (dgc): buffer is about to be marked stale - why zero it? */
|
||||
memset(bp->b_addr, 0, XFS_LBSIZE(dp->i_mount));
|
||||
memset(bp->b_addr, 0, args->geo->blksize);
|
||||
|
||||
/*
|
||||
* Clean out the prior contents of the attribute list.
|
||||
|
@ -838,6 +840,7 @@ xfs_attr3_leaf_to_shortform(
|
|||
* Copy the attributes
|
||||
*/
|
||||
memset((char *)&nargs, 0, sizeof(nargs));
|
||||
nargs.geo = args->geo;
|
||||
nargs.dp = dp;
|
||||
nargs.firstblock = args->firstblock;
|
||||
nargs.flist = args->flist;
|
||||
|
@ -904,12 +907,12 @@ xfs_attr3_leaf_to_node(
|
|||
/* copy leaf to new buffer, update identifiers */
|
||||
xfs_trans_buf_set_type(args->trans, bp2, XFS_BLFT_ATTR_LEAF_BUF);
|
||||
bp2->b_ops = bp1->b_ops;
|
||||
memcpy(bp2->b_addr, bp1->b_addr, XFS_LBSIZE(mp));
|
||||
memcpy(bp2->b_addr, bp1->b_addr, args->geo->blksize);
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
struct xfs_da3_blkinfo *hdr3 = bp2->b_addr;
|
||||
hdr3->blkno = cpu_to_be64(bp2->b_bn);
|
||||
}
|
||||
xfs_trans_log_buf(args->trans, bp2, 0, XFS_LBSIZE(mp) - 1);
|
||||
xfs_trans_log_buf(args->trans, bp2, 0, args->geo->blksize - 1);
|
||||
|
||||
/*
|
||||
* Set up the new root node.
|
||||
|
@ -930,7 +933,7 @@ xfs_attr3_leaf_to_node(
|
|||
btree[0].before = cpu_to_be32(blkno);
|
||||
icnodehdr.count = 1;
|
||||
dp->d_ops->node_hdr_to_disk(node, &icnodehdr);
|
||||
xfs_trans_log_buf(args->trans, bp1, 0, XFS_LBSIZE(mp) - 1);
|
||||
xfs_trans_log_buf(args->trans, bp1, 0, args->geo->blksize - 1);
|
||||
error = 0;
|
||||
out:
|
||||
return error;
|
||||
|
@ -966,10 +969,10 @@ xfs_attr3_leaf_create(
|
|||
bp->b_ops = &xfs_attr3_leaf_buf_ops;
|
||||
xfs_trans_buf_set_type(args->trans, bp, XFS_BLFT_ATTR_LEAF_BUF);
|
||||
leaf = bp->b_addr;
|
||||
memset(leaf, 0, XFS_LBSIZE(mp));
|
||||
memset(leaf, 0, args->geo->blksize);
|
||||
|
||||
memset(&ichdr, 0, sizeof(ichdr));
|
||||
ichdr.firstused = XFS_LBSIZE(mp);
|
||||
ichdr.firstused = args->geo->blksize;
|
||||
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
struct xfs_da3_blkinfo *hdr3 = bp->b_addr;
|
||||
|
@ -988,7 +991,7 @@ xfs_attr3_leaf_create(
|
|||
ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base;
|
||||
|
||||
xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr);
|
||||
xfs_trans_log_buf(args->trans, bp, 0, XFS_LBSIZE(mp) - 1);
|
||||
xfs_trans_log_buf(args->trans, bp, 0, args->geo->blksize - 1);
|
||||
|
||||
*bpp = bp;
|
||||
return 0;
|
||||
|
@ -1074,8 +1077,7 @@ xfs_attr3_leaf_add(
|
|||
leaf = bp->b_addr;
|
||||
xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
|
||||
ASSERT(args->index >= 0 && args->index <= ichdr.count);
|
||||
entsize = xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
|
||||
args->trans->t_mountp->m_sb.sb_blocksize, NULL);
|
||||
entsize = xfs_attr_leaf_newentsize(args, NULL);
|
||||
|
||||
/*
|
||||
* Search through freemap for first-fit on new name length.
|
||||
|
@ -1174,17 +1176,14 @@ xfs_attr3_leaf_add_work(
|
|||
* Allocate space for the new string (at the end of the run).
|
||||
*/
|
||||
mp = args->trans->t_mountp;
|
||||
ASSERT(ichdr->freemap[mapindex].base < XFS_LBSIZE(mp));
|
||||
ASSERT(ichdr->freemap[mapindex].base < args->geo->blksize);
|
||||
ASSERT((ichdr->freemap[mapindex].base & 0x3) == 0);
|
||||
ASSERT(ichdr->freemap[mapindex].size >=
|
||||
xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
|
||||
mp->m_sb.sb_blocksize, NULL));
|
||||
ASSERT(ichdr->freemap[mapindex].size < XFS_LBSIZE(mp));
|
||||
xfs_attr_leaf_newentsize(args, NULL));
|
||||
ASSERT(ichdr->freemap[mapindex].size < args->geo->blksize);
|
||||
ASSERT((ichdr->freemap[mapindex].size & 0x3) == 0);
|
||||
|
||||
ichdr->freemap[mapindex].size -=
|
||||
xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
|
||||
mp->m_sb.sb_blocksize, &tmp);
|
||||
ichdr->freemap[mapindex].size -= xfs_attr_leaf_newentsize(args, &tmp);
|
||||
|
||||
entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base +
|
||||
ichdr->freemap[mapindex].size);
|
||||
|
@ -1269,14 +1268,13 @@ xfs_attr3_leaf_compact(
|
|||
struct xfs_attr_leafblock *leaf_dst;
|
||||
struct xfs_attr3_icleaf_hdr ichdr_src;
|
||||
struct xfs_trans *trans = args->trans;
|
||||
struct xfs_mount *mp = trans->t_mountp;
|
||||
char *tmpbuffer;
|
||||
|
||||
trace_xfs_attr_leaf_compact(args);
|
||||
|
||||
tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP);
|
||||
memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(mp));
|
||||
memset(bp->b_addr, 0, XFS_LBSIZE(mp));
|
||||
tmpbuffer = kmem_alloc(args->geo->blksize, KM_SLEEP);
|
||||
memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
|
||||
memset(bp->b_addr, 0, args->geo->blksize);
|
||||
leaf_src = (xfs_attr_leafblock_t *)tmpbuffer;
|
||||
leaf_dst = bp->b_addr;
|
||||
|
||||
|
@ -1289,7 +1287,7 @@ xfs_attr3_leaf_compact(
|
|||
|
||||
/* Initialise the incore headers */
|
||||
ichdr_src = *ichdr_dst; /* struct copy */
|
||||
ichdr_dst->firstused = XFS_LBSIZE(mp);
|
||||
ichdr_dst->firstused = args->geo->blksize;
|
||||
ichdr_dst->usedbytes = 0;
|
||||
ichdr_dst->count = 0;
|
||||
ichdr_dst->holes = 0;
|
||||
|
@ -1304,13 +1302,13 @@ xfs_attr3_leaf_compact(
|
|||
* Copy all entry's in the same (sorted) order,
|
||||
* but allocate name/value pairs packed and in sequence.
|
||||
*/
|
||||
xfs_attr3_leaf_moveents(leaf_src, &ichdr_src, 0, leaf_dst, ichdr_dst, 0,
|
||||
ichdr_src.count, mp);
|
||||
xfs_attr3_leaf_moveents(args, leaf_src, &ichdr_src, 0,
|
||||
leaf_dst, ichdr_dst, 0, ichdr_src.count);
|
||||
/*
|
||||
* this logs the entire buffer, but the caller must write the header
|
||||
* back to the buffer when it is finished modifying it.
|
||||
*/
|
||||
xfs_trans_log_buf(trans, bp, 0, XFS_LBSIZE(mp) - 1);
|
||||
xfs_trans_log_buf(trans, bp, 0, args->geo->blksize - 1);
|
||||
|
||||
kmem_free(tmpbuffer);
|
||||
}
|
||||
|
@ -1461,8 +1459,8 @@ xfs_attr3_leaf_rebalance(
|
|||
/*
|
||||
* Move high entries from leaf1 to low end of leaf2.
|
||||
*/
|
||||
xfs_attr3_leaf_moveents(leaf1, &ichdr1, ichdr1.count - count,
|
||||
leaf2, &ichdr2, 0, count, state->mp);
|
||||
xfs_attr3_leaf_moveents(args, leaf1, &ichdr1,
|
||||
ichdr1.count - count, leaf2, &ichdr2, 0, count);
|
||||
|
||||
} else if (count > ichdr1.count) {
|
||||
/*
|
||||
|
@ -1490,14 +1488,14 @@ xfs_attr3_leaf_rebalance(
|
|||
/*
|
||||
* Move low entries from leaf2 to high end of leaf1.
|
||||
*/
|
||||
xfs_attr3_leaf_moveents(leaf2, &ichdr2, 0, leaf1, &ichdr1,
|
||||
ichdr1.count, count, state->mp);
|
||||
xfs_attr3_leaf_moveents(args, leaf2, &ichdr2, 0, leaf1, &ichdr1,
|
||||
ichdr1.count, count);
|
||||
}
|
||||
|
||||
xfs_attr3_leaf_hdr_to_disk(leaf1, &ichdr1);
|
||||
xfs_attr3_leaf_hdr_to_disk(leaf2, &ichdr2);
|
||||
xfs_trans_log_buf(args->trans, blk1->bp, 0, state->blocksize-1);
|
||||
xfs_trans_log_buf(args->trans, blk2->bp, 0, state->blocksize-1);
|
||||
xfs_trans_log_buf(args->trans, blk1->bp, 0, args->geo->blksize - 1);
|
||||
xfs_trans_log_buf(args->trans, blk2->bp, 0, args->geo->blksize - 1);
|
||||
|
||||
/*
|
||||
* Copy out last hashval in each block for B-tree code.
|
||||
|
@ -1592,11 +1590,9 @@ xfs_attr3_leaf_figure_balance(
|
|||
max = ichdr1->count + ichdr2->count;
|
||||
half = (max + 1) * sizeof(*entry);
|
||||
half += ichdr1->usedbytes + ichdr2->usedbytes +
|
||||
xfs_attr_leaf_newentsize(state->args->namelen,
|
||||
state->args->valuelen,
|
||||
state->blocksize, NULL);
|
||||
xfs_attr_leaf_newentsize(state->args, NULL);
|
||||
half /= 2;
|
||||
lastdelta = state->blocksize;
|
||||
lastdelta = state->args->geo->blksize;
|
||||
entry = xfs_attr3_leaf_entryp(leaf1);
|
||||
for (count = index = 0; count < max; entry++, index++, count++) {
|
||||
|
||||
|
@ -1606,10 +1602,7 @@ xfs_attr3_leaf_figure_balance(
|
|||
*/
|
||||
if (count == blk1->index) {
|
||||
tmp = totallen + sizeof(*entry) +
|
||||
xfs_attr_leaf_newentsize(
|
||||
state->args->namelen,
|
||||
state->args->valuelen,
|
||||
state->blocksize, NULL);
|
||||
xfs_attr_leaf_newentsize(state->args, NULL);
|
||||
if (XFS_ATTR_ABS(half - tmp) > lastdelta)
|
||||
break;
|
||||
lastdelta = XFS_ATTR_ABS(half - tmp);
|
||||
|
@ -1645,10 +1638,7 @@ xfs_attr3_leaf_figure_balance(
|
|||
totallen -= count * sizeof(*entry);
|
||||
if (foundit) {
|
||||
totallen -= sizeof(*entry) +
|
||||
xfs_attr_leaf_newentsize(
|
||||
state->args->namelen,
|
||||
state->args->valuelen,
|
||||
state->blocksize, NULL);
|
||||
xfs_attr_leaf_newentsize(state->args, NULL);
|
||||
}
|
||||
|
||||
*countarg = count;
|
||||
|
@ -1700,7 +1690,7 @@ xfs_attr3_leaf_toosmall(
|
|||
bytes = xfs_attr3_leaf_hdr_size(leaf) +
|
||||
ichdr.count * sizeof(xfs_attr_leaf_entry_t) +
|
||||
ichdr.usedbytes;
|
||||
if (bytes > (state->blocksize >> 1)) {
|
||||
if (bytes > (state->args->geo->blksize >> 1)) {
|
||||
*action = 0; /* blk over 50%, don't try to join */
|
||||
return(0);
|
||||
}
|
||||
|
@ -1754,7 +1744,8 @@ xfs_attr3_leaf_toosmall(
|
|||
|
||||
xfs_attr3_leaf_hdr_from_disk(&ichdr2, bp->b_addr);
|
||||
|
||||
bytes = state->blocksize - (state->blocksize >> 2) -
|
||||
bytes = state->args->geo->blksize -
|
||||
(state->args->geo->blksize >> 2) -
|
||||
ichdr.usedbytes - ichdr2.usedbytes -
|
||||
((ichdr.count + ichdr2.count) *
|
||||
sizeof(xfs_attr_leaf_entry_t)) -
|
||||
|
@ -1805,7 +1796,6 @@ xfs_attr3_leaf_remove(
|
|||
struct xfs_attr_leafblock *leaf;
|
||||
struct xfs_attr3_icleaf_hdr ichdr;
|
||||
struct xfs_attr_leaf_entry *entry;
|
||||
struct xfs_mount *mp = args->trans->t_mountp;
|
||||
int before;
|
||||
int after;
|
||||
int smallest;
|
||||
|
@ -1819,7 +1809,7 @@ xfs_attr3_leaf_remove(
|
|||
leaf = bp->b_addr;
|
||||
xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
|
||||
|
||||
ASSERT(ichdr.count > 0 && ichdr.count < XFS_LBSIZE(mp) / 8);
|
||||
ASSERT(ichdr.count > 0 && ichdr.count < args->geo->blksize / 8);
|
||||
ASSERT(args->index >= 0 && args->index < ichdr.count);
|
||||
ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) +
|
||||
xfs_attr3_leaf_hdr_size(leaf));
|
||||
|
@ -1827,7 +1817,7 @@ xfs_attr3_leaf_remove(
|
|||
entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
|
||||
|
||||
ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
|
||||
ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp));
|
||||
ASSERT(be16_to_cpu(entry->nameidx) < args->geo->blksize);
|
||||
|
||||
/*
|
||||
* Scan through free region table:
|
||||
|
@ -1842,8 +1832,8 @@ xfs_attr3_leaf_remove(
|
|||
smallest = XFS_ATTR_LEAF_MAPSIZE - 1;
|
||||
entsize = xfs_attr_leaf_entsize(leaf, args->index);
|
||||
for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
|
||||
ASSERT(ichdr.freemap[i].base < XFS_LBSIZE(mp));
|
||||
ASSERT(ichdr.freemap[i].size < XFS_LBSIZE(mp));
|
||||
ASSERT(ichdr.freemap[i].base < args->geo->blksize);
|
||||
ASSERT(ichdr.freemap[i].size < args->geo->blksize);
|
||||
if (ichdr.freemap[i].base == tablesize) {
|
||||
ichdr.freemap[i].base -= sizeof(xfs_attr_leaf_entry_t);
|
||||
ichdr.freemap[i].size += sizeof(xfs_attr_leaf_entry_t);
|
||||
|
@ -1920,11 +1910,11 @@ xfs_attr3_leaf_remove(
|
|||
* removing the name.
|
||||
*/
|
||||
if (smallest) {
|
||||
tmp = XFS_LBSIZE(mp);
|
||||
tmp = args->geo->blksize;
|
||||
entry = xfs_attr3_leaf_entryp(leaf);
|
||||
for (i = ichdr.count - 1; i >= 0; entry++, i--) {
|
||||
ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
|
||||
ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp));
|
||||
ASSERT(be16_to_cpu(entry->nameidx) < args->geo->blksize);
|
||||
|
||||
if (be16_to_cpu(entry->nameidx) < tmp)
|
||||
tmp = be16_to_cpu(entry->nameidx);
|
||||
|
@ -1947,7 +1937,7 @@ xfs_attr3_leaf_remove(
|
|||
tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) +
|
||||
ichdr.count * sizeof(xfs_attr_leaf_entry_t);
|
||||
|
||||
return tmp < mp->m_attr_magicpct; /* leaf is < 37% full */
|
||||
return tmp < args->geo->magicpct; /* leaf is < 37% full */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1964,7 +1954,6 @@ xfs_attr3_leaf_unbalance(
|
|||
struct xfs_attr3_icleaf_hdr drophdr;
|
||||
struct xfs_attr3_icleaf_hdr savehdr;
|
||||
struct xfs_attr_leaf_entry *entry;
|
||||
struct xfs_mount *mp = state->mp;
|
||||
|
||||
trace_xfs_attr_leaf_unbalance(state->args);
|
||||
|
||||
|
@ -1991,13 +1980,15 @@ xfs_attr3_leaf_unbalance(
|
|||
*/
|
||||
if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
|
||||
drop_blk->bp, &drophdr)) {
|
||||
xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0,
|
||||
xfs_attr3_leaf_moveents(state->args,
|
||||
drop_leaf, &drophdr, 0,
|
||||
save_leaf, &savehdr, 0,
|
||||
drophdr.count, mp);
|
||||
drophdr.count);
|
||||
} else {
|
||||
xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0,
|
||||
xfs_attr3_leaf_moveents(state->args,
|
||||
drop_leaf, &drophdr, 0,
|
||||
save_leaf, &savehdr,
|
||||
savehdr.count, drophdr.count, mp);
|
||||
savehdr.count, drophdr.count);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
|
@ -2007,7 +1998,7 @@ xfs_attr3_leaf_unbalance(
|
|||
struct xfs_attr_leafblock *tmp_leaf;
|
||||
struct xfs_attr3_icleaf_hdr tmphdr;
|
||||
|
||||
tmp_leaf = kmem_zalloc(state->blocksize, KM_SLEEP);
|
||||
tmp_leaf = kmem_zalloc(state->args->geo->blksize, KM_SLEEP);
|
||||
|
||||
/*
|
||||
* Copy the header into the temp leaf so that all the stuff
|
||||
|
@ -2020,35 +2011,39 @@ xfs_attr3_leaf_unbalance(
|
|||
tmphdr.magic = savehdr.magic;
|
||||
tmphdr.forw = savehdr.forw;
|
||||
tmphdr.back = savehdr.back;
|
||||
tmphdr.firstused = state->blocksize;
|
||||
tmphdr.firstused = state->args->geo->blksize;
|
||||
|
||||
/* write the header to the temp buffer to initialise it */
|
||||
xfs_attr3_leaf_hdr_to_disk(tmp_leaf, &tmphdr);
|
||||
|
||||
if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
|
||||
drop_blk->bp, &drophdr)) {
|
||||
xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0,
|
||||
xfs_attr3_leaf_moveents(state->args,
|
||||
drop_leaf, &drophdr, 0,
|
||||
tmp_leaf, &tmphdr, 0,
|
||||
drophdr.count, mp);
|
||||
xfs_attr3_leaf_moveents(save_leaf, &savehdr, 0,
|
||||
drophdr.count);
|
||||
xfs_attr3_leaf_moveents(state->args,
|
||||
save_leaf, &savehdr, 0,
|
||||
tmp_leaf, &tmphdr, tmphdr.count,
|
||||
savehdr.count, mp);
|
||||
savehdr.count);
|
||||
} else {
|
||||
xfs_attr3_leaf_moveents(save_leaf, &savehdr, 0,
|
||||
xfs_attr3_leaf_moveents(state->args,
|
||||
save_leaf, &savehdr, 0,
|
||||
tmp_leaf, &tmphdr, 0,
|
||||
savehdr.count, mp);
|
||||
xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0,
|
||||
savehdr.count);
|
||||
xfs_attr3_leaf_moveents(state->args,
|
||||
drop_leaf, &drophdr, 0,
|
||||
tmp_leaf, &tmphdr, tmphdr.count,
|
||||
drophdr.count, mp);
|
||||
drophdr.count);
|
||||
}
|
||||
memcpy(save_leaf, tmp_leaf, state->blocksize);
|
||||
memcpy(save_leaf, tmp_leaf, state->args->geo->blksize);
|
||||
savehdr = tmphdr; /* struct copy */
|
||||
kmem_free(tmp_leaf);
|
||||
}
|
||||
|
||||
xfs_attr3_leaf_hdr_to_disk(save_leaf, &savehdr);
|
||||
xfs_trans_log_buf(state->args->trans, save_blk->bp, 0,
|
||||
state->blocksize - 1);
|
||||
state->args->geo->blksize - 1);
|
||||
|
||||
/*
|
||||
* Copy out last hashval in each block for B-tree code.
|
||||
|
@ -2094,7 +2089,7 @@ xfs_attr3_leaf_lookup_int(
|
|||
leaf = bp->b_addr;
|
||||
xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
|
||||
entries = xfs_attr3_leaf_entryp(leaf);
|
||||
ASSERT(ichdr.count < XFS_LBSIZE(args->dp->i_mount) / 8);
|
||||
ASSERT(ichdr.count < args->geo->blksize / 8);
|
||||
|
||||
/*
|
||||
* Binary search. (note: small blocks will skip this loop)
|
||||
|
@ -2198,7 +2193,7 @@ xfs_attr3_leaf_getvalue(
|
|||
|
||||
leaf = bp->b_addr;
|
||||
xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
|
||||
ASSERT(ichdr.count < XFS_LBSIZE(args->dp->i_mount) / 8);
|
||||
ASSERT(ichdr.count < args->geo->blksize / 8);
|
||||
ASSERT(args->index < ichdr.count);
|
||||
|
||||
entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
|
||||
|
@ -2249,14 +2244,14 @@ xfs_attr3_leaf_getvalue(
|
|||
/*ARGSUSED*/
|
||||
STATIC void
|
||||
xfs_attr3_leaf_moveents(
|
||||
struct xfs_da_args *args,
|
||||
struct xfs_attr_leafblock *leaf_s,
|
||||
struct xfs_attr3_icleaf_hdr *ichdr_s,
|
||||
int start_s,
|
||||
struct xfs_attr_leafblock *leaf_d,
|
||||
struct xfs_attr3_icleaf_hdr *ichdr_d,
|
||||
int start_d,
|
||||
int count,
|
||||
struct xfs_mount *mp)
|
||||
int count)
|
||||
{
|
||||
struct xfs_attr_leaf_entry *entry_s;
|
||||
struct xfs_attr_leaf_entry *entry_d;
|
||||
|
@ -2276,10 +2271,10 @@ xfs_attr3_leaf_moveents(
|
|||
ASSERT(ichdr_s->magic == XFS_ATTR_LEAF_MAGIC ||
|
||||
ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC);
|
||||
ASSERT(ichdr_s->magic == ichdr_d->magic);
|
||||
ASSERT(ichdr_s->count > 0 && ichdr_s->count < XFS_LBSIZE(mp) / 8);
|
||||
ASSERT(ichdr_s->count > 0 && ichdr_s->count < args->geo->blksize / 8);
|
||||
ASSERT(ichdr_s->firstused >= (ichdr_s->count * sizeof(*entry_s))
|
||||
+ xfs_attr3_leaf_hdr_size(leaf_s));
|
||||
ASSERT(ichdr_d->count < XFS_LBSIZE(mp) / 8);
|
||||
ASSERT(ichdr_d->count < args->geo->blksize / 8);
|
||||
ASSERT(ichdr_d->firstused >= (ichdr_d->count * sizeof(*entry_d))
|
||||
+ xfs_attr3_leaf_hdr_size(leaf_d));
|
||||
|
||||
|
@ -2331,11 +2326,11 @@ xfs_attr3_leaf_moveents(
|
|||
entry_d->nameidx = cpu_to_be16(ichdr_d->firstused);
|
||||
entry_d->flags = entry_s->flags;
|
||||
ASSERT(be16_to_cpu(entry_d->nameidx) + tmp
|
||||
<= XFS_LBSIZE(mp));
|
||||
<= args->geo->blksize);
|
||||
memmove(xfs_attr3_leaf_name(leaf_d, desti),
|
||||
xfs_attr3_leaf_name(leaf_s, start_s + i), tmp);
|
||||
ASSERT(be16_to_cpu(entry_s->nameidx) + tmp
|
||||
<= XFS_LBSIZE(mp));
|
||||
<= args->geo->blksize);
|
||||
memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp);
|
||||
ichdr_s->usedbytes -= tmp;
|
||||
ichdr_d->usedbytes += tmp;
|
||||
|
@ -2356,7 +2351,7 @@ xfs_attr3_leaf_moveents(
|
|||
tmp = count * sizeof(xfs_attr_leaf_entry_t);
|
||||
entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
|
||||
ASSERT(((char *)entry_s + tmp) <=
|
||||
((char *)leaf_s + XFS_LBSIZE(mp)));
|
||||
((char *)leaf_s + args->geo->blksize));
|
||||
memset(entry_s, 0, tmp);
|
||||
} else {
|
||||
/*
|
||||
|
@ -2371,7 +2366,7 @@ xfs_attr3_leaf_moveents(
|
|||
tmp = count * sizeof(xfs_attr_leaf_entry_t);
|
||||
entry_s = &xfs_attr3_leaf_entryp(leaf_s)[ichdr_s->count];
|
||||
ASSERT(((char *)entry_s + tmp) <=
|
||||
((char *)leaf_s + XFS_LBSIZE(mp)));
|
||||
((char *)leaf_s + args->geo->blksize));
|
||||
memset(entry_s, 0, tmp);
|
||||
}
|
||||
|
||||
|
@ -2439,22 +2434,21 @@ xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
|
|||
* a "local" or a "remote" attribute.
|
||||
*/
|
||||
int
|
||||
xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local)
|
||||
xfs_attr_leaf_newentsize(
|
||||
struct xfs_da_args *args,
|
||||
int *local)
|
||||
{
|
||||
int size;
|
||||
|
||||
size = xfs_attr_leaf_entsize_local(namelen, valuelen);
|
||||
if (size < xfs_attr_leaf_entsize_local_max(blocksize)) {
|
||||
if (local) {
|
||||
size = xfs_attr_leaf_entsize_local(args->namelen, args->valuelen);
|
||||
if (size < xfs_attr_leaf_entsize_local_max(args->geo->blksize)) {
|
||||
if (local)
|
||||
*local = 1;
|
||||
}
|
||||
} else {
|
||||
size = xfs_attr_leaf_entsize_remote(namelen);
|
||||
if (local) {
|
||||
*local = 0;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
if (local)
|
||||
*local = 0;
|
||||
return xfs_attr_leaf_entsize_remote(args->namelen);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -96,8 +96,7 @@ int xfs_attr3_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp);
|
|||
xfs_dahash_t xfs_attr_leaf_lasthash(struct xfs_buf *bp, int *count);
|
||||
int xfs_attr_leaf_order(struct xfs_buf *leaf1_bp,
|
||||
struct xfs_buf *leaf2_bp);
|
||||
int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize,
|
||||
int *local);
|
||||
int xfs_attr_leaf_newentsize(struct xfs_da_args *args, int *local);
|
||||
int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
xfs_dablk_t bno, xfs_daddr_t mappedbno,
|
||||
struct xfs_buf **bpp);
|
||||
|
|
|
@ -444,6 +444,7 @@ xfs_attr3_leaf_list_int(
|
|||
xfs_da_args_t args;
|
||||
|
||||
memset((char *)&args, 0, sizeof(args));
|
||||
args.geo = context->dp->i_mount->m_attr_geo;
|
||||
args.dp = context->dp;
|
||||
args.whichfork = XFS_ATTR_FORK;
|
||||
args.valuelen = valuelen;
|
||||
|
|
|
@ -125,6 +125,7 @@ xfs_attr3_rmt_read_verify(
|
|||
char *ptr;
|
||||
int len;
|
||||
xfs_daddr_t bno;
|
||||
int blksize = mp->m_attr_geo->blksize;
|
||||
|
||||
/* no verification of non-crc buffers */
|
||||
if (!xfs_sb_version_hascrc(&mp->m_sb))
|
||||
|
@ -133,21 +134,20 @@ xfs_attr3_rmt_read_verify(
|
|||
ptr = bp->b_addr;
|
||||
bno = bp->b_bn;
|
||||
len = BBTOB(bp->b_length);
|
||||
ASSERT(len >= XFS_LBSIZE(mp));
|
||||
ASSERT(len >= blksize);
|
||||
|
||||
while (len > 0) {
|
||||
if (!xfs_verify_cksum(ptr, XFS_LBSIZE(mp),
|
||||
XFS_ATTR3_RMT_CRC_OFF)) {
|
||||
if (!xfs_verify_cksum(ptr, blksize, XFS_ATTR3_RMT_CRC_OFF)) {
|
||||
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||
break;
|
||||
}
|
||||
if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) {
|
||||
if (!xfs_attr3_rmt_verify(mp, ptr, blksize, bno)) {
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
break;
|
||||
}
|
||||
len -= XFS_LBSIZE(mp);
|
||||
ptr += XFS_LBSIZE(mp);
|
||||
bno += mp->m_bsize;
|
||||
len -= blksize;
|
||||
ptr += blksize;
|
||||
bno += BTOBB(blksize);
|
||||
}
|
||||
|
||||
if (bp->b_error)
|
||||
|
@ -165,6 +165,7 @@ xfs_attr3_rmt_write_verify(
|
|||
char *ptr;
|
||||
int len;
|
||||
xfs_daddr_t bno;
|
||||
int blksize = mp->m_attr_geo->blksize;
|
||||
|
||||
/* no verification of non-crc buffers */
|
||||
if (!xfs_sb_version_hascrc(&mp->m_sb))
|
||||
|
@ -173,10 +174,10 @@ xfs_attr3_rmt_write_verify(
|
|||
ptr = bp->b_addr;
|
||||
bno = bp->b_bn;
|
||||
len = BBTOB(bp->b_length);
|
||||
ASSERT(len >= XFS_LBSIZE(mp));
|
||||
ASSERT(len >= blksize);
|
||||
|
||||
while (len > 0) {
|
||||
if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) {
|
||||
if (!xfs_attr3_rmt_verify(mp, ptr, blksize, bno)) {
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
|
@ -187,11 +188,11 @@ xfs_attr3_rmt_write_verify(
|
|||
rmt = (struct xfs_attr3_rmt_hdr *)ptr;
|
||||
rmt->rm_lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
||||
}
|
||||
xfs_update_cksum(ptr, XFS_LBSIZE(mp), XFS_ATTR3_RMT_CRC_OFF);
|
||||
xfs_update_cksum(ptr, blksize, XFS_ATTR3_RMT_CRC_OFF);
|
||||
|
||||
len -= XFS_LBSIZE(mp);
|
||||
ptr += XFS_LBSIZE(mp);
|
||||
bno += mp->m_bsize;
|
||||
len -= blksize;
|
||||
ptr += blksize;
|
||||
bno += BTOBB(blksize);
|
||||
}
|
||||
ASSERT(len == 0);
|
||||
}
|
||||
|
@ -240,12 +241,13 @@ xfs_attr_rmtval_copyout(
|
|||
char *src = bp->b_addr;
|
||||
xfs_daddr_t bno = bp->b_bn;
|
||||
int len = BBTOB(bp->b_length);
|
||||
int blksize = mp->m_attr_geo->blksize;
|
||||
|
||||
ASSERT(len >= XFS_LBSIZE(mp));
|
||||
ASSERT(len >= blksize);
|
||||
|
||||
while (len > 0 && *valuelen > 0) {
|
||||
int hdr_size = 0;
|
||||
int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, XFS_LBSIZE(mp));
|
||||
int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, blksize);
|
||||
|
||||
byte_cnt = min(*valuelen, byte_cnt);
|
||||
|
||||
|
@ -263,9 +265,9 @@ xfs_attr_rmtval_copyout(
|
|||
memcpy(*dst, src + hdr_size, byte_cnt);
|
||||
|
||||
/* roll buffer forwards */
|
||||
len -= XFS_LBSIZE(mp);
|
||||
src += XFS_LBSIZE(mp);
|
||||
bno += mp->m_bsize;
|
||||
len -= blksize;
|
||||
src += blksize;
|
||||
bno += BTOBB(blksize);
|
||||
|
||||
/* roll attribute data forwards */
|
||||
*valuelen -= byte_cnt;
|
||||
|
@ -287,12 +289,13 @@ xfs_attr_rmtval_copyin(
|
|||
char *dst = bp->b_addr;
|
||||
xfs_daddr_t bno = bp->b_bn;
|
||||
int len = BBTOB(bp->b_length);
|
||||
int blksize = mp->m_attr_geo->blksize;
|
||||
|
||||
ASSERT(len >= XFS_LBSIZE(mp));
|
||||
ASSERT(len >= blksize);
|
||||
|
||||
while (len > 0 && *valuelen > 0) {
|
||||
int hdr_size;
|
||||
int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, XFS_LBSIZE(mp));
|
||||
int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, blksize);
|
||||
|
||||
byte_cnt = min(*valuelen, byte_cnt);
|
||||
hdr_size = xfs_attr3_rmt_hdr_set(mp, dst, ino, *offset,
|
||||
|
@ -304,17 +307,17 @@ xfs_attr_rmtval_copyin(
|
|||
* If this is the last block, zero the remainder of it.
|
||||
* Check that we are actually the last block, too.
|
||||
*/
|
||||
if (byte_cnt + hdr_size < XFS_LBSIZE(mp)) {
|
||||
if (byte_cnt + hdr_size < blksize) {
|
||||
ASSERT(*valuelen - byte_cnt == 0);
|
||||
ASSERT(len == XFS_LBSIZE(mp));
|
||||
ASSERT(len == blksize);
|
||||
memset(dst + hdr_size + byte_cnt, 0,
|
||||
XFS_LBSIZE(mp) - hdr_size - byte_cnt);
|
||||
blksize - hdr_size - byte_cnt);
|
||||
}
|
||||
|
||||
/* roll buffer forwards */
|
||||
len -= XFS_LBSIZE(mp);
|
||||
dst += XFS_LBSIZE(mp);
|
||||
bno += mp->m_bsize;
|
||||
len -= blksize;
|
||||
dst += blksize;
|
||||
bno += BTOBB(blksize);
|
||||
|
||||
/* roll attribute data forwards */
|
||||
*valuelen -= byte_cnt;
|
||||
|
|
|
@ -1098,10 +1098,11 @@ xfs_bmap_add_attrfork_local(
|
|||
|
||||
if (S_ISDIR(ip->i_d.di_mode)) {
|
||||
memset(&dargs, 0, sizeof(dargs));
|
||||
dargs.geo = ip->i_mount->m_dir_geo;
|
||||
dargs.dp = ip;
|
||||
dargs.firstblock = firstblock;
|
||||
dargs.flist = flist;
|
||||
dargs.total = ip->i_mount->m_dirblkfsbs;
|
||||
dargs.total = dargs.geo->fsbcount;
|
||||
dargs.whichfork = XFS_DATA_FORK;
|
||||
dargs.trans = tp;
|
||||
return xfs_dir2_sf_to_block(&dargs);
|
||||
|
|
|
@ -167,8 +167,8 @@ xfs_da3_node_verify(
|
|||
* we don't know if the node is for and attribute or directory tree,
|
||||
* so only fail if the count is outside both bounds
|
||||
*/
|
||||
if (ichdr.count > mp->m_dir_node_ents &&
|
||||
ichdr.count > mp->m_attr_node_ents)
|
||||
if (ichdr.count > mp->m_dir_geo->node_ents &&
|
||||
ichdr.count > mp->m_attr_geo->node_ents)
|
||||
return false;
|
||||
|
||||
/* XXX: hash order check? */
|
||||
|
@ -598,7 +598,7 @@ xfs_da3_root_split(
|
|||
* Set up the new root node.
|
||||
*/
|
||||
error = xfs_da3_node_create(args,
|
||||
(args->whichfork == XFS_DATA_FORK) ? mp->m_dirleafblk : 0,
|
||||
(args->whichfork == XFS_DATA_FORK) ? args->geo->leafblk : 0,
|
||||
level + 1, &bp, args->whichfork);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -616,10 +616,10 @@ xfs_da3_root_split(
|
|||
#ifdef DEBUG
|
||||
if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
|
||||
oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) {
|
||||
ASSERT(blk1->blkno >= mp->m_dirleafblk &&
|
||||
blk1->blkno < mp->m_dirfreeblk);
|
||||
ASSERT(blk2->blkno >= mp->m_dirleafblk &&
|
||||
blk2->blkno < mp->m_dirfreeblk);
|
||||
ASSERT(blk1->blkno >= args->geo->leafblk &&
|
||||
blk1->blkno < args->geo->freeblk);
|
||||
ASSERT(blk2->blkno >= args->geo->leafblk &&
|
||||
blk2->blkno < args->geo->freeblk);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -663,7 +663,7 @@ xfs_da3_node_split(
|
|||
/*
|
||||
* Do we have to split the node?
|
||||
*/
|
||||
if (nodehdr.count + newcount > state->node_ents) {
|
||||
if (nodehdr.count + newcount > state->args->geo->node_ents) {
|
||||
/*
|
||||
* Allocate a new node, add to the doubly linked chain of
|
||||
* nodes, then move some of our excess entries into it.
|
||||
|
@ -894,8 +894,8 @@ xfs_da3_node_add(
|
|||
ASSERT(oldblk->index >= 0 && oldblk->index <= nodehdr.count);
|
||||
ASSERT(newblk->blkno != 0);
|
||||
if (state->args->whichfork == XFS_DATA_FORK)
|
||||
ASSERT(newblk->blkno >= state->mp->m_dirleafblk &&
|
||||
newblk->blkno < state->mp->m_dirfreeblk);
|
||||
ASSERT(newblk->blkno >= state->args->geo->leafblk &&
|
||||
newblk->blkno < state->args->geo->freeblk);
|
||||
|
||||
/*
|
||||
* We may need to make some room before we insert the new node.
|
||||
|
@ -1089,14 +1089,15 @@ xfs_da3_root_join(
|
|||
* that could occur. For dir3 blocks we also need to update the block
|
||||
* number in the buffer header.
|
||||
*/
|
||||
memcpy(root_blk->bp->b_addr, bp->b_addr, state->blocksize);
|
||||
memcpy(root_blk->bp->b_addr, bp->b_addr, args->geo->blksize);
|
||||
root_blk->bp->b_ops = bp->b_ops;
|
||||
xfs_trans_buf_copy_type(root_blk->bp, bp);
|
||||
if (oldroothdr.magic == XFS_DA3_NODE_MAGIC) {
|
||||
struct xfs_da3_blkinfo *da3 = root_blk->bp->b_addr;
|
||||
da3->blkno = cpu_to_be64(root_blk->bp->b_bn);
|
||||
}
|
||||
xfs_trans_log_buf(args->trans, root_blk->bp, 0, state->blocksize - 1);
|
||||
xfs_trans_log_buf(args->trans, root_blk->bp, 0,
|
||||
args->geo->blksize - 1);
|
||||
error = xfs_da_shrink_inode(args, child, bp);
|
||||
return(error);
|
||||
}
|
||||
|
@ -1139,7 +1140,7 @@ xfs_da3_node_toosmall(
|
|||
info = blk->bp->b_addr;
|
||||
node = (xfs_da_intnode_t *)info;
|
||||
dp->d_ops->node_hdr_from_disk(&nodehdr, node);
|
||||
if (nodehdr.count > (state->node_ents >> 1)) {
|
||||
if (nodehdr.count > (state->args->geo->node_ents >> 1)) {
|
||||
*action = 0; /* blk over 50%, don't try to join */
|
||||
return(0); /* blk over 50%, don't try to join */
|
||||
}
|
||||
|
@ -1176,8 +1177,8 @@ xfs_da3_node_toosmall(
|
|||
* We prefer coalescing with the lower numbered sibling so as
|
||||
* to shrink a directory over time.
|
||||
*/
|
||||
count = state->node_ents;
|
||||
count -= state->node_ents >> 2;
|
||||
count = state->args->geo->node_ents;
|
||||
count -= state->args->geo->node_ents >> 2;
|
||||
count -= nodehdr.count;
|
||||
|
||||
/* start with smaller blk num */
|
||||
|
@ -1472,7 +1473,7 @@ xfs_da3_node_lookup_int(
|
|||
* Descend thru the B-tree searching each level for the right
|
||||
* node to use, until the right hashval is found.
|
||||
*/
|
||||
blkno = (args->whichfork == XFS_DATA_FORK)? state->mp->m_dirleafblk : 0;
|
||||
blkno = (args->whichfork == XFS_DATA_FORK)? args->geo->leafblk : 0;
|
||||
for (blk = &state->path.blk[0], state->path.active = 1;
|
||||
state->path.active <= XFS_DA_NODE_MAXDEPTH;
|
||||
blk++, state->path.active++) {
|
||||
|
@ -2090,20 +2091,12 @@ xfs_da_grow_inode(
|
|||
xfs_dablk_t *new_blkno)
|
||||
{
|
||||
xfs_fileoff_t bno;
|
||||
int count;
|
||||
int error;
|
||||
|
||||
trace_xfs_da_grow_inode(args);
|
||||
|
||||
if (args->whichfork == XFS_DATA_FORK) {
|
||||
bno = args->dp->i_mount->m_dirleafblk;
|
||||
count = args->dp->i_mount->m_dirblkfsbs;
|
||||
} else {
|
||||
bno = 0;
|
||||
count = 1;
|
||||
}
|
||||
|
||||
error = xfs_da_grow_inode_int(args, &bno, count);
|
||||
bno = args->geo->leafblk;
|
||||
error = xfs_da_grow_inode_int(args, &bno, args->geo->fsbcount);
|
||||
if (!error)
|
||||
*new_blkno = (xfs_dablk_t)bno;
|
||||
return error;
|
||||
|
@ -2158,7 +2151,7 @@ xfs_da3_swap_lastblock(
|
|||
w = args->whichfork;
|
||||
ASSERT(w == XFS_DATA_FORK);
|
||||
mp = dp->i_mount;
|
||||
lastoff = mp->m_dirfreeblk;
|
||||
lastoff = args->geo->freeblk;
|
||||
error = xfs_bmap_last_before(tp, dp, &lastoff, w);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -2170,15 +2163,15 @@ xfs_da3_swap_lastblock(
|
|||
/*
|
||||
* Read the last block in the btree space.
|
||||
*/
|
||||
last_blkno = (xfs_dablk_t)lastoff - mp->m_dirblkfsbs;
|
||||
last_blkno = (xfs_dablk_t)lastoff - args->geo->fsbcount;
|
||||
error = xfs_da3_node_read(tp, dp, last_blkno, -1, &last_buf, w);
|
||||
if (error)
|
||||
return error;
|
||||
/*
|
||||
* Copy the last block into the dead buffer and log it.
|
||||
*/
|
||||
memcpy(dead_buf->b_addr, last_buf->b_addr, mp->m_dirblksize);
|
||||
xfs_trans_log_buf(tp, dead_buf, 0, mp->m_dirblksize - 1);
|
||||
memcpy(dead_buf->b_addr, last_buf->b_addr, args->geo->blksize);
|
||||
xfs_trans_log_buf(tp, dead_buf, 0, args->geo->blksize - 1);
|
||||
dead_info = dead_buf->b_addr;
|
||||
/*
|
||||
* Get values from the moved block.
|
||||
|
@ -2247,7 +2240,7 @@ xfs_da3_swap_lastblock(
|
|||
sizeof(sib_info->back)));
|
||||
sib_buf = NULL;
|
||||
}
|
||||
par_blkno = mp->m_dirleafblk;
|
||||
par_blkno = args->geo->leafblk;
|
||||
level = -1;
|
||||
/*
|
||||
* Walk down the tree looking for the parent of the moved block.
|
||||
|
@ -2357,10 +2350,7 @@ xfs_da_shrink_inode(
|
|||
w = args->whichfork;
|
||||
tp = args->trans;
|
||||
mp = dp->i_mount;
|
||||
if (w == XFS_DATA_FORK)
|
||||
count = mp->m_dirblkfsbs;
|
||||
else
|
||||
count = 1;
|
||||
count = args->geo->fsbcount;
|
||||
for (;;) {
|
||||
/*
|
||||
* Remove extents. If we get ENOSPC for a dir we have to move
|
||||
|
@ -2479,7 +2469,10 @@ xfs_dabuf_map(
|
|||
ASSERT(map && *map);
|
||||
ASSERT(*nmaps == 1);
|
||||
|
||||
nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1;
|
||||
if (whichfork == XFS_DATA_FORK)
|
||||
nfsb = mp->m_dir_geo->fsbcount;
|
||||
else
|
||||
nfsb = mp->m_attr_geo->fsbcount;
|
||||
|
||||
/*
|
||||
* Caller doesn't have a mapping. -2 means don't complain
|
||||
|
|
|
@ -25,6 +25,23 @@ struct xfs_trans;
|
|||
struct zone;
|
||||
struct xfs_dir_ops;
|
||||
|
||||
/*
|
||||
* Directory/attribute geometry information. There will be one of these for each
|
||||
* data fork type, and it will be passed around via the xfs_da_args. Global
|
||||
* structures will be attached to the xfs_mount.
|
||||
*/
|
||||
struct xfs_da_geometry {
|
||||
int blksize; /* da block size in bytes */
|
||||
int fsbcount; /* da block size in filesystem blocks */
|
||||
uint8_t fsblog; /* log2 of _filesystem_ block size */
|
||||
uint8_t blklog; /* log2 of da block size */
|
||||
uint node_ents; /* # of entries in a danode */
|
||||
int magicpct; /* 37% of block size in bytes */
|
||||
xfs_dablk_t datablk; /* blockno of dir data v2 */
|
||||
xfs_dablk_t leafblk; /* blockno of leaf data v2 */
|
||||
xfs_dablk_t freeblk; /* blockno of free data v2 */
|
||||
};
|
||||
|
||||
/*========================================================================
|
||||
* Btree searching and modification structure definitions.
|
||||
*========================================================================*/
|
||||
|
@ -42,6 +59,7 @@ enum xfs_dacmp {
|
|||
* Structure to ease passing around component names.
|
||||
*/
|
||||
typedef struct xfs_da_args {
|
||||
struct xfs_da_geometry *geo; /* da block geometry */
|
||||
const __uint8_t *name; /* string (maybe not NULL terminated) */
|
||||
int namelen; /* length of string (maybe no NULL) */
|
||||
__uint8_t filetype; /* filetype of inode for directories */
|
||||
|
@ -110,8 +128,6 @@ typedef struct xfs_da_state_path {
|
|||
typedef struct xfs_da_state {
|
||||
xfs_da_args_t *args; /* filename arguments */
|
||||
struct xfs_mount *mp; /* filesystem mount point */
|
||||
unsigned int blocksize; /* logical block size */
|
||||
unsigned int node_ents; /* how many entries in danode */
|
||||
xfs_da_state_path_t path; /* search/split paths */
|
||||
xfs_da_state_path_t altpath; /* alternate path for join */
|
||||
unsigned char inleaf; /* insert into 1->lf, 0->splf */
|
||||
|
|
|
@ -26,8 +26,10 @@
|
|||
#include "xfs_ag.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_da_format.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_inode.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dir2_priv.h"
|
||||
|
||||
/*
|
||||
* Shortform directory ops
|
||||
|
@ -425,9 +427,9 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
|
|||
* Directory Leaf block operations
|
||||
*/
|
||||
static int
|
||||
xfs_dir2_max_leaf_ents(struct xfs_mount *mp)
|
||||
xfs_dir2_max_leaf_ents(struct xfs_da_geometry *geo)
|
||||
{
|
||||
return (mp->m_dirblksize - sizeof(struct xfs_dir2_leaf_hdr)) /
|
||||
return (geo->blksize - sizeof(struct xfs_dir2_leaf_hdr)) /
|
||||
(uint)sizeof(struct xfs_dir2_leaf_entry);
|
||||
}
|
||||
|
||||
|
@ -438,9 +440,9 @@ xfs_dir2_leaf_ents_p(struct xfs_dir2_leaf *lp)
|
|||
}
|
||||
|
||||
static int
|
||||
xfs_dir3_max_leaf_ents(struct xfs_mount *mp)
|
||||
xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo)
|
||||
{
|
||||
return (mp->m_dirblksize - sizeof(struct xfs_dir3_leaf_hdr)) /
|
||||
return (geo->blksize - sizeof(struct xfs_dir3_leaf_hdr)) /
|
||||
(uint)sizeof(struct xfs_dir2_leaf_entry);
|
||||
}
|
||||
|
||||
|
@ -591,9 +593,9 @@ xfs_da3_node_hdr_to_disk(
|
|||
* Directory free space block operations
|
||||
*/
|
||||
static int
|
||||
xfs_dir2_free_max_bests(struct xfs_mount *mp)
|
||||
xfs_dir2_free_max_bests(struct xfs_da_geometry *geo)
|
||||
{
|
||||
return (mp->m_dirblksize - sizeof(struct xfs_dir2_free_hdr)) /
|
||||
return (geo->blksize - sizeof(struct xfs_dir2_free_hdr)) /
|
||||
sizeof(xfs_dir2_data_off_t);
|
||||
}
|
||||
|
||||
|
@ -607,24 +609,25 @@ xfs_dir2_free_bests_p(struct xfs_dir2_free *free)
|
|||
* Convert data space db to the corresponding free db.
|
||||
*/
|
||||
static xfs_dir2_db_t
|
||||
xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db)
|
||||
xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
|
||||
{
|
||||
return XFS_DIR2_FREE_FIRSTDB(mp) + db / xfs_dir2_free_max_bests(mp);
|
||||
return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
|
||||
(db / xfs_dir2_free_max_bests(geo));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert data space db to the corresponding index in a free db.
|
||||
*/
|
||||
static int
|
||||
xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db)
|
||||
xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
|
||||
{
|
||||
return db % xfs_dir2_free_max_bests(mp);
|
||||
return db % xfs_dir2_free_max_bests(geo);
|
||||
}
|
||||
|
||||
static int
|
||||
xfs_dir3_free_max_bests(struct xfs_mount *mp)
|
||||
xfs_dir3_free_max_bests(struct xfs_da_geometry *geo)
|
||||
{
|
||||
return (mp->m_dirblksize - sizeof(struct xfs_dir3_free_hdr)) /
|
||||
return (geo->blksize - sizeof(struct xfs_dir3_free_hdr)) /
|
||||
sizeof(xfs_dir2_data_off_t);
|
||||
}
|
||||
|
||||
|
@ -638,18 +641,19 @@ xfs_dir3_free_bests_p(struct xfs_dir2_free *free)
|
|||
* Convert data space db to the corresponding free db.
|
||||
*/
|
||||
static xfs_dir2_db_t
|
||||
xfs_dir3_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db)
|
||||
xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
|
||||
{
|
||||
return XFS_DIR2_FREE_FIRSTDB(mp) + db / xfs_dir3_free_max_bests(mp);
|
||||
return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
|
||||
(db / xfs_dir3_free_max_bests(geo));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert data space db to the corresponding index in a free db.
|
||||
*/
|
||||
static int
|
||||
xfs_dir3_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db)
|
||||
xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
|
||||
{
|
||||
return db % xfs_dir3_free_max_bests(mp);
|
||||
return db % xfs_dir3_free_max_bests(geo);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -19,10 +19,6 @@
|
|||
#ifndef __XFS_DA_FORMAT_H__
|
||||
#define __XFS_DA_FORMAT_H__
|
||||
|
||||
/*========================================================================
|
||||
* Directory Structure when greater than XFS_LBSIZE(mp) bytes.
|
||||
*========================================================================*/
|
||||
|
||||
/*
|
||||
* This structure is common to both leaf nodes and non-leaf nodes in the Btree.
|
||||
*
|
||||
|
@ -122,8 +118,6 @@ struct xfs_da3_icnode_hdr {
|
|||
__uint16_t level;
|
||||
};
|
||||
|
||||
#define XFS_LBSIZE(mp) (mp)->m_sb.sb_blocksize
|
||||
|
||||
/*
|
||||
* Directory version 2.
|
||||
*
|
||||
|
@ -330,8 +324,6 @@ xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr)
|
|||
#define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
|
||||
#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)
|
||||
|
||||
/*
|
||||
* Describe a free area in the data block.
|
||||
|
@ -456,8 +448,6 @@ xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused *dup)
|
|||
*/
|
||||
#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)
|
||||
|
||||
/*
|
||||
* Leaf block header.
|
||||
|
@ -513,17 +503,6 @@ struct xfs_dir3_leaf {
|
|||
|
||||
#define XFS_DIR3_LEAF_CRC_OFF offsetof(struct xfs_dir3_leaf_hdr, info.crc)
|
||||
|
||||
/*
|
||||
* Get address of the bestcount field in the single-leaf block.
|
||||
*/
|
||||
static inline struct xfs_dir2_leaf_tail *
|
||||
xfs_dir2_leaf_tail_p(struct xfs_mount *mp, struct xfs_dir2_leaf *lp)
|
||||
{
|
||||
return (struct xfs_dir2_leaf_tail *)
|
||||
((char *)lp + mp->m_dirblksize -
|
||||
sizeof(struct xfs_dir2_leaf_tail));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get address of the bests array in the single-leaf block.
|
||||
*/
|
||||
|
@ -533,123 +512,6 @@ xfs_dir2_leaf_bests_p(struct xfs_dir2_leaf_tail *ltp)
|
|||
return (__be16 *)ltp - be32_to_cpu(ltp->bestcount);
|
||||
}
|
||||
|
||||
/*
|
||||
* DB blocks here are logical directory block numbers, not filesystem blocks.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Convert dataptr to byte in file space
|
||||
*/
|
||||
static inline xfs_dir2_off_t
|
||||
xfs_dir2_dataptr_to_byte(xfs_dir2_dataptr_t dp)
|
||||
{
|
||||
return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert byte in file space to dataptr. It had better be aligned.
|
||||
*/
|
||||
static inline xfs_dir2_dataptr_t
|
||||
xfs_dir2_byte_to_dataptr(xfs_dir2_off_t by)
|
||||
{
|
||||
return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert byte in space to (DB) block
|
||||
*/
|
||||
static inline xfs_dir2_db_t
|
||||
xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by)
|
||||
{
|
||||
return (xfs_dir2_db_t)
|
||||
(by >> (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert dataptr to a block number
|
||||
*/
|
||||
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(dp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert byte in space to offset in a block
|
||||
*/
|
||||
static inline xfs_dir2_data_aoff_t
|
||||
xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by)
|
||||
{
|
||||
return (xfs_dir2_data_aoff_t)(by &
|
||||
((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) - 1));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert dataptr to a byte offset in a block
|
||||
*/
|
||||
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(dp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block and offset to byte in space
|
||||
*/
|
||||
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)
|
||||
{
|
||||
return ((xfs_dir2_off_t)db <<
|
||||
(mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) + o;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block (DB) to block (dablk)
|
||||
*/
|
||||
static inline xfs_dablk_t
|
||||
xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db)
|
||||
{
|
||||
return (xfs_dablk_t)(db << mp->m_sb.sb_dirblklog);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert byte in space to (DA) block
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block and offset to dataptr
|
||||
*/
|
||||
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(xfs_dir2_db_off_to_byte(mp, db, o));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block (dablk) to block (DB)
|
||||
*/
|
||||
static inline xfs_dir2_db_t
|
||||
xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da)
|
||||
{
|
||||
return (xfs_dir2_db_t)(da >> mp->m_sb.sb_dirblklog);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block (dablk) to byte offset in space
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free space block defintions for the node format.
|
||||
*/
|
||||
|
@ -659,8 +521,6 @@ xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da)
|
|||
*/
|
||||
#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)
|
||||
|
||||
typedef struct xfs_dir2_free_hdr {
|
||||
__be32 magic; /* XFS_DIR2_FREE_MAGIC */
|
||||
|
@ -735,16 +595,6 @@ typedef struct xfs_dir2_block_tail {
|
|||
__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)
|
||||
*/
|
||||
static inline struct xfs_dir2_block_tail *
|
||||
xfs_dir2_block_tail_p(struct xfs_mount *mp, struct xfs_dir2_data_hdr *hdr)
|
||||
{
|
||||
return ((struct xfs_dir2_block_tail *)
|
||||
((char *)hdr + mp->m_dirblksize)) - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pointer to the leaf entries embedded in a data block (1-block format)
|
||||
*/
|
||||
|
@ -764,10 +614,6 @@ xfs_dir2_block_leaf_p(struct xfs_dir2_block_tail *btp)
|
|||
* of an attribute name may not be unique, we may have duplicate keys. The
|
||||
* internal links in the Btree are logical block offsets into the file.
|
||||
*
|
||||
*========================================================================
|
||||
* Attribute structure when equal to XFS_LBSIZE(mp) bytes.
|
||||
*========================================================================
|
||||
*
|
||||
* Struct leaf_entry's are packed from the top. Name/values grow from the
|
||||
* bottom but are not packed. The freemap contains run-length-encoded entries
|
||||
* for the free bytes after the leaf_entry's, but only the N largest such,
|
||||
|
|
|
@ -85,10 +85,11 @@ static struct xfs_nameops xfs_ascii_ci_nameops = {
|
|||
.compname = xfs_ascii_ci_compname,
|
||||
};
|
||||
|
||||
void
|
||||
xfs_dir_mount(
|
||||
xfs_mount_t *mp)
|
||||
int
|
||||
xfs_da_mount(
|
||||
struct xfs_mount *mp)
|
||||
{
|
||||
struct xfs_da_geometry *dageo;
|
||||
int nodehdr_size;
|
||||
|
||||
|
||||
|
@ -99,24 +100,59 @@ xfs_dir_mount(
|
|||
mp->m_dir_inode_ops = xfs_dir_get_ops(mp, NULL);
|
||||
mp->m_nondir_inode_ops = xfs_nondir_get_ops(mp, NULL);
|
||||
|
||||
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));
|
||||
|
||||
nodehdr_size = mp->m_dir_inode_ops->node_hdr_size;
|
||||
mp->m_attr_node_ents = (mp->m_sb.sb_blocksize - nodehdr_size) /
|
||||
(uint)sizeof(xfs_da_node_entry_t);
|
||||
mp->m_dir_node_ents = (mp->m_dirblksize - nodehdr_size) /
|
||||
(uint)sizeof(xfs_da_node_entry_t);
|
||||
mp->m_dir_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
|
||||
KM_SLEEP | KM_MAYFAIL);
|
||||
mp->m_attr_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
|
||||
KM_SLEEP | KM_MAYFAIL);
|
||||
if (!mp->m_dir_geo || !mp->m_attr_geo) {
|
||||
kmem_free(mp->m_dir_geo);
|
||||
kmem_free(mp->m_attr_geo);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
/* set up directory geometry */
|
||||
dageo = mp->m_dir_geo;
|
||||
dageo->blklog = mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog;
|
||||
dageo->fsblog = mp->m_sb.sb_blocklog;
|
||||
dageo->blksize = 1 << dageo->blklog;
|
||||
dageo->fsbcount = 1 << mp->m_sb.sb_dirblklog;
|
||||
|
||||
/*
|
||||
* Now we've set up the block conversion variables, we can calculate the
|
||||
* segment block constants using the geometry structure.
|
||||
*/
|
||||
dageo->datablk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_DATA_OFFSET);
|
||||
dageo->leafblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_LEAF_OFFSET);
|
||||
dageo->freeblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_FREE_OFFSET);
|
||||
dageo->node_ents = (dageo->blksize - nodehdr_size) /
|
||||
(uint)sizeof(xfs_da_node_entry_t);
|
||||
dageo->magicpct = (dageo->blksize * 37) / 100;
|
||||
|
||||
/* set up attribute geometry - single fsb only */
|
||||
dageo = mp->m_attr_geo;
|
||||
dageo->blklog = mp->m_sb.sb_blocklog;
|
||||
dageo->fsblog = mp->m_sb.sb_blocklog;
|
||||
dageo->blksize = 1 << dageo->blklog;
|
||||
dageo->fsbcount = 1;
|
||||
dageo->node_ents = (dageo->blksize - nodehdr_size) /
|
||||
(uint)sizeof(xfs_da_node_entry_t);
|
||||
dageo->magicpct = (dageo->blksize * 37) / 100;
|
||||
|
||||
mp->m_dir_magicpct = (mp->m_dirblksize * 37) / 100;
|
||||
if (xfs_sb_version_hasasciici(&mp->m_sb))
|
||||
mp->m_dirnameops = &xfs_ascii_ci_nameops;
|
||||
else
|
||||
mp->m_dirnameops = &xfs_default_nameops;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
xfs_da_unmount(
|
||||
struct xfs_mount *mp)
|
||||
{
|
||||
kmem_free(mp->m_dir_geo);
|
||||
kmem_free(mp->m_attr_geo);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -192,6 +228,7 @@ xfs_dir_init(
|
|||
if (!args)
|
||||
return ENOMEM;
|
||||
|
||||
args->geo = dp->i_mount->m_dir_geo;
|
||||
args->dp = dp;
|
||||
args->trans = tp;
|
||||
error = xfs_dir2_sf_create(args, pdp->i_ino);
|
||||
|
@ -226,6 +263,7 @@ xfs_dir_createname(
|
|||
if (!args)
|
||||
return ENOMEM;
|
||||
|
||||
args->geo = dp->i_mount->m_dir_geo;
|
||||
args->name = name->name;
|
||||
args->namelen = name->len;
|
||||
args->filetype = name->type;
|
||||
|
@ -244,7 +282,7 @@ xfs_dir_createname(
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
rval = xfs_dir2_isblock(dp, &v);
|
||||
rval = xfs_dir2_isblock(args, &v);
|
||||
if (rval)
|
||||
goto out_free;
|
||||
if (v) {
|
||||
|
@ -252,7 +290,7 @@ xfs_dir_createname(
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
rval = xfs_dir2_isleaf(dp, &v);
|
||||
rval = xfs_dir2_isleaf(args, &v);
|
||||
if (rval)
|
||||
goto out_free;
|
||||
if (v)
|
||||
|
@ -320,6 +358,7 @@ xfs_dir_lookup(
|
|||
* annotations into the reclaim path for the ilock.
|
||||
*/
|
||||
args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
|
||||
args->geo = dp->i_mount->m_dir_geo;
|
||||
args->name = name->name;
|
||||
args->namelen = name->len;
|
||||
args->filetype = name->type;
|
||||
|
@ -336,7 +375,7 @@ xfs_dir_lookup(
|
|||
goto out_check_rval;
|
||||
}
|
||||
|
||||
rval = xfs_dir2_isblock(dp, &v);
|
||||
rval = xfs_dir2_isblock(args, &v);
|
||||
if (rval)
|
||||
goto out_free;
|
||||
if (v) {
|
||||
|
@ -344,7 +383,7 @@ xfs_dir_lookup(
|
|||
goto out_check_rval;
|
||||
}
|
||||
|
||||
rval = xfs_dir2_isleaf(dp, &v);
|
||||
rval = xfs_dir2_isleaf(args, &v);
|
||||
if (rval)
|
||||
goto out_free;
|
||||
if (v)
|
||||
|
@ -391,6 +430,7 @@ xfs_dir_removename(
|
|||
if (!args)
|
||||
return ENOMEM;
|
||||
|
||||
args->geo = dp->i_mount->m_dir_geo;
|
||||
args->name = name->name;
|
||||
args->namelen = name->len;
|
||||
args->filetype = name->type;
|
||||
|
@ -408,7 +448,7 @@ xfs_dir_removename(
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
rval = xfs_dir2_isblock(dp, &v);
|
||||
rval = xfs_dir2_isblock(args, &v);
|
||||
if (rval)
|
||||
goto out_free;
|
||||
if (v) {
|
||||
|
@ -416,7 +456,7 @@ xfs_dir_removename(
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
rval = xfs_dir2_isleaf(dp, &v);
|
||||
rval = xfs_dir2_isleaf(args, &v);
|
||||
if (rval)
|
||||
goto out_free;
|
||||
if (v)
|
||||
|
@ -455,6 +495,7 @@ xfs_dir_replace(
|
|||
if (!args)
|
||||
return ENOMEM;
|
||||
|
||||
args->geo = dp->i_mount->m_dir_geo;
|
||||
args->name = name->name;
|
||||
args->namelen = name->len;
|
||||
args->filetype = name->type;
|
||||
|
@ -472,7 +513,7 @@ xfs_dir_replace(
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
rval = xfs_dir2_isblock(dp, &v);
|
||||
rval = xfs_dir2_isblock(args, &v);
|
||||
if (rval)
|
||||
goto out_free;
|
||||
if (v) {
|
||||
|
@ -480,7 +521,7 @@ xfs_dir_replace(
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
rval = xfs_dir2_isleaf(dp, &v);
|
||||
rval = xfs_dir2_isleaf(args, &v);
|
||||
if (rval)
|
||||
goto out_free;
|
||||
if (v)
|
||||
|
@ -516,6 +557,7 @@ xfs_dir_canenter(
|
|||
if (!args)
|
||||
return ENOMEM;
|
||||
|
||||
args->geo = dp->i_mount->m_dir_geo;
|
||||
args->name = name->name;
|
||||
args->namelen = name->len;
|
||||
args->filetype = name->type;
|
||||
|
@ -531,7 +573,7 @@ xfs_dir_canenter(
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
rval = xfs_dir2_isblock(dp, &v);
|
||||
rval = xfs_dir2_isblock(args, &v);
|
||||
if (rval)
|
||||
goto out_free;
|
||||
if (v) {
|
||||
|
@ -539,7 +581,7 @@ xfs_dir_canenter(
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
rval = xfs_dir2_isleaf(dp, &v);
|
||||
rval = xfs_dir2_isleaf(args, &v);
|
||||
if (rval)
|
||||
goto out_free;
|
||||
if (v)
|
||||
|
@ -579,13 +621,13 @@ xfs_dir2_grow_inode(
|
|||
* Set lowest possible block in the space requested.
|
||||
*/
|
||||
bno = XFS_B_TO_FSBT(mp, space * XFS_DIR2_SPACE_SIZE);
|
||||
count = mp->m_dirblkfsbs;
|
||||
count = args->geo->fsbcount;
|
||||
|
||||
error = xfs_da_grow_inode_int(args, &bno, count);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
*dbp = xfs_dir2_da_to_db(mp, (xfs_dablk_t)bno);
|
||||
*dbp = xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)bno);
|
||||
|
||||
/*
|
||||
* Update file's size if this is the data space and it grew.
|
||||
|
@ -607,18 +649,16 @@ xfs_dir2_grow_inode(
|
|||
*/
|
||||
int
|
||||
xfs_dir2_isblock(
|
||||
xfs_inode_t *dp,
|
||||
struct xfs_da_args *args,
|
||||
int *vp) /* out: 1 is block, 0 is not block */
|
||||
{
|
||||
xfs_fileoff_t last; /* last file offset */
|
||||
xfs_mount_t *mp;
|
||||
int rval;
|
||||
|
||||
mp = dp->i_mount;
|
||||
if ((rval = xfs_bmap_last_offset(dp, &last, XFS_DATA_FORK)))
|
||||
if ((rval = xfs_bmap_last_offset(args->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);
|
||||
rval = XFS_FSB_TO_B(args->dp->i_mount, last) == args->geo->blksize;
|
||||
ASSERT(rval == 0 || args->dp->i_d.di_size == args->geo->blksize);
|
||||
*vp = rval;
|
||||
return 0;
|
||||
}
|
||||
|
@ -628,17 +668,15 @@ xfs_dir2_isblock(
|
|||
*/
|
||||
int
|
||||
xfs_dir2_isleaf(
|
||||
xfs_inode_t *dp,
|
||||
int *vp) /* out: 1 is leaf, 0 is not leaf */
|
||||
struct xfs_da_args *args,
|
||||
int *vp) /* out: 1 is block, 0 is not block */
|
||||
{
|
||||
xfs_fileoff_t last; /* last file offset */
|
||||
xfs_mount_t *mp;
|
||||
int rval;
|
||||
|
||||
mp = dp->i_mount;
|
||||
if ((rval = xfs_bmap_last_offset(dp, &last, XFS_DATA_FORK)))
|
||||
if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK)))
|
||||
return rval;
|
||||
*vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog);
|
||||
*vp = last == args->geo->leafblk + args->geo->fsbcount;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -666,11 +704,11 @@ xfs_dir2_shrink_inode(
|
|||
dp = args->dp;
|
||||
mp = dp->i_mount;
|
||||
tp = args->trans;
|
||||
da = xfs_dir2_db_to_da(mp, db);
|
||||
da = xfs_dir2_db_to_da(args->geo, db);
|
||||
/*
|
||||
* Unmap the fsblock(s).
|
||||
*/
|
||||
if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs,
|
||||
if ((error = xfs_bunmapi(tp, dp, da, args->geo->fsbcount,
|
||||
XFS_BMAPI_METADATA, 0, args->firstblock, args->flist,
|
||||
&done))) {
|
||||
/*
|
||||
|
@ -697,12 +735,12 @@ xfs_dir2_shrink_inode(
|
|||
/*
|
||||
* If it's not a data block, we're done.
|
||||
*/
|
||||
if (db >= XFS_DIR2_LEAF_FIRSTDB(mp))
|
||||
if (db >= xfs_dir2_byte_to_db(args->geo, XFS_DIR2_LEAF_OFFSET))
|
||||
return 0;
|
||||
/*
|
||||
* 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(args->geo, db + 1, 0))
|
||||
return 0;
|
||||
bno = da;
|
||||
if ((error = xfs_bmap_last_before(tp, dp, &bno, XFS_DATA_FORK))) {
|
||||
|
@ -711,7 +749,7 @@ xfs_dir2_shrink_inode(
|
|||
*/
|
||||
return error;
|
||||
}
|
||||
if (db == mp->m_dirdatablk)
|
||||
if (db == args->geo->datablk)
|
||||
ASSERT(bno == 0);
|
||||
else
|
||||
ASSERT(bno > 0);
|
||||
|
|
|
@ -80,7 +80,7 @@ struct xfs_dir_ops {
|
|||
struct xfs_dir3_icleaf_hdr *from);
|
||||
void (*leaf_hdr_from_disk)(struct xfs_dir3_icleaf_hdr *to,
|
||||
struct xfs_dir2_leaf *from);
|
||||
int (*leaf_max_ents)(struct xfs_mount *mp);
|
||||
int (*leaf_max_ents)(struct xfs_da_geometry *geo);
|
||||
struct xfs_dir2_leaf_entry *
|
||||
(*leaf_ents_p)(struct xfs_dir2_leaf *lp);
|
||||
|
||||
|
@ -97,10 +97,12 @@ struct xfs_dir_ops {
|
|||
struct xfs_dir3_icfree_hdr *from);
|
||||
void (*free_hdr_from_disk)(struct xfs_dir3_icfree_hdr *to,
|
||||
struct xfs_dir2_free *from);
|
||||
int (*free_max_bests)(struct xfs_mount *mp);
|
||||
int (*free_max_bests)(struct xfs_da_geometry *geo);
|
||||
__be16 * (*free_bests_p)(struct xfs_dir2_free *free);
|
||||
xfs_dir2_db_t (*db_to_fdb)(struct xfs_mount *mp, xfs_dir2_db_t db);
|
||||
int (*db_to_fdindex)(struct xfs_mount *mp, xfs_dir2_db_t db);
|
||||
xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo,
|
||||
xfs_dir2_db_t db);
|
||||
int (*db_to_fdindex)(struct xfs_da_geometry *geo,
|
||||
xfs_dir2_db_t db);
|
||||
};
|
||||
|
||||
extern const struct xfs_dir_ops *
|
||||
|
@ -112,7 +114,9 @@ extern const struct xfs_dir_ops *
|
|||
* Generic directory interface routines
|
||||
*/
|
||||
extern void xfs_dir_startup(void);
|
||||
extern void xfs_dir_mount(struct xfs_mount *mp);
|
||||
extern int xfs_da_mount(struct xfs_mount *mp);
|
||||
extern void xfs_da_unmount(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);
|
||||
|
@ -142,23 +146,23 @@ extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
|
|||
/*
|
||||
* Interface routines used by userspace utilities
|
||||
*/
|
||||
extern int xfs_dir2_isblock(struct xfs_inode *dp, int *r);
|
||||
extern int xfs_dir2_isleaf(struct xfs_inode *dp, int *r);
|
||||
extern int xfs_dir2_isblock(struct xfs_da_args *args, int *r);
|
||||
extern int xfs_dir2_isleaf(struct xfs_da_args *args, int *r);
|
||||
extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
|
||||
struct xfs_buf *bp);
|
||||
|
||||
extern void xfs_dir2_data_freescan(struct xfs_inode *dp,
|
||||
struct xfs_dir2_data_hdr *hdr, int *loghead);
|
||||
extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
extern void xfs_dir2_data_log_entry(struct xfs_da_args *args,
|
||||
struct xfs_buf *bp, struct xfs_dir2_data_entry *dep);
|
||||
extern void xfs_dir2_data_log_header(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
extern void xfs_dir2_data_log_header(struct xfs_da_args *args,
|
||||
struct xfs_buf *bp);
|
||||
extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_buf *bp,
|
||||
struct xfs_dir2_data_unused *dup);
|
||||
extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
extern void xfs_dir2_data_log_unused(struct xfs_da_args *args,
|
||||
struct xfs_buf *bp, struct xfs_dir2_data_unused *dup);
|
||||
extern void xfs_dir2_data_make_free(struct xfs_da_args *args,
|
||||
struct xfs_buf *bp, xfs_dir2_data_aoff_t offset,
|
||||
xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);
|
||||
extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
extern void xfs_dir2_data_use_free(struct xfs_da_args *args,
|
||||
struct xfs_buf *bp, struct xfs_dir2_data_unused *dup,
|
||||
xfs_dir2_data_aoff_t offset, xfs_dir2_data_aoff_t len,
|
||||
int *needlogp, int *needscanp);
|
||||
|
|
|
@ -136,7 +136,7 @@ xfs_dir3_block_read(
|
|||
struct xfs_mount *mp = dp->i_mount;
|
||||
int err;
|
||||
|
||||
err = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, bpp,
|
||||
err = xfs_da_read_buf(tp, dp, mp->m_dir_geo->datablk, -1, bpp,
|
||||
XFS_DATA_FORK, &xfs_dir3_block_buf_ops);
|
||||
if (!err && tp)
|
||||
xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_BLOCK_BUF);
|
||||
|
@ -281,8 +281,7 @@ out:
|
|||
*/
|
||||
static void
|
||||
xfs_dir2_block_compact(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
struct xfs_da_args *args,
|
||||
struct xfs_buf *bp,
|
||||
struct xfs_dir2_data_hdr *hdr,
|
||||
struct xfs_dir2_block_tail *btp,
|
||||
|
@ -315,7 +314,7 @@ xfs_dir2_block_compact(
|
|||
*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, dp, bp,
|
||||
xfs_dir2_data_make_free(args, bp,
|
||||
(xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr),
|
||||
(xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)),
|
||||
needlog, &needscan);
|
||||
|
@ -325,7 +324,7 @@ xfs_dir2_block_compact(
|
|||
* This needs to happen before the next call to use_free.
|
||||
*/
|
||||
if (needscan)
|
||||
xfs_dir2_data_freescan(dp, hdr, needlog);
|
||||
xfs_dir2_data_freescan(args->dp, hdr, needlog);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -377,7 +376,7 @@ xfs_dir2_block_addname(
|
|||
* Set up pointers to parts of the block.
|
||||
*/
|
||||
hdr = bp->b_addr;
|
||||
btp = xfs_dir2_block_tail_p(mp, hdr);
|
||||
btp = xfs_dir2_block_tail_p(args->geo, hdr);
|
||||
blp = xfs_dir2_block_leaf_p(btp);
|
||||
|
||||
/*
|
||||
|
@ -420,7 +419,7 @@ xfs_dir2_block_addname(
|
|||
* If need to compact the leaf entries, do it now.
|
||||
*/
|
||||
if (compact) {
|
||||
xfs_dir2_block_compact(tp, dp, bp, hdr, btp, blp, &needlog,
|
||||
xfs_dir2_block_compact(args, bp, hdr, btp, blp, &needlog,
|
||||
&lfloghigh, &lfloglow);
|
||||
/* recalculate blp post-compaction */
|
||||
blp = xfs_dir2_block_leaf_p(btp);
|
||||
|
@ -455,7 +454,7 @@ xfs_dir2_block_addname(
|
|||
/*
|
||||
* Mark the space needed for the new leaf entry, now in use.
|
||||
*/
|
||||
xfs_dir2_data_use_free(tp, dp, bp, enddup,
|
||||
xfs_dir2_data_use_free(args, bp, enddup,
|
||||
(xfs_dir2_data_aoff_t)
|
||||
((char *)enddup - (char *)hdr + be16_to_cpu(enddup->length) -
|
||||
sizeof(*blp)),
|
||||
|
@ -542,7 +541,7 @@ xfs_dir2_block_addname(
|
|||
/*
|
||||
* Mark space for the data entry used.
|
||||
*/
|
||||
xfs_dir2_data_use_free(tp, dp, bp, dup,
|
||||
xfs_dir2_data_use_free(args, bp, dup,
|
||||
(xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr),
|
||||
(xfs_dir2_data_aoff_t)len, &needlog, &needscan);
|
||||
/*
|
||||
|
@ -560,9 +559,9 @@ xfs_dir2_block_addname(
|
|||
if (needscan)
|
||||
xfs_dir2_data_freescan(dp, hdr, &needlog);
|
||||
if (needlog)
|
||||
xfs_dir2_data_log_header(tp, dp, bp);
|
||||
xfs_dir2_data_log_header(args, bp);
|
||||
xfs_dir2_block_log_tail(tp, bp);
|
||||
xfs_dir2_data_log_entry(tp, dp, bp, dep);
|
||||
xfs_dir2_data_log_entry(args, bp, dep);
|
||||
xfs_dir3_data_check(dp, bp);
|
||||
return 0;
|
||||
}
|
||||
|
@ -581,7 +580,7 @@ xfs_dir2_block_log_leaf(
|
|||
xfs_dir2_leaf_entry_t *blp;
|
||||
xfs_dir2_block_tail_t *btp;
|
||||
|
||||
btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr);
|
||||
btp = xfs_dir2_block_tail_p(tp->t_mountp->m_dir_geo, hdr);
|
||||
blp = xfs_dir2_block_leaf_p(btp);
|
||||
xfs_trans_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)hdr),
|
||||
(uint)((char *)&blp[last + 1] - (char *)hdr - 1));
|
||||
|
@ -598,7 +597,7 @@ xfs_dir2_block_log_tail(
|
|||
xfs_dir2_data_hdr_t *hdr = bp->b_addr;
|
||||
xfs_dir2_block_tail_t *btp;
|
||||
|
||||
btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr);
|
||||
btp = xfs_dir2_block_tail_p(tp->t_mountp->m_dir_geo, hdr);
|
||||
xfs_trans_log_buf(tp, bp, (uint)((char *)btp - (char *)hdr),
|
||||
(uint)((char *)(btp + 1) - (char *)hdr - 1));
|
||||
}
|
||||
|
@ -633,13 +632,14 @@ xfs_dir2_block_lookup(
|
|||
mp = dp->i_mount;
|
||||
hdr = bp->b_addr;
|
||||
xfs_dir3_data_check(dp, bp);
|
||||
btp = xfs_dir2_block_tail_p(mp, hdr);
|
||||
btp = xfs_dir2_block_tail_p(args->geo, hdr);
|
||||
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 *)hdr +
|
||||
xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address)));
|
||||
xfs_dir2_dataptr_to_off(args->geo,
|
||||
be32_to_cpu(blp[ent].address)));
|
||||
/*
|
||||
* Fill in inode number, CI name if appropriate, release the block.
|
||||
*/
|
||||
|
@ -685,7 +685,7 @@ xfs_dir2_block_lookup_int(
|
|||
|
||||
hdr = bp->b_addr;
|
||||
xfs_dir3_data_check(dp, bp);
|
||||
btp = xfs_dir2_block_tail_p(mp, hdr);
|
||||
btp = xfs_dir2_block_tail_p(args->geo, hdr);
|
||||
blp = xfs_dir2_block_leaf_p(btp);
|
||||
/*
|
||||
* Loop doing a binary search for our hash value.
|
||||
|
@ -723,7 +723,7 @@ xfs_dir2_block_lookup_int(
|
|||
* Get pointer to the entry from the leaf.
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)hdr + xfs_dir2_dataptr_to_off(mp, addr));
|
||||
((char *)hdr + xfs_dir2_dataptr_to_off(args->geo, addr));
|
||||
/*
|
||||
* Compare name and if it's an exact match, return the index
|
||||
* and buffer. If it's the first case-insensitive match, store
|
||||
|
@ -790,18 +790,19 @@ xfs_dir2_block_removename(
|
|||
tp = args->trans;
|
||||
mp = dp->i_mount;
|
||||
hdr = bp->b_addr;
|
||||
btp = xfs_dir2_block_tail_p(mp, hdr);
|
||||
btp = xfs_dir2_block_tail_p(args->geo, hdr);
|
||||
blp = xfs_dir2_block_leaf_p(btp);
|
||||
/*
|
||||
* Point to the data entry using the leaf entry.
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address)));
|
||||
dep = (xfs_dir2_data_entry_t *)((char *)hdr +
|
||||
xfs_dir2_dataptr_to_off(args->geo,
|
||||
be32_to_cpu(blp[ent].address)));
|
||||
/*
|
||||
* Mark the data entry's space free.
|
||||
*/
|
||||
needlog = needscan = 0;
|
||||
xfs_dir2_data_make_free(tp, dp, bp,
|
||||
xfs_dir2_data_make_free(args, bp,
|
||||
(xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
|
||||
dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
|
||||
/*
|
||||
|
@ -820,7 +821,7 @@ xfs_dir2_block_removename(
|
|||
if (needscan)
|
||||
xfs_dir2_data_freescan(dp, hdr, &needlog);
|
||||
if (needlog)
|
||||
xfs_dir2_data_log_header(tp, dp, bp);
|
||||
xfs_dir2_data_log_header(args, bp);
|
||||
xfs_dir3_data_check(dp, bp);
|
||||
/*
|
||||
* See if the size as a shortform is good enough.
|
||||
|
@ -865,20 +866,21 @@ xfs_dir2_block_replace(
|
|||
dp = args->dp;
|
||||
mp = dp->i_mount;
|
||||
hdr = bp->b_addr;
|
||||
btp = xfs_dir2_block_tail_p(mp, hdr);
|
||||
btp = xfs_dir2_block_tail_p(args->geo, hdr);
|
||||
blp = xfs_dir2_block_leaf_p(btp);
|
||||
/*
|
||||
* Point to the data entry we need to change.
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address)));
|
||||
dep = (xfs_dir2_data_entry_t *)((char *)hdr +
|
||||
xfs_dir2_dataptr_to_off(args->geo,
|
||||
be32_to_cpu(blp[ent].address)));
|
||||
ASSERT(be64_to_cpu(dep->inumber) != args->inumber);
|
||||
/*
|
||||
* Change the inode number to the new value.
|
||||
*/
|
||||
dep->inumber = cpu_to_be64(args->inumber);
|
||||
dp->d_ops->data_put_ftype(dep, args->filetype);
|
||||
xfs_dir2_data_log_entry(args->trans, dp, bp, dep);
|
||||
xfs_dir2_data_log_entry(args, bp, dep);
|
||||
xfs_dir3_data_check(dp, bp);
|
||||
return 0;
|
||||
}
|
||||
|
@ -938,7 +940,7 @@ xfs_dir2_leaf_to_block(
|
|||
leaf = lbp->b_addr;
|
||||
dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
ents = dp->d_ops->leaf_ents_p(leaf);
|
||||
ltp = xfs_dir2_leaf_tail_p(mp, leaf);
|
||||
ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
|
||||
|
||||
ASSERT(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC ||
|
||||
leafhdr.magic == XFS_DIR3_LEAF1_MAGIC);
|
||||
|
@ -948,13 +950,13 @@ xfs_dir2_leaf_to_block(
|
|||
* been left behind during no-space-reservation operations.
|
||||
* These will show up in the leaf bests table.
|
||||
*/
|
||||
while (dp->i_d.di_size > mp->m_dirblksize) {
|
||||
while (dp->i_d.di_size > args->geo->blksize) {
|
||||
int hdrsz;
|
||||
|
||||
hdrsz = dp->d_ops->data_entry_offset;
|
||||
bestsp = xfs_dir2_leaf_bests_p(ltp);
|
||||
if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) ==
|
||||
mp->m_dirblksize - hdrsz) {
|
||||
args->geo->blksize - hdrsz) {
|
||||
if ((error =
|
||||
xfs_dir2_leaf_trim_data(args, lbp,
|
||||
(xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1))))
|
||||
|
@ -966,7 +968,7 @@ xfs_dir2_leaf_to_block(
|
|||
* Read the data block if we don't already have it, give up if it fails.
|
||||
*/
|
||||
if (!dbp) {
|
||||
error = xfs_dir3_data_read(tp, dp, mp->m_dirdatablk, -1, &dbp);
|
||||
error = xfs_dir3_data_read(tp, dp, args->geo->datablk, -1, &dbp);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
@ -982,7 +984,7 @@ xfs_dir2_leaf_to_block(
|
|||
/*
|
||||
* Look at the last data entry.
|
||||
*/
|
||||
tagp = (__be16 *)((char *)hdr + mp->m_dirblksize) - 1;
|
||||
tagp = (__be16 *)((char *)hdr + args->geo->blksize) - 1;
|
||||
dup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp));
|
||||
/*
|
||||
* If it's not free or is too short we can't do it.
|
||||
|
@ -1001,12 +1003,12 @@ xfs_dir2_leaf_to_block(
|
|||
/*
|
||||
* Use up the space at the end of the block (blp/btp).
|
||||
*/
|
||||
xfs_dir2_data_use_free(tp, dp, dbp, dup, mp->m_dirblksize - size, size,
|
||||
xfs_dir2_data_use_free(args, dbp, dup, args->geo->blksize - size, size,
|
||||
&needlog, &needscan);
|
||||
/*
|
||||
* Initialize the block tail.
|
||||
*/
|
||||
btp = xfs_dir2_block_tail_p(mp, hdr);
|
||||
btp = xfs_dir2_block_tail_p(args->geo, hdr);
|
||||
btp->count = cpu_to_be32(leafhdr.count - leafhdr.stale);
|
||||
btp->stale = 0;
|
||||
xfs_dir2_block_log_tail(tp, dbp);
|
||||
|
@ -1027,11 +1029,11 @@ xfs_dir2_leaf_to_block(
|
|||
if (needscan)
|
||||
xfs_dir2_data_freescan(dp, hdr, &needlog);
|
||||
if (needlog)
|
||||
xfs_dir2_data_log_header(tp, dp, dbp);
|
||||
xfs_dir2_data_log_header(args, dbp);
|
||||
/*
|
||||
* Pitch the old leaf block.
|
||||
*/
|
||||
error = xfs_da_shrink_inode(args, mp->m_dirleafblk, lbp);
|
||||
error = xfs_da_shrink_inode(args, args->geo->leafblk, lbp);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -1140,13 +1142,13 @@ xfs_dir2_sf_to_block(
|
|||
*/
|
||||
dup = dp->d_ops->data_unused_p(hdr);
|
||||
needlog = needscan = 0;
|
||||
xfs_dir2_data_use_free(tp, dp, bp, dup, mp->m_dirblksize - i, i, &needlog,
|
||||
&needscan);
|
||||
xfs_dir2_data_use_free(args, bp, dup, args->geo->blksize - i,
|
||||
i, &needlog, &needscan);
|
||||
ASSERT(needscan == 0);
|
||||
/*
|
||||
* Fill in the tail.
|
||||
*/
|
||||
btp = xfs_dir2_block_tail_p(mp, hdr);
|
||||
btp = xfs_dir2_block_tail_p(args->geo, hdr);
|
||||
btp->count = cpu_to_be32(sfp->count + 2); /* ., .. */
|
||||
btp->stale = 0;
|
||||
blp = xfs_dir2_block_leaf_p(btp);
|
||||
|
@ -1154,7 +1156,7 @@ xfs_dir2_sf_to_block(
|
|||
/*
|
||||
* Remove the freespace, we'll manage it.
|
||||
*/
|
||||
xfs_dir2_data_use_free(tp, dp, bp, dup,
|
||||
xfs_dir2_data_use_free(args, bp, dup,
|
||||
(xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr),
|
||||
be16_to_cpu(dup->length), &needlog, &needscan);
|
||||
/*
|
||||
|
@ -1167,7 +1169,7 @@ xfs_dir2_sf_to_block(
|
|||
dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
|
||||
tagp = dp->d_ops->data_entry_tag_p(dep);
|
||||
*tagp = cpu_to_be16((char *)dep - (char *)hdr);
|
||||
xfs_dir2_data_log_entry(tp, dp, bp, dep);
|
||||
xfs_dir2_data_log_entry(args, bp, dep);
|
||||
blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot);
|
||||
blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(
|
||||
(char *)dep - (char *)hdr));
|
||||
|
@ -1181,7 +1183,7 @@ xfs_dir2_sf_to_block(
|
|||
dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
|
||||
tagp = dp->d_ops->data_entry_tag_p(dep);
|
||||
*tagp = cpu_to_be16((char *)dep - (char *)hdr);
|
||||
xfs_dir2_data_log_entry(tp, dp, bp, dep);
|
||||
xfs_dir2_data_log_entry(args, bp, dep);
|
||||
blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
|
||||
blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(
|
||||
(char *)dep - (char *)hdr));
|
||||
|
@ -1215,7 +1217,7 @@ xfs_dir2_sf_to_block(
|
|||
dup->length = cpu_to_be16(newoffset - offset);
|
||||
*xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16(
|
||||
((char *)dup - (char *)hdr));
|
||||
xfs_dir2_data_log_unused(tp, bp, dup);
|
||||
xfs_dir2_data_log_unused(args, bp, dup);
|
||||
xfs_dir2_data_freeinsert(hdr,
|
||||
dp->d_ops->data_bestfree_p(hdr),
|
||||
dup, &dummy);
|
||||
|
@ -1232,7 +1234,7 @@ xfs_dir2_sf_to_block(
|
|||
memcpy(dep->name, sfep->name, dep->namelen);
|
||||
tagp = dp->d_ops->data_entry_tag_p(dep);
|
||||
*tagp = cpu_to_be16((char *)dep - (char *)hdr);
|
||||
xfs_dir2_data_log_entry(tp, dp, bp, dep);
|
||||
xfs_dir2_data_log_entry(args, bp, dep);
|
||||
name.name = sfep->name;
|
||||
name.len = sfep->namelen;
|
||||
blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops->
|
||||
|
|
|
@ -63,8 +63,10 @@ __xfs_dir3_data_check(
|
|||
int stale; /* count of stale leaves */
|
||||
struct xfs_name name;
|
||||
const struct xfs_dir_ops *ops;
|
||||
struct xfs_da_geometry *geo;
|
||||
|
||||
mp = bp->b_target->bt_mount;
|
||||
geo = mp->m_dir_geo;
|
||||
|
||||
/*
|
||||
* We can be passed a null dp here from a verifier, so we need to go the
|
||||
|
@ -78,7 +80,7 @@ __xfs_dir3_data_check(
|
|||
switch (hdr->magic) {
|
||||
case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
|
||||
case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
|
||||
btp = xfs_dir2_block_tail_p(mp, hdr);
|
||||
btp = xfs_dir2_block_tail_p(geo, hdr);
|
||||
lep = xfs_dir2_block_leaf_p(btp);
|
||||
endp = (char *)lep;
|
||||
|
||||
|
@ -94,7 +96,7 @@ __xfs_dir3_data_check(
|
|||
break;
|
||||
case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
|
||||
case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
|
||||
endp = (char *)hdr + mp->m_dirblksize;
|
||||
endp = (char *)hdr + geo->blksize;
|
||||
break;
|
||||
default:
|
||||
XFS_ERROR_REPORT("Bad Magic", XFS_ERRLEVEL_LOW, mp);
|
||||
|
@ -172,7 +174,7 @@ __xfs_dir3_data_check(
|
|||
lastfree = 0;
|
||||
if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
|
||||
hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
|
||||
addr = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
|
||||
addr = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
|
||||
(xfs_dir2_data_aoff_t)
|
||||
((char *)dep - (char *)hdr));
|
||||
name.name = dep->name;
|
||||
|
@ -509,6 +511,7 @@ xfs_dir2_data_freescan(
|
|||
struct xfs_dir2_data_free *bf;
|
||||
char *endp; /* end of block's data */
|
||||
char *p; /* current entry pointer */
|
||||
struct xfs_da_geometry *geo = dp->i_mount->m_dir_geo;
|
||||
|
||||
ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
|
||||
hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
|
||||
|
@ -527,10 +530,10 @@ xfs_dir2_data_freescan(
|
|||
p = (char *)dp->d_ops->data_entry_p(hdr);
|
||||
if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
|
||||
hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
|
||||
btp = xfs_dir2_block_tail_p(dp->i_mount, hdr);
|
||||
btp = xfs_dir2_block_tail_p(geo, hdr);
|
||||
endp = (char *)xfs_dir2_block_leaf_p(btp);
|
||||
} else
|
||||
endp = (char *)hdr + dp->i_mount->m_dirblksize;
|
||||
endp = (char *)hdr + geo->blksize;
|
||||
/*
|
||||
* Loop over the block's entries.
|
||||
*/
|
||||
|
@ -584,8 +587,8 @@ xfs_dir3_data_init(
|
|||
/*
|
||||
* Get the buffer set up for the block.
|
||||
*/
|
||||
error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, blkno), -1, &bp,
|
||||
XFS_DATA_FORK);
|
||||
error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, blkno),
|
||||
-1, &bp, XFS_DATA_FORK);
|
||||
if (error)
|
||||
return error;
|
||||
bp->b_ops = &xfs_dir3_data_buf_ops;
|
||||
|
@ -620,15 +623,15 @@ xfs_dir3_data_init(
|
|||
dup = dp->d_ops->data_unused_p(hdr);
|
||||
dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
|
||||
|
||||
t = mp->m_dirblksize - (uint)dp->d_ops->data_entry_offset;
|
||||
t = args->geo->blksize - (uint)dp->d_ops->data_entry_offset;
|
||||
bf[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 *)hdr);
|
||||
/*
|
||||
* Log it and return it.
|
||||
*/
|
||||
xfs_dir2_data_log_header(tp, dp, bp);
|
||||
xfs_dir2_data_log_unused(tp, bp, dup);
|
||||
xfs_dir2_data_log_header(args, bp);
|
||||
xfs_dir2_data_log_unused(args, bp, dup);
|
||||
*bpp = bp;
|
||||
return 0;
|
||||
}
|
||||
|
@ -638,8 +641,7 @@ xfs_dir3_data_init(
|
|||
*/
|
||||
void
|
||||
xfs_dir2_data_log_entry(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
struct xfs_da_args *args,
|
||||
struct xfs_buf *bp,
|
||||
xfs_dir2_data_entry_t *dep) /* data entry pointer */
|
||||
{
|
||||
|
@ -650,8 +652,8 @@ xfs_dir2_data_log_entry(
|
|||
hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
|
||||
hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
|
||||
|
||||
xfs_trans_log_buf(tp, bp, (uint)((char *)dep - (char *)hdr),
|
||||
(uint)((char *)(dp->d_ops->data_entry_tag_p(dep) + 1) -
|
||||
xfs_trans_log_buf(args->trans, bp, (uint)((char *)dep - (char *)hdr),
|
||||
(uint)((char *)(args->dp->d_ops->data_entry_tag_p(dep) + 1) -
|
||||
(char *)hdr - 1));
|
||||
}
|
||||
|
||||
|
@ -660,8 +662,7 @@ xfs_dir2_data_log_entry(
|
|||
*/
|
||||
void
|
||||
xfs_dir2_data_log_header(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
struct xfs_da_args *args,
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
|
@ -673,7 +674,8 @@ xfs_dir2_data_log_header(
|
|||
hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
|
||||
#endif
|
||||
|
||||
xfs_trans_log_buf(tp, bp, 0, dp->d_ops->data_entry_offset - 1);
|
||||
xfs_trans_log_buf(args->trans, bp, 0,
|
||||
args->dp->d_ops->data_entry_offset - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -681,7 +683,7 @@ xfs_dir2_data_log_header(
|
|||
*/
|
||||
void
|
||||
xfs_dir2_data_log_unused(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_da_args *args,
|
||||
struct xfs_buf *bp,
|
||||
xfs_dir2_data_unused_t *dup) /* data unused pointer */
|
||||
{
|
||||
|
@ -695,13 +697,13 @@ xfs_dir2_data_log_unused(
|
|||
/*
|
||||
* Log the first part of the unused entry.
|
||||
*/
|
||||
xfs_trans_log_buf(tp, bp, (uint)((char *)dup - (char *)hdr),
|
||||
xfs_trans_log_buf(args->trans, bp, (uint)((char *)dup - (char *)hdr),
|
||||
(uint)((char *)&dup->length + sizeof(dup->length) -
|
||||
1 - (char *)hdr));
|
||||
/*
|
||||
* Log the end (tag) of the unused entry.
|
||||
*/
|
||||
xfs_trans_log_buf(tp, bp,
|
||||
xfs_trans_log_buf(args->trans, bp,
|
||||
(uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr),
|
||||
(uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr +
|
||||
sizeof(xfs_dir2_data_off_t) - 1));
|
||||
|
@ -713,8 +715,7 @@ xfs_dir2_data_log_unused(
|
|||
*/
|
||||
void
|
||||
xfs_dir2_data_make_free(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
struct xfs_da_args *args,
|
||||
struct xfs_buf *bp,
|
||||
xfs_dir2_data_aoff_t offset, /* starting byte offset */
|
||||
xfs_dir2_data_aoff_t len, /* length in bytes */
|
||||
|
@ -724,14 +725,12 @@ xfs_dir2_data_make_free(
|
|||
xfs_dir2_data_hdr_t *hdr; /* data block pointer */
|
||||
xfs_dir2_data_free_t *dfp; /* bestfree pointer */
|
||||
char *endptr; /* end of data area */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
int needscan; /* need to regen bestfree */
|
||||
xfs_dir2_data_unused_t *newdup; /* new unused entry */
|
||||
xfs_dir2_data_unused_t *postdup; /* unused entry after us */
|
||||
xfs_dir2_data_unused_t *prevdup; /* unused entry before us */
|
||||
struct xfs_dir2_data_free *bf;
|
||||
|
||||
mp = tp->t_mountp;
|
||||
hdr = bp->b_addr;
|
||||
|
||||
/*
|
||||
|
@ -739,20 +738,20 @@ xfs_dir2_data_make_free(
|
|||
*/
|
||||
if (hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
|
||||
hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC))
|
||||
endptr = (char *)hdr + mp->m_dirblksize;
|
||||
endptr = (char *)hdr + args->geo->blksize;
|
||||
else {
|
||||
xfs_dir2_block_tail_t *btp; /* block tail */
|
||||
|
||||
ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
|
||||
hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
|
||||
btp = xfs_dir2_block_tail_p(mp, hdr);
|
||||
btp = xfs_dir2_block_tail_p(args->geo, hdr);
|
||||
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 > dp->d_ops->data_entry_offset) {
|
||||
if (offset > args->dp->d_ops->data_entry_offset) {
|
||||
__be16 *tagp; /* tag just before us */
|
||||
|
||||
tagp = (__be16 *)((char *)hdr + offset) - 1;
|
||||
|
@ -778,7 +777,7 @@ xfs_dir2_data_make_free(
|
|||
* Previous and following entries are both free,
|
||||
* merge everything into a single free entry.
|
||||
*/
|
||||
bf = dp->d_ops->data_bestfree_p(hdr);
|
||||
bf = args->dp->d_ops->data_bestfree_p(hdr);
|
||||
if (prevdup && postdup) {
|
||||
xfs_dir2_data_free_t *dfp2; /* another bestfree pointer */
|
||||
|
||||
|
@ -800,7 +799,7 @@ xfs_dir2_data_make_free(
|
|||
be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length));
|
||||
*xfs_dir2_data_unused_tag_p(prevdup) =
|
||||
cpu_to_be16((char *)prevdup - (char *)hdr);
|
||||
xfs_dir2_data_log_unused(tp, bp, prevdup);
|
||||
xfs_dir2_data_log_unused(args, bp, prevdup);
|
||||
if (!needscan) {
|
||||
/*
|
||||
* Has to be the case that entries 0 and 1 are
|
||||
|
@ -835,7 +834,7 @@ xfs_dir2_data_make_free(
|
|||
be16_add_cpu(&prevdup->length, len);
|
||||
*xfs_dir2_data_unused_tag_p(prevdup) =
|
||||
cpu_to_be16((char *)prevdup - (char *)hdr);
|
||||
xfs_dir2_data_log_unused(tp, bp, prevdup);
|
||||
xfs_dir2_data_log_unused(args, bp, prevdup);
|
||||
/*
|
||||
* If the previous entry was in the table, the new entry
|
||||
* is longer, so it will be in the table too. Remove
|
||||
|
@ -863,7 +862,7 @@ xfs_dir2_data_make_free(
|
|||
newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length));
|
||||
*xfs_dir2_data_unused_tag_p(newdup) =
|
||||
cpu_to_be16((char *)newdup - (char *)hdr);
|
||||
xfs_dir2_data_log_unused(tp, bp, newdup);
|
||||
xfs_dir2_data_log_unused(args, bp, newdup);
|
||||
/*
|
||||
* If the following entry was in the table, the new entry
|
||||
* is longer, so it will be in the table too. Remove
|
||||
|
@ -890,7 +889,7 @@ xfs_dir2_data_make_free(
|
|||
newdup->length = cpu_to_be16(len);
|
||||
*xfs_dir2_data_unused_tag_p(newdup) =
|
||||
cpu_to_be16((char *)newdup - (char *)hdr);
|
||||
xfs_dir2_data_log_unused(tp, bp, newdup);
|
||||
xfs_dir2_data_log_unused(args, bp, newdup);
|
||||
xfs_dir2_data_freeinsert(hdr, bf, newdup, needlogp);
|
||||
}
|
||||
*needscanp = needscan;
|
||||
|
@ -901,8 +900,7 @@ xfs_dir2_data_make_free(
|
|||
*/
|
||||
void
|
||||
xfs_dir2_data_use_free(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
struct xfs_da_args *args,
|
||||
struct xfs_buf *bp,
|
||||
xfs_dir2_data_unused_t *dup, /* unused entry */
|
||||
xfs_dir2_data_aoff_t offset, /* starting offset to use */
|
||||
|
@ -933,7 +931,7 @@ xfs_dir2_data_use_free(
|
|||
* Look up the entry in the bestfree table.
|
||||
*/
|
||||
oldlen = be16_to_cpu(dup->length);
|
||||
bf = dp->d_ops->data_bestfree_p(hdr);
|
||||
bf = args->dp->d_ops->data_bestfree_p(hdr);
|
||||
dfp = xfs_dir2_data_freefind(hdr, bf, dup);
|
||||
ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length));
|
||||
/*
|
||||
|
@ -965,7 +963,7 @@ xfs_dir2_data_use_free(
|
|||
newdup->length = cpu_to_be16(oldlen - len);
|
||||
*xfs_dir2_data_unused_tag_p(newdup) =
|
||||
cpu_to_be16((char *)newdup - (char *)hdr);
|
||||
xfs_dir2_data_log_unused(tp, bp, newdup);
|
||||
xfs_dir2_data_log_unused(args, bp, newdup);
|
||||
/*
|
||||
* If it was in the table, remove it and add the new one.
|
||||
*/
|
||||
|
@ -993,7 +991,7 @@ xfs_dir2_data_use_free(
|
|||
newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup);
|
||||
*xfs_dir2_data_unused_tag_p(newdup) =
|
||||
cpu_to_be16((char *)newdup - (char *)hdr);
|
||||
xfs_dir2_data_log_unused(tp, bp, newdup);
|
||||
xfs_dir2_data_log_unused(args, bp, newdup);
|
||||
/*
|
||||
* If it was in the table, remove it and add the new one.
|
||||
*/
|
||||
|
@ -1021,13 +1019,13 @@ xfs_dir2_data_use_free(
|
|||
newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup);
|
||||
*xfs_dir2_data_unused_tag_p(newdup) =
|
||||
cpu_to_be16((char *)newdup - (char *)hdr);
|
||||
xfs_dir2_data_log_unused(tp, bp, newdup);
|
||||
xfs_dir2_data_log_unused(args, bp, newdup);
|
||||
newdup2 = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
|
||||
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 *)hdr);
|
||||
xfs_dir2_data_log_unused(tp, bp, newdup2);
|
||||
xfs_dir2_data_log_unused(args, bp, newdup2);
|
||||
/*
|
||||
* If the old entry was in the table, we need to scan
|
||||
* if the 3rd entry was valid, since these entries
|
||||
|
|
|
@ -41,9 +41,10 @@
|
|||
*/
|
||||
static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, struct xfs_buf **lbpp,
|
||||
int *indexp, struct xfs_buf **dbpp);
|
||||
static void xfs_dir3_leaf_log_bests(struct xfs_trans *tp, struct xfs_buf *bp,
|
||||
int first, int last);
|
||||
static void xfs_dir3_leaf_log_tail(struct xfs_trans *tp, struct xfs_buf *bp);
|
||||
static void xfs_dir3_leaf_log_bests(struct xfs_da_args *args,
|
||||
struct xfs_buf *bp, int first, int last);
|
||||
static void xfs_dir3_leaf_log_tail(struct xfs_da_args *args,
|
||||
struct xfs_buf *bp);
|
||||
|
||||
/*
|
||||
* Check the internal consistency of a leaf1 block.
|
||||
|
@ -92,6 +93,7 @@ xfs_dir3_leaf_check_int(
|
|||
int i;
|
||||
const struct xfs_dir_ops *ops;
|
||||
struct xfs_dir3_icleaf_hdr leafhdr;
|
||||
struct xfs_da_geometry *geo = mp->m_dir_geo;
|
||||
|
||||
/*
|
||||
* we can be passed a null dp here from a verifier, so we need to go the
|
||||
|
@ -105,14 +107,14 @@ xfs_dir3_leaf_check_int(
|
|||
}
|
||||
|
||||
ents = ops->leaf_ents_p(leaf);
|
||||
ltp = xfs_dir2_leaf_tail_p(mp, leaf);
|
||||
ltp = xfs_dir2_leaf_tail_p(geo, leaf);
|
||||
|
||||
/*
|
||||
* XXX (dgc): 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.
|
||||
*/
|
||||
if (hdr->count > ops->leaf_max_ents(mp))
|
||||
if (hdr->count > ops->leaf_max_ents(geo))
|
||||
return false;
|
||||
|
||||
/* Leaves and bests don't overlap in leaf format. */
|
||||
|
@ -323,7 +325,7 @@ xfs_dir3_leaf_init(
|
|||
if (type == XFS_DIR2_LEAF1_MAGIC) {
|
||||
struct xfs_dir2_leaf_tail *ltp;
|
||||
|
||||
ltp = xfs_dir2_leaf_tail_p(mp, leaf);
|
||||
ltp = xfs_dir2_leaf_tail_p(mp->m_dir_geo, leaf);
|
||||
ltp->bestcount = 0;
|
||||
bp->b_ops = &xfs_dir3_leaf1_buf_ops;
|
||||
xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_LEAF1_BUF);
|
||||
|
@ -347,18 +349,18 @@ xfs_dir3_leaf_get_buf(
|
|||
int error;
|
||||
|
||||
ASSERT(magic == XFS_DIR2_LEAF1_MAGIC || magic == XFS_DIR2_LEAFN_MAGIC);
|
||||
ASSERT(bno >= XFS_DIR2_LEAF_FIRSTDB(mp) &&
|
||||
bno < XFS_DIR2_FREE_FIRSTDB(mp));
|
||||
ASSERT(bno >= xfs_dir2_byte_to_db(args->geo, XFS_DIR2_LEAF_OFFSET) &&
|
||||
bno < xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET));
|
||||
|
||||
error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, bno), -1, &bp,
|
||||
XFS_DATA_FORK);
|
||||
error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, bno),
|
||||
-1, &bp, XFS_DATA_FORK);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
xfs_dir3_leaf_init(mp, tp, bp, dp->i_ino, magic);
|
||||
xfs_dir3_leaf_log_header(tp, dp, bp);
|
||||
xfs_dir3_leaf_log_header(args, bp);
|
||||
if (magic == XFS_DIR2_LEAF1_MAGIC)
|
||||
xfs_dir3_leaf_log_tail(tp, bp);
|
||||
xfs_dir3_leaf_log_tail(args, bp);
|
||||
*bpp = bp;
|
||||
return 0;
|
||||
}
|
||||
|
@ -403,8 +405,8 @@ xfs_dir2_block_to_leaf(
|
|||
if ((error = xfs_da_grow_inode(args, &blkno))) {
|
||||
return error;
|
||||
}
|
||||
ldb = xfs_dir2_da_to_db(mp, blkno);
|
||||
ASSERT(ldb == XFS_DIR2_LEAF_FIRSTDB(mp));
|
||||
ldb = xfs_dir2_da_to_db(args->geo, blkno);
|
||||
ASSERT(ldb == xfs_dir2_byte_to_db(args->geo, XFS_DIR2_LEAF_OFFSET));
|
||||
/*
|
||||
* Initialize the leaf block, get a buffer for it.
|
||||
*/
|
||||
|
@ -415,7 +417,7 @@ xfs_dir2_block_to_leaf(
|
|||
leaf = lbp->b_addr;
|
||||
hdr = dbp->b_addr;
|
||||
xfs_dir3_data_check(dp, dbp);
|
||||
btp = xfs_dir2_block_tail_p(mp, hdr);
|
||||
btp = xfs_dir2_block_tail_p(args->geo, hdr);
|
||||
blp = xfs_dir2_block_leaf_p(btp);
|
||||
bf = dp->d_ops->data_bestfree_p(hdr);
|
||||
ents = dp->d_ops->leaf_ents_p(leaf);
|
||||
|
@ -427,23 +429,23 @@ xfs_dir2_block_to_leaf(
|
|||
leafhdr.count = be32_to_cpu(btp->count);
|
||||
leafhdr.stale = be32_to_cpu(btp->stale);
|
||||
dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
|
||||
xfs_dir3_leaf_log_header(tp, dp, lbp);
|
||||
xfs_dir3_leaf_log_header(args, lbp);
|
||||
|
||||
/*
|
||||
* Could compact these but I think we always do the conversion
|
||||
* after squeezing out stale entries.
|
||||
*/
|
||||
memcpy(ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t));
|
||||
xfs_dir3_leaf_log_ents(tp, dp, lbp, 0, leafhdr.count - 1);
|
||||
xfs_dir3_leaf_log_ents(args, lbp, 0, leafhdr.count - 1);
|
||||
needscan = 0;
|
||||
needlog = 1;
|
||||
/*
|
||||
* Make the space formerly occupied by the leaf entries and block
|
||||
* tail be free.
|
||||
*/
|
||||
xfs_dir2_data_make_free(tp, dp, dbp,
|
||||
xfs_dir2_data_make_free(args, dbp,
|
||||
(xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr),
|
||||
(xfs_dir2_data_aoff_t)((char *)hdr + mp->m_dirblksize -
|
||||
(xfs_dir2_data_aoff_t)((char *)hdr + args->geo->blksize -
|
||||
(char *)blp),
|
||||
&needlog, &needscan);
|
||||
/*
|
||||
|
@ -461,7 +463,7 @@ xfs_dir2_block_to_leaf(
|
|||
/*
|
||||
* Set up leaf tail and bests table.
|
||||
*/
|
||||
ltp = xfs_dir2_leaf_tail_p(mp, leaf);
|
||||
ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
|
||||
ltp->bestcount = cpu_to_be32(1);
|
||||
bestsp = xfs_dir2_leaf_bests_p(ltp);
|
||||
bestsp[0] = bf[0].length;
|
||||
|
@ -469,10 +471,10 @@ xfs_dir2_block_to_leaf(
|
|||
* Log the data header and leaf bests table.
|
||||
*/
|
||||
if (needlog)
|
||||
xfs_dir2_data_log_header(tp, dp, dbp);
|
||||
xfs_dir2_data_log_header(args, dbp);
|
||||
xfs_dir3_leaf_check(dp, lbp);
|
||||
xfs_dir3_data_check(dp, dbp);
|
||||
xfs_dir3_leaf_log_bests(tp, lbp, 0, 0);
|
||||
xfs_dir3_leaf_log_bests(args, lbp, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -641,7 +643,7 @@ xfs_dir2_leaf_addname(
|
|||
tp = args->trans;
|
||||
mp = dp->i_mount;
|
||||
|
||||
error = xfs_dir3_leaf_read(tp, dp, mp->m_dirleafblk, -1, &lbp);
|
||||
error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, -1, &lbp);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -653,7 +655,7 @@ xfs_dir2_leaf_addname(
|
|||
*/
|
||||
index = xfs_dir2_leaf_search_hash(args, lbp);
|
||||
leaf = lbp->b_addr;
|
||||
ltp = xfs_dir2_leaf_tail_p(mp, leaf);
|
||||
ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
|
||||
ents = dp->d_ops->leaf_ents_p(leaf);
|
||||
dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
bestsp = xfs_dir2_leaf_bests_p(ltp);
|
||||
|
@ -670,7 +672,7 @@ xfs_dir2_leaf_addname(
|
|||
index++, lep++) {
|
||||
if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
|
||||
continue;
|
||||
i = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address));
|
||||
i = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
|
||||
ASSERT(i < be32_to_cpu(ltp->bestcount));
|
||||
ASSERT(bestsp[i] != cpu_to_be16(NULLDATAOFF));
|
||||
if (be16_to_cpu(bestsp[i]) >= length) {
|
||||
|
@ -810,14 +812,15 @@ xfs_dir2_leaf_addname(
|
|||
memmove(&bestsp[0], &bestsp[1],
|
||||
be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0]));
|
||||
be32_add_cpu(<p->bestcount, 1);
|
||||
xfs_dir3_leaf_log_tail(tp, lbp);
|
||||
xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
|
||||
xfs_dir3_leaf_log_tail(args, lbp);
|
||||
xfs_dir3_leaf_log_bests(args, lbp, 0,
|
||||
be32_to_cpu(ltp->bestcount) - 1);
|
||||
}
|
||||
/*
|
||||
* If we're filling in a previously empty block just log it.
|
||||
*/
|
||||
else
|
||||
xfs_dir3_leaf_log_bests(tp, lbp, use_block, use_block);
|
||||
xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block);
|
||||
hdr = dbp->b_addr;
|
||||
bf = dp->d_ops->data_bestfree_p(hdr);
|
||||
bestsp[use_block] = bf[0].length;
|
||||
|
@ -828,7 +831,7 @@ xfs_dir2_leaf_addname(
|
|||
* Just read that one in.
|
||||
*/
|
||||
error = xfs_dir3_data_read(tp, dp,
|
||||
xfs_dir2_db_to_da(mp, use_block),
|
||||
xfs_dir2_db_to_da(args->geo, use_block),
|
||||
-1, &dbp);
|
||||
if (error) {
|
||||
xfs_trans_brelse(tp, lbp);
|
||||
|
@ -848,7 +851,7 @@ xfs_dir2_leaf_addname(
|
|||
/*
|
||||
* Mark the initial part of our freespace in use for the new entry.
|
||||
*/
|
||||
xfs_dir2_data_use_free(tp, dp, dbp, dup,
|
||||
xfs_dir2_data_use_free(args, dbp, dup,
|
||||
(xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length,
|
||||
&needlog, &needscan);
|
||||
/*
|
||||
|
@ -870,8 +873,8 @@ xfs_dir2_leaf_addname(
|
|||
* Need to log the data block's header.
|
||||
*/
|
||||
if (needlog)
|
||||
xfs_dir2_data_log_header(tp, dp, dbp);
|
||||
xfs_dir2_data_log_entry(tp, dp, dbp, dep);
|
||||
xfs_dir2_data_log_header(args, dbp);
|
||||
xfs_dir2_data_log_entry(args, dbp, dep);
|
||||
/*
|
||||
* If the bests table needs to be changed, do it.
|
||||
* Log the change unless we've already done that.
|
||||
|
@ -879,7 +882,7 @@ xfs_dir2_leaf_addname(
|
|||
if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(bf[0].length)) {
|
||||
bestsp[use_block] = bf[0].length;
|
||||
if (!grown)
|
||||
xfs_dir3_leaf_log_bests(tp, lbp, use_block, use_block);
|
||||
xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block);
|
||||
}
|
||||
|
||||
lep = xfs_dir3_leaf_find_entry(&leafhdr, ents, index, compact, lowstale,
|
||||
|
@ -889,14 +892,15 @@ xfs_dir2_leaf_addname(
|
|||
* Fill in the new leaf entry.
|
||||
*/
|
||||
lep->hashval = cpu_to_be32(args->hashval);
|
||||
lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, use_block,
|
||||
lep->address = cpu_to_be32(
|
||||
xfs_dir2_db_off_to_dataptr(args->geo, use_block,
|
||||
be16_to_cpu(*tagp)));
|
||||
/*
|
||||
* Log the leaf fields and give up the buffers.
|
||||
*/
|
||||
dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
|
||||
xfs_dir3_leaf_log_header(tp, dp, lbp);
|
||||
xfs_dir3_leaf_log_ents(tp, dp, lbp, lfloglow, lfloghigh);
|
||||
xfs_dir3_leaf_log_header(args, lbp);
|
||||
xfs_dir3_leaf_log_ents(args, lbp, lfloglow, lfloghigh);
|
||||
xfs_dir3_leaf_check(dp, lbp);
|
||||
xfs_dir3_data_check(dp, dbp);
|
||||
return 0;
|
||||
|
@ -948,9 +952,9 @@ xfs_dir3_leaf_compact(
|
|||
leafhdr->stale = 0;
|
||||
|
||||
dp->d_ops->leaf_hdr_to_disk(leaf, leafhdr);
|
||||
xfs_dir3_leaf_log_header(args->trans, dp, bp);
|
||||
xfs_dir3_leaf_log_header(args, bp);
|
||||
if (loglow != -1)
|
||||
xfs_dir3_leaf_log_ents(args->trans, dp, bp, loglow, to - 1);
|
||||
xfs_dir3_leaf_log_ents(args, bp, loglow, to - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1052,7 +1056,7 @@ xfs_dir3_leaf_compact_x1(
|
|||
*/
|
||||
static void
|
||||
xfs_dir3_leaf_log_bests(
|
||||
xfs_trans_t *tp, /* transaction pointer */
|
||||
struct xfs_da_args *args,
|
||||
struct xfs_buf *bp, /* leaf buffer */
|
||||
int first, /* first entry to log */
|
||||
int last) /* last entry to log */
|
||||
|
@ -1065,10 +1069,11 @@ xfs_dir3_leaf_log_bests(
|
|||
ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
|
||||
leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC));
|
||||
|
||||
ltp = xfs_dir2_leaf_tail_p(tp->t_mountp, leaf);
|
||||
ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
|
||||
firstb = xfs_dir2_leaf_bests_p(ltp) + first;
|
||||
lastb = xfs_dir2_leaf_bests_p(ltp) + last;
|
||||
xfs_trans_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf),
|
||||
xfs_trans_log_buf(args->trans, bp,
|
||||
(uint)((char *)firstb - (char *)leaf),
|
||||
(uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1));
|
||||
}
|
||||
|
||||
|
@ -1077,8 +1082,7 @@ xfs_dir3_leaf_log_bests(
|
|||
*/
|
||||
void
|
||||
xfs_dir3_leaf_log_ents(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
struct xfs_da_args *args,
|
||||
struct xfs_buf *bp,
|
||||
int first,
|
||||
int last)
|
||||
|
@ -1093,10 +1097,11 @@ xfs_dir3_leaf_log_ents(
|
|||
leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
|
||||
leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC));
|
||||
|
||||
ents = dp->d_ops->leaf_ents_p(leaf);
|
||||
ents = args->dp->d_ops->leaf_ents_p(leaf);
|
||||
firstlep = &ents[first];
|
||||
lastlep = &ents[last];
|
||||
xfs_trans_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf),
|
||||
xfs_trans_log_buf(args->trans, bp,
|
||||
(uint)((char *)firstlep - (char *)leaf),
|
||||
(uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1));
|
||||
}
|
||||
|
||||
|
@ -1105,8 +1110,7 @@ xfs_dir3_leaf_log_ents(
|
|||
*/
|
||||
void
|
||||
xfs_dir3_leaf_log_header(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
struct xfs_da_args *args,
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
struct xfs_dir2_leaf *leaf = bp->b_addr;
|
||||
|
@ -1116,8 +1120,9 @@ xfs_dir3_leaf_log_header(
|
|||
leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
|
||||
leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC));
|
||||
|
||||
xfs_trans_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf),
|
||||
dp->d_ops->leaf_hdr_size - 1);
|
||||
xfs_trans_log_buf(args->trans, bp,
|
||||
(uint)((char *)&leaf->hdr - (char *)leaf),
|
||||
args->dp->d_ops->leaf_hdr_size - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1125,21 +1130,20 @@ xfs_dir3_leaf_log_header(
|
|||
*/
|
||||
STATIC void
|
||||
xfs_dir3_leaf_log_tail(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_da_args *args,
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
struct xfs_dir2_leaf *leaf = bp->b_addr;
|
||||
xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
|
||||
struct xfs_mount *mp = tp->t_mountp;
|
||||
|
||||
ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
|
||||
leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) ||
|
||||
leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
|
||||
leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC));
|
||||
|
||||
ltp = xfs_dir2_leaf_tail_p(mp, leaf);
|
||||
xfs_trans_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf),
|
||||
(uint)(mp->m_dirblksize - 1));
|
||||
ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
|
||||
xfs_trans_log_buf(args->trans, bp, (uint)((char *)ltp - (char *)leaf),
|
||||
(uint)(args->geo->blksize - 1));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1185,7 +1189,7 @@ xfs_dir2_leaf_lookup(
|
|||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)dbp->b_addr +
|
||||
xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address)));
|
||||
xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address)));
|
||||
/*
|
||||
* Return the found inode number & CI name if appropriate
|
||||
*/
|
||||
|
@ -1231,7 +1235,7 @@ xfs_dir2_leaf_lookup_int(
|
|||
tp = args->trans;
|
||||
mp = dp->i_mount;
|
||||
|
||||
error = xfs_dir3_leaf_read(tp, dp, mp->m_dirleafblk, -1, &lbp);
|
||||
error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, -1, &lbp);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -1260,7 +1264,8 @@ xfs_dir2_leaf_lookup_int(
|
|||
/*
|
||||
* Get the new data block number.
|
||||
*/
|
||||
newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address));
|
||||
newdb = xfs_dir2_dataptr_to_db(args->geo,
|
||||
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.
|
||||
|
@ -1269,7 +1274,7 @@ xfs_dir2_leaf_lookup_int(
|
|||
if (dbp)
|
||||
xfs_trans_brelse(tp, dbp);
|
||||
error = xfs_dir3_data_read(tp, dp,
|
||||
xfs_dir2_db_to_da(mp, newdb),
|
||||
xfs_dir2_db_to_da(args->geo, newdb),
|
||||
-1, &dbp);
|
||||
if (error) {
|
||||
xfs_trans_brelse(tp, lbp);
|
||||
|
@ -1281,7 +1286,8 @@ xfs_dir2_leaf_lookup_int(
|
|||
* Point to the data entry.
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)((char *)dbp->b_addr +
|
||||
xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)));
|
||||
xfs_dir2_dataptr_to_off(args->geo,
|
||||
be32_to_cpu(lep->address)));
|
||||
/*
|
||||
* Compare name and if it's an exact match, return the index
|
||||
* and buffer. If it's the first case-insensitive match, store
|
||||
|
@ -1310,7 +1316,7 @@ xfs_dir2_leaf_lookup_int(
|
|||
if (cidb != curdb) {
|
||||
xfs_trans_brelse(tp, dbp);
|
||||
error = xfs_dir3_data_read(tp, dp,
|
||||
xfs_dir2_db_to_da(mp, cidb),
|
||||
xfs_dir2_db_to_da(args->geo, cidb),
|
||||
-1, &dbp);
|
||||
if (error) {
|
||||
xfs_trans_brelse(tp, lbp);
|
||||
|
@ -1380,18 +1386,18 @@ xfs_dir2_leaf_removename(
|
|||
* Point to the leaf entry, use that to point to the data entry.
|
||||
*/
|
||||
lep = &ents[index];
|
||||
db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address));
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)));
|
||||
db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
|
||||
dep = (xfs_dir2_data_entry_t *)((char *)hdr +
|
||||
xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address)));
|
||||
needscan = needlog = 0;
|
||||
oldbest = be16_to_cpu(bf[0].length);
|
||||
ltp = xfs_dir2_leaf_tail_p(mp, leaf);
|
||||
ltp = xfs_dir2_leaf_tail_p(args->geo, 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, dp, dbp,
|
||||
xfs_dir2_data_make_free(args, dbp,
|
||||
(xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
|
||||
dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
|
||||
/*
|
||||
|
@ -1399,10 +1405,10 @@ xfs_dir2_leaf_removename(
|
|||
*/
|
||||
leafhdr.stale++;
|
||||
dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
|
||||
xfs_dir3_leaf_log_header(tp, dp, lbp);
|
||||
xfs_dir3_leaf_log_header(args, lbp);
|
||||
|
||||
lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
|
||||
xfs_dir3_leaf_log_ents(tp, dp, lbp, index, index);
|
||||
xfs_dir3_leaf_log_ents(args, lbp, index, index);
|
||||
|
||||
/*
|
||||
* Scan the freespace in the data block again if necessary,
|
||||
|
@ -1411,22 +1417,22 @@ xfs_dir2_leaf_removename(
|
|||
if (needscan)
|
||||
xfs_dir2_data_freescan(dp, hdr, &needlog);
|
||||
if (needlog)
|
||||
xfs_dir2_data_log_header(tp, dp, dbp);
|
||||
xfs_dir2_data_log_header(args, dbp);
|
||||
/*
|
||||
* If the longest freespace in the data block has changed,
|
||||
* put the new value in the bests table and log that.
|
||||
*/
|
||||
if (be16_to_cpu(bf[0].length) != oldbest) {
|
||||
bestsp[db] = bf[0].length;
|
||||
xfs_dir3_leaf_log_bests(tp, lbp, db, db);
|
||||
xfs_dir3_leaf_log_bests(args, lbp, db, db);
|
||||
}
|
||||
xfs_dir3_data_check(dp, dbp);
|
||||
/*
|
||||
* If the data block is now empty then get rid of the data block.
|
||||
*/
|
||||
if (be16_to_cpu(bf[0].length) ==
|
||||
mp->m_dirblksize - dp->d_ops->data_entry_offset) {
|
||||
ASSERT(db != mp->m_dirdatablk);
|
||||
args->geo->blksize - dp->d_ops->data_entry_offset) {
|
||||
ASSERT(db != args->geo->datablk);
|
||||
if ((error = xfs_dir2_shrink_inode(args, db, dbp))) {
|
||||
/*
|
||||
* Nope, can't get rid of it because it caused
|
||||
|
@ -1459,15 +1465,16 @@ xfs_dir2_leaf_removename(
|
|||
memmove(&bestsp[db - i], bestsp,
|
||||
(be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp));
|
||||
be32_add_cpu(<p->bestcount, -(db - i));
|
||||
xfs_dir3_leaf_log_tail(tp, lbp);
|
||||
xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
|
||||
xfs_dir3_leaf_log_tail(args, lbp);
|
||||
xfs_dir3_leaf_log_bests(args, lbp, 0,
|
||||
be32_to_cpu(ltp->bestcount) - 1);
|
||||
} else
|
||||
bestsp[db] = cpu_to_be16(NULLDATAOFF);
|
||||
}
|
||||
/*
|
||||
* If the data block was not the first one, drop it.
|
||||
*/
|
||||
else if (db != mp->m_dirdatablk)
|
||||
else if (db != args->geo->datablk)
|
||||
dbp = NULL;
|
||||
|
||||
xfs_dir3_leaf_check(dp, lbp);
|
||||
|
@ -1515,7 +1522,7 @@ xfs_dir2_leaf_replace(
|
|||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)dbp->b_addr +
|
||||
xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address)));
|
||||
xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address)));
|
||||
ASSERT(args->inumber != be64_to_cpu(dep->inumber));
|
||||
/*
|
||||
* Put the new inode number in, log it.
|
||||
|
@ -1523,7 +1530,7 @@ xfs_dir2_leaf_replace(
|
|||
dep->inumber = cpu_to_be64(args->inumber);
|
||||
dp->d_ops->data_put_ftype(dep, args->filetype);
|
||||
tp = args->trans;
|
||||
xfs_dir2_data_log_entry(tp, dp, dbp, dep);
|
||||
xfs_dir2_data_log_entry(args, dbp, dep);
|
||||
xfs_dir3_leaf_check(dp, lbp);
|
||||
xfs_trans_brelse(tp, lbp);
|
||||
return 0;
|
||||
|
@ -1609,12 +1616,13 @@ xfs_dir2_leaf_trim_data(
|
|||
/*
|
||||
* Read the offending data block. We need its buffer.
|
||||
*/
|
||||
error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp);
|
||||
error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(args->geo, db),
|
||||
-1, &dbp);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
leaf = lbp->b_addr;
|
||||
ltp = xfs_dir2_leaf_tail_p(mp, leaf);
|
||||
ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
|
@ -1624,7 +1632,7 @@ xfs_dir2_leaf_trim_data(
|
|||
ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
|
||||
hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
|
||||
ASSERT(be16_to_cpu(bf[0].length) ==
|
||||
mp->m_dirblksize - dp->d_ops->data_entry_offset);
|
||||
args->geo->blksize - dp->d_ops->data_entry_offset);
|
||||
ASSERT(db == be32_to_cpu(ltp->bestcount) - 1);
|
||||
}
|
||||
#endif
|
||||
|
@ -1643,8 +1651,8 @@ xfs_dir2_leaf_trim_data(
|
|||
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_dir3_leaf_log_tail(tp, lbp);
|
||||
xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
|
||||
xfs_dir3_leaf_log_tail(args, lbp);
|
||||
xfs_dir3_leaf_log_bests(args, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1711,19 +1719,19 @@ xfs_dir2_node_to_leaf(
|
|||
if ((error = xfs_bmap_last_offset(dp, &fo, XFS_DATA_FORK))) {
|
||||
return error;
|
||||
}
|
||||
fo -= mp->m_dirblkfsbs;
|
||||
fo -= args->geo->fsbcount;
|
||||
/*
|
||||
* If there are freespace blocks other than the first one,
|
||||
* take this opportunity to remove trailing empty freespace blocks
|
||||
* that may have been left behind during no-space-reservation
|
||||
* operations.
|
||||
*/
|
||||
while (fo > mp->m_dirfreeblk) {
|
||||
while (fo > args->geo->freeblk) {
|
||||
if ((error = xfs_dir2_node_trim_free(args, fo, &rval))) {
|
||||
return error;
|
||||
}
|
||||
if (rval)
|
||||
fo -= mp->m_dirblkfsbs;
|
||||
fo -= args->geo->fsbcount;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
@ -1736,7 +1744,7 @@ xfs_dir2_node_to_leaf(
|
|||
/*
|
||||
* If it's not the single leaf block, give up.
|
||||
*/
|
||||
if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + mp->m_dirblksize)
|
||||
if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + args->geo->blksize)
|
||||
return 0;
|
||||
lbp = state->path.blk[0].bp;
|
||||
leaf = lbp->b_addr;
|
||||
|
@ -1748,7 +1756,7 @@ xfs_dir2_node_to_leaf(
|
|||
/*
|
||||
* Read the freespace block.
|
||||
*/
|
||||
error = xfs_dir2_free_read(tp, dp, mp->m_dirfreeblk, &fbp);
|
||||
error = xfs_dir2_free_read(tp, dp, args->geo->freeblk, &fbp);
|
||||
if (error)
|
||||
return error;
|
||||
free = fbp->b_addr;
|
||||
|
@ -1760,7 +1768,7 @@ xfs_dir2_node_to_leaf(
|
|||
* Now see if the leafn and free data will fit in a leaf1.
|
||||
* If not, release the buffer and give up.
|
||||
*/
|
||||
if (xfs_dir3_leaf_size(&leafhdr, freehdr.nvalid) > mp->m_dirblksize) {
|
||||
if (xfs_dir3_leaf_size(&leafhdr, freehdr.nvalid) > args->geo->blksize) {
|
||||
xfs_trans_brelse(tp, fbp);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1780,7 +1788,7 @@ xfs_dir2_node_to_leaf(
|
|||
/*
|
||||
* Set up the leaf tail from the freespace block.
|
||||
*/
|
||||
ltp = xfs_dir2_leaf_tail_p(mp, leaf);
|
||||
ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
|
||||
ltp->bestcount = cpu_to_be32(freehdr.nvalid);
|
||||
|
||||
/*
|
||||
|
@ -1790,15 +1798,17 @@ xfs_dir2_node_to_leaf(
|
|||
freehdr.nvalid * sizeof(xfs_dir2_data_off_t));
|
||||
|
||||
dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
|
||||
xfs_dir3_leaf_log_header(tp, dp, lbp);
|
||||
xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
|
||||
xfs_dir3_leaf_log_tail(tp, lbp);
|
||||
xfs_dir3_leaf_log_header(args, lbp);
|
||||
xfs_dir3_leaf_log_bests(args, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
|
||||
xfs_dir3_leaf_log_tail(args, lbp);
|
||||
xfs_dir3_leaf_check(dp, lbp);
|
||||
|
||||
/*
|
||||
* Get rid of the freespace block.
|
||||
*/
|
||||
error = xfs_dir2_shrink_inode(args, XFS_DIR2_FREE_FIRSTDB(mp), fbp);
|
||||
error = xfs_dir2_shrink_inode(args,
|
||||
xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET),
|
||||
fbp);
|
||||
if (error) {
|
||||
/*
|
||||
* This can't fail here because it can only happen when
|
||||
|
|
|
@ -195,17 +195,18 @@ xfs_dir2_free_try_read(
|
|||
|
||||
static int
|
||||
xfs_dir3_free_get_buf(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
xfs_da_args_t *args,
|
||||
xfs_dir2_db_t fbno,
|
||||
struct xfs_buf **bpp)
|
||||
{
|
||||
struct xfs_trans *tp = args->trans;
|
||||
struct xfs_inode *dp = args->dp;
|
||||
struct xfs_mount *mp = dp->i_mount;
|
||||
struct xfs_buf *bp;
|
||||
int error;
|
||||
struct xfs_dir3_icfree_hdr hdr;
|
||||
|
||||
error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, fbno),
|
||||
error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, fbno),
|
||||
-1, &bp, XFS_DATA_FORK);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -240,8 +241,7 @@ xfs_dir3_free_get_buf(
|
|||
*/
|
||||
STATIC void
|
||||
xfs_dir2_free_log_bests(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
struct xfs_da_args *args,
|
||||
struct xfs_buf *bp,
|
||||
int first, /* first entry to log */
|
||||
int last) /* last entry to log */
|
||||
|
@ -250,10 +250,10 @@ xfs_dir2_free_log_bests(
|
|||
__be16 *bests;
|
||||
|
||||
free = bp->b_addr;
|
||||
bests = dp->d_ops->free_bests_p(free);
|
||||
bests = args->dp->d_ops->free_bests_p(free);
|
||||
ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
|
||||
free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
|
||||
xfs_trans_log_buf(tp, bp,
|
||||
xfs_trans_log_buf(args->trans, bp,
|
||||
(uint)((char *)&bests[first] - (char *)free),
|
||||
(uint)((char *)&bests[last] - (char *)free +
|
||||
sizeof(bests[0]) - 1));
|
||||
|
@ -264,8 +264,7 @@ xfs_dir2_free_log_bests(
|
|||
*/
|
||||
static void
|
||||
xfs_dir2_free_log_header(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
struct xfs_da_args *args,
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
|
@ -275,7 +274,8 @@ xfs_dir2_free_log_header(
|
|||
ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
|
||||
free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
|
||||
#endif
|
||||
xfs_trans_log_buf(tp, bp, 0, dp->d_ops->free_hdr_size - 1);
|
||||
xfs_trans_log_buf(args->trans, bp, 0,
|
||||
args->dp->d_ops->free_hdr_size - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -315,20 +315,20 @@ xfs_dir2_leaf_to_node(
|
|||
if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, &fdb))) {
|
||||
return error;
|
||||
}
|
||||
ASSERT(fdb == XFS_DIR2_FREE_FIRSTDB(mp));
|
||||
ASSERT(fdb == xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET));
|
||||
/*
|
||||
* Get the buffer for the new freespace block.
|
||||
*/
|
||||
error = xfs_dir3_free_get_buf(tp, dp, fdb, &fbp);
|
||||
error = xfs_dir3_free_get_buf(args, fdb, &fbp);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
free = fbp->b_addr;
|
||||
dp->d_ops->free_hdr_from_disk(&freehdr, free);
|
||||
leaf = lbp->b_addr;
|
||||
ltp = xfs_dir2_leaf_tail_p(mp, leaf);
|
||||
ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
|
||||
ASSERT(be32_to_cpu(ltp->bestcount) <=
|
||||
(uint)dp->i_d.di_size / mp->m_dirblksize);
|
||||
(uint)dp->i_d.di_size / args->geo->blksize);
|
||||
|
||||
/*
|
||||
* Copy freespace entries from the leaf block to the new block.
|
||||
|
@ -349,8 +349,8 @@ xfs_dir2_leaf_to_node(
|
|||
freehdr.nvalid = be32_to_cpu(ltp->bestcount);
|
||||
|
||||
dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr);
|
||||
xfs_dir2_free_log_bests(tp, dp, fbp, 0, freehdr.nvalid - 1);
|
||||
xfs_dir2_free_log_header(tp, dp, fbp);
|
||||
xfs_dir2_free_log_bests(args, fbp, 0, freehdr.nvalid - 1);
|
||||
xfs_dir2_free_log_header(args, fbp);
|
||||
|
||||
/*
|
||||
* Converting the leaf to a leafnode is just a matter of changing the
|
||||
|
@ -364,7 +364,7 @@ xfs_dir2_leaf_to_node(
|
|||
leaf->hdr.info.magic = cpu_to_be16(XFS_DIR3_LEAFN_MAGIC);
|
||||
lbp->b_ops = &xfs_dir3_leafn_buf_ops;
|
||||
xfs_trans_buf_set_type(tp, lbp, XFS_BLFT_DIR_LEAFN_BUF);
|
||||
xfs_dir3_leaf_log_header(tp, dp, lbp);
|
||||
xfs_dir3_leaf_log_header(args, lbp);
|
||||
xfs_dir3_leaf_check(dp, lbp);
|
||||
return 0;
|
||||
}
|
||||
|
@ -415,7 +415,7 @@ xfs_dir2_leafn_add(
|
|||
* a compact.
|
||||
*/
|
||||
|
||||
if (leafhdr.count == dp->d_ops->leaf_max_ents(mp)) {
|
||||
if (leafhdr.count == dp->d_ops->leaf_max_ents(args->geo)) {
|
||||
if (!leafhdr.stale)
|
||||
return XFS_ERROR(ENOSPC);
|
||||
compact = leafhdr.stale > 1;
|
||||
|
@ -450,12 +450,12 @@ xfs_dir2_leafn_add(
|
|||
highstale, &lfloglow, &lfloghigh);
|
||||
|
||||
lep->hashval = cpu_to_be32(args->hashval);
|
||||
lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp,
|
||||
lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(args->geo,
|
||||
args->blkno, args->index));
|
||||
|
||||
dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
|
||||
xfs_dir3_leaf_log_header(tp, dp, bp);
|
||||
xfs_dir3_leaf_log_ents(tp, dp, bp, lfloglow, lfloghigh);
|
||||
xfs_dir3_leaf_log_header(args, bp);
|
||||
xfs_dir3_leaf_log_ents(args, bp, lfloglow, lfloghigh);
|
||||
xfs_dir3_leaf_check(dp, bp);
|
||||
return 0;
|
||||
}
|
||||
|
@ -471,7 +471,8 @@ xfs_dir2_free_hdr_check(
|
|||
|
||||
dp->d_ops->free_hdr_from_disk(&hdr, bp->b_addr);
|
||||
|
||||
ASSERT((hdr.firstdb % dp->d_ops->free_max_bests(dp->i_mount)) == 0);
|
||||
ASSERT((hdr.firstdb %
|
||||
dp->d_ops->free_max_bests(dp->i_mount->m_dir_geo)) == 0);
|
||||
ASSERT(hdr.firstdb <= db);
|
||||
ASSERT(db < hdr.firstdb + hdr.nvalid);
|
||||
}
|
||||
|
@ -576,7 +577,8 @@ xfs_dir2_leafn_lookup_for_addname(
|
|||
/*
|
||||
* Pull the data block number from the entry.
|
||||
*/
|
||||
newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address));
|
||||
newdb = xfs_dir2_dataptr_to_db(args->geo,
|
||||
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
|
||||
|
@ -593,7 +595,7 @@ xfs_dir2_leafn_lookup_for_addname(
|
|||
* Convert the data block to the free block
|
||||
* holding its freespace information.
|
||||
*/
|
||||
newfdb = dp->d_ops->db_to_fdb(mp, newdb);
|
||||
newfdb = dp->d_ops->db_to_fdb(args->geo, newdb);
|
||||
/*
|
||||
* If it's not the one we have in hand, read it in.
|
||||
*/
|
||||
|
@ -605,7 +607,8 @@ xfs_dir2_leafn_lookup_for_addname(
|
|||
xfs_trans_brelse(tp, curbp);
|
||||
|
||||
error = xfs_dir2_free_read(tp, dp,
|
||||
xfs_dir2_db_to_da(mp, newfdb),
|
||||
xfs_dir2_db_to_da(args->geo,
|
||||
newfdb),
|
||||
&curbp);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -616,7 +619,7 @@ xfs_dir2_leafn_lookup_for_addname(
|
|||
/*
|
||||
* Get the index for our entry.
|
||||
*/
|
||||
fi = dp->d_ops->db_to_fdindex(mp, curdb);
|
||||
fi = dp->d_ops->db_to_fdindex(args->geo, curdb);
|
||||
/*
|
||||
* If it has room, return it.
|
||||
*/
|
||||
|
@ -721,7 +724,8 @@ xfs_dir2_leafn_lookup_for_entry(
|
|||
/*
|
||||
* Pull the data block number from the entry.
|
||||
*/
|
||||
newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address));
|
||||
newdb = xfs_dir2_dataptr_to_db(args->geo,
|
||||
be32_to_cpu(lep->address));
|
||||
/*
|
||||
* Not adding a new entry, so we really want to find
|
||||
* the name given to us.
|
||||
|
@ -746,7 +750,8 @@ xfs_dir2_leafn_lookup_for_entry(
|
|||
curbp = state->extrablk.bp;
|
||||
} else {
|
||||
error = xfs_dir3_data_read(tp, dp,
|
||||
xfs_dir2_db_to_da(mp, newdb),
|
||||
xfs_dir2_db_to_da(args->geo,
|
||||
newdb),
|
||||
-1, &curbp);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -758,7 +763,8 @@ xfs_dir2_leafn_lookup_for_entry(
|
|||
* Point to the data entry.
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)((char *)curbp->b_addr +
|
||||
xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)));
|
||||
xfs_dir2_dataptr_to_off(args->geo,
|
||||
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
|
||||
|
@ -844,7 +850,6 @@ xfs_dir3_leafn_moveents(
|
|||
int start_d,/* destination leaf index */
|
||||
int count) /* count of leaves to copy */
|
||||
{
|
||||
struct xfs_trans *tp = args->trans;
|
||||
int stale; /* count stale leaves copied */
|
||||
|
||||
trace_xfs_dir2_leafn_moveents(args, start_s, start_d, count);
|
||||
|
@ -863,7 +868,7 @@ xfs_dir3_leafn_moveents(
|
|||
if (start_d < dhdr->count) {
|
||||
memmove(&dents[start_d + count], &dents[start_d],
|
||||
(dhdr->count - start_d) * sizeof(xfs_dir2_leaf_entry_t));
|
||||
xfs_dir3_leaf_log_ents(tp, args->dp, bp_d, start_d + count,
|
||||
xfs_dir3_leaf_log_ents(args, bp_d, start_d + count,
|
||||
count + dhdr->count - 1);
|
||||
}
|
||||
/*
|
||||
|
@ -885,8 +890,7 @@ xfs_dir3_leafn_moveents(
|
|||
*/
|
||||
memcpy(&dents[start_d], &sents[start_s],
|
||||
count * sizeof(xfs_dir2_leaf_entry_t));
|
||||
xfs_dir3_leaf_log_ents(tp, args->dp, bp_d,
|
||||
start_d, start_d + count - 1);
|
||||
xfs_dir3_leaf_log_ents(args, bp_d, start_d, start_d + count - 1);
|
||||
|
||||
/*
|
||||
* If there are source entries after the ones we copied,
|
||||
|
@ -895,8 +899,7 @@ xfs_dir3_leafn_moveents(
|
|||
if (start_s + count < shdr->count) {
|
||||
memmove(&sents[start_s], &sents[start_s + count],
|
||||
count * sizeof(xfs_dir2_leaf_entry_t));
|
||||
xfs_dir3_leaf_log_ents(tp, args->dp, bp_s,
|
||||
start_s, start_s + count - 1);
|
||||
xfs_dir3_leaf_log_ents(args, bp_s, start_s, start_s + count - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1032,8 +1035,8 @@ xfs_dir2_leafn_rebalance(
|
|||
/* log the changes made when moving the entries */
|
||||
dp->d_ops->leaf_hdr_to_disk(leaf1, &hdr1);
|
||||
dp->d_ops->leaf_hdr_to_disk(leaf2, &hdr2);
|
||||
xfs_dir3_leaf_log_header(args->trans, dp, blk1->bp);
|
||||
xfs_dir3_leaf_log_header(args->trans, dp, blk2->bp);
|
||||
xfs_dir3_leaf_log_header(args, blk1->bp);
|
||||
xfs_dir3_leaf_log_header(args, blk2->bp);
|
||||
|
||||
xfs_dir3_leaf_check(dp, blk1->bp);
|
||||
xfs_dir3_leaf_check(dp, blk2->bp);
|
||||
|
@ -1076,7 +1079,6 @@ xfs_dir3_data_block_free(
|
|||
struct xfs_buf *fbp,
|
||||
int longest)
|
||||
{
|
||||
struct xfs_trans *tp = args->trans;
|
||||
int logfree = 0;
|
||||
__be16 *bests;
|
||||
struct xfs_dir3_icfree_hdr freehdr;
|
||||
|
@ -1090,7 +1092,7 @@ xfs_dir3_data_block_free(
|
|||
* value.
|
||||
*/
|
||||
bests[findex] = cpu_to_be16(longest);
|
||||
xfs_dir2_free_log_bests(tp, dp, fbp, findex, findex);
|
||||
xfs_dir2_free_log_bests(args, fbp, findex, findex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1118,7 +1120,7 @@ xfs_dir3_data_block_free(
|
|||
}
|
||||
|
||||
dp->d_ops->free_hdr_to_disk(free, &freehdr);
|
||||
xfs_dir2_free_log_header(tp, dp, fbp);
|
||||
xfs_dir2_free_log_header(args, fbp);
|
||||
|
||||
/*
|
||||
* If there are no useful entries left in the block, get rid of the
|
||||
|
@ -1142,7 +1144,7 @@ xfs_dir3_data_block_free(
|
|||
|
||||
/* Log the free entry that changed, unless we got rid of it. */
|
||||
if (logfree)
|
||||
xfs_dir2_free_log_bests(tp, dp, fbp, findex, findex);
|
||||
xfs_dir2_free_log_bests(args, fbp, findex, findex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1193,9 +1195,9 @@ xfs_dir2_leafn_remove(
|
|||
/*
|
||||
* Extract the data block and offset from the entry.
|
||||
*/
|
||||
db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address));
|
||||
db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
|
||||
ASSERT(dblk->blkno == db);
|
||||
off = xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address));
|
||||
off = xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address));
|
||||
ASSERT(dblk->index == off);
|
||||
|
||||
/*
|
||||
|
@ -1204,10 +1206,10 @@ xfs_dir2_leafn_remove(
|
|||
*/
|
||||
leafhdr.stale++;
|
||||
dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
|
||||
xfs_dir3_leaf_log_header(tp, dp, bp);
|
||||
xfs_dir3_leaf_log_header(args, bp);
|
||||
|
||||
lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
|
||||
xfs_dir3_leaf_log_ents(tp, dp, bp, index, index);
|
||||
xfs_dir3_leaf_log_ents(args, bp, index, index);
|
||||
|
||||
/*
|
||||
* Make the data entry free. Keep track of the longest freespace
|
||||
|
@ -1219,7 +1221,7 @@ xfs_dir2_leafn_remove(
|
|||
bf = dp->d_ops->data_bestfree_p(hdr);
|
||||
longest = be16_to_cpu(bf[0].length);
|
||||
needlog = needscan = 0;
|
||||
xfs_dir2_data_make_free(tp, dp, dbp, off,
|
||||
xfs_dir2_data_make_free(args, dbp, off,
|
||||
dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
|
||||
/*
|
||||
* Rescan the data block freespaces for bestfree.
|
||||
|
@ -1228,7 +1230,7 @@ xfs_dir2_leafn_remove(
|
|||
if (needscan)
|
||||
xfs_dir2_data_freescan(dp, hdr, &needlog);
|
||||
if (needlog)
|
||||
xfs_dir2_data_log_header(tp, dp, dbp);
|
||||
xfs_dir2_data_log_header(args, dbp);
|
||||
xfs_dir3_data_check(dp, dbp);
|
||||
/*
|
||||
* If the longest data block freespace changes, need to update
|
||||
|
@ -1245,8 +1247,9 @@ xfs_dir2_leafn_remove(
|
|||
* Convert the data block number to a free block,
|
||||
* read in the free block.
|
||||
*/
|
||||
fdb = dp->d_ops->db_to_fdb(mp, db);
|
||||
error = xfs_dir2_free_read(tp, dp, xfs_dir2_db_to_da(mp, fdb),
|
||||
fdb = dp->d_ops->db_to_fdb(args->geo, db);
|
||||
error = xfs_dir2_free_read(tp, dp,
|
||||
xfs_dir2_db_to_da(args->geo, fdb),
|
||||
&fbp);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -1255,20 +1258,21 @@ xfs_dir2_leafn_remove(
|
|||
{
|
||||
struct xfs_dir3_icfree_hdr freehdr;
|
||||
dp->d_ops->free_hdr_from_disk(&freehdr, free);
|
||||
ASSERT(freehdr.firstdb == dp->d_ops->free_max_bests(mp) *
|
||||
(fdb - XFS_DIR2_FREE_FIRSTDB(mp)));
|
||||
ASSERT(freehdr.firstdb == dp->d_ops->free_max_bests(args->geo) *
|
||||
(fdb - xfs_dir2_byte_to_db(args->geo,
|
||||
XFS_DIR2_FREE_OFFSET)));
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Calculate which entry we need to fix.
|
||||
*/
|
||||
findex = dp->d_ops->db_to_fdindex(mp, db);
|
||||
findex = dp->d_ops->db_to_fdindex(args->geo, db);
|
||||
longest = be16_to_cpu(bf[0].length);
|
||||
/*
|
||||
* If the data block is now empty we can get rid of it
|
||||
* (usually).
|
||||
*/
|
||||
if (longest == mp->m_dirblksize -
|
||||
if (longest == args->geo->blksize -
|
||||
dp->d_ops->data_entry_offset) {
|
||||
/*
|
||||
* Try to punch out the data block.
|
||||
|
@ -1303,7 +1307,7 @@ xfs_dir2_leafn_remove(
|
|||
*/
|
||||
*rval = (dp->d_ops->leaf_hdr_size +
|
||||
(uint)sizeof(ents[0]) * (leafhdr.count - leafhdr.stale)) <
|
||||
mp->m_dir_magicpct;
|
||||
args->geo->magicpct;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1336,7 +1340,7 @@ xfs_dir2_leafn_split(
|
|||
/*
|
||||
* Initialize the new leaf block.
|
||||
*/
|
||||
error = xfs_dir3_leaf_get_buf(args, xfs_dir2_da_to_db(mp, blkno),
|
||||
error = xfs_dir3_leaf_get_buf(args, xfs_dir2_da_to_db(args->geo, blkno),
|
||||
&newblk->bp, XFS_DIR2_LEAFN_MAGIC);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -1410,7 +1414,7 @@ xfs_dir2_leafn_toosmall(
|
|||
|
||||
count = leafhdr.count - leafhdr.stale;
|
||||
bytes = dp->d_ops->leaf_hdr_size + count * sizeof(ents[0]);
|
||||
if (bytes > (state->blocksize >> 1)) {
|
||||
if (bytes > (state->args->geo->blksize >> 1)) {
|
||||
/*
|
||||
* Blk over 50%, don't try to join.
|
||||
*/
|
||||
|
@ -1463,7 +1467,8 @@ xfs_dir2_leafn_toosmall(
|
|||
* Count bytes in the two blocks combined.
|
||||
*/
|
||||
count = leafhdr.count - leafhdr.stale;
|
||||
bytes = state->blocksize - (state->blocksize >> 2);
|
||||
bytes = state->args->geo->blksize -
|
||||
(state->args->geo->blksize >> 2);
|
||||
|
||||
leaf = bp->b_addr;
|
||||
dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf);
|
||||
|
@ -1560,8 +1565,8 @@ xfs_dir2_leafn_unbalance(
|
|||
/* log the changes made when moving the entries */
|
||||
dp->d_ops->leaf_hdr_to_disk(save_leaf, &savehdr);
|
||||
dp->d_ops->leaf_hdr_to_disk(drop_leaf, &drophdr);
|
||||
xfs_dir3_leaf_log_header(args->trans, dp, save_blk->bp);
|
||||
xfs_dir3_leaf_log_header(args->trans, dp, drop_blk->bp);
|
||||
xfs_dir3_leaf_log_header(args, save_blk->bp);
|
||||
xfs_dir3_leaf_log_header(args, drop_blk->bp);
|
||||
|
||||
xfs_dir3_leaf_check(dp, save_blk->bp);
|
||||
xfs_dir3_leaf_check(dp, drop_blk->bp);
|
||||
|
@ -1587,8 +1592,6 @@ xfs_dir2_node_addname(
|
|||
state = xfs_da_state_alloc();
|
||||
state->args = args;
|
||||
state->mp = args->dp->i_mount;
|
||||
state->blocksize = state->mp->m_dirblksize;
|
||||
state->node_ents = state->mp->m_dir_node_ents;
|
||||
/*
|
||||
* Look up the name. We're not supposed to find it, but
|
||||
* this gives us the insertion point.
|
||||
|
@ -1729,7 +1732,7 @@ xfs_dir2_node_addname_int(
|
|||
|
||||
if ((error = xfs_bmap_last_offset(dp, &fo, XFS_DATA_FORK)))
|
||||
return error;
|
||||
lastfbno = xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo);
|
||||
lastfbno = xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)fo);
|
||||
fbno = ifbno;
|
||||
}
|
||||
/*
|
||||
|
@ -1747,7 +1750,8 @@ xfs_dir2_node_addname_int(
|
|||
* us a freespace block to start with.
|
||||
*/
|
||||
if (++fbno == 0)
|
||||
fbno = XFS_DIR2_FREE_FIRSTDB(mp);
|
||||
fbno = xfs_dir2_byte_to_db(args->geo,
|
||||
XFS_DIR2_FREE_OFFSET);
|
||||
/*
|
||||
* If it's ifbno we already looked at it.
|
||||
*/
|
||||
|
@ -1765,7 +1769,7 @@ xfs_dir2_node_addname_int(
|
|||
* to avoid it.
|
||||
*/
|
||||
error = xfs_dir2_free_try_read(tp, dp,
|
||||
xfs_dir2_db_to_da(mp, fbno),
|
||||
xfs_dir2_db_to_da(args->geo, fbno),
|
||||
&fbp);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -1834,9 +1838,9 @@ xfs_dir2_node_addname_int(
|
|||
* Get the freespace block corresponding to the data block
|
||||
* that was just allocated.
|
||||
*/
|
||||
fbno = dp->d_ops->db_to_fdb(mp, dbno);
|
||||
fbno = dp->d_ops->db_to_fdb(args->geo, dbno);
|
||||
error = xfs_dir2_free_try_read(tp, dp,
|
||||
xfs_dir2_db_to_da(mp, fbno),
|
||||
xfs_dir2_db_to_da(args->geo, fbno),
|
||||
&fbp);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -1851,12 +1855,13 @@ xfs_dir2_node_addname_int(
|
|||
if (error)
|
||||
return error;
|
||||
|
||||
if (unlikely(dp->d_ops->db_to_fdb(mp, dbno) != fbno)) {
|
||||
if (dp->d_ops->db_to_fdb(args->geo, dbno) != fbno) {
|
||||
xfs_alert(mp,
|
||||
"%s: dir ino %llu needed freesp block %lld for\n"
|
||||
" data block %lld, got %lld ifbno %llu lastfbno %d",
|
||||
__func__, (unsigned long long)dp->i_ino,
|
||||
(long long)dp->d_ops->db_to_fdb(mp, dbno),
|
||||
(long long)dp->d_ops->db_to_fdb(
|
||||
args->geo, dbno),
|
||||
(long long)dbno, (long long)fbno,
|
||||
(unsigned long long)ifbno, lastfbno);
|
||||
if (fblk) {
|
||||
|
@ -1877,7 +1882,7 @@ xfs_dir2_node_addname_int(
|
|||
/*
|
||||
* Get a buffer for the new block.
|
||||
*/
|
||||
error = xfs_dir3_free_get_buf(tp, dp, fbno, &fbp);
|
||||
error = xfs_dir3_free_get_buf(args, fbno, &fbp);
|
||||
if (error)
|
||||
return error;
|
||||
free = fbp->b_addr;
|
||||
|
@ -1887,8 +1892,10 @@ xfs_dir2_node_addname_int(
|
|||
/*
|
||||
* Remember the first slot as our empty slot.
|
||||
*/
|
||||
freehdr.firstdb = (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) *
|
||||
dp->d_ops->free_max_bests(mp);
|
||||
freehdr.firstdb =
|
||||
(fbno - xfs_dir2_byte_to_db(args->geo,
|
||||
XFS_DIR2_FREE_OFFSET)) *
|
||||
dp->d_ops->free_max_bests(args->geo);
|
||||
} else {
|
||||
free = fbp->b_addr;
|
||||
bests = dp->d_ops->free_bests_p(free);
|
||||
|
@ -1898,13 +1905,13 @@ xfs_dir2_node_addname_int(
|
|||
/*
|
||||
* Set the freespace block index from the data block number.
|
||||
*/
|
||||
findex = dp->d_ops->db_to_fdindex(mp, dbno);
|
||||
findex = dp->d_ops->db_to_fdindex(args->geo, dbno);
|
||||
/*
|
||||
* If it's after the end of the current entries in the
|
||||
* freespace block, extend that table.
|
||||
*/
|
||||
if (findex >= freehdr.nvalid) {
|
||||
ASSERT(findex < dp->d_ops->free_max_bests(mp));
|
||||
ASSERT(findex < dp->d_ops->free_max_bests(args->geo));
|
||||
freehdr.nvalid = findex + 1;
|
||||
/*
|
||||
* Tag new entry so nused will go up.
|
||||
|
@ -1918,7 +1925,7 @@ xfs_dir2_node_addname_int(
|
|||
if (bests[findex] == cpu_to_be16(NULLDATAOFF)) {
|
||||
freehdr.nused++;
|
||||
dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr);
|
||||
xfs_dir2_free_log_header(tp, dp, fbp);
|
||||
xfs_dir2_free_log_header(args, fbp);
|
||||
}
|
||||
/*
|
||||
* Update the real value in the table.
|
||||
|
@ -1943,7 +1950,8 @@ xfs_dir2_node_addname_int(
|
|||
/*
|
||||
* Read the data block in.
|
||||
*/
|
||||
error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(mp, dbno),
|
||||
error = xfs_dir3_data_read(tp, dp,
|
||||
xfs_dir2_db_to_da(args->geo, dbno),
|
||||
-1, &dbp);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -1961,7 +1969,7 @@ xfs_dir2_node_addname_int(
|
|||
/*
|
||||
* Mark the first part of the unused space, inuse for us.
|
||||
*/
|
||||
xfs_dir2_data_use_free(tp, dp, dbp, dup,
|
||||
xfs_dir2_data_use_free(args, dbp, dup,
|
||||
(xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length,
|
||||
&needlog, &needscan);
|
||||
/*
|
||||
|
@ -1974,7 +1982,7 @@ xfs_dir2_node_addname_int(
|
|||
dp->d_ops->data_put_ftype(dep, args->filetype);
|
||||
tagp = dp->d_ops->data_entry_tag_p(dep);
|
||||
*tagp = cpu_to_be16((char *)dep - (char *)hdr);
|
||||
xfs_dir2_data_log_entry(tp, dp, dbp, dep);
|
||||
xfs_dir2_data_log_entry(args, dbp, dep);
|
||||
/*
|
||||
* Rescan the block for bestfree if needed.
|
||||
*/
|
||||
|
@ -1984,7 +1992,7 @@ xfs_dir2_node_addname_int(
|
|||
* Log the data block header if needed.
|
||||
*/
|
||||
if (needlog)
|
||||
xfs_dir2_data_log_header(tp, dp, dbp);
|
||||
xfs_dir2_data_log_header(args, dbp);
|
||||
/*
|
||||
* If the freespace entry is now wrong, update it.
|
||||
*/
|
||||
|
@ -1997,7 +2005,7 @@ xfs_dir2_node_addname_int(
|
|||
* Log the freespace entry if needed.
|
||||
*/
|
||||
if (logfree)
|
||||
xfs_dir2_free_log_bests(tp, dp, fbp, findex, findex);
|
||||
xfs_dir2_free_log_bests(args, fbp, findex, findex);
|
||||
/*
|
||||
* Return the data block and offset in args, then drop the data block.
|
||||
*/
|
||||
|
@ -2028,8 +2036,6 @@ xfs_dir2_node_lookup(
|
|||
state = xfs_da_state_alloc();
|
||||
state->args = args;
|
||||
state->mp = args->dp->i_mount;
|
||||
state->blocksize = state->mp->m_dirblksize;
|
||||
state->node_ents = state->mp->m_dir_node_ents;
|
||||
/*
|
||||
* Fill in the path to the entry in the cursor.
|
||||
*/
|
||||
|
@ -2083,8 +2089,6 @@ xfs_dir2_node_removename(
|
|||
state = xfs_da_state_alloc();
|
||||
state->args = args;
|
||||
state->mp = args->dp->i_mount;
|
||||
state->blocksize = state->mp->m_dirblksize;
|
||||
state->node_ents = state->mp->m_dir_node_ents;
|
||||
|
||||
/* Look up the entry we're deleting, set up the cursor. */
|
||||
error = xfs_da3_node_lookup_int(state, &rval);
|
||||
|
@ -2153,8 +2157,6 @@ xfs_dir2_node_replace(
|
|||
state = xfs_da_state_alloc();
|
||||
state->args = args;
|
||||
state->mp = args->dp->i_mount;
|
||||
state->blocksize = state->mp->m_dirblksize;
|
||||
state->node_ents = state->mp->m_dir_node_ents;
|
||||
inum = args->inumber;
|
||||
/*
|
||||
* Lookup the entry to change in the btree.
|
||||
|
@ -2186,15 +2188,15 @@ xfs_dir2_node_replace(
|
|||
hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)hdr +
|
||||
xfs_dir2_dataptr_to_off(state->mp, be32_to_cpu(lep->address)));
|
||||
xfs_dir2_dataptr_to_off(args->geo,
|
||||
be32_to_cpu(lep->address)));
|
||||
ASSERT(inum != be64_to_cpu(dep->inumber));
|
||||
/*
|
||||
* Fill in the new inode number and log the entry.
|
||||
*/
|
||||
dep->inumber = cpu_to_be64(inum);
|
||||
args->dp->d_ops->data_put_ftype(dep, args->filetype);
|
||||
xfs_dir2_data_log_entry(args->trans, args->dp,
|
||||
state->extrablk.bp, dep);
|
||||
xfs_dir2_data_log_entry(args, state->extrablk.bp, dep);
|
||||
rval = 0;
|
||||
}
|
||||
/*
|
||||
|
@ -2262,9 +2264,9 @@ xfs_dir2_node_trim_free(
|
|||
/*
|
||||
* Blow the block away.
|
||||
*/
|
||||
if ((error =
|
||||
xfs_dir2_shrink_inode(args, xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo),
|
||||
bp))) {
|
||||
error = xfs_dir2_shrink_inode(args,
|
||||
xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)fo), bp);
|
||||
if (error) {
|
||||
/*
|
||||
* Can't fail with ENOSPC since that only happens with no
|
||||
* space reservation, when breaking up an extent into two
|
||||
|
|
|
@ -20,6 +20,140 @@
|
|||
|
||||
struct dir_context;
|
||||
|
||||
/*
|
||||
* Directory offset/block conversion functions.
|
||||
*
|
||||
* DB blocks here are logical directory block numbers, not filesystem blocks.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Convert dataptr to byte in file space
|
||||
*/
|
||||
static inline xfs_dir2_off_t
|
||||
xfs_dir2_dataptr_to_byte(xfs_dir2_dataptr_t dp)
|
||||
{
|
||||
return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert byte in file space to dataptr. It had better be aligned.
|
||||
*/
|
||||
static inline xfs_dir2_dataptr_t
|
||||
xfs_dir2_byte_to_dataptr(xfs_dir2_off_t by)
|
||||
{
|
||||
return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert byte in space to (DB) block
|
||||
*/
|
||||
static inline xfs_dir2_db_t
|
||||
xfs_dir2_byte_to_db(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
|
||||
{
|
||||
return (xfs_dir2_db_t)(by >> geo->blklog);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert dataptr to a block number
|
||||
*/
|
||||
static inline xfs_dir2_db_t
|
||||
xfs_dir2_dataptr_to_db(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
|
||||
{
|
||||
return xfs_dir2_byte_to_db(geo, xfs_dir2_dataptr_to_byte(dp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert byte in space to offset in a block
|
||||
*/
|
||||
static inline xfs_dir2_data_aoff_t
|
||||
xfs_dir2_byte_to_off(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
|
||||
{
|
||||
return (xfs_dir2_data_aoff_t)(by & (geo->blksize - 1));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert dataptr to a byte offset in a block
|
||||
*/
|
||||
static inline xfs_dir2_data_aoff_t
|
||||
xfs_dir2_dataptr_to_off(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
|
||||
{
|
||||
return xfs_dir2_byte_to_off(geo, xfs_dir2_dataptr_to_byte(dp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block and offset to byte in space
|
||||
*/
|
||||
static inline xfs_dir2_off_t
|
||||
xfs_dir2_db_off_to_byte(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
|
||||
xfs_dir2_data_aoff_t o)
|
||||
{
|
||||
return ((xfs_dir2_off_t)db << geo->blklog) + o;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block (DB) to block (dablk)
|
||||
*/
|
||||
static inline xfs_dablk_t
|
||||
xfs_dir2_db_to_da(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
|
||||
{
|
||||
return (xfs_dablk_t)(db << (geo->blklog - geo->fsblog));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert byte in space to (DA) block
|
||||
*/
|
||||
static inline xfs_dablk_t
|
||||
xfs_dir2_byte_to_da(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
|
||||
{
|
||||
return xfs_dir2_db_to_da(geo, xfs_dir2_byte_to_db(geo, by));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block and offset to dataptr
|
||||
*/
|
||||
static inline xfs_dir2_dataptr_t
|
||||
xfs_dir2_db_off_to_dataptr(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
|
||||
xfs_dir2_data_aoff_t o)
|
||||
{
|
||||
return xfs_dir2_byte_to_dataptr(xfs_dir2_db_off_to_byte(geo, db, o));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block (dablk) to block (DB)
|
||||
*/
|
||||
static inline xfs_dir2_db_t
|
||||
xfs_dir2_da_to_db(struct xfs_da_geometry *geo, xfs_dablk_t da)
|
||||
{
|
||||
return (xfs_dir2_db_t)(da >> (geo->blklog - geo->fsblog));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block (dablk) to byte offset in space
|
||||
*/
|
||||
static inline xfs_dir2_off_t
|
||||
xfs_dir2_da_to_byte(struct xfs_da_geometry *geo, xfs_dablk_t da)
|
||||
{
|
||||
return xfs_dir2_db_off_to_byte(geo, xfs_dir2_da_to_db(geo, da), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Directory tail pointer accessor functions. Based on block geometry.
|
||||
*/
|
||||
static inline struct xfs_dir2_block_tail *
|
||||
xfs_dir2_block_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_data_hdr *hdr)
|
||||
{
|
||||
return ((struct xfs_dir2_block_tail *)
|
||||
((char *)hdr + geo->blksize)) - 1;
|
||||
}
|
||||
|
||||
static inline struct xfs_dir2_leaf_tail *
|
||||
xfs_dir2_leaf_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_leaf *lp)
|
||||
{
|
||||
return (struct xfs_dir2_leaf_tail *)
|
||||
((char *)lp + geo->blksize -
|
||||
sizeof(struct xfs_dir2_leaf_tail));
|
||||
}
|
||||
|
||||
/* xfs_dir2.c */
|
||||
extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
|
||||
extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
|
||||
|
@ -77,9 +211,9 @@ extern void xfs_dir3_leaf_compact_x1(struct xfs_dir3_icleaf_hdr *leafhdr,
|
|||
int *lowstalep, int *highstalep, int *lowlogp, int *highlogp);
|
||||
extern int xfs_dir3_leaf_get_buf(struct xfs_da_args *args, xfs_dir2_db_t bno,
|
||||
struct xfs_buf **bpp, __uint16_t magic);
|
||||
extern void xfs_dir3_leaf_log_ents(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
extern void xfs_dir3_leaf_log_ents(struct xfs_da_args *args,
|
||||
struct xfs_buf *bp, int first, int last);
|
||||
extern void xfs_dir3_leaf_log_header(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
extern void xfs_dir3_leaf_log_header(struct xfs_da_args *args,
|
||||
struct xfs_buf *bp);
|
||||
extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args);
|
||||
extern int xfs_dir2_leaf_removename(struct xfs_da_args *args);
|
||||
|
|
|
@ -76,26 +76,25 @@ const unsigned char xfs_mode_to_ftype[S_IFMT >> S_SHIFT] = {
|
|||
|
||||
STATIC int
|
||||
xfs_dir2_sf_getdents(
|
||||
xfs_inode_t *dp, /* incore directory inode */
|
||||
struct xfs_da_args *args,
|
||||
struct dir_context *ctx)
|
||||
{
|
||||
int i; /* shortform entry number */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
struct xfs_inode *dp = args->dp; /* incore directory inode */
|
||||
xfs_dir2_dataptr_t off; /* current entry's offset */
|
||||
xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
|
||||
xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
|
||||
xfs_dir2_dataptr_t dot_offset;
|
||||
xfs_dir2_dataptr_t dotdot_offset;
|
||||
xfs_ino_t ino;
|
||||
|
||||
mp = dp->i_mount;
|
||||
struct xfs_da_geometry *geo = args->geo;
|
||||
|
||||
ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
|
||||
/*
|
||||
* Give up if the directory is way too short.
|
||||
*/
|
||||
if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
|
||||
ASSERT(XFS_FORCED_SHUTDOWN(mp));
|
||||
ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
|
||||
return XFS_ERROR(EIO);
|
||||
}
|
||||
|
||||
|
@ -109,18 +108,18 @@ xfs_dir2_sf_getdents(
|
|||
/*
|
||||
* If the block number in the offset is out of range, we're done.
|
||||
*/
|
||||
if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk)
|
||||
if (xfs_dir2_dataptr_to_db(geo, ctx->pos) > geo->datablk)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Precalculate offsets for . and .. as we will always need them.
|
||||
*
|
||||
* XXX(hch): the second argument is sometimes 0 and sometimes
|
||||
* mp->m_dirdatablk.
|
||||
* geo->datablk
|
||||
*/
|
||||
dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
|
||||
dot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
|
||||
dp->d_ops->data_dot_offset);
|
||||
dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
|
||||
dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
|
||||
dp->d_ops->data_dotdot_offset);
|
||||
|
||||
/*
|
||||
|
@ -149,7 +148,7 @@ xfs_dir2_sf_getdents(
|
|||
for (i = 0; i < sfp->count; i++) {
|
||||
__uint8_t filetype;
|
||||
|
||||
off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
|
||||
off = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
|
||||
xfs_dir2_sf_get_offset(sfep));
|
||||
|
||||
if (ctx->pos > off) {
|
||||
|
@ -161,12 +160,12 @@ xfs_dir2_sf_getdents(
|
|||
filetype = dp->d_ops->sf_get_ftype(sfep);
|
||||
ctx->pos = off & 0x7fffffff;
|
||||
if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino,
|
||||
xfs_dir3_get_dtype(mp, filetype)))
|
||||
xfs_dir3_get_dtype(dp->i_mount, filetype)))
|
||||
return 0;
|
||||
sfep = dp->d_ops->sf_nextentry(sfp, sfep);
|
||||
}
|
||||
|
||||
ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) &
|
||||
ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) &
|
||||
0x7fffffff;
|
||||
return 0;
|
||||
}
|
||||
|
@ -176,9 +175,10 @@ xfs_dir2_sf_getdents(
|
|||
*/
|
||||
STATIC int
|
||||
xfs_dir2_block_getdents(
|
||||
xfs_inode_t *dp, /* incore inode */
|
||||
struct xfs_da_args *args,
|
||||
struct dir_context *ctx)
|
||||
{
|
||||
struct xfs_inode *dp = args->dp; /* incore directory inode */
|
||||
xfs_dir2_data_hdr_t *hdr; /* block header */
|
||||
struct xfs_buf *bp; /* buffer for block */
|
||||
xfs_dir2_block_tail_t *btp; /* block tail */
|
||||
|
@ -186,16 +186,15 @@ xfs_dir2_block_getdents(
|
|||
xfs_dir2_data_unused_t *dup; /* block unused entry */
|
||||
char *endptr; /* end of the data entries */
|
||||
int error; /* error return value */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
char *ptr; /* current data entry */
|
||||
int wantoff; /* starting block offset */
|
||||
xfs_off_t cook;
|
||||
struct xfs_da_geometry *geo = args->geo;
|
||||
|
||||
mp = dp->i_mount;
|
||||
/*
|
||||
* If the block number in the offset is out of range, we're done.
|
||||
*/
|
||||
if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk)
|
||||
if (xfs_dir2_dataptr_to_db(geo, ctx->pos) > geo->datablk)
|
||||
return 0;
|
||||
|
||||
error = xfs_dir3_block_read(NULL, dp, &bp);
|
||||
|
@ -206,13 +205,13 @@ xfs_dir2_block_getdents(
|
|||
* Extract the byte offset we start at from the seek pointer.
|
||||
* We'll skip entries before this.
|
||||
*/
|
||||
wantoff = xfs_dir2_dataptr_to_off(mp, ctx->pos);
|
||||
wantoff = xfs_dir2_dataptr_to_off(geo, ctx->pos);
|
||||
hdr = bp->b_addr;
|
||||
xfs_dir3_data_check(dp, bp);
|
||||
/*
|
||||
* Set up values for the loop.
|
||||
*/
|
||||
btp = xfs_dir2_block_tail_p(mp, hdr);
|
||||
btp = xfs_dir2_block_tail_p(geo, hdr);
|
||||
ptr = (char *)dp->d_ops->data_entry_p(hdr);
|
||||
endptr = (char *)xfs_dir2_block_leaf_p(btp);
|
||||
|
||||
|
@ -244,7 +243,7 @@ xfs_dir2_block_getdents(
|
|||
if ((char *)dep - (char *)hdr < wantoff)
|
||||
continue;
|
||||
|
||||
cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
|
||||
cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
|
||||
(char *)dep - (char *)hdr);
|
||||
|
||||
ctx->pos = cook & 0x7fffffff;
|
||||
|
@ -254,7 +253,7 @@ xfs_dir2_block_getdents(
|
|||
*/
|
||||
if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
|
||||
be64_to_cpu(dep->inumber),
|
||||
xfs_dir3_get_dtype(mp, filetype))) {
|
||||
xfs_dir3_get_dtype(dp->i_mount, filetype))) {
|
||||
xfs_trans_brelse(NULL, bp);
|
||||
return 0;
|
||||
}
|
||||
|
@ -264,7 +263,7 @@ xfs_dir2_block_getdents(
|
|||
* Reached the end of the block.
|
||||
* Set the offset to a non-existent block 1 and return.
|
||||
*/
|
||||
ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) &
|
||||
ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) &
|
||||
0x7fffffff;
|
||||
xfs_trans_brelse(NULL, bp);
|
||||
return 0;
|
||||
|
@ -286,13 +285,13 @@ struct xfs_dir2_leaf_map_info {
|
|||
|
||||
STATIC int
|
||||
xfs_dir2_leaf_readbuf(
|
||||
struct xfs_inode *dp,
|
||||
struct xfs_da_args *args,
|
||||
size_t bufsize,
|
||||
struct xfs_dir2_leaf_map_info *mip,
|
||||
xfs_dir2_off_t *curoff,
|
||||
struct xfs_buf **bpp)
|
||||
{
|
||||
struct xfs_mount *mp = dp->i_mount;
|
||||
struct xfs_inode *dp = args->dp;
|
||||
struct xfs_buf *bp = *bpp;
|
||||
struct xfs_bmbt_irec *map = mip->map;
|
||||
struct blk_plug plug;
|
||||
|
@ -300,6 +299,7 @@ xfs_dir2_leaf_readbuf(
|
|||
int length;
|
||||
int i;
|
||||
int j;
|
||||
struct xfs_da_geometry *geo = args->geo;
|
||||
|
||||
/*
|
||||
* If we have a buffer, we need to release it and
|
||||
|
@ -309,12 +309,12 @@ xfs_dir2_leaf_readbuf(
|
|||
if (bp) {
|
||||
xfs_trans_brelse(NULL, bp);
|
||||
bp = NULL;
|
||||
mip->map_blocks -= mp->m_dirblkfsbs;
|
||||
mip->map_blocks -= geo->fsbcount;
|
||||
/*
|
||||
* Loop to get rid of the extents for the
|
||||
* directory block.
|
||||
*/
|
||||
for (i = mp->m_dirblkfsbs; i > 0; ) {
|
||||
for (i = geo->fsbcount; i > 0; ) {
|
||||
j = min_t(int, map->br_blockcount, i);
|
||||
map->br_blockcount -= j;
|
||||
map->br_startblock += j;
|
||||
|
@ -333,8 +333,7 @@ xfs_dir2_leaf_readbuf(
|
|||
/*
|
||||
* Recalculate the readahead blocks wanted.
|
||||
*/
|
||||
mip->ra_want = howmany(bufsize + mp->m_dirblksize,
|
||||
mp->m_sb.sb_blocksize) - 1;
|
||||
mip->ra_want = howmany(bufsize + geo->blksize, (1 << geo->fsblog)) - 1;
|
||||
ASSERT(mip->ra_want >= 0);
|
||||
|
||||
/*
|
||||
|
@ -342,14 +341,14 @@ xfs_dir2_leaf_readbuf(
|
|||
* run out of data blocks, get some more mappings.
|
||||
*/
|
||||
if (1 + mip->ra_want > mip->map_blocks &&
|
||||
mip->map_off < xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET)) {
|
||||
mip->map_off < xfs_dir2_byte_to_da(geo, XFS_DIR2_LEAF_OFFSET)) {
|
||||
/*
|
||||
* Get more bmaps, fill in after the ones
|
||||
* we already have in the table.
|
||||
*/
|
||||
mip->nmap = mip->map_size - mip->map_valid;
|
||||
error = xfs_bmapi_read(dp, mip->map_off,
|
||||
xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET) -
|
||||
xfs_dir2_byte_to_da(geo, XFS_DIR2_LEAF_OFFSET) -
|
||||
mip->map_off,
|
||||
&map[mip->map_valid], &mip->nmap, 0);
|
||||
|
||||
|
@ -370,7 +369,7 @@ xfs_dir2_leaf_readbuf(
|
|||
i = mip->map_valid + mip->nmap - 1;
|
||||
mip->map_off = map[i].br_startoff + map[i].br_blockcount;
|
||||
} else
|
||||
mip->map_off = xfs_dir2_byte_to_da(mp,
|
||||
mip->map_off = xfs_dir2_byte_to_da(geo,
|
||||
XFS_DIR2_LEAF_OFFSET);
|
||||
|
||||
/*
|
||||
|
@ -396,18 +395,18 @@ xfs_dir2_leaf_readbuf(
|
|||
* No valid mappings, so no more data blocks.
|
||||
*/
|
||||
if (!mip->map_valid) {
|
||||
*curoff = xfs_dir2_da_to_byte(mp, mip->map_off);
|
||||
*curoff = xfs_dir2_da_to_byte(geo, mip->map_off);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the directory block starting at the first mapping.
|
||||
*/
|
||||
mip->curdb = xfs_dir2_da_to_db(mp, map->br_startoff);
|
||||
mip->curdb = xfs_dir2_da_to_db(geo, map->br_startoff);
|
||||
error = xfs_dir3_data_read(NULL, dp, map->br_startoff,
|
||||
map->br_blockcount >= mp->m_dirblkfsbs ?
|
||||
XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, &bp);
|
||||
|
||||
map->br_blockcount >= geo->fsbcount ?
|
||||
XFS_FSB_TO_DADDR(dp->i_mount, map->br_startblock) :
|
||||
-1, &bp);
|
||||
/*
|
||||
* Should just skip over the data block instead of giving up.
|
||||
*/
|
||||
|
@ -419,7 +418,7 @@ xfs_dir2_leaf_readbuf(
|
|||
* was previously ra.
|
||||
*/
|
||||
if (mip->ra_current)
|
||||
mip->ra_current -= mp->m_dirblkfsbs;
|
||||
mip->ra_current -= geo->fsbcount;
|
||||
|
||||
/*
|
||||
* Do we need more readahead?
|
||||
|
@ -427,16 +426,16 @@ xfs_dir2_leaf_readbuf(
|
|||
blk_start_plug(&plug);
|
||||
for (mip->ra_index = mip->ra_offset = i = 0;
|
||||
mip->ra_want > mip->ra_current && i < mip->map_blocks;
|
||||
i += mp->m_dirblkfsbs) {
|
||||
i += geo->fsbcount) {
|
||||
ASSERT(mip->ra_index < mip->map_valid);
|
||||
/*
|
||||
* Read-ahead a contiguous directory block.
|
||||
*/
|
||||
if (i > mip->ra_current &&
|
||||
map[mip->ra_index].br_blockcount >= mp->m_dirblkfsbs) {
|
||||
map[mip->ra_index].br_blockcount >= geo->fsbcount) {
|
||||
xfs_dir3_data_readahead(dp,
|
||||
map[mip->ra_index].br_startoff + mip->ra_offset,
|
||||
XFS_FSB_TO_DADDR(mp,
|
||||
XFS_FSB_TO_DADDR(dp->i_mount,
|
||||
map[mip->ra_index].br_startblock +
|
||||
mip->ra_offset));
|
||||
mip->ra_current = i;
|
||||
|
@ -456,12 +455,12 @@ xfs_dir2_leaf_readbuf(
|
|||
/*
|
||||
* Advance offset through the mapping table.
|
||||
*/
|
||||
for (j = 0; j < mp->m_dirblkfsbs; j += length ) {
|
||||
for (j = 0; j < geo->fsbcount; j += length ) {
|
||||
/*
|
||||
* The rest of this extent but not more than a dir
|
||||
* block.
|
||||
*/
|
||||
length = min_t(int, mp->m_dirblkfsbs,
|
||||
length = min_t(int, geo->fsbcount,
|
||||
map[mip->ra_index].br_blockcount -
|
||||
mip->ra_offset);
|
||||
mip->ra_offset += length;
|
||||
|
@ -488,22 +487,23 @@ out:
|
|||
*/
|
||||
STATIC int
|
||||
xfs_dir2_leaf_getdents(
|
||||
xfs_inode_t *dp, /* incore directory inode */
|
||||
struct xfs_da_args *args,
|
||||
struct dir_context *ctx,
|
||||
size_t bufsize)
|
||||
{
|
||||
struct xfs_inode *dp = args->dp;
|
||||
struct xfs_buf *bp = NULL; /* data block buffer */
|
||||
xfs_dir2_data_hdr_t *hdr; /* data block header */
|
||||
xfs_dir2_data_entry_t *dep; /* data entry */
|
||||
xfs_dir2_data_unused_t *dup; /* unused entry */
|
||||
int error = 0; /* error return value */
|
||||
int length; /* temporary length value */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
int byteoff; /* offset in current block */
|
||||
xfs_dir2_off_t curoff; /* current overall offset */
|
||||
xfs_dir2_off_t newoff; /* new curoff after new blk */
|
||||
char *ptr = NULL; /* pointer to current data */
|
||||
struct xfs_dir2_leaf_map_info *map_info;
|
||||
struct xfs_da_geometry *geo = args->geo;
|
||||
|
||||
/*
|
||||
* If the offset is at or past the largest allowed value,
|
||||
|
@ -512,15 +512,12 @@ xfs_dir2_leaf_getdents(
|
|||
if (ctx->pos >= XFS_DIR2_MAX_DATAPTR)
|
||||
return 0;
|
||||
|
||||
mp = dp->i_mount;
|
||||
|
||||
/*
|
||||
* Set up to bmap a number of blocks based on the caller's
|
||||
* buffer size, the directory block size, and the filesystem
|
||||
* block size.
|
||||
*/
|
||||
length = howmany(bufsize + mp->m_dirblksize,
|
||||
mp->m_sb.sb_blocksize);
|
||||
length = howmany(bufsize + geo->blksize, (1 << geo->fsblog));
|
||||
map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) +
|
||||
(length * sizeof(struct xfs_bmbt_irec)),
|
||||
KM_SLEEP | KM_NOFS);
|
||||
|
@ -536,8 +533,8 @@ xfs_dir2_leaf_getdents(
|
|||
* Force this conversion through db so we truncate the offset
|
||||
* down to get the start of the data block.
|
||||
*/
|
||||
map_info->map_off = xfs_dir2_db_to_da(mp,
|
||||
xfs_dir2_byte_to_db(mp, curoff));
|
||||
map_info->map_off = xfs_dir2_db_to_da(geo,
|
||||
xfs_dir2_byte_to_db(geo, curoff));
|
||||
|
||||
/*
|
||||
* Loop over directory entries until we reach the end offset.
|
||||
|
@ -550,9 +547,9 @@ xfs_dir2_leaf_getdents(
|
|||
* If we have no buffer, or we're off the end of the
|
||||
* current buffer, need to get another one.
|
||||
*/
|
||||
if (!bp || ptr >= (char *)bp->b_addr + mp->m_dirblksize) {
|
||||
if (!bp || ptr >= (char *)bp->b_addr + geo->blksize) {
|
||||
|
||||
error = xfs_dir2_leaf_readbuf(dp, bufsize, map_info,
|
||||
error = xfs_dir2_leaf_readbuf(args, bufsize, map_info,
|
||||
&curoff, &bp);
|
||||
if (error || !map_info->map_valid)
|
||||
break;
|
||||
|
@ -560,7 +557,8 @@ xfs_dir2_leaf_getdents(
|
|||
/*
|
||||
* Having done a read, we need to set a new offset.
|
||||
*/
|
||||
newoff = xfs_dir2_db_off_to_byte(mp, map_info->curdb, 0);
|
||||
newoff = xfs_dir2_db_off_to_byte(geo,
|
||||
map_info->curdb, 0);
|
||||
/*
|
||||
* Start of the current block.
|
||||
*/
|
||||
|
@ -570,7 +568,7 @@ xfs_dir2_leaf_getdents(
|
|||
* Make sure we're in the right block.
|
||||
*/
|
||||
else if (curoff > newoff)
|
||||
ASSERT(xfs_dir2_byte_to_db(mp, curoff) ==
|
||||
ASSERT(xfs_dir2_byte_to_db(geo, curoff) ==
|
||||
map_info->curdb);
|
||||
hdr = bp->b_addr;
|
||||
xfs_dir3_data_check(dp, bp);
|
||||
|
@ -578,7 +576,7 @@ xfs_dir2_leaf_getdents(
|
|||
* Find our position in the block.
|
||||
*/
|
||||
ptr = (char *)dp->d_ops->data_entry_p(hdr);
|
||||
byteoff = xfs_dir2_byte_to_off(mp, curoff);
|
||||
byteoff = xfs_dir2_byte_to_off(geo, curoff);
|
||||
/*
|
||||
* Skip past the header.
|
||||
*/
|
||||
|
@ -607,10 +605,10 @@ xfs_dir2_leaf_getdents(
|
|||
* Now set our real offset.
|
||||
*/
|
||||
curoff =
|
||||
xfs_dir2_db_off_to_byte(mp,
|
||||
xfs_dir2_byte_to_db(mp, curoff),
|
||||
xfs_dir2_db_off_to_byte(geo,
|
||||
xfs_dir2_byte_to_db(geo, curoff),
|
||||
(char *)ptr - (char *)hdr);
|
||||
if (ptr >= (char *)hdr + mp->m_dirblksize) {
|
||||
if (ptr >= (char *)hdr + geo->blksize) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -637,7 +635,7 @@ xfs_dir2_leaf_getdents(
|
|||
ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff;
|
||||
if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
|
||||
be64_to_cpu(dep->inumber),
|
||||
xfs_dir3_get_dtype(mp, filetype)))
|
||||
xfs_dir3_get_dtype(dp->i_mount, filetype)))
|
||||
break;
|
||||
|
||||
/*
|
||||
|
@ -667,12 +665,13 @@ xfs_dir2_leaf_getdents(
|
|||
*/
|
||||
int
|
||||
xfs_readdir(
|
||||
xfs_inode_t *dp,
|
||||
struct xfs_inode *dp,
|
||||
struct dir_context *ctx,
|
||||
size_t bufsize)
|
||||
{
|
||||
int rval; /* return value */
|
||||
int v; /* type-checking value */
|
||||
struct xfs_da_args args = { NULL };
|
||||
int rval;
|
||||
int v;
|
||||
uint lock_mode;
|
||||
|
||||
trace_xfs_readdir(dp);
|
||||
|
@ -683,15 +682,18 @@ xfs_readdir(
|
|||
ASSERT(S_ISDIR(dp->i_d.di_mode));
|
||||
XFS_STATS_INC(xs_dir_getdents);
|
||||
|
||||
args.dp = dp;
|
||||
args.geo = dp->i_mount->m_dir_geo;
|
||||
|
||||
lock_mode = xfs_ilock_data_map_shared(dp);
|
||||
if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
|
||||
rval = xfs_dir2_sf_getdents(dp, ctx);
|
||||
else if ((rval = xfs_dir2_isblock(dp, &v)))
|
||||
rval = xfs_dir2_sf_getdents(&args, ctx);
|
||||
else if ((rval = xfs_dir2_isblock(&args, &v)))
|
||||
;
|
||||
else if (v)
|
||||
rval = xfs_dir2_block_getdents(dp, ctx);
|
||||
rval = xfs_dir2_block_getdents(&args, ctx);
|
||||
else
|
||||
rval = xfs_dir2_leaf_getdents(dp, ctx, bufsize);
|
||||
rval = xfs_dir2_leaf_getdents(&args, ctx, bufsize);
|
||||
xfs_iunlock(dp, lock_mode);
|
||||
|
||||
return rval;
|
||||
|
|
|
@ -82,8 +82,10 @@ xfs_dir2_block_sfsize(
|
|||
xfs_ino_t parent = 0; /* parent inode number */
|
||||
int size=0; /* total computed size */
|
||||
int has_ftype;
|
||||
struct xfs_da_geometry *geo;
|
||||
|
||||
mp = dp->i_mount;
|
||||
geo = mp->m_dir_geo;
|
||||
|
||||
/*
|
||||
* if there is a filetype field, add the extra byte to the namelen
|
||||
|
@ -92,7 +94,7 @@ xfs_dir2_block_sfsize(
|
|||
has_ftype = xfs_sb_version_hasftype(&mp->m_sb) ? 1 : 0;
|
||||
|
||||
count = i8count = namelen = 0;
|
||||
btp = xfs_dir2_block_tail_p(mp, hdr);
|
||||
btp = xfs_dir2_block_tail_p(geo, hdr);
|
||||
blp = xfs_dir2_block_leaf_p(btp);
|
||||
|
||||
/*
|
||||
|
@ -104,8 +106,8 @@ xfs_dir2_block_sfsize(
|
|||
/*
|
||||
* Calculate the pointer to the entry at hand.
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)hdr + xfs_dir2_dataptr_to_off(mp, addr));
|
||||
dep = (xfs_dir2_data_entry_t *)((char *)hdr +
|
||||
xfs_dir2_dataptr_to_off(geo, addr));
|
||||
/*
|
||||
* Detect . and .., so we can special-case them.
|
||||
* . is not included in sf directories.
|
||||
|
@ -195,7 +197,7 @@ xfs_dir2_block_to_sf(
|
|||
/*
|
||||
* Set up to loop over the block's entries.
|
||||
*/
|
||||
btp = xfs_dir2_block_tail_p(mp, hdr);
|
||||
btp = xfs_dir2_block_tail_p(args->geo, hdr);
|
||||
ptr = (char *)dp->d_ops->data_entry_p(hdr);
|
||||
endptr = (char *)xfs_dir2_block_leaf_p(btp);
|
||||
sfep = xfs_dir2_sf_firstentry(sfp);
|
||||
|
@ -247,7 +249,7 @@ xfs_dir2_block_to_sf(
|
|||
|
||||
/* now we are done with the block, we can shrink the inode */
|
||||
logflags = XFS_ILOG_CORE;
|
||||
error = xfs_dir2_shrink_inode(args, mp->m_dirdatablk, bp);
|
||||
error = xfs_dir2_shrink_inode(args, args->geo->datablk, bp);
|
||||
if (error) {
|
||||
ASSERT(error != ENOSPC);
|
||||
goto out;
|
||||
|
@ -586,7 +588,7 @@ xfs_dir2_sf_addname_pick(
|
|||
* we'll go back, convert to block, then try the insert and convert
|
||||
* to leaf.
|
||||
*/
|
||||
if (used + (holefit ? 0 : size) > mp->m_dirblksize)
|
||||
if (used + (holefit ? 0 : size) > args->geo->blksize)
|
||||
return 0;
|
||||
/*
|
||||
* If changing the inode number size, do it the hard way.
|
||||
|
@ -601,7 +603,7 @@ xfs_dir2_sf_addname_pick(
|
|||
/*
|
||||
* If it won't fit at the end then do it the hard way (use the hole).
|
||||
*/
|
||||
if (used + size > mp->m_dirblksize)
|
||||
if (used + size > args->geo->blksize)
|
||||
return 2;
|
||||
/*
|
||||
* Do it the easy way.
|
||||
|
@ -652,7 +654,7 @@ xfs_dir2_sf_check(
|
|||
ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size);
|
||||
ASSERT(offset +
|
||||
(sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) +
|
||||
(uint)sizeof(xfs_dir2_block_tail_t) <= mp->m_dirblksize);
|
||||
(uint)sizeof(xfs_dir2_block_tail_t) <= args->geo->blksize);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_da_format.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_inode.h"
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_inode_item.h"
|
||||
|
@ -105,7 +107,7 @@ xfs_fs_geometry(
|
|||
geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ?
|
||||
mp->m_sb.sb_logsectsize : BBSIZE;
|
||||
geo->rtsectsize = mp->m_sb.sb_blocksize;
|
||||
geo->dirblocksize = mp->m_dirblksize;
|
||||
geo->dirblocksize = mp->m_dir_geo->blksize;
|
||||
}
|
||||
if (new_version >= 4) {
|
||||
geo->flags |=
|
||||
|
|
|
@ -42,7 +42,7 @@ xfs_log_calc_max_attrsetm_res(
|
|||
int size;
|
||||
int nblks;
|
||||
|
||||
size = xfs_attr_leaf_entsize_local_max(mp->m_sb.sb_blocksize) -
|
||||
size = xfs_attr_leaf_entsize_local_max(mp->m_attr_geo->blksize) -
|
||||
MAXNAMELEN - 1;
|
||||
nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
|
||||
nblks += XFS_B_TO_FSB(mp, size);
|
||||
|
|
|
@ -780,12 +780,11 @@ xfs_mountfs(
|
|||
|
||||
mp->m_dmevmask = 0; /* not persistent; set after each mount */
|
||||
|
||||
xfs_dir_mount(mp);
|
||||
|
||||
/*
|
||||
* Initialize the attribute manager's entries.
|
||||
*/
|
||||
mp->m_attr_magicpct = (mp->m_sb.sb_blocksize * 37) / 100;
|
||||
error = xfs_da_mount(mp);
|
||||
if (error) {
|
||||
xfs_warn(mp, "Failed dir/attr init: %d", error);
|
||||
goto out_remove_uuid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the precomputed transaction reservations values.
|
||||
|
@ -800,7 +799,7 @@ xfs_mountfs(
|
|||
error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
|
||||
if (error) {
|
||||
xfs_warn(mp, "Failed per-ag init: %d", error);
|
||||
goto out_remove_uuid;
|
||||
goto out_free_dir;
|
||||
}
|
||||
|
||||
if (!sbp->sb_logblocks) {
|
||||
|
@ -975,6 +974,8 @@ xfs_mountfs(
|
|||
xfs_wait_buftarg(mp->m_ddev_targp);
|
||||
out_free_perag:
|
||||
xfs_free_perag(mp);
|
||||
out_free_dir:
|
||||
xfs_da_unmount(mp);
|
||||
out_remove_uuid:
|
||||
xfs_uuid_unmount(mp);
|
||||
out:
|
||||
|
@ -1052,6 +1053,7 @@ xfs_unmountfs(
|
|||
"Freespace may not be correct on next mount.");
|
||||
|
||||
xfs_log_unmount(mp);
|
||||
xfs_da_unmount(mp);
|
||||
xfs_uuid_unmount(mp);
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
|
|
@ -27,6 +27,7 @@ struct xfs_nameops;
|
|||
struct xfs_ail;
|
||||
struct xfs_quotainfo;
|
||||
struct xfs_dir_ops;
|
||||
struct xfs_da_geometry;
|
||||
|
||||
#ifdef HAVE_PERCPU_SB
|
||||
|
||||
|
@ -96,6 +97,8 @@ typedef struct xfs_mount {
|
|||
uint m_readio_blocks; /* min read size blocks */
|
||||
uint m_writeio_log; /* min write size log bytes */
|
||||
uint m_writeio_blocks; /* min write size blocks */
|
||||
struct xfs_da_geometry *m_dir_geo; /* directory block geometry */
|
||||
struct xfs_da_geometry *m_attr_geo; /* attribute block geometry */
|
||||
struct xlog *m_log; /* log specific stuff */
|
||||
int m_logbufs; /* number of log buffers */
|
||||
int m_logbsize; /* size of each log buffer */
|
||||
|
@ -131,8 +134,6 @@ typedef struct xfs_mount {
|
|||
int m_fixedfsid[2]; /* unchanged for life of FS */
|
||||
uint m_dmevmask; /* DMI events for this FS */
|
||||
__uint64_t m_flags; /* global mount flags */
|
||||
uint m_dir_node_ents; /* #entries in a dir danode */
|
||||
uint m_attr_node_ents; /* #entries in attr danode */
|
||||
int m_ialloc_inos; /* inodes in inode allocation */
|
||||
int m_ialloc_blks; /* blocks in inode allocation */
|
||||
int m_inoalign_mask;/* mask sb_inoalignmt if used */
|
||||
|
@ -145,17 +146,10 @@ typedef struct xfs_mount {
|
|||
int m_dalign; /* stripe unit */
|
||||
int m_swidth; /* stripe width */
|
||||
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_sectbb_log; /* sectlog - BBSHIFT */
|
||||
const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */
|
||||
const struct xfs_dir_ops *m_dir_inode_ops; /* vector of dir inode ops */
|
||||
const struct xfs_dir_ops *m_nondir_inode_ops; /* !dir inode 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 */
|
||||
xfs_dablk_t m_dirleafblk; /* blockno of dir non-data v2 */
|
||||
xfs_dablk_t m_dirfreeblk; /* blockno of dirfreeindex v2 */
|
||||
uint m_chsize; /* size of next field */
|
||||
atomic_t m_active_trans; /* number trans frozen */
|
||||
#ifdef HAVE_PERCPU_SB
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "xfs_ag.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_da_format.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_inode.h"
|
||||
#include "xfs_ialloc.h"
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "xfs_ag.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_da_format.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_inode.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_ialloc.h"
|
||||
|
@ -609,7 +610,7 @@ xfs_calc_addafork_reservation(
|
|||
return XFS_DQUOT_LOGRES(mp) +
|
||||
xfs_calc_inode_res(mp, 1) +
|
||||
xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
|
||||
xfs_calc_buf_res(1, mp->m_dirblksize) +
|
||||
xfs_calc_buf_res(1, mp->m_dir_geo->blksize) +
|
||||
xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1,
|
||||
XFS_FSB_TO_B(mp, 1)) +
|
||||
xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
(((b + XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp) - 1) / \
|
||||
XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp)) * \
|
||||
XFS_EXTENTADD_SPACE_RES(mp,w))
|
||||
#define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1)
|
||||
#define XFS_DAENTER_1B(mp,w) \
|
||||
((w) == XFS_DATA_FORK ? (mp)->m_dir_geo->fsbcount : 1)
|
||||
#define XFS_DAENTER_DBS(mp,w) \
|
||||
(XFS_DA_NODE_MAXDEPTH + (((w) == XFS_DATA_FORK) ? 2 : 0))
|
||||
#define XFS_DAENTER_BLOCKS(mp,w) \
|
||||
|
@ -55,7 +56,7 @@
|
|||
* Space reservation values for various transactions.
|
||||
*/
|
||||
#define XFS_ADDAFORK_SPACE_RES(mp) \
|
||||
((mp)->m_dirblkfsbs + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK))
|
||||
((mp)->m_dir_geo->fsbcount + 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 */
|
||||
|
|
Загрузка…
Ссылка в новой задаче