@zenfs/core 2.6.5 → 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.
@@ -11,7 +11,8 @@ const journalOperations = new Set(['delete']);
11
11
  function isJournalOp(op) {
12
12
  return journalOperations.has(op);
13
13
  }
14
- const maxOpLength = Math.max(...[...journalOperations].map(op => op.length));
14
+ // @todo use `Iterator` helper #296
15
+ const maxOpLength = [...journalOperations].reduce((max, op) => Math.max(max, op.length), 0);
15
16
  const journalMagicString = '#journal@v0\n';
16
17
  /**
17
18
  * Tracks various operations for the CoW backend
@@ -450,7 +451,7 @@ export class CopyOnWriteFS extends FileSystem {
450
451
  if (size)
451
452
  this.readable.readSync(path, data, 0, size);
452
453
  this.writable.createFileSync(path, stats);
453
- this.writable.touchSync(path, stats);
454
+ this.writable.touchSync(path, { ...pick(stats, _inode_fields), attributes: stats.attributes, size });
454
455
  if (size)
455
456
  this.writable.writeSync(path, data, 0);
456
457
  }
@@ -468,7 +469,7 @@ export class CopyOnWriteFS extends FileSystem {
468
469
  if (size)
469
470
  await this.readable.read(path, data, 0, size);
470
471
  await this.writable.createFile(path, stats);
471
- await this.writable.touch(path, stats);
472
+ await this.writable.touch(path, { ...pick(stats, _inode_fields), attributes: stats.attributes, size });
472
473
  if (size)
473
474
  await this.writable.write(path, data, 0);
474
475
  }
@@ -1,6 +1,7 @@
1
1
  import type { IndexData } from '../internal/file_index.js';
2
2
  import { Index } from '../internal/file_index.js';
3
3
  import { IndexFS } from '../internal/index_fs.js';
4
+ import type { Inode, InodeLike } from '../internal/inode.js';
4
5
  import type { SharedConfig } from './backend.js';
5
6
  /**
6
7
  * Configuration options for FetchFS.
@@ -45,6 +46,9 @@ export declare class FetchFS extends IndexFS {
45
46
  */
46
47
  protected _async(p: Promise<unknown>): void;
47
48
  constructor(index: Index, baseUrl: string, requestInit?: RequestInit, remoteWrite?: boolean | undefined);
49
+ protected resize(path: string, inode: Inode, oldSize: number): Promise<void> | void;
50
+ touch(path: string, metadata: InodeLike): Promise<void>;
51
+ touchSync(path: string, metadata: InodeLike): void;
48
52
  protected remove(path: string): Promise<void>;
49
53
  protected removeSync(path: string): void;
50
54
  read(path: string, buffer: Uint8Array, offset: number | undefined, end: number): Promise<void>;
@@ -1,10 +1,12 @@
1
1
  // SPDX-License-Identifier: LGPL-3.0-or-later
2
2
  import { withErrno } from 'kerium';
3
3
  import { debug, err, warn } from 'kerium/log';
4
- import { decodeUTF8 } from 'utilium';
4
+ import { _throw, decodeUTF8 } from 'utilium';
5
+ import { Resource } from 'utilium/cache';
5
6
  import * as requests from 'utilium/requests';
6
7
  import { Index } from '../internal/file_index.js';
7
8
  import { IndexFS } from '../internal/index_fs.js';
9
+ import { isDirectory } from '../internal/inode.js';
8
10
  import { normalizePath } from '../utils.js';
9
11
  import { S_IFREG } from '../constants.js';
10
12
  /** Parse and throw */
@@ -48,6 +50,33 @@ export class FetchFS extends IndexFS {
48
50
  this.requestInit = requestInit;
49
51
  this.remoteWrite = remoteWrite;
50
52
  }
