A problem of directory

Kunihiro Kusano kunihiro.kusano at k4.dion.ne.jp
Mon Oct 25 07:03:57 PDT 2004


 >Submitter-Id:   current-users
 >Originator:       Kunihiro Kusano
 >Organization:   no
 >Confidential:    no
 >synopsis:           A problem of directory
 >Severity:           non-critical
 >Priority:            medium
 >Category:          kern
 >Class:                 change-request
 >Release:             FreeBSD 4.5-RELEASE-p2+ i386
 >Environment:
System: FreeBSD catherine 4.5-RELEASE-p2+ FreeBSD 4.5-RELEASE-p2+ #105: 
Tue Oct 19 17:08;43 JST 2004 kusano at catherine:/usr/src/compile/CATHERINE 
i386

machine: IBM Think Pad 2635-9aj

 >Description:

See below "How-To-Repeat.
In this case, "." and "../x" are identical.

I thought that
as "rmdir ." returns "Invalid argument",
"rmdir ../x" also returns the same error message.

You know /bin/rmdir depends on rmdir(2).
So this is a problem of system call.

I read a part of code for rmdir() function
which is in the /sys/kern/vfs_syscalls.c.

And I found that the program compares "struct vnode pointer".
One is for result directory, the other is for its parent directory.

When only command line argument is "rmdir .",
these two values can be identical.

This is not enough.
Struct proc has current directory vnode pointer.
                          ^^^^^^ ^^^^^^^ ^^^^^ ^^^^^^
I think program should use this value.
See below a.patch.

 >How-To-Repeat:

$ mkdir x
$ cd x
$ rmdir .
rmdir: .: Invalid argument
$ rmdir ../x
$ /bin/pwd
pwd: .: No such file or directory
$


 >Fix:

--- a.patch begins here ---
--- org/vfs_syscalls.c Tue Jan  8 05:47:34 2002
+++ vfs_syscalls.c     Tue Oct 19 17:05:41 2004
@@ -2784,9 +2784,10 @@ rmdir(p, uap)
                               syscallarg(char *)path;
                } */ *uap;
 {
-              register struct vnode *vp;
+             register struct vnode *vp, *cvp;
               int error;
               struct nameidata nd;
+             struct filedesc *fdp;

               bwillwrite();
               NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE,
@@ -2798,10 +2799,13 @@ rmdir(p, uap)
                                 error = ENOTDIR;
                                  goto out;
                }
+
+              fdp = p->p_fd;
+              cvp = fdp->fd_cdir;                    /* current 
directory vnode ptr  */
                /*
                 * No rmdir "." please.
                 */
-               if ( nd.ni_dvp == vp) {
+              if ( cvp == vp) {
                             error = EINVAL;
                             goto out;
                 }
--- a.patch ends here ---





More information about the freebsd-bugbusters mailing list