#include <arpa/inet.h>#include <stdio.h>#include <atalk/adouble.h>#include "directory.h"#include "volume.h"Go to the source code of this file.
Data Structures | |
| struct | file_key |
| struct | ofork |
Macros | |
| #define | OPENFORK_DATA (0) |
| #define | OPENFORK_RSCS (1<<7) |
| #define | OPENACC_RD (1<<0) |
| #define | OPENACC_WR (1<<1) |
| #define | OPENACC_DRD (1<<4) |
| #define | OPENACC_DWR (1<<5) |
| #define | AFPFORK_DATA (1<<0) |
| #define | AFPFORK_RSRC (1<<1) |
| #define | AFPFORK_META (1<<2) |
| #define | AFPFORK_DIRTY (1<<3) |
| #define | AFPFORK_ACCRD (1<<4) |
| #define | AFPFORK_ACCWR (1<<5) |
| #define | AFPFORK_ACCMASK (AFPFORK_ACCRD | AFPFORK_ACCWR) |
| #define | AFPFORK_MODIFIED (1<<6) |
| #define | AFPFORK_ERROR (1<<7) |
| #define | AFPFORK_VIRTUAL (1<<8) |
| #define | of_name(a) |
Enumerations | |
| enum | of_locks_status { OF_LOCKS_ERROR = -1 , OF_LOCKS_OK = 0 , OF_LOCKS_NOENT = 1 } |
Functions | |
| static int | fork_range_within (off_t offset, off_t length, off_t size) |
| struct ofork * | of_alloc (struct vol *, struct dir *, char *, uint16_t *, const int, struct adouble *, struct stat *) |
| void | of_dealloc (struct ofork *) |
| struct ofork * | of_find (const uint16_t) |
| struct ofork * | of_findname (const struct vol *vol, struct path *) |
| int | of_rename (const struct vol *, struct ofork *, struct dir *, const char *, struct dir *, const char *) |
| int | of_flush (const struct vol *) |
| void | of_pforkdesc (FILE *) |
| void | of_log_highwater (void) |
| int | of_stat (const struct vol *vol, struct path *) |
| int | of_statdir (struct vol *vol, struct path *) |
| stat the current directory. | |
| int | of_closefork (const AFPObj *obj, struct ofork *ofork) |
| void | of_closevol (const AFPObj *obj, const struct vol *vol) |
| void | of_close_all_forks (const AFPObj *obj) |
| struct adouble * | of_ad (const struct vol *, struct path *, struct adouble *) |
| struct ofork * | of_findnameat (int dirfd, struct path *path) |
| Search for open fork by dirfd/name. | |
| int | of_delete_blocked (const struct ofork *of, uint16_t *band, int *content) |
| Does this child hold a delete-blocking claim on the fork's file? | |
| void | of_close_inode_forks (const AFPObj *obj, const struct vol *vol, struct path *path) |
| Close every fork this child holds on path's inode. | |
| int | of_fstatat (int dirfd, struct path *path) |
| int | of_get_locks (const struct vol *vol, int dirfd, struct path *path, int df_get, off_t df_off, off_t df_len, int rf_get, off_t rf_off, off_t rf_len, uint16_t band_request, int try_root, int *df_locked, int *rf_locked, uint16_t *band_held) |
| Conflict GET (F_GETLK only): read another holder's locks on a file. | |
| int | flushfork (struct ofork *) |
| int | fork_setmode_deny (int access, int f_rddny, int f_wrdny, int f_nodny) |
| int | afp_openfork (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_bytelock (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_getforkparams (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_setforkparams (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_read (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_write (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_flushfork (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_flush (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_closefork (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_bytelock_ext (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_read_ext (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_write_ext (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| int | afp_syncfork (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) |
| #define AFPFORK_ACCMASK (AFPFORK_ACCRD | AFPFORK_ACCWR) |
| #define AFPFORK_ACCRD (1<<4) |
| #define AFPFORK_ACCWR (1<<5) |
| #define AFPFORK_DATA (1<<0) |
open datafork
| #define AFPFORK_DIRTY (1<<3) |
| #define AFPFORK_ERROR (1<<7) |
used to indicate an error in opening the fork
| #define AFPFORK_META (1<<2) |
open metadata
| #define AFPFORK_MODIFIED (1<<6) |
used in FCE for modified files
| #define AFPFORK_RSRC (1<<1) |
open rsrcfork
| #define AFPFORK_VIRTUAL (1<<8) |
virtual file fork
| #define of_name | ( | a | ) |
| #define OPENACC_DRD (1<<4) |
| #define OPENACC_DWR (1<<5) |
| #define OPENACC_RD (1<<0) |
| #define OPENACC_WR (1<<1) |
| #define OPENFORK_DATA (0) |
| #define OPENFORK_RSCS (1<<7) |
| enum of_locks_status |
| int afp_bytelock | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_bytelock_ext | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_closefork | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_flush | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_flushfork | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_getforkparams | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_openfork | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_read | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_read_ext | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_setforkparams | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_syncfork | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_write | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
| int afp_write_ext | ( | AFPObj * | obj, |
| char * | ibuf, | ||
| size_t | ibuflen, | ||
| char * | rbuf, | ||
| size_t * | rbuflen ) |
|
extern |
|
inlinestatic |
|
extern |
|
extern |
|
extern |
close all forks
Close every fork this child holds on path's inode.
Same-session sweep for FPDelete, called after a successful delete: every refusal condition (DeleteInhibit, peer claims, the session's own claims via of_delete_blocked()) has already passed and the file is unlinked, so only claim-free forks (any OPEN_* access, no deny mode, no content lock) reach this sweep. Each fork is closed individually — the blocking check needs one fork (shared adouble), the close needs them all. of_closefork() deallocs even on flush error (nothing is stranded), so a failed close is logged and the sweep continues — matching of_closevol().
| [in] | obj | the AFP session object |
| [in] | vol | volume the deleted file lived on |
| [in] | path | deleted file; path->st must be the pre-delete stat (the file no longer exists, so a re-stat cannot rebuild it) |
|
extern |
|
extern |
Does this child hold a delete-blocking claim on the fork's file?
The cross-process conflict check (deletefile()'s F_GETLK read) cannot by POSIX report the calling process's own locks, so the delete path asks this helper for the local complement: scan the session's own lock bookkeeping for the same claims and apply the same DELETE_BLOCKING_BAND_BITS policy — a deny mode or content byte-range lock refuses the delete whether its holder is a peer process or this session itself. OPEN_* markers never block (an open is just an open; only declared claims do).
Any one fork on the file suffices as of: sibling forks on an inode share one adouble, whose data-fork adf_lock[] holds ALL of the session's band entries (OPEN/DENY incl. the RSRC_* mirrors via rf2off) and its own content ranges; the rfork's adf_lock[] (reached via ad_rfp on the same adouble) holds only rfork content ranges. So one lookup sees every claim — unlike the post-delete sweep, which must visit each fork to close it.
| [in] | of | a fork this child holds on the file |
| [out] | band | held blocking band bits, positional (may be NULL) |
| [out] | content | set if a content byte-range lock is held (may be NULL) |
|
extern |
Search for open fork by dirfd/name.
Function call of_fstatat with dirfd and path and uses dev and ino to search the open fork table.
| [in] | dirfd | directory fd |
| [in,out] | path | pointer to struct path |
|
extern |
|
extern |
|
extern |
Conflict GET (F_GETLK only): read another holder's locks on a file.
Reuses a held fork's fd when one exists, else opens+closes a transient one. Reading through a held fd (never a transient open+close on an inode we hold a lock on) is what keeps the held byte locks from being dropped on close. The rfork is never opened onto of->of_ad (would corrupt ad_rlen / underflow the v2 meta refcount).
| [in] | vol | volume the target lives on |
| [in] | dirfd | directory fd for openat-style resolution, or -1 |
| [in] | path | target; both fork inodes derive from it |
| [in] | df_get | probe data-fork content if non-zero |
| [in] | df_off | data-fork content offset |
| [in] | df_len | data-fork content length (0 = whole data zone) |
| [in] | rf_get | probe resource-fork content if non-zero |
| [in] | rf_off | resource-fork content offset |
| [in] | rf_len | resource-fork content length (0 = whole zone) |
| [in] | band_request | share-mode band bitmap; OR together the per-offset *_BIT aliases from adouble.h (or ALL_BAND_BITS for all ten). Bit n maps to offset AD_FILELOCK_BASE + n. |
| [in] | try_root | retry the open as root on EACCES (the band is the server's own bookkeeping, not a user permission) |
| [out] | df_locked | set if the data-fork content range is locked |
| [out] | rf_locked | set if the resource-fork content range is locked |
| [out] | band_held | positional bitmap of held band bits (same positions as band_request) |
Data/band fd is fail-closed (any non-ENOENT failure -> ERROR). The rfork-content leg is best-effort (rf_locked stays 0 on open failure / the HAVE_EAFD && SOLARIS skip; the rfork band is still read via the data fd).
|
extern |
|
extern |
|
extern |