Casey,
thanks for your explanation.
On Mon, 03 Oct 2011 12:42:25 -0700, Casey Schaufler wrote:
The Linux filesystem semantics, inherited in all their
glory from UNIX, permit multiple directory entries to
refer to the same inode. That means that there can be
multiple names for the same object in the filesystem
name space. These names are all peers. None is the "real"
name of the object. The only possible real name for the
object is the inode number (combined with an identification
of the containing filesystem). This identifies the object
even when all entries in the filesystem namespace are
gone but the file is open. Auditible event can occur on
files that are open but have not filesystem entries.
Linux does not support multiple hardlinks to a directory[1] though?
Since the first argument to *at(2) syscalls is a dirfd, would it not be
possible to do something similar to getcwd(2)?
1. identify the root directory -> root
2. identify the given directory using the dirfd -> dir
3. until we reach root:
- open ".." -> parent
- scan for a dentry that matches dir
- dir = parent
4. reconstruct path from dentry components
d_path() in fs/dcache.c[2] seems to implement that.
I understand that this is ambiguous because of directory symlinks, but
it's better than the current situation. It would work out fine on
filesystems without symlinks (AFAIK this is only possible using FUSE on
Linux as of now, FreeBSD has had mount -o nosymlink for ages).
However, I'm not sure if it's worth the performance penalty. What about
making this configurable with sysctl? If enabled, PATH records for
syscall arguments consisting of a directory file descriptor will get
their name field reconstructed (best-effort/ambiguous). If disabled, the
name field will simply remain empty, instead of falling back to the cwd.
[1]
http://lwn.net/Articles/249607/
[2]
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=fs/...