#include <arpa/inet.h>#include <dirent.h>#include <stdbool.h>#include <sys/sysmacros.h>#include <sys/types.h>#include <atalk/adouble.h>#include <atalk/directory.h>#include <atalk/globals.h>#include "volume.h"Go to the source code of this file.
Data Structures | |
| struct | dir_modify_args |
| Parameters for dir_modify() selective field updates. More... | |
| struct | maccess |
Macros | |
| #define | DCMOD_PATH (1 << 0) |
| #define | DCMOD_STAT (1 << 1) |
| #define | DCMOD_AD (1 << 2) |
| #define | DCMOD_AD_INV (1 << 3) |
| #define | DCMOD_NO_PROMOTE (1 << 4) /* Skip ARC promotion (cross-process hints) */ |
| #define | DIRPBIT_ATTR 0 |
| #define | DIRPBIT_PDID 1 |
| #define | DIRPBIT_CDATE 2 |
| #define | DIRPBIT_MDATE 3 |
| #define | DIRPBIT_BDATE 4 |
| #define | DIRPBIT_FINFO 5 |
| #define | DIRPBIT_LNAME 6 |
| #define | DIRPBIT_SNAME 7 |
| #define | DIRPBIT_DID 8 |
| #define | DIRPBIT_OFFCNT 9 |
| #define | DIRPBIT_UID 10 |
| #define | DIRPBIT_GID 11 |
| #define | DIRPBIT_ACCESS 12 |
| #define | DIRPBIT_PDINFO 13 |
| #define | DIRPBIT_UNIXPR 15 |
| #define | FILDIRBIT_ISDIR (1 << 7) |
| #define | FILDIRBIT_ISFILE (0) |
| #define | CNID(a, b) |
| #define | AR_USEARCH (1<<0) |
| #define | AR_UREAD (1<<1) |
| #define | AR_UWRITE (1<<2) |
| #define | AR_UOWN (1<<7) |
Typedefs | |
| typedef int(* | dir_loop) (struct dirent *, char *, void *) |
Functions | |
| void | dir_remove_and_free (const struct vol *, struct dir *) |
| Remove a cache entry and free it immediately. | |
| void | dir_free_invalid_q (void) |
| Free the queue with invalid struct dirs. | |
| struct dir * | dir_new (const char *mname, const char *uname, const struct vol *, cnid_t pdid, cnid_t did, bstring fullpath, struct stat *) |
| Construct struct dir. | |
| void | dir_free (struct dir *) |
| Free a struct dir and all its members. | |
| struct dir * | dir_add (struct vol *, const struct dir *, struct path *, int) |
| Create struct dir from struct path. | |
| int | dir_modify (const struct vol *vol, struct dir *dir, const struct dir_modify_args *args) |
| Update a cached entry in-place with selective field updates. | |
| int | dir_remove (const struct vol *vol, struct dir *dir, int report_invalid) |
| Remove a file/directory from dircache with automatic curdir recovery. | |
| struct dir * | dirlookup (const struct vol *, cnid_t) |
| Optimistic CNID resolution for read/safe code paths. | |
| struct dir * | dirlookup_strict (const struct vol *, cnid_t) |
| Validated DID resolution for write/change code paths. | |
| struct dir * | dirlookup_bypath (const struct vol *vol, const char *path) |
| int | movecwd (const struct vol *, struct dir *) |
| chdir() to dir | |
| struct path * | cname (struct vol *, struct dir *, char **) |
| Resolve a catalog node name path. | |
| int | deletecurdir (struct vol *) |
| mode_t | mtoumode (struct maccess *) |
| int | getdirparams (const AFPObj *obj, const struct vol *, uint16_t, struct path *, struct dir *, char *, size_t *) |
| int | setdirparams (struct vol *, struct path *, uint16_t, char *) |
| int | renamedir (struct vol *, int, char *, char *, struct dir *, char *) |
| Rename a directory. | |
| int | path_error (struct path *, int error) |
| void | setdiroffcnt (struct dir *dir, struct stat *st, uint32_t count) |
| int | dirreenumerate (struct dir *dir, struct stat *st) |
| int | for_each_dirent (const struct vol *, char *, dir_loop, void *) |
| int | check_access (const AFPObj *obj, struct vol *, char *name, int mode) |
| int | file_access (const AFPObj *obj, struct vol *vol, struct path *path, int mode) |
| int | netatalk_unlink (const char *name) |
| system unlink with afp error code. | |
| char * | check_dirent (const struct vol *, char *) |
| int | afp_createdir (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_opendir (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_setdirparams (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_closedir (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_mapid (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_mapname (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_syncdir (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_enumerate (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_enumerate_ext (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_enumerate_ext2 (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_catsearch (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_catsearch_ext (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
Variables | |
| q_t * | invalid_dircache_entries |
| #define AR_UOWN (1<<7) |
| #define AR_UREAD (1<<1) |
| #define AR_USEARCH (1<<0) |
| #define AR_UWRITE (1<<2) |
| #define CNID | ( | a, | |
| b ) |
| #define DCMOD_AD (1 << 2) |
AD cache: finderinfo/filedatesi/afpfilei/rlen (Phase 2)
| #define DCMOD_AD_INV (1 << 3) |
AD invalidate: zero AD fields, set rlen = -1 (Phase 2)
| #define DCMOD_NO_PROMOTE (1 << 4) /* Skip ARC promotion (cross-process hints) */ |
| #define DCMOD_PATH (1 << 0) |
Identity/navigation: d_pdid, names, d_fullpath
| #define DCMOD_STAT (1 << 1) |
Stat cache: dcache_ctime/ino/mode/mtime/uid/gid/size
| #define DIRPBIT_ACCESS 12 |
| #define DIRPBIT_ATTR 0 |
| #define DIRPBIT_BDATE 4 |
| #define DIRPBIT_CDATE 2 |
| #define DIRPBIT_DID 8 |
| #define DIRPBIT_FINFO 5 |
| #define DIRPBIT_GID 11 |
| #define DIRPBIT_LNAME 6 |
| #define DIRPBIT_MDATE 3 |
| #define DIRPBIT_OFFCNT 9 |
| #define DIRPBIT_PDID 1 |
| #define DIRPBIT_PDINFO 13 |
ProDOS Info
| #define DIRPBIT_SNAME 7 |
| #define DIRPBIT_UID 10 |
| #define DIRPBIT_UNIXPR 15 |
| #define FILDIRBIT_ISDIR (1 << 7) |
is a directory
| #define FILDIRBIT_ISFILE (0) |
is a file
| typedef int(* dir_loop) (struct dirent *, char *, void *) |
| int afp_catsearch | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_catsearch_ext | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_closedir | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_createdir | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_enumerate | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_enumerate_ext | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_enumerate_ext2 | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_mapid | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_mapname | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_opendir | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_setdirparams | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_syncdir | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
We can't use unix file's perm to support Apple's inherited protection modes. If we aren't the file's owner we can't change its perms when moving it and smb nfs,... don't even try.
|
extern |
afp_enumerate return an empty listing but offspring count != 0 in afp_getdirparams and the client doesn't try to call afp_delete!
Resolve a catalog node name path.
|
extern |
delete an empty directory
|
extern |
Create struct dir from struct path.
Create a new struct dir from struct path. Then add it to the cache.
| [in] | vol | pointer to struct vol, possibly modified in callee |
| [in] | dir | pointer to parent directory |
| [in,out] | path | pointer to struct path with valid path->u_name |
| [in] | len | strlen of path->u_name |
|
extern |
Free a struct dir and all its members.
| dir | (rw) pointer to struct dir |
|
extern |
Free the queue with invalid struct dirs.
|
extern |
Update a cached entry in-place with selective field updates.
Modifies specified field groups on an existing cache entry while maintaining hash table consistency. The DCMOD_* bitmask in args->flags controls which fields are updated — unset groups are not touched.
When DCMOD_PATH is set and new_uname or new_pdid differs from current values, the DID/name index is automatically reindexed. The CNID index (d_vid, d_did) is NEVER changed.
Always promotes the entry in ARC (signals recency to eviction algorithm).
Common call patterns: Rename: DCMOD_PATH | DCMOD_STAT After setfilparams: DCMOD_STAT | DCMOD_AD (Phase 2) Stat-only refresh: DCMOD_STAT
| [in] | vol | Volume (required) |
| [in,out] | dir | Cache entry to update (required) |
| [in] | args | Parameter struct with DCMOD_* flags and field values |
|
extern |
Construct struct dir.
Construct struct dir from parameters.
| [in] | m_name | directory name in UTF8-dec |
| [in] | u_name | directory name in server side encoding |
| [in] | vol | pointer to struct vol |
| [in] | pdid | Parent CNID |
| [in] | did | CNID |
| [in] | path | Full unix path to object |
| [in] | st | struct stat of object |
Remove a file/directory from dircache with automatic curdir recovery.
This function centralizes global curdir safety for all callers. When removing a cache entry that is curdir, it attempts curdir recovery via CNID database and falls back to volume root if recovery fails.
| [in] | vol | volume pointer |
| [in,out] | dir | directory/file entry to remove from cache |
| [in] | report_invalid | 1 = report as invalid_on_use (entry was used and found stale), 0 = don't report (proactive cleanup, user deletion, etc.) |
Remove a cache entry and free it immediately.
Unlike dir_remove(), this function:
DIRCACHE_NOSHRINK prevents hash table shrink during worker iteration.
Used by idle worker during temporal separation AND by dircache_flush_deferred_for_vol() during synchronous volume close.
Optimistic CNID resolution for read/safe code paths.
Resolves a CNID to its cached entry using probabilistic validation. Safe for read operations (enumerate, getparams, opendir, openfork) because stale entries are detected on use and recovered via movecwd().
| [in] | vol | pointer to struct vol |
| [in] | did | DID to resolve |
Validated DID resolution for write/change code paths.
Like dirlookup(), but performs stat()+inode validation to ensure the cached entry matches the current filesystem state. Gurantees operating on valid entry. Use for all write/change operations: delete, setdirparams, setfilparams, setfildirparams, setacl, copyfile (dest), exchangefiles, createdir, createfile
| [in] | vol | pointer to struct vol |
| [in] | did | DID to resolve |
|
extern |
|
extern |
chdir() to dir
| [in] | vol | pointer to struct vol |
| [in] | dir | pointer to struct dir |
|
extern |
|
extern |
system unlink with afp error code.
|
extern |
|
extern |
Rename a directory.
| vol | volume |
| dirfd | -1 means ignore dirfd (or use AT_FDCWD), otherwise src is relative to dirfd |
| src | old unix filename (not a pathname) |
| dst | new unix filename (not a pathname) |
| newparent | curdir |
| newname | new mac name |
|
extern |
|
extern |