1 /*
2  * Copyright (c) 2009-2015 Travis Geiselbrecht
3  *
4  * Use of this source code is governed by a MIT-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/MIT
7  */
8 #pragma once
9 
10 #include <stdbool.h>
11 #include <sys/types.h>
12 #include <lk/compiler.h>
13 
14 #define FS_MAX_PATH_LEN 128
15 #define FS_MAX_FILE_LEN 64
16 
17 __BEGIN_CDECLS
18 
19 // Generic FS ioctls
20 enum fs_ioctl_num {
21     FS_IOCTL_NULL = 0,
22     FS_IOCTL_GET_FILE_ADDR,
23     FS_IOCTL_IS_LINEAR,         // If supported, determine if the underlying device is in linear mode.
24 };
25 
26 struct file_stat {
27     bool is_dir;
28     uint64_t size;
29     uint64_t capacity;
30 };
31 
32 struct fs_stat {
33     uint64_t free_space;
34     uint64_t total_space;
35 
36     uint32_t free_inodes;
37     uint32_t total_inodes;
38 };
39 
40 struct dirent {
41     char name[FS_MAX_FILE_LEN];
42 };
43 
44 typedef struct filehandle filehandle;
45 typedef struct dirhandle dirhandle;
46 
47 
48 status_t fs_format_device(const char *fsname, const char *device, const void *args) __NONNULL((1));
49 status_t fs_mount(const char *path, const char *fs, const char *device) __NONNULL((1)) __NONNULL((2));
50 status_t fs_unmount(const char *path) __NONNULL();
51 status_t fs_file_ioctl(filehandle *handle, int request, void *argp) __NONNULL((1)) __NONNULL((3));
52 
53 /* file api */
54 status_t fs_create_file(const char *path, filehandle **handle, uint64_t len) __NONNULL();
55 status_t fs_open_file(const char *path, filehandle **handle) __NONNULL();
56 status_t fs_remove_file(const char *path) __NONNULL();
57 ssize_t fs_read_file(filehandle *handle, void *buf, off_t offset, size_t len) __NONNULL();
58 ssize_t fs_write_file(filehandle *handle, const void *buf, off_t offset, size_t len) __NONNULL();
59 status_t fs_close_file(filehandle *handle) __NONNULL();
60 status_t fs_stat_file(filehandle *handle, struct file_stat *) __NONNULL((1));
61 status_t fs_truncate_file(filehandle *handle, uint64_t len) __NONNULL((1));
62 
63 /* dir api */
64 status_t fs_make_dir(const char *path) __NONNULL();
65 status_t fs_open_dir(const char *path, dirhandle **handle) __NONNULL();
66 status_t fs_read_dir(dirhandle *handle, struct dirent *ent) __NONNULL();
67 status_t fs_close_dir(dirhandle *handle) __NONNULL();
68 
69 status_t fs_stat_fs(const char *mountpoint, struct fs_stat *stat) __NONNULL((1)) __NONNULL((2));
70 
71 /* convenience routines */
72 ssize_t fs_load_file(const char *path, void *ptr, size_t maxlen) __NONNULL();
73 
74 /* walk through a path string, removing duplicate path separators, flattening . and .. references */
75 void fs_normalize_path(char *path) __NONNULL();
76 
77 /* Remove any leading spaces or slashes */
78 const char *trim_name(const char *_name);
79 
80 /* file system api */
81 typedef struct fscookie fscookie;
82 typedef struct filecookie filecookie;
83 typedef struct dircookie dircookie;
84 struct bdev;
85 
86 struct fs_api {
87     status_t (*format)(struct bdev *, const void *);
88     status_t (*fs_stat)(fscookie *, struct fs_stat *);
89 
90     status_t (*mount)(struct bdev *, fscookie **);
91     status_t (*unmount)(fscookie *);
92     status_t (*open)(fscookie *, const char *, filecookie **);
93     status_t (*create)(fscookie *, const char *, filecookie **, uint64_t);
94     status_t (*remove)(fscookie *, const char *);
95     status_t (*truncate)(filecookie *, uint64_t);
96     status_t (*stat)(filecookie *, struct file_stat *);
97     ssize_t (*read)(filecookie *, void *, off_t, size_t);
98     ssize_t (*write)(filecookie *, const void *, off_t, size_t);
99     status_t (*close)(filecookie *);
100 
101     status_t (*mkdir)(fscookie *, const char *);
102     status_t (*opendir)(fscookie *, const char *, dircookie **) __NONNULL();
103     status_t (*readdir)(dircookie *, struct dirent *) __NONNULL();
104     status_t (*closedir)(dircookie *) __NONNULL();
105 
106     status_t (*file_ioctl)(filecookie *, int, void *);
107 };
108 
109 struct fs_impl {
110     const char *name;
111     const struct fs_api *api;
112 };
113 
114 /* define in your fs implementation to register your api with the fs layer */
115 #define STATIC_FS_IMPL(_name, _api) const struct fs_impl __fs_impl_##_name __ALIGNED(sizeof(void *)) __SECTION("fs_impl") = \
116     { .name = #_name, .api = _api }
117 
118 __END_CDECLS
119