summaryrefslogtreecommitdiffstats
path: root/fs/fs.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2007-07-05 18:01:37 +0200
committerSascha Hauer <sha@octopus.labnet.pengutronix.de>2007-07-05 18:01:37 +0200
commit9db8ed3312a2137b12cb0cb15c4267ead96dbf8b (patch)
treeefa8cebc8db28bf6e7fafae2d920f15d66381047 /fs/fs.c
parent225b19227203911f9bda410746ef4e366a008852 (diff)
downloadbarebox-9db8ed3312a2137b12cb0cb15c4267ead96dbf8b.tar.gz
barebox-9db8ed3312a2137b12cb0cb15c4267ead96dbf8b.tar.xz
svn_rev_261
WIP Filesystem support
Diffstat (limited to 'fs/fs.c')
-rw-r--r--fs/fs.c238
1 files changed, 186 insertions, 52 deletions
diff --git a/fs/fs.c b/fs/fs.c
index 824645bca3..ec2373c97b 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -37,26 +37,48 @@ char *mkmodestr(unsigned long mode, char *str)
return str;
}
-static int fs_probe(struct device_d *dev)
-{
- struct fs_device_d *fs_dev = dev->platform_data;
+struct mtab_entry {
+ char path[PATH_MAX];
+ struct mtab_entry *next;
+ struct device_d *dev;
+};
- return fs_dev->driver->probe(fs_dev->parent);
-}
+static struct mtab_entry *mtab;
-int register_fs_driver(struct fs_driver_d *new_fs_drv)
+struct mtab_entry *get_mtab_entry_by_path(const char *_path)
{
- new_fs_drv->drv.probe = fs_probe;
- new_fs_drv->drv.driver_data = new_fs_drv;
+ struct mtab_entry *match = NULL, *e = mtab;
+ char *path, *tok;
+
+ if (*_path != '/')
+ return NULL;
+
+ path = strdup(_path);
+
+ tok = strchr(path + 1, '/');
+ if (tok)
+ *tok = 0;
+
+ while (e) {
+ if (!strcmp(path, e->path)) {
+ match = e;
+ break;
+ }
+ e = e->next;
+ }
+
+ free(path);
- return register_driver(&new_fs_drv->drv);
+ return match ? match : mtab;
}
-int register_filesystem(struct device_d *dev, char *fsname)
+int mount (struct device_d *dev, char *fsname, char *path)
{
- struct fs_device_d *new_fs_dev;
struct driver_d *drv;
struct fs_driver_d *fs_drv;
+ struct mtab_entry *entry;
+ struct fs_device_d *fsdev;
+ int ret;
drv = get_driver_by_name(fsname);
if (!drv) {
@@ -69,72 +91,184 @@ int register_filesystem(struct device_d *dev, char *fsname)
return -EINVAL;
}
- new_fs_dev = malloc(sizeof(struct fs_device_d));
+ /* check if path exists */
+ /* TODO */
- fs_drv = drv->driver_data;
+ fs_drv = drv->type_data;
+ printf("mount: fs_drv: %p\n", fs_drv);
- new_fs_dev->driver = fs_drv;
- new_fs_dev->parent = dev;
- new_fs_dev->dev.platform_data = new_fs_dev;
- new_fs_dev->dev.type = DEVICE_TYPE_FS;
- sprintf(new_fs_dev->dev.name, "%s", fsname);
- sprintf(new_fs_dev->dev.id, "%s", "fs0");
+ if (fs_drv->flags & FS_DRIVER_NO_DEV) {
+ dev = malloc(sizeof(struct device_d));
+ memset(dev, 0, sizeof(struct device_d));
+ sprintf(dev->name, "%s", fsname);
+ dev->type = DEVICE_TYPE_FS;
+ if ((ret = register_device(dev))) {
+ free(dev);
+ return ret;
+ }
+ if (!dev->driver) {
+ /* driver didn't accept the device. Bail out */
+ free(dev);
+ return -EINVAL;
+ }
+ } else {
+ fsdev = malloc(sizeof(struct fs_device_d));
+ memset(fsdev, 0, sizeof(struct fs_device_d));
+ fsdev->parent = dev;
+ sprintf(fsdev->dev.name, "%s", fsname);
+ fsdev->dev.type = DEVICE_TYPE_FS;
+ fsdev->dev.type_data = fsdev;
+ if ((ret = register_device(&fsdev->dev))) {
+ free(fsdev);
+ return ret;
+ }
+ if (!fsdev->dev.driver) {
+ /* driver didn't accept the device. Bail out */
+ free(fsdev);
+ return -EINVAL;
+ }
+ dev = &fsdev->dev;
+ }
- register_device(&new_fs_dev->dev);
+ /* add mtab entry */
+ entry = malloc(sizeof(struct mtab_entry));
+ sprintf(entry->path, "%s", path);
+ entry->dev = dev;
+ entry->next = NULL;
- if (!new_fs_dev->dev.driver) {
- unregister_device(&new_fs_dev->dev);
- return -ENODEV;
+ if (!mtab)
+ mtab = entry;
+ else {
+ struct mtab_entry *e = mtab;
+ while (e->next)
+ e = e->next;
+ e->next = entry;
}
+ printf("mount: mtab->dev: %p\n", mtab->dev);
+
return 0;
}
-int ls(struct device_d *dev, const char *filename)
+int do_mount (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- struct fs_device_d *fs_dev;
+ struct device_d *dev;
+ int ret = 0;
- if (!dev || dev->type != DEVICE_TYPE_FS || !dev->driver)
- return -ENODEV;
+ if (argc != 4) {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
- fs_dev = dev->platform_data;
+ dev = get_device_by_id(argv[1]);
- return fs_dev->driver->ls(fs_dev->parent, filename);
+ if ((ret = mount(dev, argv[2], argv[3]))) {
+ perror("mount", ret);
+ return 1;
+ }
+ return 0;
}
-/* addfs <device> <fstype> */
-int do_addfs ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+struct dir *opendir(const char *pathname)
{
struct device_d *dev;
- int ret = 0;
+ struct fs_driver_d *fsdrv;
+ struct dir *dir;
+ struct mtab_entry *e;
- if (argc != 3) {
- printf ("Usage:\n%s\n", cmdtp->usage);
- return 1;
+ e = get_mtab_entry_by_path(pathname);
+ if (e != mtab)
+ pathname += strlen(e->path);
+
+ dev = e->dev;
+// printf("opendir: dev: %p\n",dev);
+
+ fsdrv = (struct fs_driver_d *)dev->driver->type_data;
+// printf("opendir: fsdrv: %p\n",fsdrv);
+
+ dir = fsdrv->opendir(dev, pathname);
+ if (dir) {
+ dir->dev = dev;
+ dir->fsdrv = fsdrv;
}
- dev = get_device_by_id(argv[1]);
- if (!dev) {
- printf("no such device: %s\n", argv[1]);
- return -ENODEV;
+ return dir;
+}
+
+struct dirent *readdir(struct dir *dir)
+{
+ return dir->fsdrv->readdir(dir->dev, dir);
+}
+
+int closedir(struct dir *dir)
+{
+ return dir->fsdrv->closedir(dir->dev, dir);
+}
+
+static int ls(const char *path)
+{
+ struct dir *dir;
+ struct dirent *d;
+ char modestr[11];
+
+ dir = opendir(path);
+ if (!dir)
+ return -ENOENT;
+
+ while ((d = readdir(dir))) {
+ unsigned long namelen = strlen(d->name);
+ mkmodestr(d->mode, modestr);
+ printf("%s %8d %*.*s\n",modestr, d->size, namelen, namelen, d->name);
}
- if ((ret = register_filesystem(dev, argv[2]))) {
- perror("register_device", ret);
+ closedir(dir);
+
+ return 0;
+}
+
+int do_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ int ret;
+
+ ret = ls(argv[1]);
+ if (ret) {
+ perror("ls", ret);
return 1;
}
+
return 0;
}
-int do_ls ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+U_BOOT_CMD(
+ ls, 2, 0, do_ls,
+ "ls - list a file or directory\n",
+ "<path> list files on path"
+);
+
+int mkdir (const char *pathname)
{
+ struct fs_driver_d *fsdrv;
struct device_d *dev;
- char *endp;
- int ret;
+ struct mtab_entry *e;
+
+ e = get_mtab_entry_by_path(pathname);
+ if (e != mtab)
+ pathname += strlen(e->path);
+
+ dev = e->dev;
- dev = device_from_spec_str(argv[1], &endp);
+ fsdrv = (struct fs_driver_d *)dev->driver->type_data;
- ret = ls(dev, endp);
+ if (fsdrv->mkdir)
+ return fsdrv->mkdir(dev, pathname);
+ return -EROFS;
+}
+
+int do_mkdir (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ int ret;
+
+ ret = mkdir(argv[1]);
if (ret) {
perror("ls", ret);
return 1;
@@ -144,15 +278,15 @@ int do_ls ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
}
U_BOOT_CMD(
- ls, 2, 0, do_ls,
- "ls - list a file or directory\n",
- "<dev:path> list files on device"
+ mkdir, 2, 0, do_mkdir,
+ "mkdir - create a new directory\n",
+ ""
);
U_BOOT_CMD(
- addfs, 3, 0, do_addfs,
- "addfs - add a filesystem to a device\n",
- " <device> <type> add a filesystem of type 'type' on the given device"
+ mount, 4, 0, do_mount,
+ "mount - mount a filesystem to a device\n",
+ " <device> <type> <path> add a filesystem of type 'type' on the given device"
);
#if 0
U_BOOT_CMD(