1 #ifndef FS_H
2 #define FS_H
3 
4 #include <linux/list.h>
5 #include <stddef.h>
6 #include <stdbool.h>
7 #include <string.h>
8 #include <com32.h>
9 #include <stdio.h>
10 #include <sys/dirent.h>
11 #include <dprintf.h>
12 #include "core.h"
13 #include "disk.h"
14 
15 /*
16  * Maximum number of open files.
17  */
18 #define MAX_OPEN_LG2	7
19 #define MAX_OPEN	(1 << MAX_OPEN_LG2)
20 
21 #define FILENAME_MAX_LG2 8
22 #define FILENAME_MAX     (1 << FILENAME_MAX_LG2)
23 
24 #define CURRENTDIR_MAX	FILENAME_MAX
25 
26 #define BLOCK_SIZE(fs)   ((fs)->block_size)
27 #define BLOCK_SHIFT(fs)	 ((fs)->block_shift)
28 #define SECTOR_SIZE(fs)  ((fs)->sector_size)
29 #define SECTOR_SHIFT(fs) ((fs)->sector_shift)
30 
31 struct fs_info {
32     const struct fs_ops *fs_ops;
33     struct device *fs_dev;
34     void *fs_info;             /* The fs-specific information */
35     int sector_shift, sector_size;
36     int block_shift, block_size;
37     struct inode *root, *cwd;	   	/* Root and current directories */
38     char cwd_name[CURRENTDIR_MAX];	/* Current directory by name */
39 };
40 
41 extern struct fs_info *this_fs;
42 
43 struct dirent;                  /* Directory entry structure */
44 struct file;
45 enum fs_flags {
46     FS_NODEV   = 1 << 0,
47     FS_USEMEM  = 1 << 1,        /* If we need a malloc routine, set it */
48     FS_THISIND = 1 << 2,        /* Set cwd based on config file location */
49 };
50 
51 struct fs_ops {
52     /* in fact, we use fs_ops structure to find the right fs */
53     const char *fs_name;
54     enum fs_flags fs_flags;
55 
56     int      (*fs_init)(struct fs_info *);
57     void     (*searchdir)(const char *, int, struct file *);
58     uint32_t (*getfssec)(struct file *, char *, int, bool *);
59     void     (*close_file)(struct file *);
60     void     (*mangle_name)(char *, const char *);
61     size_t   (*realpath)(struct fs_info *, char *, const char *, size_t);
62     int      (*chdir)(struct fs_info *, const char *);
63     int      (*chdir_start)(void);
64     int      (*open_config)(struct com32_filedata *);
65 
66     struct inode * (*iget_root)(struct fs_info *);
67     struct inode * (*iget)(const char *, struct inode *);
68     int	     (*readlink)(struct inode *, char *);
69 
70     /* the _dir_ stuff */
71     int	     (*readdir)(struct file *, struct dirent *);
72 
73     int      (*next_extent)(struct inode *, uint32_t);
74 
75     int      (*copy_super)(void *buf);
76 
77     char *   (*fs_uuid)(struct fs_info *);
78 
79 };
80 
81 /*
82  * Extent structure: contains the mapping of some chunk of a file
83  * that is contiguous on disk.
84  */
85 struct extent {
86     sector_t	pstart;		/* Physical start sector */
87     uint32_t	lstart;		/* Logical start sector */
88     uint32_t	len;		/* Number of contiguous sectors */
89 };
90 
91 /* Special sector numbers used for struct extent.pstart */
92 #define EXTENT_ZERO	((sector_t)-1) /* All-zero extent */
93 #define EXTENT_VOID	((sector_t)-2) /* Invalid information */
94 
95 #define EXTENT_SPECIAL(x)	((x) >= EXTENT_VOID)
96 
97 /*
98  * The inode structure, including the detail file information
99  */
100 struct inode {
101     struct fs_info *fs;	 /* The filesystem this inode is associated with */
102     struct inode *parent;	/* Parent directory, if any */
103     const char *name;		/* Name, valid for generic path search only */
104     int		 refcnt;
105     int          mode;   /* FILE , DIR or SYMLINK */
106     uint64_t     size;
107     uint64_t	 blocks; /* How many blocks the file take */
108     uint64_t     ino;    /* Inode number */
109     uint32_t     atime;  /* Access time */
110     uint32_t     mtime;  /* Modify time */
111     uint32_t     ctime;  /* Create time */
112     uint32_t     dtime;  /* Delete time */
113     uint32_t     flags;
114     uint32_t     file_acl;
115     struct extent this_extent, next_extent;
116     char         pvt[0]; /* Private filesystem data */
117 };
118 
119 struct file {
120     struct fs_info *fs;
121     uint32_t offset;            /* for next read */
122     struct inode *inode;        /* The file-specific information */
123 };
124 
125 /*
126  * Struct device contains:
127  *     the pointer points to the disk structure,
128  *     the cache stuff.
129  */
130 struct cache;
131 
132 struct device {
133     struct disk *disk;
134 
135     /* the cache stuff */
136     uint8_t cache_init; /* cache initialized state */
137     char *cache_data;
138     struct cache *cache_head;
139     uint16_t cache_block_size;
140     uint16_t cache_entries;
141     uint32_t cache_size;
142 };
143 
144 /*
145  * Our definition of "not whitespace"
146  */
not_whitespace(char c)147 static inline bool not_whitespace(char c)
148 {
149   return (unsigned char)c > ' ';
150 }
151 
152 /*
153  * Inode allocator/deallocator
154  */
155 struct inode *alloc_inode(struct fs_info *fs, uint32_t ino, size_t data);
free_inode(struct inode * inode)156 static inline void free_inode(struct inode * inode)
157 {
158     free(inode);
159 }
160 
get_inode(struct inode * inode)161 static inline struct inode *get_inode(struct inode *inode)
162 {
163     inode->refcnt++;
164     dprintf("get_inode %p name %s refcnt %d\n",
165 	    inode, inode->name, inode->refcnt);
166     return inode;
167 }
168 
169 void put_inode(struct inode *inode);
170 
malloc_error(char * obj)171 static inline void malloc_error(char *obj)
172 {
173         printf("Out of memory: can't allocate memory for %s\n", obj);
174 	kaboom();
175 }
176 
177 /*
178  * File handle conversion functions
179  */
180 extern struct file files[];
file_to_handle(struct file * file)181 static inline uint16_t file_to_handle(struct file *file)
182 {
183     return file ? (file - files)+1 : 0;
184 }
handle_to_file(uint16_t handle)185 static inline struct file *handle_to_file(uint16_t handle)
186 {
187     return handle ? &files[handle-1] : NULL;
188 }
189 
190 struct path_entry {
191     struct list_head list;
192     const char *str;
193 };
194 
195 extern struct list_head PATH;
196 
197 extern struct path_entry *path_add(const char *str);
198 
199 /* fs.c */
200 void fs_init(const struct fs_ops **ops, void *priv);
201 void pm_mangle_name(com32sys_t *);
202 void pm_searchdir(com32sys_t *);
203 void mangle_name(char *, const char *);
204 int searchdir(const char *name, int flags);
205 void _close_file(struct file *);
206 size_t pmapi_read_file(uint16_t *handle, void *buf, size_t sectors);
207 int open_file(const char *name, int flags, struct com32_filedata *filedata);
208 void pm_open_file(com32sys_t *);
209 void close_file(uint16_t handle);
210 void pm_close_file(com32sys_t *);
211 int open_config(void);
212 char *fs_uuid(void);
213 
214 extern uint16_t SectorShift;
215 
216 /* chdir.c */
217 void pm_realpath(com32sys_t *regs);
218 size_t realpath(char *dst, const char *src, size_t bufsize);
219 int chdir(const char *src);
220 
221 /* readdir.c */
222 DIR *opendir(const char *pathname);
223 struct dirent *readdir(DIR *dir);
224 int closedir(DIR *dir);
225 
226 /* getcwd.c */
227 char *core_getcwd(char *buf, size_t size);
228 
229 /*
230  * Generic functions that filesystem drivers may choose to use
231  */
232 
233 /* chdir.c */
234 int generic_chdir_start(void);
235 
236 /* mangle.c */
237 void generic_mangle_name(char *, const char *);
238 
239 /* loadconfig.c */
240 int search_dirs(struct com32_filedata *filedata,
241 		const char *search_directores[], const char *filenames[],
242 		char *realname);
243 int generic_open_config(struct com32_filedata *filedata);
244 
245 /* close.c */
246 void generic_close_file(struct file *file);
247 
248 /* getfssec.c */
249 uint32_t generic_getfssec(struct file *file, char *buf,
250 			  int sectors, bool *have_more);
251 
252 /* nonextextent.c */
253 int no_next_extent(struct inode *, uint32_t);
254 
255 #endif /* FS_H */
256