From: kjb@cs.vu.nl (Kees J. Bot)
Subject: Re: Long filenames
Organization: Fac. Wiskunde & Informatica, VU, Amsterdam
Date: Wed, 23 Dec 1992 19:29:55 GMT

torvalds@klaava.Helsinki.FI (Linus Torvalds) writes:

>In article <a75d0246@mtlookitthat.chi.il.us> chanson@mtlookitthat.chi.il.us (Chris Hanson) writes:
>>Hi!  Can anyone point me to some info (or tell me themselves) on how to
>>implement long filenames for minix?  [I know someone's done it -- one
>>of the dudes in the 'MINIX vs LINUX' discussion mentioned it.]  I'm
>>thinking that 30 chars or 62 chars shouldn't be that hard (we'd be
>>keeping a dir_entry at an even multiple of 16 bytes), but I know it'll
>>involve more than just recompiling the kernel with MAX_NAME changed.

I am the someone mentioned by this dude.

>The problem shouldn't be so much the kernel as all the binaries you are
>using: changing the directory structure will break everything that reads
>directory entries - this includes important binaries like 'ls'
>(obviously), the shell (for filename globbing, name completion etc),
>'make', etc. 

Precisely.  The changes I made to fs/path.c were only 100 lines long or
so.  With another 100 lines for the include files.  The utilities were a
major hassle, I even wrote my own ls.c.  Luckily almost all utilities in
1.6.23 use readdir now.  Only the use of d_reclen must be cut out of
cp.c, POSIX only mentiones d_name.

>>Will I need to make new filesystems and move everything to them?  Or is
>>a compatibility hack (such as puting an optional fstype flag or a
>>different magic number in a device's superblock to tell whether it has
>>long or standard pathnames) trivial?

>I'd go for the compatability hack: creating a new filesystem from
>scratch for the new kernel is simply too painful (as well as making
>debugging pretty mcuh impossible...  much easier to start off with just
>one partition with the extended setup, and test out all the new binaries
>on that one first).  I'd also suggest you add a "readdir()" system call
>while you are at it, which checks the magic number and returns the
>correct type of directory entry.  That way binaries compiled to use it
>will be able to function correctly on both the new and old type of
>filesystem.

I added a flag to the file system thereby creating a new filesystem
type.  I did not change the magic number to keep df and such working.
Readdir is still a library routine that makes a simple check on the
first read, transforming the old directory entries to the new form.

>There are a couple of alternatives you could do:

> (a) go for a complete vfs (virtual filesystems) interface.  This would
>make it possible to later add totally different types of filesystems. 
>It's more general, but it's also a lot more coding.  This is the
>approach linux uses, and it gives the possibility to mount msdos etc
>filesystems transparently. 

One of the ideas on the waiting on shelf.  It would be nice to do it
right.  (Your struct inode is way too big.)

> (b) do the long filenames by fooling around with several consecutive
>minix-type directory entries.  Depending on how you do it, you can make
>old binaries see only th first characters of a extended filename, while
>new binaries see them all.  Besides, this means you won't waste a full
>64-char direntry for short files, but instead use several entries only
>when necessary.  The downside is that it's a bit more work in the
>kernel. 

I changed everything to use use readdir, there can be too much backwards
compatibility.  There are a lot of programs that did not even read
directories, the C compiler to name one.

>The directory entries in (b) could be made to work by using a magic
>cookie at the end of a filename to mean that the filename continues in
>the next entry (which has a inode nr of 0 to make old programs ignore
>it).  It could look something like this:

>file "really_long_name", use '\000\377' as continuation marker:

>	.word inode_number
>	.byte 'really_long_\000\377'	/* first 12 chars */
>	.word 0x0000			/* next entry is a continuation */
>	.byte 'filename\0'		/* rest of the filename */

>This can be extended to any filename length, and old programs will see
>only the first 12 characters, but they should work otherwise.  I think
>somebody implemented something like this.  Patches, anybody? Naturally,
>you'd have to make sure that none of your current filesystems happen to
>have the '\000\377' sequence at the end of a directory entry, but that
>should be simple enough. 

Not even your C code contains assembly, but your articles too. :-)

(Last time I tried Linux I installed it on a partition I had reserved
as swap space for Minix.  What fun it was when Philip implemented
swapping... (I wasn't too wild about Linux then (0.96), it kept
crashing.)  Did you implement swapping on floppies Linus?  Try the Minix
distribution disks. :-)  )

My directory entries look like this:

	struct _fl_direct {
		ino_t	d_ino;
		unsigned char d_extent;
		char	d_name[5];
	}

The d_extent field tells how many 8-byte slots follow the first.
Readdir knows it has a new type if d_extent is 0 instead of '.'.
struct dirent looks like _fl_direct (fl for flex), but with d_name at
the maximum, 61.  The max is so low because fsck keeps one entry for
each component in a deep path...  (I invented this for Minix 1.3 on my
old 286.)  I decided that it was close enough to infinity.

I have to answer any questions at 2400 baud, so if you can wait until
January 4 with the big ones...
--
	                        Kees J. Bot  (kjb@cs.vu.nl)
	              Systems Programmer, Vrije Universiteit Amsterdam
Newsgroups: comp.os.minix