Loading fs/xfs/xfs_attr.c +4 −13 Original line number Original line Diff line number Diff line Loading @@ -88,6 +88,7 @@ xfs_attr_args_init( return EINVAL; return EINVAL; memset(args, 0, sizeof(*args)); memset(args, 0, sizeof(*args)); args->geo = dp->i_mount->m_attr_geo; args->whichfork = XFS_ATTR_FORK; args->whichfork = XFS_ATTR_FORK; args->dp = dp; args->dp = dp; args->flags = flags; args->flags = flags; Loading Loading @@ -173,12 +174,10 @@ xfs_attr_calc_size( * Determine space new attribute will use, and if it would be * Determine space new attribute will use, and if it would be * "local" or "remote" (note: local != inline). * "local" or "remote" (note: local != inline). */ */ size = xfs_attr_leaf_newentsize(args->namelen, args->valuelen, size = xfs_attr_leaf_newentsize(args, local); mp->m_sb.sb_blocksize, local); nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); if (*local) { if (*local) { if (size > (mp->m_sb.sb_blocksize >> 1)) { if (size > (args->geo->blksize / 2)) { /* Double split possible */ /* Double split possible */ nblks *= 2; nblks *= 2; } } Loading Loading @@ -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 *========================================================================*/ *========================================================================*/ /* /* Loading Loading @@ -897,8 +896,6 @@ restart: state = xfs_da_state_alloc(); state = xfs_da_state_alloc(); state->args = args; state->args = args; state->mp = mp; 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 * Search to see if name already exists, and get back a pointer Loading Loading @@ -1076,8 +1073,6 @@ restart: state = xfs_da_state_alloc(); state = xfs_da_state_alloc(); state->args = args; state->args = args; state->mp = mp; state->mp = mp; state->blocksize = state->mp->m_sb.sb_blocksize; state->node_ents = state->mp->m_attr_node_ents; state->inleaf = 0; state->inleaf = 0; error = xfs_da3_node_lookup_int(state, &retval); error = xfs_da3_node_lookup_int(state, &retval); if (error) if (error) Loading Loading @@ -1168,8 +1163,6 @@ xfs_attr_node_removename(xfs_da_args_t *args) state = xfs_da_state_alloc(); state = xfs_da_state_alloc(); state->args = args; state->args = args; state->mp = dp->i_mount; 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. * Search to see if name exists, and get back a pointer to it. Loading Loading @@ -1431,8 +1424,6 @@ xfs_attr_node_get(xfs_da_args_t *args) state = xfs_da_state_alloc(); state = xfs_da_state_alloc(); state->args = args; state->args = args; state->mp = args->dp->i_mount; 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. * Search to see if name exists, and get back a pointer to it. Loading fs/xfs/xfs_attr_leaf.c +89 −95 Original line number Original line Diff line number Diff line Loading @@ -80,11 +80,12 @@ STATIC int xfs_attr3_leaf_figure_balance(xfs_da_state_t *state, /* /* * Utility routines. * 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_attr3_icleaf_hdr *src_ichdr, int src_start, struct xfs_attr_leafblock *dst_leaf, struct xfs_attr_leafblock *dst_leaf, struct xfs_attr3_icleaf_hdr *dst_ichdr, int dst_start, 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); STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); void void Loading Loading @@ -711,6 +712,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) memset((char *)&nargs, 0, sizeof(nargs)); memset((char *)&nargs, 0, sizeof(nargs)); nargs.dp = dp; nargs.dp = dp; nargs.geo = args->geo; nargs.firstblock = args->firstblock; nargs.firstblock = args->firstblock; nargs.flist = args->flist; nargs.flist = args->flist; nargs.total = args->total; nargs.total = args->total; Loading Loading @@ -805,18 +807,18 @@ xfs_attr3_leaf_to_shortform( trace_xfs_attr_leaf_to_sf(args); 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) if (!tmpbuffer) return ENOMEM; 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; leaf = (xfs_attr_leafblock_t *)tmpbuffer; xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); entry = xfs_attr3_leaf_entryp(leaf); entry = xfs_attr3_leaf_entryp(leaf); /* XXX (dgc): buffer is about to be marked stale - why zero it? */ /* 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. * Clean out the prior contents of the attribute list. Loading @@ -838,6 +840,7 @@ xfs_attr3_leaf_to_shortform( * Copy the attributes * Copy the attributes */ */ memset((char *)&nargs, 0, sizeof(nargs)); memset((char *)&nargs, 0, sizeof(nargs)); nargs.geo = args->geo; nargs.dp = dp; nargs.dp = dp; nargs.firstblock = args->firstblock; nargs.firstblock = args->firstblock; nargs.flist = args->flist; nargs.flist = args->flist; Loading Loading @@ -904,12 +907,12 @@ xfs_attr3_leaf_to_node( /* copy leaf to new buffer, update identifiers */ /* copy leaf to new buffer, update identifiers */ xfs_trans_buf_set_type(args->trans, bp2, XFS_BLFT_ATTR_LEAF_BUF); xfs_trans_buf_set_type(args->trans, bp2, XFS_BLFT_ATTR_LEAF_BUF); bp2->b_ops = bp1->b_ops; 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)) { if (xfs_sb_version_hascrc(&mp->m_sb)) { struct xfs_da3_blkinfo *hdr3 = bp2->b_addr; struct xfs_da3_blkinfo *hdr3 = bp2->b_addr; hdr3->blkno = cpu_to_be64(bp2->b_bn); 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. * Set up the new root node. Loading @@ -930,7 +933,7 @@ xfs_attr3_leaf_to_node( btree[0].before = cpu_to_be32(blkno); btree[0].before = cpu_to_be32(blkno); icnodehdr.count = 1; icnodehdr.count = 1; dp->d_ops->node_hdr_to_disk(node, &icnodehdr); 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; error = 0; out: out: return error; return error; Loading Loading @@ -966,10 +969,10 @@ xfs_attr3_leaf_create( bp->b_ops = &xfs_attr3_leaf_buf_ops; bp->b_ops = &xfs_attr3_leaf_buf_ops; xfs_trans_buf_set_type(args->trans, bp, XFS_BLFT_ATTR_LEAF_BUF); xfs_trans_buf_set_type(args->trans, bp, XFS_BLFT_ATTR_LEAF_BUF); leaf = bp->b_addr; leaf = bp->b_addr; memset(leaf, 0, XFS_LBSIZE(mp)); memset(leaf, 0, args->geo->blksize); memset(&ichdr, 0, sizeof(ichdr)); memset(&ichdr, 0, sizeof(ichdr)); ichdr.firstused = XFS_LBSIZE(mp); ichdr.firstused = args->geo->blksize; if (xfs_sb_version_hascrc(&mp->m_sb)) { if (xfs_sb_version_hascrc(&mp->m_sb)) { struct xfs_da3_blkinfo *hdr3 = bp->b_addr; struct xfs_da3_blkinfo *hdr3 = bp->b_addr; Loading @@ -988,7 +991,7 @@ xfs_attr3_leaf_create( ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base; ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base; xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr); 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; *bpp = bp; return 0; return 0; Loading Loading @@ -1074,8 +1077,7 @@ xfs_attr3_leaf_add( leaf = bp->b_addr; leaf = bp->b_addr; xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); ASSERT(args->index >= 0 && args->index <= ichdr.count); ASSERT(args->index >= 0 && args->index <= ichdr.count); entsize = xfs_attr_leaf_newentsize(args->namelen, args->valuelen, entsize = xfs_attr_leaf_newentsize(args, NULL); args->trans->t_mountp->m_sb.sb_blocksize, NULL); /* /* * Search through freemap for first-fit on new name length. * Search through freemap for first-fit on new name length. Loading Loading @@ -1174,17 +1176,14 @@ xfs_attr3_leaf_add_work( * Allocate space for the new string (at the end of the run). * Allocate space for the new string (at the end of the run). */ */ mp = args->trans->t_mountp; 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].base & 0x3) == 0); ASSERT(ichdr->freemap[mapindex].size >= ASSERT(ichdr->freemap[mapindex].size >= xfs_attr_leaf_newentsize(args->namelen, args->valuelen, xfs_attr_leaf_newentsize(args, NULL)); mp->m_sb.sb_blocksize, NULL)); ASSERT(ichdr->freemap[mapindex].size < args->geo->blksize); ASSERT(ichdr->freemap[mapindex].size < XFS_LBSIZE(mp)); ASSERT((ichdr->freemap[mapindex].size & 0x3) == 0); ASSERT((ichdr->freemap[mapindex].size & 0x3) == 0); ichdr->freemap[mapindex].size -= ichdr->freemap[mapindex].size -= xfs_attr_leaf_newentsize(args, &tmp); xfs_attr_leaf_newentsize(args->namelen, args->valuelen, mp->m_sb.sb_blocksize, &tmp); entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base + entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base + ichdr->freemap[mapindex].size); ichdr->freemap[mapindex].size); Loading Loading @@ -1269,14 +1268,13 @@ xfs_attr3_leaf_compact( struct xfs_attr_leafblock *leaf_dst; struct xfs_attr_leafblock *leaf_dst; struct xfs_attr3_icleaf_hdr ichdr_src; struct xfs_attr3_icleaf_hdr ichdr_src; struct xfs_trans *trans = args->trans; struct xfs_trans *trans = args->trans; struct xfs_mount *mp = trans->t_mountp; char *tmpbuffer; char *tmpbuffer; trace_xfs_attr_leaf_compact(args); trace_xfs_attr_leaf_compact(args); tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP); tmpbuffer = kmem_alloc(args->geo->blksize, KM_SLEEP); memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(mp)); memcpy(tmpbuffer, bp->b_addr, args->geo->blksize); memset(bp->b_addr, 0, XFS_LBSIZE(mp)); memset(bp->b_addr, 0, args->geo->blksize); leaf_src = (xfs_attr_leafblock_t *)tmpbuffer; leaf_src = (xfs_attr_leafblock_t *)tmpbuffer; leaf_dst = bp->b_addr; leaf_dst = bp->b_addr; Loading @@ -1289,7 +1287,7 @@ xfs_attr3_leaf_compact( /* Initialise the incore headers */ /* Initialise the incore headers */ ichdr_src = *ichdr_dst; /* struct copy */ ichdr_src = *ichdr_dst; /* struct copy */ ichdr_dst->firstused = XFS_LBSIZE(mp); ichdr_dst->firstused = args->geo->blksize; ichdr_dst->usedbytes = 0; ichdr_dst->usedbytes = 0; ichdr_dst->count = 0; ichdr_dst->count = 0; ichdr_dst->holes = 0; ichdr_dst->holes = 0; Loading @@ -1304,13 +1302,13 @@ xfs_attr3_leaf_compact( * Copy all entry's in the same (sorted) order, * Copy all entry's in the same (sorted) order, * but allocate name/value pairs packed and in sequence. * but allocate name/value pairs packed and in sequence. */ */ xfs_attr3_leaf_moveents(leaf_src, &ichdr_src, 0, leaf_dst, ichdr_dst, 0, xfs_attr3_leaf_moveents(args, leaf_src, &ichdr_src, 0, ichdr_src.count, mp); leaf_dst, ichdr_dst, 0, ichdr_src.count); /* /* * this logs the entire buffer, but the caller must write the header * this logs the entire buffer, but the caller must write the header * back to the buffer when it is finished modifying it. * 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); kmem_free(tmpbuffer); } } Loading Loading @@ -1461,8 +1459,8 @@ xfs_attr3_leaf_rebalance( /* /* * Move high entries from leaf1 to low end of leaf2. * Move high entries from leaf1 to low end of leaf2. */ */ xfs_attr3_leaf_moveents(leaf1, &ichdr1, ichdr1.count - count, xfs_attr3_leaf_moveents(args, leaf1, &ichdr1, leaf2, &ichdr2, 0, count, state->mp); ichdr1.count - count, leaf2, &ichdr2, 0, count); } else if (count > ichdr1.count) { } else if (count > ichdr1.count) { /* /* Loading Loading @@ -1490,14 +1488,14 @@ xfs_attr3_leaf_rebalance( /* /* * Move low entries from leaf2 to high end of leaf1. * Move low entries from leaf2 to high end of leaf1. */ */ xfs_attr3_leaf_moveents(leaf2, &ichdr2, 0, leaf1, &ichdr1, xfs_attr3_leaf_moveents(args, leaf2, &ichdr2, 0, leaf1, &ichdr1, ichdr1.count, count, state->mp); ichdr1.count, count); } } xfs_attr3_leaf_hdr_to_disk(leaf1, &ichdr1); xfs_attr3_leaf_hdr_to_disk(leaf1, &ichdr1); xfs_attr3_leaf_hdr_to_disk(leaf2, &ichdr2); 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, blk1->bp, 0, args->geo->blksize - 1); xfs_trans_log_buf(args->trans, blk2->bp, 0, state->blocksize-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. * Copy out last hashval in each block for B-tree code. Loading Loading @@ -1592,11 +1590,9 @@ xfs_attr3_leaf_figure_balance( max = ichdr1->count + ichdr2->count; max = ichdr1->count + ichdr2->count; half = (max + 1) * sizeof(*entry); half = (max + 1) * sizeof(*entry); half += ichdr1->usedbytes + ichdr2->usedbytes + half += ichdr1->usedbytes + ichdr2->usedbytes + xfs_attr_leaf_newentsize(state->args->namelen, xfs_attr_leaf_newentsize(state->args, NULL); state->args->valuelen, state->blocksize, NULL); half /= 2; half /= 2; lastdelta = state->blocksize; lastdelta = state->args->geo->blksize; entry = xfs_attr3_leaf_entryp(leaf1); entry = xfs_attr3_leaf_entryp(leaf1); for (count = index = 0; count < max; entry++, index++, count++) { for (count = index = 0; count < max; entry++, index++, count++) { Loading @@ -1606,10 +1602,7 @@ xfs_attr3_leaf_figure_balance( */ */ if (count == blk1->index) { if (count == blk1->index) { tmp = totallen + sizeof(*entry) + tmp = totallen + sizeof(*entry) + xfs_attr_leaf_newentsize( xfs_attr_leaf_newentsize(state->args, NULL); state->args->namelen, state->args->valuelen, state->blocksize, NULL); if (XFS_ATTR_ABS(half - tmp) > lastdelta) if (XFS_ATTR_ABS(half - tmp) > lastdelta) break; break; lastdelta = XFS_ATTR_ABS(half - tmp); lastdelta = XFS_ATTR_ABS(half - tmp); Loading Loading @@ -1645,10 +1638,7 @@ xfs_attr3_leaf_figure_balance( totallen -= count * sizeof(*entry); totallen -= count * sizeof(*entry); if (foundit) { if (foundit) { totallen -= sizeof(*entry) + totallen -= sizeof(*entry) + xfs_attr_leaf_newentsize( xfs_attr_leaf_newentsize(state->args, NULL); state->args->namelen, state->args->valuelen, state->blocksize, NULL); } } *countarg = count; *countarg = count; Loading Loading @@ -1700,7 +1690,7 @@ xfs_attr3_leaf_toosmall( bytes = xfs_attr3_leaf_hdr_size(leaf) + bytes = xfs_attr3_leaf_hdr_size(leaf) + ichdr.count * sizeof(xfs_attr_leaf_entry_t) + ichdr.count * sizeof(xfs_attr_leaf_entry_t) + ichdr.usedbytes; ichdr.usedbytes; if (bytes > (state->blocksize >> 1)) { if (bytes > (state->args->geo->blksize >> 1)) { *action = 0; /* blk over 50%, don't try to join */ *action = 0; /* blk over 50%, don't try to join */ return(0); return(0); } } Loading Loading @@ -1754,7 +1744,8 @@ xfs_attr3_leaf_toosmall( xfs_attr3_leaf_hdr_from_disk(&ichdr2, bp->b_addr); 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.usedbytes - ichdr2.usedbytes - ((ichdr.count + ichdr2.count) * ((ichdr.count + ichdr2.count) * sizeof(xfs_attr_leaf_entry_t)) - sizeof(xfs_attr_leaf_entry_t)) - Loading Loading @@ -1805,7 +1796,6 @@ xfs_attr3_leaf_remove( struct xfs_attr_leafblock *leaf; struct xfs_attr_leafblock *leaf; struct xfs_attr3_icleaf_hdr ichdr; struct xfs_attr3_icleaf_hdr ichdr; struct xfs_attr_leaf_entry *entry; struct xfs_attr_leaf_entry *entry; struct xfs_mount *mp = args->trans->t_mountp; int before; int before; int after; int after; int smallest; int smallest; Loading @@ -1819,7 +1809,7 @@ xfs_attr3_leaf_remove( leaf = bp->b_addr; leaf = bp->b_addr; xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); 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(args->index >= 0 && args->index < ichdr.count); ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) + ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) + xfs_attr3_leaf_hdr_size(leaf)); xfs_attr3_leaf_hdr_size(leaf)); Loading @@ -1827,7 +1817,7 @@ xfs_attr3_leaf_remove( entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused); 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: * Scan through free region table: Loading @@ -1842,8 +1832,8 @@ xfs_attr3_leaf_remove( smallest = XFS_ATTR_LEAF_MAPSIZE - 1; smallest = XFS_ATTR_LEAF_MAPSIZE - 1; entsize = xfs_attr_leaf_entsize(leaf, args->index); entsize = xfs_attr_leaf_entsize(leaf, args->index); for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { ASSERT(ichdr.freemap[i].base < XFS_LBSIZE(mp)); ASSERT(ichdr.freemap[i].base < args->geo->blksize); ASSERT(ichdr.freemap[i].size < XFS_LBSIZE(mp)); ASSERT(ichdr.freemap[i].size < args->geo->blksize); if (ichdr.freemap[i].base == tablesize) { if (ichdr.freemap[i].base == tablesize) { ichdr.freemap[i].base -= sizeof(xfs_attr_leaf_entry_t); ichdr.freemap[i].base -= sizeof(xfs_attr_leaf_entry_t); ichdr.freemap[i].size += sizeof(xfs_attr_leaf_entry_t); ichdr.freemap[i].size += sizeof(xfs_attr_leaf_entry_t); Loading Loading @@ -1920,11 +1910,11 @@ xfs_attr3_leaf_remove( * removing the name. * removing the name. */ */ if (smallest) { if (smallest) { tmp = XFS_LBSIZE(mp); tmp = args->geo->blksize; entry = xfs_attr3_leaf_entryp(leaf); entry = xfs_attr3_leaf_entryp(leaf); for (i = ichdr.count - 1; i >= 0; entry++, i--) { for (i = ichdr.count - 1; i >= 0; entry++, i--) { ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused); 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) if (be16_to_cpu(entry->nameidx) < tmp) tmp = be16_to_cpu(entry->nameidx); tmp = be16_to_cpu(entry->nameidx); Loading @@ -1947,7 +1937,7 @@ xfs_attr3_leaf_remove( tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) + tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) + ichdr.count * sizeof(xfs_attr_leaf_entry_t); 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 */ } } /* /* Loading @@ -1964,7 +1954,6 @@ xfs_attr3_leaf_unbalance( struct xfs_attr3_icleaf_hdr drophdr; struct xfs_attr3_icleaf_hdr drophdr; struct xfs_attr3_icleaf_hdr savehdr; struct xfs_attr3_icleaf_hdr savehdr; struct xfs_attr_leaf_entry *entry; struct xfs_attr_leaf_entry *entry; struct xfs_mount *mp = state->mp; trace_xfs_attr_leaf_unbalance(state->args); trace_xfs_attr_leaf_unbalance(state->args); Loading @@ -1991,13 +1980,15 @@ xfs_attr3_leaf_unbalance( */ */ if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, drop_blk->bp, &drophdr)) { 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, save_leaf, &savehdr, 0, drophdr.count, mp); drophdr.count); } else { } else { xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, xfs_attr3_leaf_moveents(state->args, drop_leaf, &drophdr, 0, save_leaf, &savehdr, save_leaf, &savehdr, savehdr.count, drophdr.count, mp); savehdr.count, drophdr.count); } } } else { } else { /* /* Loading @@ -2007,7 +1998,7 @@ xfs_attr3_leaf_unbalance( struct xfs_attr_leafblock *tmp_leaf; struct xfs_attr_leafblock *tmp_leaf; struct xfs_attr3_icleaf_hdr tmphdr; 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 * Copy the header into the temp leaf so that all the stuff Loading @@ -2020,35 +2011,39 @@ xfs_attr3_leaf_unbalance( tmphdr.magic = savehdr.magic; tmphdr.magic = savehdr.magic; tmphdr.forw = savehdr.forw; tmphdr.forw = savehdr.forw; tmphdr.back = savehdr.back; tmphdr.back = savehdr.back; tmphdr.firstused = state->blocksize; tmphdr.firstused = state->args->geo->blksize; /* write the header to the temp buffer to initialise it */ /* write the header to the temp buffer to initialise it */ xfs_attr3_leaf_hdr_to_disk(tmp_leaf, &tmphdr); xfs_attr3_leaf_hdr_to_disk(tmp_leaf, &tmphdr); if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, drop_blk->bp, &drophdr)) { 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, tmp_leaf, &tmphdr, 0, drophdr.count, mp); drophdr.count); xfs_attr3_leaf_moveents(save_leaf, &savehdr, 0, xfs_attr3_leaf_moveents(state->args, save_leaf, &savehdr, 0, tmp_leaf, &tmphdr, tmphdr.count, tmp_leaf, &tmphdr, tmphdr.count, savehdr.count, mp); savehdr.count); } else { } else { xfs_attr3_leaf_moveents(save_leaf, &savehdr, 0, xfs_attr3_leaf_moveents(state->args, save_leaf, &savehdr, 0, tmp_leaf, &tmphdr, 0, tmp_leaf, &tmphdr, 0, savehdr.count, mp); savehdr.count); xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, xfs_attr3_leaf_moveents(state->args, drop_leaf, &drophdr, 0, tmp_leaf, &tmphdr, tmphdr.count, 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 */ savehdr = tmphdr; /* struct copy */ kmem_free(tmp_leaf); kmem_free(tmp_leaf); } } xfs_attr3_leaf_hdr_to_disk(save_leaf, &savehdr); xfs_attr3_leaf_hdr_to_disk(save_leaf, &savehdr); xfs_trans_log_buf(state->args->trans, save_blk->bp, 0, 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. * Copy out last hashval in each block for B-tree code. Loading Loading @@ -2094,7 +2089,7 @@ xfs_attr3_leaf_lookup_int( leaf = bp->b_addr; leaf = bp->b_addr; xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); entries = xfs_attr3_leaf_entryp(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) * Binary search. (note: small blocks will skip this loop) Loading Loading @@ -2198,7 +2193,7 @@ xfs_attr3_leaf_getvalue( leaf = bp->b_addr; leaf = bp->b_addr; xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); 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); ASSERT(args->index < ichdr.count); entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; Loading Loading @@ -2249,14 +2244,14 @@ xfs_attr3_leaf_getvalue( /*ARGSUSED*/ /*ARGSUSED*/ STATIC void STATIC void xfs_attr3_leaf_moveents( xfs_attr3_leaf_moveents( struct xfs_da_args *args, struct xfs_attr_leafblock *leaf_s, struct xfs_attr_leafblock *leaf_s, struct xfs_attr3_icleaf_hdr *ichdr_s, struct xfs_attr3_icleaf_hdr *ichdr_s, int start_s, int start_s, struct xfs_attr_leafblock *leaf_d, struct xfs_attr_leafblock *leaf_d, struct xfs_attr3_icleaf_hdr *ichdr_d, struct xfs_attr3_icleaf_hdr *ichdr_d, int start_d, int start_d, int count, int count) struct xfs_mount *mp) { { struct xfs_attr_leaf_entry *entry_s; struct xfs_attr_leaf_entry *entry_s; struct xfs_attr_leaf_entry *entry_d; struct xfs_attr_leaf_entry *entry_d; Loading @@ -2276,10 +2271,10 @@ xfs_attr3_leaf_moveents( ASSERT(ichdr_s->magic == XFS_ATTR_LEAF_MAGIC || ASSERT(ichdr_s->magic == XFS_ATTR_LEAF_MAGIC || ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC); ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC); ASSERT(ichdr_s->magic == ichdr_d->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)) ASSERT(ichdr_s->firstused >= (ichdr_s->count * sizeof(*entry_s)) + xfs_attr3_leaf_hdr_size(leaf_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)) ASSERT(ichdr_d->firstused >= (ichdr_d->count * sizeof(*entry_d)) + xfs_attr3_leaf_hdr_size(leaf_d)); + xfs_attr3_leaf_hdr_size(leaf_d)); Loading Loading @@ -2331,11 +2326,11 @@ xfs_attr3_leaf_moveents( entry_d->nameidx = cpu_to_be16(ichdr_d->firstused); entry_d->nameidx = cpu_to_be16(ichdr_d->firstused); entry_d->flags = entry_s->flags; entry_d->flags = entry_s->flags; ASSERT(be16_to_cpu(entry_d->nameidx) + tmp ASSERT(be16_to_cpu(entry_d->nameidx) + tmp <= XFS_LBSIZE(mp)); <= args->geo->blksize); memmove(xfs_attr3_leaf_name(leaf_d, desti), memmove(xfs_attr3_leaf_name(leaf_d, desti), xfs_attr3_leaf_name(leaf_s, start_s + i), tmp); xfs_attr3_leaf_name(leaf_s, start_s + i), tmp); ASSERT(be16_to_cpu(entry_s->nameidx) + 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); memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp); ichdr_s->usedbytes -= tmp; ichdr_s->usedbytes -= tmp; ichdr_d->usedbytes += tmp; ichdr_d->usedbytes += tmp; Loading @@ -2356,7 +2351,7 @@ xfs_attr3_leaf_moveents( tmp = count * sizeof(xfs_attr_leaf_entry_t); tmp = count * sizeof(xfs_attr_leaf_entry_t); entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s]; entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s]; ASSERT(((char *)entry_s + tmp) <= ASSERT(((char *)entry_s + tmp) <= ((char *)leaf_s + XFS_LBSIZE(mp))); ((char *)leaf_s + args->geo->blksize)); memset(entry_s, 0, tmp); memset(entry_s, 0, tmp); } else { } else { /* /* Loading @@ -2371,7 +2366,7 @@ xfs_attr3_leaf_moveents( tmp = count * sizeof(xfs_attr_leaf_entry_t); tmp = count * sizeof(xfs_attr_leaf_entry_t); entry_s = &xfs_attr3_leaf_entryp(leaf_s)[ichdr_s->count]; entry_s = &xfs_attr3_leaf_entryp(leaf_s)[ichdr_s->count]; ASSERT(((char *)entry_s + tmp) <= ASSERT(((char *)entry_s + tmp) <= ((char *)leaf_s + XFS_LBSIZE(mp))); ((char *)leaf_s + args->geo->blksize)); memset(entry_s, 0, tmp); memset(entry_s, 0, tmp); } } Loading Loading @@ -2439,22 +2434,21 @@ xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index) * a "local" or a "remote" attribute. * a "local" or a "remote" attribute. */ */ int 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; int size; size = xfs_attr_leaf_entsize_local(namelen, valuelen); size = xfs_attr_leaf_entsize_local(args->namelen, args->valuelen); if (size < xfs_attr_leaf_entsize_local_max(blocksize)) { if (size < xfs_attr_leaf_entsize_local_max(args->geo->blksize)) { if (local) { if (local) *local = 1; *local = 1; return size; } } } else { if (local) size = xfs_attr_leaf_entsize_remote(namelen); if (local) { *local = 0; *local = 0; } return xfs_attr_leaf_entsize_remote(args->namelen); } return size; } } Loading fs/xfs/xfs_attr_leaf.h +1 −2 Original line number Original line Diff line number Diff line Loading @@ -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); xfs_dahash_t xfs_attr_leaf_lasthash(struct xfs_buf *bp, int *count); int xfs_attr_leaf_order(struct xfs_buf *leaf1_bp, int xfs_attr_leaf_order(struct xfs_buf *leaf1_bp, struct xfs_buf *leaf2_bp); struct xfs_buf *leaf2_bp); int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int xfs_attr_leaf_newentsize(struct xfs_da_args *args, int *local); int *local); int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, xfs_dablk_t bno, xfs_daddr_t mappedbno, xfs_dablk_t bno, xfs_daddr_t mappedbno, struct xfs_buf **bpp); struct xfs_buf **bpp); Loading fs/xfs/xfs_attr_list.c +1 −0 Original line number Original line Diff line number Diff line Loading @@ -444,6 +444,7 @@ xfs_attr3_leaf_list_int( xfs_da_args_t args; xfs_da_args_t args; memset((char *)&args, 0, sizeof(args)); memset((char *)&args, 0, sizeof(args)); args.geo = context->dp->i_mount->m_attr_geo; args.dp = context->dp; args.dp = context->dp; args.whichfork = XFS_ATTR_FORK; args.whichfork = XFS_ATTR_FORK; args.valuelen = valuelen; args.valuelen = valuelen; Loading fs/xfs/xfs_attr_remote.c +29 −26 Original line number Original line Diff line number Diff line Loading @@ -125,6 +125,7 @@ xfs_attr3_rmt_read_verify( char *ptr; char *ptr; int len; int len; xfs_daddr_t bno; xfs_daddr_t bno; int blksize = mp->m_attr_geo->blksize; /* no verification of non-crc buffers */ /* no verification of non-crc buffers */ if (!xfs_sb_version_hascrc(&mp->m_sb)) if (!xfs_sb_version_hascrc(&mp->m_sb)) Loading @@ -133,21 +134,20 @@ xfs_attr3_rmt_read_verify( ptr = bp->b_addr; ptr = bp->b_addr; bno = bp->b_bn; bno = bp->b_bn; len = BBTOB(bp->b_length); len = BBTOB(bp->b_length); ASSERT(len >= XFS_LBSIZE(mp)); ASSERT(len >= blksize); while (len > 0) { while (len > 0) { if (!xfs_verify_cksum(ptr, XFS_LBSIZE(mp), if (!xfs_verify_cksum(ptr, blksize, XFS_ATTR3_RMT_CRC_OFF)) { XFS_ATTR3_RMT_CRC_OFF)) { xfs_buf_ioerror(bp, EFSBADCRC); xfs_buf_ioerror(bp, EFSBADCRC); break; 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); xfs_buf_ioerror(bp, EFSCORRUPTED); break; break; } } len -= XFS_LBSIZE(mp); len -= blksize; ptr += XFS_LBSIZE(mp); ptr += blksize; bno += mp->m_bsize; bno += BTOBB(blksize); } } if (bp->b_error) if (bp->b_error) Loading @@ -165,6 +165,7 @@ xfs_attr3_rmt_write_verify( char *ptr; char *ptr; int len; int len; xfs_daddr_t bno; xfs_daddr_t bno; int blksize = mp->m_attr_geo->blksize; /* no verification of non-crc buffers */ /* no verification of non-crc buffers */ if (!xfs_sb_version_hascrc(&mp->m_sb)) if (!xfs_sb_version_hascrc(&mp->m_sb)) Loading @@ -173,10 +174,10 @@ xfs_attr3_rmt_write_verify( ptr = bp->b_addr; ptr = bp->b_addr; bno = bp->b_bn; bno = bp->b_bn; len = BBTOB(bp->b_length); len = BBTOB(bp->b_length); ASSERT(len >= XFS_LBSIZE(mp)); ASSERT(len >= blksize); while (len > 0) { 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_buf_ioerror(bp, EFSCORRUPTED); xfs_verifier_error(bp); xfs_verifier_error(bp); return; return; Loading @@ -187,11 +188,11 @@ xfs_attr3_rmt_write_verify( rmt = (struct xfs_attr3_rmt_hdr *)ptr; rmt = (struct xfs_attr3_rmt_hdr *)ptr; rmt->rm_lsn = cpu_to_be64(bip->bli_item.li_lsn); 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); len -= blksize; ptr += XFS_LBSIZE(mp); ptr += blksize; bno += mp->m_bsize; bno += BTOBB(blksize); } } ASSERT(len == 0); ASSERT(len == 0); } } Loading Loading @@ -240,12 +241,13 @@ xfs_attr_rmtval_copyout( char *src = bp->b_addr; char *src = bp->b_addr; xfs_daddr_t bno = bp->b_bn; xfs_daddr_t bno = bp->b_bn; int len = BBTOB(bp->b_length); 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) { while (len > 0 && *valuelen > 0) { int hdr_size = 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); byte_cnt = min(*valuelen, byte_cnt); Loading @@ -263,9 +265,9 @@ xfs_attr_rmtval_copyout( memcpy(*dst, src + hdr_size, byte_cnt); memcpy(*dst, src + hdr_size, byte_cnt); /* roll buffer forwards */ /* roll buffer forwards */ len -= XFS_LBSIZE(mp); len -= blksize; src += XFS_LBSIZE(mp); src += blksize; bno += mp->m_bsize; bno += BTOBB(blksize); /* roll attribute data forwards */ /* roll attribute data forwards */ *valuelen -= byte_cnt; *valuelen -= byte_cnt; Loading @@ -287,12 +289,13 @@ xfs_attr_rmtval_copyin( char *dst = bp->b_addr; char *dst = bp->b_addr; xfs_daddr_t bno = bp->b_bn; xfs_daddr_t bno = bp->b_bn; int len = BBTOB(bp->b_length); 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) { while (len > 0 && *valuelen > 0) { int hdr_size; 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); byte_cnt = min(*valuelen, byte_cnt); hdr_size = xfs_attr3_rmt_hdr_set(mp, dst, ino, *offset, hdr_size = xfs_attr3_rmt_hdr_set(mp, dst, ino, *offset, Loading @@ -304,17 +307,17 @@ xfs_attr_rmtval_copyin( * If this is the last block, zero the remainder of it. * If this is the last block, zero the remainder of it. * Check that we are actually the last block, too. * 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(*valuelen - byte_cnt == 0); ASSERT(len == XFS_LBSIZE(mp)); ASSERT(len == blksize); memset(dst + hdr_size + byte_cnt, 0, memset(dst + hdr_size + byte_cnt, 0, XFS_LBSIZE(mp) - hdr_size - byte_cnt); blksize - hdr_size - byte_cnt); } } /* roll buffer forwards */ /* roll buffer forwards */ len -= XFS_LBSIZE(mp); len -= blksize; dst += XFS_LBSIZE(mp); dst += blksize; bno += mp->m_bsize; bno += BTOBB(blksize); /* roll attribute data forwards */ /* roll attribute data forwards */ *valuelen -= byte_cnt; *valuelen -= byte_cnt; Loading Loading
fs/xfs/xfs_attr.c +4 −13 Original line number Original line Diff line number Diff line Loading @@ -88,6 +88,7 @@ xfs_attr_args_init( return EINVAL; return EINVAL; memset(args, 0, sizeof(*args)); memset(args, 0, sizeof(*args)); args->geo = dp->i_mount->m_attr_geo; args->whichfork = XFS_ATTR_FORK; args->whichfork = XFS_ATTR_FORK; args->dp = dp; args->dp = dp; args->flags = flags; args->flags = flags; Loading Loading @@ -173,12 +174,10 @@ xfs_attr_calc_size( * Determine space new attribute will use, and if it would be * Determine space new attribute will use, and if it would be * "local" or "remote" (note: local != inline). * "local" or "remote" (note: local != inline). */ */ size = xfs_attr_leaf_newentsize(args->namelen, args->valuelen, size = xfs_attr_leaf_newentsize(args, local); mp->m_sb.sb_blocksize, local); nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); if (*local) { if (*local) { if (size > (mp->m_sb.sb_blocksize >> 1)) { if (size > (args->geo->blksize / 2)) { /* Double split possible */ /* Double split possible */ nblks *= 2; nblks *= 2; } } Loading Loading @@ -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 *========================================================================*/ *========================================================================*/ /* /* Loading Loading @@ -897,8 +896,6 @@ restart: state = xfs_da_state_alloc(); state = xfs_da_state_alloc(); state->args = args; state->args = args; state->mp = mp; 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 * Search to see if name already exists, and get back a pointer Loading Loading @@ -1076,8 +1073,6 @@ restart: state = xfs_da_state_alloc(); state = xfs_da_state_alloc(); state->args = args; state->args = args; state->mp = mp; state->mp = mp; state->blocksize = state->mp->m_sb.sb_blocksize; state->node_ents = state->mp->m_attr_node_ents; state->inleaf = 0; state->inleaf = 0; error = xfs_da3_node_lookup_int(state, &retval); error = xfs_da3_node_lookup_int(state, &retval); if (error) if (error) Loading Loading @@ -1168,8 +1163,6 @@ xfs_attr_node_removename(xfs_da_args_t *args) state = xfs_da_state_alloc(); state = xfs_da_state_alloc(); state->args = args; state->args = args; state->mp = dp->i_mount; 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. * Search to see if name exists, and get back a pointer to it. Loading Loading @@ -1431,8 +1424,6 @@ xfs_attr_node_get(xfs_da_args_t *args) state = xfs_da_state_alloc(); state = xfs_da_state_alloc(); state->args = args; state->args = args; state->mp = args->dp->i_mount; 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. * Search to see if name exists, and get back a pointer to it. Loading
fs/xfs/xfs_attr_leaf.c +89 −95 Original line number Original line Diff line number Diff line Loading @@ -80,11 +80,12 @@ STATIC int xfs_attr3_leaf_figure_balance(xfs_da_state_t *state, /* /* * Utility routines. * 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_attr3_icleaf_hdr *src_ichdr, int src_start, struct xfs_attr_leafblock *dst_leaf, struct xfs_attr_leafblock *dst_leaf, struct xfs_attr3_icleaf_hdr *dst_ichdr, int dst_start, 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); STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); void void Loading Loading @@ -711,6 +712,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) memset((char *)&nargs, 0, sizeof(nargs)); memset((char *)&nargs, 0, sizeof(nargs)); nargs.dp = dp; nargs.dp = dp; nargs.geo = args->geo; nargs.firstblock = args->firstblock; nargs.firstblock = args->firstblock; nargs.flist = args->flist; nargs.flist = args->flist; nargs.total = args->total; nargs.total = args->total; Loading Loading @@ -805,18 +807,18 @@ xfs_attr3_leaf_to_shortform( trace_xfs_attr_leaf_to_sf(args); 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) if (!tmpbuffer) return ENOMEM; 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; leaf = (xfs_attr_leafblock_t *)tmpbuffer; xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); entry = xfs_attr3_leaf_entryp(leaf); entry = xfs_attr3_leaf_entryp(leaf); /* XXX (dgc): buffer is about to be marked stale - why zero it? */ /* 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. * Clean out the prior contents of the attribute list. Loading @@ -838,6 +840,7 @@ xfs_attr3_leaf_to_shortform( * Copy the attributes * Copy the attributes */ */ memset((char *)&nargs, 0, sizeof(nargs)); memset((char *)&nargs, 0, sizeof(nargs)); nargs.geo = args->geo; nargs.dp = dp; nargs.dp = dp; nargs.firstblock = args->firstblock; nargs.firstblock = args->firstblock; nargs.flist = args->flist; nargs.flist = args->flist; Loading Loading @@ -904,12 +907,12 @@ xfs_attr3_leaf_to_node( /* copy leaf to new buffer, update identifiers */ /* copy leaf to new buffer, update identifiers */ xfs_trans_buf_set_type(args->trans, bp2, XFS_BLFT_ATTR_LEAF_BUF); xfs_trans_buf_set_type(args->trans, bp2, XFS_BLFT_ATTR_LEAF_BUF); bp2->b_ops = bp1->b_ops; 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)) { if (xfs_sb_version_hascrc(&mp->m_sb)) { struct xfs_da3_blkinfo *hdr3 = bp2->b_addr; struct xfs_da3_blkinfo *hdr3 = bp2->b_addr; hdr3->blkno = cpu_to_be64(bp2->b_bn); 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. * Set up the new root node. Loading @@ -930,7 +933,7 @@ xfs_attr3_leaf_to_node( btree[0].before = cpu_to_be32(blkno); btree[0].before = cpu_to_be32(blkno); icnodehdr.count = 1; icnodehdr.count = 1; dp->d_ops->node_hdr_to_disk(node, &icnodehdr); 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; error = 0; out: out: return error; return error; Loading Loading @@ -966,10 +969,10 @@ xfs_attr3_leaf_create( bp->b_ops = &xfs_attr3_leaf_buf_ops; bp->b_ops = &xfs_attr3_leaf_buf_ops; xfs_trans_buf_set_type(args->trans, bp, XFS_BLFT_ATTR_LEAF_BUF); xfs_trans_buf_set_type(args->trans, bp, XFS_BLFT_ATTR_LEAF_BUF); leaf = bp->b_addr; leaf = bp->b_addr; memset(leaf, 0, XFS_LBSIZE(mp)); memset(leaf, 0, args->geo->blksize); memset(&ichdr, 0, sizeof(ichdr)); memset(&ichdr, 0, sizeof(ichdr)); ichdr.firstused = XFS_LBSIZE(mp); ichdr.firstused = args->geo->blksize; if (xfs_sb_version_hascrc(&mp->m_sb)) { if (xfs_sb_version_hascrc(&mp->m_sb)) { struct xfs_da3_blkinfo *hdr3 = bp->b_addr; struct xfs_da3_blkinfo *hdr3 = bp->b_addr; Loading @@ -988,7 +991,7 @@ xfs_attr3_leaf_create( ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base; ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base; xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr); 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; *bpp = bp; return 0; return 0; Loading Loading @@ -1074,8 +1077,7 @@ xfs_attr3_leaf_add( leaf = bp->b_addr; leaf = bp->b_addr; xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); ASSERT(args->index >= 0 && args->index <= ichdr.count); ASSERT(args->index >= 0 && args->index <= ichdr.count); entsize = xfs_attr_leaf_newentsize(args->namelen, args->valuelen, entsize = xfs_attr_leaf_newentsize(args, NULL); args->trans->t_mountp->m_sb.sb_blocksize, NULL); /* /* * Search through freemap for first-fit on new name length. * Search through freemap for first-fit on new name length. Loading Loading @@ -1174,17 +1176,14 @@ xfs_attr3_leaf_add_work( * Allocate space for the new string (at the end of the run). * Allocate space for the new string (at the end of the run). */ */ mp = args->trans->t_mountp; 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].base & 0x3) == 0); ASSERT(ichdr->freemap[mapindex].size >= ASSERT(ichdr->freemap[mapindex].size >= xfs_attr_leaf_newentsize(args->namelen, args->valuelen, xfs_attr_leaf_newentsize(args, NULL)); mp->m_sb.sb_blocksize, NULL)); ASSERT(ichdr->freemap[mapindex].size < args->geo->blksize); ASSERT(ichdr->freemap[mapindex].size < XFS_LBSIZE(mp)); ASSERT((ichdr->freemap[mapindex].size & 0x3) == 0); ASSERT((ichdr->freemap[mapindex].size & 0x3) == 0); ichdr->freemap[mapindex].size -= ichdr->freemap[mapindex].size -= xfs_attr_leaf_newentsize(args, &tmp); xfs_attr_leaf_newentsize(args->namelen, args->valuelen, mp->m_sb.sb_blocksize, &tmp); entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base + entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base + ichdr->freemap[mapindex].size); ichdr->freemap[mapindex].size); Loading Loading @@ -1269,14 +1268,13 @@ xfs_attr3_leaf_compact( struct xfs_attr_leafblock *leaf_dst; struct xfs_attr_leafblock *leaf_dst; struct xfs_attr3_icleaf_hdr ichdr_src; struct xfs_attr3_icleaf_hdr ichdr_src; struct xfs_trans *trans = args->trans; struct xfs_trans *trans = args->trans; struct xfs_mount *mp = trans->t_mountp; char *tmpbuffer; char *tmpbuffer; trace_xfs_attr_leaf_compact(args); trace_xfs_attr_leaf_compact(args); tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP); tmpbuffer = kmem_alloc(args->geo->blksize, KM_SLEEP); memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(mp)); memcpy(tmpbuffer, bp->b_addr, args->geo->blksize); memset(bp->b_addr, 0, XFS_LBSIZE(mp)); memset(bp->b_addr, 0, args->geo->blksize); leaf_src = (xfs_attr_leafblock_t *)tmpbuffer; leaf_src = (xfs_attr_leafblock_t *)tmpbuffer; leaf_dst = bp->b_addr; leaf_dst = bp->b_addr; Loading @@ -1289,7 +1287,7 @@ xfs_attr3_leaf_compact( /* Initialise the incore headers */ /* Initialise the incore headers */ ichdr_src = *ichdr_dst; /* struct copy */ ichdr_src = *ichdr_dst; /* struct copy */ ichdr_dst->firstused = XFS_LBSIZE(mp); ichdr_dst->firstused = args->geo->blksize; ichdr_dst->usedbytes = 0; ichdr_dst->usedbytes = 0; ichdr_dst->count = 0; ichdr_dst->count = 0; ichdr_dst->holes = 0; ichdr_dst->holes = 0; Loading @@ -1304,13 +1302,13 @@ xfs_attr3_leaf_compact( * Copy all entry's in the same (sorted) order, * Copy all entry's in the same (sorted) order, * but allocate name/value pairs packed and in sequence. * but allocate name/value pairs packed and in sequence. */ */ xfs_attr3_leaf_moveents(leaf_src, &ichdr_src, 0, leaf_dst, ichdr_dst, 0, xfs_attr3_leaf_moveents(args, leaf_src, &ichdr_src, 0, ichdr_src.count, mp); leaf_dst, ichdr_dst, 0, ichdr_src.count); /* /* * this logs the entire buffer, but the caller must write the header * this logs the entire buffer, but the caller must write the header * back to the buffer when it is finished modifying it. * 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); kmem_free(tmpbuffer); } } Loading Loading @@ -1461,8 +1459,8 @@ xfs_attr3_leaf_rebalance( /* /* * Move high entries from leaf1 to low end of leaf2. * Move high entries from leaf1 to low end of leaf2. */ */ xfs_attr3_leaf_moveents(leaf1, &ichdr1, ichdr1.count - count, xfs_attr3_leaf_moveents(args, leaf1, &ichdr1, leaf2, &ichdr2, 0, count, state->mp); ichdr1.count - count, leaf2, &ichdr2, 0, count); } else if (count > ichdr1.count) { } else if (count > ichdr1.count) { /* /* Loading Loading @@ -1490,14 +1488,14 @@ xfs_attr3_leaf_rebalance( /* /* * Move low entries from leaf2 to high end of leaf1. * Move low entries from leaf2 to high end of leaf1. */ */ xfs_attr3_leaf_moveents(leaf2, &ichdr2, 0, leaf1, &ichdr1, xfs_attr3_leaf_moveents(args, leaf2, &ichdr2, 0, leaf1, &ichdr1, ichdr1.count, count, state->mp); ichdr1.count, count); } } xfs_attr3_leaf_hdr_to_disk(leaf1, &ichdr1); xfs_attr3_leaf_hdr_to_disk(leaf1, &ichdr1); xfs_attr3_leaf_hdr_to_disk(leaf2, &ichdr2); 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, blk1->bp, 0, args->geo->blksize - 1); xfs_trans_log_buf(args->trans, blk2->bp, 0, state->blocksize-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. * Copy out last hashval in each block for B-tree code. Loading Loading @@ -1592,11 +1590,9 @@ xfs_attr3_leaf_figure_balance( max = ichdr1->count + ichdr2->count; max = ichdr1->count + ichdr2->count; half = (max + 1) * sizeof(*entry); half = (max + 1) * sizeof(*entry); half += ichdr1->usedbytes + ichdr2->usedbytes + half += ichdr1->usedbytes + ichdr2->usedbytes + xfs_attr_leaf_newentsize(state->args->namelen, xfs_attr_leaf_newentsize(state->args, NULL); state->args->valuelen, state->blocksize, NULL); half /= 2; half /= 2; lastdelta = state->blocksize; lastdelta = state->args->geo->blksize; entry = xfs_attr3_leaf_entryp(leaf1); entry = xfs_attr3_leaf_entryp(leaf1); for (count = index = 0; count < max; entry++, index++, count++) { for (count = index = 0; count < max; entry++, index++, count++) { Loading @@ -1606,10 +1602,7 @@ xfs_attr3_leaf_figure_balance( */ */ if (count == blk1->index) { if (count == blk1->index) { tmp = totallen + sizeof(*entry) + tmp = totallen + sizeof(*entry) + xfs_attr_leaf_newentsize( xfs_attr_leaf_newentsize(state->args, NULL); state->args->namelen, state->args->valuelen, state->blocksize, NULL); if (XFS_ATTR_ABS(half - tmp) > lastdelta) if (XFS_ATTR_ABS(half - tmp) > lastdelta) break; break; lastdelta = XFS_ATTR_ABS(half - tmp); lastdelta = XFS_ATTR_ABS(half - tmp); Loading Loading @@ -1645,10 +1638,7 @@ xfs_attr3_leaf_figure_balance( totallen -= count * sizeof(*entry); totallen -= count * sizeof(*entry); if (foundit) { if (foundit) { totallen -= sizeof(*entry) + totallen -= sizeof(*entry) + xfs_attr_leaf_newentsize( xfs_attr_leaf_newentsize(state->args, NULL); state->args->namelen, state->args->valuelen, state->blocksize, NULL); } } *countarg = count; *countarg = count; Loading Loading @@ -1700,7 +1690,7 @@ xfs_attr3_leaf_toosmall( bytes = xfs_attr3_leaf_hdr_size(leaf) + bytes = xfs_attr3_leaf_hdr_size(leaf) + ichdr.count * sizeof(xfs_attr_leaf_entry_t) + ichdr.count * sizeof(xfs_attr_leaf_entry_t) + ichdr.usedbytes; ichdr.usedbytes; if (bytes > (state->blocksize >> 1)) { if (bytes > (state->args->geo->blksize >> 1)) { *action = 0; /* blk over 50%, don't try to join */ *action = 0; /* blk over 50%, don't try to join */ return(0); return(0); } } Loading Loading @@ -1754,7 +1744,8 @@ xfs_attr3_leaf_toosmall( xfs_attr3_leaf_hdr_from_disk(&ichdr2, bp->b_addr); 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.usedbytes - ichdr2.usedbytes - ((ichdr.count + ichdr2.count) * ((ichdr.count + ichdr2.count) * sizeof(xfs_attr_leaf_entry_t)) - sizeof(xfs_attr_leaf_entry_t)) - Loading Loading @@ -1805,7 +1796,6 @@ xfs_attr3_leaf_remove( struct xfs_attr_leafblock *leaf; struct xfs_attr_leafblock *leaf; struct xfs_attr3_icleaf_hdr ichdr; struct xfs_attr3_icleaf_hdr ichdr; struct xfs_attr_leaf_entry *entry; struct xfs_attr_leaf_entry *entry; struct xfs_mount *mp = args->trans->t_mountp; int before; int before; int after; int after; int smallest; int smallest; Loading @@ -1819,7 +1809,7 @@ xfs_attr3_leaf_remove( leaf = bp->b_addr; leaf = bp->b_addr; xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); 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(args->index >= 0 && args->index < ichdr.count); ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) + ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) + xfs_attr3_leaf_hdr_size(leaf)); xfs_attr3_leaf_hdr_size(leaf)); Loading @@ -1827,7 +1817,7 @@ xfs_attr3_leaf_remove( entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused); 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: * Scan through free region table: Loading @@ -1842,8 +1832,8 @@ xfs_attr3_leaf_remove( smallest = XFS_ATTR_LEAF_MAPSIZE - 1; smallest = XFS_ATTR_LEAF_MAPSIZE - 1; entsize = xfs_attr_leaf_entsize(leaf, args->index); entsize = xfs_attr_leaf_entsize(leaf, args->index); for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { ASSERT(ichdr.freemap[i].base < XFS_LBSIZE(mp)); ASSERT(ichdr.freemap[i].base < args->geo->blksize); ASSERT(ichdr.freemap[i].size < XFS_LBSIZE(mp)); ASSERT(ichdr.freemap[i].size < args->geo->blksize); if (ichdr.freemap[i].base == tablesize) { if (ichdr.freemap[i].base == tablesize) { ichdr.freemap[i].base -= sizeof(xfs_attr_leaf_entry_t); ichdr.freemap[i].base -= sizeof(xfs_attr_leaf_entry_t); ichdr.freemap[i].size += sizeof(xfs_attr_leaf_entry_t); ichdr.freemap[i].size += sizeof(xfs_attr_leaf_entry_t); Loading Loading @@ -1920,11 +1910,11 @@ xfs_attr3_leaf_remove( * removing the name. * removing the name. */ */ if (smallest) { if (smallest) { tmp = XFS_LBSIZE(mp); tmp = args->geo->blksize; entry = xfs_attr3_leaf_entryp(leaf); entry = xfs_attr3_leaf_entryp(leaf); for (i = ichdr.count - 1; i >= 0; entry++, i--) { for (i = ichdr.count - 1; i >= 0; entry++, i--) { ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused); 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) if (be16_to_cpu(entry->nameidx) < tmp) tmp = be16_to_cpu(entry->nameidx); tmp = be16_to_cpu(entry->nameidx); Loading @@ -1947,7 +1937,7 @@ xfs_attr3_leaf_remove( tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) + tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) + ichdr.count * sizeof(xfs_attr_leaf_entry_t); 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 */ } } /* /* Loading @@ -1964,7 +1954,6 @@ xfs_attr3_leaf_unbalance( struct xfs_attr3_icleaf_hdr drophdr; struct xfs_attr3_icleaf_hdr drophdr; struct xfs_attr3_icleaf_hdr savehdr; struct xfs_attr3_icleaf_hdr savehdr; struct xfs_attr_leaf_entry *entry; struct xfs_attr_leaf_entry *entry; struct xfs_mount *mp = state->mp; trace_xfs_attr_leaf_unbalance(state->args); trace_xfs_attr_leaf_unbalance(state->args); Loading @@ -1991,13 +1980,15 @@ xfs_attr3_leaf_unbalance( */ */ if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, drop_blk->bp, &drophdr)) { 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, save_leaf, &savehdr, 0, drophdr.count, mp); drophdr.count); } else { } else { xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, xfs_attr3_leaf_moveents(state->args, drop_leaf, &drophdr, 0, save_leaf, &savehdr, save_leaf, &savehdr, savehdr.count, drophdr.count, mp); savehdr.count, drophdr.count); } } } else { } else { /* /* Loading @@ -2007,7 +1998,7 @@ xfs_attr3_leaf_unbalance( struct xfs_attr_leafblock *tmp_leaf; struct xfs_attr_leafblock *tmp_leaf; struct xfs_attr3_icleaf_hdr tmphdr; 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 * Copy the header into the temp leaf so that all the stuff Loading @@ -2020,35 +2011,39 @@ xfs_attr3_leaf_unbalance( tmphdr.magic = savehdr.magic; tmphdr.magic = savehdr.magic; tmphdr.forw = savehdr.forw; tmphdr.forw = savehdr.forw; tmphdr.back = savehdr.back; tmphdr.back = savehdr.back; tmphdr.firstused = state->blocksize; tmphdr.firstused = state->args->geo->blksize; /* write the header to the temp buffer to initialise it */ /* write the header to the temp buffer to initialise it */ xfs_attr3_leaf_hdr_to_disk(tmp_leaf, &tmphdr); xfs_attr3_leaf_hdr_to_disk(tmp_leaf, &tmphdr); if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, drop_blk->bp, &drophdr)) { 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, tmp_leaf, &tmphdr, 0, drophdr.count, mp); drophdr.count); xfs_attr3_leaf_moveents(save_leaf, &savehdr, 0, xfs_attr3_leaf_moveents(state->args, save_leaf, &savehdr, 0, tmp_leaf, &tmphdr, tmphdr.count, tmp_leaf, &tmphdr, tmphdr.count, savehdr.count, mp); savehdr.count); } else { } else { xfs_attr3_leaf_moveents(save_leaf, &savehdr, 0, xfs_attr3_leaf_moveents(state->args, save_leaf, &savehdr, 0, tmp_leaf, &tmphdr, 0, tmp_leaf, &tmphdr, 0, savehdr.count, mp); savehdr.count); xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, xfs_attr3_leaf_moveents(state->args, drop_leaf, &drophdr, 0, tmp_leaf, &tmphdr, tmphdr.count, 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 */ savehdr = tmphdr; /* struct copy */ kmem_free(tmp_leaf); kmem_free(tmp_leaf); } } xfs_attr3_leaf_hdr_to_disk(save_leaf, &savehdr); xfs_attr3_leaf_hdr_to_disk(save_leaf, &savehdr); xfs_trans_log_buf(state->args->trans, save_blk->bp, 0, 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. * Copy out last hashval in each block for B-tree code. Loading Loading @@ -2094,7 +2089,7 @@ xfs_attr3_leaf_lookup_int( leaf = bp->b_addr; leaf = bp->b_addr; xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); entries = xfs_attr3_leaf_entryp(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) * Binary search. (note: small blocks will skip this loop) Loading Loading @@ -2198,7 +2193,7 @@ xfs_attr3_leaf_getvalue( leaf = bp->b_addr; leaf = bp->b_addr; xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); 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); ASSERT(args->index < ichdr.count); entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; Loading Loading @@ -2249,14 +2244,14 @@ xfs_attr3_leaf_getvalue( /*ARGSUSED*/ /*ARGSUSED*/ STATIC void STATIC void xfs_attr3_leaf_moveents( xfs_attr3_leaf_moveents( struct xfs_da_args *args, struct xfs_attr_leafblock *leaf_s, struct xfs_attr_leafblock *leaf_s, struct xfs_attr3_icleaf_hdr *ichdr_s, struct xfs_attr3_icleaf_hdr *ichdr_s, int start_s, int start_s, struct xfs_attr_leafblock *leaf_d, struct xfs_attr_leafblock *leaf_d, struct xfs_attr3_icleaf_hdr *ichdr_d, struct xfs_attr3_icleaf_hdr *ichdr_d, int start_d, int start_d, int count, int count) struct xfs_mount *mp) { { struct xfs_attr_leaf_entry *entry_s; struct xfs_attr_leaf_entry *entry_s; struct xfs_attr_leaf_entry *entry_d; struct xfs_attr_leaf_entry *entry_d; Loading @@ -2276,10 +2271,10 @@ xfs_attr3_leaf_moveents( ASSERT(ichdr_s->magic == XFS_ATTR_LEAF_MAGIC || ASSERT(ichdr_s->magic == XFS_ATTR_LEAF_MAGIC || ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC); ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC); ASSERT(ichdr_s->magic == ichdr_d->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)) ASSERT(ichdr_s->firstused >= (ichdr_s->count * sizeof(*entry_s)) + xfs_attr3_leaf_hdr_size(leaf_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)) ASSERT(ichdr_d->firstused >= (ichdr_d->count * sizeof(*entry_d)) + xfs_attr3_leaf_hdr_size(leaf_d)); + xfs_attr3_leaf_hdr_size(leaf_d)); Loading Loading @@ -2331,11 +2326,11 @@ xfs_attr3_leaf_moveents( entry_d->nameidx = cpu_to_be16(ichdr_d->firstused); entry_d->nameidx = cpu_to_be16(ichdr_d->firstused); entry_d->flags = entry_s->flags; entry_d->flags = entry_s->flags; ASSERT(be16_to_cpu(entry_d->nameidx) + tmp ASSERT(be16_to_cpu(entry_d->nameidx) + tmp <= XFS_LBSIZE(mp)); <= args->geo->blksize); memmove(xfs_attr3_leaf_name(leaf_d, desti), memmove(xfs_attr3_leaf_name(leaf_d, desti), xfs_attr3_leaf_name(leaf_s, start_s + i), tmp); xfs_attr3_leaf_name(leaf_s, start_s + i), tmp); ASSERT(be16_to_cpu(entry_s->nameidx) + 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); memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp); ichdr_s->usedbytes -= tmp; ichdr_s->usedbytes -= tmp; ichdr_d->usedbytes += tmp; ichdr_d->usedbytes += tmp; Loading @@ -2356,7 +2351,7 @@ xfs_attr3_leaf_moveents( tmp = count * sizeof(xfs_attr_leaf_entry_t); tmp = count * sizeof(xfs_attr_leaf_entry_t); entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s]; entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s]; ASSERT(((char *)entry_s + tmp) <= ASSERT(((char *)entry_s + tmp) <= ((char *)leaf_s + XFS_LBSIZE(mp))); ((char *)leaf_s + args->geo->blksize)); memset(entry_s, 0, tmp); memset(entry_s, 0, tmp); } else { } else { /* /* Loading @@ -2371,7 +2366,7 @@ xfs_attr3_leaf_moveents( tmp = count * sizeof(xfs_attr_leaf_entry_t); tmp = count * sizeof(xfs_attr_leaf_entry_t); entry_s = &xfs_attr3_leaf_entryp(leaf_s)[ichdr_s->count]; entry_s = &xfs_attr3_leaf_entryp(leaf_s)[ichdr_s->count]; ASSERT(((char *)entry_s + tmp) <= ASSERT(((char *)entry_s + tmp) <= ((char *)leaf_s + XFS_LBSIZE(mp))); ((char *)leaf_s + args->geo->blksize)); memset(entry_s, 0, tmp); memset(entry_s, 0, tmp); } } Loading Loading @@ -2439,22 +2434,21 @@ xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index) * a "local" or a "remote" attribute. * a "local" or a "remote" attribute. */ */ int 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; int size; size = xfs_attr_leaf_entsize_local(namelen, valuelen); size = xfs_attr_leaf_entsize_local(args->namelen, args->valuelen); if (size < xfs_attr_leaf_entsize_local_max(blocksize)) { if (size < xfs_attr_leaf_entsize_local_max(args->geo->blksize)) { if (local) { if (local) *local = 1; *local = 1; return size; } } } else { if (local) size = xfs_attr_leaf_entsize_remote(namelen); if (local) { *local = 0; *local = 0; } return xfs_attr_leaf_entsize_remote(args->namelen); } return size; } } Loading
fs/xfs/xfs_attr_leaf.h +1 −2 Original line number Original line Diff line number Diff line Loading @@ -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); xfs_dahash_t xfs_attr_leaf_lasthash(struct xfs_buf *bp, int *count); int xfs_attr_leaf_order(struct xfs_buf *leaf1_bp, int xfs_attr_leaf_order(struct xfs_buf *leaf1_bp, struct xfs_buf *leaf2_bp); struct xfs_buf *leaf2_bp); int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int xfs_attr_leaf_newentsize(struct xfs_da_args *args, int *local); int *local); int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, xfs_dablk_t bno, xfs_daddr_t mappedbno, xfs_dablk_t bno, xfs_daddr_t mappedbno, struct xfs_buf **bpp); struct xfs_buf **bpp); Loading
fs/xfs/xfs_attr_list.c +1 −0 Original line number Original line Diff line number Diff line Loading @@ -444,6 +444,7 @@ xfs_attr3_leaf_list_int( xfs_da_args_t args; xfs_da_args_t args; memset((char *)&args, 0, sizeof(args)); memset((char *)&args, 0, sizeof(args)); args.geo = context->dp->i_mount->m_attr_geo; args.dp = context->dp; args.dp = context->dp; args.whichfork = XFS_ATTR_FORK; args.whichfork = XFS_ATTR_FORK; args.valuelen = valuelen; args.valuelen = valuelen; Loading
fs/xfs/xfs_attr_remote.c +29 −26 Original line number Original line Diff line number Diff line Loading @@ -125,6 +125,7 @@ xfs_attr3_rmt_read_verify( char *ptr; char *ptr; int len; int len; xfs_daddr_t bno; xfs_daddr_t bno; int blksize = mp->m_attr_geo->blksize; /* no verification of non-crc buffers */ /* no verification of non-crc buffers */ if (!xfs_sb_version_hascrc(&mp->m_sb)) if (!xfs_sb_version_hascrc(&mp->m_sb)) Loading @@ -133,21 +134,20 @@ xfs_attr3_rmt_read_verify( ptr = bp->b_addr; ptr = bp->b_addr; bno = bp->b_bn; bno = bp->b_bn; len = BBTOB(bp->b_length); len = BBTOB(bp->b_length); ASSERT(len >= XFS_LBSIZE(mp)); ASSERT(len >= blksize); while (len > 0) { while (len > 0) { if (!xfs_verify_cksum(ptr, XFS_LBSIZE(mp), if (!xfs_verify_cksum(ptr, blksize, XFS_ATTR3_RMT_CRC_OFF)) { XFS_ATTR3_RMT_CRC_OFF)) { xfs_buf_ioerror(bp, EFSBADCRC); xfs_buf_ioerror(bp, EFSBADCRC); break; 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); xfs_buf_ioerror(bp, EFSCORRUPTED); break; break; } } len -= XFS_LBSIZE(mp); len -= blksize; ptr += XFS_LBSIZE(mp); ptr += blksize; bno += mp->m_bsize; bno += BTOBB(blksize); } } if (bp->b_error) if (bp->b_error) Loading @@ -165,6 +165,7 @@ xfs_attr3_rmt_write_verify( char *ptr; char *ptr; int len; int len; xfs_daddr_t bno; xfs_daddr_t bno; int blksize = mp->m_attr_geo->blksize; /* no verification of non-crc buffers */ /* no verification of non-crc buffers */ if (!xfs_sb_version_hascrc(&mp->m_sb)) if (!xfs_sb_version_hascrc(&mp->m_sb)) Loading @@ -173,10 +174,10 @@ xfs_attr3_rmt_write_verify( ptr = bp->b_addr; ptr = bp->b_addr; bno = bp->b_bn; bno = bp->b_bn; len = BBTOB(bp->b_length); len = BBTOB(bp->b_length); ASSERT(len >= XFS_LBSIZE(mp)); ASSERT(len >= blksize); while (len > 0) { 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_buf_ioerror(bp, EFSCORRUPTED); xfs_verifier_error(bp); xfs_verifier_error(bp); return; return; Loading @@ -187,11 +188,11 @@ xfs_attr3_rmt_write_verify( rmt = (struct xfs_attr3_rmt_hdr *)ptr; rmt = (struct xfs_attr3_rmt_hdr *)ptr; rmt->rm_lsn = cpu_to_be64(bip->bli_item.li_lsn); 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); len -= blksize; ptr += XFS_LBSIZE(mp); ptr += blksize; bno += mp->m_bsize; bno += BTOBB(blksize); } } ASSERT(len == 0); ASSERT(len == 0); } } Loading Loading @@ -240,12 +241,13 @@ xfs_attr_rmtval_copyout( char *src = bp->b_addr; char *src = bp->b_addr; xfs_daddr_t bno = bp->b_bn; xfs_daddr_t bno = bp->b_bn; int len = BBTOB(bp->b_length); 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) { while (len > 0 && *valuelen > 0) { int hdr_size = 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); byte_cnt = min(*valuelen, byte_cnt); Loading @@ -263,9 +265,9 @@ xfs_attr_rmtval_copyout( memcpy(*dst, src + hdr_size, byte_cnt); memcpy(*dst, src + hdr_size, byte_cnt); /* roll buffer forwards */ /* roll buffer forwards */ len -= XFS_LBSIZE(mp); len -= blksize; src += XFS_LBSIZE(mp); src += blksize; bno += mp->m_bsize; bno += BTOBB(blksize); /* roll attribute data forwards */ /* roll attribute data forwards */ *valuelen -= byte_cnt; *valuelen -= byte_cnt; Loading @@ -287,12 +289,13 @@ xfs_attr_rmtval_copyin( char *dst = bp->b_addr; char *dst = bp->b_addr; xfs_daddr_t bno = bp->b_bn; xfs_daddr_t bno = bp->b_bn; int len = BBTOB(bp->b_length); 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) { while (len > 0 && *valuelen > 0) { int hdr_size; 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); byte_cnt = min(*valuelen, byte_cnt); hdr_size = xfs_attr3_rmt_hdr_set(mp, dst, ino, *offset, hdr_size = xfs_attr3_rmt_hdr_set(mp, dst, ino, *offset, Loading @@ -304,17 +307,17 @@ xfs_attr_rmtval_copyin( * If this is the last block, zero the remainder of it. * If this is the last block, zero the remainder of it. * Check that we are actually the last block, too. * 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(*valuelen - byte_cnt == 0); ASSERT(len == XFS_LBSIZE(mp)); ASSERT(len == blksize); memset(dst + hdr_size + byte_cnt, 0, memset(dst + hdr_size + byte_cnt, 0, XFS_LBSIZE(mp) - hdr_size - byte_cnt); blksize - hdr_size - byte_cnt); } } /* roll buffer forwards */ /* roll buffer forwards */ len -= XFS_LBSIZE(mp); len -= blksize; dst += XFS_LBSIZE(mp); dst += blksize; bno += mp->m_bsize; bno += BTOBB(blksize); /* roll attribute data forwards */ /* roll attribute data forwards */ *valuelen -= byte_cnt; *valuelen -= byte_cnt; Loading