@zenfs/core 2.6.6 → 2.7.1

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/vfs/ioctl.js CHANGED
@@ -5,387 +5,85 @@
5
5
  - include/uapi/asm-generic/ioctl.h
6
6
  - include/uapi/linux/fs.h (`FS_IOC_*`)
7
7
  */
8
- var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
9
- function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
10
- var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
11
- var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
12
- var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
13
- var _, done = false;
14
- for (var i = decorators.length - 1; i >= 0; i--) {
15
- var context = {};
16
- for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
17
- for (var p in contextIn.access) context.access[p] = contextIn.access[p];
18
- context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
19
- var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
20
- if (kind === "accessor") {
21
- if (result === void 0) continue;
22
- if (result === null || typeof result !== "object") throw new TypeError("Object expected");
23
- if (_ = accept(result.get)) descriptor.get = _;
24
- if (_ = accept(result.set)) descriptor.set = _;
25
- if (_ = accept(result.init)) initializers.unshift(_);
26
- }
27
- else if (_ = accept(result)) {
28
- if (kind === "field") initializers.unshift(_);
29
- else descriptor[key] = _;
30
- }
31
- }
32
- if (target) Object.defineProperty(target, contextIn.name, descriptor);
33
- done = true;
34
- };
35
- var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
36
- var useValue = arguments.length > 2;
37
- for (var i = 0; i < initializers.length; i++) {
38
- value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
39
- }
40
- return useValue ? value : void 0;
41
- };
42
- import { Errno, Exception, setUVMessage, UV } from 'kerium';
43
- import { sizeof } from 'memium';
44
- import { $from, struct, types as t } from 'memium/decorators';
45
- import { _throw } from 'utilium';
46
- import { BufferView } from 'utilium/buffer';
47
- import { Inode, InodeFlags } from '../internal/inode.js';
8
+ import { setUVMessage, UV } from 'kerium';
48
9
  import { normalizePath } from '../utils.js';
