@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.
@@ -7728,7 +7728,7 @@ function satisfies(version, range2) {
7728
7728
  }
7729
7729
 
7730
7730
  // src/version.ts
7731
- var KERNEL_VERSION = true ? "1.146.2" : "0.0.0-dev";
7731
+ var KERNEL_VERSION = true ? "1.146.3" : "0.0.0-dev";
7732
7732
  var OS_RELEASE = "6.0.0-slicc";
7733
7733
  function procVersion() {
7734
7734
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -8600,6 +8600,55 @@ var Crontabs = class {
8600
8600
 
8601
8601
  // src/fs/unlinked.ts
8602
8602
  var UNLINKED_DIR = ".slicc-unlinked";
8603
+ var PathMarks = class {
8604
+ gen = 0;
8605
+ floor = 0;
8606
+ touched = /* @__PURE__ */ new Map();
8607
+ flying = /* @__PURE__ */ new Map();
8608
+ generation() {
8609
+ return this.gen;
8610
+ }
8611
+ touch(target) {
8612
+ this.gen += 1;
8613
+ this.touched.delete(target);
8614
+ this.touched.set(target, this.gen);
8615
+ if (this.touched.size <= TOUCHED_MAX) return;
8616
+ const [oldest, at] = this.touched.entries().next().value;
8617
+ this.touched.delete(oldest);
8618
+ this.floor = at;
8619
+ }
8620
+ changedSince(path, gen) {
8621
+ if (gen < this.floor) return true;
8622
+ for (let p = path; this.touched.size > 0; p = parentOf5(p)) {
8623
+ if ((this.touched.get(p) ?? 0) > gen) return true;
8624
+ if (p === "/") return false;
8625
+ }
8626
+ return false;
8627
+ }
8628
+ async around(paths, op) {
8629
+ for (const p of paths) {
8630
+ this.flying.set(p, (this.flying.get(p) ?? 0) + 1);
8631
+ this.touch(p);
8632
+ }
8633
+ try {
8634
+ return await op();
8635
+ } finally {
8636
+ for (const p of paths) {
8637
+ const n = (this.flying.get(p) ?? 1) - 1;
8638
+ if (n > 0) this.flying.set(p, n);
8639
+ else this.flying.delete(p);
8640
+ this.touch(p);
8641
+ }
8642
+ }
8643
+ }
8644
+ inFlight(path) {
8645
+ for (let p = path; this.flying.size > 0; p = parentOf5(p)) {
8646
+ if (this.flying.has(p)) return true;
8647
+ if (p === "/") return false;
8648
+ }
8649
+ return false;
8650
+ }
8651
+ };
8603
8652
  function webLocks() {
8604
8653
  return globalThis.navigator?.locks;
8605
8654
  }
@@ -8653,14 +8702,13 @@ var UnlinkedKeeper = class {
8653
8702
  queue = Promise.resolve();
8654
8703
  count = 0;
8655
8704
  replacing = /* @__PURE__ */ new Map();
8656
- gen = 0;
8657
- floor = 0;
8658
- touched = /* @__PURE__ */ new Map();
8705
+ marks;
8659
8706
  replaced = 0;
8660
8707
  links = /* @__PURE__ */ new Map();
8661
8708
  linked = /* @__PURE__ */ new Map();
8662
8709
  dirOwner;
8663
8710
  constructor(fs, holders, rootOf, options = {}) {
8711
+ this.marks = options.marks ?? new PathMarks();
8664
8712
  const { locks, owner } = options;
8665
8713
  this.dirOwner = options.dirOwner;
8666
8714
  this.fs = fs;
@@ -8682,7 +8730,6 @@ var UnlinkedKeeper = class {
8682
8730
  const { replacing } = this;
8683
8731
  const replace = async (target, op) => {
8684
8732
  const { promise, resolve: resolve2 } = Promise.withResolvers();
8685
- keeper.touch(target);
8686
8733
  let mine;
8687
8734
  const gated = () => {
8688
8735
  const before = replacing.get(target);
@@ -8693,10 +8740,9 @@ var UnlinkedKeeper = class {
8693
8740
  if (mine) mine.sealed = true;
8694
8741
  };
8695
8742
  try {
8696
- await op(gated, sealed);
8743
+ await keeper.marks.around([target], () => op(gated, sealed));
8697
8744
  } finally {
8698
8745
  keeper.replaced += 1;
8699
- keeper.touch(target);
8700
8746
  resolve2();
8701
8747
  if (mine && replacing.get(target) === mine) replacing.delete(target);
8702
8748
  }
@@ -8747,25 +8793,15 @@ var UnlinkedKeeper = class {
8747
8793
  const target = fs.resolvePath("/", to);
8748
8794
  const source = fs.resolvePath("/", from);
8749
8795
  if (target === source) return fs.rename(from, to);
8750
- keeper.touch(source);
8751
- try {
8752
- await replace(target, async (gated, sealed) => {
8796
+ await keeper.marks.around(
8797
+ [source],
8798
+ () => replace(target, async (gated, sealed) => {
8753
8799
  const pinned = await keeper.pin(target, gated, sealed);
8754
8800
  await keeper.settle(pinned, () => fs.rename(from, to));
8755
- });
8756
- } finally {
8757
- keeper.touch(source);
8758
- }
8759
- },
8760
- async symlink(target, path, owner) {
8761
- const at = fs.resolvePath("/", path);
8762
- keeper.touch(at);
8763
- try {
8764
- await fs.symlink(target, path, owner);
8765
- } finally {
8766
- keeper.touch(at);
8767
- }
8801
+ })
8802
+ );
8768
8803
  },
8804
+ symlink: (target, path, owner) => keeper.marks.around([fs.resolvePath("/", path)], () => fs.symlink(target, path, owner)),
8769
8805
  readdir: async (path) => visible(await fs.readdir(path)),
8770
8806
  readdirStat: async (path) => (await fs.readdirStat(path)).filter(([name2]) => name2 !== UNLINKED_DIR).map(([name2, st]) => [name2, st && counted2(st)])
8771
8807
  };
@@ -8777,24 +8813,13 @@ var UnlinkedKeeper = class {
8777
8813
  }
8778
8814
  }
8779
8815
  generation() {
8780
- return this.gen;
8816
+ return this.marks.generation();
8781
8817
  }
8782
8818
  changedSince(path, gen) {
8783
- if (gen < this.floor) return true;
8784
- for (let p = path; this.touched.size > 0; p = parentOf5(p)) {
8785
- if ((this.touched.get(p) ?? 0) > gen) return true;
8786
- if (p === "/") return false;
8787
- }
8788
- return false;
8819
+ return this.marks.changedSince(path, gen);
8789
8820
  }
8790
- touch(target) {
8791
- this.gen += 1;
8792
- this.touched.delete(target);
8793
- this.touched.set(target, this.gen);
8794
- if (this.touched.size <= TOUCHED_MAX) return;
8795
- const [oldest, at] = this.touched.entries().next().value;
8796
- this.touched.delete(oldest);
8797
- this.floor = at;
8821
+ inFlight(path) {
8822
+ return this.marks.inFlight(path);
8798
8823
  }
8799
8824
  missed(path) {
8800
8825
  for (let p = path; this.replacing.size > 0; p = parentOf5(p)) {
@@ -13610,13 +13635,24 @@ async function holdOp(entry, path, req) {
13610
13635
  const real = await entry.fs.realpath?.(path, true).catch(() => path);
13611
13636
  await entry.source?.open(path, real);
13612
13637
  await stillThere(entry, path, req);
13613
- if (!r || !r.missed(path) && !r.changedSince(path, gen))
13638
+ if (req.nofollow && !await ownEntry(entry, path, real ?? path)) continue;
13639
+ if (!r || !r.missed(path) && !r.changedSince(path, gen) && !r.inFlight?.(path))
13614
13640
  return json2(entry.hold?.(path, on, open2, real) ?? null);
13615
13641
  }
13616
13642
  }
13617
13643
  entry.hold?.(path, on, open2, void 0, req.handle);
13618
13644
  return done2;
13619
13645
  }
13646
+ async function ownEntry(entry, path, real) {
13647
+ const own = await entry.fs.realpath?.(path, false).catch((err) => {
13648
+ if (err.code !== "ENOENT") throw err;
13649
+ return path;
13650
+ });
13651
+ if (own !== void 0 && own !== real) return false;
13652
+ const st = await entry.fs.lstat(path);
13653
+ if (st.isSymbolicLink) throw syncError("ELOOP", path);
13654
+ return true;
13655
+ }
13620
13656
  async function followed(g, path) {
13621
13657
  const st = await g.fs.lstat(path).catch(() => void 0);
13622
13658
  if (st?.isSymbolicLink && !trustedLink(permOf(st), g.links)) deny(g, "follow", path);
@@ -28971,6 +29007,7 @@ var Launcher = class {
28971
29007
  fstabRetries;
28972
29008
  inserted = /* @__PURE__ */ new Map();
28973
29009
  openFiles = /* @__PURE__ */ new Set();
29010
+ pathMarks = new PathMarks();
28974
29011
  deciding = /* @__PURE__ */ new Map();
28975
29012
  identities = { asked: 0, timedOut: 0 };
28976
29013
  nodes;
@@ -29105,6 +29142,7 @@ var Launcher = class {
29105
29142
  locks: webLocks(),
29106
29143
  busy: (path) => [...this.openFiles].some((nodes) => nodes.holds(path)),
29107
29144
  owner: options.unlinkOwner,
29145
+ marks: this.pathMarks,
29108
29146
  ...this.owners ? { dirOwner: { uid: 0, gid: 0, mode: 448 } } : {}
29109
29147
  }
29110
29148
  );
@@ -31026,6 +31064,7 @@ var Launcher = class {
31026
31064
  locks: webLocks(),
31027
31065
  busy: (path) => [...this.openFiles].some((open2) => open2.holds(path)),
31028
31066
  owner: this.unlinkOwnerOption,
31067
+ marks: this.pathMarks,
31029
31068
  ...this.owners ? { dirOwner: { uid: 0, gid: 0, mode: 448 } } : {}
31030
31069
  }
31031
31070
  );