Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Oct 2004 23:03:50 +0900
From:      Kunihiro Kusano <kunihiro.kusano@k4.dion.ne.jp>
To:        bugbusters@FreeBSD.org
Subject:   A problem of directory
Message-ID:  <417D07C6.2070607@k4.dion.ne.jp>

next in thread | raw e-mail | index | archive | help
 >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@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 ---





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?417D07C6.2070607>