Ejemplo n.º 1
0
static int
sfs_mkdir_nolock(struct sfs_fs *sfs, struct sfs_inode *sin, const char *name) {
    int ret, slot;
    if ((ret = sfs_dirent_search_nolock(sfs, sin, name, NULL, NULL, &slot)) != -E_NOENT) {
        return (ret != 0) ? ret : -E_EXISTS;
    }
    struct inode *link_node;
    if ((ret = sfs_dirent_create_inode(sfs, SFS_TYPE_DIR, &link_node)) != 0) {
        return ret;
    }
    struct sfs_inode *lnksin = vop_info(link_node, sfs_inode);
    if ((ret = sfs_dirent_link_nolock(sfs, sin, slot, lnksin, name)) != 0) {
        assert(lnksin->din->nlinks == 0);
        assert(inode_ref_count(link_node) == 1 && inode_open_count(link_node) == 0);
        goto out;
    }

    /* set parent */
    sfs_dirinfo_set_parent(lnksin, sin);

    /* add '.' link to itself */
    sfs_nlinks_inc_nolock(lnksin);

    /* add '..' link to parent */
    sfs_nlinks_inc_nolock(sin);

out:
    vop_ref_dec(link_node);
    return ret;
}
Ejemplo n.º 2
0
/* *
 * inode_check - check the various things being valid
 * called before all vop_* calls
 * */
void
inode_check(struct inode *node, const char *opstr) {
    assert(node != NULL && node->in_ops != NULL);
    assert(node->in_ops->vop_magic == VOP_MAGIC);
    int ref_count = inode_ref_count(node), open_count = inode_open_count(node);
    assert(ref_count >= open_count && open_count >= 0);
    assert(ref_count < MAX_INODE_COUNT && open_count < MAX_INODE_COUNT);
}
Ejemplo n.º 3
0
/* *
 * inode_open_dec - decrement the open_count
 * invoked by vop_open_dec
 * calls vop_close if the open_count hits zero
 * */
int
inode_open_dec(struct inode *node) {
    assert(inode_open_count(node) > 0);
    int open_count, ret;
    if ((open_count = atomic_sub_return(&(node->open_count), 1)) == 0) {
        if ((ret = vop_close(node)) != 0) {
            kprintf("vfs: warning: vop_close: %e.\n", ret);
        }
    }
    return open_count;
}
Ejemplo n.º 4
0
static int
sfs_reclaim(struct inode *node) {
    struct sfs_fs *sfs = fsop_info(vop_fs(node), sfs);
    struct sfs_inode *sin = vop_info(node, sfs_inode);

    lock_sfs_fs(sfs);

    int ret = -E_BUSY;
    assert(sin->reclaim_count > 0);
    if ((-- sin->reclaim_count) != 0) {
        goto failed_unlock;
    }
    assert(inode_ref_count(node) == 0 && inode_open_count(node) == 0);

    if (sin->din->nlinks == 0) {
        uint32_t nblks;
        for (nblks = sin->din->blocks; nblks != 0; nblks --) {
            sfs_bmap_truncate_nolock(sfs, sin);
        }
    }
    else if (sin->dirty) {
        if ((ret = vop_fsync(node)) != 0) {
            goto failed_unlock;
        }
    }
    
    sfs_remove_links(sin);
    unlock_sfs_fs(sfs);

    if (sin->din->nlinks == 0) {
        sfs_block_free(sfs, sin->ino);
        uint32_t ent;
        if ((ent = sin->din->indirect) != 0) {
            sfs_block_free(sfs, ent);
        }
        if ((ent = sin->din->db_indirect) != 0) {
            int i;
            for (i = 0; i < SFS_BLK_NENTRY; i ++) {
                sfs_bmap_free_sub_nolock(sfs, ent, i);
            }
            sfs_block_free(sfs, ent);
        }
    }
    kfree(sin->din);
    vop_kill(node);
    return 0;

failed_unlock:
    unlock_sfs_fs(sfs);
    return ret;
}
Ejemplo n.º 5
0
/* *
 * inode_kill - kill a inode structure
 * invoked by vop_kill
 * */
void
inode_kill(struct inode *node) {
    assert(inode_ref_count(node) == 0);
    assert(inode_open_count(node) == 0);
    kfree(node);
}