The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/umsdos/specs

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* #Specification: umsdos / readdir
    2  * umsdos_readdir() should fill a struct dirent with
    3  * an inode number. The cheap way to get it is to
    4  * do a lookup in the MSDOS directory for each
    5  * entry processed by the readdir() function.
    6  * This is not very efficient, but very simple. The
    7  * other way around is to maintain a copy of the inode
    8  * number in the EMD file. This is a problem because
    9  * this has to be maintained in sync using tricks.
   10  * Remember that MSDOS (the OS) does not update the
   11  * modification time (mtime) of a directory. There is
   12  * no easy way to tell that a directory was modified
   13  * during a DOS session and synchronise the EMD file.
   14  */
   15                 /* #Specification: readdir / . and ..
   16                  * The msdos filesystem manages the . and .. entry properly
   17                  * so the EMD file won't hold any info about it.
   18                  * 
   19                  * In readdir, we assume that for the root directory
   20                  * the read position will be 0 for ".", 1 for "..". For
   21                  * a non root directory, the read position will be 0 for "."
   22                  * and 32 for "..".
   23                  */
   24                 /*
   25                  * This is a trick used by the msdos file system (fs/msdos/dir.c)
   26                  * to manage . and .. for the root directory of a file system.
   27                  * Since there is no such entry in the root, fs/msdos/dir.c
   28                  * use the following:
   29                  * 
   30                  * if f_pos == 0, return ".".
   31                  * if f_pos == 1, return "..".
   32                  * 
   33                  * So let msdos handle it
   34                  * 
   35                  * Since umsdos entries are much larger, we share the same f_pos.
   36                  * if f_pos is 0 or 1 or 32, we are clearly looking at . and
   37                  * ..
   38                  * 
   39                  * As soon as we get f_pos == 2 or f_pos == 64, then back to
   40                  * 0, but this time we are reading the EMD file.
   41                  * 
   42                  * Well, not so true. The problem, is that UMSDOS_REC_SIZE is
   43                  * also 64, so as soon as we read the first record in the
   44                  * EMD, we are back at offset 64. So we set the offset
   45                  * to UMSDOS_SPECIAL_DIRFPOS(3) as soon as we have read the
   46                  * .. entry from msdos.
   47                  * 
   48                  * Now (linux 1.3), umsdos_readdir can read more than one
   49                  * entry even if we limit (umsdos_dir_once) to only one:
   50                  * It skips over hidden file. So we switch to
   51                  * UMSDOS_SPECIAL_DIRFPOS as soon as we have read successfully
   52                  * the .. entry.
   53                  */
   54                         /* #Specification: umsdos / lookup / inode info
   55                          * After successfully reading an inode from the MSDOS
   56                          * filesystem, we use the EMD file to complete it.
   57                          * We update the following field.
   58                          * 
   59                          * uid, gid, atime, ctime, mtime, mode.
   60                          * 
   61                          * We rely on MSDOS for mtime. If the file
   62                          * was modified during an MSDOS session, at least
   63                          * mtime will be meaningful. We do this only for regular
   64                          * file.
   65                          * 
   66                          * We don't rely on MS-DOS for mtime for directories
   67                          * because the MS-DOS date on a directory is its
   68                          * creation time (strange MSDOS behavior) which
   69                          * corresponds to none of the three Unix time stamps.
   70                          */
   71         /* #Specification: umsdos / conversion mode
   72          * The msdos filesystem can do some inline conversion
   73          * of the data of a file.  It can translate silently
   74          * from the MS-DOS text file format to the Unix one
   75          * (CRLF -> LF) while reading, and the reverse
   76          * while writing. This is activated using the mount
   77          * option conv=....
   78          * 
   79          * This is not useful for Linux files in a promoted
   80          * directory.  It can even be harmful.  For this
   81          * reason, the binary (no conversion) mode is
   82          * always activated.
   83          */
   84         /* #Specification: umsdos / conversion mode / todo
   85          * A flag could be added to file and directories
   86          * forcing an automatic conversion mode (as
   87          * done with the msdos filesystem).
   88          * 
   89          * This flag could be setup on a directory basis
   90          * (instead of file) and all files in it would
   91          * logically inherit it.  If the conversion mode
   92          * is active (conv=) then the i_binary flag would
   93          * be left untouched in those directories.
   94          * 
   95          * It was proposed that the sticky bit be used to set
   96          * this.  A problem with that is that new files would
   97          * be written incorrectly.  The other problem is that
   98          * the sticky bit has a meaning for directories. So
   99          * another bit should be used (there is some space
  100          * in the EMD file for it) and a special utility
  101          * would be used to assign the flag to a directory).
  102          * I don't think it is useful to assign this flag
  103          * on a single file.
  104          */
  105  * #Specification: weakness / rename
  106  * There is a case where UMSDOS rename has a different behavior
  107  * than a normal Unix file system.  Renaming an open file across
  108  * directory boundary does not work.  Renaming an open file within
  109  * a directory does work, however.
  110  * 
  111  * The problem may is in Linux VFS driver for msdos.
  112  * I believe this is not a bug but a design feature, because
  113  * an inode number represents some sort of directory address
  114  * in the MSDOS directory structure, so moving the file into
  115  * another directory does not preserve the inode number.
  116  */
  117 /* #Specification: rename / new name exist
  118  * If the destination name already exists, it will
  119  * silently be removed.  EXT2 does it this way
  120  * and this is the spec of SunOS.  So does UMSDOS.
  121  * 
  122  * If the destination is an empty directory it will
  123  * also be removed.
  124  */
  125 /* #Specification: rename / new name exist / possible flaw
  126  * The code to handle the deletion of the target (file
  127  * and directory) use to be in umsdos_rename_f, surrounded
  128  * by proper directory locking.  This was ensuring that only
  129  * one process could achieve a rename (modification) operation
  130  * in the source and destination directory.  This was also
  131  * ensuring the operation was "atomic".
  132  * 
  133  * This has been changed because this was creating a
  134  * stack overflow (the stack is only 4 kB) in the kernel.  To avoid
  135  * the code doing the deletion of the target (if exist) has
  136  * been moved to a upper layer. umsdos_rename_f is tried
  137  * once and if it fails with EEXIST, the target is removed
  138  * and umsdos_rename_f is done again.
  139  * 
  140  * This makes the code cleaner and may solve a
  141  * deadlock problem one tester was experiencing.
  142  * 
  143  * The point is to mention that possibly, the semantic of
  144  * "rename" may be wrong. Anyone dare to check that :-)
  145  * Be aware that IF it is wrong, to produce the problem you
  146  * will need two process trying to rename a file to the
  147  * same target at the same time. Again, I am not sure it
  148  * is a problem at all.
  149  */
  150 
  151 /* #Specification: hard link / strategy
  152  * Hard links are difficult to implement on top of an MS-DOS FAT file
  153  * system. Unlike Unix file systems, there are no inodes. A directory
  154  * entry holds the functionality of the inode and the entry.
  155  * 
  156  * We will used the same strategy as a normal Unix file system
  157  * (with inodes) except we will do it symbolically (using paths).
  158  * 
  159  * Because anything can happen during a DOS session (defragment,
  160  * directory sorting, etc.), we can't rely on an MS-DOS pseudo
  161  * inode number to record the link. For this reason, the link
  162  * will be done using hidden symbolic links. The following
  163  * scenario illustrates how it works.
  164  * 
  165  * Given a file /foo/file
  166  * 
  167  * #
  168  * ln /foo/file /tmp/file2
  169  * 
  170  * become internally
  171  * 
  172  * mv /foo/file /foo/-LINK1
  173  * ln -s /foo/-LINK1 /foo/file
  174  * ln -s /foo/-LINK1 /tmp/file2
  175  * #
  176  * 
  177  * Using this strategy, we can operate on /foo/file or /foo/file2.
  178  * We can remove one and keep the other, like a normal Unix hard link.
  179  * We can rename /foo/file or /tmp/file2 independently.
  180  * 
  181  * The entry -LINK1 will be hidden. It will hold a link count.
  182  * When all link are erased, the hidden file is erased too.
  183  */
  184 
  185 /* #Specification: weakness / hard link
  186  * The strategy for hard link introduces a side effect that
  187  * may or may not be acceptable. Here is the sequence
  188  * 
  189  * #
  190  * mkdir subdir1
  191  * touch subdir1/file
  192  * mkdir subdir2
  193  * ln    subdir1/file subdir2/file
  194  * rm    subdir1/file
  195  * rmdir subdir1
  196  * rmdir: subdir1: Directory not empty
  197  * #
  198  * 
  199  * This happen because there is an invisible file (--link) in
  200  * subdir1 which is referenced by subdir2/file.
  201  * 
  202  * Any idea ?
  203  */
  204 /* #Specification: weakness / hard link / rename directory
  205  * Another weakness of hard link come from the fact that
  206  * it is based on hidden symbolic links. Here is an example.
  207  * 
  208  * #
  209  * mkdir /subdir1
  210  * touch /subdir1/file
  211  * mkdir /subdir2
  212  * ln    /subdir1/file subdir2/file
  213  * mv    /subdir1 subdir3
  214  * ls -l /subdir2/file
  215  * #
  216  * 
  217  * Since /subdir2/file is a hidden symbolic link
  218  * to /subdir1/..hlinkNNN, accessing it will fail since
  219  * /subdir1 does not exist anymore (has been renamed).
  220  */
  221 /* #Specification: hard link / directory
  222  * A hard link can't be made on a directory. EPERM is returned
  223  * in this case.
  224  */
  225 /* #Specification: hard link / first hard link
  226  * The first time a hard link is done on a file, this
  227  * file must be renamed and hidden. Then an internal
  228  * symbolic link must be done on the hidden file.
  229  * 
  230  * The second link is done after on this hidden file.
  231  * 
  232  * It is expected that the Linux MSDOS file system
  233  * keeps the same pseudo inode when a rename operation
  234  * is done on a file in the same directory.
  235  */
  236 /* #Specification: function name / convention
  237  * A simple convention for function names has been used in
  238  * the UMSDOS filesystem. First, all functions use the prefix
  239  * umsdos_ to avoid name clashes with other parts of the kernel.
  240  * 
  241  * Standard VFS entry points use the prefix UMSDOS (upper case)
  242  * so it's easier to tell them apart.
  243  * N.B. (FIXME) PTW, the order and contents of this struct changed.
  244  */
  245 
  246 /* #Specification: mount / options
  247  * Umsdos run on top of msdos. Currently, it supports no
  248  * mount option, but happily pass all option received to
  249  * the msdos driver. I am not sure if all msdos mount option
  250  * make sense with Umsdos. Here are at least those who
  251  * are useful.
  252  * uid=
  253  * gid=
  254  * 
  255  * These options affect the operation of umsdos in directories
  256  * which do not have an EMD file. They behave like normal
  257  * msdos directory, with all limitation of msdos.
  258  */
  259 
  260 /* #Specification: pseudo root / mount
  261  * When a umsdos fs is mounted, a special handling is done
  262  * if it is the root partition. We check for the presence
  263  * of the file /linux/etc/init or /linux/etc/rc or
  264  * /linux/sbin/init. If one is there, we do a chroot("/linux").
  265  * 
  266  * We check both because (see init/main.c) the kernel
  267  * try to exec init at different place and if it fails
  268  * it tries /bin/sh /etc/rc. To be consistent with
  269  * init/main.c, many more test would have to be done
  270  * to locate init. Any complain ?
  271  * 
  272  * The chroot is done manually in init/main.c but the
  273  * info (the inode) is located at mount time and store
  274  * in a global variable (pseudo_root) which is used at
  275  * different place in the umsdos driver. There is no
  276  * need to store this variable elsewhere because it
  277  * will always be one, not one per mount.
  278  * 
  279  * This feature allows the installation
  280  * of a linux system within a DOS system in a subdirectory.
  281  * 
  282  * A user may install its linux stuff in c:\linux
  283  * avoiding any clash with existing DOS file and subdirectory.
  284  * When linux boots, it hides this fact, showing a normal
  285  * root directory with /etc /bin /tmp ...
  286  * 
  287  * The word "linux" is hardcoded in /usr/include/linux/umsdos_fs.h
  288  * in the macro UMSDOS_PSDROOT_NAME.
  289  */

Cache object: 3a9a15aeb8590391439004faa0496604


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.