256 lines
6.6 KiB
C
256 lines
6.6 KiB
C
#ifndef FS_H
|
|
#define FS_H
|
|
|
|
#include <linux/list.h>
|
|
#include <stddef.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#include <com32.h>
|
|
#include <stdio.h>
|
|
#include <sys/dirent.h>
|
|
#include <dprintf.h>
|
|
#include "core.h"
|
|
#include "disk.h"
|
|
|
|
/*
|
|
* Maximum number of open files.
|
|
*/
|
|
#define MAX_OPEN_LG2 7
|
|
#define MAX_OPEN (1 << MAX_OPEN_LG2)
|
|
|
|
#define FILENAME_MAX_LG2 8
|
|
#define FILENAME_MAX (1 << FILENAME_MAX_LG2)
|
|
|
|
#define CURRENTDIR_MAX FILENAME_MAX
|
|
|
|
#define BLOCK_SIZE(fs) ((fs)->block_size)
|
|
#define BLOCK_SHIFT(fs) ((fs)->block_shift)
|
|
#define SECTOR_SIZE(fs) ((fs)->sector_size)
|
|
#define SECTOR_SHIFT(fs) ((fs)->sector_shift)
|
|
|
|
struct fs_info {
|
|
const struct fs_ops *fs_ops;
|
|
struct device *fs_dev;
|
|
void *fs_info; /* The fs-specific information */
|
|
int sector_shift, sector_size;
|
|
int block_shift, block_size;
|
|
struct inode *root, *cwd; /* Root and current directories */
|
|
char cwd_name[CURRENTDIR_MAX]; /* Current directory by name */
|
|
};
|
|
|
|
extern struct fs_info *this_fs;
|
|
|
|
struct dirent; /* Directory entry structure */
|
|
struct file;
|
|
enum fs_flags {
|
|
FS_NODEV = 1 << 0,
|
|
FS_USEMEM = 1 << 1, /* If we need a malloc routine, set it */
|
|
FS_THISIND = 1 << 2, /* Set cwd based on config file location */
|
|
};
|
|
|
|
struct fs_ops {
|
|
/* in fact, we use fs_ops structure to find the right fs */
|
|
const char *fs_name;
|
|
enum fs_flags fs_flags;
|
|
|
|
int (*fs_init)(struct fs_info *);
|
|
void (*searchdir)(const char *, int, struct file *);
|
|
uint32_t (*getfssec)(struct file *, char *, int, bool *);
|
|
void (*close_file)(struct file *);
|
|
void (*mangle_name)(char *, const char *);
|
|
size_t (*realpath)(struct fs_info *, char *, const char *, size_t);
|
|
int (*chdir)(struct fs_info *, const char *);
|
|
int (*chdir_start)(void);
|
|
int (*open_config)(struct com32_filedata *);
|
|
|
|
struct inode * (*iget_root)(struct fs_info *);
|
|
struct inode * (*iget)(const char *, struct inode *);
|
|
int (*readlink)(struct inode *, char *);
|
|
|
|
/* the _dir_ stuff */
|
|
int (*readdir)(struct file *, struct dirent *);
|
|
|
|
int (*next_extent)(struct inode *, uint32_t);
|
|
|
|
int (*copy_super)(void *buf);
|
|
|
|
char * (*fs_uuid)(struct fs_info *);
|
|
|
|
};
|
|
|
|
/*
|
|
* Extent structure: contains the mapping of some chunk of a file
|
|
* that is contiguous on disk.
|
|
*/
|
|
struct extent {
|
|
sector_t pstart; /* Physical start sector */
|
|
uint32_t lstart; /* Logical start sector */
|
|
uint32_t len; /* Number of contiguous sectors */
|
|
};
|
|
|
|
/* Special sector numbers used for struct extent.pstart */
|
|
#define EXTENT_ZERO ((sector_t)-1) /* All-zero extent */
|
|
#define EXTENT_VOID ((sector_t)-2) /* Invalid information */
|
|
|
|
#define EXTENT_SPECIAL(x) ((x) >= EXTENT_VOID)
|
|
|
|
/*
|
|
* The inode structure, including the detail file information
|
|
*/
|
|
struct inode {
|
|
struct fs_info *fs; /* The filesystem this inode is associated with */
|
|
struct inode *parent; /* Parent directory, if any */
|
|
const char *name; /* Name, valid for generic path search only */
|
|
int refcnt;
|
|
int mode; /* FILE , DIR or SYMLINK */
|
|
uint64_t size;
|
|
uint64_t blocks; /* How many blocks the file take */
|
|
uint64_t ino; /* Inode number */
|
|
uint32_t atime; /* Access time */
|
|
uint32_t mtime; /* Modify time */
|
|
uint32_t ctime; /* Create time */
|
|
uint32_t dtime; /* Delete time */
|
|
uint32_t flags;
|
|
uint32_t file_acl;
|
|
struct extent this_extent, next_extent;
|
|
char pvt[0]; /* Private filesystem data */
|
|
};
|
|
|
|
struct file {
|
|
struct fs_info *fs;
|
|
uint32_t offset; /* for next read */
|
|
struct inode *inode; /* The file-specific information */
|
|
};
|
|
|
|
/*
|
|
* Struct device contains:
|
|
* the pointer points to the disk structure,
|
|
* the cache stuff.
|
|
*/
|
|
struct cache;
|
|
|
|
struct device {
|
|
struct disk *disk;
|
|
|
|
/* the cache stuff */
|
|
uint8_t cache_init; /* cache initialized state */
|
|
char *cache_data;
|
|
struct cache *cache_head;
|
|
uint16_t cache_block_size;
|
|
uint16_t cache_entries;
|
|
uint32_t cache_size;
|
|
};
|
|
|
|
/*
|
|
* Our definition of "not whitespace"
|
|
*/
|
|
static inline bool not_whitespace(char c)
|
|
{
|
|
return (unsigned char)c > ' ';
|
|
}
|
|
|
|
/*
|
|
* Inode allocator/deallocator
|
|
*/
|
|
struct inode *alloc_inode(struct fs_info *fs, uint32_t ino, size_t data);
|
|
static inline void free_inode(struct inode * inode)
|
|
{
|
|
free(inode);
|
|
}
|
|
|
|
static inline struct inode *get_inode(struct inode *inode)
|
|
{
|
|
inode->refcnt++;
|
|
dprintf("get_inode %p name %s refcnt %d\n",
|
|
inode, inode->name, inode->refcnt);
|
|
return inode;
|
|
}
|
|
|
|
void put_inode(struct inode *inode);
|
|
|
|
static inline void malloc_error(char *obj)
|
|
{
|
|
printf("Out of memory: can't allocate memory for %s\n", obj);
|
|
kaboom();
|
|
}
|
|
|
|
/*
|
|
* File handle conversion functions
|
|
*/
|
|
extern struct file files[];
|
|
static inline uint16_t file_to_handle(struct file *file)
|
|
{
|
|
return file ? (file - files)+1 : 0;
|
|
}
|
|
static inline struct file *handle_to_file(uint16_t handle)
|
|
{
|
|
return handle ? &files[handle-1] : NULL;
|
|
}
|
|
|
|
struct path_entry {
|
|
struct list_head list;
|
|
const char *str;
|
|
};
|
|
|
|
extern struct list_head PATH;
|
|
|
|
extern struct path_entry *path_add(const char *str);
|
|
|
|
/* fs.c */
|
|
void fs_init(const struct fs_ops **ops, void *priv);
|
|
void pm_mangle_name(com32sys_t *);
|
|
void pm_searchdir(com32sys_t *);
|
|
void mangle_name(char *, const char *);
|
|
int searchdir(const char *name, int flags);
|
|
void _close_file(struct file *);
|
|
size_t pmapi_read_file(uint16_t *handle, void *buf, size_t sectors);
|
|
int open_file(const char *name, int flags, struct com32_filedata *filedata);
|
|
void pm_open_file(com32sys_t *);
|
|
void close_file(uint16_t handle);
|
|
void pm_close_file(com32sys_t *);
|
|
int open_config(void);
|
|
char *fs_uuid(void);
|
|
|
|
extern uint16_t SectorShift;
|
|
|
|
/* chdir.c */
|
|
void pm_realpath(com32sys_t *regs);
|
|
size_t realpath(char *dst, const char *src, size_t bufsize);
|
|
int chdir(const char *src);
|
|
|
|
/* readdir.c */
|
|
DIR *opendir(const char *pathname);
|
|
struct dirent *readdir(DIR *dir);
|
|
int closedir(DIR *dir);
|
|
|
|
/* getcwd.c */
|
|
char *core_getcwd(char *buf, size_t size);
|
|
|
|
/*
|
|
* Generic functions that filesystem drivers may choose to use
|
|
*/
|
|
|
|
/* chdir.c */
|
|
int generic_chdir_start(void);
|
|
|
|
/* mangle.c */
|
|
void generic_mangle_name(char *, const char *);
|
|
|
|
/* loadconfig.c */
|
|
int search_dirs(struct com32_filedata *filedata,
|
|
const char *search_directores[], const char *filenames[],
|
|
char *realname);
|
|
int generic_open_config(struct com32_filedata *filedata);
|
|
|
|
/* close.c */
|
|
void generic_close_file(struct file *file);
|
|
|
|
/* getfssec.c */
|
|
uint32_t generic_getfssec(struct file *file, char *buf,
|
|
int sectors, bool *have_more);
|
|
|
|
/* nonextextent.c */
|
|
int no_next_extent(struct inode *, uint32_t);
|
|
|
|
#endif /* FS_H */
|