Exemplo n.º 1
0
static int
ramfs_unlink(vnode_t *dir, const char *name, size_t namelen)
{
        vnode_t *vn;
        int ret;
        off_t i;
        ramfs_dirent_t *entry;

        ret = ramfs_lookup(dir, name, namelen, &vn);
        KASSERT(0 == ret);
        KASSERT(!S_ISDIR(vn->vn_mode));

        /* And then remove the entry from the directory */
        entry = VNODE_TO_DIRENT(dir);
        for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) {
                if (name_match(entry->rd_name, name, namelen)) {
                        entry->rd_name[0] = '\0';
                        break;
                }
        }

        VNODE_TO_RAMFSINODE(dir)->rf_size -= sizeof(ramfs_dirent_t);

        VNODE_TO_RAMFSINODE(vn)->rf_linkcount--;
        vput(vn);

        return 0;
}
Exemplo n.º 2
0
static int
ramfs_link(vnode_t *oldvnode, vnode_t *dir,
           const char *name, size_t name_len)
{
        vnode_t *vn;
        off_t i;
        ramfs_dirent_t *entry;

        KASSERT(oldvnode->vn_fs == dir->vn_fs);
        KASSERT(0 != ramfs_lookup(dir, name, name_len, &vn));

        /* Look for space in the directory */
        entry = VNODE_TO_DIRENT(dir);
        for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) {
                if (!entry->rd_name[0])
                        break;
        }

        if (i == RAMFS_MAX_DIRENT) {
                return -ENOSPC;
        }

        /* Set entry in parent */
        entry->rd_ino = oldvnode->vn_vno;
        strncpy(entry->rd_name, name, MIN(name_len, NAME_LEN - 1));
        entry->rd_name[MIN(name_len, NAME_LEN - 1)] = '\0';

        VNODE_TO_RAMFSINODE(dir)->rf_size += sizeof(ramfs_dirent_t);

        /* Increase linkcount */
        VNODE_TO_RAMFSINODE(oldvnode)->rf_linkcount++;
        return 0;
}
Exemplo n.º 3
0
static int
ramfs_rmdir(vnode_t *dir, const char *name, size_t name_len)
{
        vnode_t *vn;
        int ret;
        off_t i;
        ramfs_dirent_t *entry;

        KASSERT(!name_match(".", name, name_len) &&
                !name_match("..", name, name_len));

        if ((ret = ramfs_lookup(dir, name, name_len, &vn)) != 0)
                return ret;

        if (!S_ISDIR(vn->vn_mode)) {
                vput(vn);
                return -ENOTDIR;
        }

        /* We have to make sure that this directory is empty */
        entry = VNODE_TO_DIRENT(vn);
        for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) {
                if (!strcmp(entry->rd_name, ".") ||
                    !strcmp(entry->rd_name, ".."))
                        continue;

                if (entry->rd_name[0]) {
                        vput(vn);
                        return -ENOTEMPTY;
                }
        }

        /* Finally, remove the entry from the parent directory */
        entry = VNODE_TO_DIRENT(dir);
        for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) {
                if (name_match(entry->rd_name, name, name_len)) {
                        entry->rd_name[0] = '\0';
                        break;
                }
        }
        VNODE_TO_RAMFSINODE(dir)->rf_size -= sizeof(ramfs_dirent_t);

        VNODE_TO_RAMFSINODE(vn)->rf_linkcount--;
        vput(vn);

        return 0;
}
Exemplo n.º 4
0
static int
ramfs_mkdir(vnode_t *dir, const char *name, size_t name_len)
{
        vnode_t *vn;
        off_t i;
        ramfs_dirent_t *entry;
	
	 dbg(DBG_INIT,"RAMFS_MKDIR before KASSERT %s\n",name);
        KASSERT(0 != ramfs_lookup(dir, name, name_len, &vn));

        /* Look for space in the directory */
        entry = VNODE_TO_DIRENT(dir);
        for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) {
                if (!entry->rd_name[0])
                        break;
        }

        if (i == RAMFS_MAX_DIRENT) {
                return -ENOSPC;
        }

        /* Allocate an inode */
        int ino;
        if (0 > (ino = ramfs_alloc_inode(dir->vn_fs, RAMFS_TYPE_DIR, 0))) {
                return ino;
        }

        /* Set entry in parent */
        entry->rd_ino = ino;
        strncpy(entry->rd_name, name, MIN(name_len, NAME_LEN - 1));
        entry->rd_name[MIN(name_len, NAME_LEN - 1)] = '\0';

        VNODE_TO_RAMFSINODE(dir)->rf_size += sizeof(ramfs_dirent_t);

        /* Set up '.' and '..' in the directory */
        entry = (ramfs_dirent_t *) VNODE_TO_RAMFS(dir)->rfs_inodes[ino]->rf_mem;
        entry->rd_ino = ino;
        strcpy(entry->rd_name, ".");
        entry++;
        entry->rd_ino = dir->vn_vno;
        strcpy(entry->rd_name, "..");

        /* Increase inode size accordingly */
        VNODE_TO_RAMFS(dir)->rfs_inodes[ino]->rf_size = 2 * sizeof(ramfs_dirent_t);

        return 0;
}
Exemplo n.º 5
0
static int
ramfs_mknod(struct vnode *dir, const char *name, size_t name_len, int mode, devid_t devid)
{
        vnode_t *vn;
        off_t i;
        ramfs_dirent_t *entry;

        KASSERT(0 != ramfs_lookup(dir, name, name_len, &vn));

        /* Look for space in the directory */
        entry = VNODE_TO_DIRENT(dir);
        for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) {
                if (!entry->rd_name[0])
                        break;
        }

        if (i == RAMFS_MAX_DIRENT) {
                return -ENOSPC;
        }

        int ino;
        if (S_ISCHR(mode)) {
                if (0 > (ino = ramfs_alloc_inode(dir->vn_fs, RAMFS_TYPE_CHR, devid))) {
                        return ino;
                }
        } else if (S_ISBLK(mode)) {
                if (0 > (ino = ramfs_alloc_inode(dir->vn_fs, RAMFS_TYPE_BLK, devid))) {
                        return ino;
                }
        } else {
                panic("Invalid mode!\n");
        }

        /* Set entry in directory */
        entry->rd_ino = ino;
        strncpy(entry->rd_name, name, MIN(name_len, NAME_LEN - 1));
        entry->rd_name[MIN(name_len, NAME_LEN - 1)] = '\0';

        VNODE_TO_RAMFSINODE(dir)->rf_size += sizeof(ramfs_dirent_t);

        return 0;
}
Exemplo n.º 6
0
static int
ramfs_create(vnode_t *dir, const char *name, size_t name_len, vnode_t **result)
{
        vnode_t *vn;
        off_t i;
        ramfs_dirent_t *entry;

        KASSERT(0 != ramfs_lookup(dir, name, name_len, &vn));

        /* Look for space in the directory */
        entry = VNODE_TO_DIRENT(dir);
        for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) {
                if (!entry->rd_name[0])
                        break;
        }

        if (i == RAMFS_MAX_DIRENT) {
                return -ENOSPC;
        }

        /* Allocate an inode */
        int ino;
        if (0 > (ino = ramfs_alloc_inode(dir->vn_fs, RAMFS_TYPE_DATA, 0))) {
                return ino;
        }

        /* Get a vnode, set entry in directory */
        vn = vget(dir->vn_fs, (ino_t) ino);

        entry->rd_ino = vn->vn_vno;
        strncpy(entry->rd_name, name, MIN(name_len, NAME_LEN - 1));
        entry->rd_name[MIN(name_len, NAME_LEN - 1)] = '\0';

        VNODE_TO_RAMFSINODE(dir)->rf_size += sizeof(ramfs_dirent_t);

        *result = vn;

        return 0;
}
Exemplo n.º 7
0
static errval_t write_file(struct dirent *root, const char *path, uint8_t *data,
                           size_t len)
{
    errval_t err;

    assert(path != NULL);
    assert(root != NULL);

    // walk path, creating/locating directories as we go
    struct dirent *d = root;
    while (true) {
        // remove any leading /
        while (path[0] == '/') {
            path++;
        }

        char *nextsep = strchr(path, '/');

        // no more /, we have the filename
        if (nextsep == NULL) {
            break;
        }

        // extract dirname, advance path
        size_t namelen = nextsep - path;
        char *dirname = malloc(namelen + 1);
        assert(dirname != NULL);
        memcpy(dirname, path, namelen);
        dirname[namelen] = '\0';
        path += namelen;

        // does this directory exist?
        struct dirent *next;
        err = ramfs_lookup(d, dirname, &next);
        if (err_is_ok(err)) {
            free(dirname);
            d = next;
            continue;
        } else if (err_no(err) != FS_ERR_NOTFOUND) {
            free(dirname);
            return err;
        }

        // create the directory
        err = ramfs_mkdir(d, dirname, &next);
        if (err_is_fail(err)) {
            free(dirname);
            return err;
        }
        d = next;
    }

    // create the file!
    struct dirent *f;
    char *path_copy = strdup(path);
    assert(path_copy != NULL);
    err = ramfs_create(d, path_copy, &f);
    if (err_is_fail(err)) {
        free(path_copy);
        return err;
    }

    // allocate storage
    uint8_t *buf;
    err = ramfs_grow(f, 0, len, &buf);
    if (err_is_fail(err)) {
        ramfs_delete(f);
        return err;
    }

    // copy the payload
    memcpy(buf, data, len);

    return SYS_ERR_OK;
}