af_intro(3)
π af_intro(3) β the AtFS intro page, bestie edition π
okay so welcome to the Attribute Filesystem, aka AtFS, and this is the manual page that tells you what the whole thing even is. It's long, so it's split into 3 parts, and this is part 1. More parts are coming, so don't go anywhere π
β¨ NAME β¨
AtFS β the lil intro to all the AtFS library functions and the error codes, so you know what's what before you start calling stuff π
β¨ SYNOPSIS β¨
#include <atfs.h>
int af_errno
β¨ DESCRIPTION β¨
So the manual pages you're about to read, the ones all named af*, describe the library functions of the Attribute File System (AtFS).
AtFS is basically an extension to the UNIX file system interface, and what it does is let you store files as a complex of content data plus an arbitrary number of associated attributes. Those attributes come in two flavors: standard attributes and user defined attributes (which people also call application defined attributes). A whole data complex β the contents data and the attributes together β is called an Attributed Software Object (ASO). And just so you're not confused later: throughout these pages, ASOs also get called object versions, or just versions. iykyk π¦
AtFS has a built-in version control system that manages object histories. An object history is made of:
- an optional busy version, and
- a number of saved versions.
The busy version is just an ordinary, alterable UNIX file. You can get at it through AtFS and through regular UNIX file system operations. Saved versions come into being when you make a copy of the current state of the busy version. And those saved versions can be stored either as source versions or as derived versions.
πΈ source versions πΈ
Source versions are typically composed manually β think you, a text editor, and vibes. AtFS stores source versions as immutable objects, which is the fancy way of saying: once they're saved, they cannot be modified any longer, periodt. Saved versions live in archive files, which hang out in a subdirectory named AtFS. AtFS keeps two archive files for each history of source versions β one holding the attributes and the other holding the data. And to save disk space, versions in an archive are stored as deltas, meaning only the differences between two successive versions get stored. efficient queen π
πΈ derived versions πΈ
Derived versions are typically derived automatically (a compiler is the classic example) from a source version, which means they can be reproduced at any time. They're kept in a derived object cache β a data store of limited size that's administered in a cache fashion. When space runs short, old versions get cleaned out of the cache according to a defined policy. Check af_cache(3) for the details π
AtFS makes no assumptions about whether a copy of a busy object should be stored as a source object or as a derived object. That's on you, the application β you decide by calling the appropriate function:
af_saverevβ manual pageaf_version(3)af_savecacheβ manual pageaf_cache(3)
π the main data types for AtFS applications π
- The object key β uniquely identifies an ASO (version). The structure of this type can be different in different implementations of AtFS, so application programs should treat this type as an opaque type and should not access single fields. no peeking π
- A set descriptor β represents a set of object keys. It contains info about the size of the set and a list of object keys in the set.
- The user identification β represents a user. Since AtFS realizes a simple network user concept, it does not identify users by their UNIX user id. Instead it identifies them by the user name and the domain where this name is valid. See
af_afuser(manual pageaf_misc(3)) for the deets. - An attribute buffer β can hold all the attributes of a software object (standard attributes and user defined attributes). Attribute buffers have two different purposes:
- They can hold a retrieve pattern β i.e. they may be (partially) filled with the desired attribute values, and then passed as an argument to a retrieve operation (
af_findandaf_cachefindβ manual pageaf_retrieve(3)). - An attribute buffer is used to return all attributes of an identified ASO, on demand.
- They can hold a retrieve pattern β i.e. they may be (partially) filled with the desired attribute values, and then passed as an argument to a retrieve operation (
π¦ getting yourself an object key π¦
There are several ways for an AtFS application to get an object key pointing to a specific object version. The most important one is the function af_getkey (manual page af_retrieve(3)), which returns a key for an explicitly named version.
Once you've retrieved a key, the data for that object version stays cached in memory as long as the application doesn't explicitly give the key back. So:
af_dropkey(manual pageaf_retrieve(3)) β gives a key back and releases the object version.- A retrieved set of keys also has to be given back, using
af_dropset(manual pageaf_retrieve(3)). af_dropall(manual pageaf_retrieve(3)) β sets all reference counters for cached object versions to zero. Translation: it gives back all formerly retrieved keys and sets. bye besties π
β οΈ heads up: if any attribute, or the contents data of a cached object version, is modified on disk by another application, the data in the cache is automatically updated. And when that happens, a warning is written to the error log file. so keep an eye on that log, fr fr
π set algebra, we love her π
For handling sets of keys, AtFS provides a full set algebra, with functions for:
- adding and deleting single keys
- sorting
- building subsets
- intersections
- unions
- differences of sets
math but make it slay β¨
π the built-in version control functionality π
It features a status mode for versions. Each object version has a certain state, one of:
busysavedproposedpublishedaccessedfrozen
The already-known busy version always has the state busy. And when we previously referenced saved versions, we meant a version that can have any state from saved to frozen.
Now, important: AtFS does not enforce any specific semantics with the version state. It's more of a help for applications to implement their own classification for versions. So it's giving suggestion, not law π
Another part of the version control functionality is a locking facility. Adding a new version to an existing object history always requires a lock on the most recent version, or on the generation to which the version shall be added. Locks can be used for implementing a synchronization mechanism for concurrent updates to one object history. π
π user defined attributes π
A user defined attribute (or application defined attribute) has the general form:
name[=value [value [...]]]
It has a name and a (possibly empty) list of values. The name may consist of any characters (even non-alphanumeric ones) β except an equal sign (=). The equal sign is the delimiter between name and value.
β οΈ the attribute value may not contain Ctrl-A (\001) characters.
And even though AtFS promises storage of an arbitrary number of user defined attributes, the current implementation limits their number to 255. so like. 255. remember that π
π errors, the not-so-fun part π
Most of the AtFS calls have one or more error returns. An error is indicated by a return value that is either -1 or a nil pointer, depending on the return type of the function.
If one of the functions returns with an error, the variable af_errno is set to indicate the appropriate error number.
π¨ and this one's important: af_errno is not cleared upon successful calls. so don't go assuming a zero means everything's fine β check the return value, bestie π
part 1 done, more parts on the way π«Ά
β¨ ERROR CODES β¨
Okay bestie, here's the full tea on every error number defined in atfs.h. π« The first list? Those are your everyday "oops" return values β like when you pass a goofy argument to an AtFS function or you hit a permission wall. The second list? That's the serious trouble energy: either an internal error inside AtFS or a corrupted archive file. π When one of those serious problems happens, it gets recorded in an error protocol at /usr/adm/AtFSerrlog. And on machines where syslog(3) isn't switched on for AtFS, the error protocol lives at /tmp/AtFSerrlog instead. π
AF_ESYSERR (-2)β Error during execution of system library command or system call: A called system library function or system call returned with an error condition. Seeerrnofor a more precise error specification.AF_EACCES (-3)β permission denied: An attempt was made to perform an operation (e.g. open a file) without appropriate permissions.AF_EARCHANGED (-4)β archive file has changed since last read: One of the archive files you're operating on has been modified by another process since your process read it from disk. In this case, AtFS refuses to store your changes because that would destroy the modifications made by the other process. To make your desired changes happen, you have to rerun your application.AF_EBUSY (-7)β Specified ASO must not be a busy version: Some AtFS operations cannot be performed on ASOs which have the stateAF_BUSY.AF_EDERIVED (-8)β Specified ASO must not be a derived object: Some AtFS operations (eg.af_lock- manual pageaf_lock(3),af_newgen- manual pageaf_version(3)) cannot be performed on ASOs stored in derived object caches.AF_EINVKEY (-9)β invalid object key: An invalid object key (eg. nil pointer) was passed to an AtFS function.AF_EINVSET (-10)β invalid set descriptor: An invalid set descriptor (eg. nil pointer) was passed to an AtFS function.AF_EINVUSER (-11)β invalid user: An invalid user structure or user id was passed to an AtFS operation.AF_EINVVNUM (-12)β Bad version number: An attempt was made to set a version number, that contradicts the AtFS version numbering philosophy, to an ASO. You cannot change the version number of an ASO into a version number that is "smaller" than the one given by the system.AF_EMISC (-15)β miscellaneous errors: This error code is set when an error occurs that does not fit in any of the other error categories. See your error logging file (/usr/adm/AtFSerrlogof/tmp/AtFSerrlog) for a detailed description of the error.af_perror(manual pageaf_error(3)) also gives a diagnostic message explaining the error.AF_EMODE (-16)β invalid mode: The functionaf_setattr(manual pageaf_attrs(3)) requires a change mode. This error condition complains about an invalid mode given to this function.AF_ENOATFSDIR (-17)β AtFS subdirectory missing or not writable: There is no place where AtFS can create its archive files. Either a global archive path should be defined (seeaf_setarchpath- manual pageaf_misc(3)) or a subdirectory namedAtFSshould be present and writable.AF_ENOKEY (-18)β key does not exist in set: A specified key that shall be removed from a keyset does not exist in the concerning set.AF_ENOPOS (-19)β invalid position in set: A specified position in a keyset (keysets are organized as arrays of object keys) lies beyond the bounds of the concerning set.AF_ENOREV (-20)β specified revision does not exist: A revision β uniquely identified by a set of attributes (eg.af_getkey- manual pageaf_retrieve(3)) β does not exist in the current search space.AF_ENOTBUSY (-21)β specified ASO is not busy version: Some AtFS operations (eg.af_setbusy- manual pageaf_version(3)) require the key of a busy ASO as input parameter. If you pass key of a non-busy ASO, the function sets this error code.AF_ENOTDERIVED (-22)β specified ASO is no derived object: An attempt was made to restore an object that in not stored in a derived object cache.AF_ENOTLOCKED (-23)β specified ASO is not locked or locked by another user: An AtFS operation cannot be performed because the specified ASO is either not locked (seeaf_lock(3)) or it is locked by another user.AF_ENOTREGULAR (-24)β specified ASO is no regular file: With this error number AtFS refuses to generate versions of non-regular UNIX files such as directories, special files and sockets.AF_ENOTVERS (-25)β specified ASO has no versions: Typically, this error occurs if an operation requiring at least one saved revision (eg.af_newgen- manual pageaf_version(3)) is applied on a versionless file.AF_ENOUDA (-26)β user defined attribute does not exist: A user defined attribute with the given name does not exist.AF_ESAVED (-27)β saved versions cannot be modified: An attempt was made to open a non-busy version with write access.AF_ESTATE (-28)β invalid state transition: The Attribute File System's built in revision-states model allows only well defined revision state changes.AF_EWRONGSTATE (-31)β wrong state: Some AtFS operations can only be performed on ASOs with a specific version state.
The error codes indicating real trouble:
AF_EDELTA (-32)β Error during delta operation: Some error occurred during invocation of the delta processor.AF_EINCONSIST (-33)β Archive file inconsistent: The data in the archive file are corrupted. This may have happened by editing the archive file or by malfunction of an AtFS operation. Tryatfsrepair ti fix it.AF_EINTERNAL (-34)β internal error: Please inform your local trouble shooting service, go to your favorite pub and order a beers. Cheers !AF_ENOATFSFILE (-35)β No AtFS file: Archive file lost.
π BUGS π
ok so bestie, i need to be so fr with you rn. the built in archive file locking that's supposed to stop concurrent updates is very simple and it may lead to some genuinely confusing situations. like, the vibes get weird.
it may happen that changes will not be saved to disk. that's it. they're just gone. the file said "not today" and moved on with its life. π
want the receipts? go look at the error conditions AF_EARCHANGED and AF_EARLOCKED for more details. those two are the ones carrying the whole story, no cap.
π«Ά friendly reminder: simple locking = simple problems, and simple problems can still eat your work. know the error codes, check your returns, and stay safe out there.
π AUTHOR π
this absolute legend, the main character of this whole manpage, is Andreas Lampen, Tech. Univ. Berlin (Andres.Lampen@cs.tu-berlin.de) β¨
and here's the whole mailing situation, verbatim, because respect:
Technische Universitaet Berlin
Sekr. FR 5-6
Franklinstr. 28/29
D-10587 Berlin, Germany
πΈ okay that's the whole af_intro(3) page, start to finish, and honestly? ate. this version is AtFS-1.71, dated Fri Jun 25 14:32:56 1993 β yeah, 1993, this documentation has vintage main character energy and we're obsessed with her. thanks for reading all three parts with me, ily, now go check your error codes ππ
π¦
periodt. β¨
π¦ where this page comes from
- debian bookworm: atfs-dev 1.4pl6-15+b1
- ubuntu jammy: atfs-dev 1.4pl6-15
- ubuntu noble: atfs-dev 1.4pl6-16.1build1
- ubuntu resolute: atfs-dev 1.4pl6-17
- ubuntu stonking: atfs-dev 1.4pl6-17
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms