Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | Read/Write HPFS 2.09 |
| 2 | 1998-2004, Mikulas Patocka |
| 3 | |
| 4 | email: mikulas@artax.karlin.mff.cuni.cz |
| 5 | homepage: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi |
| 6 | |
| 7 | CREDITS: |
| 8 | Chris Smith, 1993, original read-only HPFS, some code and hpfs structures file |
| 9 | is taken from it |
| 10 | Jacques Gelinas, MSDos mmap, Inspired by fs/nfs/mmap.c (Jon Tombs 15 Aug 1993) |
| 11 | Werner Almesberger, 1992, 1993, MSDos option parser & CR/LF conversion |
| 12 | |
| 13 | Mount options |
| 14 | |
| 15 | uid=xxx,gid=xxx,umask=xxx (default uid=gid=0 umask=default_system_umask) |
| 16 | Set owner/group/mode for files that do not have it specified in extended |
| 17 | attributes. Mode is inverted umask - for example umask 027 gives owner |
| 18 | all permission, group read permission and anybody else no access. Note |
| 19 | that for files mode is anded with 0666. If you want files to have 'x' |
| 20 | rights, you must use extended attributes. |
| 21 | case=lower,asis (default asis) |
| 22 | File name lowercasing in readdir. |
| 23 | conv=binary,text,auto (default binary) |
| 24 | CR/LF -> LF conversion, if auto, decision is made according to extension |
| 25 | - there is a list of text extensions (I thing it's better to not convert |
| 26 | text file than to damage binary file). If you want to change that list, |
| 27 | change it in the source. Original readonly HPFS contained some strange |
| 28 | heuristic algorithm that I removed. I thing it's danger to let the |
| 29 | computer decide whether file is text or binary. For example, DJGPP |
| 30 | binaries contain small text message at the beginning and they could be |
| 31 | misidentified and damaged under some circumstances. |
| 32 | check=none,normal,strict (default normal) |
| 33 | Check level. Selecting none will cause only little speedup and big |
| 34 | danger. I tried to write it so that it won't crash if check=normal on |
| 35 | corrupted filesystems. check=strict means many superfluous checks - |
| 36 | used for debugging (for example it checks if file is allocated in |
| 37 | bitmaps when accessing it). |
| 38 | errors=continue,remount-ro,panic (default remount-ro) |
| 39 | Behaviour when filesystem errors found. |
| 40 | chkdsk=no,errors,always (default errors) |
| 41 | When to mark filesystem dirty so that OS/2 checks it. |
| 42 | eas=no,ro,rw (default rw) |
| 43 | What to do with extended attributes. 'no' - ignore them and use always |
| 44 | values specified in uid/gid/mode options. 'ro' - read extended |
| 45 | attributes but do not create them. 'rw' - create extended attributes |
| 46 | when you use chmod/chown/chgrp/mknod/ln -s on the filesystem. |
| 47 | timeshift=(-)nnn (default 0) |
| 48 | Shifts the time by nnn seconds. For example, if you see under linux |
| 49 | one hour more, than under os/2, use timeshift=-3600. |
| 50 | |
| 51 | |
| 52 | File names |
| 53 | |
| 54 | As in OS/2, filenames are case insensitive. However, shell thinks that names |
| 55 | are case sensitive, so for example when you create a file FOO, you can use |
| 56 | 'cat FOO', 'cat Foo', 'cat foo' or 'cat F*' but not 'cat f*'. Note, that you |
| 57 | also won't be able to compile linux kernel (and maybe other things) on HPFS |
| 58 | because kernel creates different files with names like bootsect.S and |
| 59 | bootsect.s. When searching for file thats name has characters >= 128, codepages |
| 60 | are used - see below. |
| 61 | OS/2 ignores dots and spaces at the end of file name, so this driver does as |
| 62 | well. If you create 'a. ...', the file 'a' will be created, but you can still |
| 63 | access it under names 'a.', 'a..', 'a . . . ' etc. |
| 64 | |
| 65 | |
| 66 | Extended attributes |
| 67 | |
| 68 | On HPFS partitions, OS/2 can associate to each file a special information called |
| 69 | extended attributes. Extended attributes are pairs of (key,value) where key is |
| 70 | an ascii string identifying that attribute and value is any string of bytes of |
| 71 | variable length. OS/2 stores window and icon positions and file types there. So |
| 72 | why not use it for unix-specific info like file owner or access rights? This |
| 73 | driver can do it. If you chown/chgrp/chmod on a hpfs partition, extended |
| 74 | attributes with keys "UID", "GID" or "MODE" and 2-byte values are created. Only |
| 75 | that extended attributes those value differs from defaults specified in mount |
| 76 | options are created. Once created, the extended attributes are never deleted, |
| 77 | they're just changed. It means that when your default uid=0 and you type |
| 78 | something like 'chown luser file; chown root file' the file will contain |
| 79 | extended attribute UID=0. And when you umount the fs and mount it again with |
| 80 | uid=luser_uid, the file will be still owned by root! If you chmod file to 444, |
| 81 | extended attribute "MODE" will not be set, this special case is done by setting |
| 82 | read-only flag. When you mknod a block or char device, besides "MODE", the |
| 83 | special 4-byte extended attribute "DEV" will be created containing the device |
| 84 | number. Currently this driver cannot resize extended attributes - it means |
| 85 | that if somebody (I don't know who?) has set "UID", "GID", "MODE" or "DEV" |
| 86 | attributes with different sizes, they won't be rewritten and changing these |
| 87 | values doesn't work. |
| 88 | |
| 89 | |
| 90 | Symlinks |
| 91 | |
| 92 | You can do symlinks on HPFS partition, symlinks are achieved by setting extended |
| 93 | attribute named "SYMLINK" with symlink value. Like on ext2, you can chown and |
| 94 | chgrp symlinks but I don't know what is it good for. chmoding symlink results |
| 95 | in chmoding file where symlink points. These symlinks are just for Linux use and |
| 96 | incompatible with OS/2. OS/2 PmShell symlinks are not supported because they are |
| 97 | stored in very crazy way. They tried to do it so that link changes when file is |
| 98 | moved ... sometimes it works. But the link is partly stored in directory |
| 99 | extended attributes and partly in OS2SYS.INI. I don't want (and don't know how) |
| 100 | to analyze or change OS2SYS.INI. |
| 101 | |
| 102 | |
| 103 | Codepages |
| 104 | |
| 105 | HPFS can contain several uppercasing tables for several codepages and each |
| 106 | file has a pointer to codepage it's name is in. However OS/2 was created in |
| 107 | America where people don't care much about codepages and so multiple codepages |
| 108 | support is quite buggy. I have Czech OS/2 working in codepage 852 on my disk. |
| 109 | Once I booted English OS/2 working in cp 850 and I created a file on my 852 |
| 110 | partition. It marked file name codepage as 850 - good. But when I again booted |
| 111 | Czech OS/2, the file was completely inaccessible under any name. It seems that |
| 112 | OS/2 uppercases the search pattern with its system code page (852) and file |
| 113 | name it's comparing to with its code page (850). These could never match. Is it |
| 114 | really what IBM developers wanted? But problems continued. When I created in |
| 115 | Czech OS/2 another file in that directory, that file was inaccessible too. OS/2 |
| 116 | probably uses different uppercasing method when searching where to place a file |
| 117 | (note, that files in HPFS directory must be sorted) and when searching for |
| 118 | a file. Finally when I opened this directory in PmShell, PmShell crashed (the |
| 119 | funny thing was that, when rebooted, PmShell tried to reopen this directory |
| 120 | again :-). chkdsk happily ignores these errors and only low-level disk |
| 121 | modification saved me. Never mix different language versions of OS/2 on one |
| 122 | system although HPFS was designed to allow that. |
| 123 | OK, I could implement complex codepage support to this driver but I think it |
| 124 | would cause more problems than benefit with such buggy implementation in OS/2. |
| 125 | So this driver simply uses first codepage it finds for uppercasing and |
| 126 | lowercasing no matter what's file codepage index. Usually all file names are in |
| 127 | this codepage - if you don't try to do what I described above :-) |
| 128 | |
| 129 | |
| 130 | Known bugs |
| 131 | |
| 132 | HPFS386 on OS/2 server is not supported. HPFS386 installed on normal OS/2 client |
| 133 | should work. If you have OS/2 server, use only read-only mode. I don't know how |
| 134 | to handle some HPFS386 structures like access control list or extended perm |
| 135 | list, I don't know how to delete them when file is deleted and how to not |
| 136 | overwrite them with extended attributes. Send me some info on these structures |
| 137 | and I'll make it. However, this driver should detect presence of HPFS386 |
| 138 | structures, remount read-only and not destroy them (I hope). |
| 139 | |
| 140 | When there's not enough space for extended attributes, they will be truncated |
| 141 | and no error is returned. |
| 142 | |
| 143 | OS/2 can't access files if the path is longer than about 256 chars but this |
| 144 | driver allows you to do it. chkdsk ignores such errors. |
| 145 | |
| 146 | Sometimes you won't be able to delete some files on a very full filesystem |
| 147 | (returning error ENOSPC). That's because file in non-leaf node in directory tree |
| 148 | (one directory, if it's large, has dirents in tree on HPFS) must be replaced |
| 149 | with another node when deleted. And that new file might have larger name than |
| 150 | the old one so the new name doesn't fit in directory node (dnode). And that |
| 151 | would result in directory tree splitting, that takes disk space. Workaround is |
| 152 | to delete other files that are leaf (probability that the file is non-leaf is |
| 153 | about 1/50) or to truncate file first to make some space. |
| 154 | You encounter this problem only if you have many directories so that |
| 155 | preallocated directory band is full i.e. |
| 156 | number_of_directories / size_of_filesystem_in_mb > 4. |
| 157 | |
| 158 | You can't delete open directories. |
| 159 | |
| 160 | You can't rename over directories (what is it good for?). |
| 161 | |
| 162 | Renaming files so that only case changes doesn't work. This driver supports it |
| 163 | but vfs doesn't. Something like 'mv file FILE' won't work. |
| 164 | |
| 165 | All atimes and directory mtimes are not updated. That's because of performance |
| 166 | reasons. If you extremely wish to update them, let me know, I'll write it (but |
| 167 | it will be slow). |
| 168 | |
| 169 | When the system is out of memory and swap, it may slightly corrupt filesystem |
| 170 | (lost files, unbalanced directories). (I guess all filesystem may do it). |
| 171 | |
| 172 | When compiled, you get warning: function declaration isn't a prototype. Does |
| 173 | anybody know what does it mean? |
| 174 | |
| 175 | |
| 176 | What does "unbalanced tree" message mean? |
| 177 | |
| 178 | Old versions of this driver created sometimes unbalanced dnode trees. OS/2 |
| 179 | chkdsk doesn't scream if the tree is unbalanced (and sometimes creates |
| 180 | unbalanced trees too :-) but both HPFS and HPFS386 contain bug that it rarely |
| 181 | crashes when the tree is not balanced. This driver handles unbalanced trees |
| 182 | correctly and writes warning if it finds them. If you see this message, this is |
| 183 | probably because of directories created with old version of this driver. |
| 184 | Workaround is to move all files from that directory to another and then back |
| 185 | again. Do it in Linux, not OS/2! If you see this message in directory that is |
| 186 | whole created by this driver, it is BUG - let me know about it. |
| 187 | |
| 188 | |
| 189 | Bugs in OS/2 |
| 190 | |
| 191 | When you have two (or more) lost directories pointing each to other, chkdsk |
| 192 | locks up when repairing filesystem. |
| 193 | |
| 194 | Sometimes (I think it's random) when you create a file with one-char name under |
| 195 | OS/2, OS/2 marks it as 'long'. chkdsk then removes this flag saying "Minor fs |
| 196 | error corrected". |
| 197 | |
| 198 | File names like "a .b" are marked as 'long' by OS/2 but chkdsk "corrects" it and |
| 199 | marks them as short (and writes "minor fs error corrected"). This bug is not in |
| 200 | HPFS386. |
| 201 | |
| 202 | Codepage bugs described above. |
| 203 | |
| 204 | If you don't install fixpacks, there are many, many more... |
| 205 | |
| 206 | |
| 207 | History |
| 208 | |
| 209 | 0.90 First public release |
| 210 | 0.91 Fixed bug that caused shooting to memory when write_inode was called on |
| 211 | open inode (rarely happened) |
| 212 | 0.92 Fixed a little memory leak in freeing directory inodes |
| 213 | 0.93 Fixed bug that locked up the machine when there were too many filenames |
| 214 | with first 15 characters same |
| 215 | Fixed write_file to zero file when writing behind file end |
| 216 | 0.94 Fixed a little memory leak when trying to delete busy file or directory |
| 217 | 0.95 Fixed a bug that i_hpfs_parent_dir was not updated when moving files |
| 218 | 1.90 First version for 2.1.1xx kernels |
| 219 | 1.91 Fixed a bug that chk_sectors failed when sectors were at the end of disk |
| 220 | Fixed a race-condition when write_inode is called while deleting file |
| 221 | Fixed a bug that could possibly happen (with very low probability) when |
| 222 | using 0xff in filenames |
| 223 | Rewritten locking to avoid race-conditions |
| 224 | Mount option 'eas' now works |
| 225 | Fsync no longer returns error |
| 226 | Files beginning with '.' are marked hidden |
| 227 | Remount support added |
| 228 | Alloc is not so slow when filesystem becomes full |
| 229 | Atimes are no more updated because it slows down operation |
| 230 | Code cleanup (removed all commented debug prints) |
| 231 | 1.92 Corrected a bug when sync was called just before closing file |
| 232 | 1.93 Modified, so that it works with kernels >= 2.1.131, I don't know if it |
| 233 | works with previous versions |
| 234 | Fixed a possible problem with disks > 64G (but I don't have one, so I can't |
| 235 | test it) |
| 236 | Fixed a file overflow at 2G |
| 237 | Added new option 'timeshift' |
| 238 | Changed behaviour on HPFS386: It is now possible to operate on HPFS386 in |
| 239 | read-only mode |
| 240 | Fixed a bug that slowed down alloc and prevented allocating 100% space |
| 241 | (this bug was not destructive) |
| 242 | 1.94 Added workaround for one bug in Linux |
| 243 | Fixed one buffer leak |
| 244 | Fixed some incompatibilities with large extended attributes (but it's still |
| 245 | not 100% ok, I have no info on it and OS/2 doesn't want to create them) |
| 246 | Rewritten allocation |
| 247 | Fixed a bug with i_blocks (du sometimes didn't display correct values) |
| 248 | Directories have no longer archive attribute set (some programs don't like |
| 249 | it) |
| 250 | Fixed a bug that it set badly one flag in large anode tree (it was not |
| 251 | destructive) |
| 252 | 1.95 Fixed one buffer leak, that could happen on corrupted filesystem |
| 253 | Fixed one bug in allocation in 1.94 |
| 254 | 1.96 Added workaround for one bug in OS/2 (HPFS locked up, HPFS386 reported |
| 255 | error sometimes when opening directories in PMSHELL) |
| 256 | Fixed a possible bitmap race |
| 257 | Fixed possible problem on large disks |
| 258 | You can now delete open files |
| 259 | Fixed a nondestructive race in rename |
| 260 | 1.97 Support for HPFS v3 (on large partitions) |
| 261 | Fixed a bug that it didn't allow creation of files > 128M (it should be 2G) |
| 262 | 1.97.1 Changed names of global symbols |
| 263 | Fixed a bug when chmoding or chowning root directory |
| 264 | 1.98 Fixed a deadlock when using old_readdir |
| 265 | Better directory handling; workaround for "unbalanced tree" bug in OS/2 |
| 266 | 1.99 Corrected a possible problem when there's not enough space while deleting |
| 267 | file |
| 268 | Now it tries to truncate the file if there's not enough space when deleting |
| 269 | Removed a lot of redundant code |
| 270 | 2.00 Fixed a bug in rename (it was there since 1.96) |
| 271 | Better anti-fragmentation strategy |
| 272 | 2.01 Fixed problem with directory listing over NFS |
| 273 | Directory lseek now checks for proper parameters |
| 274 | Fixed race-condition in buffer code - it is in all filesystems in Linux; |
| 275 | when reading device (cat /dev/hda) while creating files on it, files |
| 276 | could be damaged |
| 277 | 2.02 Woraround for bug in breada in Linux. breada could cause accesses beyond |
| 278 | end of partition |
| 279 | 2.03 Char, block devices and pipes are correctly created |
| 280 | Fixed non-crashing race in unlink (Alexander Viro) |
| 281 | Now it works with Japanese version of OS/2 |
| 282 | 2.04 Fixed error when ftruncate used to extend file |
| 283 | 2.05 Fixed crash when got mount parameters without = |
| 284 | Fixed crash when allocation of anode failed due to full disk |
| 285 | Fixed some crashes when block io or inode allocation failed |
| 286 | 2.06 Fixed some crash on corrupted disk structures |
| 287 | Better allocation strategy |
| 288 | Reschedule points added so that it doesn't lock CPU long time |
| 289 | It should work in read-only mode on Warp Server |
| 290 | 2.07 More fixes for Warp Server. Now it really works |
| 291 | 2.08 Creating new files is not so slow on large disks |
| 292 | An attempt to sync deleted file does not generate filesystem error |
| 293 | 2.09 Fixed error on extremly fragmented files |
| 294 | |
| 295 | |
| 296 | vim: set textwidth=80: |