Example #1
0
static int
unixfs_internal_namei(ino_t parentino, const char* name, struct stat* stbuf)
{
    int ret = ENOENT;
    stbuf->st_ino = 0;

    size_t namelen = strlen(name);
    if (namelen > DIRSIZ)
        return ENAMETOOLONG;

    struct inode* dp = unixfs_internal_iget(parentino);
    if (!dp)
        return ENOENT;

    if (!S_ISDIR(dp->I_mode)) {
        ret = ENOTDIR;
        goto out;
    }

    struct ar_node_info* child =
        ((struct ar_node_info*)dp->I_private)->ar_children;;

    if (!child) {
        ret = ENOENT;
        goto out;
    }

    int found = 0;

    do {
        size_t target_namelen = strlen((const char*)child->ar_name);
        if ((namelen == target_namelen) &&
                (memcmp(name, child->ar_name, target_namelen) == 0)) {
            found = 1;
            break;
        }
        child = child->ar_next_sibling;
    } while (child);

    if (found)
        ret = unixfs_internal_igetattr((ino_t)child->ar_self->I_ino, stbuf);

out:
    unixfs_internal_iput(dp);

    return ret;
}
Example #2
0
static int
unixfs_internal_namei(ino_t parentino, const char* name, struct stat* stbuf)
{
    if (parentino == OSXFUSE_ROOTINO)
        parentino = MINIX_ROOT_INO;

    stbuf->st_ino = ENOENT;

    struct inode* dir = unixfs_internal_iget(parentino);
    if (!dir)
        return ENOENT;

    if (!S_ISDIR(dir->I_mode)) {
        unixfs_internal_iput(dir);
        return ENOTDIR;
    }

    int ret = ENOENT;

    unsigned long namelen = strlen(name);
    unsigned long start, n;
    unsigned long npages = minix_dir_pages(dir);
    minix3_dirent* de3;
    minix_dirent* de;
    char page[PAGE_SIZE];
    char* kaddr = NULL;


    struct super_block* sb = dir->I_sb;
    struct minix_sb_info* sbi = minix_sb(sb);
    unsigned chunk_size = sbi->s_dirsize;
    struct minix_inode_info* minix_inode = minix_i(dir);

    start = minix_inode->i_dir_start_lookup;
    if (start >= npages)
        start = 0;
    n = start;

    ino_t found_ino = 0;

    do {
        int error = minixfs_get_page(dir, n, page);
        if (!error) {
            kaddr = (char*)page;
            if (INODE_VERSION(dir) == MINIX_V3) {
                de3 = (minix3_dirent*)kaddr;
                kaddr += PAGE_CACHE_SIZE - chunk_size;
                for (; (char*)de3 <= kaddr; de3++) {
                    if (!de3->inode)
                        continue;
                    if (minix_namecompare(namelen, chunk_size,
                                          name, de3->name)) {
                        found_ino = de3->inode;
                        goto found;
                    }
                }
            } else {
                de = (minix_dirent*)kaddr;
                kaddr += PAGE_CACHE_SIZE - chunk_size;
                for (; (char*)de <= kaddr; de++) {
                    if (!de->inode)
                        continue;
                    if (minix_namecompare(namelen, chunk_size,
                                          name, de->name)) {
                        found_ino = de->inode;
                        goto found;
                    }
                }
            }
        }

        if (++n >= npages)
            n = 0;
    } while (n != start);

found:

    if (found_ino)
        minix_inode->i_dir_start_lookup = n;

    unixfs_internal_iput(dir);

    if (found_ino)
        ret = unixfs_internal_igetattr(found_ino, stbuf);

    return ret;
}