FreeBSD/sys/fs/tmpfs/tmpfs_subr.c
/* Lookup directory entry by cookie, initialize directory cursor accordingly. */
Lookup directory entry by cookie, initialize directory cursor accordingly.
Lookup directory entry by cookie initialize directory cursor accordingly .
static struct tmpfs_dirent *
tmpfs_dir_lookup_cookie(struct tmpfs_node *node, off_t cookie,
    struct tmpfs_dir_cursor *dc)
{
	struct tmpfs_dir *dirhead = &node->tn_dir.tn_dirhead;
	struct tmpfs_dirent *de, dekey;
	MPASS(cookie >= TMPFS_DIRCOOKIE_MIN);
	if (cookie == node->tn_dir.tn_readdir_lastn &&
	    (de = node->tn_dir.tn_readdir_lastp) != NULL) {
		if (cookie == tmpfs_dirent_cookie(de))
			goto out;
	}
	if ((cookie & TMPFS_DIRCOOKIE_DUP) != 0) {
		LIST_FOREACH(de, &node->tn_dir.tn_dupindex,
		    uh.td_dup.index_entries) {
			MPASS(tmpfs_dirent_dup(de));
			if (de->td_cookie == cookie)
				goto out;
			if (de->td_cookie < cookie) {
				de = NULL;
				goto out;
			}
		}
		MPASS(de == NULL);
		goto out;
	}
	MPASS((cookie & TMPFS_DIRCOOKIE_MASK) == cookie);
	dekey.td_hash = cookie;
	de = RB_NFIND(tmpfs_dir, dirhead, &dekey);
	dc->tdc_tree = de;
	dc->tdc_current = de;
	if (de != NULL && tmpfs_dirent_duphead(de)) {
		dc->tdc_current = LIST_FIRST(&de->ud.td_duphead);
		MPASS(dc->tdc_current != NULL);
	}
	return (dc->tdc_current);
out:
	dc->tdc_tree = de;
	dc->tdc_current = de;
	if (de != NULL && tmpfs_dirent_dup(de))
		dc->tdc_tree = tmpfs_dir_xlookup_hash(node,
		    de->td_hash);
	return (dc->tdc_current);
}
static struct tmpfs_dirent * tmpfs_dir_lookup_cookie ( struct tmpfs_node * node , off_t cookie , struct tmpfs_dir_cursor * dc ) { struct tmpfs_dir * dirhead = & node -> tn_dir . tn_dirhead ; struct tmpfs_dirent * de , dekey ; MPASS ( cookie >= TMPFS_DIRCOOKIE_MIN ) ; if ( cookie == node -> tn_dir . tn_readdir_lastn && ( de = node -> tn_dir . tn_readdir_lastp ) != NULL ) { if ( cookie == tmpfs_dirent_cookie ( de ) ) goto out ; } if ( ( cookie & TMPFS_DIRCOOKIE_DUP ) != 0 ) { LIST_FOREACH ( de , & node -> tn_dir . tn_dupindex , uh . td_dup . index_entries ) { MPASS ( tmpfs_dirent_dup ( de ) ) ; if ( de -> td_cookie == cookie ) goto out ; if ( de -> td_cookie < cookie ) { de = NULL ; goto out ; } } MPASS ( de == NULL ) ; goto out ; } MPASS ( ( cookie & TMPFS_DIRCOOKIE_MASK ) == cookie ) ; dekey . td_hash = cookie ; de = RB_NFIND ( tmpfs_dir , dirhead , & dekey ) ; dc -> tdc_tree = de ; dc -> tdc_current = de ; if ( de != NULL && tmpfs_dirent_duphead ( de ) ) { dc -> tdc_current = LIST_FIRST ( & de -> ud . td_duphead ) ; MPASS ( dc -> tdc_current != NULL ) ; } return ( dc -> tdc_current ) ; out : dc -> tdc_tree = de ; dc -> tdc_current = de ; if ( de != NULL && tmpfs_dirent_dup ( de ) ) dc -> tdc_tree = tmpfs_dir_xlookup_hash ( node , de -> td_hash ) ; return ( dc -> tdc_current ) ; }
Lookup directory entry by cookie, initialize directory cursor accordingly.
Lookup directory entry by cookie initialize directory cursor accordingly .
/* Protect against possible race, tn_readdir_last[pn]
		 * may be updated with only shared vnode lock held. */ /* dupindex list is sorted. */ /* Recover if direntry for cookie was removed */