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; }
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; }