Larry Osterman's WebLog

Confessions of an Old Fogey
Blog - Title

..

..

  • Comments 24

Way back when when NTFS was first being designed, the designers of the filesystem had a problem - what should they do with "." and "..".  Traditionally, in *nix filesystems (and MS-DOS's FAT filesystem), "." and ".." were two hard links that were created by the mkdir command that included links to the current and parent directory. 

For subdirectories, "." and ".." posed no issues at all - NTFS could do exactly what *nix and FAT did - create links to the parent and current directory and be done with it.

But there was a problem with the root.  You see, *nix just had a "." in the root, HPFS had "." in the root, but FAT didn't have any special characters in the root. 

The NTFS guys decided to treat the root exactly the same as any other directory - the root would have a "." and a "..", both of which linked to the root directory.  That way apps that traversed should behave correctly.

When they rolled this out, I raised some issues about appcompat to the NTFS team, and their answer was "Nah, it shouldn't be a problem, after all, the worst thing that can happen is if they traverse ".." through the root - no big deal.  And it made their design much cleaner - there was nothing special about the root directory, it was just another directory.

 

 

Anyone who's read Raymond's blog knows exactly what happened next :).

 

Yup, the bugs started coming in.  You see, applications that tried to present pretty dialogs for navigation (like the common file dialog) allowed the user to type in ".." into their control (or select the ".." entry).  Because they wanted to be helpful, they would also show the full path to the file, so when you clicked on ".." it removed the last path element from the file (so "C:\Users\LarryO\Pictures" would be displayed as "C:\Users\LarryO" in the title of the dialog box).  Of course, when you clicked on the ".." entry in the root, they immediately crashed because they tried to navigate through "C:" and couldn't find a \ to back up.

 

So the NTFS guys had to rethink their plans for the root directory.  They probably could have gotten away with having just "." in the root and no "..", but the developers decided to be safe - "If FAT doesn't put entries in the root, we won't."  And thus the root directory on NTFS partitions doesn't contain a "." or ".." entry.

 

 

This post written with Windows Live Writer.

