Skip to main content

Names: link, unlink, rename, and exchange

In the Master Server's metadata a file and its name are two records. The node holds the object and everything that belongs to the object. An edge holds one name in one directory and points from a parent to the node (metadata and namespace introduces the pair). This page describes the operations that work on edges: adding a second name, removing a name, renaming, and swapping two names in one call. Which timestamps these operations set is covered in timestamps.

A hard link is one more edge that leads to the same node. The Master Server creates the edge, raises the file's link count, and does nothing else. The Master Server touches no chunk, copies no attribute, and consults no pattern. Patterns are matched at creation and at rename. A new hard link is neither. The link count (nlink) that a client sees is the number of edges that lead to the node. No edge is special: the name that a file was created under has no priority over a name added later.

Everything except the name belongs to the node, so all names share what the node holds. This includes owner, permission bits, Storage Class, trash retention, and extra attributes, among the rest. A change made through one name is at once the state seen under every other name. A file linked into two directories still has one class and one retention, regardless of what the two directories would give to files created in those directories.

Every object type except a directory can have more than one name. The Master Server refuses a hard link to a directory. The Master Server answers a link to a file already in the trash or in the sustained area as if the file did not exist. A new link to an object marked immutable is refused. A link is also refused once the file's link count reaches MAX_ALLOWED_HARD_LINKS from mfsmaster.cfg, 32767 by default (limits lists the accepted range). The new name charges the file's full figures against the quotas of the directory that the file is linked into. The charges are itemized in quota enforcement.

A file needs a name or a holder​

Removing a name removes one edge. As long as any other edge remains, the node is untouched: the file keeps its chunks, its attributes, and its open descriptors. Only the link count drops. When the last name is removed, the file is no longer in the namespace. Trash retention covers what happens then. The node becomes a trash entry when its retention is above zero (trash retention explains the exception: by default, an empty file is destroyed). The node stays as a sustained file while a client holds the file open. Otherwise the node is destroyed.

The path that a trash entry records is the path of the name that was removed last. Names unlinked earlier leave no trace on the node. If a file had three names over its life, recovery can therefore rebuild only the name whose removal sent the file to the trash.

A rename moves the edge, reapplies the patterns​

A rename removes the source edge and creates an edge under the destination name. The node stays unchanged: same inode number, same chunks, same attributes, whether the new name is in the same directory or elsewhere in the tree. The destination directory gives the file nothing: inheritance of class, retention, and attributes happens at creation only. A file moved into a directory therefore keeps its own policy. A file created there would get the directory's policy instead.

A rename matches the patterns again. The destination name is matched against them in the same way as a newly created name. The winning pattern replaces the file's class, retention, or attributes in the same operation. How policies are applied covers that chain and what a class change starts. A rename is the only moment after creation when a file's policy can change without a command addressed to that file.

When the destination name already exists, the rename removes that name first. The file that this name pointed to follows the last-name rule above. With no other name and no holder, the file goes to the trash or is destroyed. A client that passes the RENAME_NOREPLACE flag of renameat2() is refused with "file exists" instead. Renaming a name onto another name of the same file succeeds and changes nothing, so both names stay. Since 5.2.0 this covers another hard link to that file as well as the very same directory entry.

An export can switch these operations off one by one. disable=rename refuses a rename that changes the name. disable=move refuses a rename that changes the directory. disable=link refuses a new hard link. An overwriting rename is also refused when the removal that it implies is disabled: under disable=unlink for a file target, under disable=rmdir for a directory target. The options are listed with mfsexports.cfg.

An exchange swaps two names and applies nothing​

renameat2() with the RENAME_EXCHANGE flag swaps two existing names in one operation. The two edges are removed and re-created crosswise, so each object keeps everything it had. Each object continues under the name and in the directory of the other object. Both names must exist. Unlike an ordinary rename, the swap consults no patterns for either object. The same distinction is made from the policy side in how policies are applied.

A directory has one name and no cycles​

A directory keeps the namespace a tree. Each directory has exactly one parent edge. Hard links to a directory are refused. The link count of a directory is 2 plus the number of its subdirectories.

A rename of a directory moves its whole subtree, so the Master Server refuses a rename whose destination is in the renamed directory itself or anywhere below that directory. The check goes through the ancestors of the destination directory. Moving a directory under a different parent also needs write permission on the directory being moved, because the move formally rewrites the parent (..) entry of that directory. A directory can be overwritten only by a directory, and only when the directory being overwritten is empty. A file cannot overwrite a directory. A directory cannot overwrite a file. In an exchange, the subtree rule is checked in both directions.

The protection attributes refuse the removal of names​

The three protection extra attributes act on names at the Master Server, so no mount setting bypasses them. An object marked undeletable, immutable, or appendonly cannot be unlinked. Nothing can be unlinked from a directory marked immutable or appendonly. A rename is refused when the renamed object is immutable, when its source directory is immutable or appendonly, or when the destination directory is immutable. An overwriting rename is refused when the destination directory is appendonly. Since 5.2.0, an overwriting rename is also refused when the name it would replace leads to an object marked undeletable, immutable, or appendonly. Up to 5.1.0, such a rename removed the protected name. Adding a hard link is refused when the linked file or the destination directory is immutable. An exchange is refused when either of the swapped objects is immutable, and when either of the two directories is immutable or appendonly.

OperationRefused when the object carriesRefused when the source directory carriesRefused when the destination directory carries
Unlinking a nameundeletable, immutable, appendonlyimmutable, appendonly
Adding a hard linkimmutableimmutable
Renaming onto a free nameimmutableimmutable, appendonlyimmutable
Renaming over an existing nameimmutable. Since 5.2.0, also a replaced object that carries undeletable, immutable, or appendonlyimmutable, appendonlyimmutable, appendonly
Exchanging two namesimmutable on either objectimmutable, appendonlyimmutable, appendonly