[PATCH 17/17] fs/squashfs: implement exists() function

Richard Genoud
2020-10-14T08:06:22Z

This permits to find a file and use the distro_bootcmd

Signed-off-by: Richard Genoud <richard.genoud@posteo.net>
---
fs/fs.c | 2 +-
fs/squashfs/sqfs.c | 38 ++++++++++++++++++++++++++++++++++++++
include/squashfs.h | 1 +
3 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/fs/fs.c b/fs/fs.c
index fb27c910d4f..7a4020607a3 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -296,7 +296,7 @@ static struct fstype_info fstypes[] = {
.size = sqfs_size,
.close = sqfs_close,
.closedir = sqfs_closedir,
- .exists = fs_exists_unsupported,
+ .exists = sqfs_exists,
.uuid = fs_uuid_unsupported,
.write = fs_write_unsupported,
.ln = fs_ln_unsupported,
diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c
index 82bf1faf25f..6952fc2b53e 100644
--- a/fs/squashfs/sqfs.c
+++ b/fs/squashfs/sqfs.c
@@ -1627,6 +1627,44 @@ free_strings:
return ret;
}

+int sqfs_exists(const char *filename)
+{
+ struct fs_dir_stream *dirsp = NULL;
+ struct squashfs_dir_stream *dirs;
+ char *dir, *file;
+ struct fs_dirent *dent;
+ int ret;
+
+ sqfs_split_path(&file, &dir, filename);
+ /*
+ * sqfs_opendir will uncompress inode and directory tables, and will
+ * return a pointer to the directory that contains the requested file.
+ */
+ ret = sqfs_opendir(dir, &dirsp);
+ if (ret) {
+ ret = -EINVAL;
+ goto free_strings;
+ }
+
+ dirs = (struct squashfs_dir_stream *)dirsp;
+
+ while (!sqfs_readdir(dirsp, &dent)) {
+ ret = strcmp(dent->name, file);
+ if (!ret)
+ break;
+ free(dirs->entry);
+ dirs->entry = NULL;
+ }
+
+ sqfs_closedir(dirsp);
+
+free_strings:
+ free(dir);
+ free(file);
+
+ return ret == 0;
+}
+
void sqfs_close(void)
{
free(ctxt.sblk);
diff --git a/include/squashfs.h b/include/squashfs.h
index 819cf8c2da8..7489eefa1f2 100644
--- a/include/squashfs.h
+++ b/include/squashfs.h
@@ -19,6 +19,7 @@ int sqfs_probe(struct blk_desc *fs_dev_desc,
int sqfs_read(const char *filename, void *buf, loff_t offset,
loff_t len, loff_t *actread);
int sqfs_size(const char *filename, loff_t *size);
+int sqfs_exists(const char *filename);
void sqfs_close(void);
void sqfs_closedir(struct fs_dir_stream *dirs);