@zenfs/core 2.6.6 → 2.7.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/memory.d.ts +1 -1
- package/dist/backends/store/fs.js +4 -4
- package/dist/config.js +7 -7
- package/dist/internal/contexts.d.ts +4 -0
- package/dist/internal/contexts.js +10 -6
- package/dist/internal/filesystem.d.ts +5 -0
- package/dist/internal/filesystem.js +18 -0
- package/dist/internal/inode.d.ts +6 -1
- package/dist/internal/inode.js +12 -3
- package/dist/internal/ioctl.d.ts +148 -0
- package/dist/internal/ioctl.js +368 -0
- package/dist/mixins/async.js +6 -1
- package/dist/mixins/mutexed.d.ts +3 -0
- package/dist/mixins/mutexed.js +29 -1
- package/dist/mixins/shared.d.ts +1 -1
- package/dist/mixins/shared.js +1 -0
- package/dist/mixins/sync.js +3 -0
- package/dist/node/sync.js +8 -8
- package/dist/vfs/async.js +2 -2
- package/dist/vfs/file.js +1 -1
- package/dist/vfs/ioctl.d.ts +8 -85
- package/dist/vfs/ioctl.js +67 -369
- package/dist/vfs/shared.d.ts +2 -0
- package/dist/vfs/shared.js +12 -8
- package/dist/vfs/sync.d.ts +1 -1
- package/dist/vfs/sync.js +11 -11
- package/package.json +10 -1
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
35
|
+
import { Errno, Exception, withErrno } from 'kerium';
|
|
36
|
+
import { sizeof } from 'memium';
|
|
37
|
+
import { $from, struct, types as t } from 'memium/decorators';
|
|
38
|
+
import { _throw } from 'utilium';
|
|
39
|
+
import { BufferView } from 'utilium/buffer';
|
|
40
|
+
import { InodeFlags } from './inode.js';
|
|
41
|
+
/*
|
|
42
|
+
* Flags for the fsxattr.xflags field
|
|
43
|
+
*/
|
|
44
|
+
var XFlag;
|
|
45
|
+
(function (XFlag) {
|
|
46
|
+
/** data in realtime volume */
|
|
47
|
+
XFlag[XFlag["RealTime"] = 1] = "RealTime";
|
|
48
|
+
/** preallocated file extents */
|
|
49
|
+
XFlag[XFlag["PreAlloc"] = 2] = "PreAlloc";
|
|
50
|
+
/** file cannot be modified */
|
|
51
|
+
XFlag[XFlag["Immutable"] = 8] = "Immutable";
|
|
52
|
+
/** all writes append */
|
|
53
|
+
XFlag[XFlag["Append"] = 16] = "Append";
|
|
54
|
+
/** all writes synchronous */
|
|
55
|
+
XFlag[XFlag["Sync"] = 32] = "Sync";
|
|
56
|
+
/** do not update access time */
|
|
57
|
+
XFlag[XFlag["NoAtime"] = 64] = "NoAtime";
|
|
58
|
+
/** do not include in backups */
|
|
59
|
+
XFlag[XFlag["NoDump"] = 128] = "NoDump";
|
|
60
|
+
/** create with rt bit set */
|
|
61
|
+
XFlag[XFlag["RtInherit"] = 256] = "RtInherit";
|
|
62
|
+
/** create with parents projid */
|
|
63
|
+
XFlag[XFlag["ProjInherit"] = 512] = "ProjInherit";
|
|
64
|
+
/** disallow symlink creation */
|
|
65
|
+
XFlag[XFlag["NoSymlinks"] = 1024] = "NoSymlinks";
|
|
66
|
+
/** extent size allocator hint */
|
|
67
|
+
XFlag[XFlag["ExtSize"] = 2048] = "ExtSize";
|
|
68
|
+
/** inherit inode extent size */
|
|
69
|
+
XFlag[XFlag["ExtSzInherit"] = 4096] = "ExtSzInherit";
|
|
70
|
+
/** do not defragment */
|
|
71
|
+
XFlag[XFlag["NoDefrag"] = 8192] = "NoDefrag";
|
|
72
|
+
/** use filestream allocator */
|
|
73
|
+
XFlag[XFlag["FileStream"] = 16384] = "FileStream";
|
|
74
|
+
/** use DAX for IO */
|
|
75
|
+
XFlag[XFlag["Dax"] = 32768] = "Dax";
|
|
76
|
+
/** CoW extent size allocator hint */
|
|
77
|
+
XFlag[XFlag["CowExtSize"] = 65536] = "CowExtSize";
|
|
78
|
+
/** no DIFLAG for this */
|
|
79
|
+
XFlag[XFlag["HasAttr"] = 2147483648] = "HasAttr";
|
|
80
|
+
})(XFlag || (XFlag = {}));
|
|
81
|
+
let fsxattr = (() => {
|
|
82
|
+
var _a, _b, _c, _d, _e;
|
|
83
|
+
let _classDecorators = [struct()];
|
|
84
|
+
let _classDescriptor;
|
|
85
|
+
let _classExtraInitializers = [];
|
|
86
|
+
let _classThis;
|
|
87
|
+
let _classSuper = $from(BufferView);
|
|
88
|
+
let _xflags_decorators;
|
|
89
|
+
let _xflags_initializers = [];
|
|
90
|
+
let _xflags_extraInitializers = [];
|
|
91
|
+
let _extsize_decorators;
|
|
92
|
+
let _extsize_initializers = [];
|
|
93
|
+
let _extsize_extraInitializers = [];
|
|
94
|
+
let _nextents_decorators;
|
|
95
|
+
let _nextents_initializers = [];
|
|
96
|
+
let _nextents_extraInitializers = [];
|
|
97
|
+
let _projid_decorators;
|
|
98
|
+
let _projid_initializers = [];
|
|
99
|
+
let _projid_extraInitializers = [];
|
|
100
|
+
let _cowextsize_decorators;
|
|
101
|
+
let _cowextsize_initializers = [];
|
|
102
|
+
let _cowextsize_extraInitializers = [];
|
|
103
|
+
let _pad_decorators;
|
|
104
|
+
let _pad_initializers = [];
|
|
105
|
+
let _pad_extraInitializers = [];
|
|
106
|
+
var fsxattr = class extends _classSuper {
|
|
107
|
+
static { _classThis = this; }
|
|
108
|
+
static {
|
|
109
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
110
|
+
_xflags_decorators = [(_a = t).uint32.bind(_a)];
|
|
111
|
+
_extsize_decorators = [(_b = t).uint32.bind(_b)];
|
|
112
|
+
_nextents_decorators = [(_c = t).uint32.bind(_c)];
|
|
113
|
+
_projid_decorators = [(_d = t).uint32.bind(_d)];
|
|
114
|
+
_cowextsize_decorators = [(_e = t).uint32.bind(_e)];
|
|
115
|
+
_pad_decorators = [t.char(8)];
|
|
116
|
+
__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);
|
|
117
|
+
__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);
|
|
118
|
+
__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);
|
|
119
|
+
__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);
|
|
120
|
+
__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);
|
|
121
|
+
__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);
|
|
122
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
123
|
+
fsxattr = _classThis = _classDescriptor.value;
|
|
124
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
125
|
+
}
|
|
126
|
+
static name = 'fsxattr';
|
|
127
|
+
#xflags_accessor_storage = __runInitializers(this, _xflags_initializers, void 0);
|
|
128
|
+
/** xflags field value */
|
|
129
|
+
get xflags() { return this.#xflags_accessor_storage; }
|
|
130
|
+
set xflags(value) { this.#xflags_accessor_storage = value; }
|
|
131
|
+
#extsize_accessor_storage = (__runInitializers(this, _xflags_extraInitializers), __runInitializers(this, _extsize_initializers, void 0));
|
|
132
|
+
/** extsize field value */
|
|
133
|
+
get extsize() { return this.#extsize_accessor_storage; }
|
|
134
|
+
set extsize(value) { this.#extsize_accessor_storage = value; }
|
|
135
|
+
#nextents_accessor_storage = (__runInitializers(this, _extsize_extraInitializers), __runInitializers(this, _nextents_initializers, void 0));
|
|
136
|
+
/** nextents field value */
|
|
137
|
+
get nextents() { return this.#nextents_accessor_storage; }
|
|
138
|
+
set nextents(value) { this.#nextents_accessor_storage = value; }
|
|
139
|
+
#projid_accessor_storage = (__runInitializers(this, _nextents_extraInitializers), __runInitializers(this, _projid_initializers, void 0));
|
|
140
|
+
/** project identifier */
|
|
141
|
+
get projid() { return this.#projid_accessor_storage; }
|
|
142
|
+
set projid(value) { this.#projid_accessor_storage = value; }
|
|
143
|
+
#cowextsize_accessor_storage = (__runInitializers(this, _projid_extraInitializers), __runInitializers(this, _cowextsize_initializers, void 0));
|
|
144
|
+
/** CoW extsize field value */
|
|
145
|
+
get cowextsize() { return this.#cowextsize_accessor_storage; }
|
|
146
|
+
set cowextsize(value) { this.#cowextsize_accessor_storage = value; }
|
|
147
|
+
#pad_accessor_storage = (__runInitializers(this, _cowextsize_extraInitializers), __runInitializers(this, _pad_initializers, []));
|
|
148
|
+
get pad() { return this.#pad_accessor_storage; }
|
|
149
|
+
set pad(value) { this.#pad_accessor_storage = value; }
|
|
150
|
+
constructor(inode = _throw(new Exception(Errno.EINVAL, 'fsxattr must be initialized with an inode'))) {
|
|
151
|
+
super(new ArrayBuffer(sizeof(fsxattr)));
|
|
152
|
+
__runInitializers(this, _pad_extraInitializers);
|
|
153
|
+
this.extsize = inode.size;
|
|
154
|
+
this.nextents = 1;
|
|
155
|
+
this.projid = inode.uid;
|
|
156
|
+
this.cowextsize = inode.size;
|
|
157
|
+
for (const name of Object.keys(InodeFlags)) {
|
|
158
|
+
if (!((inode.flags || 0) & InodeFlags[name]))
|
|
159
|
+
continue;
|
|
160
|
+
if (name in XFlag)
|
|
161
|
+
this.xflags |= XFlag[name];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
static {
|
|
165
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
return fsxattr = _classThis;
|
|
169
|
+
})();
|
|
170
|
+
/**
|
|
171
|
+
* Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
|
|
172
|
+
* @see `FS_*_FL` in `include/uapi/linux/fs.h` (around L250)
|
|
173
|
+
* @experimental
|
|
174
|
+
*/
|
|
175
|
+
var FileFlag;
|
|
176
|
+
(function (FileFlag) {
|
|
177
|
+
/** Secure deletion */
|
|
178
|
+
FileFlag[FileFlag["SecureRm"] = 1] = "SecureRm";
|
|
179
|
+
/** Undelete */
|
|
180
|
+
FileFlag[FileFlag["Undelete"] = 2] = "Undelete";
|
|
181
|
+
/** Compress file */
|
|
182
|
+
FileFlag[FileFlag["Compress"] = 4] = "Compress";
|
|
183
|
+
/** Synchronous updates */
|
|
184
|
+
FileFlag[FileFlag["Sync"] = 8] = "Sync";
|
|
185
|
+
/** Immutable file */
|
|
186
|
+
FileFlag[FileFlag["Immutable"] = 16] = "Immutable";
|
|
187
|
+
/** Writes to file may only append */
|
|
188
|
+
FileFlag[FileFlag["Append"] = 32] = "Append";
|
|
189
|
+
/** do not dump file */
|
|
190
|
+
FileFlag[FileFlag["NoDump"] = 64] = "NoDump";
|
|
191
|
+
/** do not update atime */
|
|
192
|
+
FileFlag[FileFlag["NoAtime"] = 128] = "NoAtime";
|
|
193
|
+
// Reserved for compression usage...
|
|
194
|
+
FileFlag[FileFlag["Dirty"] = 256] = "Dirty";
|
|
195
|
+
/** One or more compressed clusters */
|
|
196
|
+
FileFlag[FileFlag["CompressBlk"] = 512] = "CompressBlk";
|
|
197
|
+
/** Don't compress */
|
|
198
|
+
FileFlag[FileFlag["NoCompress"] = 1024] = "NoCompress";
|
|
199
|
+
// End compression flags --- maybe not all used
|
|
200
|
+
/** Encrypted file */
|
|
201
|
+
FileFlag[FileFlag["Encrypt"] = 2048] = "Encrypt";
|
|
202
|
+
/** btree format dir */
|
|
203
|
+
FileFlag[FileFlag["Btree"] = 4096] = "Btree";
|
|
204
|
+
/** hash-indexed directory */
|
|
205
|
+
// eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
|
|
206
|
+
FileFlag[FileFlag["Index"] = 4096] = "Index";
|
|
207
|
+
/** AFS directory */
|
|
208
|
+
FileFlag[FileFlag["IMagic"] = 8192] = "IMagic";
|
|
209
|
+
/** Reserved for ext3 */
|
|
210
|
+
FileFlag[FileFlag["JournalData"] = 16384] = "JournalData";
|
|
211
|
+
/** file tail should not be merged */
|
|
212
|
+
FileFlag[FileFlag["NoTail"] = 32768] = "NoTail";
|
|
213
|
+
/** dirsync behaviour (directories only) */
|
|
214
|
+
FileFlag[FileFlag["DirSync"] = 65536] = "DirSync";
|
|
215
|
+
/** Top of directory hierarchies*/
|
|
216
|
+
FileFlag[FileFlag["TopDir"] = 131072] = "TopDir";
|
|
217
|
+
/** Reserved for ext4 */
|
|
218
|
+
FileFlag[FileFlag["HugeFile"] = 262144] = "HugeFile";
|
|
219
|
+
/** Extents */
|
|
220
|
+
FileFlag[FileFlag["Extent"] = 524288] = "Extent";
|
|
221
|
+
/** Verity protected inode */
|
|
222
|
+
FileFlag[FileFlag["Verity"] = 1048576] = "Verity";
|
|
223
|
+
/** Inode used for large EA */
|
|
224
|
+
FileFlag[FileFlag["EaInode"] = 2097152] = "EaInode";
|
|
225
|
+
/** Reserved for ext4 */
|
|
226
|
+
FileFlag[FileFlag["EofBlocks"] = 4194304] = "EofBlocks";
|
|
227
|
+
/** Do not cow file */
|
|
228
|
+
FileFlag[FileFlag["NoCow"] = 8388608] = "NoCow";
|
|
229
|
+
/** Inode is DAX */
|
|
230
|
+
FileFlag[FileFlag["Dax"] = 33554432] = "Dax";
|
|
231
|
+
/** Reserved for ext4 */
|
|
232
|
+
FileFlag[FileFlag["InlineData"] = 268435456] = "InlineData";
|
|
233
|
+
/** Create with parents projid */
|
|
234
|
+
FileFlag[FileFlag["ProjInherit"] = 536870912] = "ProjInherit";
|
|
235
|
+
/** Folder is case insensitive */
|
|
236
|
+
FileFlag[FileFlag["CaseFold"] = 1073741824] = "CaseFold";
|
|
237
|
+
/** reserved for ext2 lib */
|
|
238
|
+
FileFlag[FileFlag["Reserved"] = 2147483648] = "Reserved";
|
|
239
|
+
})(FileFlag || (FileFlag = {}));
|
|
240
|
+
/**
|
|
241
|
+
* `FS_IOC_*` commands for {@link ioctl | `ioctl`}
|
|
242
|
+
* @remarks
|
|
243
|
+
* These are computed from a script since constant values are needed for enum member types
|
|
244
|
+
*/
|
|
245
|
+
export var IOC;
|
|
246
|
+
(function (IOC) {
|
|
247
|
+
IOC[IOC["GetFlags"] = 2148034049] = "GetFlags";
|
|
248
|
+
IOC[IOC["SetFlags"] = 1074292226] = "SetFlags";
|
|
249
|
+
IOC[IOC["GetVersion"] = 2148038145] = "GetVersion";
|
|
250
|
+
IOC[IOC["SetVersion"] = 1074296322] = "SetVersion";
|
|
251
|
+
IOC[IOC["Fiemap"] = 3223348747] = "Fiemap";
|
|
252
|
+
IOC[IOC["GetXattr"] = 2149341215] = "GetXattr";
|
|
253
|
+
IOC[IOC["SetXattr"] = 1075599392] = "SetXattr";
|
|
254
|
+
IOC[IOC["GetLabel"] = 2164298801] = "GetLabel";
|
|
255
|
+
IOC[IOC["SetLabel"] = 1090556978] = "SetLabel";
|
|
256
|
+
IOC[IOC["GetUUID"] = 2148603136] = "GetUUID";
|
|
257
|
+
IOC[IOC["GetSysfsPath"] = 2155943169] = "GetSysfsPath";
|
|
258
|
+
})(IOC || (IOC = {}));
|
|
259
|
+
/**
|
|
260
|
+
* `FS_IOC32_*` commands for {@link ioctl | `ioctl`}
|
|
261
|
+
* @remarks
|
|
262
|
+
* These are computed from a script since constant values are needed for enum member types
|
|
263
|
+
*/
|
|
264
|
+
export var IOC32;
|
|
265
|
+
(function (IOC32) {
|
|
266
|
+
IOC32[IOC32["GetFlags"] = 2147771905] = "GetFlags";
|
|
267
|
+
IOC32[IOC32["SetFlags"] = 1074030082] = "SetFlags";
|
|
268
|
+
IOC32[IOC32["GetVersion"] = 2147776001] = "GetVersion";
|
|
269
|
+
IOC32[IOC32["SetVersion"] = 1074034178] = "SetVersion";
|
|
270
|
+
})(IOC32 || (IOC32 = {}));
|
|
271
|
+
/**
|
|
272
|
+
* @internal
|
|
273
|
+
* @category ioctl
|
|
274
|
+
*/
|
|
275
|
+
export const ioctl_default_ops = {
|
|
276
|
+
[IOC.GetFlags]($) {
|
|
277
|
+
if (typeof $.inode.flags !== 'number')
|
|
278
|
+
throw withErrno('ENOTTY');
|
|
279
|
+
return $.inode.flags;
|
|
280
|
+
},
|
|
281
|
+
[IOC32.GetFlags]($) {
|
|
282
|
+
if (typeof $.inode.flags !== 'number')
|
|
283
|
+
throw withErrno('ENOTTY');
|
|
284
|
+
return $.inode.flags;
|
|
285
|
+
},
|
|
286
|
+
[IOC.GetVersion]($) {
|
|
287
|
+
if (typeof $.inode.version !== 'number')
|
|
288
|
+
throw withErrno('ENOTTY');
|
|
289
|
+
return $.inode.version;
|
|
290
|
+
},
|
|
291
|
+
[IOC32.GetVersion]($) {
|
|
292
|
+
if (typeof $.inode.version !== 'number')
|
|
293
|
+
throw withErrno('ENOTTY');
|
|
294
|
+
return $.inode.version;
|
|
295
|
+
},
|
|
296
|
+
[IOC.Fiemap]() {
|
|
297
|
+
throw withErrno('ENOTSUP');
|
|
298
|
+
},
|
|
299
|
+
[IOC.GetXattr]($, _name) {
|
|
300
|
+
return new fsxattr($.inode);
|
|
301
|
+
},
|
|
302
|
+
[IOC.SetXattr]($, _name, _value) {
|
|
303
|
+
throw withErrno('ENOTSUP');
|
|
304
|
+
},
|
|
305
|
+
[IOC.GetLabel]($) {
|
|
306
|
+
return $.fs.label;
|
|
307
|
+
},
|
|
308
|
+
[IOC.SetLabel]($, label) {
|
|
309
|
+
$.fs.label = label;
|
|
310
|
+
},
|
|
311
|
+
[IOC.GetUUID]($) {
|
|
312
|
+
return $.fs.uuid;
|
|
313
|
+
},
|
|
314
|
+
[IOC.GetSysfsPath]($) {
|
|
315
|
+
/**
|
|
316
|
+
* Returns the path component under /sys/fs/ that refers to this filesystem;
|
|
317
|
+
* also /sys/kernel/debug/ for filesystems with debugfs exports
|
|
318
|
+
* @todo Implement sysfs and have each FS implement the /sys/fs/<name> tree
|
|
319
|
+
*/
|
|
320
|
+
return `/sys/fs/${$.fs.name}/${$.fs.uuid}`;
|
|
321
|
+
},
|
|
322
|
+
};
|
|
323
|
+
/**
|
|
324
|
+
* @internal
|
|
325
|
+
* @category ioctl
|
|
326
|
+
*/
|
|
327
|
+
export const ioctl_default_ops_async = {
|
|
328
|
+
...ioctl_default_ops,
|
|
329
|
+
async [IOC.SetFlags]($, flags) {
|
|
330
|
+
$.inode.flags = flags;
|
|
331
|
+
await $.fs.touch($.path, $.inode);
|
|
332
|
+
},
|
|
333
|
+
async [IOC32.SetFlags]($, flags) {
|
|
334
|
+
$.inode.flags = flags;
|
|
335
|
+
await $.fs.touch($.path, $.inode);
|
|
336
|
+
},
|
|
337
|
+
async [IOC.SetVersion]($, version) {
|
|
338
|
+
$.inode.version = version;
|
|
339
|
+
await $.fs.touch($.path, $.inode);
|
|
340
|
+
},
|
|
341
|
+
async [IOC32.SetVersion]($, version) {
|
|
342
|
+
$.inode.version = version;
|
|
343
|
+
await $.fs.touch($.path, $.inode);
|
|
344
|
+
},
|
|
345
|
+
};
|
|
346
|
+
/**
|
|
347
|
+
* @internal
|
|
348
|
+
* @category ioctl
|
|
349
|
+
*/
|
|
350
|
+
export const ioctl_default_ops_sync = {
|
|
351
|
+
...ioctl_default_ops,
|
|
352
|
+
[IOC.SetFlags]($, flags) {
|
|
353
|
+
$.inode.flags = flags;
|
|
354
|
+
$.fs.touchSync($.path, $.inode);
|
|
355
|
+
},
|
|
356
|
+
[IOC32.SetFlags]($, flags) {
|
|
357
|
+
$.inode.flags = flags;
|
|
358
|
+
$.fs.touchSync($.path, $.inode);
|
|
359
|
+
},
|
|
360
|
+
[IOC.SetVersion]($, version) {
|
|
361
|
+
$.inode.version = version;
|
|
362
|
+
$.fs.touchSync($.path, $.inode);
|
|
363
|
+
},
|
|
364
|
+
[IOC32.SetVersion]($, version) {
|
|
365
|
+
$.inode.version = version;
|
|
366
|
+
$.fs.touchSync($.path, $.inode);
|
|
367
|
+
},
|
|
368
|
+
};
|
package/dist/mixins/async.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
2
2
|
import { withErrno } from 'kerium';
|
|
3
3
|
import { crit, debug, err } from 'kerium/log';
|
|
4
4
|
import { StoreFS } from '../backends/store/fs.js';
|
|
5
5
|
import { isDirectory } from '../internal/inode.js';
|
|
6
6
|
import { join } from '../path.js';
|
|
7
|
+
import { _asyncFSKeys } from './shared.js';
|
|
7
8
|
/**
|
|
8
9
|
* Async() implements synchronous methods on an asynchronous file system
|
|
9
10
|
*
|
|
@@ -143,6 +144,10 @@ export function Async(FS) {
|
|
|
143
144
|
this._sync.writeSync(path, buffer, offset);
|
|
144
145
|
this._async(() => this.write(path, buffer, offset));
|
|
145
146
|
}
|
|
147
|
+
ioctlSync(context, command, ...args) {
|
|
148
|
+
this.checkSync();
|
|
149
|
+
return this._sync.ioctlSync(context, command, ...args);
|
|
150
|
+
}
|
|
146
151
|
streamWrite(path, options) {
|
|
147
152
|
this.checkSync();
|
|
148
153
|
const sync = this._sync.streamWrite(path, options).getWriter();
|
package/dist/mixins/mutexed.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { UUID } from 'node:crypto';
|
|
|
2
2
|
import type { Concrete } from 'utilium';
|
|
3
3
|
import type { CreationOptions, FileSystem, StreamOptions, UsageInfo } from '../internal/filesystem.js';
|
|
4
4
|
import type { InodeLike } from '../internal/inode.js';
|
|
5
|
+
import type { IoctlContext } from '../internal/ioctl.js';
|
|
5
6
|
import '../polyfills.js';
|
|
6
7
|
/**
|
|
7
8
|
* @category Internals
|
|
@@ -90,6 +91,8 @@ export declare class _MutexedFS<T extends FileSystem> implements FileSystem {
|
|
|
90
91
|
writeSync(path: string, buffer: Uint8Array, offset: number): void;
|
|
91
92
|
streamRead(path: string, options: StreamOptions): ReadableStream;
|
|
92
93
|
streamWrite(path: string, options: StreamOptions): WritableStream;
|
|
94
|
+
ioctl(context: IoctlContext, command: number, ...args: any[]): Promise<any>;
|
|
95
|
+
ioctlSync(context: IoctlContext, command: number, ...args: any[]): any;
|
|
93
96
|
}
|
|
94
97
|
/**
|
|
95
98
|
* This serializes access to an underlying async filesystem.
|
package/dist/mixins/mutexed.js
CHANGED
|
@@ -50,6 +50,7 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
50
50
|
var e = new Error(message);
|
|
51
51
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
52
|
});
|
|
53
|
+
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
53
54
|
import { withErrno } from 'kerium';
|
|
54
55
|
import { err } from 'kerium/log';
|
|
55
56
|
import '../polyfills.js';
|
|
@@ -170,7 +171,6 @@ export class _MutexedFS {
|
|
|
170
171
|
get isLocked() {
|
|
171
172
|
return !!this.currentLock?.isLocked;
|
|
172
173
|
}
|
|
173
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
174
174
|
async rename(oldPath, newPath) {
|
|
175
175
|
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
176
176
|
try {
|
|
@@ -563,6 +563,34 @@ export class _MutexedFS {
|
|
|
563
563
|
__disposeResources(env_28);
|
|
564
564
|
}
|
|
565
565
|
}
|
|
566
|
+
async ioctl(context, command, ...args) {
|
|
567
|
+
const env_29 = { stack: [], error: void 0, hasError: false };
|
|
568
|
+
try {
|
|
569
|
+
const _ = __addDisposableResource(env_29, await this.lock(), false);
|
|
570
|
+
return await this._fs.ioctl({ ...context, fs: this._fs }, command, ...args);
|
|
571
|
+
}
|
|
572
|
+
catch (e_29) {
|
|
573
|
+
env_29.error = e_29;
|
|
574
|
+
env_29.hasError = true;
|
|
575
|
+
}
|
|
576
|
+
finally {
|
|
577
|
+
__disposeResources(env_29);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
ioctlSync(context, command, ...args) {
|
|
581
|
+
const env_30 = { stack: [], error: void 0, hasError: false };
|
|
582
|
+
try {
|
|
583
|
+
const _ = __addDisposableResource(env_30, this.lockSync(), false);
|
|
584
|
+
return this._fs.ioctlSync({ ...context, fs: this._fs }, command, ...args);
|
|
585
|
+
}
|
|
586
|
+
catch (e_30) {
|
|
587
|
+
env_30.error = e_30;
|
|
588
|
+
env_30.hasError = true;
|
|
589
|
+
}
|
|
590
|
+
finally {
|
|
591
|
+
__disposeResources(env_30);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
566
594
|
}
|
|
567
595
|
/**
|
|
568
596
|
* This serializes access to an underlying async filesystem.
|
package/dist/mixins/shared.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type _SyncFSKeys = Exclude<Extract<keyof FileSystem, `${string}Sync`>, '_
|
|
|
18
18
|
export type _AsyncFSKeys = {
|
|
19
19
|
[K in _SyncFSKeys]: K extends `${infer T}Sync` ? T : never;
|
|
20
20
|
}[_SyncFSKeys];
|
|
21
|
-
export declare const _asyncFSKeys: ["rename", "stat", "touch", "createFile", "unlink", "rmdir", "mkdir", "readdir", "exists", "link", "sync", "read", "write"];
|
|
21
|
+
export declare const _asyncFSKeys: ["rename", "stat", "touch", "createFile", "unlink", "rmdir", "mkdir", "readdir", "exists", "link", "sync", "read", "write", "ioctl"];
|
|
22
22
|
/**
|
|
23
23
|
* Asynchronous `FileSystem` methods. This is a convenience type for all of the async operations.
|
|
24
24
|
* @category Internals
|
package/dist/mixins/shared.js
CHANGED
package/dist/mixins/sync.js
CHANGED
package/dist/node/sync.js
CHANGED
|
@@ -117,7 +117,7 @@ lstatSync;
|
|
|
117
117
|
export function truncateSync(path, len = 0) {
|
|
118
118
|
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
119
119
|
try {
|
|
120
|
-
const file = __addDisposableResource(env_1, _sync.open
|
|
120
|
+
const file = __addDisposableResource(env_1, _sync.open(this, path, { flag: 'r+' }), false);
|
|
121
121
|
len ||= 0;
|
|
122
122
|
if (len < 0)
|
|
123
123
|
throw UV('EINVAL', 'truncate', path.toString());
|
|
@@ -165,7 +165,7 @@ unlinkSync;
|
|
|
165
165
|
* @param flag {@link https://nodejs.org/api/fs.html#file-system-flags}
|
|
166
166
|
*/
|
|
167
167
|
export function openSync(path, flag, mode = constants.F_OK) {
|
|
168
|
-
return toFD(_sync.open
|
|
168
|
+
return toFD(_sync.open(this, path, { flag, mode }));
|
|
169
169
|
}
|
|
170
170
|
openSync;
|
|
171
171
|
/**
|
|
@@ -173,7 +173,7 @@ openSync;
|
|
|
173
173
|
* @internal
|
|
174
174
|
*/
|
|
175
175
|
export function lopenSync(path, flag, mode) {
|
|
176
|
-
return toFD(_sync.open
|
|
176
|
+
return toFD(_sync.open(this, path, { flag, mode, preserveSymlinks: true }));
|
|
177
177
|
}
|
|
178
178
|
export function readFileSync(path, _options = {}) {
|
|
179
179
|
const env_3 = { stack: [], error: void 0, hasError: false };
|
|
@@ -184,7 +184,7 @@ export function readFileSync(path, _options = {}) {
|
|
|
184
184
|
throw UV('EBADF', 'read', path.toString());
|
|
185
185
|
const file = __addDisposableResource(env_3, typeof path == 'number'
|
|
186
186
|
? fromFD(this, path)
|
|
187
|
-
: _sync.open
|
|
187
|
+
: _sync.open(this, path.toString(), { flag: options.flag, mode: 0o644, preserveSymlinks: false }), false);
|
|
188
188
|
const { size } = file.stat();
|
|
189
189
|
const data = Buffer.alloc(size);
|
|
190
190
|
file.readSync(data, 0, size, 0);
|
|
@@ -216,7 +216,7 @@ export function writeFileSync(path, data, _options = {}) {
|
|
|
216
216
|
}
|
|
217
217
|
const file = __addDisposableResource(env_4, typeof path == 'number'
|
|
218
218
|
? fromFD(this, path)
|
|
219
|
-
: _sync.open
|
|
219
|
+
: _sync.open(this, path.toString(), {
|
|
220
220
|
flag,
|
|
221
221
|
mode: options.mode,
|
|
222
222
|
}), false);
|
|
@@ -250,7 +250,7 @@ export function appendFileSync(filename, data, _options = {}) {
|
|
|
250
250
|
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
251
251
|
const file = typeof filename == 'number'
|
|
252
252
|
? fromFD(this, filename)
|
|
253
|
-
: _sync.open
|
|
253
|
+
: _sync.open(this, normalizePath(filename), {
|
|
254
254
|
flag,
|
|
255
255
|
mode: options.mode,
|
|
256
256
|
});
|
|
@@ -416,7 +416,7 @@ export function symlinkSync(target, path, type = 'file') {
|
|
|
416
416
|
if (!['file', 'dir', 'junction'].includes(type))
|
|
417
417
|
throw new TypeError('Invalid symlink type: ' + type);
|
|
418
418
|
path = normalizePath(path);
|
|
419
|
-
const file = __addDisposableResource(env_6, _sync.open
|
|
419
|
+
const file = __addDisposableResource(env_6, _sync.open(this, path, { flag: 'wx', mode: 0o644 }), false);
|
|
420
420
|
file.writeSync(encodeUTF8(normalizePath(target, true)));
|
|
421
421
|
file.chmodSync(constants.S_IFLNK);
|
|
422
422
|
}
|
|
@@ -442,7 +442,7 @@ readlinkSync;
|
|
|
442
442
|
export function chownSync(path, uid, gid) {
|
|
443
443
|
const env_7 = { stack: [], error: void 0, hasError: false };
|
|
444
444
|
try {
|
|
445
|
-
const handle = __addDisposableResource(env_7, _sync.open
|
|
445
|
+
const handle = __addDisposableResource(env_7, _sync.open(this, path, { flag: 'r+', mode: constants.F_OK }), false);
|
|
446
446
|
handle.chownSync(uid, gid);
|
|
447
447
|
}
|
|
448
448
|
catch (e_7) {
|
package/dist/vfs/async.js
CHANGED
|
@@ -131,7 +131,7 @@ export async function open($, path, opt) {
|
|
|
131
131
|
throw UV('EACCES', 'open', dirname(path));
|
|
132
132
|
if (!isDirectory(parentStats))
|
|
133
133
|
throw UV('ENOTDIR', 'open', dirname(path));
|
|
134
|
-
if (!opt.allowDirectory && mode
|
|
134
|
+
if (!opt.allowDirectory && isDirectory({ mode }))
|
|
135
135
|
throw UV('EISDIR', 'open', path);
|
|
136
136
|
// Serialize entry creation with other operations on the parent directory
|
|
137
137
|
const _ = __addDisposableResource(env_1, await lockPath(fs, parentPath, 'rw', parentStats), false);
|
|
@@ -161,7 +161,7 @@ export async function open($, path, opt) {
|
|
|
161
161
|
throw UV('EACCES', $ex);
|
|
162
162
|
if (flag & constants.O_EXCL)
|
|
163
163
|
throw UV('EEXIST', $ex);
|
|
164
|
-
if (!opt.allowDirectory && mode
|
|
164
|
+
if (!opt.allowDirectory && isDirectory({ mode }))
|
|
165
165
|
throw UV('EISDIR', 'open', path);
|
|
166
166
|
const handle = new Handle($, path, resolved, flag, cacheOf(fs).ref(resolved, stats));
|
|
167
167
|
if (flag & constants.O_TRUNC)
|
package/dist/vfs/file.js
CHANGED
|
@@ -676,7 +676,7 @@ export { Handle };
|
|
|
676
676
|
export function toFD(file) {
|
|
677
677
|
const map = contextOf(file.context).descriptors;
|
|
678
678
|
// @todo use `Iterator` helper #296
|
|
679
|
-
const fd = Array.from(map.keys()).reduce((
|
|
679
|
+
const fd = Array.from(map.keys()).reduce((next, k) => Math.max(next, k + 1), 4);
|
|
680
680
|
map.set(fd, file);
|
|
681
681
|
return fd;
|
|
682
682
|
}
|