core: import NSS bitmap helper directly into libnwcore
All checks were successful
Source release / source-package (push) Successful in 1m10s
All checks were successful
Source release / source-package (push) Successful in 1m10s
This commit is contained in:
9
AI.md
9
AI.md
@@ -2400,3 +2400,12 @@ logs/archives are usually copied or uploaded later by a normal desktop user.
|
||||
(`no-device`, `unsupported`, `probe-failed`). A real Linuxquota `set-failed`
|
||||
on a QUOTA-style volume is an error to fix, not a reason to create a parallel
|
||||
metadata-authoritative state.
|
||||
|
||||
## NSS low-level library import policy
|
||||
|
||||
- Keep original NSS file names and public API names when importing small GPL-2 NSS library helpers.
|
||||
- Do not hide imported helpers under an artificial `nss/` public API/source path in `libnwcore`; imported core helpers live directly in `src/core/` and expose the original header/API names so their NSS origin remains recognizable.
|
||||
- First imported compiled helper: NSS `public_core/nss/lib/bitmap.c` -> MARS-NWE `src/core/bitmap.c`, linked into `libnwcore` with original `bitmap.h` API (`BitMap_s`, `newBitMap`, `findBits`, etc.).
|
||||
- The existing NSS SDK include layout under `include/nwfs/nss/sdk/...` remains available for compatibility and provenance; the compiled library source is what moves into `src/core/`.
|
||||
- NSS runtime-only dependencies may be reduced only as needed to compile outside NSS; for bitmap this only maps NSS `zalloc()` to libc `calloc()`.
|
||||
- Future candidates to import with original names: CRC/hash helpers after Unicode dependency review, queue macros, bit helpers, and media/type helpers already represented by the SDK headers.
|
||||
|
||||
@@ -3568,3 +3568,11 @@ restore source, not an alternate authority after a kernel `set-failed`.
|
||||
- No private MARS persistent usage xattr is part of the design.
|
||||
- The live all-smoke and DOS board-tool quota smoke are the regression gates for
|
||||
this area.
|
||||
|
||||
|
||||
### NSS low-level library imports
|
||||
|
||||
- Prefer importing small GPL-2 NSS low-level library helpers with original file/API names where they can be compiled outside the NSS runtime.
|
||||
- Imported compiled helpers should live directly in `libnwcore` source/include space rather than in an artificial `nss/` subpath; existing NSS SDK compatibility headers may keep their original source-like paths.
|
||||
- Initial compiled import is `bitmap.c`/`bitmap.h` in `libnwcore`; replace local duplicate bitmap/bit allocation helpers gradually only after tests cover each call site.
|
||||
- Keep libowfat-provided primitives where they are already the better fit; use NSS helpers where NetWare/NSS source compatibility or media-layout semantics matter.
|
||||
|
||||
8
TODO.md
8
TODO.md
@@ -190,3 +190,11 @@ These items are no longer active TODOs. Keep patch-by-patch chronology in
|
||||
SYS metadata, NWQUOTA userquota and an `nw.log` slice.
|
||||
- The DOS quota smoke proves the same write-deny boundary from DOS board tools
|
||||
for both `QUOTA` and `SYS`.
|
||||
|
||||
|
||||
### NSS low-level library imports
|
||||
|
||||
- Import small GPL-2 NSS low-level library helpers with original file/API names where they can be compiled outside the NSS runtime.
|
||||
- Keep imported compiled helpers directly in `src/core/`/`libnwcore`, not under a new artificial `nss/` subdirectory; preserve original names so the NSS provenance and possible external-source compatibility remain clear.
|
||||
- Initial compiled import is `bitmap.c`/`bitmap.h` in `libnwcore`; replace local duplicate bitmap/bit allocation helpers gradually only after tests cover each call site.
|
||||
- Keep libowfat-provided primitives where they are already the better fit; use NSS helpers where NetWare/NSS source compatibility or media-layout semantics matter.
|
||||
|
||||
@@ -40,9 +40,13 @@ configure_file(
|
||||
"${NWCORE_BUILD_INCLUDE_DIR}/yyjson.h"
|
||||
COPYONLY)
|
||||
|
||||
set(NWCORE_IMPORTED_NSS_SOURCES
|
||||
bitmap.c)
|
||||
|
||||
add_library(nwcore SHARED
|
||||
core.c
|
||||
${NWCORE_ZLOG_SOURCES}
|
||||
${NWCORE_IMPORTED_NSS_SOURCES}
|
||||
"${NWCORE_YYJSON_DIR}/src/yyjson.c")
|
||||
add_library(mars_nwe::core ALIAS nwcore)
|
||||
|
||||
|
||||
374
src/core/bitmap.c
Normal file
374
src/core/bitmap.c
Normal file
@@ -0,0 +1,374 @@
|
||||
/****************************************************************************
|
||||
|
|
||||
| (C) Copyright 1995-2005 Novell, Inc.
|
||||
| All Rights Reserved.
|
||||
|
|
||||
| This program is free software; you can redistribute it and/or
|
||||
| modify it under the terms of version 2 of the GNU General Public
|
||||
| License as published by the Free Software Foundation.
|
||||
|
|
||||
| This program is distributed in the hope that it will be useful,
|
||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
| GNU General Public License for more details.
|
||||
|
|
||||
| You should have received a copy of the GNU General Public License
|
||||
| along with this program; if not, contact Novell, Inc.
|
||||
|
|
||||
| To contact Novell about this file by physical or electronic mail,
|
||||
| you may find current contact information at www.novell.com
|
||||
|
|
||||
|***************************************************************************
|
||||
|
|
||||
| NetWare Advance File Services (NSS) Initialization module
|
||||
|
|
||||
|---------------------------------------------------------------------------
|
||||
|
|
||||
| $Author: randys $
|
||||
| $Date: 2005-01-11 23:43:47 +0530 (Tue, 11 Jan 2005) $
|
||||
|
|
||||
| $RCSfile$
|
||||
| $Revision: 511 $
|
||||
|
|
||||
|---------------------------------------------------------------------------
|
||||
| This module is used to:
|
||||
| Define routines for manipulating bit maps.
|
||||
+-------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* MARS-NWE imports this NSS low-level helper with its original public
|
||||
* function names and header name. The file is installed directly in the
|
||||
* libnwcore source directory instead of an artificial nss/ subdirectory so
|
||||
* the original NSS API remains recognizable. The original NSS source path
|
||||
* is public_core/nss/lib/bitmap.c. NSS normally gets zalloc() from its
|
||||
* loader/runtime library; libnwcore builds the helper outside that runtime,
|
||||
* so map the allocator to libc calloc while keeping the NSS API surface.
|
||||
*/
|
||||
#ifndef zalloc
|
||||
#define zalloc(_bytes) calloc(1, (_bytes))
|
||||
#endif
|
||||
|
||||
#include "omni.h"
|
||||
#include "bitmap.h"
|
||||
|
||||
NINT getMaxBits (BitMap_s *bitMap)
|
||||
{
|
||||
return bitMap->max;
|
||||
}
|
||||
|
||||
BOOL testABit (BitMap_s *bitMap, NINT bitNum)
|
||||
{
|
||||
return TST_BIT(bitMap->bits, bitNum);
|
||||
}
|
||||
void setAbit (BitMap_s *bitMap, NINT bitNum)
|
||||
{
|
||||
SET_BIT(bitMap->bits, bitNum);
|
||||
if (bitNum < bitMap->start)
|
||||
{
|
||||
bitMap->start = bitNum;
|
||||
}
|
||||
}
|
||||
|
||||
void setBits (BitMap_s *bitMap, NINT startBit, NINT numBits)
|
||||
{
|
||||
NINT *bits = bitMap->bits;
|
||||
NINT endBit = startBit + numBits;
|
||||
NINT i;
|
||||
|
||||
if (endBit > bitMap->max)
|
||||
{
|
||||
endBit = bitMap->max;
|
||||
}
|
||||
for (i = startBit; i < endBit; ++i)
|
||||
{
|
||||
SET_BIT(bits, i);
|
||||
}
|
||||
if (startBit < bitMap->start)
|
||||
{
|
||||
bitMap->start = startBit;
|
||||
}
|
||||
}
|
||||
|
||||
void clearAbit (BitMap_s *bitMap, NINT bitNum)
|
||||
{
|
||||
NINT *bits = bitMap->bits;
|
||||
|
||||
CLR_BIT(bits, bitNum);
|
||||
}
|
||||
|
||||
void clearBits (BitMap_s *bitMap, NINT startBit, NINT numBits)
|
||||
{
|
||||
NINT *bits = bitMap->bits;
|
||||
NINT endBit = startBit + numBits;
|
||||
NINT i;
|
||||
|
||||
if (endBit > bitMap->max)
|
||||
{
|
||||
endBit = bitMap->max;
|
||||
}
|
||||
for (i = startBit; i < endBit; ++i)
|
||||
{
|
||||
CLR_BIT(bits, i);
|
||||
}
|
||||
}
|
||||
|
||||
BitMap_s *newBitMap (BitMap_s *bitMap, NINT numBits)
|
||||
{
|
||||
NINT max = ALIGN(numBits, BITS_PER_NINT);
|
||||
NINT numBytes = max / BITS_PER_BYTE;
|
||||
NINT *bits;
|
||||
|
||||
bits = zalloc(numBytes);
|
||||
if (bits == NULL) return NULL;
|
||||
|
||||
bitMap->bits = bits;
|
||||
bitMap->max = max;
|
||||
bitMap->start = 0;
|
||||
|
||||
setBits(bitMap, 0, numBits);
|
||||
bitMap->max = numBits;
|
||||
|
||||
return bitMap;
|
||||
}
|
||||
|
||||
void freeBitMap (BitMap_s *bitMap)
|
||||
{
|
||||
if (bitMap->bits != NULL)
|
||||
{
|
||||
free(bitMap->bits);
|
||||
}
|
||||
}
|
||||
|
||||
NINT countBits (BitMap_s *bitMap)
|
||||
{
|
||||
NINT *bits = bitMap->bits;
|
||||
NINT max = bitMap->max;
|
||||
NINT numBits = 0;
|
||||
NINT i;
|
||||
|
||||
for (i = 0; i < max; ++i)
|
||||
{
|
||||
if (TST_BIT(bits, i))
|
||||
{
|
||||
++numBits;
|
||||
}
|
||||
}
|
||||
return numBits;
|
||||
}
|
||||
|
||||
SNINT findBits (BitMap_s *bitMap, NINT bitsNeeded)
|
||||
{
|
||||
NINT *bits = bitMap->bits;
|
||||
NINT numBits = 0;
|
||||
NINT start = 0;
|
||||
NINT i;
|
||||
|
||||
/*
|
||||
* Position start at the first set bit
|
||||
*/
|
||||
for (i = bitMap->start; i < bitMap->max; ++i)
|
||||
{
|
||||
if (TST_BIT(bits, i))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
bitMap->start = i;
|
||||
|
||||
for (; i < bitMap->max; ++i)
|
||||
{
|
||||
if (TST_BIT(bits, i))
|
||||
{
|
||||
++numBits;
|
||||
if (numBits == bitsNeeded)
|
||||
{
|
||||
start = (i + 1) - numBits;
|
||||
clearBits(bitMap, start, numBits);
|
||||
return start;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
numBits = 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
void printBitMap (BitMap_s *bitMap)
|
||||
{
|
||||
NINT i;
|
||||
const NINT max = bitMap->max;
|
||||
const NINT *bits = bitMap->bits;
|
||||
|
||||
printf(" max = %3d start = %3d\n", bitMap->max, bitMap->start);
|
||||
for (i = 0; i < max; ++i)
|
||||
{
|
||||
if (TST_BIT(bits, i))
|
||||
{
|
||||
printf("%d", i % 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(".");
|
||||
}
|
||||
if ((i + 1) % 64 == 0)
|
||||
{
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
// printf(" %d", countBits(bitMap));
|
||||
// if (i % 64 != 0) printf("\n");
|
||||
}
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct Allocated_s {
|
||||
NINT start;
|
||||
NINT length;
|
||||
} Allocated_s;
|
||||
|
||||
enum {
|
||||
USERS = 20,
|
||||
BLOCKS = 8,
|
||||
};
|
||||
|
||||
Allocated_s Users[USERS] = { 0 };
|
||||
BitMap_s BitMap;
|
||||
BitMap_s UsedBits;
|
||||
|
||||
void printUsers (void)
|
||||
{
|
||||
NINT i;
|
||||
|
||||
printf("Users:\n");
|
||||
for (i = 0; i < USERS; ++i) {
|
||||
printf("%d. %10d %10d\n", i, Users[i].start, Users[i].length);
|
||||
}
|
||||
}
|
||||
|
||||
void outOfMemory (NINT length)
|
||||
{
|
||||
printf("Could not allocate %d\n", length);
|
||||
|
||||
printBitMap( &BitMap);
|
||||
|
||||
printUsers();
|
||||
}
|
||||
|
||||
void checkUsers (void)
|
||||
{
|
||||
NINT i, j;
|
||||
|
||||
for (i = 0; i < USERS; ++i) {
|
||||
if (Users[i].length == 0) continue;
|
||||
for (j = 0; j < USERS; ++j) {
|
||||
if (i == j) continue;
|
||||
if (Users[j].length == 0) continue;
|
||||
if (Users[i].start + Users[i].length <= Users[j].start) continue;
|
||||
if (Users[j].start + Users[j].length <= Users[i].start) continue;
|
||||
printf("Overlapping users: %d %d\n", i, j);
|
||||
printUsers();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
Allocated_s *user;
|
||||
NINT length;
|
||||
SNINT start;
|
||||
NINT i, j;
|
||||
|
||||
if (newBitMap( &BitMap, BLOCKS) == NULL) return 1;
|
||||
if (newBitMap( &UsedBits, BLOCKS) == NULL) return 2;
|
||||
clearBits( &UsedBits, 0, BLOCKS);
|
||||
clearBits( &BitMap, 0, BLOCKS);
|
||||
|
||||
SET_BIT(BitMap.bits, BLOCKS);
|
||||
setBits( &BitMap, 0, BLOCKS);
|
||||
for (i = 0; i < 1000; ++i)
|
||||
{
|
||||
printBitMap( &BitMap);
|
||||
if (findBits( &BitMap, 4) == -1)
|
||||
{
|
||||
for (j = 0; j < 3*BLOCKS / 4; ++j)
|
||||
{
|
||||
setAbit( &BitMap, rand() % BLOCKS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 1000; ++i)
|
||||
{
|
||||
NINT bitNum = rand() % BLOCKS;
|
||||
NINT numBits = 2;
|
||||
|
||||
printBitMap( &BitMap);
|
||||
if (TST_BIT(BitMap.bits, bitNum))
|
||||
{
|
||||
printf(" Clear %3d ", bitNum);
|
||||
clearBits( &BitMap, bitNum, numBits);
|
||||
//clearAbit( &BitMap, bitNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" Set %3d ", bitNum);
|
||||
setBits( &BitMap, bitNum, numBits);
|
||||
//setAbit( &BitMap, bitNum);
|
||||
}
|
||||
}
|
||||
printBitMap( &BitMap);
|
||||
#if 0
|
||||
for (i = 0; i < 30; ++i) {
|
||||
// printBitMap( &BitMap);
|
||||
// printUsers();
|
||||
checkUsers();
|
||||
user = &Users[rand() % USERS];
|
||||
if (user->length == 0) {
|
||||
length = rand() % (BLOCKS / 6) + 1;
|
||||
start = findBits( &BitMap, length);
|
||||
if (start < 0) {
|
||||
NINT freeBits = countBits( &BitMap);
|
||||
|
||||
printf("%d %d %f\n", length, freeBits,
|
||||
(double)freeBits / (double)length);
|
||||
// outOfMemory(length);
|
||||
} else {
|
||||
user->length = length;
|
||||
user->start = start;
|
||||
}
|
||||
} else {
|
||||
setBits( &BitMap, user->start, user->length);
|
||||
user->length = 0;
|
||||
user->start = -1;
|
||||
}
|
||||
}
|
||||
/***************************************************************/
|
||||
if (newBitMap( &BitMap, BLOCKS) == NULL) return 1;
|
||||
if (newBitMap( &UsedBits, BLOCKS) == NULL) return 2;
|
||||
clearBits( &UsedBits, 0, BLOCKS);
|
||||
|
||||
for (i = 0; i < 10000; ++i)
|
||||
{
|
||||
NINT bitNum = rand() % BLOCKS;
|
||||
|
||||
if (TST_BIT(BitMap.bits, bitNum))
|
||||
{
|
||||
clearAbit( &BitMap, bitNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
setAbit( &BitMap, bitNum);
|
||||
}
|
||||
}
|
||||
printf(" high=%d low = %d\n", BitMap.high, BitMap.low);
|
||||
printf("minHigh=%d maxLow = %d\n", BitMap.minHigh, BitMap.maxLow);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user