Edit: Replaced symlinks with hard links.

 

  • Immediately thought of a few situations where such a change would lead to an infinite loop, although I question whether anyone has actually written such code.

    Anyway, the weirdest part about this all is that running "CD ." works in the root directory on Windows 98 using FAT, even though "CD .." does not.

    In Windows XP using NTFS, both "CD ." and "CD .." work in the root.  This leads me to believe that both shells have special-casing for "." and ".." for some commands.

    I wonder, is it possible to delete the "." and ".." symlinks in any filesystem/operating system?  What's to stop something from removing them at a low level?  What kind of chaos happens if they are gone?  Do disk-checking (chkdisk or fsck) fix these problems?
  • Interesting, I never noticed the missing '.' & '..' in the root on NTFS volumes.

    "type .\autoexec.bat" however still works when you run it from the root. I wonder how that is implemented.

    -
  • In Unix, . and .. are *hard* links.  Not symbolic links.
  • > For subdirectories, "." and ".." posed no issues at all - NTFS
    > could do exactly what *nix and FAT did - create symlinks to
    > the parent and current directory and be done with it.

    In Unix they're hard links, and Unix had "." and ".." before it even had symlinks.

    Though the command "cd .." behaves differently in Linux than in every other Unix system I've used, and I always thought Linux's "cd" command was coded specially to do that, but now you make me wonder if Linux has made ".." into symlinks instead.

    This is the first I've heard about FAT having symlinks.

    Thursday, September 07, 2006 3:55 PM by TheMuuj
    > I wonder, is it possible to delete the "." and ".." symlinks in
    > any filesystem/operating system?

    Considering that they were (and usually if not always still are) hard links, think of what might happen when "rm -r" gets to "..".  My understanding is that the "rm" command got some extra coding added to it very quickly, maybe when only around 3 people had ever heard of Unix ^_^
  • You're right Clinton.

    Norman, they were special symlinks - exactly the same as they were implemented on *nix - the root FAT index on the parent drive simply was the FAT index of the parent and similarly the . pointed to itself.  chkdsk knew about these entries and knew how to verify them.

    For RM, it had special code to bypass . and ..  So did a bunch of "tree walking" utilities.

  • To understand about hard links in UNIX you need to understand a little bit about how directories and inodes are associated with each other.

    A directory in it's most simplest form is a list of inode numbers and file names.

    An inode can have an entry in more than one directory. These are called "hard links". For each one of these a link count in the inode is incremented.

    Now, if we have a look at the root of the directory tree (here's where Unix differs as it uses a single rooted tree as against a rooted tree per drive), we see that the entries for '.' and '..' are pointers to the same inode (for historical reasons this happens to be inode 2).

    The filesystem has no concept of orignal and linked copy. Both entries are references to the same inode.

    As both '.' and '..' point at the same inode, doing a cd to either leaves you at the root of the tree.

    Things get a little more complex when you mount other filesystems into the tree. Basically, the act of doing the mount replaces the lookup of the directory on which the filesystem is mounted with inode 2 of the mounted filesystem and the lookup of '..' in this filesystem is replaced with a lookup to the parent of the directory it is mounted on. This is probably beyond the scope of what we are talking about here. :)

    This way, the behaviour o faccessing directories through '.' and '..' on Unix remains predictable.

    alan.
  • Thanks Alan.

    That's essentially what happens in FAT and NTFS as well - they're not inodes obviously, but logically it's a similar situation - for FAT, it's the index of the starting cluster in the FAT, for NTFS it's something else (I don't exactly know what).
  • Larry: for NTFS, it's an inode :-) (the index in the MFT) NTFS is structured just like an UNIX filesystem

    AC: it's handled in user mode. A copy of the current path is kept as a string, in fact the kernel has no concept at all of current directory, and relative paths are turned into full paths according to the bizarro DOS path composition rules. Among others:
    * X:\path\path = X:\path\path, but X:path\path = %=X:%\path\path (note missing backslash after X:), where the environment variable %=X:% contains the working directory for drive X:
    * don't forget special device names: X:\any\NUL.any\any === NUL, both of which get translated into the device path \\.\NUL
    * \\server\share\path becomes \\.\UNC\server\share\path, where \\.\UNC is a device that routes UNC paths to the right client driver

    Finally, all paths are translated into kernel ("native") paths, which basically involves prepending \??\ to drive paths, replacing \\.\ with \??\ in device paths, and replacing \\?\ with \??\ in "long Unicode paths" (an officially nameless entity recognized by CreateFileW, which is converted in-place)
  • This is not a comment related to the subject of your post.
    In this post I saw that you have prepared this using Windows Live Writer!!!. Is it working fine for you? I'm always getting an error. Are you using Proxy server for connection?

    This was the error I got:

    "Error attempting to connect to weblog at:
    http://sarathc.wordpress.com/xmlrpc.php

    The underlying connection was closed: A connection that was expected to be kept alive was closed by the server."
  • Norman Diamond wrote:
    > Though the command "cd .." behaves differently in Linux than in
    > every other Unix system I've used, and I always thought Linux's
    > "cd" command was coded specially to do that, but now you
    > make me wonder if Linux has made ".." into symlinks instead.

    Instead of "Linux" you mean "bash" and instead of "Unix system" you mean "shell". "cd" is implemented by the shell.

    Think about it -- there's no way for a child process, like some alleged "cd" program, to change its parent's working directory (actually I hear that there is under Windows, but there isn't in POSIX). So "cd" must be implemented by the shell.

    To support symlinked directories sensibly, bash interprets a .. in the argument to cd as meaning "find and remove everything at or after the last / in $PWD". For instance:

    ~$ ln -s . test
    ~$ cd test
    ~/test$ cd test
    ~/test/test$ cd ..
    ~/test$ cd ..
    ~$

    Had cd been working with the *real* .., the first "cd .." would leave you in /home, not in ~/test. This is annoying, because "ls .." at this point *would* list /home. Likewise, tab-completion is broken in this situation under bash. Alas.

    Larry: ISTR that NTFS supports hard links on directories. If a directory can have multiple parents, what does ".." point at in that case? Likewise, if I use "subst" to map C:\foo to D:\, is there a C:\foo\.. or not? Does it depend on whether I'm calling it D:\.. or C:\foo\..?

    I can't try this out here at work, because I'm not root on this box so I can't make hardlinks to directories... and I guess the ".." problem is one reason why (other problems include the possibility of your file system no longer being a tree).
  • KJK::Hyperion:

    RE: Special environment varaible "where the environment variable %=X:% contains the working directory for drive X: "

    These actually seem to be X:= variables, and do not have a name.

    I've just dumped all of my environment variables, and what I actually see (on XP) is that there are several unnamed environment variables whose values are, e.g.,  "C:=C:\temp" and "D:=D:\testvideo".  Interestingly, these are only created by actually visiting a disk; until I actually set my current disk to "X:" I didn't get an "X:=..." variable.

    Other unnamed variables include one with the value ::=::\ and, after a program runs, an "ExitCode=00000000" value.  

    Does anyone know of a 'canonical' list of possible unnamed environment variables?

  • I'm 99.999% sure that in Windows 9x if you were in C:\dir1\dir2, you could go dir ... and it would show you the contents of C:\. Similarly, if you were in C:\dir1\dir2\dir3, you could go dir .... and get the same thing, ad infinitum. Don't have a machine to try it on, though.
    Now I try it on Win 2k, dir ... in C:\dir1\dir2 gives you the contents of C:\dir1\dir2\.. while dir .. gives you C:\dir1 - i.e. same listing, different header, so it looks like the shell is doing something here. And dir .... doesn't work at all.
    Anyone know how to search for "..." on Google????
  • i always wondered why cd ... didn't move up by *two* directories, and so on.
    the idea of having a "cd .........................."
    command seemed fun (when i was about ten years old, anyway...)

Page 1 of 2 (24 items) 12