"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
Re: Optimized branch switching?
To:
Christian Weisgerber <naddy@mips.inka.de>, gameoftrees@openbsd.org
Date:
Tue, 13 Sep 2022 13:17:19 +0200

Download raw body.

Thread
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");