Ticket #9255: 0001-Use-memcpy-to-get-and-set-unaligned-BPlusTree-elemen.patch

File 0001-Use-memcpy-to-get-and-set-unaligned-BPlusTree-elemen.patch, 24.7 KB (added by mmlr, 11 years ago)

Workaround to unaligned memory access using memcpy.

  • src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp

    From 3ab278ee205842906ccf34269862552687b5880a Mon Sep 17 00:00:00 2001
    From: Michael Lotz <mmlr@mlotz.ch>
    Date: Sun, 2 Dec 2012 14:11:37 +0100
    Subject: [PATCH] Use memcpy to get and set unaligned BPlusTree elements.
    
    ---
     src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp |  192 +++++++++++----------
     src/add-ons/kernel/file_systems/bfs/BPlusTree.h   |   59 +++++--
     src/add-ons/kernel/file_systems/bfs/Debug.cpp     |   15 +-
     3 files changed, 158 insertions(+), 108 deletions(-)
    
    diff --git a/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp b/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp
    index df5d999..848105d 100644
    a b BPlusTree::_FindKey(const bplustree_node* node, const uint8* key,  
    994994        return B_ENTRY_NOT_FOUND;
    995995    }
    996996
    997     off_t* values = node->Values();
    998997    int16 saveIndex = -1;
    999998
    1000999    // binary search in the key array
    BPlusTree::_FindKey(const bplustree_node* node, const uint8* key,  
    10201019            if (_index)
    10211020                *_index = i;
    10221021            if (_next)
    1023                 *_next = BFS_ENDIAN_TO_HOST_INT64(values[i]);
     1022                *_next = BFS_ENDIAN_TO_HOST_INT64(node->ValueAt(i));
    10241023            return B_OK;
    10251024        }
    10261025    }
    BPlusTree::_FindKey(const bplustree_node* node, const uint8* key,  
    10311030        if (saveIndex == node->NumKeys())
    10321031            *_next = node->OverflowLink();
    10331032        else
    1034             *_next = BFS_ENDIAN_TO_HOST_INT64(values[saveIndex]);
     1033            *_next = BFS_ENDIAN_TO_HOST_INT64(node->ValueAt(saveIndex));
    10351034    }
    10361035    return B_ENTRY_NOT_FOUND;
    10371036}
    BPlusTree::_FindFreeDuplicateFragment(Transaction& transaction,  
    10931092    const bplustree_node* node, CachedNode& cached,
    10941093    off_t* _offset, bplustree_node** _fragment, uint32* _index)
    10951094{
    1096     off_t* values = node->Values();
    10971095    for (int32 i = 0; i < node->NumKeys(); i++) {
    1098         off_t value = BFS_ENDIAN_TO_HOST_INT64(values[i]);
     1096        off_t value = BFS_ENDIAN_TO_HOST_INT64(node->ValueAt(i));
    10991097
    11001098        // does the value link to a duplicate fragment?
    11011099        if (bplustree_node::LinkType(value) != BPLUSTREE_DUPLICATE_FRAGMENT)
    BPlusTree::_InsertDuplicate(Transaction& transaction, CachedNode& cached,  
    11351133    const bplustree_node* node, uint16 index, off_t value)
    11361134{
    11371135    CachedNode cachedDuplicate(this);
    1138     off_t* values = node->Values();
    1139     off_t oldValue = BFS_ENDIAN_TO_HOST_INT64(values[index]);
     1136    off_t oldValue = BFS_ENDIAN_TO_HOST_INT64(node->ValueAt(index));
    11401137    status_t status;
    11411138    off_t offset;
    11421139
    BPlusTree::_InsertDuplicate(Transaction& transaction, CachedNode& cached,  
    12081205                if (cached.MakeWritable(transaction) == NULL)
    12091206                    return B_IO_ERROR;
    12101207
    1211                 values[index]
    1212                     = HOST_ENDIAN_TO_BFS_INT64(bplustree_node::MakeLink(
    1213                         BPLUSTREE_DUPLICATE_NODE, offset));
     1208                node->SetValueAt(index,
     1209                    HOST_ENDIAN_TO_BFS_INT64(bplustree_node::MakeLink(
     1210                        BPLUSTREE_DUPLICATE_NODE, offset)));
    12141211            }
    12151212
    12161213            return B_OK;
    BPlusTree::_InsertDuplicate(Transaction& transaction, CachedNode& cached,  
    12901287    if (cached.MakeWritable(transaction) == NULL)
    12911288        return B_IO_ERROR;
    12921289
    1293     values[index] = HOST_ENDIAN_TO_BFS_INT64(bplustree_node::MakeLink(
    1294         BPLUSTREE_DUPLICATE_FRAGMENT, offset, fragmentIndex));
     1290    node->SetValueAt(index, HOST_ENDIAN_TO_BFS_INT64(bplustree_node::MakeLink(
     1291        BPLUSTREE_DUPLICATE_FRAGMENT, offset, fragmentIndex)));
    12951292
    12961293    return B_OK;
    12971294}
    BPlusTree::_InsertKey(bplustree_node* node, uint16 index, uint8* key,  
    13051302    if (index > node->NumKeys())
    13061303        return;
    13071304
    1308     off_t* values = node->Values();
    1309     uint16* keyLengths = node->KeyLengths();
     1305    uint8* values = (uint8*)node->ValuesBase();
     1306    uint8* keyLengths = (uint8*)node->KeyLengthsBase();
    13101307    uint8* keys = node->Keys();
    13111308
    13121309    node->all_key_count = HOST_ENDIAN_TO_BFS_INT16(node->NumKeys() + 1);
    13131310    node->all_key_length = HOST_ENDIAN_TO_BFS_INT16(node->AllKeyLength()
    13141311        + keyLength);
    13151312
    1316     off_t* newValues = node->Values();
    1317     uint16* newKeyLengths = node->KeyLengths();
     1313    uint8* newValues = (uint8*)node->ValuesBase();
     1314    uint8* newKeyLengths = (uint8*)node->KeyLengthsBase();
    13181315
    13191316    // move values and copy new value into them
    1320     memmove(newValues + index + 1, values + index,
    1321         sizeof(off_t) * (node->NumKeys() - 1 - index));
     1317    memmove(newValues + (index + 1) * sizeof(off_t), values + index
     1318            * sizeof(off_t), sizeof(off_t) * (node->NumKeys() - 1 - index));
    13221319    memmove(newValues, values, sizeof(off_t) * index);
    13231320
    1324     newValues[index] = HOST_ENDIAN_TO_BFS_INT64(value);
     1321    node->SetValueAt(index, HOST_ENDIAN_TO_BFS_INT64(value));
    13251322
    1326     // move and update key length index
     1323    memmove(newKeyLengths + (index + 1) * sizeof(uint16), keyLengths + index
     1324            * sizeof(uint16), sizeof(uint16) * (node->NumKeys() - 1 - index));
     1325
     1326    // update key length index
    13271327    for (uint16 i = node->NumKeys(); i-- > index + 1;) {
    1328         newKeyLengths[i] = HOST_ENDIAN_TO_BFS_INT16(
    1329             BFS_ENDIAN_TO_HOST_INT16(keyLengths[i - 1]) + keyLength);
     1328        node->SetKeyLengthAt(i, HOST_ENDIAN_TO_BFS_INT16(
     1329            BFS_ENDIAN_TO_HOST_INT16(node->KeyLengthAt(i) + keyLength)));
    13301330    }
     1331
    13311332    memmove(newKeyLengths, keyLengths, sizeof(uint16) * index);
    13321333
    13331334    int32 keyStart;
    1334     newKeyLengths[index] = HOST_ENDIAN_TO_BFS_INT16(keyLength
     1335    node->SetKeyLengthAt(index, HOST_ENDIAN_TO_BFS_INT16(keyLength
    13351336        + (keyStart = index > 0
    1336             ? BFS_ENDIAN_TO_HOST_INT16(newKeyLengths[index - 1]) : 0));
     1337            ? BFS_ENDIAN_TO_HOST_INT16(node->KeyLengthAt(index - 1)) : 0)));
    13371338
    13381339    // move keys and copy new key into them
    1339     uint16 length = BFS_ENDIAN_TO_HOST_INT16(newKeyLengths[index]);
     1340    uint16 length = BFS_ENDIAN_TO_HOST_INT16(node->KeyLengthAt(index));
    13401341    int32 size = node->AllKeyLength() - length;
    13411342    if (size > 0)
    13421343        memmove(keys + length, keys + length - keyLength, size);
    BPlusTree::_SplitNode(bplustree_node* node, off_t nodeOffset,  
    13571358    if (*_keyIndex > node->NumKeys() + 1)
    13581359        return B_BAD_VALUE;
    13591360
    1360     uint16* inKeyLengths = node->KeyLengths();
    1361     off_t* inKeyValues = node->Values();
     1361    uint8* inKeyLengths = (uint8*)node->KeyLengthsBase();
     1362    uint8* inKeyValues = (uint8*)node->ValuesBase();
    13621363    uint8* inKeys = node->Keys();
    13631364    uint8* outKeys = other->Keys();
    13641365    int32 keyIndex = *_keyIndex;    // can become less than zero!
    BPlusTree::_SplitNode(bplustree_node* node, off_t nodeOffset,  
    13831384    for (in = out = 0; in < node->NumKeys() + 1;) {
    13841385        if (!bytes) {
    13851386            bytesBefore = in > 0
    1386                 ? BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[in - 1]) : 0;
     1387                ? BFS_ENDIAN_TO_HOST_INT16(node->KeyLengthAt(in - 1)) : 0;
    13871388        }
    13881389
    13891390        if (in == keyIndex && !bytes) {
    13901391            bytes = *_keyLength;
    13911392        } else {
    13921393            if (keyIndex < out) {
    1393                 bytesAfter = BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[in])
     1394                bytesAfter = BFS_ENDIAN_TO_HOST_INT16(node->KeyLengthAt(in))
    13941395                    - bytesBefore;
    13951396            }
    13961397
    BPlusTree::_SplitNode(bplustree_node* node, off_t nodeOffset,  
    14081409    // if the new key was not inserted, set the length of the keys
    14091410    // that can be copied directly
    14101411    if (keyIndex >= out && in > 0)
    1411         bytesBefore = BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[in - 1]);
     1412        bytesBefore = BFS_ENDIAN_TO_HOST_INT16(node->KeyLengthAt(in - 1));
    14121413
    14131414    if (bytesBefore < 0 || bytesAfter < 0)
    14141415        return B_BAD_DATA;
    BPlusTree::_SplitNode(bplustree_node* node, off_t nodeOffset,  
    14191420        + bytesAfter);
    14201421    other->all_key_count = HOST_ENDIAN_TO_BFS_INT16(out);
    14211422
    1422     uint16* outKeyLengths = other->KeyLengths();
    1423     off_t* outKeyValues = other->Values();
     1423    uint8* outKeyLengths = (uint8*)other->KeyLengthsBase();
     1424    uint8* outKeyValues = (uint8*)other->ValuesBase();
    14241425    int32 keys = out > keyIndex ? keyIndex : out;
    14251426
    14261427    if (bytesBefore) {
    BPlusTree::_SplitNode(bplustree_node* node, off_t nodeOffset,  
    14321433    if (bytes) {
    14331434        // copy the newly inserted key
    14341435        memcpy(outKeys + bytesBefore, key, bytes);
    1435         outKeyLengths[keyIndex] = HOST_ENDIAN_TO_BFS_INT16(bytes + bytesBefore);
    1436         outKeyValues[keyIndex] = HOST_ENDIAN_TO_BFS_INT64(*_value);
     1436        other->SetKeyLengthAt(keyIndex,
     1437            HOST_ENDIAN_TO_BFS_INT16(bytes + bytesBefore));
     1438        other->SetValueAt(keyIndex, HOST_ENDIAN_TO_BFS_INT64(*_value));
    14371439
    14381440        if (bytesAfter) {
    14391441            // copy the keys after the new key
    BPlusTree::_SplitNode(bplustree_node* node, off_t nodeOffset,  
    14411443                bytesAfter);
    14421444            keys = out - keyIndex - 1;
    14431445            for (int32 i = 0;i < keys;i++) {
    1444                 outKeyLengths[keyIndex + i + 1] = HOST_ENDIAN_TO_BFS_INT16(
    1445                     BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[keyIndex + i])
    1446                         + bytes);
     1446                other->SetKeyLengthAt(keyIndex + i + 1,
     1447                    HOST_ENDIAN_TO_BFS_INT16(BFS_ENDIAN_TO_HOST_INT16(
     1448                        node->KeyLengthAt(keyIndex + i)) + bytes));
    14471449            }
    1448             memcpy(outKeyValues + keyIndex + 1, inKeyValues + keyIndex,
    1449                 keys * sizeof(off_t));
     1450            memcpy(outKeyValues + (keyIndex + 1) * sizeof(off_t),
     1451                inKeyValues + keyIndex * sizeof(off_t), keys * sizeof(off_t));
    14501452        }
    14511453    }
    14521454
    BPlusTree::_SplitNode(bplustree_node* node, off_t nodeOffset,  
    14901492            newAllocated = true;
    14911493            memcpy(newKey, droppedKey, newLength);
    14921494
    1493             other->overflow_link = inKeyValues[in];
    1494             total = BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[in++]);
     1495            other->overflow_link = node->ValueAt(in);
     1496            total = BFS_ENDIAN_TO_HOST_INT16(node->KeyLengthAt(in++));
    14951497        }
    14961498    }
    14971499
    BPlusTree::_SplitNode(bplustree_node* node, off_t nodeOffset,  
    15071509            // not need to know the exact length of all keys in this
    15081510            // loop
    15091511            bytesBefore = in > skip
    1510                 ? BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[in - 1]) : 0;
     1512                ? BFS_ENDIAN_TO_HOST_INT16(node->KeyLengthAt(in - 1)) : 0;
    15111513            bytes = *_keyLength;
    15121514            out++;
    15131515        } else {
    15141516            if (in < node->NumKeys()) {
    1515                 inKeyLengths[in] = HOST_ENDIAN_TO_BFS_INT16(
    1516                     BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[in]) - total);
     1517                node->SetKeyLengthAt(in, HOST_ENDIAN_TO_BFS_INT16(
     1518                    BFS_ENDIAN_TO_HOST_INT16(node->KeyLengthAt(in)) - total));
    15171519
    15181520                if (bytes) {
    1519                     inKeyLengths[in] = HOST_ENDIAN_TO_BFS_INT16(
    1520                         BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[in]) + bytes);
     1521                    node->SetKeyLengthAt(in, HOST_ENDIAN_TO_BFS_INT16(
     1522                        BFS_ENDIAN_TO_HOST_INT16(node->KeyLengthAt(in))
     1523                            + bytes));
    15211524
    1522                     bytesAfter = BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[in])
     1525                    bytesAfter = BFS_ENDIAN_TO_HOST_INT16(node->KeyLengthAt(in))
    15231526                        - bytesBefore - bytes;
    15241527                }
    15251528                out++;
    BPlusTree::_SplitNode(bplustree_node* node, off_t nodeOffset,  
    15451548    node->all_key_count = HOST_ENDIAN_TO_BFS_INT16(out);
    15461549
    15471550    // array positions have changed
    1548     outKeyLengths = node->KeyLengths();
    1549     outKeyValues = node->Values();
     1551    outKeyLengths = (uint8*)node->KeyLengthsBase();
     1552    outKeyValues = (uint8*)node->ValuesBase();
    15501553
    15511554    // move the keys in the old node: the order is important here,
    15521555    // because we don't want to overwrite any contents
    BPlusTree::_SplitNode(bplustree_node* node, off_t nodeOffset,  
    15651568            bytesAfter);
    15661569    }
    15671570
    1568     if (bytesBefore)
    1569         memmove(outKeyLengths, inKeyLengths + skip, keys * sizeof(uint16));
     1571    if (bytesBefore) {
     1572        memmove(outKeyLengths, inKeyLengths + skip * sizeof(uint16),
     1573            keys * sizeof(uint16));
     1574    }
     1575
    15701576    if (bytesAfter) {
    15711577        // if byteAfter is > 0, keyIndex is larger than skip
    1572         memmove(outKeyLengths + keyIndex + 1, inKeyLengths + skip + keyIndex,
     1578        memmove(outKeyLengths + (keyIndex + 1) * sizeof(uint16),
     1579            inKeyLengths + (skip + keyIndex) * sizeof(uint16),
    15731580            in * sizeof(uint16));
    15741581    }
    15751582
    15761583    if (bytesBefore)
    1577         memmove(outKeyValues, inKeyValues + skip, keys * sizeof(off_t));
     1584        memmove(outKeyValues, inKeyValues + skip * sizeof(off_t),
     1585            keys * sizeof(off_t));
    15781586    if (bytesAfter) {
    1579         memmove(outKeyValues + keyIndex + 1, inKeyValues + skip + keyIndex,
     1587        memmove(outKeyValues + (keyIndex + 1) * sizeof(off_t),
     1588            inKeyValues + (skip + keyIndex) * sizeof(off_t),
    15801589            in * sizeof(off_t));
    15811590    }
    15821591
    15831592    if (bytes) {
    15841593        // finally, copy the newly inserted key (don't overwrite anything)
    15851594        memcpy(inKeys + bytesBefore, key, bytes);
    1586         outKeyLengths[keyIndex] = HOST_ENDIAN_TO_BFS_INT16(bytes + bytesBefore);
    1587         outKeyValues[keyIndex] = HOST_ENDIAN_TO_BFS_INT64(*_value);
     1595        node->SetKeyLengthAt(keyIndex,
     1596            HOST_ENDIAN_TO_BFS_INT16(bytes + bytesBefore));
     1597        node->SetValueAt(keyIndex, HOST_ENDIAN_TO_BFS_INT64(*_value));
    15881598    }
    15891599
    15901600    // Prepare the key that will be inserted in the parent node which
    BPlusTree::_RemoveDuplicate(Transaction& transaction,  
    17661776    const bplustree_node* node, CachedNode& cached, uint16 index,
    17671777    off_t value)
    17681778{
    1769     off_t* values = node->Values();
    1770     off_t oldValue = BFS_ENDIAN_TO_HOST_INT64(values[index]);
     1779    off_t oldValue = BFS_ENDIAN_TO_HOST_INT64(node->ValueAt(index));
    17711780
    17721781    CachedNode cachedDuplicate(this);
    17731782    off_t duplicateOffset = bplustree_node::FragmentOffset(oldValue);
    BPlusTree::_RemoveDuplicate(Transaction& transaction,  
    18021811            if (cached.MakeWritable(transaction) == NULL)
    18031812                return B_IO_ERROR;
    18041813
    1805             values[index] = array->values[0];
     1814            node->SetValueAt(index, array->values[0]);
    18061815
    18071816            // Remove the whole fragment node, if this was the only array,
    18081817            // otherwise free just the array
    BPlusTree::_RemoveDuplicate(Transaction& transaction,  
    18771886                    // This is the last node, and there is only one value left;
    18781887                    // replace the duplicate link with that value, it's no
    18791888                    // duplicate anymore
    1880                     values[index] = array->values[0];
     1889                    node->SetValueAt(index, array->values[0]);
    18811890                } else {
    18821891                    // Move the duplicate link to the next node
    1883                     values[index] = HOST_ENDIAN_TO_BFS_INT64(
     1892                    node->SetValueAt(index, HOST_ENDIAN_TO_BFS_INT64(
    18841893                        bplustree_node::MakeLink(
    1885                             BPLUSTREE_DUPLICATE_NODE, right));
     1894                            BPLUSTREE_DUPLICATE_NODE, right)));
    18861895                }
    18871896            }
    18881897
    BPlusTree::_RemoveDuplicate(Transaction& transaction,  
    19541963            if (cached.MakeWritable(transaction) == NULL)
    19551964                return B_IO_ERROR;
    19561965
    1957             values[index] = HOST_ENDIAN_TO_BFS_INT64(bplustree_node::MakeLink(
    1958                 BPLUSTREE_DUPLICATE_FRAGMENT, duplicateOffset, fragmentIndex));
     1966            node->SetValueAt(index,
     1967                HOST_ENDIAN_TO_BFS_INT64(bplustree_node::MakeLink(
     1968                    BPLUSTREE_DUPLICATE_FRAGMENT, duplicateOffset,
     1969                        fragmentIndex)));
    19591970        }
    19601971        return B_OK;
    19611972    }
    BPlusTree::_RemoveKey(bplustree_node* node, uint16 index)  
    19771988        return;
    19781989    }
    19791990
    1980     off_t* values = node->Values();
    1981 
    19821991    // if we would have to drop the overflow link, drop
    19831992    // the last key instead and update the overflow link
    19841993    // to the value of that one
    19851994    if (!node->IsLeaf() && index == node->NumKeys())
    1986         node->overflow_link = values[--index];
     1995        node->overflow_link = node->ValueAt(--index);
    19871996
    19881997    uint16 length;
    19891998    uint8* key = node->KeyAt(index, &length);
    BPlusTree::_RemoveKey(bplustree_node* node, uint16 index)  
    19952004        return;
    19962005    }
    19972006
    1998     uint16* keyLengths = node->KeyLengths();
     2007    uint8* values = (uint8*)node->ValuesBase();
     2008    uint8* keyLengths = (uint8*)node->KeyLengthsBase();
    19992009    uint8* keys = node->Keys();
    20002010
    20012011    node->all_key_count = HOST_ENDIAN_TO_BFS_INT16(node->NumKeys() - 1);
    20022012    node->all_key_length = HOST_ENDIAN_TO_BFS_INT64(
    20032013        node->AllKeyLength() - length);
    20042014
    2005     off_t* newValues = node->Values();
    2006     uint16* newKeyLengths = node->KeyLengths();
     2015    uint8* newValues = (uint8*)node->ValuesBase();
     2016    uint8* newKeyLengths = (uint8*)node->KeyLengthsBase();
    20072017
    20082018    // move key data
    20092019    memmove(key, key + length, node->AllKeyLength() - (key - keys));
    BPlusTree::_RemoveKey(bplustree_node* node, uint16 index)  
    20112021    // move and update key lengths
    20122022    if (index > 0 && newKeyLengths != keyLengths)
    20132023        memmove(newKeyLengths, keyLengths, index * sizeof(uint16));
     2024    memmove(newKeyLengths + index * sizeof(uint16), keyLengths + (index + 1)
     2025            * sizeof(uint16), (node->NumKeys() - index) * sizeof(uint16));
    20142026    for (uint16 i = index; i < node->NumKeys(); i++) {
    2015         newKeyLengths[i] = HOST_ENDIAN_TO_BFS_INT16(
    2016             BFS_ENDIAN_TO_HOST_INT16(keyLengths[i + 1]) - length);
     2027        node->SetKeyLengthAt(i, HOST_ENDIAN_TO_BFS_INT16(
     2028            BFS_ENDIAN_TO_HOST_INT16(node->KeyLengthAt(i)) - length));
    20172029    }
    20182030
    20192031    // move values
    20202032    if (index > 0)
    20212033        memmove(newValues, values, index * sizeof(off_t));
    20222034    if (node->NumKeys() > index) {
    2023         memmove(newValues + index, values + index + 1,
    2024             (node->NumKeys() - index) * sizeof(off_t));
     2035        memmove(newValues + index * sizeof(off_t), values + (index + 1)
     2036                * sizeof(off_t), (node->NumKeys() - index) * sizeof(off_t));
    20252037    }
    20262038}
    20272039
    BPlusTree::Remove(Transaction& transaction, const uint8* key, uint16 keyLength,  
    20632075
    20642076            // Is this a duplicate entry?
    20652077            if (bplustree_node::IsDuplicate(BFS_ENDIAN_TO_HOST_INT64(
    2066                     node->Values()[nodeAndKey.keyIndex]))) {
     2078                    node->ValueAt(nodeAndKey.keyIndex)))) {
    20672079                if (fAllowDuplicates) {
    20682080                    return _RemoveDuplicate(transaction, node, cached,
    20692081                        nodeAndKey.keyIndex, value);
    BPlusTree::Remove(Transaction& transaction, const uint8* key, uint16 keyLength,  
    20732085                    "allowed, inode %" B_PRIdOFF "!\n", fStream->ID()));
    20742086                RETURN_ERROR(B_ERROR);
    20752087            } else {
    2076                 if (node->Values()[nodeAndKey.keyIndex] != value)
     2088                if (node->ValueAt(nodeAndKey.keyIndex) != value)
    20772089                    return B_ENTRY_NOT_FOUND;
    20782090
    20792091                // If we will remove the last key, the iterator will be set
    BPlusTree::Replace(Transaction& transaction, const uint8* key, uint16 keyLength,  
    21822194            if (status == B_OK) {
    21832195                bplustree_node* writableNode = cached.MakeWritable(transaction);
    21842196                if (writableNode != NULL) {
    2185                     writableNode->Values()[keyIndex]
    2186                         = HOST_ENDIAN_TO_BFS_INT64(value);
     2197                    writableNode->SetValueAt(keyIndex,
     2198                        HOST_ENDIAN_TO_BFS_INT64(value));
    21872199                } else
    21882200                    status = B_IO_ERROR;
    21892201            }
    BPlusTree::Find(const uint8* key, uint16 keyLength, off_t* _value)  
    22412253#endif
    22422254        if (node->OverflowLink() == BPLUSTREE_NULL) {
    22432255            if (status == B_OK && _value != NULL)
    2244                 *_value = BFS_ENDIAN_TO_HOST_INT64(node->Values()[keyIndex]);
     2256                *_value = BFS_ENDIAN_TO_HOST_INT64(node->ValueAt(keyIndex));
    22452257
    22462258#ifdef DEBUG
    22472259            if (levels != (int32)fHeader.MaxNumberOfLevels())
    BPlusTree::_ValidateChildren(TreeCheck& check, uint32 level, off_t offset,  
    22892301    check.SetVisited(offset);
    22902302
    22912303    uint32 count = parent->NumKeys();
    2292     off_t* values = parent->Values();
    22932304    off_t lastOffset = check.PreviousOffset(level);
    22942305    CachedNode cached(this);
    22952306
    BPlusTree::_ValidateChildren(TreeCheck& check, uint32 level, off_t offset,  
    23072318            }
    23082319        }
    23092320
    2310         off_t childOffset = BFS_ENDIAN_TO_HOST_INT64(values[i]);
     2321        off_t childOffset = BFS_ENDIAN_TO_HOST_INT64(parent->ValueAt(i));
    23112322        if (bplustree_node::IsDuplicate(childOffset)) {
    23122323            // Walk the duplicate nodes
    23132324            off_t duplicateOffset = bplustree_node::FragmentOffset(childOffset);
    BPlusTree::_ValidateChildren(TreeCheck& check, uint32 level, off_t offset,  
    24032414            // Test a regular child node recursively
    24042415            off_t nextOffset = parent->OverflowLink();
    24052416            if (i < count - 1)
    2406                 nextOffset = BFS_ENDIAN_TO_HOST_INT64(values[i + 1]);
     2417                nextOffset = BFS_ENDIAN_TO_HOST_INT64(parent->ValueAt(i + 1));
    24072418
    24082419            if (i == 0 && lastOffset != BPLUSTREE_NULL) {
    24092420                // Test right link of the previous node
    TreeIterator::Goto(int8 to)  
    25332544            nextOffset = node->OverflowLink();
    25342545        else {
    25352546            if (node->AllKeyLength() > fTree->fNodeSize
    2536                 || (addr_t)node->Values() > (addr_t)node + fTree->fNodeSize
     2547                || (addr_t)node->ValuesBase() > (addr_t)node + fTree->fNodeSize
    25372548                    - 8 * node->NumKeys())
    25382549                RETURN_ERROR(B_ERROR);
    25392550
    2540             nextOffset = BFS_ENDIAN_TO_HOST_INT64(node->Values()[0]);
     2551            nextOffset = BFS_ENDIAN_TO_HOST_INT64(node->ValueAt(0));
    25412552        }
    25422553        if (nextOffset == nodeOffset)
    25432554            break;
    TreeIterator::Traverse(int8 direction, void* key, uint16* keyLength,  
    26742685    }
    26752686    *keyLength = length;
    26762687
    2677     off_t offset = BFS_ENDIAN_TO_HOST_INT64(node->Values()[fCurrentKey]);
     2688    off_t offset = BFS_ENDIAN_TO_HOST_INT64(node->ValueAt(fCurrentKey));
    26782689
    26792690    // duplicate fragments?
    26802691    uint8 type = bplustree_node::LinkType(offset);
    bplustree_node::KeyAt(int32 index, uint16* keyLength) const  
    28402851        return NULL;
    28412852
    28422853    uint8* keyStart = Keys();
    2843     uint16* keyLengths = KeyLengths();
    28442854
    2845     *keyLength = BFS_ENDIAN_TO_HOST_INT16(keyLengths[index])
    2846         - (index != 0 ? BFS_ENDIAN_TO_HOST_INT16(keyLengths[index - 1]) : 0);
     2855    *keyLength = BFS_ENDIAN_TO_HOST_INT16(KeyLengthAt(index))
     2856        - (index != 0 ? BFS_ENDIAN_TO_HOST_INT16(KeyLengthAt(index - 1)) : 0);
    28472857    if (index > 0)
    2848         keyStart += BFS_ENDIAN_TO_HOST_INT16(keyLengths[index - 1]);
     2858        keyStart += BFS_ENDIAN_TO_HOST_INT16(KeyLengthAt(index - 1));
    28492859
    28502860    return keyStart;
    28512861}
    bplustree_node::CheckIntegrity(uint32 nodeSize) const  
    29122922            dprintf("invalid node %p, key %d: keys corrupted\n", this, (int)i);
    29132923            return B_BAD_DATA;
    29142924        }
    2915         if (Values()[i] == -1) {
     2925        if (ValueAt(i) == -1) {
    29162926            dprintf("invalid node %p, value %d: %" B_PRIdOFF ": values "
    2917                 "corrupted\n", this, (int)i, Values()[i]);
     2927                "corrupted\n", this, (int)i, ValueAt(i));
    29182928            return B_BAD_DATA;
    29192929        }
    29202930    }
  • src/add-ons/kernel/file_systems/bfs/BPlusTree.h

    diff --git a/src/add-ons/kernel/file_systems/bfs/BPlusTree.h b/src/add-ons/kernel/file_systems/bfs/BPlusTree.h
    index c1e1ad2..096e57f 100644
    a b struct bplustree_node {  
    8484                                    { return BFS_ENDIAN_TO_HOST_INT16(
    8585                                        all_key_length); }
    8686
    87     inline  uint16*             KeyLengths() const;
    88     inline  off_t*              Values() const;
     87    inline  void*               KeyLengthsBase() const;
     88    inline  uint16              KeyLengthAt(uint16 index) const;
     89    inline  void                SetKeyLengthAt(uint16 index,
     90                                    uint16 value) const;
     91    inline  void*               ValuesBase() const;
     92    inline  off_t               ValueAt(uint16 index) const;
     93    inline  void                SetValueAt(uint16 index, off_t value) const;
    8994    inline  uint8*              Keys() const;
    9095    inline  int32               Used() const;
    9196            uint8*              KeyAt(int32 index, uint16* keyLength) const;
    bplustree_header::CheckNode(bplustree_node* node) const  
    495500    return IsValidLink(node->LeftLink())
    496501        && IsValidLink(node->RightLink())
    497502        && IsValidLink(node->OverflowLink())
    498         && (int8*)node->Values() + node->NumKeys() * sizeof(off_t)
     503        && (int8*)node->ValuesBase() + node->NumKeys() * sizeof(off_t)
    499504                <= (int8*)node + NodeSize();
    500505}
    501506
    bplustree_header::IsValidLink(off_t link) const  
    511516//  #pragma mark - bplustree_node inline functions
    512517
    513518
    514 inline uint16*
    515 bplustree_node::KeyLengths() const
     519inline void*
     520bplustree_node::KeyLengthsBase() const
    516521{
    517     return (uint16*)(((char*)this) + key_align(sizeof(bplustree_node)
    518         + AllKeyLength()));
     522    return (uint8*)this + key_align(sizeof(bplustree_node) + AllKeyLength());
    519523}
    520524
    521525
    522 inline off_t*
    523 bplustree_node::Values() const
     526inline uint16
     527bplustree_node::KeyLengthAt(uint16 index) const
    524528{
    525     return (off_t*)((char*)KeyLengths() + NumKeys() * sizeof(uint16));
     529    uint16 result;
     530    memcpy(&result, (uint8*)KeyLengthsBase() + index * sizeof(uint16),
     531        sizeof(uint16));
     532    return result;
     533}
     534
     535
     536inline void
     537bplustree_node::SetKeyLengthAt(uint16 index, uint16 value) const
     538{
     539    memcpy((uint8*)KeyLengthsBase() + index * sizeof(uint16), &value,
     540        sizeof(uint16));
     541}
     542
     543
     544inline void*
     545bplustree_node::ValuesBase() const
     546{
     547    return (uint8*)KeyLengthsBase() + NumKeys() * sizeof(uint16);
     548}
     549
     550
     551inline off_t
     552bplustree_node::ValueAt(uint16 index) const
     553{
     554    off_t result;
     555    memcpy(&result, (uint8*)ValuesBase() + index * sizeof(off_t),
     556        sizeof(off_t));
     557    return result;
     558}
     559
     560
     561inline void
     562bplustree_node::SetValueAt(uint16 index, off_t value) const
     563{
     564    memcpy((uint8*)ValuesBase() + index * sizeof(off_t), &value, sizeof(off_t));
    526565}
    527566
    528567
  • src/add-ons/kernel/file_systems/bfs/Debug.cpp

    diff --git a/src/add-ons/kernel/file_systems/bfs/Debug.cpp b/src/add-ons/kernel/file_systems/bfs/Debug.cpp
    index 02a8a58..d98f10b 100644
    a b dump_bplustree_node(const bplustree_node* node, const bplustree_header* header,  
    227227        memcpy(buffer, key, length);
    228228        buffer[length] = '\0';
    229229
    230         off_t* value = node->Values() + i;
    231         if ((addr_t)value < (addr_t)node
    232             || (addr_t)value > (addr_t)node + header->node_size)
     230        uint8* valueAddress = (uint8*)node->ValuesBase() + i * sizeof(off_t);
     231        if ((addr_t)valueAddress < (addr_t)node
     232            || (addr_t)valueAddress > (addr_t)node + header->node_size)
    233233            kprintf("  %2d. Invalid Offset!!\n", (int)i);
    234234        else {
    235235            kprintf("  %2d. ", (int)i);
    dump_bplustree_node(const bplustree_node* node, const bplustree_header* header,  
    247247            } else
    248248                kprintf("???");
    249249
    250             off_t offset = *value & 0x3fffffffffffffffLL;
     250            off_t value = node->ValueAt(i);
     251            off_t offset = value & 0x3fffffffffffffffLL;
    251252            kprintf(" (%d bytes) -> %" B_PRIdOFF, length, offset);
    252253            if (volume != NULL) {
    253254                block_run run = volume->ToBlockRun(offset);
    254255                kprintf(" (%d, %d)", (int)run.allocation_group, run.start);
    255256            }
    256             if (bplustree_node::LinkType(*value)
     257            if (bplustree_node::LinkType(value)
    257258                    == BPLUSTREE_DUPLICATE_FRAGMENT) {
    258259                kprintf(" (duplicate fragment %" B_PRIdOFF ")\n",
    259                     *value & 0x3ff);
    260             } else if (bplustree_node::LinkType(*value)
     260                    value & 0x3ff);
     261            } else if (bplustree_node::LinkType(value)
    261262                    == BPLUSTREE_DUPLICATE_NODE) {
    262263                kprintf(" (duplicate node)\n");
    263264            } else