49
- import { resolveMount } from './shared.js';
50
- /*
51
- * Flags for the fsxattr.xflags field
52
- */
53
- var XFlag;
54
- (function (XFlag) {
55
- /** data in realtime volume */
56
- XFlag[XFlag["RealTime"] = 1] = "RealTime";
57
- /** preallocated file extents */
58
- XFlag[XFlag["PreAlloc"] = 2] = "PreAlloc";
59
- /** file cannot be modified */
60
- XFlag[XFlag["Immutable"] = 8] = "Immutable";
61
- /** all writes append */
62
- XFlag[XFlag["Append"] = 16] = "Append";
63
- /** all writes synchronous */
64
- XFlag[XFlag["Sync"] = 32] = "Sync";
65
- /** do not update access time */
66
- XFlag[XFlag["NoAtime"] = 64] = "NoAtime";
67
- /** do not include in backups */
68
- XFlag[XFlag["NoDump"] = 128] = "NoDump";
69
- /** create with rt bit set */
70
- XFlag[XFlag["RtInherit"] = 256] = "RtInherit";
71
- /** create with parents projid */
72
- XFlag[XFlag["ProjInherit"] = 512] = "ProjInherit";
73
- /** disallow symlink creation */
74
- XFlag[XFlag["NoSymlinks"] = 1024] = "NoSymlinks";
75
- /** extent size allocator hint */
76
- XFlag[XFlag["ExtSize"] = 2048] = "ExtSize";
77
- /** inherit inode extent size */
78
- XFlag[XFlag["ExtSzInherit"] = 4096] = "ExtSzInherit";
79
- /** do not defragment */
80
- XFlag[XFlag["NoDefrag"] = 8192] = "NoDefrag";
81
- /** use filestream allocator */
82
- XFlag[XFlag["FileStream"] = 16384] = "FileStream";
83
- /** use DAX for IO */
84
- XFlag[XFlag["Dax"] = 32768] = "Dax";
85
- /** CoW extent size allocator hint */
86
- XFlag[XFlag["CowExtSize"] = 65536] = "CowExtSize";
87
- /** no DIFLAG for this */
88
- XFlag[XFlag["HasAttr"] = 2147483648] = "HasAttr";
89
- })(XFlag || (XFlag = {}));
90
- let fsxattr = (() => {
91
- var _a, _b, _c, _d, _e;
92
- let _classDecorators = [struct()];
93
- let _classDescriptor;
94
- let _classExtraInitializers = [];
95
- let _classThis;
96
- let _classSuper = $from(BufferView);
97
- let _xflags_decorators;
98
- let _xflags_initializers = [];
99
- let _xflags_extraInitializers = [];
100
- let _extsize_decorators;
101
- let _extsize_initializers = [];
102
- let _extsize_extraInitializers = [];
103
- let _nextents_decorators;
104
- let _nextents_initializers = [];
105
- let _nextents_extraInitializers = [];
106
- let _projid_decorators;
107
- let _projid_initializers = [];
108
- let _projid_extraInitializers = [];
109
- let _cowextsize_decorators;
110
- let _cowextsize_initializers = [];
111
- let _cowextsize_extraInitializers = [];
112
- let _pad_decorators;
113
- let _pad_initializers = [];
114
- let _pad_extraInitializers = [];
115
- var fsxattr = class extends _classSuper {
116
- static { _classThis = this; }
117
- static {
118
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
119
- _xflags_decorators = [(_a = t).uint32.bind(_a)];
120
- _extsize_decorators = [(_b = t).uint32.bind(_b)];
121
- _nextents_decorators = [(_c = t).uint32.bind(_c)];
122
- _projid_decorators = [(_d = t).uint32.bind(_d)];
123
- _cowextsize_decorators = [(_e = t).uint32.bind(_e)];
124
- _pad_decorators = [t.char(8)];
125
- __esDecorate(this, null, _xflags_decorators, { kind: "accessor", name: "xflags", static: false, private: false, access: { has: obj => "xflags" in obj, get: obj => obj.xflags, set: (obj, value) => { obj.xflags = value; } }, metadata: _metadata }, _xflags_initializers, _xflags_extraInitializers);
126
- __esDecorate(this, null, _extsize_decorators, { kind: "accessor", name: "extsize", static: false, private: false, access: { has: obj => "extsize" in obj, get: obj => obj.extsize, set: (obj, value) => { obj.extsize = value; } }, metadata: _metadata }, _extsize_initializers, _extsize_extraInitializers);
127
- __esDecorate(this, null, _nextents_decorators, { kind: "accessor", name: "nextents", static: false, private: false, access: { has: obj => "nextents" in obj, get: obj => obj.nextents, set: (obj, value) => { obj.nextents = value; } }, metadata: _metadata }, _nextents_initializers, _nextents_extraInitializers);
128
- __esDecorate(this, null, _projid_decorators, { kind: "accessor", name: "projid", static: false, private: false, access: { has: obj => "projid" in obj, get: obj => obj.projid, set: (obj, value) => { obj.projid = value; } }, metadata: _metadata }, _projid_initializers, _projid_extraInitializers);
129
- __esDecorate(this, null, _cowextsize_decorators, { kind: "accessor", name: "cowextsize", static: false, private: false, access: { has: obj => "cowextsize" in obj, get: obj => obj.cowextsize, set: (obj, value) => { obj.cowextsize = value; } }, metadata: _metadata }, _cowextsize_initializers, _cowextsize_extraInitializers);
130
- __esDecorate(this, null, _pad_decorators, { kind: "accessor", name: "pad", static: false, private: false, access: { has: obj => "pad" in obj, get: obj => obj.pad, set: (obj, value) => { obj.pad = value; } }, metadata: _metadata }, _pad_initializers, _pad_extraInitializers);
131
- __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
132
- fsxattr = _classThis = _classDescriptor.value;
133
- if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
134
- }
135
- static name = 'fsxattr';
136
- #xflags_accessor_storage = __runInitializers(this, _xflags_initializers, void 0);
137
- /** xflags field value */
138
- get xflags() { return this.#xflags_accessor_storage; }
139
- set xflags(value) { this.#xflags_accessor_storage = value; }
140
- #extsize_accessor_storage = (__runInitializers(this, _xflags_extraInitializers), __runInitializers(this, _extsize_initializers, void 0));
141
- /** extsize field value */
142
- get extsize() { return this.#extsize_accessor_storage; }
143
- set extsize(value) { this.#extsize_accessor_storage = value; }
144
- #nextents_accessor_storage = (__runInitializers(this, _extsize_extraInitializers), __runInitializers(this, _nextents_initializers, void 0));
145
- /** nextents field value */
146
- get nextents() { return this.#nextents_accessor_storage; }
147
- set nextents(value) { this.#nextents_accessor_storage = value; }
148
- #projid_accessor_storage = (__runInitializers(this, _nextents_extraInitializers), __runInitializers(this, _projid_initializers, void 0));
149
- /** project identifier */
150
- get projid() { return this.#projid_accessor_storage; }
151
- set projid(value) { this.#projid_accessor_storage = value; }
152
- #cowextsize_accessor_storage = (__runInitializers(this, _projid_extraInitializers), __runInitializers(this, _cowextsize_initializers, void 0));
153
- /** CoW extsize field value */
154
- get cowextsize() { return this.#cowextsize_accessor_storage; }
155
- set cowextsize(value) { this.#cowextsize_accessor_storage = value; }
156
- #pad_accessor_storage = (__runInitializers(this, _cowextsize_extraInitializers), __runInitializers(this, _pad_initializers, []));
157
- get pad() { return this.#pad_accessor_storage; }
158
- set pad(value) { this.#pad_accessor_storage = value; }
159
- constructor(inode = _throw(new Exception(Errno.EINVAL, 'fsxattr must be initialized with an inode'))) {
160
- super(new ArrayBuffer(sizeof(fsxattr)));
161
- __runInitializers(this, _pad_extraInitializers);
162
- this.extsize = inode.size;
163
- this.nextents = 1;
164
- this.projid = inode.uid;
165
- this.cowextsize = inode.size;
166
- for (const name of Object.keys(InodeFlags)) {
167
- if (!(inode.flags & InodeFlags[name]))
168
- continue;
169
- if (name in XFlag)
170
- this.xflags |= XFlag[name];
171
- }
172
- }
173
- static {
174
- __runInitializers(_classThis, _classExtraInitializers);
175
- }
176
- };
177
- return fsxattr = _classThis;
178
- })();
10
+ import { resolve as resolveAsync } from './async.js';
11
+ import { fromFD } from './file.js';
12
+ import { resolve as resolveSync } from './sync.js';
13
+ import { cacheOf } from './vcache.js';
179
14
  /**
180
- * Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
181
- * @see `FS_*_FL` in `include/uapi/linux/fs.h` (around L250)
182
- * @experimental
15
+ * Perform an `ioctl` on a file or file system.
16
+ * @category ioctl
183
17
  */
184
- var FileFlag;
185
- (function (FileFlag) {
186
- /** Secure deletion */
187
- FileFlag[FileFlag["SecureRm"] = 1] = "SecureRm";
188
- /** Undelete */
189
- FileFlag[FileFlag["Undelete"] = 2] = "Undelete";
190
- /** Compress file */
191
- FileFlag[FileFlag["Compress"] = 4] = "Compress";
192
- /** Synchronous updates */
193
- FileFlag[FileFlag["Sync"] = 8] = "Sync";
194
- /** Immutable file */
195
- FileFlag[FileFlag["Immutable"] = 16] = "Immutable";
196
- /** Writes to file may only append */
197
- FileFlag[FileFlag["Append"] = 32] = "Append";
198
- /** do not dump file */
199
- FileFlag[FileFlag["NoDump"] = 64] = "NoDump";
200
- /** do not update atime */
201
- FileFlag[FileFlag["NoAtime"] = 128] = "NoAtime";
202
- // Reserved for compression usage...
203
- FileFlag[FileFlag["Dirty"] = 256] = "Dirty";
204
- /** One or more compressed clusters */
205
- FileFlag[FileFlag["CompressBlk"] = 512] = "CompressBlk";
206
- /** Don't compress */
207
- FileFlag[FileFlag["NoCompress"] = 1024] = "NoCompress";
208
- // End compression flags --- maybe not all used
209
- /** Encrypted file */
210
- FileFlag[FileFlag["Encrypt"] = 2048] = "Encrypt";
211
- /** btree format dir */
212
- FileFlag[FileFlag["Btree"] = 4096] = "Btree";
213
- /** hash-indexed directory */
214
- // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
215
- FileFlag[FileFlag["Index"] = 4096] = "Index";
216
- /** AFS directory */
217
- FileFlag[FileFlag["IMagic"] = 8192] = "IMagic";
218
- /** Reserved for ext3 */
219
- FileFlag[FileFlag["JournalData"] = 16384] = "JournalData";
220
- /** file tail should not be merged */
221
- FileFlag[FileFlag["NoTail"] = 32768] = "NoTail";
222
- /** dirsync behaviour (directories only) */
223
- FileFlag[FileFlag["DirSync"] = 65536] = "DirSync";
224
- /** Top of directory hierarchies*/
225
- FileFlag[FileFlag["TopDir"] = 131072] = "TopDir";
226
- /** Reserved for ext4 */
227
- FileFlag[FileFlag["HugeFile"] = 262144] = "HugeFile";
228
- /** Extents */
229
- FileFlag[FileFlag["Extent"] = 524288] = "Extent";
230
- /** Verity protected inode */
231
- FileFlag[FileFlag["Verity"] = 1048576] = "Verity";
232
- /** Inode used for large EA */
233
- FileFlag[FileFlag["EaInode"] = 2097152] = "EaInode";
234
- /** Reserved for ext4 */
235
- FileFlag[FileFlag["EofBlocks"] = 4194304] = "EofBlocks";
236
- /** Do not cow file */
237
- FileFlag[FileFlag["NoCow"] = 8388608] = "NoCow";
238
- /** Inode is DAX */
239
- FileFlag[FileFlag["Dax"] = 33554432] = "Dax";
240
- /** Reserved for ext4 */
241
- FileFlag[FileFlag["InlineData"] = 268435456] = "InlineData";
242
- /** Create with parents projid */
243
- FileFlag[FileFlag["ProjInherit"] = 536870912] = "ProjInherit";
244
- /** Folder is case insensitive */
245
- FileFlag[FileFlag["CaseFold"] = 1073741824] = "CaseFold";
246
- /** reserved for ext2 lib */
247
- FileFlag[FileFlag["Reserved"] = 2147483648] = "Reserved";
248
- })(FileFlag || (FileFlag = {}));
249
- /**
250
- * `FS_IOC_*` commands for {@link ioctl | `ioctl`}
251
- * @remarks
252
- * These are computed from a script since constant values are needed for enum member types
253
- */
254
- export var IOC;
255
- (function (IOC) {
256
- IOC[IOC["GetFlags"] = 2148034049] = "GetFlags";
257
- IOC[IOC["SetFlags"] = 1074292226] = "SetFlags";
258
- IOC[IOC["GetVersion"] = 2148038145] = "GetVersion";
259
- IOC[IOC["SetVersion"] = 1074296322] = "SetVersion";
260
- IOC[IOC["Fiemap"] = 3223348747] = "Fiemap";
261
- IOC[IOC["GetXattr"] = 2149341215] = "GetXattr";
262
- IOC[IOC["SetXattr"] = 1075599392] = "SetXattr";
263
- IOC[IOC["GetLabel"] = 2164298801] = "GetLabel";
264
- IOC[IOC["SetLabel"] = 1090556978] = "SetLabel";
265
- IOC[IOC["GetUUID"] = 2148603136] = "GetUUID";
266
- IOC[IOC["GetSysfsPath"] = 2155943169] = "GetSysfsPath";
267
- })(IOC || (IOC = {}));
268
- /**
269
- * `FS_IOC32_*` commands for {@link ioctl | `ioctl`}
270
- * @remarks
271
- * These are computed from a script since constant values are needed for enum member types
272
- */
273
- export var IOC32;
274
- (function (IOC32) {
275
- IOC32[IOC32["GetFlags"] = 2147771905] = "GetFlags";
276
- IOC32[IOC32["SetFlags"] = 1074030082] = "SetFlags";
277
- IOC32[IOC32["GetVersion"] = 2147776001] = "GetVersion";
278
- IOC32[IOC32["SetVersion"] = 1074034178] = "SetVersion";
279
- })(IOC32 || (IOC32 = {}));
280
- /** Perform an `ioctl` on a file or file system. */
281
- export async function ioctl(
282
- /** The path to the file or file system to perform the `ioctl` on */
283
- path,
284
- /** The command to perform (uint32) */
285
- command,
286
- /** The arguments to pass to the command */
287
- ...args) {
288
- path = normalizePath(path);
289
- const { fs, path: resolved } = resolveMount(path, this);
18
+ export async function ioctl(path, command, ...args) {
19
+ let vcache, vnode, file;
20
+ if (typeof path == 'number') {
21
+ file = fromFD(this, path);
22
+ vcache = cacheOf(file.fs);
23
+ vnode = file.vnode;
24
+ // In the future we may need to use `vcache.ref(...)`
25
+ // For now this avoids some issues: touching vnode.paths, triggering the "referenced by more paths" error, and inode assignment
26
+ vnode.refs++;
27
+ }
28
+ else {
29
+ path = normalizePath.call(this, path);
30
+ const mnt = await resolveAsync(this, path, false, { syscall: 'ioctl', path });
31
+ if (!mnt.stats)
32
+ throw UV('ENOENT', { syscall: 'ioctl', path });
33
+ vcache = cacheOf(mnt.fs);
34
+ vnode = vcache.ref(mnt.path, vcache.get(mnt.path)?.inode ?? mnt.stats);
35
+ }
36
+ const context = {
37
+ fs: vnode.fs,
38
+ inode: vnode.inode,
39
+ path: vnode.path,
40
+ file,
41
+ };
290
42
  try {
291
- const inode = new Inode(await fs.stat(resolved));
292
- switch (command) {
293
- case IOC.GetFlags:
294
- case IOC32.GetFlags:
295
- return inode.flags;
296
- case IOC.SetFlags:
297
- case IOC32.SetFlags:
298
- inode.flags = args[0];
299
- await fs.touch(resolved, inode);
300
- return undefined;
301
- case IOC.GetVersion:
302
- case IOC32.GetVersion:
303
- return inode.version;
304
- case IOC.SetVersion:
305
- case IOC32.SetVersion:
306
- inode.version = args[0];
307
- await fs.touch(resolved, inode);
308
- return undefined;
309
- case IOC.Fiemap:
310
- break;
311
- case IOC.GetXattr:
312
- return new fsxattr(inode);
313
- case IOC.SetXattr:
314
- break;
315
- case IOC.GetLabel:
316
- return fs.label;
317
- case IOC.SetLabel:
318
- fs.label = args[0];
319
- return undefined;
320
- case IOC.GetUUID:
321
- return fs.uuid;
322
- case IOC.GetSysfsPath:
323
- /**
324
- * Returns the path component under /sys/fs/ that refers to this filesystem;
325
- * also /sys/kernel/debug/ for filesystems with debugfs exports
326
- * @todo Implement sysfs and have each FS implement the /sys/fs/<name> tree
327
- */
328
- return `/sys/fs/${fs.name}/${fs.uuid}`;
329
- }
43
+ return await vnode.fs.ioctl(context, command, ...args);
330
44
  }
331
45
  catch (e) {
332
46
  throw setUVMessage(Object.assign(e, { syscall: 'ioctl', path }));
333
47
  }
334
- throw UV('ENOTSUP', 'ioctl', path);
48
+ finally {
49
+ vcache.unref(vnode);
50
+ }
335
51
  }
336
- /** Perform an `ioctl` on a file or file system */
337
- export function ioctlSync(
338
- /** The path to the file or file system to perform the `ioctl` on */
339
- path,
340
- /** The command to perform (uint32) */
341
- command,
342
- /** The arguments to pass to the command */
343
- ...args) {
344
- path = normalizePath(path);
345
- const { fs, path: resolved } = resolveMount(path, this);
52
+ /**
53
+ * Perform an `ioctl` on a file or file system
54
+ * @category ioctl
55
+ */
56
+ export function ioctlSync(path, command, ...args) {
57
+ let vcache, vnode, file;
58
+ if (typeof path == 'number') {
59
+ file = fromFD(this, path);
60
+ vcache = cacheOf(file.fs);
61
+ vnode = file.vnode;
62
+ // In the future we may need to use `vcache.ref(...)`
63
+ // For now this avoids some issues: touching vnode.paths, triggering the "referenced by more paths" error, and inode assignment
64
+ vnode.refs++;
65
+ }
66
+ else {
67
+ path = normalizePath.call(this, path);
68
+ const mnt = resolveSync(this, path, false, { syscall: 'ioctl', path });
69
+ if (!mnt.stats)
70
+ throw UV('ENOENT', { syscall: 'ioctl', path });
71
+ vcache = cacheOf(mnt.fs);
72
+ vnode = vcache.ref(mnt.path, vcache.get(mnt.path)?.inode ?? mnt.stats);
73
+ }
74
+ const context = {
75
+ fs: vnode.fs,
76
+ inode: vnode.inode,
77
+ path: vnode.path,
78
+ file,
79
+ };
346
80
  try {
347
- const inode = new Inode(fs.statSync(resolved));
348
- switch (command) {
349
- case IOC.GetFlags:
350
- case IOC32.GetFlags:
351
- return inode.flags;
352
- case IOC.SetFlags:
353
- case IOC32.SetFlags:
354
- inode.flags = args[0];
355
- fs.touchSync(resolved, inode);
356
- return undefined;
357
- case IOC.GetVersion:
358
- case IOC32.GetVersion:
359
- return inode.version;
360
- case IOC.SetVersion:
361
- case IOC32.SetVersion:
362
- inode.version = args[0];
363
- fs.touchSync(resolved, inode);
364
- return undefined;
365
- case IOC.Fiemap:
366
- break;
367
- case IOC.GetXattr:
368
- return new fsxattr(inode);
369
- case IOC.SetXattr:
370
- break;
371
- case IOC.GetLabel:
372
- return fs.label;
373
- case IOC.SetLabel:
374
- fs.label = args[0];
375
- return undefined;
376
- case IOC.GetUUID:
377
- return fs.uuid;
378
- case IOC.GetSysfsPath:
379
- /**
380
- * Returns the path component under /sys/fs/ that refers to this filesystem;
381
- * also /sys/kernel/debug/ for filesystems with debugfs exports
382
- * @todo Implement sysfs and have each FS implement the /sys/fs/<name> tree
383
- */
384
- return `/sys/fs/${fs.name}/${fs.uuid}`;
385
- }
81
+ return vnode.fs.ioctlSync(context, command, ...args);
386
82
  }
387
83
  catch (e) {
388
84
  throw setUVMessage(Object.assign(e, { syscall: 'ioctl', path }));
389
85
  }
390
- throw UV('ENOTSUP', 'ioctl', path);
86
+ finally {
87
+ vcache.unref(vnode);
88
+ }
391
89
  }
@@ -12,6 +12,8 @@ export type MountObject = Record<AbsolutePath, FileSystem>;
12
12
  * The map of mount points
13
13
  * @category Backends and Configuration
14
14
  * @internal
15
+ * @deprecated Use `defaultContext.mounts`.
16
+ * @todo [breaking] remove this
15
17
  */
16
18
  export declare const mounts: Map<string, FileSystem>;
17
19
  /**
@@ -4,7 +4,7 @@ import { Errno, Exception, UV, withErrno } from 'kerium';
4
4
  import { alert, debug, err, info, notice, warn } from 'kerium/log';
5
5
  import { InMemory } from '../backends/memory.js';
6
6
  import { size_max } from '../constants.js';
7
- import { contextOf } from '../internal/contexts.js';
7
+ import { contextOf, defaultContext } from '../internal/contexts.js';
8
8
  import { credentialsAllowRoot } from '../internal/credentials.js';
9
9
  import { withExceptionContext } from '../internal/error.js';
10
10
  import { join, resolve } from '../path.js';
@@ -14,8 +14,10 @@ import { caches, VCache } from './vcache.js';
14
14
  * The map of mount points
15
15
  * @category Backends and Configuration
16
16
  * @internal
17
+ * @deprecated Use `defaultContext.mounts`.
18
+ * @todo [breaking] remove this
17
19
  */
18
- export const mounts = new Map();
20
+ export const mounts = defaultContext.mounts;
19
21
  // Set a default root.
20
22
  mount('/', InMemory.create({ label: 'root' }));
21
23
  /**
@@ -24,13 +26,14 @@ mount('/', InMemory.create({ label: 'root' }));
24
26
  * @internal
25
27
  */
26
28
  export function mount(mountPoint, fs) {
29
+ const $ = contextOf(this);
27
30
  if (mountPoint[0] != '/')
28
31
  mountPoint = '/' + mountPoint;
29
- mountPoint = resolve.call(this, mountPoint);
30
- if (mounts.has(mountPoint))
32
+ mountPoint = resolve.call($, mountPoint);
33
+ if ($.mounts.has(mountPoint))
31
34
  throw err(withErrno('EINVAL', 'Mount point is already in use: ' + mountPoint));
32
35
  fs._mountPoint = mountPoint;
33
- mounts.set(mountPoint, fs);
36
+ $.mounts.set(mountPoint, fs);
34
37
  if (!caches.has(fs.uuid))
35
38
  caches.set(fs.uuid, new VCache(fs));
36
39
  info(`Mounted ${fs.name} on ${mountPoint}`);
@@ -42,10 +45,11 @@ export function mount(mountPoint, fs) {
42
45
  * @todo [BREAKING] make this `async` and `await` vcache sync
43
46
  */
44
47
  export function umount(mountPoint) {
48
+ const $ = contextOf(this);
45
49
  if (mountPoint[0] != '/')
46
50
  mountPoint = '/' + mountPoint;
47
51
  mountPoint = resolve.call(this, mountPoint);
48
- const fs = mounts.get(mountPoint);
52
+ const fs = $.mounts.get(mountPoint);
49
53
  if (!fs) {
50
54
  warn(mountPoint + ' is already unmounted');
51
55
  return;
@@ -62,7 +66,7 @@ export function umount(mountPoint) {
62
66
  warn(`Could not flush to ${mountPoint} synchronously.`);
63
67
  void caches.get(fs.uuid)?.sync().then(_done);
64
68
  }
65
- mounts.delete(mountPoint);
69
+ $.mounts.delete(mountPoint);
66
70
  notice('Unmounted ' + mountPoint);
67
71
  }
68
72
  /**
@@ -70,7 +74,7 @@ export function umount(mountPoint) {
70
74
  * @internal @hidden
71
75
  */
72
76
  export function resolveMount(path, ctx, extra) {
73
- const { root } = contextOf(ctx);
77
+ const { root, mounts } = contextOf(ctx);
74
78
  const _exceptionContext = { path, ...extra };
75
79
  path = normalizePath(join(root, path), true);
76
80
  path = resolve.call(ctx, path);
@@ -16,7 +16,7 @@ export declare function resolve($: V_Context, path: string, preserveSymlinks?: b
16
16
  * @category VFS
17
17
  * @internal
18
18
  */
19
- export declare function open(this: V_Context, path: PathLike, opt: OpenOptions): Handle;
19
+ export declare function open($: V_Context, path: PathLike, opt: OpenOptions): Handle;
20
20
  export declare function readlink(this: V_Context, path: PathLike): string;
21
21
  export declare function mkdir(this: V_Context, path: PathLike, options?: MkdirOptions): string | void;
22
22
  export declare function readdir(this: V_Context, path: PathLike, options?: ReaddirOptions): Dirent[];
package/dist/vfs/sync.js CHANGED
@@ -113,11 +113,11 @@ export function resolve($, path, preserveSymlinks, extra) {
113
113
  * @category VFS
114
114
  * @internal
115
115
  */
116
- export function open(path, opt) {
117
- path = normalizePath(path);
116
+ export function open($, path, opt) {
117
+ path = normalizePath.call($, path);
118
118
  const mode = normalizeMode(opt.mode, 0o644), flag = flags.parse(opt.flag);
119
- path = opt.preserveSymlinks ? path : resolve(this, path).fullPath;
120
- const { fs, path: resolved } = resolveMount(path, this);
119
+ path = opt.preserveSymlinks ? path : resolve($, path).fullPath;
120
+ const { fs, path: resolved } = resolveMount(path, $);
121
121
  let stats;
122
122
  try {
123
123
  stats = fs.statSync(resolved);
@@ -134,25 +134,25 @@ export function open(path, opt) {
134
134
  // Create the file
135
135
  const parentPath = dirname(resolved);
136
136
  const parentStats = fs.statSync(parentPath);
137
- if (checkAccess && !hasAccess(this, parentStats, constants.W_OK)) {
137
+ if (checkAccess && !hasAccess($, parentStats, constants.W_OK)) {
138
138
  throw UV('EACCES', 'open', path);
139
139
  }
140
140
  if (!isDirectory(parentStats)) {
141
141
  throw UV('ENOTDIR', 'open', path);
142
142
  }
143
- if (!opt.allowDirectory && mode & constants.S_IFDIR)
143
+ if (!opt.allowDirectory && isDirectory({ mode }))
144
144
  throw UV('EISDIR', 'open', path);
145
145
  // Serialize entry creation with other operations on the parent directory
146
146
  const _ = __addDisposableResource(env_1, lockPathSync(fs, parentPath, 'rw', parentStats), false);
147
- const { euid: uid, egid: gid } = contextOf(this).credentials;
147
+ const { euid: uid, egid: gid } = contextOf($).credentials;
148
148
  const inode = fs.createFileSync(resolved, {
149
149
  mode,
150
150
  uid: parentStats.mode & constants.S_ISUID ? parentStats.uid : uid,
151
151
  gid: parentStats.mode & constants.S_ISGID ? parentStats.gid : gid,
152
152
  });
153
153
  // A new entry in the parent directory, which is a 'rename' event
154
- emitChange(this, 'rename', path);
155
- return new Handle(this, path, resolved, flag, cacheOf(fs).ref(resolved, inode));
154
+ emitChange($, 'rename', path);
155
+ return new Handle($, path, resolved, flag, cacheOf(fs).ref(resolved, inode));
156
156
  }
157
157
  catch (e_1) {
158
158
  env_1.error = e_1;
@@ -162,20 +162,20 @@ export function open(path, opt) {
162
162
  __disposeResources(env_1);
163
163
  }
164
164
  }
165
- if (checkAccess && (!hasAccess(this, stats, mode) || !hasAccess(this, stats, flags.toMode(flag)))) {
165
+ if (checkAccess && (!hasAccess($, stats, mode) || !hasAccess($, stats, flags.toMode(flag)))) {
166
166
  throw UV('EACCES', 'open', path);
167
167
  }
168
168
  if (flag & constants.O_EXCL)
169
169
  throw UV('EEXIST', 'open', path);
170
- if (!opt.allowDirectory && stats.mode & constants.S_IFDIR)
170
+ if (!opt.allowDirectory && isDirectory(stats))
171
171
  throw UV('EISDIR', 'open', path);
172
- const file = new Handle(this, path, resolved, flag, cacheOf(fs).ref(resolved, stats));
172
+ const file = new Handle($, path, resolved, flag, cacheOf(fs).ref(resolved, stats));
173
173
  if (flag & constants.O_TRUNC)
174
174
  file.truncateSync(0);
175
175
  return file;
176
176
  }
177
177
  export function readlink(path) {
178
- path = normalizePath(path);
178
+ path = normalizePath.call(this, path);
179
179
  const { fs, stats, path: resolved } = resolve(this, path, true, { syscall: 'readlink' });
180
180
  if (!stats)
181
181
  throw UV('ENOENT', 'readlink', path);
@@ -189,7 +189,7 @@ export function readlink(path) {
189
189
  return decodeUTF8(data);
190
190
  }
191
191
  export function mkdir(path, options = {}) {
192
- const original = normalizePath(path);
192
+ const original = normalizePath.call(this, path);
193
193
  const $ex = { syscall: 'mkdir', path: original };
194
194
  const { fullPath: realParent } = resolve(this, dirname(original), false, $ex);
195
195
  const { fs, path: target } = resolveMount(join(realParent, basename(original)), this, $ex);
@@ -246,7 +246,7 @@ export function mkdir(path, options = {}) {
246
246
  return firstCreated;
247
247
  }
248
248
  export function readdir(path, options = {}) {
249
- path = normalizePath(path);
249
+ path = normalizePath.call(this, path);
250
250
  const { fs, path: resolved } = resolve(this, path);
251
251
  // Node reports `readdir` failures as `scandir`
252
252
  const stats = cacheOf(fs).get(resolved)?.inode ?? wrap(fs, 'statSync', { path, syscall: 'scandir' })(resolved);
@@ -300,8 +300,8 @@ export function readdir(path, options = {}) {
300
300
  export function rename(oldPath, newPath) {
301
301
  const env_4 = { stack: [], error: void 0, hasError: false };
302
302
  try {
303
- oldPath = normalizePath(oldPath);
304
- newPath = normalizePath(newPath);
303
+ oldPath = normalizePath.call(this, oldPath);
304
+ newPath = normalizePath.call(this, newPath);
305
305
  const $ex = { syscall: 'rename', path: oldPath, dest: newPath };
306
306
  const src = resolve(this, oldPath, true, $ex);
307
307
  const dst = resolveMount(newPath, this, $ex);
@@ -357,8 +357,8 @@ export function rename(oldPath, newPath) {
357
357
  export function link(target, link) {
358
358
  const env_5 = { stack: [], error: void 0, hasError: false };
359
359
  try {
360
- target = normalizePath(target);
361
- link = normalizePath(link);
360
+ target = normalizePath.call(this, target);
361
+ link = normalizePath.call(this, link);
362
362
  const $ex = { syscall: 'link', path: target, dest: link };
363
363
  const { fs, path: resolved } = resolveMount(target, this, $ex);
364
364
  const dst = resolveMount(link, this, $ex);