specs
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:11k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  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. /* #Specification: hard link / strategy
  151.  * Hard links are difficult to implement on top of an MS-DOS FAT file
  152.  * system. Unlike Unix file systems, there are no inodes. A directory
  153.  * entry holds the functionality of the inode and the entry.
  154.  * 
  155.  * We will used the same strategy as a normal Unix file system
  156.  * (with inodes) except we will do it symbolically (using paths).
  157.  * 
  158.  * Because anything can happen during a DOS session (defragment,
  159.  * directory sorting, etc.), we can't rely on an MS-DOS pseudo
  160.  * inode number to record the link. For this reason, the link
  161.  * will be done using hidden symbolic links. The following
  162.  * scenario illustrates how it works.
  163.  * 
  164.  * Given a file /foo/file
  165.  * 
  166.  * #
  167.  * ln /foo/file /tmp/file2
  168.  * 
  169.  * become internally
  170.  * 
  171.  * mv /foo/file /foo/-LINK1
  172.  * ln -s /foo/-LINK1 /foo/file
  173.  * ln -s /foo/-LINK1 /tmp/file2
  174.  * #
  175.  * 
  176.  * Using this strategy, we can operate on /foo/file or /foo/file2.
  177.  * We can remove one and keep the other, like a normal Unix hard link.
  178.  * We can rename /foo/file or /tmp/file2 independently.
  179.  * 
  180.  * The entry -LINK1 will be hidden. It will hold a link count.
  181.  * When all link are erased, the hidden file is erased too.
  182.  */
  183. /* #Specification: weakness / hard link
  184.  * The strategy for hard link introduces a side effect that
  185.  * may or may not be acceptable. Here is the sequence
  186.  * 
  187.  * #
  188.  * mkdir subdir1
  189.  * touch subdir1/file
  190.  * mkdir subdir2
  191.  * ln    subdir1/file subdir2/file
  192.  * rm    subdir1/file
  193.  * rmdir subdir1
  194.  * rmdir: subdir1: Directory not empty
  195.  * #
  196.  * 
  197.  * This happen because there is an invisible file (--link) in
  198.  * subdir1 which is referenced by subdir2/file.
  199.  * 
  200.  * Any idea ?
  201.  */
  202. /* #Specification: weakness / hard link / rename directory
  203.  * Another weakness of hard link come from the fact that
  204.  * it is based on hidden symbolic links. Here is an example.
  205.  * 
  206.  * #
  207.  * mkdir /subdir1
  208.  * touch /subdir1/file
  209.  * mkdir /subdir2
  210.  * ln    /subdir1/file subdir2/file
  211.  * mv    /subdir1 subdir3
  212.  * ls -l /subdir2/file
  213.  * #
  214.  * 
  215.  * Since /subdir2/file is a hidden symbolic link
  216.  * to /subdir1/..hlinkNNN, accessing it will fail since
  217.  * /subdir1 does not exist anymore (has been renamed).
  218.  */
  219. /* #Specification: hard link / directory
  220.  * A hard link can't be made on a directory. EPERM is returned
  221.  * in this case.
  222.  */
  223. /* #Specification: hard link / first hard link
  224.  * The first time a hard link is done on a file, this
  225.  * file must be renamed and hidden. Then an internal
  226.  * symbolic link must be done on the hidden file.
  227.  * 
  228.  * The second link is done after on this hidden file.
  229.  * 
  230.  * It is expected that the Linux MSDOS file system
  231.  * keeps the same pseudo inode when a rename operation
  232.  * is done on a file in the same directory.
  233.  */
  234. /* #Specification: function name / convention
  235.  * A simple convention for function names has been used in
  236.  * the UMSDOS filesystem. First, all functions use the prefix
  237.  * umsdos_ to avoid name clashes with other parts of the kernel.
  238.  * 
  239.  * Standard VFS entry points use the prefix UMSDOS (upper case)
  240.  * so it's easier to tell them apart.
  241.  * N.B. (FIXME) PTW, the order and contents of this struct changed.
  242.  */
  243. /* #Specification: mount / options
  244.  * Umsdos run on top of msdos. Currently, it supports no
  245.  * mount option, but happily pass all option received to
  246.  * the msdos driver. I am not sure if all msdos mount option
  247.  * make sense with Umsdos. Here are at least those who
  248.  * are useful.
  249.  * uid=
  250.  * gid=
  251.  * 
  252.  * These options affect the operation of umsdos in directories
  253.  * which do not have an EMD file. They behave like normal
  254.  * msdos directory, with all limitation of msdos.
  255.  */
  256. /* #Specification: pseudo root / mount
  257.  * When a umsdos fs is mounted, a special handling is done
  258.  * if it is the root partition. We check for the presence
  259.  * of the file /linux/etc/init or /linux/etc/rc or
  260.  * /linux/sbin/init. If one is there, we do a chroot("/linux").
  261.  * 
  262.  * We check both because (see init/main.c) the kernel
  263.  * try to exec init at different place and if it fails
  264.  * it tries /bin/sh /etc/rc. To be consistent with
  265.  * init/main.c, many more test would have to be done
  266.  * to locate init. Any complain ?
  267.  * 
  268.  * The chroot is done manually in init/main.c but the
  269.  * info (the inode) is located at mount time and store
  270.  * in a global variable (pseudo_root) which is used at
  271.  * different place in the umsdos driver. There is no
  272.  * need to store this variable elsewhere because it
  273.  * will always be one, not one per mount.
  274.  * 
  275.  * This feature allows the installation
  276.  * of a linux system within a DOS system in a subdirectory.
  277.  * 
  278.  * A user may install its linux stuff in c:linux
  279.  * avoiding any clash with existing DOS file and subdirectory.
  280.  * When linux boots, it hides this fact, showing a normal
  281.  * root directory with /etc /bin /tmp ...
  282.  * 
  283.  * The word "linux" is hardcoded in /usr/include/linux/umsdos_fs.h
  284.  * in the macro UMSDOS_PSDROOT_NAME.
  285.  */