From 03ba4131783cc9e872f8bb26a03f15bc11f27564 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 19 Sep 1998 19:15:08 +0000 Subject: - Merge with Linux 2.1.121. - Bugfixes. --- fs/umsdos/specs | 287 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 fs/umsdos/specs (limited to 'fs/umsdos/specs') diff --git a/fs/umsdos/specs b/fs/umsdos/specs new file mode 100644 index 000000000..7b88a78e4 --- /dev/null +++ b/fs/umsdos/specs @@ -0,0 +1,287 @@ +/* #Specification: umsdos / readdir + * umsdos_readdir() should fill a struct dirent with + * an inode number. The cheap way to get it is to + * do a lookup in the MSDOS directory for each + * entry processed by the readdir() function. + * This is not very efficient, but very simple. The + * other way around is to maintain a copy of the inode + * number in the EMD file. This is a problem because + * this has to be maintained in sync using tricks. + * Remember that MSDOS (the OS) does not update the + * modification time (mtime) of a directory. There is + * no easy way to tell that a directory was modified + * during a DOS session and synchronise the EMD file. + */ + /* #Specification: readdir / . and .. + * The msdos filesystem manages the . and .. entry properly + * so the EMD file won't hold any info about it. + * + * In readdir, we assume that for the root directory + * the read position will be 0 for ".", 1 for "..". For + * a non root directory, the read position will be 0 for "." + * and 32 for "..". + */ + /* + * This is a trick used by the msdos file system (fs/msdos/dir.c) + * to manage . and .. for the root directory of a file system. + * Since there is no such entry in the root, fs/msdos/dir.c + * use the following: + * + * if f_pos == 0, return ".". + * if f_pos == 1, return "..". + * + * So let msdos handle it + * + * Since umsdos entries are much larger, we share the same f_pos. + * if f_pos is 0 or 1 or 32, we are clearly looking at . and + * .. + * + * As soon as we get f_pos == 2 or f_pos == 64, then back to + * 0, but this time we are reading the EMD file. + * + * Well, not so true. The problem, is that UMSDOS_REC_SIZE is + * also 64, so as soon as we read the first record in the + * EMD, we are back at offset 64. So we set the offset + * to UMSDOS_SPECIAL_DIRFPOS(3) as soon as we have read the + * .. entry from msdos. + * + * Now (linux 1.3), umsdos_readdir can read more than one + * entry even if we limit (umsdos_dir_once) to only one: + * It skips over hidden file. So we switch to + * UMSDOS_SPECIAL_DIRFPOS as soon as we have read successfully + * the .. entry. + */ + /* #Specification: umsdos / lookup / inode info + * After successfully reading an inode from the MSDOS + * filesystem, we use the EMD file to complete it. + * We update the following field. + * + * uid, gid, atime, ctime, mtime, mode. + * + * We rely on MSDOS for mtime. If the file + * was modified during an MSDOS session, at least + * mtime will be meaningful. We do this only for regular + * file. + * + * We don't rely on MS-DOS for mtime for directories + * because the MS-DOS date on a directory is its + * creation time (strange MSDOS behavior) which + * corresponds to none of the three Unix time stamps. + */ + /* #Specification: umsdos / conversion mode + * The msdos filesystem can do some inline conversion + * of the data of a file. It can translate silently + * from the MS-DOS text file format to the Unix one + * (CRLF -> LF) while reading, and the reverse + * while writing. This is activated using the mount + * option conv=.... + * + * This is not useful for Linux files in a promoted + * directory. It can even be harmful. For this + * reason, the binary (no conversion) mode is + * always activated. + */ + /* #Specification: umsdos / conversion mode / todo + * A flag could be added to file and directories + * forcing an automatic conversion mode (as + * done with the msdos filesystem). + * + * This flag could be setup on a directory basis + * (instead of file) and all files in it would + * logically inherit it. If the conversion mode + * is active (conv=) then the i_binary flag would + * be left untouched in those directories. + * + * It was proposed that the sticky bit be used to set + * this. A problem with that is that new files would + * be written incorrectly. The other problem is that + * the sticky bit has a meaning for directories. So + * another bit should be used (there is some space + * in the EMD file for it) and a special utility + * would be used to assign the flag to a directory). + * I don't think it is useful to assign this flag + * on a single file. + */ + * #Specification: weakness / rename + * There is a case where UMSDOS rename has a different behavior + * than a normal Unix file system. Renaming an open file across + * directory boundary does not work. Renaming an open file within + * a directory does work, however. + * + * The problem may is in Linux VFS driver for msdos. + * I believe this is not a bug but a design feature, because + * an inode number represents some sort of directory address + * in the MSDOS directory structure, so moving the file into + * another directory does not preserve the inode number. + */ +/* #Specification: rename / new name exist + * If the destination name already exists, it will + * silently be removed. EXT2 does it this way + * and this is the spec of SunOS. So does UMSDOS. + * + * If the destination is an empty directory it will + * also be removed. + */ +/* #Specification: rename / new name exist / possible flaw + * The code to handle the deletion of the target (file + * and directory) use to be in umsdos_rename_f, surrounded + * by proper directory locking. This was ensuring that only + * one process could achieve a rename (modification) operation + * in the source and destination directory. This was also + * ensuring the operation was "atomic". + * + * This has been changed because this was creating a + * stack overflow (the stack is only 4 kB) in the kernel. To avoid + * the code doing the deletion of the target (if exist) has + * been moved to a upper layer. umsdos_rename_f is tried + * once and if it fails with EEXIST, the target is removed + * and umsdos_rename_f is done again. + * + * This makes the code cleaner and may solve a + * deadlock problem one tester was experiencing. + * + * The point is to mention that possibly, the semantic of + * "rename" may be wrong. Anyone dare to check that :-) + * Be aware that IF it is wrong, to produce the problem you + * will need two process trying to rename a file to the + * same target at the same time. Again, I am not sure it + * is a problem at all. + */ +/* #Specification: hard link / strategy + * Hard links are difficult to implement on top of an MS-DOS FAT file + * system. Unlike Unix file systems, there are no inodes. A directory + * entry holds the functionality of the inode and the entry. + * + * We will used the same strategy as a normal Unix file system + * (with inodes) except we will do it symbolically (using paths). + * + * Because anything can happen during a DOS session (defragment, + * directory sorting, etc.), we can't rely on an MS-DOS pseudo + * inode number to record the link. For this reason, the link + * will be done using hidden symbolic links. The following + * scenario illustrates how it works. + * + * Given a file /foo/file + * + * # + * ln /foo/file /tmp/file2 + * + * become internally + * + * mv /foo/file /foo/-LINK1 + * ln -s /foo/-LINK1 /foo/file + * ln -s /foo/-LINK1 /tmp/file2 + * # + * + * Using this strategy, we can operate on /foo/file or /foo/file2. + * We can remove one and keep the other, like a normal Unix hard link. + * We can rename /foo/file or /tmp/file2 independently. + * + * The entry -LINK1 will be hidden. It will hold a link count. + * When all link are erased, the hidden file is erased too. + */ +/* #Specification: weakness / hard link + * The strategy for hard link introduces a side effect that + * may or may not be acceptable. Here is the sequence + * + * # + * mkdir subdir1 + * touch subdir1/file + * mkdir subdir2 + * ln subdir1/file subdir2/file + * rm subdir1/file + * rmdir subdir1 + * rmdir: subdir1: Directory not empty + * # + * + * This happen because there is an invisible file (--link) in + * subdir1 which is referenced by subdir2/file. + * + * Any idea ? + */ +/* #Specification: weakness / hard link / rename directory + * Another weakness of hard link come from the fact that + * it is based on hidden symbolic links. Here is an example. + * + * # + * mkdir /subdir1 + * touch /subdir1/file + * mkdir /subdir2 + * ln /subdir1/file subdir2/file + * mv /subdir1 subdir3 + * ls -l /subdir2/file + * # + * + * Since /subdir2/file is a hidden symbolic link + * to /subdir1/..hlinkNNN, accessing it will fail since + * /subdir1 does not exist anymore (has been renamed). + */ +/* #Specification: hard link / directory + * A hard link can't be made on a directory. EPERM is returned + * in this case. + */ +/* #Specification: hard link / first hard link + * The first time a hard link is done on a file, this + * file must be renamed and hidden. Then an internal + * symbolic link must be done on the hidden file. + * + * The second link is done after on this hidden file. + * + * It is expected that the Linux MSDOS file system + * keeps the same pseudo inode when a rename operation + * is done on a file in the same directory. + */ +/* #Specification: function name / convention + * A simple convention for function names has been used in + * the UMSDOS filesystem. First, all functions use the prefix + * umsdos_ to avoid name clashes with other parts of the kernel. + * + * Standard VFS entry points use the prefix UMSDOS (upper case) + * so it's easier to tell them apart. + * N.B. (FIXME) PTW, the order and contents of this struct changed. + */ + +/* #Specification: mount / options + * Umsdos run on top of msdos. Currently, it supports no + * mount option, but happily pass all option received to + * the msdos driver. I am not sure if all msdos mount option + * make sense with Umsdos. Here are at least those who + * are useful. + * uid= + * gid= + * + * These options affect the operation of umsdos in directories + * which do not have an EMD file. They behave like normal + * msdos directory, with all limitation of msdos. + */ + +/* #Specification: pseudo root / mount + * When a umsdos fs is mounted, a special handling is done + * if it is the root partition. We check for the presence + * of the file /linux/etc/init or /linux/etc/rc or + * /linux/sbin/init. If one is there, we do a chroot("/linux"). + * + * We check both because (see init/main.c) the kernel + * try to exec init at different place and if it fails + * it tries /bin/sh /etc/rc. To be consistent with + * init/main.c, many more test would have to be done + * to locate init. Any complain ? + * + * The chroot is done manually in init/main.c but the + * info (the inode) is located at mount time and store + * in a global variable (pseudo_root) which is used at + * different place in the umsdos driver. There is no + * need to store this variable elsewhere because it + * will always be one, not one per mount. + * + * This feature allows the installation + * of a linux system within a DOS system in a subdirectory. + * + * A user may install its linux stuff in c:\linux + * avoiding any clash with existing DOS file and subdirectory. + * When linux boots, it hides this fact, showing a normal + * root directory with /etc /bin /tmp ... + * + * The word "linux" is hardcoded in /usr/include/linux/umsdos_fs.h + * in the macro UMSDOS_PSDROOT_NAME. + */ -- cgit v1.2.3