@zenfs/core 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backends/backend.js +6 -5
- package/dist/backends/cow.d.ts +2 -2
- package/dist/backends/cow.js +39 -58
- package/dist/backends/fetch.js +27 -29
- package/dist/backends/passthrough.d.ts +2 -3
- package/dist/backends/passthrough.js +84 -199
- package/dist/backends/port.d.ts +16 -3
- package/dist/backends/port.js +61 -30
- package/dist/backends/single_buffer.d.ts +52 -46
- package/dist/backends/single_buffer.js +462 -219
- package/dist/backends/store/fs.d.ts +16 -10
- package/dist/backends/store/fs.js +227 -242
- package/dist/backends/store/store.d.ts +3 -3
- package/dist/backends/store/store.js +11 -10
- package/dist/config.d.ts +2 -2
- package/dist/config.js +10 -11
- package/dist/internal/devices.d.ts +2 -2
- package/dist/internal/devices.js +39 -49
- package/dist/internal/error.d.ts +9 -204
- package/dist/internal/error.js +19 -288
- package/dist/internal/file_index.d.ts +1 -1
- package/dist/internal/file_index.js +9 -9
- package/dist/internal/filesystem.d.ts +23 -8
- package/dist/internal/index.d.ts +1 -1
- package/dist/internal/index.js +1 -1
- package/dist/internal/index_fs.d.ts +2 -2
- package/dist/internal/index_fs.js +19 -19
- package/dist/internal/inode.d.ts +81 -103
- package/dist/internal/inode.js +336 -195
- package/dist/mixins/async.js +32 -28
- package/dist/mixins/mutexed.d.ts +4 -4
- package/dist/mixins/mutexed.js +39 -39
- package/dist/mixins/readonly.d.ts +2 -2
- package/dist/mixins/readonly.js +20 -20
- package/dist/mixins/sync.js +2 -2
- package/dist/polyfills.js +1 -1
- package/dist/readline.js +1 -1
- package/dist/utils.d.ts +8 -5
- package/dist/utils.js +14 -17
- package/dist/vfs/acl.d.ts +8 -8
- package/dist/vfs/acl.js +66 -47
- package/dist/vfs/async.d.ts +2 -2
- package/dist/vfs/async.js +6 -8
- package/dist/vfs/dir.d.ts +1 -1
- package/dist/vfs/dir.js +3 -4
- package/dist/vfs/file.js +33 -24
- package/dist/vfs/flags.js +3 -3
- package/dist/vfs/ioctl.d.ts +8 -7
- package/dist/vfs/ioctl.js +132 -27
- package/dist/vfs/promises.d.ts +3 -3
- package/dist/vfs/promises.js +200 -235
- package/dist/vfs/shared.d.ts +1 -12
- package/dist/vfs/shared.js +7 -35
- package/dist/vfs/streams.js +9 -9
- package/dist/vfs/sync.d.ts +1 -2
- package/dist/vfs/sync.js +158 -170
- package/dist/vfs/watchers.js +8 -8
- package/dist/vfs/xattr.js +89 -106
- package/package.json +4 -2
- package/scripts/test.js +2 -2
- package/tests/assignment.ts +1 -1
- package/tests/backend/port.test.ts +4 -4
- package/tests/backend/single-buffer.test.ts +39 -10
- package/tests/backend/single-buffer.worker.js +30 -0
- package/tests/common/context.test.ts +2 -2
- package/tests/common/mutex.test.ts +9 -9
- package/tests/fetch/fetch.ts +1 -1
- package/tests/fs/append.test.ts +4 -4
- package/tests/fs/directory.test.ts +25 -25
- package/tests/fs/errors.test.ts +15 -19
- package/tests/fs/links.test.ts +3 -2
- package/tests/fs/open.test.ts +4 -21
- package/tests/fs/permissions.test.ts +8 -13
- package/tests/fs/read.test.ts +10 -9
- package/tests/fs/readFile.test.ts +8 -24
- package/tests/fs/rename.test.ts +4 -9
- package/tests/fs/stat.test.ts +2 -2
- package/tests/fs/times.test.ts +6 -6
- package/tests/fs/truncate.test.ts +8 -36
- package/tests/fs/watch.test.ts +10 -10
- package/tests/fs/write.test.ts +77 -13
- package/tests/fs/xattr.test.ts +7 -7
- package/tests/logs.js +2 -2
- package/tests/setup/port.ts +6 -0
- package/dist/internal/log.d.ts +0 -139
- package/dist/internal/log.js +0 -219
- package/tests/fs/writeFile.test.ts +0 -70
|
@@ -32,24 +32,97 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
32
32
|
}
|
|
33
33
|
return useValue ? value : void 0;
|
|
34
34
|
};
|
|
35
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
36
|
+
if (value !== null && value !== void 0) {
|
|
37
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
38
|
+
var dispose, inner;
|
|
39
|
+
if (async) {
|
|
40
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
41
|
+
dispose = value[Symbol.asyncDispose];
|
|
42
|
+
}
|
|
43
|
+
if (dispose === void 0) {
|
|
44
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
45
|
+
dispose = value[Symbol.dispose];
|
|
46
|
+
if (async) inner = dispose;
|
|
47
|
+
}
|
|
48
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
49
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
50
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
51
|
+
}
|
|
52
|
+
else if (async) {
|
|
53
|
+
env.stack.push({ async: true });
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
};
|
|
57
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
58
|
+
return function (env) {
|
|
59
|
+
function fail(e) {
|
|
60
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
61
|
+
env.hasError = true;
|
|
62
|
+
}
|
|
63
|
+
var r, s = 0;
|
|
64
|
+
function next() {
|
|
65
|
+
while (r = env.stack.pop()) {
|
|
66
|
+
try {
|
|
67
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
68
|
+
if (r.dispose) {
|
|
69
|
+
var result = r.dispose.call(r.value);
|
|
70
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
71
|
+
}
|
|
72
|
+
else s |= 1;
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
fail(e);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
79
|
+
if (env.hasError) throw env.error;
|
|
80
|
+
}
|
|
81
|
+
return next();
|
|
82
|
+
};
|
|
83
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
84
|
+
var e = new Error(message);
|
|
85
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
86
|
+
});
|
|
35
87
|
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
36
88
|
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
37
89
|
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
38
90
|
};
|
|
39
|
-
|
|
91
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
92
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
93
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
94
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
95
|
+
};
|
|
96
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
97
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
98
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
99
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
100
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
101
|
+
};
|
|
102
|
+
import { withErrno } from 'kerium';
|
|
103
|
+
import { alert, crit, err, warn } from 'kerium/log';
|
|
104
|
+
import { field, offsetof, packed, sizeof, struct, types as t } from 'memium';
|
|
105
|
+
import { BufferView } from 'utilium/buffer.js';
|
|
40
106
|
import { crc32c } from 'utilium/checksum.js';
|
|
41
|
-
import {
|
|
42
|
-
import { _inode_version } from '../internal/inode.js';
|
|
43
|
-
import { crit, warn } from '../internal/log.js';
|
|
107
|
+
import { decodeUUID, encodeUUID } from 'utilium/string.js';
|
|
108
|
+
import { _inode_version, Inode } from '../internal/inode.js';
|
|
44
109
|
import { StoreFS } from './store/fs.js';
|
|
45
110
|
import { SyncMapTransaction } from './store/map.js';
|
|
46
|
-
|
|
111
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
112
|
+
const { format } = new Intl.NumberFormat('en-US', {
|
|
113
|
+
notation: 'compact',
|
|
114
|
+
maximumFractionDigits: 2,
|
|
115
|
+
unit: 'byte',
|
|
116
|
+
unitDisplay: 'narrow',
|
|
117
|
+
});
|
|
47
118
|
let MetadataEntry = (() => {
|
|
119
|
+
var _MetadataEntry_id_accessor_storage, _MetadataEntry_offset__accessor_storage, _MetadataEntry_offset_accessor_storage, _MetadataEntry_size_accessor_storage;
|
|
48
120
|
var _a, _b, _c, _d;
|
|
49
|
-
let _classDecorators = [struct()];
|
|
121
|
+
let _classDecorators = [struct(packed)];
|
|
50
122
|
let _classDescriptor;
|
|
51
123
|
let _classExtraInitializers = [];
|
|
52
124
|
let _classThis;
|
|
125
|
+
let _classSuper = BufferView;
|
|
53
126
|
let _id_decorators;
|
|
54
127
|
let _id_initializers = [];
|
|
55
128
|
let _id_extraInitializers = [];
|
|
@@ -62,30 +135,47 @@ let MetadataEntry = (() => {
|
|
|
62
135
|
let _size_decorators;
|
|
63
136
|
let _size_initializers = [];
|
|
64
137
|
let _size_extraInitializers = [];
|
|
65
|
-
var MetadataEntry = _classThis = class {
|
|
138
|
+
var MetadataEntry = _classThis = class extends _classSuper {
|
|
139
|
+
/** Inode or data ID */
|
|
140
|
+
get id() { return __classPrivateFieldGet(this, _MetadataEntry_id_accessor_storage, "f"); }
|
|
141
|
+
set id(value) { __classPrivateFieldSet(this, _MetadataEntry_id_accessor_storage, value, "f"); }
|
|
142
|
+
/** Reserved for 64-bit offset expansion */
|
|
143
|
+
get offset_() { return __classPrivateFieldGet(this, _MetadataEntry_offset__accessor_storage, "f"); }
|
|
144
|
+
set offset_(value) { __classPrivateFieldSet(this, _MetadataEntry_offset__accessor_storage, value, "f"); }
|
|
145
|
+
/** Offset into the buffer the data is stored at. */
|
|
146
|
+
get offset() { return __classPrivateFieldGet(this, _MetadataEntry_offset_accessor_storage, "f"); }
|
|
147
|
+
set offset(value) { __classPrivateFieldSet(this, _MetadataEntry_offset_accessor_storage, value, "f"); }
|
|
148
|
+
/** The size of the data */
|
|
149
|
+
get size() { return __classPrivateFieldGet(this, _MetadataEntry_size_accessor_storage, "f"); }
|
|
150
|
+
set size(value) { __classPrivateFieldSet(this, _MetadataEntry_size_accessor_storage, value, "f"); }
|
|
151
|
+
toString() {
|
|
152
|
+
return `<MetadataEntry @ 0x${this.byteOffset.toString(16).padStart(8, '0')}>`;
|
|
153
|
+
}
|
|
66
154
|
constructor() {
|
|
67
|
-
|
|
68
|
-
this
|
|
69
|
-
|
|
70
|
-
this
|
|
71
|
-
|
|
72
|
-
this.offset = (__runInitializers(this, _offset__extraInitializers), __runInitializers(this, _offset_initializers, 0));
|
|
73
|
-
/** The size of the data */
|
|
74
|
-
this.size = (__runInitializers(this, _offset_extraInitializers), __runInitializers(this, _size_initializers, 0));
|
|
155
|
+
super(...arguments);
|
|
156
|
+
_MetadataEntry_id_accessor_storage.set(this, __runInitializers(this, _id_initializers, void 0));
|
|
157
|
+
_MetadataEntry_offset__accessor_storage.set(this, (__runInitializers(this, _id_extraInitializers), __runInitializers(this, _offset__initializers, void 0)));
|
|
158
|
+
_MetadataEntry_offset_accessor_storage.set(this, (__runInitializers(this, _offset__extraInitializers), __runInitializers(this, _offset_initializers, void 0)));
|
|
159
|
+
_MetadataEntry_size_accessor_storage.set(this, (__runInitializers(this, _offset_extraInitializers), __runInitializers(this, _size_initializers, void 0)));
|
|
75
160
|
__runInitializers(this, _size_extraInitializers);
|
|
76
161
|
}
|
|
77
162
|
};
|
|
163
|
+
_MetadataEntry_id_accessor_storage = new WeakMap();
|
|
164
|
+
_MetadataEntry_offset__accessor_storage = new WeakMap();
|
|
165
|
+
_MetadataEntry_offset_accessor_storage = new WeakMap();
|
|
166
|
+
_MetadataEntry_size_accessor_storage = new WeakMap();
|
|
78
167
|
__setFunctionName(_classThis, "MetadataEntry");
|
|
79
168
|
(() => {
|
|
80
|
-
|
|
169
|
+
var _a;
|
|
170
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create((_a = _classSuper[Symbol.metadata]) !== null && _a !== void 0 ? _a : null) : void 0;
|
|
81
171
|
_id_decorators = [(_a = t).uint32.bind(_a)];
|
|
82
172
|
_offset__decorators = [(_b = t).uint32.bind(_b)];
|
|
83
173
|
_offset_decorators = [(_c = t).uint32.bind(_c)];
|
|
84
174
|
_size_decorators = [(_d = t).uint32.bind(_d)];
|
|
85
|
-
__esDecorate(
|
|
86
|
-
__esDecorate(
|
|
87
|
-
__esDecorate(
|
|
88
|
-
__esDecorate(
|
|
175
|
+
__esDecorate(_classThis, null, _id_decorators, { kind: "accessor", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
|
|
176
|
+
__esDecorate(_classThis, null, _offset__decorators, { kind: "accessor", name: "offset_", static: false, private: false, access: { has: obj => "offset_" in obj, get: obj => obj.offset_, set: (obj, value) => { obj.offset_ = value; } }, metadata: _metadata }, _offset__initializers, _offset__extraInitializers);
|
|
177
|
+
__esDecorate(_classThis, null, _offset_decorators, { kind: "accessor", name: "offset", static: false, private: false, access: { has: obj => "offset" in obj, get: obj => obj.offset, set: (obj, value) => { obj.offset = value; } }, metadata: _metadata }, _offset_initializers, _offset_extraInitializers);
|
|
178
|
+
__esDecorate(_classThis, null, _size_decorators, { kind: "accessor", name: "size", static: false, private: false, access: { has: obj => "size" in obj, get: obj => obj.size, set: (obj, value) => { obj.size = value; } }, metadata: _metadata }, _size_initializers, _size_extraInitializers);
|
|
89
179
|
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
90
180
|
MetadataEntry = _classThis = _classDescriptor.value;
|
|
91
181
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
@@ -97,80 +187,148 @@ let MetadataEntry = (() => {
|
|
|
97
187
|
* Number of entries per block of metadata
|
|
98
188
|
*/
|
|
99
189
|
const entries_per_block = 255;
|
|
190
|
+
/**
|
|
191
|
+
* Number of times to attempt to acquire a lock before giving up.
|
|
192
|
+
*/
|
|
193
|
+
const max_lock_attempts = 5;
|
|
100
194
|
/**
|
|
101
195
|
* A block of metadata for a single-buffer file system.
|
|
102
196
|
* This metadata maps IDs (for inodes and data) to actual offsets in the buffer.
|
|
103
197
|
* This is done since IDs are not guaranteed to be sequential.
|
|
104
198
|
*/
|
|
105
199
|
let MetadataBlock = (() => {
|
|
200
|
+
var _MetadataBlock_checksum_accessor_storage, _MetadataBlock_timestamp_accessor_storage, _MetadataBlock_previous_offset_accessor_storage, _MetadataBlock_items_accessor_storage, _MetadataBlock_locked_accessor_storage;
|
|
106
201
|
var _a, _b, _c, _d;
|
|
107
|
-
let _classDecorators = [struct()];
|
|
202
|
+
let _classDecorators = [struct(packed)];
|
|
108
203
|
let _classDescriptor;
|
|
109
204
|
let _classExtraInitializers = [];
|
|
110
205
|
let _classThis;
|
|
206
|
+
let _classSuper = Int32Array;
|
|
111
207
|
let _checksum_decorators;
|
|
112
208
|
let _checksum_initializers = [];
|
|
113
209
|
let _checksum_extraInitializers = [];
|
|
114
210
|
let _timestamp_decorators;
|
|
115
211
|
let _timestamp_initializers = [];
|
|
116
212
|
let _timestamp_extraInitializers = [];
|
|
117
|
-
let _previous_offset__decorators;
|
|
118
|
-
let _previous_offset__initializers = [];
|
|
119
|
-
let _previous_offset__extraInitializers = [];
|
|
120
213
|
let _previous_offset_decorators;
|
|
121
214
|
let _previous_offset_initializers = [];
|
|
122
215
|
let _previous_offset_extraInitializers = [];
|
|
123
|
-
let
|
|
124
|
-
let
|
|
125
|
-
let
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
/** Metadata entries. */
|
|
143
|
-
this.entries = __runInitializers(this, _entries_initializers, Array.from({ length: entries_per_block }, () => new MetadataEntry()));
|
|
144
|
-
__runInitializers(this, _entries_extraInitializers);
|
|
145
|
-
this.superblock = superblock;
|
|
146
|
-
this.offset = offset;
|
|
147
|
-
if (!offset)
|
|
148
|
-
return; // fresh block
|
|
149
|
-
deserialize(this, superblock.store._buffer.subarray(offset, offset + sizeof(MetadataBlock)));
|
|
150
|
-
if (!checksumMatches(this))
|
|
151
|
-
throw crit(new ErrnoError(Errno.EIO, 'SingleBuffer: Checksum mismatch for metadata block at 0x' + offset.toString(16)));
|
|
152
|
-
}
|
|
216
|
+
let _items_decorators;
|
|
217
|
+
let _items_initializers = [];
|
|
218
|
+
let _items_extraInitializers = [];
|
|
219
|
+
let _locked_decorators;
|
|
220
|
+
let _locked_initializers = [];
|
|
221
|
+
let _locked_extraInitializers = [];
|
|
222
|
+
var MetadataBlock = _classThis = class extends _classSuper {
|
|
223
|
+
/**
|
|
224
|
+
* The crc32c checksum for the metadata block.
|
|
225
|
+
* @privateRemarks Keep this first!
|
|
226
|
+
*/
|
|
227
|
+
get checksum() { return __classPrivateFieldGet(this, _MetadataBlock_checksum_accessor_storage, "f"); }
|
|
228
|
+
set checksum(value) { __classPrivateFieldSet(this, _MetadataBlock_checksum_accessor_storage, value, "f"); }
|
|
229
|
+
/** The (last) time this metadata block was updated */
|
|
230
|
+
get timestamp() { return __classPrivateFieldGet(this, _MetadataBlock_timestamp_accessor_storage, "f"); }
|
|
231
|
+
set timestamp(value) { __classPrivateFieldSet(this, _MetadataBlock_timestamp_accessor_storage, value, "f"); }
|
|
232
|
+
/** Offset to the previous metadata block */
|
|
233
|
+
get previous_offset() { return __classPrivateFieldGet(this, _MetadataBlock_previous_offset_accessor_storage, "f"); }
|
|
234
|
+
set previous_offset(value) { __classPrivateFieldSet(this, _MetadataBlock_previous_offset_accessor_storage, value, "f"); }
|
|
153
235
|
get previous() {
|
|
154
236
|
var _a;
|
|
155
237
|
if (!this.previous_offset)
|
|
156
238
|
return;
|
|
157
|
-
(_a = this._previous) !== null && _a !== void 0 ? _a : (this._previous = new MetadataBlock(this.
|
|
239
|
+
(_a = this._previous) !== null && _a !== void 0 ? _a : (this._previous = new MetadataBlock(this.buffer, this.previous_offset));
|
|
158
240
|
return this._previous;
|
|
159
241
|
}
|
|
242
|
+
get offsetHex() {
|
|
243
|
+
return '0x' + this.byteOffset.toString(16).padStart(8, '0');
|
|
244
|
+
}
|
|
245
|
+
/** Metadata entries. */
|
|
246
|
+
get items() { return __classPrivateFieldGet(this, _MetadataBlock_items_accessor_storage, "f"); }
|
|
247
|
+
set items(value) { __classPrivateFieldSet(this, _MetadataBlock_items_accessor_storage, value, "f"); }
|
|
248
|
+
toString(long = false) {
|
|
249
|
+
if (!long)
|
|
250
|
+
return `<MetadataBlock @ ${this.offsetHex}>`;
|
|
251
|
+
let text = [
|
|
252
|
+
`---- Metadata block at ${this.offsetHex} ----`,
|
|
253
|
+
`Checksum: 0x${this.checksum.toString(16).padStart(8, '0')}`,
|
|
254
|
+
`Last updated: ${new Date(Number(this.timestamp)).toLocaleString()}`,
|
|
255
|
+
`Previous block: 0x${this.previous_offset.toString(16).padStart(8, '0')}`,
|
|
256
|
+
'Entries:',
|
|
257
|
+
].join('\n');
|
|
258
|
+
for (const entry of this.items) {
|
|
259
|
+
if (!entry.offset)
|
|
260
|
+
continue;
|
|
261
|
+
text += `\n\t0x${entry.id.toString(16).padStart(8, '0')}: ${format(entry.size).padStart(5)} at 0x${entry.offset.toString(16).padStart(8, '0')}`;
|
|
262
|
+
}
|
|
263
|
+
return text;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* If non-zero, this block is locked for writing.
|
|
267
|
+
* Note a int32 is used for `Atomics.wait`
|
|
268
|
+
*/
|
|
269
|
+
get locked() { return __classPrivateFieldGet(this, _MetadataBlock_locked_accessor_storage, "f"); }
|
|
270
|
+
set locked(value) { __classPrivateFieldSet(this, _MetadataBlock_locked_accessor_storage, value, "f"); }
|
|
271
|
+
/**
|
|
272
|
+
* Wait for the block to be unlocked.
|
|
273
|
+
*/
|
|
274
|
+
waitUnlocked(depth = 0) {
|
|
275
|
+
if (depth > max_lock_attempts)
|
|
276
|
+
throw crit(withErrno('EBUSY', `sbfs: exceeded max attempts waiting for metadata block at ${this.offsetHex} to be unlocked`));
|
|
277
|
+
const i = this.length - 1;
|
|
278
|
+
if (!Atomics.load(this, i))
|
|
279
|
+
return;
|
|
280
|
+
switch (Atomics.wait(this, i, 1)) {
|
|
281
|
+
case 'ok':
|
|
282
|
+
break;
|
|
283
|
+
case 'not-equal':
|
|
284
|
+
depth++;
|
|
285
|
+
err(`sbfs: waiting for metadata block at ${this.offsetHex} to be unlocked (${depth}/${max_lock_attempts})`);
|
|
286
|
+
return this.waitUnlocked(depth);
|
|
287
|
+
case 'timed-out':
|
|
288
|
+
throw crit(withErrno('EBUSY', `sbfs: timed out waiting for metadata block at ${this.offsetHex} to be unlocked`));
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
lock() {
|
|
292
|
+
this.waitUnlocked();
|
|
293
|
+
const i = offsetof(this, 'locked');
|
|
294
|
+
Atomics.store(this, i, 1);
|
|
295
|
+
const release = () => {
|
|
296
|
+
Atomics.store(this, i, 0);
|
|
297
|
+
Atomics.notify(this, i, 1);
|
|
298
|
+
};
|
|
299
|
+
release[Symbol.dispose] = release;
|
|
300
|
+
return release;
|
|
301
|
+
}
|
|
302
|
+
constructor() {
|
|
303
|
+
super(...arguments);
|
|
304
|
+
_MetadataBlock_checksum_accessor_storage.set(this, __runInitializers(this, _checksum_initializers, void 0));
|
|
305
|
+
_MetadataBlock_timestamp_accessor_storage.set(this, (__runInitializers(this, _checksum_extraInitializers), __runInitializers(this, _timestamp_initializers, BigInt(Date.now()))));
|
|
306
|
+
_MetadataBlock_previous_offset_accessor_storage.set(this, (__runInitializers(this, _timestamp_extraInitializers), __runInitializers(this, _previous_offset_initializers, void 0)));
|
|
307
|
+
this._previous = __runInitializers(this, _previous_offset_extraInitializers);
|
|
308
|
+
_MetadataBlock_items_accessor_storage.set(this, __runInitializers(this, _items_initializers, void 0));
|
|
309
|
+
_MetadataBlock_locked_accessor_storage.set(this, (__runInitializers(this, _items_extraInitializers), __runInitializers(this, _locked_initializers, void 0)));
|
|
310
|
+
__runInitializers(this, _locked_extraInitializers);
|
|
311
|
+
}
|
|
160
312
|
};
|
|
313
|
+
_MetadataBlock_checksum_accessor_storage = new WeakMap();
|
|
314
|
+
_MetadataBlock_timestamp_accessor_storage = new WeakMap();
|
|
315
|
+
_MetadataBlock_previous_offset_accessor_storage = new WeakMap();
|
|
316
|
+
_MetadataBlock_items_accessor_storage = new WeakMap();
|
|
317
|
+
_MetadataBlock_locked_accessor_storage = new WeakMap();
|
|
161
318
|
__setFunctionName(_classThis, "MetadataBlock");
|
|
162
319
|
(() => {
|
|
163
|
-
|
|
320
|
+
var _a;
|
|
321
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create((_a = _classSuper[Symbol.metadata]) !== null && _a !== void 0 ? _a : null) : void 0;
|
|
164
322
|
_checksum_decorators = [(_a = t).uint32.bind(_a)];
|
|
165
|
-
_timestamp_decorators = [(_b = t).
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
__esDecorate(
|
|
170
|
-
__esDecorate(
|
|
171
|
-
__esDecorate(
|
|
172
|
-
__esDecorate(
|
|
173
|
-
__esDecorate(
|
|
323
|
+
_timestamp_decorators = [(_b = t).uint64.bind(_b)];
|
|
324
|
+
_previous_offset_decorators = [(_c = t).uint32.bind(_c)];
|
|
325
|
+
_items_decorators = [field(MetadataEntry, { length: entries_per_block })];
|
|
326
|
+
_locked_decorators = [(_d = t).int32.bind(_d)];
|
|
327
|
+
__esDecorate(_classThis, null, _checksum_decorators, { kind: "accessor", name: "checksum", static: false, private: false, access: { has: obj => "checksum" in obj, get: obj => obj.checksum, set: (obj, value) => { obj.checksum = value; } }, metadata: _metadata }, _checksum_initializers, _checksum_extraInitializers);
|
|
328
|
+
__esDecorate(_classThis, null, _timestamp_decorators, { kind: "accessor", name: "timestamp", static: false, private: false, access: { has: obj => "timestamp" in obj, get: obj => obj.timestamp, set: (obj, value) => { obj.timestamp = value; } }, metadata: _metadata }, _timestamp_initializers, _timestamp_extraInitializers);
|
|
329
|
+
__esDecorate(_classThis, null, _previous_offset_decorators, { kind: "accessor", name: "previous_offset", static: false, private: false, access: { has: obj => "previous_offset" in obj, get: obj => obj.previous_offset, set: (obj, value) => { obj.previous_offset = value; } }, metadata: _metadata }, _previous_offset_initializers, _previous_offset_extraInitializers);
|
|
330
|
+
__esDecorate(_classThis, null, _items_decorators, { kind: "accessor", name: "items", static: false, private: false, access: { has: obj => "items" in obj, get: obj => obj.items, set: (obj, value) => { obj.items = value; } }, metadata: _metadata }, _items_initializers, _items_extraInitializers);
|
|
331
|
+
__esDecorate(_classThis, null, _locked_decorators, { kind: "accessor", name: "locked", static: false, private: false, access: { has: obj => "locked" in obj, get: obj => obj.locked, set: (obj, value) => { obj.locked = value; } }, metadata: _metadata }, _locked_initializers, _locked_extraInitializers);
|
|
174
332
|
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
175
333
|
MetadataBlock = _classThis = _classDescriptor.value;
|
|
176
334
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
@@ -178,16 +336,19 @@ let MetadataBlock = (() => {
|
|
|
178
336
|
})();
|
|
179
337
|
return MetadataBlock = _classThis;
|
|
180
338
|
})();
|
|
181
|
-
|
|
339
|
+
export { MetadataBlock };
|
|
340
|
+
const sb_magic = 0x62732e7a; // 'z.sb'
|
|
182
341
|
/**
|
|
183
342
|
* The super block structure for a single-buffer file system
|
|
184
343
|
*/
|
|
185
344
|
let SuperBlock = (() => {
|
|
186
|
-
var
|
|
187
|
-
|
|
345
|
+
var _SuperBlock_checksum_accessor_storage, _SuperBlock_magic_accessor_storage, _SuperBlock_version_accessor_storage, _SuperBlock_inode_format_accessor_storage, _SuperBlock_flags_accessor_storage, _SuperBlock_used_bytes_accessor_storage, _SuperBlock_total_bytes_accessor_storage, _SuperBlock_uuid_accessor_storage, _SuperBlock_metadata_block_size_accessor_storage, _SuperBlock_metadata_offset__accessor_storage, _SuperBlock_metadata_offset_accessor_storage, _SuperBlock_label_accessor_storage, _SuperBlock__padding_accessor_storage;
|
|
346
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
347
|
+
let _classDecorators = [struct(packed)];
|
|
188
348
|
let _classDescriptor;
|
|
189
349
|
let _classExtraInitializers = [];
|
|
190
350
|
let _classThis;
|
|
351
|
+
let _classSuper = BufferView;
|
|
191
352
|
let _checksum_decorators;
|
|
192
353
|
let _checksum_initializers = [];
|
|
193
354
|
let _checksum_extraInitializers = [];
|
|
@@ -227,60 +388,97 @@ let SuperBlock = (() => {
|
|
|
227
388
|
let __padding_decorators;
|
|
228
389
|
let __padding_initializers = [];
|
|
229
390
|
let __padding_extraInitializers = [];
|
|
230
|
-
var SuperBlock = _classThis = class {
|
|
231
|
-
constructor(
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
this
|
|
238
|
-
|
|
239
|
-
this
|
|
240
|
-
|
|
241
|
-
this
|
|
242
|
-
|
|
243
|
-
this
|
|
244
|
-
/** Flags for the file system. Currently unused */
|
|
245
|
-
this.flags = (__runInitializers(this, _inode_format_extraInitializers), __runInitializers(this, _flags_initializers, 0));
|
|
246
|
-
/** The number of used bytes, including the super block and metadata */
|
|
247
|
-
this.used_bytes = (__runInitializers(this, _flags_extraInitializers), __runInitializers(this, _used_bytes_initializers, BigInt(0)));
|
|
248
|
-
/** The total size of the entire file system, including the super block and metadata */
|
|
249
|
-
this.total_bytes = (__runInitializers(this, _used_bytes_extraInitializers), __runInitializers(this, _total_bytes_initializers, BigInt(0)));
|
|
250
|
-
/** A UUID for this file system */
|
|
251
|
-
this.uuid = (__runInitializers(this, _total_bytes_extraInitializers), __runInitializers(this, _uuid_initializers, BigInt(0)));
|
|
252
|
-
/**
|
|
253
|
-
* The size in bytes of a metadata block.
|
|
254
|
-
* Not currently configurable.
|
|
255
|
-
*/
|
|
256
|
-
this.metadata_block_size = (__runInitializers(this, _uuid_extraInitializers), __runInitializers(this, _metadata_block_size_initializers, sizeof(MetadataBlock)));
|
|
257
|
-
/** Reserved for 64-bit offset expansion */
|
|
258
|
-
this.metadata_offset_ = (__runInitializers(this, _metadata_block_size_extraInitializers), __runInitializers(this, _metadata_offset__initializers, 0));
|
|
259
|
-
/** Offset of the current metadata block */
|
|
260
|
-
this.metadata_offset = (__runInitializers(this, _metadata_offset__extraInitializers), __runInitializers(this, _metadata_offset_initializers, 0));
|
|
391
|
+
var SuperBlock = _classThis = class extends _classSuper {
|
|
392
|
+
constructor(...args) {
|
|
393
|
+
super(...args);
|
|
394
|
+
_SuperBlock_checksum_accessor_storage.set(this, __runInitializers(this, _checksum_initializers, void 0));
|
|
395
|
+
_SuperBlock_magic_accessor_storage.set(this, (__runInitializers(this, _checksum_extraInitializers), __runInitializers(this, _magic_initializers, void 0)));
|
|
396
|
+
_SuperBlock_version_accessor_storage.set(this, (__runInitializers(this, _magic_extraInitializers), __runInitializers(this, _version_initializers, void 0)));
|
|
397
|
+
_SuperBlock_inode_format_accessor_storage.set(this, (__runInitializers(this, _version_extraInitializers), __runInitializers(this, _inode_format_initializers, void 0)));
|
|
398
|
+
_SuperBlock_flags_accessor_storage.set(this, (__runInitializers(this, _inode_format_extraInitializers), __runInitializers(this, _flags_initializers, void 0)));
|
|
399
|
+
_SuperBlock_used_bytes_accessor_storage.set(this, (__runInitializers(this, _flags_extraInitializers), __runInitializers(this, _used_bytes_initializers, void 0)));
|
|
400
|
+
_SuperBlock_total_bytes_accessor_storage.set(this, (__runInitializers(this, _used_bytes_extraInitializers), __runInitializers(this, _total_bytes_initializers, void 0)));
|
|
401
|
+
_SuperBlock_uuid_accessor_storage.set(this, (__runInitializers(this, _total_bytes_extraInitializers), __runInitializers(this, _uuid_initializers, void 0)));
|
|
402
|
+
_SuperBlock_metadata_block_size_accessor_storage.set(this, (__runInitializers(this, _uuid_extraInitializers), __runInitializers(this, _metadata_block_size_initializers, void 0)));
|
|
403
|
+
_SuperBlock_metadata_offset__accessor_storage.set(this, (__runInitializers(this, _metadata_block_size_extraInitializers), __runInitializers(this, _metadata_offset__initializers, void 0)));
|
|
404
|
+
_SuperBlock_metadata_offset_accessor_storage.set(this, (__runInitializers(this, _metadata_offset__extraInitializers), __runInitializers(this, _metadata_offset_initializers, void 0)));
|
|
261
405
|
this.metadata = __runInitializers(this, _metadata_offset_extraInitializers);
|
|
262
|
-
|
|
263
|
-
this
|
|
264
|
-
/** Padded to 256 bytes */
|
|
265
|
-
this._padding = (__runInitializers(this, _label_extraInitializers), __runInitializers(this, __padding_initializers, new Array(132).fill(0)));
|
|
406
|
+
_SuperBlock_label_accessor_storage.set(this, __runInitializers(this, _label_initializers, void 0));
|
|
407
|
+
_SuperBlock__padding_accessor_storage.set(this, (__runInitializers(this, _label_extraInitializers), __runInitializers(this, __padding_initializers, void 0)));
|
|
266
408
|
__runInitializers(this, __padding_extraInitializers);
|
|
267
|
-
this.
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
409
|
+
if (this.magic != sb_magic) {
|
|
410
|
+
warn('sbfs: Invalid magic value, assuming this is a fresh super block');
|
|
411
|
+
const md = new MetadataBlock(this.buffer, sizeof(SuperBlock));
|
|
412
|
+
Object.assign(this, {
|
|
413
|
+
metadata: md,
|
|
414
|
+
metadata_offset: md.byteOffset,
|
|
415
|
+
used_bytes: BigInt(sizeof(SuperBlock) + sizeof(MetadataBlock)),
|
|
416
|
+
total_bytes: BigInt(this.buffer.byteLength),
|
|
417
|
+
magic: sb_magic,
|
|
418
|
+
version: 1,
|
|
419
|
+
inode_format: _inode_version,
|
|
420
|
+
metadata_block_size: sizeof(MetadataBlock),
|
|
421
|
+
uuid: encodeUUID(crypto.randomUUID()),
|
|
422
|
+
});
|
|
423
|
+
_update(this);
|
|
424
|
+
_update(md);
|
|
277
425
|
return;
|
|
278
426
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
this.metadata
|
|
427
|
+
if (this.checksum !== checksum(this))
|
|
428
|
+
throw crit(withErrno('EIO', 'sbfs: checksum mismatch for super block'));
|
|
429
|
+
this.metadata = new MetadataBlock(this.buffer, this.metadata_offset);
|
|
430
|
+
if (this.metadata.checksum !== checksum(this.metadata))
|
|
431
|
+
throw crit(withErrno('EIO', `sbfs: checksum mismatch for metadata block (saved ${this.metadata.checksum.toString(16).padStart(8, '0')}, computed ${checksum(this.metadata).toString(16).padStart(8, '0')})`));
|
|
432
|
+
if (this.inode_format != _inode_version)
|
|
433
|
+
throw crit(withErrno('EIO', 'sbfs: inode format mismatch'));
|
|
434
|
+
if (this.metadata_block_size != sizeof(MetadataBlock))
|
|
435
|
+
throw crit(withErrno('EIO', 'sbfs: metadata block size mismatch'));
|
|
283
436
|
}
|
|
437
|
+
/**
|
|
438
|
+
* The crc32c checksum for the super block.
|
|
439
|
+
* @privateRemarks Keep this first!
|
|
440
|
+
*/
|
|
441
|
+
get checksum() { return __classPrivateFieldGet(this, _SuperBlock_checksum_accessor_storage, "f"); }
|
|
442
|
+
set checksum(value) { __classPrivateFieldSet(this, _SuperBlock_checksum_accessor_storage, value, "f"); }
|
|
443
|
+
/** Signature for the superblock. */
|
|
444
|
+
get magic() { return __classPrivateFieldGet(this, _SuperBlock_magic_accessor_storage, "f"); }
|
|
445
|
+
set magic(value) { __classPrivateFieldSet(this, _SuperBlock_magic_accessor_storage, value, "f"); }
|
|
446
|
+
/** The version of the on-disk format */
|
|
447
|
+
get version() { return __classPrivateFieldGet(this, _SuperBlock_version_accessor_storage, "f"); }
|
|
448
|
+
set version(value) { __classPrivateFieldSet(this, _SuperBlock_version_accessor_storage, value, "f"); }
|
|
449
|
+
/** Which format of `Inode` is used */
|
|
450
|
+
get inode_format() { return __classPrivateFieldGet(this, _SuperBlock_inode_format_accessor_storage, "f"); }
|
|
451
|
+
set inode_format(value) { __classPrivateFieldSet(this, _SuperBlock_inode_format_accessor_storage, value, "f"); }
|
|
452
|
+
/** Flags for the file system. Currently unused */
|
|
453
|
+
get flags() { return __classPrivateFieldGet(this, _SuperBlock_flags_accessor_storage, "f"); }
|
|
454
|
+
set flags(value) { __classPrivateFieldSet(this, _SuperBlock_flags_accessor_storage, value, "f"); }
|
|
455
|
+
/** The number of used bytes, including the super block and metadata */
|
|
456
|
+
get used_bytes() { return __classPrivateFieldGet(this, _SuperBlock_used_bytes_accessor_storage, "f"); }
|
|
457
|
+
set used_bytes(value) { __classPrivateFieldSet(this, _SuperBlock_used_bytes_accessor_storage, value, "f"); }
|
|
458
|
+
/** The total size of the entire file system, including the super block and metadata */
|
|
459
|
+
get total_bytes() { return __classPrivateFieldGet(this, _SuperBlock_total_bytes_accessor_storage, "f"); }
|
|
460
|
+
set total_bytes(value) { __classPrivateFieldSet(this, _SuperBlock_total_bytes_accessor_storage, value, "f"); }
|
|
461
|
+
/** A UUID for this file system */
|
|
462
|
+
get uuid() { return __classPrivateFieldGet(this, _SuperBlock_uuid_accessor_storage, "f"); }
|
|
463
|
+
set uuid(value) { __classPrivateFieldSet(this, _SuperBlock_uuid_accessor_storage, value, "f"); }
|
|
464
|
+
/**
|
|
465
|
+
* The size in bytes of a metadata block.
|
|
466
|
+
* Not currently configurable.
|
|
467
|
+
*/
|
|
468
|
+
get metadata_block_size() { return __classPrivateFieldGet(this, _SuperBlock_metadata_block_size_accessor_storage, "f"); }
|
|
469
|
+
set metadata_block_size(value) { __classPrivateFieldSet(this, _SuperBlock_metadata_block_size_accessor_storage, value, "f"); }
|
|
470
|
+
/** Reserved for 64-bit offset expansion */
|
|
471
|
+
get metadata_offset_() { return __classPrivateFieldGet(this, _SuperBlock_metadata_offset__accessor_storage, "f"); }
|
|
472
|
+
set metadata_offset_(value) { __classPrivateFieldSet(this, _SuperBlock_metadata_offset__accessor_storage, value, "f"); }
|
|
473
|
+
/** Offset of the current metadata block */
|
|
474
|
+
get metadata_offset() { return __classPrivateFieldGet(this, _SuperBlock_metadata_offset_accessor_storage, "f"); }
|
|
475
|
+
set metadata_offset(value) { __classPrivateFieldSet(this, _SuperBlock_metadata_offset_accessor_storage, value, "f"); }
|
|
476
|
+
/** An optional label for the file system */
|
|
477
|
+
get label() { return __classPrivateFieldGet(this, _SuperBlock_label_accessor_storage, "f"); }
|
|
478
|
+
set label(value) { __classPrivateFieldSet(this, _SuperBlock_label_accessor_storage, value, "f"); }
|
|
479
|
+
/** Padded to 256 bytes */
|
|
480
|
+
get _padding() { return __classPrivateFieldGet(this, _SuperBlock__padding_accessor_storage, "f"); }
|
|
481
|
+
set _padding(value) { __classPrivateFieldSet(this, _SuperBlock__padding_accessor_storage, value, "f"); }
|
|
284
482
|
/**
|
|
285
483
|
* Rotate out the current metadata block.
|
|
286
484
|
* Allocates a new metadata block, moves the current one to backup,
|
|
@@ -288,14 +486,13 @@ let SuperBlock = (() => {
|
|
|
288
486
|
* @returns the new metadata block
|
|
289
487
|
*/
|
|
290
488
|
rotateMetadata() {
|
|
291
|
-
const metadata = new MetadataBlock(this);
|
|
292
|
-
metadata.offset = Number(this.used_bytes);
|
|
489
|
+
const metadata = new MetadataBlock(this.buffer, Number(this.used_bytes));
|
|
293
490
|
metadata.previous_offset = this.metadata_offset;
|
|
294
491
|
this.metadata = metadata;
|
|
295
|
-
this.metadata_offset = metadata.
|
|
296
|
-
|
|
492
|
+
this.metadata_offset = metadata.byteOffset;
|
|
493
|
+
_update(metadata);
|
|
297
494
|
this.used_bytes += BigInt(sizeof(MetadataBlock));
|
|
298
|
-
|
|
495
|
+
_update(this);
|
|
299
496
|
return metadata;
|
|
300
497
|
}
|
|
301
498
|
/**
|
|
@@ -308,9 +505,9 @@ let SuperBlock = (() => {
|
|
|
308
505
|
if (offset + length > this.total_bytes || offset < sizeof(SuperBlock))
|
|
309
506
|
return false;
|
|
310
507
|
for (let block = this.metadata; block; block = block.previous) {
|
|
311
|
-
if (offset < block.
|
|
508
|
+
if (offset < block.byteOffset + sizeof(MetadataBlock) && offset + length > block.byteOffset)
|
|
312
509
|
return false;
|
|
313
|
-
for (const entry of block.
|
|
510
|
+
for (const entry of block.items) {
|
|
314
511
|
if (!entry.offset)
|
|
315
512
|
continue;
|
|
316
513
|
if ((offset >= entry.offset && offset < entry.offset + entry.size)
|
|
@@ -323,9 +520,23 @@ let SuperBlock = (() => {
|
|
|
323
520
|
return true;
|
|
324
521
|
}
|
|
325
522
|
};
|
|
523
|
+
_SuperBlock_checksum_accessor_storage = new WeakMap();
|
|
524
|
+
_SuperBlock_magic_accessor_storage = new WeakMap();
|
|
525
|
+
_SuperBlock_version_accessor_storage = new WeakMap();
|
|
526
|
+
_SuperBlock_inode_format_accessor_storage = new WeakMap();
|
|
527
|
+
_SuperBlock_flags_accessor_storage = new WeakMap();
|
|
528
|
+
_SuperBlock_used_bytes_accessor_storage = new WeakMap();
|
|
529
|
+
_SuperBlock_total_bytes_accessor_storage = new WeakMap();
|
|
530
|
+
_SuperBlock_uuid_accessor_storage = new WeakMap();
|
|
531
|
+
_SuperBlock_metadata_block_size_accessor_storage = new WeakMap();
|
|
532
|
+
_SuperBlock_metadata_offset__accessor_storage = new WeakMap();
|
|
533
|
+
_SuperBlock_metadata_offset_accessor_storage = new WeakMap();
|
|
534
|
+
_SuperBlock_label_accessor_storage = new WeakMap();
|
|
535
|
+
_SuperBlock__padding_accessor_storage = new WeakMap();
|
|
326
536
|
__setFunctionName(_classThis, "SuperBlock");
|
|
327
537
|
(() => {
|
|
328
|
-
|
|
538
|
+
var _a;
|
|
539
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create((_a = _classSuper[Symbol.metadata]) !== null && _a !== void 0 ? _a : null) : void 0;
|
|
329
540
|
_checksum_decorators = [(_a = t).uint32.bind(_a)];
|
|
330
541
|
_magic_decorators = [(_b = t).uint32.bind(_b)];
|
|
331
542
|
_version_decorators = [(_c = t).uint16.bind(_c)];
|
|
@@ -333,25 +544,25 @@ let SuperBlock = (() => {
|
|
|
333
544
|
_flags_decorators = [(_e = t).uint32.bind(_e)];
|
|
334
545
|
_used_bytes_decorators = [(_f = t).uint64.bind(_f)];
|
|
335
546
|
_total_bytes_decorators = [(_g = t).uint64.bind(_g)];
|
|
336
|
-
_uuid_decorators = [
|
|
337
|
-
_metadata_block_size_decorators = [(
|
|
338
|
-
_metadata_offset__decorators = [(
|
|
339
|
-
_metadata_offset_decorators = [(
|
|
547
|
+
_uuid_decorators = [t.uint8(16)];
|
|
548
|
+
_metadata_block_size_decorators = [(_h = t).uint32.bind(_h)];
|
|
549
|
+
_metadata_offset__decorators = [(_j = t).uint32.bind(_j)];
|
|
550
|
+
_metadata_offset_decorators = [(_k = t).uint32.bind(_k)];
|
|
340
551
|
_label_decorators = [t.char(64)];
|
|
341
552
|
__padding_decorators = [t.char(132)];
|
|
342
|
-
__esDecorate(
|
|
343
|
-
__esDecorate(
|
|
344
|
-
__esDecorate(
|
|
345
|
-
__esDecorate(
|
|
346
|
-
__esDecorate(
|
|
347
|
-
__esDecorate(
|
|
348
|
-
__esDecorate(
|
|
349
|
-
__esDecorate(
|
|
350
|
-
__esDecorate(
|
|
351
|
-
__esDecorate(
|
|
352
|
-
__esDecorate(
|
|
353
|
-
__esDecorate(
|
|
354
|
-
__esDecorate(
|
|
553
|
+
__esDecorate(_classThis, null, _checksum_decorators, { kind: "accessor", name: "checksum", static: false, private: false, access: { has: obj => "checksum" in obj, get: obj => obj.checksum, set: (obj, value) => { obj.checksum = value; } }, metadata: _metadata }, _checksum_initializers, _checksum_extraInitializers);
|
|
554
|
+
__esDecorate(_classThis, null, _magic_decorators, { kind: "accessor", name: "magic", static: false, private: false, access: { has: obj => "magic" in obj, get: obj => obj.magic, set: (obj, value) => { obj.magic = value; } }, metadata: _metadata }, _magic_initializers, _magic_extraInitializers);
|
|
555
|
+
__esDecorate(_classThis, null, _version_decorators, { kind: "accessor", name: "version", static: false, private: false, access: { has: obj => "version" in obj, get: obj => obj.version, set: (obj, value) => { obj.version = value; } }, metadata: _metadata }, _version_initializers, _version_extraInitializers);
|
|
556
|
+
__esDecorate(_classThis, null, _inode_format_decorators, { kind: "accessor", name: "inode_format", static: false, private: false, access: { has: obj => "inode_format" in obj, get: obj => obj.inode_format, set: (obj, value) => { obj.inode_format = value; } }, metadata: _metadata }, _inode_format_initializers, _inode_format_extraInitializers);
|
|
557
|
+
__esDecorate(_classThis, null, _flags_decorators, { kind: "accessor", name: "flags", static: false, private: false, access: { has: obj => "flags" in obj, get: obj => obj.flags, set: (obj, value) => { obj.flags = value; } }, metadata: _metadata }, _flags_initializers, _flags_extraInitializers);
|
|
558
|
+
__esDecorate(_classThis, null, _used_bytes_decorators, { kind: "accessor", name: "used_bytes", static: false, private: false, access: { has: obj => "used_bytes" in obj, get: obj => obj.used_bytes, set: (obj, value) => { obj.used_bytes = value; } }, metadata: _metadata }, _used_bytes_initializers, _used_bytes_extraInitializers);
|
|
559
|
+
__esDecorate(_classThis, null, _total_bytes_decorators, { kind: "accessor", name: "total_bytes", static: false, private: false, access: { has: obj => "total_bytes" in obj, get: obj => obj.total_bytes, set: (obj, value) => { obj.total_bytes = value; } }, metadata: _metadata }, _total_bytes_initializers, _total_bytes_extraInitializers);
|
|
560
|
+
__esDecorate(_classThis, null, _uuid_decorators, { kind: "accessor", name: "uuid", static: false, private: false, access: { has: obj => "uuid" in obj, get: obj => obj.uuid, set: (obj, value) => { obj.uuid = value; } }, metadata: _metadata }, _uuid_initializers, _uuid_extraInitializers);
|
|
561
|
+
__esDecorate(_classThis, null, _metadata_block_size_decorators, { kind: "accessor", name: "metadata_block_size", static: false, private: false, access: { has: obj => "metadata_block_size" in obj, get: obj => obj.metadata_block_size, set: (obj, value) => { obj.metadata_block_size = value; } }, metadata: _metadata }, _metadata_block_size_initializers, _metadata_block_size_extraInitializers);
|
|
562
|
+
__esDecorate(_classThis, null, _metadata_offset__decorators, { kind: "accessor", name: "metadata_offset_", static: false, private: false, access: { has: obj => "metadata_offset_" in obj, get: obj => obj.metadata_offset_, set: (obj, value) => { obj.metadata_offset_ = value; } }, metadata: _metadata }, _metadata_offset__initializers, _metadata_offset__extraInitializers);
|
|
563
|
+
__esDecorate(_classThis, null, _metadata_offset_decorators, { kind: "accessor", name: "metadata_offset", static: false, private: false, access: { has: obj => "metadata_offset" in obj, get: obj => obj.metadata_offset, set: (obj, value) => { obj.metadata_offset = value; } }, metadata: _metadata }, _metadata_offset_initializers, _metadata_offset_extraInitializers);
|
|
564
|
+
__esDecorate(_classThis, null, _label_decorators, { kind: "accessor", name: "label", static: false, private: false, access: { has: obj => "label" in obj, get: obj => obj.label, set: (obj, value) => { obj.label = value; } }, metadata: _metadata }, _label_initializers, _label_extraInitializers);
|
|
565
|
+
__esDecorate(_classThis, null, __padding_decorators, { kind: "accessor", name: "_padding", static: false, private: false, access: { has: obj => "_padding" in obj, get: obj => obj._padding, set: (obj, value) => { obj._padding = value; } }, metadata: _metadata }, __padding_initializers, __padding_extraInitializers);
|
|
355
566
|
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
356
567
|
SuperBlock = _classThis = _classDescriptor.value;
|
|
357
568
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
@@ -359,120 +570,150 @@ let SuperBlock = (() => {
|
|
|
359
570
|
})();
|
|
360
571
|
return SuperBlock = _classThis;
|
|
361
572
|
})();
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
573
|
+
export { SuperBlock };
|
|
574
|
+
/**
|
|
575
|
+
* Compute the checksum for a super block or metadata block.
|
|
576
|
+
* Note we don't include the checksum when computing a new one.
|
|
577
|
+
*/
|
|
578
|
+
function checksum(value) {
|
|
579
|
+
return crc32c(new Uint8Array(value.buffer, value.byteOffset + 4, sizeof(value) - 4));
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Update a block's checksum and timestamp.
|
|
583
|
+
* @internal @hidden
|
|
584
|
+
*/
|
|
585
|
+
function _update(value) {
|
|
586
|
+
if (value instanceof MetadataBlock)
|
|
587
|
+
value.timestamp = BigInt(Date.now());
|
|
588
|
+
value.checksum = checksum(value);
|
|
366
589
|
}
|
|
367
590
|
/**
|
|
368
591
|
*
|
|
369
592
|
* @category Stores and Transactions
|
|
370
593
|
*/
|
|
371
|
-
export class SingleBufferStore {
|
|
594
|
+
export class SingleBufferStore extends BufferView {
|
|
372
595
|
get uuid() {
|
|
373
|
-
return
|
|
596
|
+
return decodeUUID(this.superblock.uuid);
|
|
374
597
|
}
|
|
375
|
-
constructor(
|
|
598
|
+
constructor(...args) {
|
|
599
|
+
super(...args);
|
|
376
600
|
this.flags = [];
|
|
377
601
|
this.name = 'sbfs';
|
|
378
602
|
this.type = 0x73626673; // 'sbfs'
|
|
379
|
-
if (
|
|
380
|
-
throw crit(
|
|
381
|
-
this._view =
|
|
382
|
-
this.
|
|
383
|
-
this.superblock = new SuperBlock(this);
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* Update a block's checksum and write it to the store's buffer.
|
|
387
|
-
* @internal @hidden
|
|
388
|
-
*/
|
|
389
|
-
_write(value) {
|
|
390
|
-
value.checksum = crc32c(serialize(value).subarray(4));
|
|
391
|
-
const offset = 'offset' in value ? value.offset : 0;
|
|
392
|
-
this._buffer.set(serialize(value), offset);
|
|
603
|
+
if (this.byteLength < sizeof(SuperBlock) + sizeof(MetadataBlock))
|
|
604
|
+
throw crit(withErrno('EINVAL', 'sbfs: Buffer is too small for a file system'));
|
|
605
|
+
this._view = new DataView(this.buffer, this.byteOffset, this.byteLength);
|
|
606
|
+
this._u8 = new Uint8Array(this.buffer, this.byteOffset, this.byteLength);
|
|
607
|
+
this.superblock = new SuperBlock(this.buffer, this.byteOffset);
|
|
393
608
|
}
|
|
394
|
-
keys() {
|
|
609
|
+
*keys() {
|
|
395
610
|
const keys = new Set();
|
|
396
611
|
for (let block = this.superblock.metadata; block; block = block.previous) {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
612
|
+
block.waitUnlocked();
|
|
613
|
+
for (const entry of block.items) {
|
|
614
|
+
if (!entry.offset || keys.has(entry.id))
|
|
615
|
+
continue;
|
|
616
|
+
keys.add(entry.id);
|
|
617
|
+
yield entry.id;
|
|
618
|
+
}
|
|
400
619
|
}
|
|
401
|
-
return keys;
|
|
402
620
|
}
|
|
403
621
|
get(id) {
|
|
404
622
|
for (let block = this.superblock.metadata; block; block = block.previous) {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
623
|
+
block.waitUnlocked();
|
|
624
|
+
for (const entry of block.items) {
|
|
625
|
+
if (!entry.offset || entry.id != id)
|
|
626
|
+
continue;
|
|
627
|
+
const off = this.byteOffset + entry.offset;
|
|
628
|
+
return new Uint8Array(this.buffer.slice(off, off + entry.size));
|
|
409
629
|
}
|
|
410
630
|
}
|
|
411
631
|
}
|
|
412
632
|
set(id, data) {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
633
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
634
|
+
try {
|
|
635
|
+
if (id === 0 && data.length < sizeof(Inode))
|
|
636
|
+
throw alert(withErrno('EIO', `sbfs: tried to set ${data.length} bytes for id 0!`));
|
|
637
|
+
for (let block = this.superblock.metadata; block; block = block.previous) {
|
|
638
|
+
block.waitUnlocked();
|
|
639
|
+
for (const entry of block.items) {
|
|
640
|
+
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
641
|
+
try {
|
|
642
|
+
if (!entry.offset || entry.id != id)
|
|
643
|
+
continue;
|
|
644
|
+
const lock = __addDisposableResource(env_2, block.lock(), false);
|
|
645
|
+
if (data.length == entry.size) {
|
|
646
|
+
this._u8.set(data, entry.offset);
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
if (data.length < entry.size || this.superblock.isUnused(entry.offset, data.length)) {
|
|
650
|
+
this._u8.set(data, entry.offset);
|
|
651
|
+
entry.size = data.length;
|
|
652
|
+
_update(block);
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
entry.offset = Number(this.superblock.used_bytes);
|
|
420
656
|
entry.size = data.length;
|
|
421
|
-
this.
|
|
657
|
+
this._u8.set(data, entry.offset);
|
|
658
|
+
_update(block);
|
|
659
|
+
this.superblock.used_bytes += BigInt(data.length);
|
|
660
|
+
_update(this.superblock);
|
|
661
|
+
return;
|
|
422
662
|
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
return;
|
|
430
|
-
}
|
|
431
|
-
const used_bytes = Number(this.superblock.used_bytes);
|
|
432
|
-
for (let block = this.superblock.metadata; block; block = block.previous) {
|
|
433
|
-
for (const entry of block.entries) {
|
|
434
|
-
if (entry.offset != used_bytes)
|
|
435
|
-
continue;
|
|
436
|
-
entry.offset += data.length;
|
|
437
|
-
this._write(block);
|
|
438
|
-
break;
|
|
663
|
+
catch (e_1) {
|
|
664
|
+
env_2.error = e_1;
|
|
665
|
+
env_2.hasError = true;
|
|
666
|
+
}
|
|
667
|
+
finally {
|
|
668
|
+
__disposeResources(env_2);
|
|
439
669
|
}
|
|
440
670
|
}
|
|
441
|
-
entry.offset = used_bytes;
|
|
442
|
-
entry.size = data.length;
|
|
443
|
-
this._buffer.set(data, entry.offset);
|
|
444
|
-
this._write(block);
|
|
445
|
-
this.superblock.used_bytes += BigInt(data.length);
|
|
446
|
-
this._write(this.superblock);
|
|
447
|
-
return;
|
|
448
671
|
}
|
|
672
|
+
let entry = Array.from(this.superblock.metadata.items).find(e => !e.offset);
|
|
673
|
+
if (!entry) {
|
|
674
|
+
this.superblock.rotateMetadata();
|
|
675
|
+
entry = this.superblock.metadata.items[0];
|
|
676
|
+
}
|
|
677
|
+
const lock = __addDisposableResource(env_1, this.superblock.metadata.lock(), false);
|
|
678
|
+
const offset = Number(this.superblock.used_bytes);
|
|
679
|
+
entry.id = id;
|
|
680
|
+
entry.offset = offset;
|
|
681
|
+
entry.size = data.length;
|
|
682
|
+
this._u8.set(data, offset);
|
|
683
|
+
this.superblock.used_bytes += BigInt(data.length);
|
|
684
|
+
_update(this.superblock.metadata);
|
|
685
|
+
_update(this.superblock);
|
|
686
|
+
}
|
|
687
|
+
catch (e_2) {
|
|
688
|
+
env_1.error = e_2;
|
|
689
|
+
env_1.hasError = true;
|
|
449
690
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
this.superblock.rotateMetadata();
|
|
453
|
-
entry = this.superblock.metadata.entries[0];
|
|
691
|
+
finally {
|
|
692
|
+
__disposeResources(env_1);
|
|
454
693
|
}
|
|
455
|
-
const offset = Number(this.superblock.used_bytes);
|
|
456
|
-
entry.id = id;
|
|
457
|
-
entry.offset = offset;
|
|
458
|
-
entry.size = data.length;
|
|
459
|
-
this._buffer.set(data, offset);
|
|
460
|
-
this.superblock.used_bytes += BigInt(data.length);
|
|
461
|
-
this._write(this.superblock.metadata);
|
|
462
|
-
this._write(this.superblock);
|
|
463
694
|
}
|
|
464
695
|
delete(id) {
|
|
465
696
|
for (let block = this.superblock.metadata; block; block = block.previous) {
|
|
466
|
-
|
|
697
|
+
block.waitUnlocked();
|
|
698
|
+
for (const entry of block.items) {
|
|
467
699
|
if (entry.id != id)
|
|
468
700
|
continue;
|
|
469
701
|
entry.offset = 0;
|
|
470
702
|
entry.size = 0;
|
|
471
|
-
|
|
703
|
+
entry.id = 0;
|
|
704
|
+
_update(block);
|
|
472
705
|
return;
|
|
473
706
|
}
|
|
474
707
|
}
|
|
475
708
|
}
|
|
709
|
+
get fs() {
|
|
710
|
+
return this._fs;
|
|
711
|
+
}
|
|
712
|
+
set fs(fs) {
|
|
713
|
+
if (this.buffer instanceof SharedArrayBuffer)
|
|
714
|
+
fs === null || fs === void 0 ? void 0 : fs.attributes.set('no_id_tables', true);
|
|
715
|
+
this._fs = fs;
|
|
716
|
+
}
|
|
476
717
|
sync() {
|
|
477
718
|
return Promise.resolve();
|
|
478
719
|
}
|
|
@@ -491,8 +732,10 @@ const _SingleBuffer = {
|
|
|
491
732
|
options: {
|
|
492
733
|
buffer: { type: 'object', required: true },
|
|
493
734
|
},
|
|
494
|
-
create(
|
|
495
|
-
const fs = new StoreFS(
|
|
735
|
+
create(opt) {
|
|
736
|
+
const fs = new StoreFS(ArrayBuffer.isView(opt.buffer)
|
|
737
|
+
? new SingleBufferStore(opt.buffer.buffer, opt.buffer.byteOffset, opt.buffer.byteLength)
|
|
738
|
+
: new SingleBufferStore(opt.buffer));
|
|
496
739
|
fs.checkRootSync();
|
|
497
740
|
return fs;
|
|
498
741
|
},
|