Download raw body.
On Tue, Sep 13, 2022 at 12:34:49PM +0200, Stefan Sperling wrote:
> The attached profile trace graph suggests a bottleneck is in the open()
> call in get_file_status(). We might be able to work around that somehow.
This patch avoids the open() call in favour of lstat(); However, this does
not improve performance. We spend 37% runtime in either open() or lstat(),
so this patch makes no difference.
I don't see how to make this code path faster by tweaking userland code.
Disabling unveil() would make it faster, but we don't want to do that.
diff /home/stsp/src/got
commit - c9f38fbe5854f0986bfe240a76c72ca0e66b058b
path + /home/stsp/src/got
blob - 30e991da06f030404cbce64de63293d385ff1ac8
file + lib/worktree.c
--- lib/worktree.c
+++ lib/worktree.c
@@ -1629,7 +1629,7 @@ get_file_status(unsigned char *status, struct stat *sb
const struct got_error *err = NULL;
struct got_object_id id;
size_t hdrlen;
- int fd = -1, fd1 = -1;
+ int fd = -1, fd1 = -1, have_file = 1;
FILE *f = NULL;
uint8_t fbuf[8192];
struct got_blob_object *blob = NULL;
@@ -1646,36 +1646,28 @@ get_file_status(unsigned char *status, struct stat *sb
*/
if (dirfd != -1) {
if (fstatat(dirfd, de_name, sb, AT_SYMLINK_NOFOLLOW) == -1) {
- if (errno == ENOENT) {
- if (got_fileindex_entry_has_file_on_disk(ie))
- *status = GOT_STATUS_MISSING;
- else
- *status = GOT_STATUS_DELETE;
+ if (errno != ENOENT) {
+ err = got_error_from_errno2("fstatat", abspath);
goto done;
- }
- err = got_error_from_errno2("fstatat", abspath);
- goto done;
+ } else
+ have_file = 0;
}
} else {
- fd = open(abspath, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
- if (fd == -1 && errno != ENOENT &&
- !got_err_open_nofollow_on_symlink())
- return got_error_from_errno2("open", abspath);
- else if (fd == -1 && got_err_open_nofollow_on_symlink()) {
- if (lstat(abspath, sb) == -1)
- return got_error_from_errno2("lstat", abspath);
- } else if (fd == -1 || fstat(fd, sb) == -1) {
- if (errno == ENOENT) {
- if (got_fileindex_entry_has_file_on_disk(ie))
- *status = GOT_STATUS_MISSING;
- else
- *status = GOT_STATUS_DELETE;
+ if (lstat(abspath, sb) == -1) {
+ if (errno != ENOENT) {
+ err = got_error_from_errno2("lstat", abspath);
goto done;
- }
- err = got_error_from_errno2("fstat", abspath);
- goto done;
+ } else
+ have_file = 0;
}
}
+ if (!have_file) {
+ if (got_fileindex_entry_has_file_on_disk(ie))
+ *status = GOT_STATUS_MISSING;
+ else
+ *status = GOT_STATUS_DELETE;
+ return NULL;
+ }
if (!S_ISREG(sb->st_mode) && !S_ISLNK(sb->st_mode)) {
*status = GOT_STATUS_OBSTRUCTED;
@@ -1727,6 +1719,12 @@ get_file_status(unsigned char *status, struct stat *sb
err = got_error_from_errno2("openat", abspath);
goto done;
}
+ } else {
+ fd = open(abspath, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
+ if (fd == -1) {
+ err = got_error_from_errno2("open", abspath);
+ goto done;
+ }
}
f = fdopen(fd, "r");