attrctl - manipulate (extended) attributes of system objects
|
int count); |
The attrctl system call allows a user to attach name/value pairs to system objects typically filesystem objects (inodes).
This is a first draft proposal which may well *not* be the final interface it has been implemented to address some immediate issues with the current XFS implementation and is the first attempt at an interface which could allow both XFS and EXT2 extended attributes implementations to coexist.
Extended attributes can be used to store metainformation about a file, for example "characterset=kanji" could tell a document browser to use the Kanji character set when displaying that document and "thumbnail=..." could provide a reduced resolution overview of a high resolution graphic image.
The names can be up to MAXNAMELEN bytes in length, terminated by the first 0 byte. The intent is that they be printable ASCII (or other character set) names for the attribute.
The values can be up to ATTR_MAX_VALUELEN (currently 64KB) of arbitrary binary data.
Attributes can be attached to all types of inodes: regular files, directories, symbolic links, device nodes, etc.
There are 2 disjoint attribute name spaces associated with every filesystem object. They are the root and user address spaces. The root address space is accessible only to the superuser, and then only by specifying a flag to the operation request. Nonroot users will not see or be able to modify attributes in the root address space. The user address space is protected by the normal file permissions mechanism, so the owner of the file can decide who is able to see and/or modify the value of attributes on any particular file. The attribute get/list operations require read permission, and attribute set/remove require write permission.
Attributes are currently supported only in the XFS and EXT2 filesystem types. However, this system call has been designed to be generic and extensible, such that other filesystems should be able to make use of it.
The attrctl system call provides a way to access arbitrary extended attributes.
Obj indicates the system object whose extended attributes are to be manipulated. The contents of the attr_obj_t union are as follows:
typedef union {
|
char *path; |
|
int fd; |
type identifies the type of obj currently only file descriptors and path names are implemented (ATTR_TYPE_NAME and ATTR_TYPE_FD), but processes have also been proposed (ATTR_TYPE_PID).
Ops refers to an array of one or more input/output structures containing control information related to attribute operations and those operations' results.
The count argument indicates the number of structures in the ops array.
The contents of an attr_op_t structure are as follows:
typedef struct {
|
int opcode; /* which operation to perform (see below) */ |
|
int error; /* [out arg] result of this subop (an errno) */ |
|
char *name; /* attribute name to work with */ |
|
char *value; /* [in/out arg] attribute value (raw bytes) */ |
|
int flags; /* flags (bitwise OR of #defines below) */ |
void *aux; /* optional commandspecific data */
} attr_op_t;
The opcode field defines how the remaining fields are to be interpreted and can take on one of the following ATTR_OP values.
ATTR_OP_GET returns the value associated with attribute name. The size of the user buffer is passed in as length, and the size of the attribute value is returned in the same field. Valid flags are ATTR_ROOT and ATTR_DONTFOLLOW.
ATTR_OP_SET sets (possibly creating a new attribute) the value of the attribute specified by name to value. The length parameter specifies the size of the new value, and the valid flags are ATTR_ROOT, ATTR_DONTFOLLOW, ATTR_CREATE, and ATTR_REPLACE.
ATTR_OP_REMOVE provides a way to remove previously created attributes. If the attribute name exists, the attribute name and its associated value will be removed. Valid flags are ATTR_ROOT and ATTR_DONTFOLLOW.
ATTR_OP_LIST is used to list the existing attributes associated with an object. The name field is ignored - value and size specify the buffer to be filled with at least a portion of the attributes associated with the given object. An attrlist_t structure will be written into the value buffer, containing a list of the attributes associated with the object, up to a maximum of size bytes. The attrlist_t structure contains the following elements:
typedef struct {
__s32 count; /* number of entries in attribute list */
__s32 more; /* [in/out arg] more attrs (call again) */
|
__s32 offset[1]; /* byte offsets of attrs [varsized] */ |
The count field shows the number of attributes represented in this buffer, which is also the number of elements in the offset array. The more field will be nonzero if another ATTR_OP_LIST call would retrieve more attributes. The offset array contains the byte offset within the value buffer of the structure describing each of the attributes, an attrlist_ent_t structure. The ATTR_ENTRY(buffer, index) macro will help with decoding the list. It takes a pointer to the value and an index into the offset array, and returns a pointer to the corresponding attrlist_ent_t structure.
typedef struct {
|
__u32 valuelen; /* number of bytes in attribute value */ |
The valuelen field shows the size in bytes of the value associated with the attribute whose name is stored in the name field.
Valid flags for the ATTR_LIST command are ATTR_ROOT and ATTR_DONTFOLLOW. The aux pointer is used to reference an opaque cursor (type attrlist_cursor_t), which the kernel uses to track the calling process's position in the attribute list. The only valid operations on this cursor are to pass it into the operation or to zero it out (it should be zeroed before the first attrctl call. Note that multithreaded applications may keep more than one cursor in order to serve multiple contexts (i.e. the ATTR_LIST operation is "threadsafe").
All operations will set error to an error code if the operation fails, otherwise it will contain zero indicating success. The set of valid flags field values (combined using bitwise OR) is as follows:
|
ATTR_ROOT |
Look for attribute name in the root address space, not in the user |
ATTR_DONTFOLLOW Do not follow symbolic links when resolving a path on an attr_set
function call. The default is to follow symbolic links.
|
ATTR_CREATE |
Set error field (EEXIST) if an attribute of the given name already exists on the indicated object. This flag is used to implement a pure create operation, without this flag ATTR_SET will create the attribute if it does not already exist. |
|
ATTR_REPLACE |
Set error field (ENOENT) if an attribute of the given name does not already exist on the indicated object, otherwise replace the existing attribute´s value with the given value. This flag is used to implement a pure replacement operation, without this flag ATTR_SET will create the attribute if it does not already exist. |
The error field will be set (EINVAL) if both ATTR_CREATE and ATTR_REPLACE are requested in the same operation.
attrctl will return 0 on success, and an error code on any failure. Since the attrctl system call is arbitrarily extensible, and the intention is that it will always be used through an overlying API, refer to the manual pages for overlying API calls for specific error code values.
attrctl will always attempt to perform all operations, and a set of operations are not atomic (failure of one operation does not necessarily cause prior successful operations to be undone).
attr(1),
attr_list(3), attr_listf(3),
attr_multi(3), attr_multif(3),
attr_remove(3), attr_removef(3),
attr_set(3), attr_setf(3).