Skip to content

Commit

Permalink
fix: link, symlinks with current database schema
Browse files Browse the repository at this point in the history
  • Loading branch information
divyenduz committed Nov 1, 2023
1 parent b88de62 commit cff929a
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 66 deletions.
7 changes: 4 additions & 3 deletions packages/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@ type Result<T> =

export interface Backend {
getFiles: (dir: string) => Promise<File[]>;
getFile: (filepath: string) => Promise<Result<File>>;
getFileRaw: (filepath: string) => Promise<Result<File>>;
getFileResolved: (filepath: string) => Promise<Result<File>>;

createFile: (
filepath: string,
type: FileType,
mode: number,
uid: number,
gid: number,
targetId: number
targetPath: string
) => Promise<Result<File>>;

writeFile: (
Expand All @@ -32,7 +33,7 @@ export interface Backend {
gid: number
) => Promise<Result<File>>;

deleteFile: (filepath: string) => Promise<Result<File>>;
deleteFile: (filepath: string) => Promise<Result<number>>;
renameFile: (srcPath: string, destPath: string) => Promise<Result<File>>;
updateMode: (filepath: string, mode: number) => Promise<Result<File>>;
}
11 changes: 6 additions & 5 deletions packages/fuse-client/syscalls/getattr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,24 @@ export const getattr: (backend: SQLiteBackend) => MountOptions["getattr"] = (
backend
) => {
return async (path, cb) => {
console.log("getattr(%s)", path);
const r = await backend.getFile(path);

console.info("getattr(%s)", path);
const r = await backend.getFileResolved(path);
await match(r)
.with({ status: "ok" }, async (r) => {
const rSize = await backend.getFileSize(path);
if (rSize.status !== "ok") {
cb(fuse.ENOENT);
return;
}

const rNlinks = await backend.getFileNLinks(path);
const { mtime, atime, ctime, mode } = r.file;
cb(0, {
mtime,
atime,
ctime,
nlink: 1,
blocks: 1,
ino: r.file.id,
nlink: rNlinks.nLinks?.length || 1,
size: rSize.size,
mode: mode,
// TODO: enable posix mode where real uid/gid are returned
Expand Down
4 changes: 2 additions & 2 deletions packages/fuse-client/syscalls/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ export const init: (backend: SQLiteBackend) => MountOptions["init"] = (
backend
) => {
return async (cb) => {
console.log("init");
console.info("init");

//@ts-expect-error fix types
const context = fuse.context();
const { uid, gid } = context;

const rootFolder = await backend.getFile("/");
const rootFolder = await backend.getFileResolved("/");
match(rootFolder)
.with({ status: "ok" }, () => {})
.with({ status: "not_found" }, async () => {
Expand Down
35 changes: 29 additions & 6 deletions packages/fuse-client/syscalls/link.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
import { SQLiteBackend } from "@zoid-fs/sqlite-backend";
import { MountOptions } from "@zoid-fs/node-fuse-bindings";
import { symlink } from "./symlink";
import fuse, { MountOptions } from "@zoid-fs/node-fuse-bindings";
import { match } from "ts-pattern";

export const link: (backend: SQLiteBackend) => MountOptions["link"] = (
backend
) => {
return async (src, dest, cb) => {
console.log("link(%s, %s)", src, dest);
return async (srcPath, destPath, cb) => {
console.info("link(%s, %s)", srcPath, destPath);

// TODO: throw if destination doesn't exist

//@ts-expect-error fix types
// TODO: implement link properly
symlink(backend)(src, dest, cb);
const context = fuse.context();
const { uid, gid } = context;

// TODO: double check if mode for link is correct
// https://unix.stackexchange.com/questions/193465/what-file-mode-is-a-link
const r = await backend.createFile(
destPath,
"link",
41453, // Link's mode??? from node-fuse-binding source, why though?
uid,
gid,
srcPath
);
console.log({ r });
match(r)
.with({ status: "ok" }, () => {
cb(0);
})
.with({ status: "not_found" }, () => {
cb(fuse.ENOENT);
})
.exhaustive();
};
};
4 changes: 2 additions & 2 deletions packages/fuse-client/syscalls/open.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ export const open: (backend: SQLiteBackend) => MountOptions["open"] = (
backend
) => {
return async (path, flags, cb) => {
console.log("open(%s, %d)", path, flags);
const r = await backend.getFile(path);
console.info("open(%s, %d)", path, flags);
const r = await backend.getFileResolved(path);

match(r)
.with({ status: "ok" }, (r) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/fuse-client/syscalls/opendir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ export const opendir: (backend: SQLiteBackend) => MountOptions["opendir"] = (
backend
) => {
return async (path, flags, cb) => {
console.log("opendir(%s, %d)", path, flags);
console.info("opendir(%s, %d)", path, flags);

if (path === "/") {
cb(0, 42); // TODO: Universal FD for root dir, it should probably be in the database as bootstrap
return;
}

const r = await backend.getFile(path);
const r = await backend.getFileResolved(path);
match(r)
.with({ status: "ok" }, (r) => {
cb(0, r.file.id);
Expand Down
6 changes: 3 additions & 3 deletions packages/fuse-client/syscalls/readlink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ export const readlink: (backend: SQLiteBackend) => MountOptions["readlink"] = (
backend
) => {
return async (path, cb) => {
console.log("readlink(%s)", path);
const r = await backend.getFile(path);
console.info("readlink(%s)", path);
const r = await backend.getFileRaw(path);
match(r)
.with({ status: "ok" }, (r) => {
cb(0, r.file.name);
cb(0, r.file.targetPath);
})
.with({ status: "not_found" }, () => {
//@ts-expect-error fix types, what to do if readlink fails?
Expand Down
11 changes: 2 additions & 9 deletions packages/fuse-client/syscalls/symlink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,7 @@ export const symlink: (backend: SQLiteBackend) => MountOptions["symlink"] = (
backend
) => {
return async (srcPath, destPath, cb) => {
console.log("symlink(%s, %s)", srcPath, destPath);

const targetFile = await backend.getFile(srcPath);
console.log({ targetFile });
if (targetFile.status === "not_found") {
cb(fuse.ENOENT);
return;
}
console.info("symlink(%s, %s)", srcPath, destPath);

//@ts-expect-error fix types
const context = fuse.context();
Expand All @@ -27,7 +20,7 @@ export const symlink: (backend: SQLiteBackend) => MountOptions["symlink"] = (
33188,
uid,
gid,
targetFile.file.id
srcPath
);
match(r)
.with({ status: "ok" }, () => {
Expand Down
Loading

0 comments on commit cff929a

Please sign in to comment.