git: 6e011d15031a - main - makefs: don't needlessly require directories to exist

From: Brooks Davis <brooks_at_FreeBSD.org>
Date: Thu, 12 Jan 2023 19:21:34 UTC
The branch main has been updated by brooks:

URL: https://cgit.FreeBSD.org/src/commit/?id=6e011d15031a73956912ca8b0e476484a58f905c

commit 6e011d15031a73956912ca8b0e476484a58f905c
Author:     Brooks Davis <brooks@FreeBSD.org>
AuthorDate: 2023-01-12 18:19:14 +0000
Commit:     Brooks Davis <brooks@FreeBSD.org>
CommitDate: 2023-01-12 19:16:14 +0000

    makefs: don't needlessly require directories to exist
    
    If a type=dir entry exists and all contents are directories, files
    added with contents=, or symlinks with link= attributes then it doesn't
    need to exist.  Just let openat fail in that case.  It's conceivable
    this will make debugging some cases weird, but it's sufficent to handle
    the way we add /root/.ssh in CheriBSD VM images.
    
    This is a recommit of 794154149f95d0cbc11aade166f9da919747e397 with
    bugfixes.
    
    Reviewed by:    markj
    Differential Revision:  https://reviews.freebsd.org/D38029
---
 usr.sbin/makefs/zfs/fs.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/usr.sbin/makefs/zfs/fs.c b/usr.sbin/makefs/zfs/fs.c
index 3cf328122df8..6a90396cb155 100644
--- a/usr.sbin/makefs/zfs/fs.c
+++ b/usr.sbin/makefs/zfs/fs.c
@@ -292,6 +292,17 @@ fs_open(const fsnode *cur, struct fs_populate_arg *arg, int flags)
 	return (fd);
 }
 
+static int
+fs_open_can_fail(const fsnode *cur, struct fs_populate_arg *arg, int flags)
+{
+	int fd;
+	char path[PATH_MAX];
+
+	fs_populate_path(cur, arg, path, sizeof(path), &fd);
+
+	return (openat(fd, path, flags));
+}
+
 static void
 fs_readlink(const fsnode *cur, struct fs_populate_arg *arg,
     char *buf, size_t bufsz)
@@ -590,7 +601,12 @@ fs_populate_dir(fsnode *cur, struct fs_populate_arg *arg)
 	 */
 	if (!SLIST_EMPTY(&arg->dirs)) {
 		fs_populate_dirent(arg, cur, dnid);
-		dirfd = fs_open(cur, arg, O_DIRECTORY | O_RDONLY);
+		/*
+		 * We only need the directory fd if we're finding files in
+		 * it.  If it's just there for other directories or
+		 * files using contents= we don't need to succeed here.
+		 */
+		dirfd = fs_open_can_fail(cur, arg, O_DIRECTORY | O_RDONLY);
 	} else {
 		arg->rootdirid = dnid;
 		dirfd = arg->rootdirfd;