53
+ resize(path, inode, oldSize) {
54
+ if (isDirectory(inode) || inode.size == oldSize)
55
+ return;
56
+ const url = this.baseUrl + path;
57
+ const resource = requests.resourcesCache.get(url) ?? new Resource(url, oldSize, {}, requests.resourcesCache);
58
+ resource.size = inode.size;
59
+ if (inode.size < oldSize)
60
+ return;
61
+ const zeroes = new Uint8Array(inode.size - oldSize);
62
+ resource.add(zeroes, oldSize);
63
+ if (this.remoteWrite)
64
+ return requests.set(url, zeroes, { offset: oldSize, warn }, this.requestInit).catch(parseError);
65
+ }
66
+ async touch(path, metadata) {
67
+ const inode = this.index.get(path) ?? _throw(withErrno('ENOENT'));
68
+ const oldSize = inode.size;
69
+ inode.update(metadata);
70
+ await this.resize(path, inode, oldSize);
71
+ }
72
+ touchSync(path, metadata) {
73
+ const inode = this.index.get(path) ?? _throw(withErrno('ENOENT'));
74
+ const oldSize = inode.size;
75
+ inode.update(metadata);
76
+ const pending = this.resize(path, inode, oldSize);
77
+ if (pending)
78
+ this._async(pending);
79
+ }
51
80
  async remove(path) {
52
81
  await requests.remove(this.baseUrl + path, { warn, cacheOnly: !this.remoteWrite }, this.requestInit);
53
82
  }
@@ -9,7 +9,7 @@ export declare class InMemoryStore extends Map<number, Uint8Array> implements Sy
9
9
  readonly maxSize: number;
10
10
  readonly label?: string | undefined;
11
11
  readonly flags: readonly [];
12
- readonly name = "tmpfs";
12
+ readonly name: string;
13
13
  constructor(maxSize?: number, label?: string | undefined);
14
14
  sync(): Promise<void>;
15
15
  transaction(): SyncMapTransaction;
