[comp.unix.internals] Slashes in file names

barmar@think.com (Barry Margolin) (02/13/91)

In article <2135@m1.cs.man.ac.uk> dente@els.ee.man.ac.uk (Colin Dente) writes:
>Forgive my ignorance in all this, but how *does* nfs create these
>files with slashes in their names?  It seems rather strange that nfs
>doesn't go through the kernel to do it (and hence get pulled up short
>by namei() etc.)  Perhaps this should go to comp.nfs.clueless, but I
>really don't understand!

It's a fair question about a non-obvious point, don't sell yourself short.

Unix NFS servers are generally implemented *in* the kernel, not as
user-mode processes that make system calls (the nfsd(8) command forks the
specified number of processes, and then they all simply make a
non-returning system call that starts up a server in the kernel).  This
permits them to use inode numbers in file handles, and then access the
files using the extracted inode information.  Since it accesses files and
directories directly, it doesn't go through namei().  Note that the NFS
protocol never passes pathnames from the client to the server (except for
the target of a symbolic link, but it's treated as an arbitrary string by
the NFS server); it is the client's job to parse pathnames and make
separate calls to look up the name at each level of the directory
hierarchy.  For instance, a Unix client with the directory /mnt
NFS-mounted, would perform the following calls when asked to create
/mnt/foo/bar/baz:

	foo_handle = NFS_Lookup(mnt_handle, "foo");
	foo_stat = NFS_Stat(foo_handle);
	if (foo_stat.type != DIRECTORY) error();
	bar_handle = NFS_Lookup(foo_handle, "bar");
	bar_stat = NFS_Stat(bar_handle);
	if (bar_stat.type != DIRECTORY) error();
	NFS_Create (bar_handle, "baz");

Since only file names, not pathnames, are ever passed, the server never
calls namei() to parse the arguments.


--
Barry Margolin, Thinking Machines Corp.

barmar@think.com
{uunet,harvard}!think!barmar

scs@adam.mit.edu (Steve Summit) (02/14/91)

I begin to understand why people have such passionately awful
things to say about NFS.

As far as I'm concerned, if the NFS server code can create an
illegal file (where "illegal" is defined by the host on which the
server is running), then that's a bug in the NFS server, period.
If the protocol doesn't include an error return of "I can't
create a file of that name" (not surprising; <errno.h> doesn't
define that specific error either, although it probably should),
then it should just say something halfway like "no such file or
directory."

If the client can help out by trying not to ask for illegal files
in the first place, that's fine; but in the final analysis the
server has got to protect itself.  Having the client not ask for
illegal files is never going to work perfectly, anyway: even if a
negotiation is defined by which the client can learn which
characters are illegal, some operating system somewhere is going
to have rules that can't be encoded that simply.

Has anyone ever considered modifying namei so that it essentially
checks to see if the current path character matches a target
filename character *before* checking to see if the current path
character is a '/'?  That would make the filesystem robust
against inadvertent /'s in filenames, because unlink("a/b/c")
would in fact unlink a file called "b/c" in directory "a", if one
somehow existed.

(To be sure, there would be idiosyncrasies associated with such
an algorithm.  In the above example, if directory "a" also
contained a subdirectory "b" as well as a file "b/c" the behavior
would depend on which came first, or something.  Still, it might
be a nice escape hatch.  Note that by only attempting to match
existing files in this way, it would still never create a
filename with a slash.)

                                            Steve Summit
                                            scs@adam.mit.edu

sef@kithrup.COM (Sean Eric Fagan) (02/14/91)

In article <1991Feb14.070512.24190@athena.mit.edu> scs@adam.mit.edu writes:
>If the protocol doesn't include an error return of "I can't
>create a file of that name" (not surprising; <errno.h> doesn't
>define that specific error either, although it probably should),

It does.  BSD has been using EINVAL to indicate an illegal filename (8-bit
set in one or more of the characters), I believe.  Thus, I think that's the
error that should have been used, if possible.

-- 
Sean Eric Fagan  | "I made the universe, but please don't blame me for it;
sef@kithrup.COM  |  I had a bellyache at the time."
-----------------+           -- The Turtle (Stephen King, _It_)
Any opinions expressed are my own, and generally unpopular with others.

jik@athena.mit.edu (Jonathan I. Kamens) (02/15/91)

In article <15898.27bc3908@levels.sait.edu.au>, xtdn@levels.sait.edu.au writes:
|> So SysV has allowed filenames with 8-bit set for ages.  Sorry that I don't
|> have access to BSD right now, but I wouldn't think that it was different.
|> Am I wrong?

  Yes, or at least you are for 4.3.  Our 4.3 kernel sources show filenames
being rejected if they contain characters with the eighth bit set, and I've
verified that this actually happens.

  I can't find a similar restriction in the 4.3tahoe kernel, although the
structure is noticeably different, so I may be missing it.  My suspicion,
though, is that 4.3tahoe (and 4.3reno and eventually 4.4) remove this
restriction.  But stock 4.3 definitely has it.

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

