コード例 #1
0
ファイル: sfs_inode.c プロジェクト: geraint0923/ucore_plus
static int
sfs_rename2_nolock(struct sfs_fs *sfs, struct sfs_inode *sin, const char *name, struct sfs_inode *newsin, const char *new_name) {
    uint32_t ino;
    int ret, slot1, slot2;
    if ((ret = sfs_dirent_search_nolock(sfs, sin, name, &ino, &slot1, NULL)) != 0) {
        return ret;
    }
    if ((ret = sfs_dirent_search_nolock(sfs, newsin, new_name, NULL, NULL, &slot2)) != -E_NOENT) {
        return (ret != 0) ? ret : -E_EXISTS;
    }

    struct inode *link_node;
    if ((ret = sfs_load_inode(sfs, &link_node, ino)) != 0) {
        return ret;
    }

    struct sfs_inode *lnksin = vop_info(link_node, sfs_inode);
    if ((ret = sfs_dirent_unlink_nolock(sfs, sin, slot1, lnksin)) != 0) {
        goto out;
    }

    int isdir = (lnksin->din->type == SFS_TYPE_DIR);

    /* remove '..' link from old parent */
    if (isdir) {
        sfs_nlinks_dec_nolock(sin);
    }

    /* if link fails try to recover its old link */
    if ((ret = sfs_dirent_link_nolock(sfs, newsin, slot2, lnksin, new_name)) != 0) {
        if (sfs_dirent_link_nolock_check(sfs, sin, slot1, lnksin, name) == 0) {
            if (isdir) {
                sfs_nlinks_inc_nolock(sin);
            }
        }
        goto out;
    }
    
    if (isdir) {
        /* set '..' link to new directory */
        sfs_nlinks_inc_nolock(newsin);

        /* update parent relationship */
        sfs_dirinfo_set_parent(lnksin, newsin);
    }

out:
    vop_ref_dec(link_node);
    return ret;
}
コード例 #2
0
ファイル: sfs_inode.c プロジェクト: geraint0923/ucore_plus
static int
sfs_rename1_nolock(struct sfs_fs *sfs, struct sfs_inode *sin, const char *name, const char *new_name) {
    if (strcmp(name, new_name) == 0) {
        return 0;
    }
    int ret, slot;
    uint32_t ino;
    if ((ret = sfs_dirent_search_nolock(sfs, sin, name, &ino, &slot, NULL)) != 0) {
        return ret;
    }
    if ((ret = sfs_dirent_search_nolock(sfs, sin, new_name, NULL, NULL, NULL)) != -E_NOENT) {
        return (ret != 0) ? ret : -E_EXISTS;
    }
    return sfs_dirent_write_nolock(sfs, sin, slot, ino, new_name);
}
コード例 #3
0
ファイル: sfs_inode.c プロジェクト: geraint0923/ucore_plus
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;
}
コード例 #4
0
ファイル: sfs_inode.c プロジェクト: geraint0923/ucore_plus
static int
sfs_create_nolock(struct sfs_fs *sfs, struct sfs_inode *sin, const char *name, bool excl, struct inode **node_store) {
    int ret, slot;
    uint32_t ino;
    struct inode *link_node;
    if ((ret = sfs_dirent_search_nolock(sfs, sin, name, &ino, NULL, &slot)) != -E_NOENT) {
        if (ret != 0) {
            return ret;
        }
        if (!excl) {
            if ((ret = sfs_load_inode(sfs, &link_node, ino)) != 0) {
                return ret;
            }
            if (vop_info(link_node, sfs_inode)->din->type == SFS_TYPE_FILE) {
                goto out;
            }
            vop_ref_dec(link_node);
        }
        return -E_EXISTS;
    }
    else {
        if ((ret = sfs_dirent_create_inode(sfs, SFS_TYPE_FILE, &link_node)) != 0) {
            return ret;
        }
        if ((ret = sfs_dirent_link_nolock(sfs, sin, slot, vop_info(link_node, sfs_inode), name)) != 0) {
            vop_ref_dec(link_node);
            return ret;
        }
    }

out:
    *node_store = link_node;
    return 0;
}
コード例 #5
0
ファイル: sfs_inode.c プロジェクト: geraint0923/ucore_plus
static int
sfs_link_nolock(struct sfs_fs *sfs, struct sfs_inode *sin, struct sfs_inode *lnksin, 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;
    }
    return sfs_dirent_link_nolock(sfs, sin, slot, lnksin, name);
}
コード例 #6
0
ファイル: sfs_inode.c プロジェクト: 593141477/ucore-thumips
static int
sfs_lookup_once(struct sfs_fs *sfs, struct sfs_inode *sin, const char *name, struct inode **node_store, int *slot) {
    int ret;
    uint32_t ino;
    lock_sin(sin);
    {
        ret = sfs_dirent_search_nolock(sfs, sin, name, &ino, slot, NULL);
    }
    unlock_sin(sin);
    if (ret == 0) {
        ret = sfs_load_inode(sfs, node_store, ino);
    }
    return ret;
}
コード例 #7
0
ファイル: sfs_inode.c プロジェクト: Aureate-Sunshine/ucore
/*
 * sfs_lookup_once - find inode corresponding the file name in DIR's sin inode
 * @sfs:        sfs file system
 * @sin:        DIR sfs inode in memory
 * @name:       the file name in DIR
 * @node_store: the inode corresponding the file name in DIR
 * @slot:       the logical index of file entry
 */
static int
sfs_lookup_once(struct sfs_fs *sfs, struct sfs_inode *sin, const char *name, struct inode **node_store, int *slot) {
    int ret;
    uint32_t ino;
    lock_sin(sin);
    {   // find the NO. of disk block and logical index of file entry
        ret = sfs_dirent_search_nolock(sfs, sin, name, &ino, slot, NULL);
    }
    unlock_sin(sin);
    if (ret == 0) {
		// load the content of inode with the the NO. of disk block
        ret = sfs_load_inode(sfs, node_store, ino);
    }
    return ret;
}
コード例 #8
0
ファイル: sfs_inode.c プロジェクト: geraint0923/ucore_plus
static int
sfs_unlink_nolock(struct sfs_fs *sfs, struct sfs_inode *sin, const char *name) {
    int ret, slot;
    uint32_t ino;
    if ((ret = sfs_dirent_search_nolock(sfs, sin, name, &ino, &slot, NULL)) != 0) {
        return ret;
    }
    struct inode *link_node;
    if ((ret = sfs_load_inode(sfs, &link_node, ino)) != 0) {
        return ret;
    }
    struct sfs_inode *lnksin = vop_info(link_node, sfs_inode);
    if (lnksin->din->type != SFS_TYPE_DIR) {
        ret = sfs_dirent_unlink_nolock(sfs, sin, slot, lnksin);
    }
    else {
        if ((ret = trylock_sin(lnksin)) == 0) {
            if (lnksin->din->dirinfo.slots != 0) {
                ret = -E_NOTEMPTY;
            }
            else if ((ret = sfs_dirent_unlink_nolock(sfs, sin, slot, lnksin)) == 0) {
                /* lnksin must be empty, so set SFS_removed bit to invalidate further trylock opts */
                SetSFSInodeRemoved(lnksin);

                /* remove '.' link */
                sfs_nlinks_dec_nolock(lnksin);

                /* remove '..' link */
                sfs_nlinks_dec_nolock(sin);
            }
            unlock_sin(lnksin);
        }
    }
    vop_ref_dec(link_node);
    return ret;
}
コード例 #9
0
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;
}