FreeBSD/sys/fs/tmpfs/tmpfs_subr.c
/*
 * Attach duplicate-cookie directory entry nde to dnode and insert to dupindex
 * list, allocate new cookie value.
 */
Attach duplicate-cookie directory entry nde to dnode and insert to dupindex
list, allocate new cookie value.
Attach duplicate - cookie directory entry nde to dnode and insert to dupindex list allocate new cookie value .
static void
tmpfs_dir_attach_dup(struct tmpfs_node *dnode,
    struct tmpfs_dir_duphead *duphead, struct tmpfs_dirent *nde)
{
	struct tmpfs_dir_duphead *dupindex;
	struct tmpfs_dirent *de, *pde;
	dupindex = &dnode->tn_dir.tn_dupindex;
	de = LIST_FIRST(dupindex);
	if (de == NULL || de->td_cookie < TMPFS_DIRCOOKIE_DUP_MAX) {
		if (de == NULL)
			nde->td_cookie = TMPFS_DIRCOOKIE_DUP_MIN;
		else
			nde->td_cookie = de->td_cookie + 1;
		MPASS(tmpfs_dirent_dup(nde));
		LIST_INSERT_HEAD(dupindex, nde, uh.td_dup.index_entries);
		LIST_INSERT_HEAD(duphead, nde, uh.td_dup.entries);
		return;
	}
	while (1) {
		pde = de;
		de = LIST_NEXT(de, uh.td_dup.index_entries);
		if (de == NULL && pde->td_cookie != TMPFS_DIRCOOKIE_DUP_MIN) {
			nde->td_cookie = TMPFS_DIRCOOKIE_DUP_MIN;
			LIST_INSERT_AFTER(pde, nde, uh.td_dup.index_entries);
			LIST_INSERT_HEAD(duphead, nde, uh.td_dup.entries);
			return;
		} else if (de == NULL) {
			nde->td_cookie = TMPFS_DIRCOOKIE_DUP_MAX;
			LIST_INSERT_HEAD(dupindex, nde,
			    uh.td_dup.index_entries);
			LIST_INSERT_HEAD(duphead, nde, uh.td_dup.entries);
			return;
		}
		if (de->td_cookie + 1 == pde->td_cookie ||
		    de->td_cookie >= TMPFS_DIRCOOKIE_DUP_MAX)
			continue;	
		nde->td_cookie = de->td_cookie + 1;
		MPASS(tmpfs_dirent_dup(nde));
		MPASS(pde->td_cookie > nde->td_cookie);
		MPASS(nde->td_cookie > de->td_cookie);
		LIST_INSERT_BEFORE(de, nde, uh.td_dup.index_entries);
		LIST_INSERT_HEAD(duphead, nde, uh.td_dup.entries);
		return;
	}
}
static void tmpfs_dir_attach_dup ( struct tmpfs_node * dnode , struct tmpfs_dir_duphead * duphead , struct tmpfs_dirent * nde ) { struct tmpfs_dir_duphead * dupindex ; struct tmpfs_dirent * de , * pde ; dupindex = & dnode -> tn_dir . tn_dupindex ; de = LIST_FIRST ( dupindex ) ; if ( de == NULL || de -> td_cookie < TMPFS_DIRCOOKIE_DUP_MAX ) { if ( de == NULL ) nde -> td_cookie = TMPFS_DIRCOOKIE_DUP_MIN ; else nde -> td_cookie = de -> td_cookie + 1 ; MPASS ( tmpfs_dirent_dup ( nde ) ) ; LIST_INSERT_HEAD ( dupindex , nde , uh . td_dup . index_entries ) ; LIST_INSERT_HEAD ( duphead , nde , uh . td_dup . entries ) ; return ; } while ( 1 ) { pde = de ; de = LIST_NEXT ( de , uh . td_dup . index_entries ) ; if ( de == NULL && pde -> td_cookie != TMPFS_DIRCOOKIE_DUP_MIN ) { nde -> td_cookie = TMPFS_DIRCOOKIE_DUP_MIN ; LIST_INSERT_AFTER ( pde , nde , uh . td_dup . index_entries ) ; LIST_INSERT_HEAD ( duphead , nde , uh . td_dup . entries ) ; return ; } else if ( de == NULL ) { nde -> td_cookie = TMPFS_DIRCOOKIE_DUP_MAX ; LIST_INSERT_HEAD ( dupindex , nde , uh . td_dup . index_entries ) ; LIST_INSERT_HEAD ( duphead , nde , uh . td_dup . entries ) ; return ; } if ( de -> td_cookie + 1 == pde -> td_cookie || de -> td_cookie >= TMPFS_DIRCOOKIE_DUP_MAX ) continue ; nde -> td_cookie = de -> td_cookie + 1 ; MPASS ( tmpfs_dirent_dup ( nde ) ) ; MPASS ( pde -> td_cookie > nde -> td_cookie ) ; MPASS ( nde -> td_cookie > de -> td_cookie ) ; LIST_INSERT_BEFORE ( de , nde , uh . td_dup . index_entries ) ; LIST_INSERT_HEAD ( duphead , nde , uh . td_dup . entries ) ; return ; } }
Attach duplicate-cookie directory entry nde to dnode and insert to dupindex
 list, allocate new cookie value.
Attach duplicate - cookie directory entry nde to dnode and insert to dupindex list allocate new cookie value .
/*
	 * Cookie numbers are near exhaustion. Scan dupindex list for unused
	 * numbers. dupindex list is sorted in descending order. Keep it so
	 * after inserting nde.
	 */ /*
			 * Last element of the index doesn't have minimal cookie
			 * value, use it.
			 */ /*
			 * We are so lucky have 2^30 hash duplicates in single
			 * directory :) Return largest possible cookie value.
			 * It should be fine except possible issues with
			 * VOP_READDIR restart.
			 */ /* No hole or invalid cookie. */