1 /*
2  * Copyright (c) 2025 Antmicro <www.antmicro.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdio.h>
8 #include <string.h>
9 #include <zephyr/device.h>
10 #include <zephyr/fs/fs.h>
11 #include <zephyr/fs/virtiofs.h>
12 #include <zephyr/kernel.h>
13 
14 #define VIRTIO_DEV DEVICE_DT_GET(DT_NODELABEL(virtio_pci))
15 
16 #define MOUNT_POINT "/virtiofs"
17 
18 struct virtiofs_fs_data fs_data;
19 
20 static struct fs_mount_t mp = {
21 	.type = FS_VIRTIOFS,
22 	.fs_data = &fs_data,
23 	.flags = 0,
24 	.storage_dev = (void *)VIRTIO_DEV,
25 	.mnt_point = MOUNT_POINT,
26 };
27 
dirtree(const char * path,int indent)28 void dirtree(const char *path, int indent)
29 {
30 	struct fs_dir_t dir;
31 
32 	fs_dir_t_init(&dir);
33 	if (fs_opendir(&dir, path) == 0) {
34 		while (1) {
35 			struct fs_dirent entry;
36 
37 			if (fs_readdir(&dir, &entry) == 0) {
38 				if (entry.name[0] == '\0') {
39 					break;
40 				}
41 				if (entry.type == FS_DIR_ENTRY_DIR) {
42 					printf("%*s- %s (type=dir)\n", indent * 2, "", entry.name);
43 					char *subdir_path = k_malloc(
44 						strlen(path) + strlen(entry.name) + 2
45 					);
46 
47 					if (subdir_path == NULL) {
48 						printf("failed to allocate subdir path\n");
49 						continue;
50 					}
51 					strcpy(subdir_path, path);
52 					strcat(subdir_path, "/");
53 					strcat(subdir_path, entry.name);
54 					dirtree(subdir_path, indent + 1);
55 					k_free(subdir_path);
56 				} else {
57 					printf(
58 						"%*s- %s (type=file, size=%zu)\n",
59 						indent * 2, "", entry.name, entry.size
60 					);
61 				}
62 			} else {
63 				printf("failed to readdir %s\n", path);
64 				break;
65 			}
66 		};
67 
68 		fs_closedir(&dir);
69 	} else {
70 		printf("failed to opendir %s\n", path);
71 	}
72 }
73 
create_file(const char * path,const char * content)74 void create_file(const char *path, const char *content)
75 {
76 	struct fs_file_t file;
77 
78 	fs_file_t_init(&file);
79 	if (fs_open(&file, path, FS_O_CREATE | FS_O_WRITE) == 0) {
80 		fs_write(&file, content, strlen(content) + 1);
81 	} else {
82 		printf("failed to create %s\n", path);
83 	}
84 	fs_close(&file);
85 }
86 
print_file(const char * path)87 void print_file(const char *path)
88 {
89 	struct fs_file_t file;
90 
91 	fs_file_t_init(&file);
92 	if (fs_open(&file, path, FS_O_READ) == 0) {
93 		char buf[256] = "\0";
94 		int read_c = fs_read(&file, buf, sizeof(buf));
95 
96 		if (read_c >= 0) {
97 			buf[read_c] = 0;
98 
99 			printf(
100 				"%s content:\n"
101 				"%s\n",
102 				path, buf
103 			);
104 		} else {
105 			printf("failed to read from %s\n", path);
106 		}
107 
108 		fs_close(&file);
109 	} else {
110 		printf("failed to open %s\n", path);
111 	}
112 }
113 
main(void)114 int main(void)
115 {
116 	if (fs_mount(&mp) == 0) {
117 		printf("%s directory tree:\n", MOUNT_POINT);
118 		dirtree(MOUNT_POINT, 0);
119 		printf("\n");
120 
121 		print_file(MOUNT_POINT"/file");
122 
123 		create_file("/virtiofs/file_created_by_zephyr", "hello world\n");
124 
125 		create_file("/virtiofs/second_file_created_by_zephyr", "lorem ipsum\n");
126 
127 		fs_mkdir("/virtiofs/dir_created_by_zephyr");
128 	} else {
129 		printf("failed to mount %s\n", MOUNT_POINT);
130 	}
131 
132 	return 0;
133 }
134