rmdir(2) and mkdir(2) both return EISDIR for argument "/"

Gary Jennejohn gary.jennejohn at freenet.de
Fri Nov 6 17:23:12 UTC 2009


On Fri, 06 Nov 2009 17:43:06 +0100 (CET)
Alexander Best <alexbestms at math.uni-muenster.de> wrote:

> Gary Jennejohn schrieb am 2009-11-06:
> > On Fri, 06 Nov 2009 16:32:22 +0100 (CET)
> > Alexander Best <alexbestms at math.uni-muenster.de> wrote:
> 
> > > Alex Dupre schrieb am 2009-11-06:
> > > > Alexander Best ha scritto:
> > > > > i dug up this old pr
> > > > > http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/59739
> 
> > > > I think the EISDIR error is coming from kern/vfs_lookup.c,
> > > > lookup()
> > > > function with cn_nameptr = "":
> 
> 
> > > >         /*
> > > >          * Check for degenerate name (e.g. / or "")
> > > >          * which is a way of talking about a directory,
> > > >          * e.g. like "/." or ".".
> > > >          */
> > > >         if (cnp->cn_nameptr[0] == '\0') {
> > > >                 ...
> > > >                 if (cnp->cn_nameiop != LOOKUP) {
> > > >                         error = EISDIR;
> > > >                         goto bad;
> > > >                 }
> > > >                 ...
> 
> > > thanks a lot for finding the problem in the src. what do you think
> > > of the
> > > patch attached to this message? after applying it the example code
> > > i posted in
> > > my previous message returns the following output (instead of
> > > EISDIR):
> 
> > > rmdir errno: 16 (which is EBUSY)
> > > mkdir errno: 17 (which is EEXIST)
> 
> > > i don't know if these really are the correct return values, but
> > > it's what the
> > > originator of the PR requested.
> 
> 
> > What if cn_nameiop is != LOOKUP but also neither DELETE nor CREATE,
> > assuming that case is possible?  I'd leave the original if-clause at
> > the end to catch that.
> 
> > ---
> > Gary Jennejohn
> 
> how about this patch?
> 
> 1. i've added "if (cnp->cn_nameiop != LOOKUP)" although i don't think it's
> necessary since the first blocks should cover all the possible cases.
> 2. i've used rename() to test the case (cnp->cn_nameiop != RENAME). is this
> correct or does rename() use a combo of DELETE and CREATE? problem is that the
> rename(2) manual doesn't seem to cover the case that arg 1 is a mountpoint.
> right now EBUSY gets returned if cnp->cn_nameiop != RENAME. however BUSY needs
> to be added to all manuals which use cnp->cn_nameiop != RENAME (shouldn't be
> too many). or are there any other suggestions what rename() should return if
> arg 1 is a mountpoint?
> 

Hmm. In rename(2) there's

[EINVAL]           The from argument is a parent directory of to, or an
                   attempt is made to rename `.' or `..'.

and a few lines below your patch this case is handled for ISDOTDOT
for both RENAME and DELETE.  I don't see off hand where renaming or
deleting "." is handled.

According to the comment above your patch the case of "/." or "." is
being checked, which would seem to correspond to the above part of
rename(2), i.e. perhaps EINVAL should be returned for RENAME and DELETE.

---
Gary Jennejohn


More information about the freebsd-hackers mailing list