Directory support in tmpfs
This commit is contained in:
parent
716ce11c83
commit
8c16a86206
@ -7,37 +7,63 @@
|
||||
/* 1KB */
|
||||
#define BLOCKSIZE 1024
|
||||
|
||||
#define TMPFS_TYPE_FILE 1
|
||||
#define TMPFS_TYPE_DIR 2
|
||||
|
||||
static uint8_t volatile lock = 0;
|
||||
|
||||
struct tmpfs_file {
|
||||
char * name;
|
||||
size_t length;
|
||||
size_t block_count;
|
||||
size_t pointers;
|
||||
uint32_t flags;
|
||||
char ** blocks;
|
||||
int type;
|
||||
int mask;
|
||||
int uid;
|
||||
int gid;
|
||||
unsigned int atime;
|
||||
unsigned int mtime;
|
||||
unsigned int ctime;
|
||||
size_t length;
|
||||
size_t block_count;
|
||||
size_t pointers;
|
||||
char ** blocks;
|
||||
};
|
||||
|
||||
list_t * tmpfs_files = NULL;
|
||||
struct tmpfs_dir;
|
||||
|
||||
struct tmpfs_dir {
|
||||
char * name;
|
||||
int type;
|
||||
int mask;
|
||||
int uid;
|
||||
int gid;
|
||||
unsigned int atime;
|
||||
unsigned int mtime;
|
||||
unsigned int ctime;
|
||||
list_t * files;
|
||||
struct tmpfs_dir * parent;
|
||||
};
|
||||
|
||||
char empty_block[BLOCKSIZE] = {0};
|
||||
|
||||
struct tmpfs_dir * tmpfs_root = NULL;
|
||||
|
||||
fs_node_t * tmpfs_from_dir(struct tmpfs_dir * d);
|
||||
|
||||
static struct tmpfs_file * tmpfs_file_new(char * name) {
|
||||
|
||||
spin_lock(&lock);
|
||||
|
||||
struct tmpfs_file * t = malloc(sizeof(struct tmpfs_file));
|
||||
t->name = strdup(name);
|
||||
t->type = TMPFS_TYPE_FILE;
|
||||
t->length = 0;
|
||||
t->pointers = 2;
|
||||
t->block_count = 0;
|
||||
t->flags = 0;
|
||||
t->mask = 0;
|
||||
t->uid = 0;
|
||||
t->gid = 0;
|
||||
t->atime = now();
|
||||
t->mtime = t->atime;
|
||||
t->ctime = t->ctime;
|
||||
t->blocks = malloc(t->pointers * sizeof(char *));
|
||||
for (size_t i = 0; i < t->pointers; ++i) {
|
||||
t->blocks[i] = NULL;
|
||||
@ -47,6 +73,24 @@ static struct tmpfs_file * tmpfs_file_new(char * name) {
|
||||
return t;
|
||||
}
|
||||
|
||||
static struct tmpfs_dir * tmpfs_dir_new(char * name, struct tmpfs_dir * parent) {
|
||||
spin_lock(&lock);
|
||||
|
||||
struct tmpfs_dir * d = malloc(sizeof(struct tmpfs_dir));
|
||||
d->name = strdup(name);
|
||||
d->type = TMPFS_TYPE_DIR;
|
||||
d->mask = 0;
|
||||
d->uid = 0;
|
||||
d->gid = 0;
|
||||
d->atime = now();
|
||||
d->mtime = d->atime;
|
||||
d->ctime = d->ctime;
|
||||
d->files = list_create();
|
||||
|
||||
spin_unlock(&lock);
|
||||
return d;
|
||||
}
|
||||
|
||||
static void tmpfs_file_free(struct tmpfs_file * t) {
|
||||
for (size_t i = 0; i < t->block_count; ++i) {
|
||||
free(t->blocks[i]);
|
||||
@ -85,6 +129,9 @@ static char * tmpfs_file_getset_block(struct tmpfs_file * t, size_t blockid, int
|
||||
|
||||
static uint32_t read_tmpfs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
|
||||
struct tmpfs_file * t = (struct tmpfs_file *)(node->device);
|
||||
|
||||
t->atime = now();
|
||||
|
||||
uint32_t end;
|
||||
if (offset + size > t->length) {
|
||||
end = t->length;
|
||||
@ -124,6 +171,10 @@ static uint32_t read_tmpfs(fs_node_t *node, uint32_t offset, uint32_t size, uint
|
||||
|
||||
static uint32_t write_tmpfs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
|
||||
struct tmpfs_file * t = (struct tmpfs_file *)(node->device);
|
||||
|
||||
t->atime = now();
|
||||
t->mtime = t->atime;
|
||||
|
||||
uint32_t end;
|
||||
if (offset + size > t->length) {
|
||||
t->length = offset + size;
|
||||
@ -176,6 +227,9 @@ static fs_node_t * tmpfs_from_file(struct tmpfs_file * t) {
|
||||
fnode->mask = t->mask;
|
||||
fnode->uid = t->uid;
|
||||
fnode->gid = t->gid;
|
||||
fnode->atime = t->atime;
|
||||
fnode->ctime = t->ctime;
|
||||
fnode->mtime = t->mtime;
|
||||
fnode->flags = FS_FILE;
|
||||
fnode->read = read_tmpfs;
|
||||
fnode->write = write_tmpfs;
|
||||
@ -189,13 +243,14 @@ static fs_node_t * tmpfs_from_file(struct tmpfs_file * t) {
|
||||
}
|
||||
|
||||
static struct dirent * readdir_tmpfs(fs_node_t *node, uint32_t index) {
|
||||
struct tmpfs_dir * d = (struct tmpfs_dir *)node->device;
|
||||
uint32_t i = 0;
|
||||
|
||||
debug_print(NOTICE, "tmpfs - readdir id=%d", index);
|
||||
|
||||
if (index >= tmpfs_files->length) return NULL;
|
||||
if (index >= d->files->length) return NULL;
|
||||
|
||||
foreach(f, tmpfs_files) {
|
||||
foreach(f, d->files) {
|
||||
if (i == index) {
|
||||
struct tmpfs_file * t = (struct tmpfs_file *)f->value;
|
||||
struct dirent * out = malloc(sizeof(struct dirent));
|
||||
@ -213,13 +268,20 @@ static struct dirent * readdir_tmpfs(fs_node_t *node, uint32_t index) {
|
||||
static fs_node_t * finddir_tmpfs(fs_node_t * node, char * name) {
|
||||
if (!name) return NULL;
|
||||
|
||||
struct tmpfs_dir * d = (struct tmpfs_dir *)node->device;
|
||||
|
||||
spin_lock(&lock);
|
||||
|
||||
foreach(f, tmpfs_files) {
|
||||
foreach(f, d->files) {
|
||||
struct tmpfs_file * t = (struct tmpfs_file *)f->value;
|
||||
if (!strcmp(name, t->name)) {
|
||||
spin_unlock(&lock);
|
||||
return tmpfs_from_file(t);
|
||||
switch (t->type) {
|
||||
case TMPFS_TYPE_FILE:
|
||||
return tmpfs_from_file(t);
|
||||
case TMPFS_TYPE_DIR:
|
||||
return tmpfs_from_dir((struct tmpfs_dir *)t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,10 +291,11 @@ static fs_node_t * finddir_tmpfs(fs_node_t * node, char * name) {
|
||||
}
|
||||
|
||||
static void unlink_tmpfs(fs_node_t * node, char * name) {
|
||||
struct tmpfs_dir * d = (struct tmpfs_dir *)node->device;
|
||||
int i = -1, j = 0;
|
||||
spin_lock(&lock);
|
||||
|
||||
foreach(f, tmpfs_files) {
|
||||
foreach(f, d->files) {
|
||||
struct tmpfs_file * t = (struct tmpfs_file *)f->value;
|
||||
if (!strcmp(name, t->name)) {
|
||||
tmpfs_file_free(t);
|
||||
@ -244,7 +307,7 @@ static void unlink_tmpfs(fs_node_t * node, char * name) {
|
||||
}
|
||||
|
||||
if (i >= 0) {
|
||||
list_remove(tmpfs_files, i);
|
||||
list_remove(d->files, i);
|
||||
}
|
||||
|
||||
spin_unlock(&lock);
|
||||
@ -254,10 +317,11 @@ static void unlink_tmpfs(fs_node_t * node, char * name) {
|
||||
void create_tmpfs(fs_node_t *parent, char *name, uint16_t permission) {
|
||||
if (!name) return;
|
||||
|
||||
debug_print(CRITICAL, "Creating TMPFS file %s", name);
|
||||
struct tmpfs_dir * d = (struct tmpfs_dir *)parent->device;
|
||||
debug_print(CRITICAL, "Creating TMPFS file %s in %s", name, d->name);
|
||||
|
||||
spin_lock(&lock);
|
||||
foreach(f, tmpfs_files) {
|
||||
foreach(f, d->files) {
|
||||
struct tmpfs_file * t = (struct tmpfs_file *)f->value;
|
||||
if (!strcmp(name, t->name)) {
|
||||
spin_unlock(&lock);
|
||||
@ -273,17 +337,47 @@ void create_tmpfs(fs_node_t *parent, char *name, uint16_t permission) {
|
||||
t->uid = current_process->user;
|
||||
t->gid = current_process->user;
|
||||
|
||||
list_insert(tmpfs_files, t);
|
||||
list_insert(d->files, t);
|
||||
}
|
||||
|
||||
fs_node_t * tmpfs_create() {
|
||||
void mkdir_tmpfs(fs_node_t * parent, char * name, uint16_t permission) {
|
||||
if (!name) return;
|
||||
|
||||
struct tmpfs_dir * d = (struct tmpfs_dir *)parent->device;
|
||||
debug_print(CRITICAL, "Creating TMPFS directory %s (in %s)", name, d->name);
|
||||
|
||||
spin_lock(&lock);
|
||||
foreach(f, d->files) {
|
||||
struct tmpfs_file * t = (struct tmpfs_file *)f->value;
|
||||
if (!strcmp(name, t->name)) {
|
||||
spin_unlock(&lock);
|
||||
debug_print(WARNING, "... already exists.");
|
||||
return; /* Already exists */
|
||||
}
|
||||
}
|
||||
spin_unlock(&lock);
|
||||
|
||||
debug_print(NOTICE, "... creating a new directory.");
|
||||
struct tmpfs_dir * out = tmpfs_dir_new(name, d);
|
||||
out->mask = permission;
|
||||
out->uid = current_process->user;
|
||||
out->gid = current_process->user;
|
||||
|
||||
list_insert(d->files, out);
|
||||
}
|
||||
|
||||
fs_node_t * tmpfs_from_dir(struct tmpfs_dir * d) {
|
||||
fs_node_t * fnode = malloc(sizeof(fs_node_t));
|
||||
memset(fnode, 0x00, sizeof(fs_node_t));
|
||||
fnode->inode = 0;
|
||||
strcpy(fnode->name, "tmp");
|
||||
fnode->mask = 0777;
|
||||
fnode->uid = 0;
|
||||
fnode->gid = 0;
|
||||
fnode->mask = d->mask;
|
||||
fnode->uid = d->uid;
|
||||
fnode->gid = d->gid;
|
||||
fnode->device = d;
|
||||
fnode->atime = d->atime;
|
||||
fnode->mtime = d->mtime;
|
||||
fnode->ctime = d->ctime;
|
||||
fnode->flags = FS_DIRECTORY;
|
||||
fnode->read = NULL;
|
||||
fnode->write = NULL;
|
||||
@ -293,7 +387,16 @@ fs_node_t * tmpfs_create() {
|
||||
fnode->finddir = finddir_tmpfs;
|
||||
fnode->create = create_tmpfs;
|
||||
fnode->unlink = unlink_tmpfs;
|
||||
fnode->mkdir = mkdir_tmpfs;
|
||||
|
||||
tmpfs_files = list_create();
|
||||
return fnode;
|
||||
}
|
||||
|
||||
fs_node_t * tmpfs_create() {
|
||||
tmpfs_root = tmpfs_dir_new("tmp", NULL);
|
||||
tmpfs_root->mask = 0777;
|
||||
tmpfs_root->uid = 0;
|
||||
tmpfs_root->gid = 0;
|
||||
|
||||
return tmpfs_from_dir(tmpfs_root);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user