9
0
Fork 0

svn_rev_268

WIP
This commit is contained in:
Sascha Hauer 2007-07-05 18:01:38 +02:00 committed by Sascha Hauer
parent 5c1f086941
commit cf7a56fc78
14 changed files with 514 additions and 276 deletions

View File

@ -90,3 +90,6 @@ obj-y += mtdpart.o
obj-y += env.o
obj-y += startup.o
obj-y += misc.o
obj-y += cmd_fs.o

View File

@ -51,7 +51,7 @@ int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 1;
}
erase(mem.device, mem.size, mem.start);
dev_erase(mem.device, mem.size, mem.start);
return 0;
}

View File

@ -131,9 +131,9 @@ int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
do {
now = min(RW_BUF_SIZE, nbytes);
r = read(mem.device, rw_buf, now, offs, RW_SIZE(size));
r = dev_read(mem.device, rw_buf, now, offs, RW_SIZE(size));
if (r <= 0) {
perror("read", r);
perror("read");
return r;
}
@ -184,7 +184,7 @@ int do_mem_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
count = size;
if (count == size) {
return write(mem.device, (uchar *)&writeval, count, mem.start, RW_SIZE(size));
return dev_write(mem.device, (uchar *)&writeval, count, mem.start, RW_SIZE(size));
} else {
printf("write multiple not yet implemented\n");
}
@ -300,11 +300,11 @@ int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
while (count > 0) {
now = min(RW_BUF_SIZE, count);
ret = read(src.device, rw_buf, now, src.start + offset, RW_SIZE(size));
ret = dev_read(src.device, rw_buf, now, src.start + offset, RW_SIZE(size));
if (ret <= 0)
return ret;
ret = write(dst.device, rw_buf, ret, dst.start + offset, RW_SIZE(size));
ret = dev_write(dst.device, rw_buf, ret, dst.start + offset, RW_SIZE(size));
if (ret <= 0)
return ret;
if (ret < now)
@ -432,14 +432,19 @@ static void memcpy_sz(void *_dst, void *_src, ulong count, ulong rwsize)
ssize_t mem_read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong rwflags)
{
memcpy_sz(buf, (void *)(dev->map_base + offset), count, rwflags & RW_SIZE_MASK);
return count;
ulong size;
size = min(count, dev->size - offset);
printf("mem_read: dev->map_base: %p size: %d offset: %d\n",dev->map_base, size, offset);
memcpy_sz(buf, (void *)(dev->map_base + offset), size, rwflags & RW_SIZE_MASK);
return size;
}
ssize_t mem_write(struct device_d *dev, void *buf, size_t count, ulong offset, ulong rwflags)
{
memcpy_sz((void *)(dev->map_base + offset), buf, count, rwflags & RW_SIZE_MASK);
return count;
ulong size;
size = min(count, dev->size - offset);
memcpy_sz((void *)(dev->map_base + offset), buf, size, rwflags & RW_SIZE_MASK);
return size;
}
static struct device_d mem_dev = {

View File

@ -123,7 +123,7 @@ int add_env_spec(char *spec)
env_list->next = NULL;
err = read(info.device, env, env_size, info.start, 0);
err = dev_read(info.device, env, env_size, info.start, 0);
if (err != env_size)
goto err_out;
@ -206,13 +206,13 @@ int saveenv(void)
*(ulong *)env = crc32(0, env + sizeof(ulong), env_size - sizeof(ulong));
ret = erase(info.device, info.size, info.start);
ret = dev_erase(info.device, info.size, info.start);
if (ret) {
printf("unable to erase\n");
goto err_out;
}
ret = write(info.device, env, info.size, info.start, 0);
ret = dev_write(info.device, env, info.size, info.start, 0);
if (ret < 0) {
printf("unable to write\n");
goto err_out;

View File

@ -196,14 +196,14 @@ ssize_t part_read(struct device_d *dev, void *buf, size_t count, unsigned long o
{
struct partition *part = dev->platform_data;
return read(part->parent, buf, count, offset + part->offset, flags);
return dev_read(part->parent, buf, count, offset + part->offset, flags);
}
ssize_t part_write(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags)
{
struct partition *part = dev->platform_data;
return write(part->parent, buf, count, offset + part->offset, flags);
return dev_write(part->parent, buf, count, offset + part->offset, flags);
}
struct driver_d part_driver = {

View File

@ -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,
}

324
fs/fs.c
View File

@ -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);
if (argc != 4) {
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
normalise_path(p);
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);
errno = -EROFS;
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;
}
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

View File

@ -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"
);

View File

@ -593,7 +593,7 @@ void vprintf(const char *fmt, va_list args);
#define stdin 0
#define stdout 1
#define stderr 2
#define MAX_FILES 3
#define MAX_FILES 16
void fprintf(int file, const char *fmt, ...);
void fputs(int file, const char *s);

View File

@ -48,6 +48,7 @@ struct driver_d {
struct driver_d *next;
int (*probe) (struct device_d *);
int (*remove)(struct device_d *);
ssize_t (*read) (struct device_d*, void* buf, size_t count, ulong offset, ulong flags);
ssize_t (*write) (struct device_d*, void* buf, size_t count, ulong offset, ulong flags);
ssize_t (*erase) (struct device_d*, size_t count, unsigned long offset);
@ -74,13 +75,13 @@ void unregister_device(struct device_d *);
struct device_d *device_from_spec_str(const char *str, char **endp);
struct device_d *get_device_by_name(char *name);
struct device_d *get_device_by_type(ulong type, struct device_d *last);
struct device_d *get_device_by_id(char *id);
struct device_d *get_device_by_id(const char *id);
struct driver_d *get_driver_by_name(char *name);
ssize_t read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
ssize_t write(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
ssize_t erase(struct device_d *dev, size_t count, unsigned long offset);
ssize_t dev_read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
ssize_t dev_write(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
ssize_t dev_erase(struct device_d *dev, size_t count, unsigned long offset);
ssize_t mem_read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
ssize_t mem_write(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);

View File

@ -1,6 +1,8 @@
#ifndef __ERRNO_H
#define __ERRNO_H
void perror(const char *s, int errno);
extern int errno;
void perror(const char *s);
#endif /* __ERRNO_H */

View File

@ -10,10 +10,9 @@
struct partition;
struct node_d;
struct stat;
struct dirent {
unsigned long mode;
unsigned long size;
char name[256];
};
@ -25,20 +24,32 @@ struct dir {
void *priv; /* private data for the fs driver */
};
typedef struct filep {
struct device_d *dev;
ulong pos;
char used;
int no;
void *inode; /* private to the filesystem driver */
} FILE;
#define FS_DRIVER_NO_DEV 1
struct fs_driver_d {
ulong type;
char *name;
int (*load) (char *dst, struct device_d *dev, const char *filename);
int (*probe) (struct device_d *dev);
int (*create)(struct device_d *dev, const char *pathname, ulong type);
int (*mkdir)(struct device_d *dev, const char *pathname);
struct handle_d *(*open)(struct device_d *dev, const char *pathname);
int (*open)(struct device_d *dev, FILE *f, const char *pathname);
int (*close)(struct device_d *dev, FILE *f);
int (*read)(struct device_d *dev, FILE *f, void *buf, size_t size);
int (*write)(struct device_d *dev, FILE *f, void *buf, size_t size);
struct dir* (*opendir)(struct device_d *dev, const char *pathname);
struct dirent* (*readdir)(struct device_d *dev, struct dir *dir);
int (*closedir)(struct device_d *dev, struct dir *dir);
int (*stat)(struct device_d *dev, const char *file, struct stat *stat);
struct driver_d drv;
@ -52,11 +63,29 @@ struct fs_device_d {
struct fs_driver_d *driver;
};
int register_filesystem(struct device_d *dev, char *fsname);
//int unregister_filesystem(struct device_d *dev);
int open(const char *pathname, int flags);
int close(int fd);
int read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
int ls(const char *path);
int mkdir (const char *pathname);
int mount (struct device_d *dev, char *fsname, char *path);
int umount(const char *pathname);
int register_fs_driver(struct fs_driver_d *new_fs_drv);
struct dir *opendir(const char *pathname);
struct dirent *readdir(struct dir *dir);
int closedir(struct dir *dir);
char *mkmodestr(unsigned long mode, char *str);
struct mtab_entry *get_mtab_entry_by_path(const char *path);
struct mtab_entry {
char path[PATH_MAX];
struct mtab_entry *next;
struct device_d *dev;
};
void normalise_path(char *path);
#endif /* __FS_H */

View File

@ -5,6 +5,7 @@
#include <init.h>
#include <malloc.h>
#include <linux/ctype.h>
#include <errno.h>
#include <asm-generic/errno.h>
int cmd_get_data_size(char* arg, int default_size)
@ -32,7 +33,7 @@ int cmd_get_data_size(char* arg, int default_size)
static struct device_d *first_device = NULL;
static struct driver_d *first_driver = NULL;
struct device_d *get_device_by_id(char *id)
struct device_d *get_device_by_id(const char *id)
{
struct device_d *d;
@ -357,25 +358,28 @@ out:
return 0;
}
ssize_t read(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags)
ssize_t dev_read(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags)
{
if (dev->driver->read)
return dev->driver->read(dev, buf, count, offset, flags);
return -1;
errno = -ENOSYS;
return -ENOSYS;
}
ssize_t write(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags)
ssize_t dev_write(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags)
{
if (dev->driver->write)
return dev->driver->write(dev, buf, count, offset, flags);
return -1;
errno = -ENOSYS;
return -ENOSYS;
}
ssize_t erase(struct device_d *dev, size_t count, unsigned long offset)
ssize_t dev_erase(struct device_d *dev, size_t count, unsigned long offset)
{
if (dev->driver->erase)
return dev->driver->erase(dev, count, offset);
return -1;
errno = -ENOSYS;
return -ENOSYS;
}
int dummy_probe(struct device_d *dev)
@ -414,7 +418,12 @@ struct param_d* dev_get_param(struct device_d *dev, char *name)
{
struct param_d *param = get_param_by_name(dev, name);
if (param && param->get)
if (!param) {
errno = -EINVAL;
return NULL;
}
if (param->get)
return param->get(dev, param);
return param;
@ -424,8 +433,10 @@ IPaddr_t dev_get_param_ip(struct device_d *dev, char *name)
{
struct param_d *param = dev_get_param(dev, name);
if (!param || param->type != PARAM_TYPE_IPADDR)
return -1;
if (!param || param->type != PARAM_TYPE_IPADDR) {
errno = -EINVAL;
return 0;
}
return param->value.val_ip;
}
@ -443,11 +454,15 @@ int dev_set_param(struct device_d *dev, char *name, value_t val)
{
struct param_d *param = get_param_by_name(dev, name);
if (!param)
if (!param) {
errno = -EINVAL;
return -EINVAL;
}
if (param->flags & PARAM_FLAG_RO)
if (param->flags & PARAM_FLAG_RO) {
errno = -EACCES;
return -EACCES;
}
if (param->set)
return param->set(dev, param, val);

View File

@ -65,7 +65,7 @@ store_block (unsigned block, uchar * src, unsigned len)
ulong offset = block * TFTP_BLOCK_SIZE + TftpBlockWrapOffset;
ulong newsize = offset + len;
write(net_store_mem.device, src, len, net_store_mem.start + offset, 0);
dev_write(net_store_mem.device, src, len, net_store_mem.start + offset, 0);
if (NetBootFileXferSize < newsize)
NetBootFileXferSize = newsize;