diff options
| -rw-r--r-- | fs/xfs/xfs_attr_leaf.c | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index 79ece72976ae..5b03d15b707b 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c | |||
| @@ -1445,11 +1445,12 @@ xfs_attr3_leaf_add_work( | |||
| 1445 | STATIC void | 1445 | STATIC void |
| 1446 | xfs_attr3_leaf_compact( | 1446 | xfs_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. |
