netatalk  4.5.0
Free and Open Source Apple Filing Protocol (AFP) Server
Loading...
Searching...
No Matches
dircache.h File Reference
#include <sys/types.h>
#include <atalk/directory.h>
#include <atalk/globals.h>
#include <atalk/volume.h>

Go to the source code of this file.

Macros

#define MIN_DIRCACHE_SIZE   1024 /* 1K minimum (testing/constrained systems) */
#define DEFAULT_DIRCACHE_SIZE   65536 /* 64K default (production) */
#define MAX_DIRCACHE_SIZE   1048576 /* 1M maximum (high-memory servers) */
#define DIRCACHE_FREE_QUANTUM   256
#define DEFERRED_CHAIN_BATCH   16
#define DIRCACHE   (1 << 0)
#define DIDNAME_INDEX   (1 << 1)
#define QUEUE_INDEX   (1 << 2)
#define DIRCACHE_NOSHRINK   (1 << 3) /* Skip hash table shrink */
#define DIRCACHE_ALL   (DIRCACHE|DIDNAME_INDEX|QUEUE_INDEX)

Functions

int dircache_init (int reqsize)
 Initialize the dircache and indexes.
int dircache_add (const struct vol *, struct dir *)
 create struct dir from struct path
void dircache_remove (const struct vol *, struct dir *, int flag)
 Remove an entry from the dircache.
struct dirdircache_search_by_did (const struct vol *vol, cnid_t did)
 Search the dircache via a CNID for a directory.
struct dirdircache_search_by_name (const struct vol *, const struct dir *dir, char *name, size_t len)
 Search the cache via did/name hashtable.
void dircache_dump (void)
 Dump dircache to /tmp/dircache.PID.
void log_dircache_stat (void)
 Log dircache statistics.
int dircache_set_validation_params (unsigned int freq)
 Set directory cache validation frequency.
void dircache_reset_validation_counter (void)
 Reset validation counter for consistent testing.
void dircache_report_invalid_entry (struct dir *dir)
 Report that a cache entry was invalid when actually used.
int dircache_remove_children (const struct vol *vol, struct dir *dir)
 Remove all child entries of a directory from the dircache.
int dircache_reindex_didname (const struct vol *vol, struct dir *dir)
 Re-insert entry into DID/name index after key change.
void dircache_promote (struct dir *dir)
 Promote a cache entry to signal recency.
void process_cache_hints (AFPObj *obj)
 Process cross-process dircache invalidation hints.
void dircache_remove_children_defer (const struct vol *vol, struct dir *dir)
 Enqueue a deferred dircache_remove_children operation.
void dircache_flush_deferred_for_vol (uint16_t vid)
 Process deferred cleanup entries for a closing volume synchronously.
int dircache_has_deferred_work (void)
int dircache_process_deferred_chain (void)
 Process one hash chain from the current deferred cleanup job.
void dircache_rfork_shutdown (void)
 Shutdown the rfork cache — free remaining RFork LRU nodes and sentinel.

Variables

size_t rfork_cache_used
size_t rfork_cache_budget
size_t rfork_max_entry_size
unsigned int rfork_lru_count
q_trfork_lru
unsigned long long rfork_stat_lookups
unsigned long long rfork_stat_hits
unsigned long long rfork_stat_misses
unsigned long long rfork_stat_added
unsigned long long rfork_stat_evicted
unsigned long long rfork_stat_invalidated
size_t rfork_stat_used_max

Macro Definition Documentation

◆ DEFAULT_DIRCACHE_SIZE

#define DEFAULT_DIRCACHE_SIZE   65536 /* 64K default (production) */

◆ DEFERRED_CHAIN_BATCH

#define DEFERRED_CHAIN_BATCH   16

◆ DIDNAME_INDEX

#define DIDNAME_INDEX   (1 << 1)

◆ DIRCACHE

#define DIRCACHE   (1 << 0)

◆ DIRCACHE_ALL

#define DIRCACHE_ALL   (DIRCACHE|DIDNAME_INDEX|QUEUE_INDEX)

◆ DIRCACHE_FREE_QUANTUM

#define DIRCACHE_FREE_QUANTUM   256

◆ DIRCACHE_NOSHRINK

#define DIRCACHE_NOSHRINK   (1 << 3) /* Skip hash table shrink */

◆ MAX_DIRCACHE_SIZE

