---------------------------------------------- Unix/Linux File System - (correct explanation) ---------------------------------------------- -Ian! D. Allen - idallen@idallen.ca - www.idallen.com Most diagrams showing file systems and links in Unix texts are wrong and range from confusing to seriously misleading. Here's the truth, complete with an ASCII-art file system diagram below. Names for files (and for other directories) are stored on disk in directories. Only the names are stored in the directory; the actual disk space for whatever is being named is stored somewhere else. Also in the directory, beside each name, is a number indicating where to find the disk space used to actually store the thing being named. This means that the names and the actual storage for the things being named are in separate places. Most texts make the error of writing file system diagrams that put the names right on the things that are being named. That is misleading and the cause of many misunderstandings about Unix/Linux files and directories. The name of a thing (file, directory, special file, etc.) is kept in a directory, separate from the storage space for the thing it names. (This allows things to have multiple names and names in multiple directories; all the names refer to the same storage space.) ------------- Inode numbers ------------- The actual data for each Unix file or directory stored on disk is managed by on-disk data structures called "inodes" (index nodes). One inode is allocated for each file and each directory. Unix inodes have unique numbers, not names, and it is these numbers that are kept in directories alongside the names. The "-i" option to "ls" shows these inode numbers. A Unix inode manages the disk storage space for a file or a directory. It contains a list of pointers to the disk blocks that belong to that file or directory. The larger the file or directory, the more disk block pointers it needs in the inode. Also stored in the inode are the attributes of the file or directory (permissions, owner, group, size, access/modify times, etc.); but, not the name of the file or directory. Inodes have only numbers, attributes, and disk blocks - not names. The names are kept separately, in directories. Everything in a Unix file system has a unique inode number that manages the storage for that thing: every file, directory, special file, etc. Files and directories are both managed with inodes. Directory inodes ---------------- File and directory names are stored in directories, not in the inodes with the things that they name. The *name* of a file or directory is not kept in the inode with the file attributes or pointers to disk blocks; the name is kept in a directory somewhere else. Directories are what give names to inodes on Unix. Directories can be thought of as "files containing lists of names and inode numbers". Files have disk blocks containing file data; directories also have disk blocks; but, the blocks contain lists of names and inode numbers. Like most other inodes, directory inodes contain attribute information about the inode (permissions, owner, etc.) and one or more disk block pointers in which to store data; but, what is stored in the disk blocks of a directory is not file data but directory data (names and inode numbers). A Unix directory is simply a list of pairs of names and associated inode numbers. That is all - the disk blocks of Unix directories contain only names and inode numbers. The rest of the attribute information about an item named in a directory (permissions, owner, etc.) is kept with the inode associated with the name. You must use the inode number from the directory to find the inode on disk to read its attribute information; reading the directory only tells you the name and inode number. Reading a Unix directory tells you only some names and inode numbers; you know nothing about what kind of things those names and inodes are unless you actually go out to the inodes on disk and access them. Without actually accessing the inodes, you can't even tell whether a name in a directory is the name of a file or the name of a sub-directory. To identify the name, you must use the associated inode number to find the inode of the item and look at the item's attributes. This is why "ls" or "ls -i" are much faster than "ls -l", since "ls -l" has to do a lookup on every inode in the directory to find out the inode attributes; but, "ls" or "ls -i" only needs to read the names and inode numbers from the directory - no additional inode access is needed (because no attributes are being queried). No attribute information about the things named in the directory is kept in the directory. The directory only contains pairs of names and inode numbers. (But remember that since the storage for each directory is itself managed by an inode, the inode for the directory itself contains attribute information about the *directory*, not about the things named in the directory.) To find a thing by name, the system goes to a directory inode, looks up the name in the disk space allocated to that directory, finds the inode number associated with the name, then goes out to the disk a second time and finds that inode. If that inode is another directory, the process repeats from left-to-right along the pathname until the inode of the last pathname component (on the far right in the pathname) is found. Then the disk block pointers of that last inode can be used to find the data contents of the last pathname component. The name and inode number pairing in a Unix directory is the only connection between a name and the thing it names on disk. The name is kept separate from the data belonging to the thing it names (the actual inode on disk). If a disk error damages a directory inode or the directory disk blocks, file data is not usually lost; since, the actual data for the things named in the directory are stored in inodes separate from the directory itself. If a directory is damaged, only the names of the things are lost. The storage used for the things themselves is elsewhere on disk and may be undamaged. The name of an item (file, directory, etc.) and its inode number are kept in a directory. The directory storage for that name and number is managed by its own inode that is separate from the inode of each thing in the directory. The name and number are stored in the directory inode; the data for the item named is stored in its own inode somewhere else. Multiple names - hard links --------------------------- Because (1) a file is managed by an inode with a unique number, (2) the name of the file is not kept in that inode, and (3) directories pair names with inode numbers, a Unix file (inode) can be given multiple names by having multiple name-and-inode pairs in one or more directories. Inode 123 may be paired with the name "cat" in one directory and the same 123 may be paired with the name "dog" in the same or a different directory. Either name leads to the same 123 file inode and the same data and attributes. Though there appear to be two different files "cat" and "dog" in the directory, the only thing different between the two is the name - both names lead to the same inode and therefore to the same data and attributes (permissions, owner, etc.). Multiple names for the same inode are called "hard links". The "ln" command can create a new name (a new hard link) in a directory for an existing inode. The system keeps a "link count" in each inode that counts the number of names each inode has been given. The "rm" command removes a name (a hard link) from a directory, decreasing the link count. When the link count for an inode goes to zero, the inode has no names and the inode is recycled and all the storage and data used by the item is released. The "rm" command does not remove files; it removes names. When all the names are gone, the system removes the file and releases the space. --------------------------- Tracing Inodes in Pathnames --------------------------- When you look at a Unix pathname, remember that that the slashes separate names of pathname components. All the components to the left of the rightmost slash must be directories, including the "empty" ROOT directory name to the left of the leftmost slash. For example: /home/alex/foobar In the above example, there are three slashes and therefore four pathname components. The "empty" name in front of the first slash is the name of the ROOT directory. The ROOT directory doesn't have a name. (Some books get around this by calling the ROOT directory "slash" or "/". That is wrong. ROOT doesn't have a name - slashes *separate* names.) Inside the ROOT directory is the name of the "home" directory. Inside the home directory is the name of the "alex" directory. Inside the alex directory is the name of the "foobar" file. The last (rightmost) component of a pathname can be a file or a directory; for this example, let's assume it's a file name. Below is a file system diagram written correctly, with the names for things shown one level *above* the things to which the names actually refer. Each box represents an inode; the inode numbers for the box are given beside the box, on the left. Inside the directory inodes you can see the pairing of names and inode numbers. (These inode numbers are made up - see your actual Unix system for the real inode numbers.) One of the inodes, #12, is not a directory; it is an inode for a file and contains the file data. The downward arrows trace two paths (hard links) to the same #12 file data, /home/alex/foobar and /home/alex/literature/barfoo: We will trace the inodes for two pathnames in the diagram below: 1. /home/alex/foobar 2. /home/alex/literature/foobar Follow the downward-pointing arrows: +----+-----+-----------------------------------------+ #2 |. 2 |.. 2 | home 5 | usr 9 | tmp 11 | etc 23 | ... | +----+-----+-----------------------------------------+ | The inode #2 above is the ROOT directory. It has the | name "home" in it. The *directory* "home" is not | here; only the *name* is here. The ROOT directory | itself does not have a name! V +----+-----+---------------------------------------------------+ #5 |. 5 |.. 2 | alex 31 | leslie 36 | pat 39 | abcd0001 21 | ... | +----+-----+---------------------------------------------------+ | The inode #5 above is the "home" directory. The name | "home" isn't here; it's up in the ROOT directory, | above. This directory has the name "alex" in it. V +----+-----+---------------------------------------------------+ #31 |. 31|.. 5 | foobar 12 | temp 15 | literature 7 | demo 6 | ... | +----+-----+---------------------------------------------------+ | The inode #31 above is | | the "alex" directory. The | | name "alex" isn't here; | | it's up in the "home" | | directory, above. This | | directory has the names | | "foobar" and "literature" | | in it. | | V +----+-----+--|-------------------------------------------+ #7 |. 7 |.. 31| | barfoo 12 | morestuf 123 | junk 99 | ... | +----+-----+--|-------------------------------------------+ | | The inode #7 above is the "literature" directory. | | The name "literature" isn't here; it's up | | in the "alex" directory. This directory has | | the name "barfoo" in it. | | V V *-----------* This inode #12 on the left is a file inode. | file data | It contains the data blocks for the file. #12 | file data | This file happens to have two names, "foobar" | file data | and "barfoo", but those names are not here. *-----------* The names of this file are up in the two directories that point to this file, above. The pathname /home/alex/foobar starts at the nameless ROOT directory, inode #2. It travels through a total of three directory inodes and stops at file inode #12. Using inode numbers, /home/alex/foobar could be written as #2->#5->#31->#12. The pathname /home/alex/literature/barfoo starts at the ROOT and travels through a total of four directory inodes. It stops at the same #12 file inode as /home/alex/foobar. Using inode numbers, /home/alex/literature/barfoo could be written as #2->#5->#31->#7->#12. Thus, /home/alex/foobar and /home/alex/literature/barfoo are two pathnames leading to the same inode #12 file data. The names "foobar" and "barfoo" are two names for the same file and are called "hard links". Tracing Pathname 1: /home/alex/foobar ------------------------------------- Let's examine each of the above inodes. The box below represents the layout of names and inode numbers inside the actual disk space given to the nameless ROOT directory, inode #2: +----+-----+-----------------------------------------+ #2 |. 2 |.. 2 | home 5 | usr 9 | tmp 11 | etc 23 | ... | +----+-----+-----------------------------------------+ The above ROOT directory has the name "home" in it, paired with inode #5. The actual disk *space* of the directory "home" is not here; only the *name* "home" is here, alongside of its own inode number #5. To read the actual contents of the "home" directory, you have to find the disk space managed by inode #5 somewhere else on disk and look there. The above ROOT directory pairing of "home" with inode #5 is what gives the "home" directory its name. The name "home" is separate from the disk space for "home". The ROOT directory itself does not have a name; because, it has no parent directory to give it a name! The ROOT directory is the only directory that is its own parent. If you look at the ROOT directory above, you will see that both the name "." and the name ".." in this ROOT directory are paired with inode #2, the inode number of the ROOT directory. Following either name "." or ".." will lead to inode #2 and right back to this same ROOT inode. Let us move to the storage space for the "home" directory at inode #5. The box below represents the layout of names and inode numbers inside the actual disk space given to the "home" directory, inode #5: +----+-----+---------------------------------------------------+ #5 |. 5 |.. 2 | alex 31 | leslie 36 | pat 39 | abcd0001 21 | ... | +----+-----+---------------------------------------------------+ The name "home" for this inode isn't in this inode; the name "home" is up in the ROOT directory. This "home" directory has the name "alex" in it, paired with inode #31. The *directory* "alex" is not here; only the *name* "alex" is here. To read the "alex" directory, you have to find inode #31 on disk and look there. (In fact, until you look up inode #31 and find out that it is a directory, you have no way of even knowing that the name "alex" is a name of a directory!) Let us move to the storage space for the "alex" directory at inode #31. The box below represents the layout of names and inode numbers inside the actual disk space given to the "alex" directory, inode #31: +----+-----+---------------------------------------------------+ #31 |. 31|.. 5 | foobar 12 | temp 15 | literature 7 | demo 6 | ... | +----+-----+---------------------------------------------------+ The name "alex" for this inode isn't in this inode; the name "alex" is up in the "home" directory. This "alex" directory has the name "foobar" in it, paired with inode #12. The *file* "foobar" is not here; only the *name* "foobar" is here. To read the data from file "foobar", you have to find inode #13 on disk and look there. (In fact, until you look up inode #13 and find out that it is a plain file, you have no way of even knowing that the name "foobar" is a name of a plain file!) Let us move to the storage space for the "foobar" file at inode #12. The box below represents the the actual disk space given to the "foobar" file, inode #12: *-----------* #12 | file data | *-----------* The name "foobar" for this inode isn't in this inode; the name "foobar" is up in the "alex" directory. This "foobar" inode is a file inode, not a directory inode, and the attributes of this inode will indicate that. The inode for a file contains pointers to disk blocks that contain file data, not directory data. There are no special directory names "." and ".." in files. There are no names here at all; the disk block pointers in this inode point to just file data (whatever is in the file). This completes the inode trace for /home/alex/foobar: #2->#5->#31->#12 Tracing Pathname 2: /home/alex/literature/barfoo ------------------------------------------------ Let's now trace the inode path for the name /home/alex/literature/barfoo. This pathname is a "hard link" to /home/alex/foobar; both the foobar and barfoo names point to the same inode number. Let's see how: Let us look back at inode #31 (a directory inode) and follow the trail to the "literature" directory that is stored at inode #7. The box below represents the layout of names and inode numbers inside the actual disk space given to the "literature" directory, inode #7: +----+-----+---------------------------------------------+ #7 |. 7 |.. 31| barfoo 12 | morestuf 123 | junk 99 | ... | +----+-----+---------------------------------------------+ The name "literature" for this inode isn't in this inode; the name "literature" is up in the "alex" directory. This "literature" directory has the name "barfoo" in it, paired with inode #12. The actual *data* for the thing that is "barfoo" is not here; only the *name* "barfoo" is here. You will note that we have seen inode #12 already. Above, in the "alex" directory (inode #31), inode #12 was also paired with the name "foobar". In the "literature" directory (inode #7), inode #12 is paired with the name "barfoo". Inode #12 now has two different names; names "foobar" and "barfoo" are both hard links to the same inode #12: $ ls -i /home/alex/foobar /home/alex/literature/barfoo 12 /home/alex/foobar 12 /home/alex/literature/barfoo Two names means the "link count" of inode #12 is set to "two". Both names lead to the same #12 inode and thus to the same data and same attributes. This is *one* single file with *two* names. A change to the file data using the name "foobar" changes the data in inode #12. That changes file data for the name "barfoo" too; because, "foobar" and "barfoo" are two names for the same #12 inode storage - they are two names that point to the same storage inode. Everything about data inode #12 except its name is kept with the inode. The only thing different in a long listing of "foobar" and "barfoo" will be the names; everything else (file type, permissions, owner, group, link count, size, modification times, etc.) is part of inode #12 and must therefore be identical for the two names. Neither name is more "original" than the other; both names have equal status. To release the #12 inode storage, you have to delete both names (so the link count drops to zero). -------------- Path Traversal -------------- Let's use the above inode data to follow a valid path such as: /home/alex/literature/barfoo Start on the left and walk the tree to the right. To be a valid Unix path, everything to the left of the rightmost slash must be a directory. (Thus, ROOT, "home", "alex", and "literature" must be directories.) Start with the nameless ROOT directory in front of the first slash (ROOT doesn't have a name, since it does not appear in any parent directory) and look for the first pathname component ("home") inside that directory (inside inode #2). Let's trace the pathname: Look in the ROOT directory (located in inode #2) for the name of the first pathname component: "home". We find the name "home" inside the ROOT directory, paired with inode number 5. Go back out to the disk to find the "home" directory that is inode 5. [Note how the names are separate from the things they name. The actual directory inode of "home" (#5) is not the same as the inode of the ROOT directory containing the name "home" (#2). The name is in a different place than the thing it names.] In the directory that has the name "home" (inode #5), look for the name "alex". We find "alex" paired with inode #31. Go back out to the disk to find the "alex" directory that is inode #31. [Again, the name "alex" contained in directory "home" (inode #5) is separate from the inode that is the actual directory "alex" (inode #31).] In the directory that has the name "alex" (inode #31), look for the name "literature". We find "literature" paired with inode #7. Go back out to the disk to find the "literature" directory that is inode #7. (Again, the name "literature" contained in inode #31 is separate from the inode #7 that is the actual directory "literature".) In the directory that is "literature", look for the name "barfoo". We find it paired with inode #12. Go back out to the disk to find the "barfoo" file that is inode #12. (Again, the name is separate from the thing it names, so the name is not part of the inode data that makes up the actual file.) You now have the disk node (inode) that is your file data: inode #12. If that file inode has appropriate permission attributes, you can read it or write it. It is the permission attributes on the inode containing the file data that govern what you can do with the data. The permissions on the directory containing the *name* of the file don't matter, once you have found the inode containing the file data itself. (If the inodes of the directories leading down to the file inode #12 don't give you search permission, you won't be able to reach the file's inode that way and won't be able to access the file's data using those directories; but, perhaps some other directories may lead you there.) To access the data in a file path such as: /home/alex/literature/barfoo you need appropriate permissions on the ROOT directory inode, the "home" directory inode, the "alex" directory inode, the "literature" directory inode, and finally the "barfoo" file data inode. It is the "barfoo" file data inode permissions (inode #12) that determine whether or not you can read or change the *data* of the file. Reading or changing the data in the file requires permissions on the data blocks inode of the file itself. It is the "literature" directory inode permissions (inode #7) that determine what you can do with the *name* of the file, because the "literature" directory is where the name "barfoo" is kept. Changing or removing the name of a file operates on the inode of the directory in which the file name appears; altering the name has nothing to do with changing the data of the inode of the file itself. You can have no permissions on the inode of the file (it may even be owned by some other user) and still be able to rename or remove the name of the file from a directory on which you do have permissions. Names are separate from the things that they name. The permissions are also separate. Changing a name requires permissions on a directory. Changing the content of a file requires permissions on the data inode of the file itself (not on the directory that names the file). ------------------- Notes and Questions ------------------- "What permissions do I need on a file to delete it from a directory?" None! You don't even have to own the file. You need *write* and *search* permissions on the *directory* that contains the *name* of the file, to remove the *name* of the file from the *directory*. (When all links to a file are gone, the file is reclaimed by the system.) Removing a file is a directory operation that deletes a name (a name is a link); it has absolutely nothing to do with the permissions or owner on whatever the link happens to point to. If you can write and search the directory that contains the file name ("wx" permissions on the directory), you can delete the file name (the link) from the directory. "What if I want to delete a sub-directory from a directory?" You need "wx" permissions to remove the sub-directory name from the directory, just as if the name pointed to a file. However: You can only delete from a directory a name that points to a sub-directory if that other sub-directory is *empty*. If you don't have permission to empty out that sub-directory, you won't be able to delete its name from its parent directory, even if you have permissions on the parent directory. Scenario: cannot delete non-empty directory Alex creates, in his home directory, a sub-directory "foo" with write permissions for everyone. Ian creates a sub-sub-directory "foo/bar" with permissions only for Ian, and then Ian creates a file "foo/bar/haha". It is now impossible for Alex to delete the foo sub-directory from his own home directory, because Alex cannot empty out and remove the sub-sub-directory foo/bar, because only Ian has permissions to remove the file name foo/bar/haha from the foo/bar sub-sub-directory. (Only Ian can write the sub-sub-directory named foo/bar.) Alex is stuck with the foo sub-directory in his account. Alex can rename the directory (e.g. "mv foo .junk", which changes the name) because Alex has permissions on the inode of his home directory; but, he can't actually remove the foo directory name from his home directory until Ian makes the foo directory empty. Only empty directories may be deleted. Directories Permissions Rule: "X" (execute) permissions on a directory mean you can pass "through" the directory to access a thing if you already know the name of the thing you want to access. ("X" means "search permission" for dirs.) "R" permissions on a directory mean you can see the names in the directory. (Directories only contain names and inode numbers.) You can *not* use "ls" to generate a *long* listing of the files in a directory ("ls -l") unless you have X permissions to pass through the directory to find out what kind of nodes the names in the directory represent. You *can* get a short listing of just the *names* in a directory without needing X permissions (only "read" is needed on the directory to see just the names in a directory). Without going out to the inodes associated with the names in a directory, you don't know what kinds of things the names name. In other words: If you don't have R permission, you can't see the names inside a directory. If you happen to know some names, and you have X permission, you can go *through* the directory to get to the things pointed to by the names that you already know. If you don't have X permission, then you can't *get to* the files, even if you have R permission and can see their names. Names are separate from content; you may be able to see the names without being able to pass through the directory to go get the content contained in the inodes associated with those names. "I'm logged in as idallen over in /home/idallen. What permissions do I need to read file ../alex/demo?" "../alex/demo" is a *relative* pathname. It starts with the current directory "/home/idallen" and goes up from there and back down again. All relative paths start in the current directory. We need X permission on the current directory to let us pass through using name ".." at the beginning of "../alex/demo", to its parent directory. In this example, the parent directory of "/home/idallen" would be "/home". ".." is a relative pathname, meaning it starts with an entry in our current directory, and so we must have X perms on the current directory to use the name ".." in the current directory to go up one level to the "/home" directory above "/home/idallen". Next, we must use "alex" in the ".." directory, and ".." is "/home". We need X permission on the directory ("/home") to pass through it using name "alex" to the inode that is the actual directory named "alex". (Remember - names are separate from the things they name!) We do *not* need R permission on the /home directory, only X. Next, we must use "demo" in the "/home/alex" directory. We need X permission on the inode of the directory "/home/alex" to pass through it using name "demo" to the actual file inode for the name "/home/alex/demo". We do *not* need R permission on the /home/alex directory, only X. We need R permissions on the "demo" file inode to read the file data. We do *not* need X permission on the file, only R. "I'm logged in as idallen over in /home/idallen. What permissions do I need to read file /home/alex/demo?" "/home/alex/demo" is an *absolute* pathname. It ignores the current directory. Nothing about the current directory is needed. The path search starts from the ROOT directory. The following sequence is identical, no matter what directory is your current directory: You need X permission on the ROOT directory to pass through it using name "home" to the inode of the directory named "home". (Remember - names are separate from the things they name!) You do *not* need R permission on the ROOT directory. Next, we must use "alex" in the "/home" directory. We need X permission on the inode of the "/home" directory to pass through it using name "alex" to inode that is the actual directory named "alex". (Remember - names are separate from the things they name!) You do *not* need R permission on the /home directory, only X. Next, we must use "demo" in the "/home/alex" directory. We need X permission on the inode of the directory "/home/alex" to pass through it using name "demo" to the actual file inode for the name "/home/alex/demo". We do *not* need R permission on the /home/alex directory, only X. We need R permissions on the "demo" file inode to read the file data. We do *not* need X permission on the file, only R. "The *name* of a file is separate from the actual file data. What information *is* kept with the file data?" Everything else, except the name, is part of the inode that holds the file data. This means: owner, group, access and modify times, permissions, size, etc. None of this information appears in the directory; it is all kept in the file inode along with the pointers to the disk blocks that contain the actual file data. No matter what name you use to find a file's inode on disk, the file has the same owner, group, permissions, etc. because one copy of all that information is kept in the inode *with the file data*, not in the directory. Only the name is kept in the directory. The only things you will find in a Unix directory are names and inode numbers - everything else is in the inode of the file. Explain this sequence (removing X permission on a directory): $ mkdir /tmp/idallen $ cd /tmp/idallen $ touch a b c d $ ls a b c d $ chmod -x . $ ls ls: .: Permission denied $ ls .. ls: ..: Permission denied $ ls a b c d ls: a: Permission denied ls: b: Permission denied ls: c: Permission denied ls: d: Permission denied $ ls /tmp/idallen a b c d $ ls -l /tmp/idallen ls: /tmp/idallen/a: Permission denied ls: /tmp/idallen/b: Permission denied ls: /tmp/idallen/c: Permission denied ls: /tmp/idallen/d: Permission denied $ ls /tmp/idallen/a ls: /tmp/idallen/a: Permission denied $ ls -l /tmp/idallen/a ls: /tmp/idallen/a: Permission denied $ chmod +x . chmod: .: Permission denied $ chmod +x /tmp/idallen $ ls a b c d Note how "ls -l /tmp/idallen" can find the *names* in the directory (because it can read the directory); but, it can't go *through* the directory to actually look at what the names point to. So "ls -l" can't give you a long listing to tell you anything about what the names actually *are*. An "ls -l" long listing needs to know what the names *are* - it requires more permissions that a plain "ls" that only needs to know the names, not what they are. You must also have "X" permissions on a directory for "ls -l" to work. And now study this one (removing R permission on a directory): $ mkdir /tmp/idallen $ cd /tmp/idallen $ touch a b c d $ ls a b c d $ chmod -r . $ ls ls: .: Permission denied $ ls .. file1 file2 file3 idallen $ ls a b c d a b c d $ ls /tmp/idallen ls: /tmp/idallen: Permission denied $ ls -l /tmp/idallen ls: /tmp/idallen: Permission denied $ ls /tmp/idallen/a /tmp/idallen/a $ ls -l /tmp/idallen/a -rw-r--r-- 1 idallen users 0 Jan 28 13:43 /tmp/idallen/a $ chmod +r . $ ls a b c d Without read permission on the directory, we can't find out what names are in the directory. But, if we already know some of the names in the directory, we can go through the directory to get the details about the inodes that the the names point to, because we still have X (search) permission. We can't see the names; but, we can use them. --------------------- A Study in File Links --------------------- What is the "link count" field displayed by the "ls -l" command? What causes a file's link count to increment? What happens when a file's link count becomes zero? What is the link count of an empty directory? Why? On any Unix/Linux system, use the "-i" option to "ls" on this set of files: $ ls -li /usr/bin/*sh Note the inode numbers of each name in this directory. Which names are really the same file? (The inode numbers will tell you!) Sort the output to make the inode numbers that are the same come together and be easier to see: $ ls -li /usr/bin/*sh | sort Look at the entire /usr/bin directory and note which names in this directory are actually pointers (hard links) to the same file: $ ls -li /usr/bin | sort | more Where is the name of the file "csh" stored? Where is the name of the directory "bin" stored? Where is the name of the directory "usr" stored? --------------------- Links and Directories --------------------- - Normally when you do "ls -l dir" you see the permissions of the *contents* of the directory, not the directory itself. What command and options are needed to see the access permissions and link count of a directory, instead of the *contents* of a directory? (RTFM) - When you are inside a directory, what is the name you use to refer to the directory itself? (This name works inside any directory.) What name always refers to the unique parent directory? - How many links does a brand new, empty directory have? Why isn't it just one link, as it is for a new file? (In other words, why does a new file have one link and a new directory have more than that?) - Why does creating a sub-directory in a directory cause the directory's link count to increase by one for every sub-directory created? (Recall that a link count is a count of names.) - Why doesn't the link count of the directory increase when you create files in the directory? - Give the Unix command and its output that shows the inode number and owners of the following directories: a) your HOME directory b) your current directory c) your parent directory d) the /home directory e) the root directory Note: Show only one line of output for each single directory; do not show the contents of the directory. Use a command (and options) that will show only the directory itself, not its contents. (RTFM) -- | Ian! D. Allen - idallen@idallen.ca - Ottawa, Ontario, Canada | Home Page: http://idallen.com/ Contact Improv: http://contactimprov.ca/ | College professor (Free/Libre GNU+Linux) at: http://teaching.idallen.com/ | Defend digital freedom: http://eff.org/ and have fun: http://fools.ca/