#include "file_systems.h"
#include "resolve.h"
#include "node.h"
#include "file_table.h"
#include <kmalloc.h>
#include <segment.h>
#include <errno.h>
#include <string.h>
#include <stddef.h>
static int get_device(const char *fs_filename, char **device_path, struct device_struct **device)
{
int retval;
struct file_struct *nd;
if (!fs_filename) {
*device = NULL;
*device_path = NULL;
return 0;
}
if ((retval = resolve(fs_filename, &nd)) < 0)
goto end;
if ((retval = get_path(nd, device_path)) < 0)
goto release;
if ((retval = node_get_device(nd, device)) < 0)
goto error_free;
retval = 0;
release:
node_release(nd);
end:
return retval;
error_free:
if (*device_path)
kfree(*device_path, strlen(*device_path) + 1);
goto release;
}
void fs_init()
{
root_init();
file_table_init();
}
void fs_print_info()
{
file_table_print_info();
}
int fs_create(const char *fs_filename)
{
int retval;
struct file_struct *d;
const char *fs_basename;
if ((retval = file_exists(fs_filename)) < 0)
goto end;
if (retval) {
retval = -EEXIST;
goto end;
}
if ((retval = resolve_dir(fs_filename, &d, &fs_basename)) < 0)
goto end;
if (!get_fs_byte(fs_basename)) {
retval = -EEXIST;
goto release;
}
if ((retval = node_create(d, fs_basename)) < 0)
goto release;
retval = 0;
release:
node_release(d);
end:
return retval;
}
int fs_remove(const char *fs_filename)
{
int retval;
struct file_struct *nd;
if ((retval = resolve(fs_filename, &nd)) < 0)
goto end;
if ((retval = node_remove(nd)) < 0)
goto release;
retval = 0;
release:
node_release(nd);
end:
return retval;
}
int fs_mkdir(const char *fs_filename)
{
int retval;
struct file_struct *d;
const char *fs_basename;
if ((retval = file_exists(fs_filename)) < 0)
goto end;
if (retval) {
retval = -EEXIST;
goto end;
}
if ((retval = resolve_dir(fs_filename, &d, &fs_basename)) < 0)
goto end;
if (!get_fs_byte(fs_basename)) {
retval = -EEXIST;
goto release;
}
if ((retval = node_mkdir(d, fs_basename)) < 0)
goto release;
retval = 0;
release:
node_release(d);
end:
return retval;
}
int fs_rmdir(const char *fs_filename)
{
int retval;
struct file_struct *d;
if ((retval = resolve(fs_filename, &d)) < 0)
goto end;
if ((retval = node_rmdir(d)) < 0)
goto release;
retval = 0;
release:
node_release(d);
end:
return retval;
}
int fs_rename(const char *fs_oldname, const char *fs_newname)
{
int retval;
struct file_struct *nd, *nd1, *d;
const char *fs_basename;
if ((retval = resolve(fs_oldname, &nd)) < 0)
goto end;
if ((retval = file_exists(fs_newname)) < 0)
goto release_nd;
if (retval) {
if ((retval = resolve(fs_newname, &nd1)) < 0)
goto release_nd;
node_release(nd1);
if (nd1 == nd) {
retval = 0;
goto release_nd;
}
else {
retval = -EEXIST;
goto release_nd;
}
}
if ((retval = resolve_dir(fs_newname, &d, &fs_basename)) < 0)
goto release_nd;
if (!get_fs_byte(fs_basename)) {
retval = -EEXIST;
goto release_d;
}
if ((retval = node_rename(nd, d, fs_basename)) < 0)
goto release_d;
retval = 0;
release_d:
node_release(d);
release_nd:
node_release(nd);
end:
return retval;
}
int fs_mount(const char *fs_device, const char *fs_dir, const char *fs_type)
{
int retval;
struct device_struct *dev;
char *dev_path;
struct file_struct *nd;
const struct file_system_struct *fs;
if ((retval = get_device(fs_device, &dev_path, &dev)) < 0)
goto error;
if ((retval = resolve(fs_dir, &nd)) < 0)
goto error_free;
if ((retval = get_file_system(fs_type, &fs)) < 0)
goto error_release;
if ((retval = node_mount(nd, dev_path, dev, fs)) < 0)
goto error_release;
node_release(nd);
return 0;
error_release:
node_release(nd);
error_free:
if (dev_path)
kfree(dev_path, strlen(dev_path) + 1);
error:
return retval;
}
int fs_umount(const char *fs_dir)
{
int retval;
struct file_struct *nd;
if ((retval = resolve(fs_dir, &nd)) < 0)
goto end;
if ((retval = node_umount(nd)) < 0)
goto release;
retval = 0;
release:
node_release(nd);
end:
return retval;
}