#include <errno.h>#include <stdbool.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include <atalk/adouble.h>#include <atalk/directory.h>#include <atalk/errchk.h>#include <atalk/logger.h>#include <atalk/util.h>#include <atalk/volume.h>#include "dircache.h"#include "directory.h"#include "ad_cache.h"#include "unix.h"Functions | |
| void | ad_store_to_cache (struct adouble *adp, struct dir *cached) |
| Store AD metadata results into struct dir cache fields. | |
| void | ad_rebuild_from_cache (struct adouble *adp, const struct dir *cached) |
| Populate struct adouble from struct dir cache fields. | |
| int | ad_metadata_cached (const char *name, int flags, struct adouble *adp, const struct vol *vol, struct dir *dir, bool strict, struct stat *recent_st) |
| Unified AD metadata access with integrated cache management. | |
| void | rfork_cache_free (struct dir *entry) |
| Free a single entry's rfork buffer, remove from rfork LRU, update counter. | |
| void | rfork_cache_evict_to_budget (size_t needed) |
| Evict rfork buffers from rfork LRU head (oldest/LRU) until under budget. | |
| int | rfork_cache_store_from_fd (struct dir *entry, struct adouble *adp, int eid) |
| Store resource fork data by reading directly from the ad fd. | |
Variables | |
| unsigned long long | ad_cache_hits |
| unsigned long long | ad_cache_misses |
| unsigned long long | ad_cache_no_ad |
| int ad_metadata_cached | ( | const char * | name, |
| int | flags, | ||
| struct adouble * | adp, | ||
| const struct vol * | vol, | ||
| struct dir * | dir, | ||
| bool | strict, | ||
| struct stat * | recent_st ) |
Unified AD metadata access with integrated cache management.
Read-only metadata accessor with internal ad_close(). Callers needing a writable fd (e.g., for ad_setid/ad_flush) must call ad_open() separately.
strict=false: cache-first (enumerate, FPGetFileDirParms). strict=true: validate ctime/inode before serving (moveandrename, deletecurdir). recent_st: optional stat to avoid duplicate ostat() in strict path.
Populate struct adouble from struct dir cache fields.
Sets up the entry directory in adp so that ad_getattr(), ad_getdate(), ad_entry() all work normally — downstream code is completely unchanged.
Store AD metadata results into struct dir cache fields.
Called after every ad_metadata() disk read when a cached entry is available. Pre-computes the served FILPBIT_MDATE value as max(ad_mdate, dcache_mtime).
ad_entry() returns NULL if the entry doesn't exist in this AD version. This is fine — zero-initialized cache fields are valid defaults: zero FinderInfo = no custom attributes zero FileDatesI = overridden by stat mtime fallback zero AFPFileI = no attributes
| void rfork_cache_evict_to_budget | ( | size_t | needed | ) |
Evict rfork buffers from rfork LRU head (oldest/LRU) until under budget.
Queue convention: sentinel->next = head = LRU (oldest), sentinel->prev = tail = MRU (newest). Called by rfork_cache_store_from_fd() when budget would be exceeded. O(k) where k = entries evicted.
| void rfork_cache_free | ( | struct dir * | entry | ) |
Free a single entry's rfork buffer, remove from rfork LRU, update counter.
Uses dcache_rlen for the buffer size. INVARIANT: dcache_rlen >= 0 when dcache_rfork_buf != NULL. Uses production-safe fallback: if dcache_rlen < 0 (invariant violation), logs error, frees buffer, but does NOT touch budget counter (unknown size). Handles rfork_lru_node == NULL gracefully (orphaned buffer from enqueue failure — budget is still decremented correctly). Decrements rfork_lru_count when removing from LRU. Does NOT reset dcache_rlen — the AD metadata remains valid.
Store resource fork data by reading directly from the ad fd.
Allocates dcache_rlen bytes and does ad_read(adp, eid, 0, buf, dcache_rlen). ad_read() handles all storage formats (EA, macOS xattr, AD v2 sidecar). Guards: returns -1 if !AD_RSRC_OPEN(adp) (fd not open), dcache_rlen <= 0, or rlen > rfork_max_entry_size. Validates that ad_read returns exactly dcache_rlen bytes — if not, the fork size changed since Tier 1 metadata was cached: invalidates ALL cached AD metadata (Tier 1) and returns -1 (self-healing).
| unsigned long long ad_cache_hits |
| unsigned long long ad_cache_misses |
| unsigned long long ad_cache_no_ad |