xtdn@levels.sait.edu.au (02/16/91)

sef@kithrup.COM (Sean Eric Fagan) writes:
> BSD has been using EINVAL to indicate an illegal filename (8-bit
> set in one or more of the characters), I believe.

Truly?  According to S5R1 intro(2):

    Filename.
        Names consisting of 1 to 14 characters may be used to name an
        ordinary file, special file, or directory.

        These characters may be selected from the set of all character
        values excluding \0 (null) and the ASCII code for / (slash).

So SysV has allowed filenames with 8-bit set for ages.  Sorry that I don't
have access to BSD right now, but I wouldn't think that it was different.
Am I wrong?


David Newall, who no longer works       Phone:  +61 8 344 2008
for SA Institute of Technology          E-mail: xtdn@lux.sait.edu.au
                "Life is uncertain:  Eat dessert first"

guy@auspex.auspex.com (Guy Harris) (02/18/91)

>  I can't find a similar restriction in the 4.3tahoe kernel, although the
>structure is noticeably different, so I may be missing it.

You must have a funny version of 4.3-tahoe, then; the structure of the
4.3-tahoe "ufs_namei.c" we have here isn't that different from 4.3BSD's
(<100 lines of output from "diff").  The restriction is still there in
the version of 4.3-tahoe we have.

>My suspicion, though, is that 4.3tahoe (and 4.3reno and eventually 4.4)
>remove this restriction.

4.3-reno's structure *is* considerably different; however, the
restriction is *still* there, alas, although it's imposed at the system
call layer and in the NFS server code, rather than in the file system
code.

It's not inherent to the BSD file system, of course; SunOS 4.x, System V
Release 4, and probably lots of other systems with BSD file systems
don't have it (I wouldn't be surprised if Ultrix and HP-UX removed it as
well).  (When I removed it from SunOS 4.0, I tested it by making a
symbolic link to "/vmunix" named "/UNIX(R)", where "(R)" is the ISO
Latin #1 "registered trademark" symbol (character code 0xAE).)

guy@auspex.auspex.com (Guy Harris) (02/18/91)

>So SysV has allowed filenames with 8-bit set for ages.

Yup - in fact, that dates all the way back to V7, and even earlier (I
don't think V6 disallowed them, either - dunno if any of its
predecessors did).

>Sorry that I don't have access to BSD right now, but I wouldn't think
>that it was different.  Am I wrong?

It is different.  4.1BSD disallowed the character '/'|0200, and 4.2BSD
and successors disallowed any characters with the 8th bit set.

net@opal.cs.tu-berlin.de (Oliver Laumann) (02/18/91)

In article <6104@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes:
> Yup - in fact, that dates all the way back to V7, and even earlier (I
> don't think V6 disallowed them, either - dunno if any of its
> predecessors did).

Yeah.  I'm sure you remember the

   $ date > "foo"
   $ rm foo
   foo: non-existent
   $ rm "foo"
   $

botch of the V6 shell.

Regards,
--
    Oliver Laumann,  Technical University of Berlin,  Germany.
    net@tub.cs.tu-berlin.de  net@tub.UUCP  net@pogo.ai.mit.edu

cjc@ulysses.att.com (Chris Calabrese) (02/19/91)

In article <15898.27bc3908@levels.sait.edu.au> xtdn@levels.sait.edu.au writes:
>sef@kithrup.COM (Sean Eric Fagan) writes:
>> BSD has been using EINVAL to indicate an illegal filename (8-bit
>> set in one or more of the characters), I believe.

[ stuff about sVr1 intro(2) deleted]

>So SysV has allowed filenames with 8-bit set for ages.  Sorry that I don't
>have access to BSD right now, but I wouldn't think that it was different.
>Am I wrong?

8-bit seems to work on BAD to me:

936) > kk^?
937) ls kk*
kk?
938) echo kk* | od -c
0000000    k   k 177  \n
0000004

This is on a Solboune (Sun 4 clone) running OS/SMP 4.0D_Export
(something like SunOS 4.0.3) with the BSD Fast File System.

Name:			Christopher J. Calabrese
Brain loaned to:	AT&T Bell Laboratories, Murray Hill, NJ
att!ulysses!cjc		cjc@ulysses.att.com
Obligatory Quote:	``pher - gr. vb. to schlep.  phospher - to schlep light.philosopher - to schlep thoughts.''

guy@auspex.auspex.com (Guy Harris) (02/21/91)

>8-bit seems to work on BAD to me:
>
>936) > kk^?
>937) ls kk*
>kk?
>938) echo kk* | od -c
>0000000    k   k 177  \n

There aren't any 8-bit characters there, unless those "k"s are really "k
with the 8th bit turned on"; rubout isn't an 8-bit character - it has
the bottom seven bits turned on, but not the 8th bit.

Also, SunOS ain't BSD; the checks for 8-bit characters were removed from
the SunOS file system code in 4.0.