aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_attr_leaf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_attr_leaf.c')
-rw-r--r--fs/xfs/xfs_attr_leaf.c73
1 files changed, 48 insertions, 25 deletions
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 0bce1b348580..31d3cd129269 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -1412,7 +1412,7 @@ xfs_attr3_leaf_add_work(
1412 name_rmt->valuelen = 0; 1412 name_rmt->valuelen = 0;
1413 name_rmt->valueblk = 0; 1413 name_rmt->valueblk = 0;
1414 args->rmtblkno = 1; 1414 args->rmtblkno = 1;
1415 args->rmtblkcnt = XFS_B_TO_FSB(mp, args->valuelen); 1415 args->rmtblkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen);
1416 } 1416 }
1417 xfs_trans_log_buf(args->trans, bp, 1417 xfs_trans_log_buf(args->trans, bp,
1418 XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index), 1418 XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index),
@@ -1445,11 +1445,12 @@ xfs_attr3_leaf_add_work(
1445STATIC void 1445STATIC void
1446xfs_attr3_leaf_compact( 1446xfs_attr3_leaf_compact(
1447 struct xfs_da_args *args, 1447 struct xfs_da_args *args,
1448 struct xfs_attr3_icleaf_hdr *ichdr_d, 1448 struct xfs_attr3_icleaf_hdr *ichdr_dst,
1449 struct xfs_buf *bp) 1449 struct xfs_buf *bp)
1450{ 1450{
1451 xfs_attr_leafblock_t *leaf_s, *leaf_d; 1451 struct xfs_attr_leafblock *leaf_src;
1452 struct xfs_attr3_icleaf_hdr ichdr_s; 1452 struct xfs_attr_leafblock *leaf_dst;
1453 struct xfs_attr3_icleaf_hdr ichdr_src;
1453 struct xfs_trans *trans = args->trans; 1454 struct xfs_trans *trans = args->trans;
1454 struct xfs_mount *mp = trans->t_mountp; 1455 struct xfs_mount *mp = trans->t_mountp;
1455 char *tmpbuffer; 1456 char *tmpbuffer;
@@ -1457,29 +1458,38 @@ xfs_attr3_leaf_compact(
1457 trace_xfs_attr_leaf_compact(args); 1458 trace_xfs_attr_leaf_compact(args);
1458 1459
1459 tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP); 1460 tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP);
1460 ASSERT(tmpbuffer != NULL);
1461 memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(mp)); 1461 memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(mp));
1462 memset(bp->b_addr, 0, XFS_LBSIZE(mp)); 1462 memset(bp->b_addr, 0, XFS_LBSIZE(mp));
1463 leaf_src = (xfs_attr_leafblock_t *)tmpbuffer;
1464 leaf_dst = bp->b_addr;
1463 1465
1464 /* 1466 /*
1465 * Copy basic information 1467 * Copy the on-disk header back into the destination buffer to ensure
1468 * all the information in the header that is not part of the incore
1469 * header structure is preserved.
1466 */ 1470 */
1467 leaf_s = (xfs_attr_leafblock_t *)tmpbuffer; 1471 memcpy(bp->b_addr, tmpbuffer, xfs_attr3_leaf_hdr_size(leaf_src));
1468 leaf_d = bp->b_addr; 1472
1469 ichdr_s = *ichdr_d; /* struct copy */ 1473 /* Initialise the incore headers */
1470 ichdr_d->firstused = XFS_LBSIZE(mp); 1474 ichdr_src = *ichdr_dst; /* struct copy */
1471 ichdr_d->usedbytes = 0; 1475 ichdr_dst->firstused = XFS_LBSIZE(mp);
1472 ichdr_d->count = 0; 1476 ichdr_dst->usedbytes = 0;
1473 ichdr_d->holes = 0; 1477 ichdr_dst->count = 0;
1474 ichdr_d->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_s); 1478 ichdr_dst->holes = 0;
1475 ichdr_d->freemap[0].size = ichdr_d->firstused - ichdr_d->freemap[0].base; 1479 ichdr_dst->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_src);
1480 ichdr_dst->freemap[0].size = ichdr_dst->firstused -
1481 ichdr_dst->freemap[0].base;
1482
1483
1484 /* write the header back to initialise the underlying buffer */
1485 xfs_attr3_leaf_hdr_to_disk(leaf_dst, ichdr_dst);
1476 1486
1477 /* 1487 /*
1478 * Copy all entry's in the same (sorted) order, 1488 * Copy all entry's in the same (sorted) order,
1479 * but allocate name/value pairs packed and in sequence. 1489 * but allocate name/value pairs packed and in sequence.
1480 */ 1490 */
1481 xfs_attr3_leaf_moveents(leaf_s, &ichdr_s, 0, leaf_d, ichdr_d, 0, 1491 xfs_attr3_leaf_moveents(leaf_src, &ichdr_src, 0, leaf_dst, ichdr_dst, 0,
1482 ichdr_s.count, mp); 1492 ichdr_src.count, mp);
1483 /* 1493 /*
1484 * this logs the entire buffer, but the caller must write the header 1494 * this logs the entire buffer, but the caller must write the header
1485 * back to the buffer when it is finished modifying it. 1495 * back to the buffer when it is finished modifying it.
@@ -2181,14 +2191,24 @@ xfs_attr3_leaf_unbalance(
2181 struct xfs_attr_leafblock *tmp_leaf; 2191 struct xfs_attr_leafblock *tmp_leaf;
2182 struct xfs_attr3_icleaf_hdr tmphdr; 2192 struct xfs_attr3_icleaf_hdr tmphdr;
2183 2193
2184 tmp_leaf = kmem_alloc(state->blocksize, KM_SLEEP); 2194 tmp_leaf = kmem_zalloc(state->blocksize, KM_SLEEP);
2185 memset(tmp_leaf, 0, state->blocksize);
2186 memset(&tmphdr, 0, sizeof(tmphdr));
2187 2195
2196 /*
2197 * Copy the header into the temp leaf so that all the stuff
2198 * not in the incore header is present and gets copied back in
2199 * once we've moved all the entries.
2200 */
2201 memcpy(tmp_leaf, save_leaf, xfs_attr3_leaf_hdr_size(save_leaf));
2202
2203 memset(&tmphdr, 0, sizeof(tmphdr));
2188 tmphdr.magic = savehdr.magic; 2204 tmphdr.magic = savehdr.magic;
2189 tmphdr.forw = savehdr.forw; 2205 tmphdr.forw = savehdr.forw;
2190 tmphdr.back = savehdr.back; 2206 tmphdr.back = savehdr.back;
2191 tmphdr.firstused = state->blocksize; 2207 tmphdr.firstused = state->blocksize;
2208
2209 /* write the header to the temp buffer to initialise it */
2210 xfs_attr3_leaf_hdr_to_disk(tmp_leaf, &tmphdr);
2211
2192 if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, 2212 if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
2193 drop_blk->bp, &drophdr)) { 2213 drop_blk->bp, &drophdr)) {
2194 xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, 2214 xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0,
@@ -2334,8 +2354,9 @@ xfs_attr3_leaf_lookup_int(
2334 args->index = probe; 2354 args->index = probe;
2335 args->valuelen = be32_to_cpu(name_rmt->valuelen); 2355 args->valuelen = be32_to_cpu(name_rmt->valuelen);
2336 args->rmtblkno = be32_to_cpu(name_rmt->valueblk); 2356 args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
2337 args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, 2357 args->rmtblkcnt = xfs_attr3_rmt_blocks(
2338 args->valuelen); 2358 args->dp->i_mount,
2359 args->valuelen);
2339 return XFS_ERROR(EEXIST); 2360 return XFS_ERROR(EEXIST);
2340 } 2361 }
2341 } 2362 }
@@ -2386,7 +2407,8 @@ xfs_attr3_leaf_getvalue(
2386 ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0); 2407 ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0);
2387 valuelen = be32_to_cpu(name_rmt->valuelen); 2408 valuelen = be32_to_cpu(name_rmt->valuelen);
2388 args->rmtblkno = be32_to_cpu(name_rmt->valueblk); 2409 args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
2389 args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, valuelen); 2410 args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount,
2411 valuelen);
2390 if (args->flags & ATTR_KERNOVAL) { 2412 if (args->flags & ATTR_KERNOVAL) {
2391 args->valuelen = valuelen; 2413 args->valuelen = valuelen;
2392 return 0; 2414 return 0;
@@ -2712,7 +2734,8 @@ xfs_attr3_leaf_list_int(
2712 args.valuelen = valuelen; 2734 args.valuelen = valuelen;
2713 args.value = kmem_alloc(valuelen, KM_SLEEP | KM_NOFS); 2735 args.value = kmem_alloc(valuelen, KM_SLEEP | KM_NOFS);
2714 args.rmtblkno = be32_to_cpu(name_rmt->valueblk); 2736 args.rmtblkno = be32_to_cpu(name_rmt->valueblk);
2715 args.rmtblkcnt = XFS_B_TO_FSB(args.dp->i_mount, valuelen); 2737 args.rmtblkcnt = xfs_attr3_rmt_blocks(
2738 args.dp->i_mount, valuelen);
2716 retval = xfs_attr_rmtval_get(&args); 2739 retval = xfs_attr_rmtval_get(&args);
2717 if (retval) 2740 if (retval)
2718 return retval; 2741 return retval;
@@ -3235,7 +3258,7 @@ xfs_attr3_leaf_inactive(
3235 name_rmt = xfs_attr3_leaf_name_remote(leaf, i); 3258 name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
3236 if (name_rmt->valueblk) { 3259 if (name_rmt->valueblk) {
3237 lp->valueblk = be32_to_cpu(name_rmt->valueblk); 3260 lp->valueblk = be32_to_cpu(name_rmt->valueblk);
3238 lp->valuelen = XFS_B_TO_FSB(dp->i_mount, 3261 lp->valuelen = xfs_attr3_rmt_blocks(dp->i_mount,
3239 be32_to_cpu(name_rmt->valuelen)); 3262 be32_to_cpu(name_rmt->valuelen));
3240 lp++; 3263 lp++;
3241 } 3264 }