diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2007-07-05 18:01:38 +0200 |
---|---|---|
committer | Sascha Hauer <sha@octopus.labnet.pengutronix.de> | 2007-07-05 18:01:38 +0200 |
commit | cf7a56fc78a3304fd9ad4b22c6da30cc452a5b4b (patch) | |
tree | d74423adf47b86daea48bac089b9ecc32afe4d42 /fs | |
parent | 5c1f0869414930fdebc35755217ead72d39879ec (diff) | |
download | barebox-cf7a56fc78a3304fd9ad4b22c6da30cc452a5b4b.tar.gz barebox-cf7a56fc78a3304fd9ad4b22c6da30cc452a5b4b.tar.xz |
svn_rev_268
WIP
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cramfs/cramfs.c | 240 | ||||
-rw-r--r-- | fs/fs.c | 324 | ||||
-rw-r--r-- | fs/ramfs.c | 89 |
3 files changed, 418 insertions, 235 deletions
diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c index 95dfad97ac..25631a6b74 100644 --- a/fs/cramfs/cramfs.c +++ b/fs/cramfs/cramfs.c @@ -28,6 +28,7 @@ #include <malloc.h> #include <driver.h> #include <init.h> +#include <errno.h> #include <asm-generic/errno.h> #include <fs.h> @@ -42,49 +43,56 @@ #define CRAMINO(x) (CRAMFS_GET_OFFSET(x) ? CRAMFS_GET_OFFSET(x)<<2 : 1) #define OFFSET(x) ((x)->i_ino) -struct cramfs_super super; +struct cramfs_priv { + struct cramfs_super super; + int curr_block; + struct cramfs_inode *inode; + char buf[4096]; + int curr_block_len; +}; -static int cramfs_read_super (struct device_d *dev) +static int cramfs_read_super (struct device_d *dev, struct cramfs_priv *priv) { unsigned long root_offset; + struct cramfs_super *super = &priv->super; - if (read(dev, &super, sizeof (super), 0, 0) < sizeof (super)) { + if (dev_read(dev, super, sizeof (struct cramfs_super), 0, 0) < sizeof (struct cramfs_super)) { printf("read superblock failed\n"); return -EINVAL; } /* Do sanity checks on the superblock */ - if (super.magic != CRAMFS_32 (CRAMFS_MAGIC)) { + if (super->magic != CRAMFS_32 (CRAMFS_MAGIC)) { /* check at 512 byte offset */ - if (read(dev, &super, sizeof (super), 512, 0) < sizeof (super)) { + if (dev_read(dev, super, sizeof (struct cramfs_super), 512, 0) < sizeof (struct cramfs_super)) { printf("read superblock failed\n"); return -EINVAL; } - if (super.magic != CRAMFS_32 (CRAMFS_MAGIC)) { + if (super->magic != CRAMFS_32 (CRAMFS_MAGIC)) { printf ("cramfs: wrong magic\n"); return -1; } } /* flags is reused several times, so swab it once */ - super.flags = CRAMFS_32 (super.flags); - super.size = CRAMFS_32 (super.size); + super->flags = CRAMFS_32 (super->flags); + super->size = CRAMFS_32 (super->size); /* get feature flags first */ - if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) { + if (super->flags & ~CRAMFS_SUPPORTED_FLAGS) { printf ("cramfs: unsupported filesystem features\n"); return -1; } /* Check that the root inode is in a sane state */ - if (!S_ISDIR (CRAMFS_16 (super.root.mode))) { + if (!S_ISDIR (CRAMFS_16 (super->root.mode))) { printf ("cramfs: root is not a directory\n"); return -1; } - root_offset = CRAMFS_GET_OFFSET (&(super.root)) << 2; + root_offset = CRAMFS_GET_OFFSET (&(super->root)) << 2; if (root_offset == 0) { printf ("cramfs: empty filesystem"); - } else if (!(super.flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) && + } else if (!(super->flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) && ((root_offset != sizeof (struct cramfs_super)) && (root_offset != 512 + sizeof (struct cramfs_super)))) { printf ("cramfs: bad root offset %lu\n", root_offset); @@ -153,61 +161,10 @@ static unsigned long cramfs_resolve (unsigned long begin, unsigned long offset, inodeoffset = nextoffset; } + printf ("can't find corresponding entry\n"); return 0; } -static int cramfs_uncompress (unsigned long begin, unsigned long offset, - unsigned long loadoffset) -{ - struct cramfs_inode *inode = (struct cramfs_inode *) (begin + offset); - unsigned long *block_ptrs = (unsigned long *) - (begin + (CRAMFS_GET_OFFSET (inode) << 2)); - unsigned long curr_block = (CRAMFS_GET_OFFSET (inode) + - (((CRAMFS_24 (inode->size)) + - 4095) >> 12)) << 2; - int size, total_size = 0; - int i; - - cramfs_uncompress_init (); - - for (i = 0; i < ((CRAMFS_24 (inode->size) + 4095) >> 12); i++) { - size = cramfs_uncompress_block ((void *) loadoffset, - (void *) (begin + curr_block), - (CRAMFS_32 (block_ptrs[i]) - - curr_block)); - if (size < 0) - return size; - loadoffset += size; - total_size += size; - curr_block = CRAMFS_32 (block_ptrs[i]); - } - - cramfs_uncompress_exit (); - return total_size; -} - -int cramfs_load (char *loadoffset, struct device_d *dev, const char *filename) -{ - unsigned long offset; - char *f; - if (cramfs_read_super (dev)) - return -1; - - f = strdup(filename); - offset = cramfs_resolve (dev->map_base, - CRAMFS_GET_OFFSET (&(super.root)) << 2, - CRAMFS_24 (super.root.size), 0, - strtok (f, "/")); - - free(f); - - if (offset <= 0) - return offset; - - return cramfs_uncompress (dev->map_base, offset, - (unsigned long) loadoffset); -} - static int cramfs_fill_dirent (struct device_d *dev, unsigned long offset, struct dirent *d) { struct cramfs_inode *inode = (struct cramfs_inode *) @@ -232,8 +189,6 @@ static int cramfs_fill_dirent (struct device_d *dev, unsigned long offset, struc namelen--; } - d->mode = CRAMFS_16 (inode->mode); - d->size = CRAMFS_24 (inode->size); memset(d->name, 0, 256); strncpy(d->name, name, namelen); @@ -250,6 +205,7 @@ struct cramfs_dir { struct dir* cramfs_opendir(struct device_d *_dev, const char *filename) { char *f; + struct cramfs_priv *priv = _dev->priv; struct fs_device_d *fsdev = _dev->type_data; struct device_d *dev = fsdev->parent; @@ -259,14 +215,14 @@ struct dir* cramfs_opendir(struct device_d *_dev, const char *filename) if (strlen (filename) == 0 || !strcmp (filename, "/")) { /* Root directory. Use root inode in super block */ - dir->offset = CRAMFS_GET_OFFSET (&(super.root)) << 2; - dir->size = CRAMFS_24 (super.root.size); + dir->offset = CRAMFS_GET_OFFSET (&(priv->super.root)) << 2; + dir->size = CRAMFS_24 (priv->super.root.size); } else { f = strdup(filename); /* Resolve the path */ dir->offset = cramfs_resolve (dev->map_base, - CRAMFS_GET_OFFSET (&(super.root)) << - 2, CRAMFS_24 (super.root.size), 1, + CRAMFS_GET_OFFSET (&(priv->super.root)) << + 2, CRAMFS_24 (priv->super.root.size), 1, strtok (f, "/")); free(f); if (dir->offset <= 0) @@ -291,7 +247,7 @@ err_free: return NULL; } -struct dirent* cramfs_readdir(struct device_d *_dev, struct dir *_dir) +static struct dirent* cramfs_readdir(struct device_d *_dev, struct dir *_dir) { struct fs_device_d *fsdev = _dev->type_data; struct device_d *dev = fsdev->parent; @@ -311,14 +267,123 @@ struct dirent* cramfs_readdir(struct device_d *_dev, struct dir *_dir) return NULL; } -int cramfs_closedir(struct device_d *dev, struct dir *_dir) +static int cramfs_closedir(struct device_d *dev, struct dir *_dir) { struct cramfs_dir *dir = _dir->priv; free(dir); return 0; } -int cramfs_info (struct device_d *dev) +static int cramfs_open(struct device_d *_dev, FILE *file, const char *filename) +{ + struct cramfs_priv *priv = _dev->priv; + struct fs_device_d *fsdev = _dev->type_data; + struct device_d *dev = fsdev->parent; + char *f; + unsigned long offset; + + f = strdup(filename); + offset = cramfs_resolve (dev->map_base, + CRAMFS_GET_OFFSET (&(priv->super.root)) << 2, + CRAMFS_24 (priv->super.root.size), 0, + strtok (f, "/")); + + free(f); + + if (offset <= 0) + return -ENOENT; + + file->pos = 0; + file->inode = (struct cramfs_inode *)(dev->map_base + offset); + + return 0; +} + +static int cramfs_close(struct device_d *dev, FILE *f) +{ + return 0; +} + +static int cramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size) +{ + struct cramfs_priv *priv = _dev->priv; + struct fs_device_d *fsdev = _dev->type_data; + struct device_d *dev = fsdev->parent; + struct cramfs_inode *inode = (struct cramfs_inode *)f->inode; + unsigned int blocknr; + int outsize = 0; + unsigned long *block_ptrs = (unsigned long *) + (dev->map_base + (CRAMFS_GET_OFFSET (inode) << 2)); + int ofs = f->pos % 4096; + + if (f->pos + size > inode->size) + size = inode->size - f->pos; + + while (size) { + unsigned long base; + int copy; + + blocknr = f->pos >> 12; + if (blocknr != priv->curr_block || priv->inode != inode) { + if (blocknr) + base = CRAMFS_32 (block_ptrs[blocknr - 1]); + else + base = (CRAMFS_GET_OFFSET(inode) + (((CRAMFS_24 (inode->size)) + 4095) >> 12)) << 2; + + priv->curr_block_len = cramfs_uncompress_block (priv->buf, + (void *)(dev->map_base + base), 4096); + +// printf("READ blocknr: %d len %d\n",blocknr,priv->curr_block_len ); + if (priv->curr_block_len <= 0) + break; + + priv->curr_block = blocknr; + priv->inode = inode; + } + + copy = min(priv->curr_block_len, size); + + memcpy(buf, priv->buf + ofs, copy); + ofs = 0; + + f->pos += copy; + outsize += copy; + size -= copy; + buf += copy; + } + + return outsize; +} + +static int cramfs_stat(struct device_d *_dev, const char *filename, struct stat *stat) +{ + struct cramfs_priv *priv = _dev->priv; + struct fs_device_d *fsdev = _dev->type_data; + struct device_d *dev = fsdev->parent; + struct cramfs_inode *inode; + char *f; + unsigned long offset; + + f = strdup(filename); + offset = cramfs_resolve (dev->map_base, + CRAMFS_GET_OFFSET (&(priv->super.root)) << 2, + CRAMFS_24 (priv->super.root.size), 1, + strtok (f, "/")); + + free(f); + + if (offset < 0) + return -ENOENT; + + inode = (struct cramfs_inode *) (dev->map_base + offset); + + stat->st_mode = CRAMFS_16 (inode->mode); + stat->st_size = CRAMFS_24 (inode->size); + + return 0; +} +#if 0 +static int cramfs_info (struct device_d *dev) { if (cramfs_read_super (dev)) return 0; @@ -343,32 +408,53 @@ int cramfs_info (struct device_d *dev) return 1; } +#endif int cramfs_probe(struct device_d *dev) { struct fs_device_d *fsdev; - - printf("%s: dev: %p\n",__FUNCTION__, dev); + struct cramfs_priv *priv; fsdev = dev->type_data; - printf("%s: fsdev: %p\n",__FUNCTION__, fsdev); - if (cramfs_read_super (fsdev->parent)) { + priv = malloc(sizeof(struct cramfs_priv)); + dev->priv = priv; + + if (cramfs_read_super (fsdev->parent, priv)) { printf("no valid cramfs found on %s\n",dev->id); + free(priv); return -EINVAL; } + priv->curr_block = -1; + + cramfs_uncompress_init (); + return 0; +} + +int cramfs_remove(struct device_d *dev) +{ + struct cramfs_priv *priv = dev->priv; + + cramfs_uncompress_exit (); + free(priv); + return 0; } static struct fs_driver_d cramfs_driver = { .type = FS_TYPE_CRAMFS, + .open = cramfs_open, + .close = cramfs_close, + .read = cramfs_read, .opendir = cramfs_opendir, .readdir = cramfs_readdir, .closedir = cramfs_closedir, + .stat = cramfs_stat, .drv = { .type = DEVICE_TYPE_FS, .probe = cramfs_probe, + .remove = cramfs_remove, .name = "cramfs", .type_data = &cramfs_driver, } @@ -1,5 +1,4 @@ #include <common.h> -#include <command.h> #include <fs.h> #include <driver.h> #include <errno.h> @@ -37,11 +36,35 @@ char *mkmodestr(unsigned long mode, char *str) return str; } -struct mtab_entry { - char path[PATH_MAX]; - struct mtab_entry *next; - struct device_d *dev; -}; +/* + * - Remove all multiple slashes + * - Remove trailing slashes (except path consists of only + * a single slash) + * - TODO: illegal characters? + */ +void normalise_path(char *path) +{ + char *out = path, *in = path; + + while(*in) { + if(*in == '/') { + *out++ = *in++; + while(*in == '/') + in++; + } else { + *out++ = *in++; + } + } + + /* + * Remove trailing slash, but only if + * we were given more than a single slash + */ + if (out > path + 1 && *(out - 1) == '/') + *(out - 1) = 0; + + *out = 0; +} static struct mtab_entry *mtab; @@ -72,30 +95,149 @@ struct mtab_entry *get_mtab_entry_by_path(const char *_path) return match ? match : mtab; } +FILE files[MAX_FILES]; + +FILE *get_file(void) +{ + int i; + + for (i = 3; i < MAX_FILES; i++) { + if (!files[i].used) { + files[i].used = 1; + files[i].no = i; + memset(&files[i], 0, sizeof(FILE)); + return &files[i]; + } + } + return NULL; +} + +void put_file(FILE *f) +{ + files[f->no].used = 0; +} + +int open(const char *pathname, int flags) +{ + struct device_d *dev; + struct fs_driver_d *fsdrv; + struct mtab_entry *e; + FILE *f; + int ret; + + f = get_file(); + if (!f) { + errno = -EMFILE; + return errno; + } + + if (!strncmp(pathname, "/dev/", 5)) { + dev = get_device_by_id(pathname + 5); + f->dev = dev; + } else { + e = get_mtab_entry_by_path(pathname); + if (!e) { + errno = -ENOENT; + goto out; + } + + if (e != mtab) + pathname += strlen(e->path); + + dev = e->dev; + + fsdrv = (struct fs_driver_d *)dev->driver->type_data; + f->dev = dev; + + ret = fsdrv->open(dev, f, pathname); + if (ret) { + errno = ret; + goto out; + } + } + + return f->no; + +out: + put_file(f); + return errno; +} + +int read(int fd, void *buf, size_t count) +{ + struct device_d *dev; + struct fs_driver_d *fsdrv; + FILE *f = &files[fd]; + + dev = f->dev; + if (dev->type == DEVICE_TYPE_FS) { + fsdrv = (struct fs_driver_d *)dev->driver->type_data; + errno = fsdrv->read(dev, f, buf, count); + return errno; + } else { + errno = dev->driver->read(dev, buf, count, f->pos, 0); /* FIXME: flags */ + if (errno > 0) + f->pos += errno; + return errno; + } +} + +ssize_t write(int fd, const void *buf, size_t count) +{ + return -EROFS; +} + +int close(int fd) +{ + struct device_d *dev; + struct fs_driver_d *fsdrv; + FILE *f = &files[fd]; + + dev = f->dev; + fsdrv = (struct fs_driver_d *)dev->driver->type_data; + + put_file(f); + return fsdrv->close(dev, f); +} + int mount (struct device_d *dev, char *fsname, char *path) { struct driver_d *drv; struct fs_driver_d *fs_drv; struct mtab_entry *entry; struct fs_device_d *fsdev; + struct dir *dir; int ret; + errno = 0; + drv = get_driver_by_name(fsname); if (!drv) { - printf("no driver for fstype %s\n", fsname); - return -EINVAL; + errno = -ENODEV; + goto out; } if (drv->type != DEVICE_TYPE_FS) { - printf("driver %s is no filesystem driver\n"); - return -EINVAL; + errno = -EINVAL; + goto out; } - /* check if path exists */ - /* TODO */ + if (mtab) { + /* check if path exists and is a directory */ + if (!(dir = opendir(path))) { + errno = -ENOTDIR; + goto out; + } + closedir(dir); + } else { + /* no mtab, so we only allow to mount on '/' */ + if (*path != '/' || *(path + 1)) { + errno = -ENOTDIR; + goto out; + } + } fs_drv = drv->type_data; - printf("mount: fs_drv: %p\n", fs_drv); if (fs_drv->flags & FS_DRIVER_NO_DEV) { dev = malloc(sizeof(struct device_d)); @@ -104,12 +246,14 @@ int mount (struct device_d *dev, char *fsname, char *path) dev->type = DEVICE_TYPE_FS; if ((ret = register_device(dev))) { free(dev); - return ret; + errno = ret; + goto out; } if (!dev->driver) { /* driver didn't accept the device. Bail out */ free(dev); - return -EINVAL; + errno = -EINVAL; + goto out; } } else { fsdev = malloc(sizeof(struct fs_device_d)); @@ -120,12 +264,14 @@ int mount (struct device_d *dev, char *fsname, char *path) fsdev->dev.type_data = fsdev; if ((ret = register_device(&fsdev->dev))) { free(fsdev); - return ret; + errno = ret; + goto out; } if (!fsdev->dev.driver) { /* driver didn't accept the device. Bail out */ free(fsdev); - return -EINVAL; + errno = -EINVAL; + goto out; } dev = &fsdev->dev; } @@ -144,28 +290,38 @@ int mount (struct device_d *dev, char *fsname, char *path) e = e->next; e->next = entry; } - - printf("mount: mtab->dev: %p\n", mtab->dev); - - return 0; +out: + return errno; } -int do_mount (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int umount(const char *pathname) { - struct device_d *dev; - int ret = 0; + struct mtab_entry *entry = mtab; + struct mtab_entry *last = mtab; + char *p = strdup(pathname); + + normalise_path(p); - if (argc != 4) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; + while(entry && strcmp(p, entry->path)) { + last = entry; + entry = entry->next; } - dev = get_device_by_id(argv[1]); + free(p); - if ((ret = mount(dev, argv[2], argv[3]))) { - perror("mount", ret); - return 1; + if (!entry) { + errno = -EFAULT; + return errno; } + + if (entry == mtab) + mtab = mtab->next; + else + last->next = entry->next; + + unregister_device(entry->dev); + free(entry); + return 0; } @@ -207,20 +363,59 @@ int closedir(struct dir *dir) return dir->fsdrv->closedir(dir->dev, dir); } -static int ls(const char *path) +int stat(const char *filename, struct stat *s) +{ + struct device_d *dev; + struct fs_driver_d *fsdrv; + struct mtab_entry *e; + char *f = strdup(filename); + + memset(s, 0, sizeof(struct stat)); + + normalise_path(f); + + e = get_mtab_entry_by_path(f); + if (!e) { + errno = -ENOENT; + goto out; + } + if (e != mtab) + f += strlen(e->path); + + dev = e->dev; + + fsdrv = (struct fs_driver_d *)dev->driver->type_data; + + errno = fsdrv->stat(dev, f, s); +out: + free(f); + return errno; +} + +int ls(const char *path) { struct dir *dir; struct dirent *d; char modestr[11]; + char tmp[PATH_MAX]; + struct stat s; dir = opendir(path); - if (!dir) + if (!dir) { + errno = -ENOENT; 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); + sprintf(tmp, "%s/%s", path, d->name); + if (stat(tmp, &s)) { + perror("stat"); + return errno; + } + + mkmodestr(s.st_mode, modestr); + printf("%s %8d %*.*s\n",modestr, s.st_size, namelen, namelen, d->name); } closedir(dir); @@ -228,25 +423,6 @@ static int ls(const char *path) 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; -} - -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; @@ -254,8 +430,11 @@ int mkdir (const char *pathname) struct mtab_entry *e; e = get_mtab_entry_by_path(pathname); - if (!e) - return NULL; + if (!e) { + errno = -ENOENT; + return -ENOENT; + } + if (e != mtab) pathname += strlen(e->path); @@ -265,37 +444,8 @@ int mkdir (const char *pathname) 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; - } - - return 0; + errno = -EROFS; + return -EROFS; } -U_BOOT_CMD( - mkdir, 2, 0, do_mkdir, - "mkdir - create a new directory\n", - "" -); - -U_BOOT_CMD( - 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( - delfs, 2, 0, do_delfs, - "delfs - delete a filesystem from a device\n", - "" -); -#endif diff --git a/fs/ramfs.c b/fs/ramfs.c index 7d3d2b6735..d271b27bf9 100644 --- a/fs/ramfs.c +++ b/fs/ramfs.c @@ -8,13 +8,6 @@ #include <asm-generic/errno.h> #include <linux/stat.h> -struct handle_d { - int (*read)(struct handle_d *, ...); - int (*write)(struct handle_d *, ...); - - struct device_d *dev; -}; - struct data_d { char *data; ulong size; @@ -32,19 +25,6 @@ struct node_d { struct data_d *data; }; -struct filesystem_d { - int (*create)(struct device_d *dev, const char *pathname, mode_t mode); - struct handle_d *(*open)(struct device_d *dev, const char *pathname, mode_t mode); - int (*remove)(struct device_d *dev, const char *pathname); - int (*mknod)(struct device_d *dev, const char *pathname, struct handle_d *handle); - int (*ls)(struct device_d *dev, const char *pathname); -}; - -int create(const char *pathname, ulong mode); -struct handle_d *open(const char *pathname, ulong type); -int remove(const char *pathname); -int mknod(const char *pathname, struct handle_d *handle); - struct ramfs_priv { struct node_d root; }; @@ -88,36 +68,6 @@ out: return node; } -/* - * - Remove all multiple slashes - * - Remove trailing slashes (except path consists of only - * a single slash) - * - TODO: illegal characters? - */ -void normalise_path(char *path) -{ - char *out = path, *in = path; - - while(*in) { - if(*in == '/') { - *out++ = *in++; - while(*in == '/') - in++; - } else { - *out++ = *in++; - } - } - - /* - * Remove trailing slash, but only if - * we were given more than a single slash - */ - if (out > path + 1 && *(out - 1) == '/') - *(out - 1) = 0; - - *out = 0; -} - int node_add_child(struct node_d *node, const char *filename, ulong mode) { struct node_d *new_node = malloc(sizeof(struct node_d)); @@ -192,9 +142,9 @@ int ramfs_probe(struct device_d *dev) return 0; } -static struct handle_d *ramfs_open(struct device_d *dev, const char *pathname) +static int ramfs_open(struct device_d *_dev, FILE *file, const char *filename) { - return NULL; + return -ENOENT; } struct dir* ramfs_opendir(struct device_d *dev, const char *pathname) @@ -222,7 +172,6 @@ struct dirent* ramfs_readdir(struct device_d *dev, struct dir *dir) { if (dir->node) { strcpy(dir->d.name, dir->node->name); - dir->d.mode = dir->node->mode; dir->node = dir->node->next; return &dir->d; } @@ -235,6 +184,21 @@ int ramfs_closedir(struct device_d *dev, struct dir *dir) return 0; } +int ramfs_stat(struct device_d *dev, const char *filename, struct stat *s) +{ + struct ramfs_priv *priv = dev->priv; + struct node_d *node = rlookup(&priv->root, filename); + + if (!node) { + errno = -ENOENT; + return -ENOENT; + } + + s->st_mode = node->mode; + + return 0; +} + static struct fs_driver_d ramfs_driver = { .type = FS_TYPE_RAMFS, .create = ramfs_create, @@ -245,6 +209,7 @@ static struct fs_driver_d ramfs_driver = { .opendir = ramfs_opendir, .readdir = ramfs_readdir, .closedir = ramfs_closedir, + .stat = ramfs_stat, .flags = FS_DRIVER_NO_DEV, .drv = { @@ -262,21 +227,3 @@ int ramfs_init(void) device_initcall(ramfs_init); -/* --------- Testing --------- */ - -static int do_create ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ -// int ret; - - printf("create %s\n",argv[1]); -// ret = ramfs_create(&ramfs_device, argv[1], S_IFDIR); -// perror("create", ret); - return 0; -} - -U_BOOT_CMD( - create, 2, 0, do_create, - "ls - list a file or directory\n", - "<dev:path> list files on device" -); - |