x gives you access to the inodes of the files (which means you can see their permissions and, according to it, have access to the contents), but you still cannot change anything in the directory; directory is actually some sort of a file and to change something in it you need the w permission.
Yes.
But why do you need x for creating (you could ask the system to create a file without exposing the inode?) and renaming/moving the file (when you move a file you don't change it in any way, you only change the records inside the directories and their inode counts?)?
Without x
, you can only affect the directory itself — you're seeing the directory from the outside. Without x
, the directory entries are out of bounds for you. If you want to add, remove, or modify (e.g. rename) an entry in the directory, you need to be able to access that entry.
The permissions on a file determine what you can do with the file's content. The permissions on the directory determine what you can do with the directory entry for the file, since the directory entries are the directory's content.
Write permission in a directory lets you create and remove entries. Renaming counts as atomically creating an entry and removing another one. Beyond that, directories have the same metadata as regular files. Write permission also lets you change the directory's last modification and last access timestamps. To change a directory's permissions, group ownership or access control lists (where supported), you need to own it. To change its user ownership, most unix variants require root.
You can easily get that information using stat
. As for ancestral directories, it is easily checked that if a file changes that this doesn't affect anything "up the hierarchy" by looking at /
:
root@pooh:/home/anthon-mint# stat /
File: ‘/’
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: 804h/2052d Inode: 2 Links: 30
Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2015-02-22 09:57:14.028146463 +0100
Modify: 2015-01-01 10:34:05.528461374 +0100
Change: 2015-01-01 10:34:05.528461374 +0100
Birth: -
as the system is constantly changing files, these values should be close to the current time.
If you create a new directory, and then a file in it, access and modification time of the directory change:
$ mkdir tmp
$ stat tmp
File: ‘tmp’
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: 700h/1792d Inode: 144141 Links: 2
Access: (0775/drwxrwxr-x) Uid: ( 1001/ anthon) Gid: ( 100/ users)
Access: 2015-02-27 16:19:02.523585508 +0100
Modify: 2015-02-27 16:19:02.523585508 +0100
Change: 2015-02-27 16:19:02.523585508 +0100
Birth: -
$ touch tmp/bla
$ stat tmp
File: ‘tmp’
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: 700h/1792d Inode: 144141 Links: 2
Access: (0775/drwxrwxr-x) Uid: ( 1001/ anthon) Gid: ( 100/ users)
Access: 2015-02-27 16:19:02.523585508 +0100
Modify: 2015-02-27 16:19:18.639585445 +0100
Change: 2015-02-27 16:19:18.639585445 +0100
Birth: -
Access time doesn't change, but the creation of the new file changes modification and change time.
Now touch the file again:
$ touch tmp/bla
$ stat tmp
File: ‘tmp’
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: 700h/1792d Inode: 144141 Links: 2
Access: (0775/drwxrwxr-x) Uid: ( 1001/ anthon) Gid: ( 100/ users)
Access: 2015-02-27 16:19:02.523585508 +0100
Modify: 2015-02-27 16:19:18.639585445 +0100
Change: 2015-02-27 16:19:18.639585445 +0100
Birth: -
$
And the directory doesn't change, but none of the information for the directory changes, as no new file is created.
Changing the mtime, atime, or ctime of an existing file has no effect on the directory it is in, nor on any of that directory's parents.
Best Answer
Think of a directory as a text file that looks something like:
That's all there is (at least in traditional Unix file systems).
foo.txt
is not a child of that directory in that it's not an exclusive relationship. It's just that the file of inode number 123 is referenced in two entries of that directory: with namesfoo.txt
andother-name-for-foo.txt
.Those two directory entries are also known as two hard links to the same file.
.
andother-dir
are two files of type directory, each containing a number of directory entries.ls
lists the entries of a directory whose names don't start with.
and with-i
includes the inode number.With
-a
(to include dotfiles), and-i
(ls -ai
), that's more or less dumping the content of that text file I was mentioning above.You'll notice that the file of inode 58879562 above is linked once to
other-dir
and twice to.
. That 58879562 file now has a link-count of 3, but neither.
norother-dir
care about that. That information is stored in the inode of the file and is just for the system to keep track of how many times the file is linked to a directory. If that number falls to 0, the disk space occupied by that file can be reclaimed.In addition to inode number and name, directories also contain the file type of the file (regular/fifo/directory/symlink/device..., though not for all file systems). That information can be retrieved otherwise (as it's stored in the inode) so is not necessary. It is done mainly for optimisation purposes and because it's possible. It is possible because it is not possible to change the type of a file (contrary to other metadata), so that information stored in the directory is not going to become out-of-sync with the reality.
You'll also notice that the system call to remove a file is not
remove("/foo/bar")
butunlink("/foo/bar")
. That's because all it does is remove thebar
entry from the/foo
directory, it unlinksbar
from/foo
. That file may still be linked to other (or the same by a different name) directory. It's only going to be removed when its link count reaches zero (when it's no longer linked to any directory).As to why doing an
ls
doesn't update the access time of a directory, that's probably because your filesystem is mounted with thenoatime
orrelatime
option.Updating the access-time of a file (directory or other) every time it is read is costly, so many systems give up on that nowadays.
Note that the system, if not the user reads directories all the time.
For instance, when accessing
/foo/bar
, the system needs to read the content of/
to findfoo
and then/foo
to findbar
(though most of the time that information is cached). However, in those cases, the atime is not updated (thankfully), only when user-space processes explicitely read the content of a directory likels
does.As to when the
ctime
of a directory is updated, that's the same as for a regular file: when its content is modified (entries added or removed or renamed) or its metadata (exceptatime
upon reading) is modified (like uponchmod
/chown
, ACL modifications...).