#define MAX_DIRCACHE_SIZE   1048576 /* 1M maximum (high-memory servers) */

◆ MIN_DIRCACHE_SIZE

#define MIN_DIRCACHE_SIZE   1024 /* 1K minimum (testing/constrained systems) */

◆ QUEUE_INDEX

#define QUEUE_INDEX   (1 << 2)

Function Documentation

◆ dircache_add()

int dircache_add ( const struct vol * vol,
struct dir * dir )
extern

create struct dir from struct path

Add a struct dir to the cache and its indexes. Supports both LRU mode (legacy) and ARC mode.

Parameters
[in]volpointer to volume
[in]dirpointer to parent directory
Returns
0 on success, -1 on error which should result in an abort

◆ dircache_dump()

void dircache_dump ( void )
extern

Dump dircache to /tmp/dircache.PID.

◆ dircache_flush_deferred_for_vol()

void dircache_flush_deferred_for_vol ( uint16_t vid)
extern

Process deferred cleanup entries for a closing volume synchronously.

Precondition
: Worker is dormant (called during AFP command processing). Called from afp_closevol() before volume structures are freed.

◆ dircache_has_deferred_work()

int dircache_has_deferred_work ( void )
extern

◆ dircache_init()

int dircache_init ( int reqsize)
extern

Initialize the dircache and indexes.

This is called in child afpd initialization. The maximum cache size will be max(DEFAULT_DIRCACHE_SIZE, min(size, MAX_DIRCACHE_SIZE)). It initializes a hashtable which we use to store a directory cache in. It also initializes two indexes:

  • a DID/name index on the main dircache
  • a queue index on the dircache (LRU mode) or four queues (ARC mode)
Parameters
[in]reqsizerequested maximum size from afp.conf
Returns
0 on success, -1 on error

◆ dircache_process_deferred_chain()

int dircache_process_deferred_chain ( void )
extern

Process one hash chain from the current deferred cleanup job.

Called by idle worker. Walks a single hash chain, collects up to DEFERRED_CHAIN_BATCH matching children, and removes+frees them via dir_remove_and_free(). Entries matching curdir are skipped.

Returns
1 if more work remains, 0 if all deferred work is complete

◆ dircache_promote()

void dircache_promote ( struct dir * dir)
extern

Promote a cache entry to signal recency.

Dispatches based on cache mode:

ARC mode (arc_list membership): T1/T2: arc_case_i() — move to MRU of T2 B1: arc_case_ii_adapt_and_replace() — promote ghost to T2 B2: arc_case_iii_adapt_and_replace() — promote ghost to T2

LRU mode: Move entry to MRU position of the LRU queue, so recently accessed entries are evicted last. Prevents actively-used entries from being evicted.

Parameters
[in,out]dirCache entry to promote (required)

◆ dircache_reindex_didname()

int dircache_reindex_didname ( const struct vol * vol,
struct dir * dir )
extern

Re-insert entry into DID/name index after key change.

Called by dir_modify() after updating d_pdid / d_u_name. The caller MUST have already removed the entry from the DIDNAME_INDEX via dircache_remove(vol, dir, DIDNAME_INDEX) before calling this.

Parameters
[in]volVolume (required)
[in]dirEntry with updated d_pdid / d_u_name (required)
Returns
0 on success, -1 on hash insert failure

◆ dircache_remove()

void dircache_remove ( const struct vol * vol,
struct dir * dir,
int flags )
extern

Remove an entry from the dircache.

Callers outside of dircache.c should call this with flags = QUEUE_INDEX | DIDNAME_INDEX | DIRCACHE.

◆ dircache_remove_children()

int dircache_remove_children ( const struct vol * vol,
struct dir * dir )
extern

Remove all child entries of a directory from the dircache.

When a directory is renamed or moved, the full paths stored in the dircache become invalid for all child entries of the renamed dir. This function prunes orphaned child dircache entries of given dir. CNID entries use parent DIDs and name, and requre recursion to get the full path, therefore parent changes do not invalidate the CNIDs.

Parameters
[in]volvolume
[in]dirparent directory whose children should be removed
Returns
0 on success, -1 if curdir was removed and recovery failed

◆ dircache_remove_children_defer()

void dircache_remove_children_defer ( const struct vol * vol,
struct dir * dir )
extern

Enqueue a deferred dircache_remove_children operation.

