Ejemplo n.º 1
0
static int
sfs_dirent_create_inode(struct sfs_fs *sfs, uint16_t type, struct inode **node_store) {
    struct sfs_disk_inode *din;
    if ((din = kmalloc(sizeof(struct sfs_disk_inode))) == NULL) {
        return -E_NO_MEM;
    }
    memset(din, 0, sizeof(struct sfs_disk_inode));
    din->type = type;

    int ret;
    uint32_t ino;
    if ((ret = sfs_block_alloc(sfs, &ino)) != 0) {
        goto failed_cleanup_din;
    }
    struct inode *node;
    if ((ret = sfs_create_inode(sfs, din, ino, &node)) != 0) {
        goto failed_cleanup_ino;
    }
    lock_sfs_fs(sfs);
    {
        sfs_set_links(sfs, vop_info(node, sfs_inode));
    }
    unlock_sfs_fs(sfs);
    *node_store = node;
    return 0;

failed_cleanup_ino:
    sfs_block_free(sfs, ino);
failed_cleanup_din:
    kfree(din);
    return ret;
}
int
sfs_load_inode(struct sfs_fs *sfs, struct inode **node_store, uint32_t ino) {
    // while (1);
    lock_sfs_fs(sfs);
    struct inode *node;
    if ((node = lookup_sfs_nolock(sfs, ino)) != NULL) {
        goto out_unlock;
    }

    int ret = -E_NO_MEM;
    struct sfs_disk_inode *din;
    if ((din = kmalloc(sizeof(struct sfs_disk_inode))) == NULL) {
        goto failed_unlock;
    }

    // kprintf("in %s: ino is %d\n", __func__, ino);
    // while (1);

    // kprintf("%s\n", __func__);
    assert(sfs_block_inuse(sfs, ino));
    if ((ret = sfs_rbuf(sfs, din, sizeof(struct sfs_disk_inode), ino, 0)) != 0) {
        goto failed_cleanup_din;
    }

    assert(_SFS_INODE_GET_NLINKS(din) != 0);
    if ((ret = sfs_create_inode(sfs, din, ino, &node)) != 0) {
        goto failed_cleanup_din;
    }
    sfs_set_links(sfs, vop_info(node, sfs_inode));

out_unlock:
    unlock_sfs_fs(sfs);
    *node_store = node;
    return 0;

failed_cleanup_din:
    kfree(din);
failed_unlock:
    unlock_sfs_fs(sfs);
    return ret;
}
Ejemplo n.º 3
0
/*
 * sfs_load_inode - If the inode isn't existed, load inode related ino disk block data into a new created inode.
 *                  If the inode is in memory alreadily, then do nothing
 */
int
sfs_load_inode(struct sfs_fs *sfs, struct inode **node_store, uint32_t ino) {
    lock_sfs_fs(sfs);
    struct inode *node;
    if ((node = lookup_sfs_nolock(sfs, ino)) != NULL) {
        goto out_unlock;
    }

    int ret = -E_NO_MEM;
    struct sfs_disk_inode *din;
    if ((din = kmalloc(sizeof(struct sfs_disk_inode))) == NULL) {
        goto failed_unlock;
    }

    assert(sfs_block_inuse(sfs, ino));
    if ((ret = sfs_rbuf(sfs, din, sizeof(struct sfs_disk_inode), ino, 0)) != 0) {
        goto failed_cleanup_din;
    }

    assert(din->nlinks != 0);
    if ((ret = sfs_create_inode(sfs, din, ino, &node)) != 0) {
        goto failed_cleanup_din;
    }
    sfs_set_links(sfs, vop_info(node, sfs_inode));

out_unlock:
    unlock_sfs_fs(sfs);
    *node_store = node;
    return 0;

failed_cleanup_din:
    kfree(din);
failed_unlock:
    unlock_sfs_fs(sfs);
    return ret;
}
static int
sfs_create(struct inode *node, const char *name, bool excl, struct inode **node_store) {
    // kprintf("ready to create a file\n");
    if (strlen(name) > SFS_MAX_FNAME_LEN) {
        return -1;
    }
    // sfs_create_inode(struct sfs_fs *sfs, struct sfs_disk_inode *din, uint32_t ino, struct inode **node_store)
    struct sfs_fs *sfs = fsop_info(vop_fs(node), sfs);
    struct sfs_inode *sin = vop_info(node, sfs_inode);
    int ret;
    // sfs_create_inode(struct sfs_fs *sfs, struct sfs_disk_inode *din, uint32_t ino, struct inode **node_store)
    struct inode *node_tmp = NULL;
    int empty_slot = -1;
    lock_sfs_fs(sfs);
    // sfs_block_alloc(struct sfs_fs *sfs, uint32_t *ino_store)
    sfs_dirent_search_nolock(sfs, sin, name, node_tmp, NULL, &empty_slot);
    // kprintf("%s\n", __func__);
    if (node_tmp) {
        node_store = node_tmp;
    } else {
        if (empty_slot < 0) {
            kprintf("no slot\n");
            return -1;
        }
        struct sfs_disk_inode *din = alloc_disk_inode(SFS_TYPE_FILE);
        int ino;
        sfs_block_alloc(sfs, &ino);
        // kprintf("%s\n", __func__);
        // if (sfs_block_inuse(sfs, ino)) {
        //     kprintf("be sure use\n");
        // } else {
        //     kprintf("not used\n");
        // }
        sfs_create_inode(sfs, din, ino, &node_tmp);
        ++ (din->__nlinks__);
        sfs_set_links(sfs, vop_info(node_tmp, sfs_inode));
        // kprintf("0x%08x\n", node_tmp);
        // sfs_namefile(struct inode *node, struct iobuf *iob)
        // sfs_dirent_write_nolock(struct sfs_fs *sfs, struct sfs_inode *sin, int slot, uint32_t ino, const char *name)
        sfs_dirent_write_nolock(sfs, sin, empty_slot, ino, name);
        // ++ sin->din->blocks;
        int secno = ram2block(ino);
        swapper_block_changed(secno);
        swapper_block_late_sync(secno);
        // kprintf("sin->ino is %d\n", sin->ino);
        sin->dirty = 1;
        lock_sin(sin);
        {
            if (sin->dirty) {
                sin->dirty = 0;
                if ((ret = sfs_wbuf(sfs, sin->din, sizeof(struct sfs_disk_inode), sin->ino, 0)) != 0) {
                    sin->dirty = 1;
                }
            }
        }
        unlock_sin(sin);
        secno = ram2block(sin->ino);
        swapper_block_changed(secno);
        swapper_block_late_sync(secno);
        vop_info(node_tmp, sfs_inode)->dirty = 1;
        sfs->super_dirty = 1;
        // if ((ret = sfs_bmap_load_nolock(sfs, sin, slot, &ino)) != 0) {
        //     return ret;
        // }
        // assert(sfs_block_inuse(sfs, ino));
        // kprintf("ino is %d\n", ino);
        // kprintf("empty slot is %d\n", empty_slot);
        // kprintf("father ino is %d\n", sin->ino);
        *node_store = node_tmp;
    }
    unlock_sfs_fs(sfs);
    // sfs_create_inode(sfs, struct sfs_disk_inode *din, uint32_t ino, struct inode **node_store)
    return 0;
}