@@ -234,7 +234,7 @@ export class StoreFS extends FileSystem {
234
234
  const [path, ino] = queue.shift();
235
235
  const inode = new Inode(await tx.get(ino));
236
236
  index.set(path, inode);
237
- if (inode.mode & S_IFDIR) {
237
+ if (isDirectory(inode)) {
238
238
  const dir = decodeDirListing((await tx.get(inode.data)) ?? _throw(withErrno('ENODATA')));
239
239
  for (const [name, id] of Object.entries(dir)) {
240
240
  queue.push([join(path, name), id]);
@@ -265,7 +265,7 @@ export class StoreFS extends FileSystem {
265
265
  const [path, ino] = queue.shift();
266
266
  const inode = new Inode(tx.getSync(ino));
267
267
  index.set(path, inode);
268
- if (inode.mode & S_IFDIR) {
268
+ if (isDirectory(inode)) {
269
269
  const dir = decodeDirListing(tx.getSync(inode.data) ?? _throw(withErrno('ENODATA')));
270
270
  for (const [name, id] of Object.entries(dir)) {
271
271
  queue.push([join(path, name), id]);
@@ -418,6 +418,12 @@ export class StoreFS extends FileSystem {
418
418
  try {
419
419
  const tx = __addDisposableResource(env_9, this.transaction(), true);
420
420
  const inode = await this.findInode(tx, path);
421
+ if (!isDirectory(inode) && metadata.size !== undefined && metadata.size !== inode.size) {
422
+ const data = (await tx.get(inode.data)) ?? new Uint8Array();
423
+ if (metadata.size < data.byteLength)
424
+ data.fill(0, metadata.size);
425
+ await tx.set(inode.data, metadata.size < data.byteLength ? data.subarray(0, metadata.size) : extendBuffer(data, metadata.size));
426
+ }
421
427
  if (inode.update(metadata)) {
422
428
  this._add(inode.ino, path);
423
429
  tx.setSync(inode.ino, inode);
@@ -439,6 +445,12 @@ export class StoreFS extends FileSystem {
439
445
  try {
440
446
  const tx = __addDisposableResource(env_10, this.transaction(), false);
441
447
  const inode = this.findInodeSync(tx, path);
448
+ if (!isDirectory(inode) && metadata.size !== undefined && metadata.size !== inode.size) {
449
+ const data = tx.getSync(inode.data) ?? new Uint8Array();
450
+ if (metadata.size < data.byteLength)
451
+ data.fill(0, metadata.size);
452
+ tx.setSync(inode.data, metadata.size < data.byteLength ? data.subarray(0, metadata.size) : extendBuffer(data, metadata.size));
453
+ }
442
454
  if (inode.update(metadata)) {
443
455
  this._add(inode.ino, path);
444
456
  tx.setSync(inode.ino, inode);
@@ -768,7 +780,7 @@ export class StoreFS extends FileSystem {
768
780
  // Parse the raw data into our Inode object
769
781
  const inode = new Inode(inodeData);
770
782
  // If it is a directory and not yet visited, read its directory listing
771
- if ((inode.mode & S_IFDIR) != S_IFDIR || visitedDirectories.has(ino)) {
783
+ if (!isDirectory(inode) || visitedDirectories.has(ino)) {
772
784
  continue;
773
785
  }
774
786
  visitedDirectories.add(ino);
@@ -835,7 +847,7 @@ export class StoreFS extends FileSystem {
835
847
  continue;
836
848
  }
837
849
  const inode = new Inode(inodeData);
838
- if ((inode.mode & S_IFDIR) != S_IFDIR || visitedDirectories.has(ino)) {
850
+ if (!isDirectory(inode) || visitedDirectories.has(ino)) {
839
851
  continue;
840
852
  }
841
853
  visitedDirectories.add(ino);
@@ -921,7 +933,8 @@ export class StoreFS extends FileSystem {
921
933
  _lastID;
922
934
  /** Allocates a new ID and adds the ID/path */
923
935
  allocNew(path) {
924
- this._lastID ??= Math.max(...this._paths.keys());
936
+ // @todo use `Iterator` helper #296
937
+ this._lastID ||= Array.from(this._paths.keys()).reduce((max, ino) => Math.max(max, ino), 0);
925
938
  this._lastID += 2;
926
939
  const id = this._lastID;
927
940
  if (id > size_max)
package/dist/config.js CHANGED
@@ -7,7 +7,7 @@ import { FileSystem } from './internal/filesystem.js';
7
7
  import { exists, mkdir, stat } from './node/promises.js';
8
8
  import { existsSync, mkdirSync, statSync } from './node/sync.js';
9
9
  import { _setAccessChecks } from './vfs/config.js';
10
- import { mount, mounts, umount } from './vfs/shared.js';
10
+ import { mount, umount } from './vfs/shared.js';
11
11
  /**
12
12
  * Update the configuration of a file system.
13
13
  * @category Backends and Configuration
@@ -191,7 +191,7 @@ function mountWithMkdirSync(path, fs) {
191
191
  * @category Backends and Configuration
192
192
  */
193
193
  export function addDevice(driver, options) {
194
- const devfs = mounts.get('/dev');
194
+ const devfs = defaultContext.mounts.get('/dev');
195
195
  if (!(devfs instanceof DeviceFS))
196
196
  throw log.crit(withErrno('ENOTSUP', '/dev does not exist or is not a device file system'));
197
197
  return devfs._createDevice(driver, options);
@@ -223,10 +223,10 @@ export async function configure(configuration) {
223
223
  await mountWithMkdir(point, await resolveMountConfig(mountConfig));
224
224
  }
225
225
  }
226
- for (const fs of mounts.values()) {
226
+ for (const fs of defaultContext.mounts.values()) {
227
227
  configureFileSystem(fs, configuration);
228
228
  }
229
- if (configuration.addDevices && !mounts.has('/dev')) {
229
+ if (configuration.addDevices && !defaultContext.mounts.has('/dev')) {
230
230
  const devfs = new DeviceFS();
231
231
  devfs.addDefaults();
232
232
  await devfs.ready();
@@ -270,10 +270,10 @@ export function configureSync(configuration) {
270
270
  mountWithMkdirSync(point, resolveMountConfigSync(mountConfig));
271
271
  }
272
272
  }
273
- for (const fs of mounts.values()) {
273
+ for (const fs of defaultContext.mounts.values()) {
274
274
  configureFileSystem(fs, configuration);
275
275
  }
276
- if (configuration.addDevices && !mounts.has('/dev')) {
276
+ if (configuration.addDevices && !defaultContext.mounts.has('/dev')) {
277
277
  const devfs = new DeviceFS();
278
278
  devfs.addDefaults();
279
279
  devfs.readySync();
@@ -292,6 +292,6 @@ export function configureSync(configuration) {
292
292
  }
293
293
  }
294
294
  export async function sync() {
295
- for (const fs of mounts.values())
295
+ for (const fs of defaultContext.mounts.values())
296
296
  await fs.sync();
297
297
  }
@@ -4,6 +4,7 @@ import type * as path from '../path.js';
4
4
  import type { Handle } from '../vfs/file.js';
5
5
  import type * as xattr from '../vfs/xattr.js';
6
6
  import type { Credentials, CredentialsInit } from './credentials.js';
7
+ import type { FileSystem } from './filesystem.js';
7
8
  /**
8
9
  * Symbol used for context branding
9
10
  * @internal @hidden
@@ -34,6 +35,8 @@ export interface FSContext {
34
35
  readonly parent: FSContext | null;
35
36
  /** The child contexts */
36
37
  readonly children: FSContext[];
38
+ /** The mount table for this context */
39
+ readonly mounts: Map<string, FileSystem>;
37
40
  }
38
41
  export declare function isContext(obj: unknown): obj is FSContext;
39
42
  export declare function assertContext(ctx: unknown): asserts ctx is FSContext;
@@ -64,6 +67,7 @@ export interface ContextInit {
64
67
  root?: string;
65
68
  pwd?: string;
66
69
  credentials?: CredentialsInit;
70
+ mounts?: Record<string, FileSystem>;
67
71
  }
68
72
  /**
69
73
  * The default/global context.
@@ -1,6 +1,8 @@
1
- import { createCredentials } from './credentials.js';
2
- import { warn } from 'kerium/log';
1
+ // SPDX-License-Identifier: LGPL-3.0-or-later
2
+ // This needs to be in a separate file to avoid circular dependencies
3
3
  import { withErrno } from 'kerium';
4
+ import { warn } from 'kerium/log';
5
+ import { createCredentials } from './credentials.js';
4
6
  /**
5
7
  * Symbol used for context branding
6
8
  * @internal @hidden
@@ -20,19 +22,20 @@ export function assertContext(ctx) {
20
22
  */
21
23
  export const defaultContext = {
22
24
  [kIsContext]: true,
23
- id: 0,
25
+ id: 1,
24
26
  root: '/',
25
27
  pwd: '/',
26
28
  credentials: createCredentials({ uid: 0, gid: 0 }),
27
29
  descriptors: new Map(),
28
30
  parent: null,
29
31
  children: [],
32
+ mounts: new Map(),
30
33
  };
31
34
  export function contextOf($) {
32
35
  return isContext($) ? $ : defaultContext;
33
36
  }
34
- // 0 is reserved for the global/default context
35
- let _nextId = 1;
37
+ // 1 is reserved for the global/default context
38
+ let _nextId = 2;
36
39
  /**
37
40
  * Create a blank FS Context
38
41
  * @internal
@@ -43,7 +46,7 @@ let _nextId = 1;
43
46
  */
44
47
  export function createChildContext(parent, init = {}) {
45
48
  assertContext(parent);
46
- const { root = parent.root, pwd = parent.pwd, credentials = structuredClone(parent.credentials) } = init;
49
+ const { root = parent.root, pwd = parent.pwd, credentials = structuredClone(parent.credentials), mounts = Object.fromEntries(parent.mounts), } = init;
47
50
  const ctx = {
48
51
  [kIsContext]: true,
49
52
  id: _nextId++,
@@ -53,6 +56,7 @@ export function createChildContext(parent, init = {}) {
53
56
  descriptors: new Map(),
54
57
  parent: parent,
55
58
  children: [],
59
+ mounts: new Map(Object.entries(mounts)),
56
60
  };
57
61
  Object.defineProperties(ctx, {
58
62
  id: { configurable: false, writable: false },
@@ -87,7 +87,8 @@ export class Index extends Map {
87
87
  _alloc() {
88
88
  // @todo use `Iterator.flatMap` #296
89
89
  this.#lastAlloc ||= Array.from(this.values()).reduce((max, inode) => Math.max(max, inode.ino, inode.data), 0);
90
- return ++this.#lastAlloc;
90
+ this.#lastAlloc++;
91
+ return this.#lastAlloc++;
91
92
  }
92
93
  /**
93
94
  * Gets a list of entries for each directory in the index.
@@ -1,6 +1,7 @@
1
1
  import type { UUID } from 'node:crypto';
2
2
  import type { ConstMap } from 'utilium';
3
3
  import type { InodeLike } from './inode.js';
4
+ import type { IoctlContext } from './ioctl.js';
4
5
  /**
5
6
  * Usage information about a file system
6
7
  * @category Internals
@@ -244,4 +245,8 @@ export declare abstract class FileSystem {
244
245
  * @privateRemarks The default implementation of `streamWrite` uses "chunked" `write`s
245
246
  */
246
247
  streamWrite(path: string, options: StreamOptions): WritableStream;
248
+ /** @internal */
249
+ ioctl(context: IoctlContext, command: number, ...args: any[]): Promise<any>;
250
+ /** @internal */
251
+ ioctlSync(context: IoctlContext, command: number, ...args: any[]): any;
247
252
  }
@@ -1,4 +1,6 @@
1
+ // SPDX-License-Identifier: LGPL-3.0-or-later
1
2
  import { withErrno } from 'kerium';
3
+ import { ioctl_default_ops_async, ioctl_default_ops_sync } from './ioctl.js';
2
4
  const _chunkSize = 0x1000;
3
5
  /**
4
6
  * Provides a consistent and easy to use internal API.
@@ -132,4 +134,20 @@ export class FileSystem {
132
134
  },
133
135
  });
134
136
  }
137
+ /** @internal */
138
+ async ioctl(context, command, ...args) {
139
+ // eslint-disable-next-line @typescript-eslint/unbound-method, @typescript-eslint/no-unnecessary-type-assertion
140
+ const cmd = ioctl_default_ops_async[command];
141
+ if (!cmd)
142
+ throw withErrno('ENOTTY');
143
+ return await cmd(this, context, ...args);
144
+ }
145
+ /** @internal */
146
+ ioctlSync(context, command, ...args) {
147
+ // eslint-disable-next-line @typescript-eslint/unbound-method, @typescript-eslint/no-unnecessary-type-assertion
148
+ const cmd = ioctl_default_ops_sync[command];
149
+ if (!cmd)
150
+ throw withErrno('ENOTTY');
151
+ return cmd(this, context, ...args);
152
+ }
135
153
  }
@@ -79,6 +79,10 @@ export interface InodeLike<T extends number | bigint = number> extends InodeFiel
79
79
  * Number of hard links
80
80
  */
81
81
  nlink: T;
82
+ /**
83
+ * Device ID for special files
84
+ */
85
+ rdev: T;
82
86
  /**
83
87
  * Extended attributes
84
88
  */
@@ -87,7 +91,7 @@ export interface InodeLike<T extends number | bigint = number> extends InodeFiel
87
91
  /**
88
92
  * @internal @hidden
89
93
  */
90
- export declare const _inode_fields: readonly ["ino", "data", "size", "mode", "flags", "nlink", "uid", "gid", "atimeMs", "birthtimeMs", "mtimeMs", "ctimeMs", "version"];
94
+ export declare const _inode_fields: readonly ["ino", "data", "size", "mode", "flags", "nlink", "uid", "gid", "atimeMs", "birthtimeMs", "mtimeMs", "ctimeMs", "version", "rdev"];
91
95
  /**
92
96
  * Represents which version of the `Inode` format we are on.
93
97
  * 1. 58 bytes. The first member was called `ino` but used as the ID for data.
@@ -182,6 +186,7 @@ export declare class Inode extends Inode_base implements InodeLike {
182
186
  * Unrelated to the inode format!
183
187
  */
184
188
  accessor version: number;
189
+ accessor rdev: number;
185
190
  /**
186
191
  * Padding up to 128 bytes.
187
192
  * This ensures there is enough room for expansion without breaking the ABI.
@@ -270,6 +270,7 @@ export const _inode_fields = [
270
270
  'mtimeMs',
271
271
  'ctimeMs',
272
272
  'version',
273
+ 'rdev',
273
274
  ];
274
275
  /**
275
276
  * Represents which version of the `Inode` format we are on.
@@ -335,7 +336,7 @@ export const userModifiableFlags = 0x000380ff;
335
336
  * @internal
336
337
  */
337
338
  let Inode = (() => {
338
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
339
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
339
340
  let _classDecorators = [struct.packed()];
340
341
  let _classDescriptor;
341
342
  let _classExtraInitializers = [];
@@ -389,6 +390,9 @@ let Inode = (() => {
389
390
  let _version_decorators;
390
391
  let _version_initializers = [];
391
392
  let _version_extraInitializers = [];
393
+ let _rdev_decorators;
394
+ let _rdev_initializers = [];
395
+ let _rdev_extraInitializers = [];
392
396
  let ___padding_decorators;
393
397
  let ___padding_initializers = [];
394
398
  let ___padding_extraInitializers = [];
@@ -418,7 +422,8 @@ let Inode = (() => {
418
422
  _flags_decorators = [(_p = t).uint32.bind(_p)];
419
423
  ___after_flags_decorators = [(_q = t).uint16.bind(_q)];
420
424
  _version_decorators = [(_r = t).uint32.bind(_r)];
421
- ___padding_decorators = [t.uint8(48)];
425
+ _rdev_decorators = [(_s = t).uint32.bind(_s)];
426
+ ___padding_decorators = [t.uint8(44)];
422
427
  _attributes_decorators = [field(Attributes)];
423
428
  ___data_decorators = [t.uint8(maxDynamicData)];
424
429
  __esDecorate(this, null, _data_decorators, { kind: "accessor", name: "data", static: false, private: false, access: { has: obj => "data" in obj, get: obj => obj.data, set: (obj, value) => { obj.data = value; } }, metadata: _metadata }, _data_initializers, _data_extraInitializers);
@@ -437,6 +442,7 @@ let Inode = (() => {
437
442
  __esDecorate(this, 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);
438
443
  __esDecorate(this, null, ___after_flags_decorators, { kind: "accessor", name: "__after_flags", static: false, private: false, access: { has: obj => "__after_flags" in obj, get: obj => obj.__after_flags, set: (obj, value) => { obj.__after_flags = value; } }, metadata: _metadata }, ___after_flags_initializers, ___after_flags_extraInitializers);
439
444
  __esDecorate(this, 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);
445
+ __esDecorate(this, null, _rdev_decorators, { kind: "accessor", name: "rdev", static: false, private: false, access: { has: obj => "rdev" in obj, get: obj => obj.rdev, set: (obj, value) => { obj.rdev = value; } }, metadata: _metadata }, _rdev_initializers, _rdev_extraInitializers);
440
446
  __esDecorate(this, 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);
441
447
  __esDecorate(this, null, _attributes_decorators, { kind: "accessor", name: "attributes", static: false, private: false, access: { has: obj => "attributes" in obj, get: obj => obj.attributes, set: (obj, value) => { obj.attributes = value; } }, metadata: _metadata }, _attributes_initializers, _attributes_extraInitializers);
442
448
  __esDecorate(this, null, ___data_decorators, { kind: "accessor", name: "__data", static: false, private: false, access: { has: obj => "__data" in obj, get: obj => obj.__data, set: (obj, value) => { obj.__data = value; } }, metadata: _metadata }, ___data_initializers, ___data_extraInitializers);
@@ -528,7 +534,10 @@ let Inode = (() => {
528
534
  */
529
535
  get version() { return this.#version_accessor_storage; }
530
536
  set version(value) { this.#version_accessor_storage = value; }
531
- #__padding_accessor_storage = (__runInitializers(this, _version_extraInitializers), __runInitializers(this, ___padding_initializers, void 0));
537
+ #rdev_accessor_storage = (__runInitializers(this, _version_extraInitializers), __runInitializers(this, _rdev_initializers, void 0));
538
+ get rdev() { return this.#rdev_accessor_storage; }
539
+ set rdev(value) { this.#rdev_accessor_storage = value; }
540
+ #__padding_accessor_storage = (__runInitializers(this, _rdev_extraInitializers), __runInitializers(this, ___padding_initializers, void 0));
532
541
  /**
533
542
  * Padding up to 128 bytes.
534
543
  * This ensures there is enough room for expansion without breaking the ABI.
@@ -0,0 +1,148 @@
1
+ import { BufferView } from 'utilium/buffer';
2
+ import type { FileSystem } from './filesystem.js';
3
+ import type { InodeLike } from './inode.js';
4
+ declare const fsxattr_base: import("memium").StructConstructor<BufferView<any>>;
5
+ declare class fsxattr extends fsxattr_base {
6
+ static name: string;
7
+ /** xflags field value */
8
+ accessor xflags: number;
9
+ /** extsize field value */
10
+ accessor extsize: number;
11
+ /** nextents field value */
12
+ accessor nextents: number;
13
+ /** project identifier */
14
+ accessor projid: number;
15
+ /** CoW extsize field value */
16
+ accessor cowextsize: number;
17
+ protected accessor pad: number[];
18
+ constructor(inode?: Readonly<InodeLike>);
19
+ }
20
+ /**
21
+ * `FS_IOC_*` commands for {@link ioctl | `ioctl`}
22
+ * @remarks
23
+ * These are computed from a script since constant values are needed for enum member types
24
+ */
25
+ export declare enum IOC {
26
+ GetFlags = 2148034049,
27
+ SetFlags = 1074292226,
28
+ GetVersion = 2148038145,
29
+ SetVersion = 1074296322,
30
+ Fiemap = 3223348747,
31
+ GetXattr = 2149341215,
32
+ SetXattr = 1075599392,
33
+ GetLabel = 2164298801,
34
+ SetLabel = 1090556978,
35
+ GetUUID = 2148603136,
36
+ GetSysfsPath = 2155943169
37
+ }
38
+ /**
39
+ * `FS_IOC32_*` commands for {@link ioctl | `ioctl`}
40
+ * @remarks
41
+ * These are computed from a script since constant values are needed for enum member types
42
+ */
43
+ export declare enum IOC32 {
44
+ GetFlags = 2147771905,
45
+ SetFlags = 1074030082,
46
+ GetVersion = 2147776001,
47
+ SetVersion = 1074034178
48
+ }
49
+ /**
50
+ * @category ioctl
51
+ */
52
+ export interface IoctlContext {
53
+ fs: FileSystem;
54
+ inode: InodeLike;
55
+ path: string;
56
+ file?: {
57
+ position: number;
58
+ flag: number;
59
+ };
60
+ }
61
+ /**
62
+ * @category ioctl
63
+ */
64
+ export type Ioctl = (context: IoctlContext, ...args: any[]) => any;
65
+ /**
66
+ * What an ioctl takes from whoever is calling it, which is everything but the context it is given.
67
+ * @category ioctl
68
+ */
69
+ export type IoctlArgs<T extends Ioctl> = T extends (context: IoctlContext, ...args: infer A) => any ? A : never;
70
+ /**
71
+ * @category ioctl
72
+ */
73
+ export interface IoctlOps extends Record<number, Ioctl> {
74
+ }
75
+ /**
76
+ * @internal
77
+ * @category ioctl
78
+ */
79
+ export declare const ioctl_default_ops: {
80
+ 2148034049($: IoctlContext): number;
81
+ 2147771905($: IoctlContext): number;
82
+ 2148038145($: IoctlContext): number;
83
+ 2147776001($: IoctlContext): number;
84
+ 3223348747(): never;
85
+ 2149341215($: IoctlContext, _name: string): fsxattr;
86
+ 1075599392($: IoctlContext, _name: string, _value: fsxattr): never;
87
+ 2164298801($: IoctlContext): string | undefined;
88
+ 1090556978($: IoctlContext, label: string): void;
89
+ 2148603136($: IoctlContext): string;
90
+ 2155943169($: IoctlContext): string;
91
+ };
92
+ /**
93
+ * @internal
94
+ * @category ioctl
95
+ */
96
+ export declare const ioctl_default_ops_async: {
97
+ 1074292226($: IoctlContext, flags: number): Promise<void>;
98
+ 1074030082($: IoctlContext, flags: number): Promise<void>;
99
+ 1074296322($: IoctlContext, version: number): Promise<void>;
100
+ 1074034178($: IoctlContext, version: number): Promise<void>;
101
+ 2148034049($: IoctlContext): number;
102
+ 2147771905($: IoctlContext): number;
103
+ 2148038145($: IoctlContext): number;
104
+ 2147776001($: IoctlContext): number;
105
+ 3223348747(): never;
106
+ 2149341215($: IoctlContext, _name: string): fsxattr;
107
+ 1075599392($: IoctlContext, _name: string, _value: fsxattr): never;
108
+ 2164298801($: IoctlContext): string | undefined;
109
+ 1090556978($: IoctlContext, label: string): void;
110
+ 2148603136($: IoctlContext): string;
111
+ 2155943169($: IoctlContext): string;
112
+ };
113
+ type _IoctlOpsAsync = typeof ioctl_default_ops_async;
114
+ /**
115
+ * @internal
116
+ * @category ioctl
117
+ */
118
+ export interface IoctlDefaultAsyncOps extends _IoctlOpsAsync {
119
+ }
120
+ /**
121
+ * @internal
122
+ * @category ioctl
123
+ */
124
+ export declare const ioctl_default_ops_sync: {
125
+ 1074292226($: IoctlContext, flags: number): void;
126
+ 1074030082($: IoctlContext, flags: number): void;
127
+ 1074296322($: IoctlContext, version: number): void;
128
+ 1074034178($: IoctlContext, version: number): void;
129
+ 2148034049($: IoctlContext): number;
130
+ 2147771905($: IoctlContext): number;
131
+ 2148038145($: IoctlContext): number;
132
+ 2147776001($: IoctlContext): number;
133
+ 3223348747(): never;
134
+ 2149341215($: IoctlContext, _name: string): fsxattr;
135
+ 1075599392($: IoctlContext, _name: string, _value: fsxattr): never;
136
+ 2164298801($: IoctlContext): string | undefined;
137
+ 1090556978($: IoctlContext, label: string): void;
138
+ 2148603136($: IoctlContext): string;
139
+ 2155943169($: IoctlContext): string;
140
+ };
141
+ type _IoctlOpsSync = typeof ioctl_default_ops_sync;
142
+ /**
143
+ * @internal
144
+ * @category ioctl
145
+ */
146
+ export interface IoctlDefaultSyncOps extends _IoctlOpsSync {
147
+ }
148
+ export {};