Re: rmdir of one's pwd

Andries.Brouwer@cwi.nl
Mon, 15 Feb 1999 20:35:44 +0100 (MET)


From viro@math.psu.edu Mon Feb 15 18:13:39 1999

On Mon, 15 Feb 1999 Andries.Brouwer@cwi.nl wrote:

> ENOTEMPTY or EEXIST
> newpath is a non-empty directory, i.e., contains
> entries other than "." and "..".
>
> EINVAL The new pathname contained a path prefix of the
> old, or, more generally, an attempt was made to
> make a directory a subdirectory of itself.
>
> (The second part of this description is required to cover
> cases involving symbolic links.)

Umm... Do we have a filesystem that would return EEXIST instead of ENOENT?

You mean `instead of ENOTEMPTY'?
That is irrelevant. POSIX describes that the system call can return
these two values in this case. An application program must be ready
to handle both error return values, even if Linux today uses only one
of them.

I've looked through the rename(2) manpage again and found several
inaccuracies:

| If newpath exists but the operation fails for some reason
| or the system crashes rename guarantees to leave an
| instance of newpath in place.

+++Notice that currently for some filesystems crash may lead to the
+++situation when the link disappears. Example: VFAT.

Removed the `or the system crashes' part. That was a very optimistic
author, who wanted to guarantee things even in case of a crash.
The rest of the sentence is a POSIX requirement.

| EBUSY newpath exists and is the current working direc-
| tory or root directory of some process.

+++Or is opened by some process. Or if the source is mountpoint
+++or root directory of filesystem (different things, since
+++mount over busy directories is allowed). Ditto for target
+++(if it exists, indeed).

New text:

EBUSY The rename fails because oldpath or newpath is a
directory that is in use by some process (perhaps
as current working directory, or as root directory,
or because it was open for reading) or is in use by
the system (for example as mount point), while the
system considers this an error. (Note that there
is no requirement to return EBUSY in such cases -
there is nothing wrong with doing the rename anyway
- but it is allowed to return EBUSY if the system
cannot otherwise handle such situations.)

| EACCES Write access to the directory containing oldpath
| or newpath is not allowed for the process's effec-
| tive uid, or one of the directories in oldpath or
| newpath did not allow search (execute) permission,
| or oldpath was a directory and did not allow write
| permission (needed to update the .. entry).

+++IMHO it needs a clarification. First of all, until now
+++write access to the oldpath was not checked. James
+++Griffiths spotted that out and I've included the check
+++in the latest variant of rename patch, but *only* for
+++cross-directory moves. I think that mentioning of
+++changing parents is needed here.

I don't think so. Think of ancient UNIX. A directory is just a file
containing file names. If you want to change a name, then you have
to have write permission to the directory.

| EPERM The directory containing oldpath has the sticky
| bit set and the process's effective uid is neither
| the uid of the file to be deleted nor that of the
| directory containing it, or the filesystem con-
| taining pathname does not support renaming of the
| type requested.
+++EPERM also happens if you can't delete target due to
+++sticky bit on target's parent. Root (CAP_FOWNER, actually)
+++can override sticky bit effects.

New text:

EPERM or EACCES
The directory containing oldpath has the sticky bit
set and the process's effective uid is neither the
uid of the file to be deleted nor that of the
directory containing it, or newpath is an existing
file and the directory containing it has the sticky
bit set and the process's effective uid is neither
the uid of the file to be replaced nor that of the
directory containing it, or the filesystem contain­
ing pathname does not support renaming of the type
requested.

+++Immutable and Append-only on source, target or their parents may
+++give EACCES or EPERM (hmm...)

Undocumented.

+++ENOTDIR also happens if oldpath is a directory and newpath
+++exists and is not a directory.

New text:

ENOTDIR
A component used as a directory in oldpath or new­
path is not, in fact, a directory. Or, oldpath is
a directory, and newpath exists but is not a direc­
tory.

[A nice collection of +++ items you have. A test for bad modems?]

Rename:
*We should be able to lookup the source and target.
*We should be able to remove the source (link).
*If the target exists we should be able to remove it.
*If the target doesn't exist we should be able to create a link in
target's parent.
*If the target exists and is not a directory source also should be
not a directory, otherwise - EISDIR.
*If the target exists and is a directory source also should be a
directory, otherwise - ENOTDIR.
*If both links point to the same file we succeed. (Ouch... so we
should move this check up...)
*Both source and target must be on the same filesystem, otherwise -
EXDEV.
*If source and target have different parents and source is a
directory we must have write permissions on it, otherwise -
EACCES.
(Question: what about execute permissions?)

As mentioned already, we need write permission as soon as we change
a name in a directory. We need execute (search) permission in all
directories involved, including the final ones where we'll write.

*If the move would make the source its own subdirectory - EINVAL.
*If the rename() is not supported by the filesystem - EPERM.
*If the target is somebody's root or pwd or is opened by some
process - EBUSY.

This is allowed, but not encouraged. Clearly a system without such
restrictions is much more useful.

*If the target is not empty - ENOTEMPTY (there is a borderline
case, if the target is not empty and somebody opened a file in
(under) it we return EBUSY).

ENOTEMPTY is preferable. A good system would not use EBUSY at all.

*Any checks applied by filesystem (EMLINK, EIO, EDEADLOCK (yup.
UMSDOS...))

Andries

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/