Skip to content

Commit

Permalink
Avoid some unneccesary path resolution
Browse files Browse the repository at this point in the history
There are a bunch of codepaths where we have a node or a stream and we turn
it back into a path, then eventually call `lookupPath` on it to turn it back
into a node. This removes a few of these instances.
  • Loading branch information
hoodmane committed Dec 16, 2024
1 parent dfe3356 commit 44979a6
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 21 deletions.
46 changes: 29 additions & 17 deletions src/library_fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ FS.staticInit();
streams: [],
nextInode: 1,
nameTable: null,
currentPath: '/',
currentPath: null,
currentNode: null,
initialized: false,
// Whether we are currently ignoring permissions. Useful when preparing the
// filesystem and creating files inside read-only folders.
Expand Down Expand Up @@ -173,21 +174,22 @@ FS.staticInit();
//
lookupPath(path, opts = {}) {
if (!path) return { path: '', node: null };
opts.follow_mount ??= true
opts.follow_mount ??= true;

if (!PATH.isAbs(path)) {
path = FS.cwd() + '/' + path;
var current;
var current_path;
if (PATH.isAbs(path)) {
current = FS.root;
current_path = "/";
} else {
current = FS.currentNode;
current_path = FS.currentPath;
}
var pathParts = (x) => x.split('/').filter((p) => !!p && (p !== '.'));
var parts = pathParts(path);

// limit max consecutive symlinks to 40 (SYMLOOP_MAX).
linkloop: for (var nlinks = 0; nlinks < 40; nlinks++) {
// split the absolute path
var parts = path.split('/').filter((p) => !!p && (p !== '.'));

// start at the root
var current = FS.root;
var current_path = '/';

for (var i = 0; i < parts.length; i++) {
var islast = (i === parts.length-1);
if (islast && opts.parent) {
Expand Down Expand Up @@ -226,10 +228,14 @@ FS.staticInit();
throw new FS.ErrnoError({{{ cDefs.ENOSYS }}});
}
var link = current.node_ops.readlink(current);
if (!PATH.isAbs(link)) {
link = PATH.dirname(current_path) + '/' + link;
if (PATH.isAbs(link)) {
current = FS.root;
current_path = "/";
} else {
current = current.parent;
current_path = PATH.dirname(current_path);
}
path = link + '/' + parts.slice(i + 1).join('/');
parts = [].concat(pathParts(link), parts.slice(i + 1));
continue linkloop;
}
}
Expand Down Expand Up @@ -405,7 +411,7 @@ FS.staticInit();
if (!FS.isDir(node.mode)) {
return {{{ cDefs.ENOTDIR }}};
}
if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
if (FS.isRoot(node) || node === FS.currentNode) {
return {{{ cDefs.EBUSY }}};
}
} else {
Expand Down Expand Up @@ -886,8 +892,9 @@ FS.staticInit();
#endif
},
readdir(path) {
var lookup = FS.lookupPath(path, { follow: true });
var node = lookup.node;
FS.readdirNode(FS.lookupPath(path, { follow: true }).node);
},
readdirNode(node) {
if (!node.node_ops.readdir) {
throw new FS.ErrnoError({{{ cDefs.ENOTDIR }}});
}
Expand Down Expand Up @@ -944,6 +951,9 @@ FS.staticInit();
if (!node) {
throw new FS.ErrnoError({{{ cDefs.ENOENT }}});
}
return FS.statNode(node);
},
statNode(node) {
if (!node.node_ops.getattr) {
throw new FS.ErrnoError({{{ cDefs.EPERM }}});
}
Expand Down Expand Up @@ -1366,6 +1376,7 @@ FS.staticInit();
throw new FS.ErrnoError(errCode);
}
FS.currentPath = lookup.path;
FS.currentNode = lookup.node;
},
createDefaultDirectories() {
FS.mkdir('/tmp');
Expand Down Expand Up @@ -1479,6 +1490,7 @@ FS.staticInit();
FS.nameTable = new Array(4096);

FS.mount(MEMFS, {}, '/');
FS.chdir('/');

FS.createDefaultDirectories();
FS.createDefaultDevices();
Expand Down
11 changes: 7 additions & 4 deletions src/library_syscall.js
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,11 @@ var SyscallsLibrary = {
#endif // ~PROXY_POSIX_SOCKETS==0
__syscall_fchdir: (fd) => {
var stream = SYSCALLS.getStreamFromFD(fd);
FS.chdir(stream.path);
if (!FS.isDir(stream.node.mode)) {
return -{{{ cDefs.ENOTDIR }}};
}
FS.currentPath = stream.path;
FS.currentNode = stream.node;
return 0;
},
__syscall__newselect: (nfds, readfds, writefds, exceptfds, timeout) => {
Expand Down Expand Up @@ -689,7 +693,7 @@ var SyscallsLibrary = {
__syscall_getdents64__deps: ['$stringToUTF8'],
__syscall_getdents64: (fd, dirp, count) => {
var stream = SYSCALLS.getStreamFromFD(fd)
stream.getdents ||= FS.readdir(stream.path);
stream.getdents ||= FS.readdirNode(stream.node);
var struct_size = {{{ C_STRUCTS.dirent.__size__ }}};
var pos = 0;
Expand All @@ -706,8 +710,7 @@ var SyscallsLibrary = {
type = 4; // DT_DIR
}
else if (name === '..') {
var lookup = FS.lookupPath(stream.path, { parent: true });
id = lookup.node.id;
id = stream.node.parent.id;
type = 4; // DT_DIR
}
else {
Expand Down

0 comments on commit 44979a6

Please sign in to comment.