@ai-ecoverse/slicc-kernel 1.146.2 → 1.146.3

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/node.js CHANGED
@@ -3305,7 +3305,7 @@ function satisfies(version, range2) {
3305
3305
  }
3306
3306
 
3307
3307
  // src/version.ts
3308
- var KERNEL_VERSION = true ? "1.146.2" : "0.0.0-dev";
3308
+ var KERNEL_VERSION = true ? "1.146.3" : "0.0.0-dev";
3309
3309
  var OS_RELEASE = "6.0.0-slicc";
3310
3310
  function procVersion() {
3311
3311
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -4177,6 +4177,55 @@ var Crontabs = class {
4177
4177
 
4178
4178
  // src/fs/unlinked.ts
4179
4179
  var UNLINKED_DIR = ".slicc-unlinked";
4180
+ var PathMarks = class {
4181
+ gen = 0;
4182
+ floor = 0;
4183
+ touched = /* @__PURE__ */ new Map();
4184
+ flying = /* @__PURE__ */ new Map();
4185
+ generation() {
4186
+ return this.gen;
4187
+ }
4188
+ touch(target) {
4189
+ this.gen += 1;
4190
+ this.touched.delete(target);
4191
+ this.touched.set(target, this.gen);
4192
+ if (this.touched.size <= TOUCHED_MAX) return;
4193
+ const [oldest, at] = this.touched.entries().next().value;
4194
+ this.touched.delete(oldest);
4195
+ this.floor = at;
4196
+ }
4197
+ changedSince(path, gen) {
4198
+ if (gen < this.floor) return true;
4199
+ for (let p = path; this.touched.size > 0; p = parentOf2(p)) {
4200
+ if ((this.touched.get(p) ?? 0) > gen) return true;
4201
+ if (p === "/") return false;
4202
+ }
4203
+ return false;
4204
+ }
4205
+ async around(paths, op) {
4206
+ for (const p of paths) {
4207
+ this.flying.set(p, (this.flying.get(p) ?? 0) + 1);
4208
+ this.touch(p);
4209
+ }
4210
+ try {
4211
+ return await op();
4212
+ } finally {
4213
+ for (const p of paths) {
4214
+ const n = (this.flying.get(p) ?? 1) - 1;
4215
+ if (n > 0) this.flying.set(p, n);
4216
+ else this.flying.delete(p);
4217
+ this.touch(p);
4218
+ }
4219
+ }
4220
+ }
4221
+ inFlight(path) {
4222
+ for (let p = path; this.flying.size > 0; p = parentOf2(p)) {
4223
+ if (this.flying.has(p)) return true;
4224
+ if (p === "/") return false;
4225
+ }
4226
+ return false;
4227
+ }
4228
+ };
4180
4229
  function pidOwner(proc) {
4181
4230
  return {
4182
4231
  id: `p${proc.pid}`,
@@ -4243,14 +4292,13 @@ var UnlinkedKeeper = class {
4243
4292
  queue = Promise.resolve();
4244
4293
  count = 0;
4245
4294
  replacing = /* @__PURE__ */ new Map();
4246
- gen = 0;
4247
- floor = 0;
4248
- touched = /* @__PURE__ */ new Map();
4295
+ marks;
4249
4296
  replaced = 0;
4250
4297
  links = /* @__PURE__ */ new Map();
4251
4298
  linked = /* @__PURE__ */ new Map();
4252
4299
  dirOwner;
4253
4300
  constructor(fs, holders, rootOf, options = {}) {
4301
+ this.marks = options.marks ?? new PathMarks();
4254
4302
  const { locks, owner } = options;
4255
4303
  this.dirOwner = options.dirOwner;
4256
4304
  this.fs = fs;
@@ -4272,7 +4320,6 @@ var UnlinkedKeeper = class {
4272
4320
  const { replacing } = this;
4273
4321
  const replace = async (target, op) => {
4274
4322
  const { promise, resolve: resolve2 } = Promise.withResolvers();
4275
- keeper.touch(target);
4276
4323
  let mine;
4277
4324
  const gated = () => {
4278
4325
  const before = replacing.get(target);
@@ -4283,10 +4330,9 @@ var UnlinkedKeeper = class {
4283
4330
  if (mine) mine.sealed = true;
4284
4331
  };
4285
4332
  try {
4286
- await op(gated, sealed);
4333
+ await keeper.marks.around([target], () => op(gated, sealed));
4287
4334
  } finally {
4288
4335
  keeper.replaced += 1;
4289
- keeper.touch(target);
4290
4336
  resolve2();
4291
4337
  if (mine && replacing.get(target) === mine) replacing.delete(target);
4292
4338
  }
@@ -4337,25 +4383,15 @@ var UnlinkedKeeper = class {
4337
4383
  const target = fs.resolvePath("/", to);
4338
4384
  const source = fs.resolvePath("/", from);
4339
4385
  if (target === source) return fs.rename(from, to);
4340
- keeper.touch(source);
4341
- try {
4342
- await replace(target, async (gated, sealed) => {
4386
+ await keeper.marks.around(
4387
+ [source],
4388
+ () => replace(target, async (gated, sealed) => {
4343
4389
  const pinned = await keeper.pin(target, gated, sealed);
4344
4390
  await keeper.settle(pinned, () => fs.rename(from, to));
4345
- });
4346
- } finally {
4347
- keeper.touch(source);
4348
- }
4349
- },
4350
- async symlink(target, path, owner) {
4351
- const at = fs.resolvePath("/", path);
4352
- keeper.touch(at);
4353
- try {
4354
- await fs.symlink(target, path, owner);
4355
- } finally {
4356
- keeper.touch(at);
4357
- }
4391
+ })
4392
+ );
4358
4393
  },
4394
+ symlink: (target, path, owner) => keeper.marks.around([fs.resolvePath("/", path)], () => fs.symlink(target, path, owner)),
4359
4395
  readdir: async (path) => visible(await fs.readdir(path)),
4360
4396
  readdirStat: async (path) => (await fs.readdirStat(path)).filter(([name2]) => name2 !== UNLINKED_DIR).map(([name2, st]) => [name2, st && counted3(st)])
4361
4397
  };
@@ -4367,24 +4403,13 @@ var UnlinkedKeeper = class {
4367
4403
  }
4368
4404
  }
4369
4405
  generation() {
4370
- return this.gen;
4406
+ return this.marks.generation();
4371
4407
  }
4372
4408
  changedSince(path, gen) {
4373
- if (gen < this.floor) return true;
4374
- for (let p = path; this.touched.size > 0; p = parentOf2(p)) {
4375
- if ((this.touched.get(p) ?? 0) > gen) return true;
4376
- if (p === "/") return false;
4377
- }
4378
- return false;
4409
+ return this.marks.changedSince(path, gen);
4379
4410
  }
4380
- touch(target) {
4381
- this.gen += 1;
4382
- this.touched.delete(target);
4383
- this.touched.set(target, this.gen);
4384
- if (this.touched.size <= TOUCHED_MAX) return;
4385
- const [oldest, at] = this.touched.entries().next().value;
4386
- this.touched.delete(oldest);
4387
- this.floor = at;
4411
+ inFlight(path) {
4412
+ return this.marks.inFlight(path);
4388
4413
  }
4389
4414
  missed(path) {
4390
4415
  for (let p = path; this.replacing.size > 0; p = parentOf2(p)) {
@@ -9768,13 +9793,24 @@ async function holdOp(entry, path, req) {
9768
9793
  const real = await entry.fs.realpath?.(path, true).catch(() => path);
9769
9794
  await entry.source?.open(path, real);
9770
9795
  await stillThere(entry, path, req);
9771
- if (!r || !r.missed(path) && !r.changedSince(path, gen))
9796
+ if (req.nofollow && !await ownEntry(entry, path, real ?? path)) continue;
9797
+ if (!r || !r.missed(path) && !r.changedSince(path, gen) && !r.inFlight?.(path))
9772
9798
  return json2(entry.hold?.(path, on, open, real) ?? null);
9773
9799
  }
9774
9800
  }
9775
9801
  entry.hold?.(path, on, open, void 0, req.handle);
9776
9802
  return done;
9777
9803
  }
9804
+ async function ownEntry(entry, path, real) {
9805
+ const own = await entry.fs.realpath?.(path, false).catch((err) => {
9806
+ if (err.code !== "ENOENT") throw err;
9807
+ return path;
9808
+ });
9809
+ if (own !== void 0 && own !== real) return false;
9810
+ const st = await entry.fs.lstat(path);
9811
+ if (st.isSymbolicLink) throw syncError("ELOOP", path);
9812
+ return true;
9813
+ }
9778
9814
  async function followed(g, path) {
9779
9815
  const st = await g.fs.lstat(path).catch(() => void 0);
9780
9816
  if (st?.isSymbolicLink && !trustedLink(permOf(st), g.links)) deny(g, "follow", path);
@@ -27988,6 +28024,7 @@ var Launcher = class {
27988
28024
  fstabRetries;
27989
28025
  inserted = /* @__PURE__ */ new Map();
27990
28026
  openFiles = /* @__PURE__ */ new Set();
28027
+ pathMarks = new PathMarks();
27991
28028
  deciding = /* @__PURE__ */ new Map();
27992
28029
  identities = { asked: 0, timedOut: 0 };
27993
28030
  nodes;
@@ -28122,6 +28159,7 @@ var Launcher = class {
28122
28159
  locks: webLocks(),
28123
28160
  busy: (path) => [...this.openFiles].some((nodes) => nodes.holds(path)),
28124
28161
  owner: options.unlinkOwner,
28162
+ marks: this.pathMarks,
28125
28163
  ...this.owners ? { dirOwner: { uid: 0, gid: 0, mode: 448 } } : {}
28126
28164
  }
28127
28165
  );
@@ -30043,6 +30081,7 @@ var Launcher = class {
30043
30081
  locks: webLocks(),
30044
30082
  busy: (path) => [...this.openFiles].some((open) => open.holds(path)),
30045
30083
  owner: this.unlinkOwnerOption,
30084
+ marks: this.pathMarks,
30046
30085
  ...this.owners ? { dirOwner: { uid: 0, gid: 0, mode: 448 } } : {}
30047
30086
  }
30048
30087
  );