O(1) enqueue — the idle worker performs the actual hash scan during poll() idle periods. Falls back to synchronous removal if the worker is not active or the queue is full.

◆ dircache_report_invalid_entry()

void dircache_report_invalid_entry ( struct dir * dir)
extern

Report that a cache entry was invalid when actually used.

This function should be called when a cached directory entry that was returned without validation (for performance) turns out to be invalid when actually accessed (e.g., file doesn't exist, has been modified, etc). This helps track the effectiveness of the validation frequency setting.

Parameters
[in]dirThe directory entry that was found to be invalid

◆ dircache_reset_validation_counter()

void dircache_reset_validation_counter ( void )
extern

Reset validation counter for consistent testing.

Resets the global validation counter to ensure predictable validation patterns between test runs or configuration changes.

◆ dircache_rfork_shutdown()

void dircache_rfork_shutdown ( void )
extern

Shutdown the rfork cache — free remaining RFork LRU nodes and sentinel.

Called from the child shutdown path after log_dircache_stat(). Frees the qnodes (rfork data buffers are reclaimed by exit()) and the LRU sentinel.

◆ dircache_search_by_did()

struct dir * dircache_search_by_did ( const struct vol * vol,
cnid_t cnid )
extern

Search the dircache via a CNID for a directory.

Found cache entries are expunged if both the parent directory st_ctime and the objects st_ctime are modified. This func builds on the fact, that all our code only ever needs to and does search the dircache by CNID expecting directories to be returned, but not files. Thus (1) if we find a file for a given CNID we (1a) remove it from the cache (1b) return NULL indicating nothing found (2) we can then use d_fullpath to stat the directory

Parameters
[in]volpointer to struct vol
[in]cnidCNID of the directory to search
Returns
Pointer to struct dir if found, else NULL

◆ dircache_search_by_name()

struct dir * dircache_search_by_name ( const struct vol * vol,
const struct dir * dir,
char * name,
size_t len )
extern

Search the cache via did/name hashtable.

Found cache entries are expunged if both the parent directory st_ctime and the objects st_ctime are modified.

Parameters
[in]volvolume
[in]dirdirectory
[in]namename (server side encoding)
[in]lenstrlen of name
Returns
pointer to struct dir if found in cache, else NULL

◆ dircache_set_validation_params()

int dircache_set_validation_params ( unsigned int freq)
extern

Set directory cache validation frequency.

Allows runtime configuration of cache validation behavior for performance tuning. Lower validation frequency improves performance but may delay detection of external filesystem changes.

Parameters
[in]freqvalidation frequency (1 = validate every access, 100 = every 100th access)
Returns
0 on success, -1 on invalid parameters

◆ log_dircache_stat()

void log_dircache_stat ( void )
extern

Log dircache statistics.

Includes hit ratio percentage for monitoring cache effectiveness, validation-specific metrics to monitor performance impact of the optimization changes, and username for tracking per-user stats. Shows both expunged (caught by validation) and invalid_on_use (missed by validation).

◆ process_cache_hints()

void process_cache_hints ( AFPObj * obj)
extern

Process cross-process dircache invalidation hints.

Called from the DSI command loop after each AFP command completes. Uses direct hash_lookup() on the CNID hash table to support BOTH files (DIRF_ISFILE) and directories — dircache_search_by_did() is unsuitable because it actively removes file entries.

Dispatches on hint type:

Variable Documentation

◆ rfork_cache_budget

size_t rfork_cache_budget
extern

◆ rfork_cache_used

size_t rfork_cache_used
extern

◆ rfork_lru

q_t* rfork_lru
extern

◆ rfork_lru_count

unsigned int rfork_lru_count
extern

◆ rfork_max_entry_size

size_t rfork_max_entry_size
extern

◆ rfork_stat_added

unsigned long long rfork_stat_added
extern

◆ rfork_stat_evicted

unsigned long long rfork_stat_evicted
extern

◆ rfork_stat_hits

unsigned long long rfork_stat_hits
extern

◆ rfork_stat_invalidated

unsigned long long rfork_stat_invalidated
extern

◆ rfork_stat_lookups

unsigned long long rfork_stat_lookups
extern

◆ rfork_stat_misses

unsigned long long rfork_stat_misses
extern

◆ rfork_stat_used_max

size_t rfork_stat_used_max
extern