Date: Fri, 5 Mar 2010 07:57:59 +0200 From: Jaakko Heinonen <jh@FreeBSD.org> To: freebsd-hackers@FreeBSD.org Cc: freebsd-hackers@FreeBSD.org, Poul-Henning Kamp <phk@phk.freebsd.dk>, Bruce Evans <brde@optusnet.com.au>, Alexander Best <alexbestms@wwu.de> Subject: Re: namei() returns EISDIR for "/" (Re: svn commit: r203990 - head/lib/libc/sys) Message-ID: <20100305055758.GA1062@a91-153-117-195.elisa-laajakaista.fi> In-Reply-To: <20100228174936.GA1252@a91-153-117-195.elisa-laajakaista.fi> References: <6413.1266433105@critter.freebsd.dk> <20100218064545.J2074@besplex.bde.org> <20100218095538.GA2318@a91-153-117-195.elisa-laajakaista.fi> <20100225195138.GA3323@a91-153-117-195.elisa-laajakaista.fi> <20100226091923.X2605@delplex.bde.org> <20100228174936.GA1252@a91-153-117-195.elisa-laajakaista.fi>
next in thread | previous in thread | raw e-mail | index | archive | help
--J2SCkAp4GZ/dPZZf Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On 2010-02-28, Jaakko Heinonen wrote: > > > http://people.freebsd.org/~jh/patches/lookup-root.diff I have updated the patch taking some of bde's comments into account. The new version also includes updates for namei(9) manual page. The patch is attached to this mail and also found at: http://people.freebsd.org/~jh/patches/lookup-root.2.diff -- Jaakko --J2SCkAp4GZ/dPZZf Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="lookup-root.2.diff" Index: sys/kern/vfs_lookup.c =================================================================== --- sys/kern/vfs_lookup.c (revision 204620) +++ sys/kern/vfs_lookup.c (working copy) @@ -565,18 +565,26 @@ dirloop: } /* - * Check for degenerate name (e.g. / or "") - * which is a way of talking about a directory, - * e.g. like "/." or ".". + * Check for "" which represents the root directory after slash + * removal. */ if (cnp->cn_nameptr[0] == '\0') { - if (dp->v_type != VDIR) { - error = ENOTDIR; - goto bad; - } - if (cnp->cn_nameiop != LOOKUP) { - error = EISDIR; - goto bad; + KASSERT(dp->v_type == VDIR, ("dp is not a directory")); + /* + * We can't provide a parent node for CREATE, + * DELETE and RENAME operations. + */ + switch (cnp->cn_nameiop) { + case CREATE: + error = EEXIST; + goto bad; + case DELETE: + case RENAME: + error = EBUSY; + goto bad; + default: + KASSERT(cnp->cn_nameiop == LOOKUP, + ("nameiop must be LOOKUP")); } if (wantparent) { ndp->ni_dvp = dp; @@ -948,19 +956,17 @@ relookup(struct vnode *dvp, struct vnode #endif /* - * Check for degenerate name (e.g. / or "") - * which is a way of talking about a directory, - * e.g. like "/." or ".". + * Check for "" which represents the root directory after slash + * removal. */ if (cnp->cn_nameptr[0] == '\0') { - if (cnp->cn_nameiop != LOOKUP || wantparent) { - error = EISDIR; - goto bad; - } - if (dp->v_type != VDIR) { - error = ENOTDIR; - goto bad; - } + KASSERT(dp->v_type == VDIR, ("dp is not a directory")); + /* + * Support only LOOKUP for "/" because lookup() + * can't succeed for CREATE, DELETE and RENAME. + */ + KASSERT(cnp->cn_nameiop == LOOKUP, ("nameiop must be LOOKUP")); + if (!(cnp->cn_flags & LOCKLEAF)) VOP_UNLOCK(dp, 0); *vpp = dp; Index: sys/kern/vfs_syscalls.c =================================================================== --- sys/kern/vfs_syscalls.c (revision 204620) +++ sys/kern/vfs_syscalls.c (working copy) @@ -1841,7 +1841,7 @@ restart: NDINIT_AT(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE | AUDITVNODE1, pathseg, path, fd, td); if ((error = namei(&nd)) != 0) - return (error == EINVAL ? EPERM : error); + return ((error == EINVAL || error == EBUSY) ? EPERM : error); vfslocked = NDHASGIANT(&nd); vp = nd.ni_vp; if (vp->v_type == VDIR && oldinum == 0) { @@ -3617,9 +3617,6 @@ kern_renameat(struct thread *td, int old if (fromnd.ni_vp->v_type == VDIR) tond.ni_cnd.cn_flags |= WILLBEDIR; if ((error = namei(&tond)) != 0) { - /* Translate error code for rename("dir1", "dir2/."). */ - if (error == EISDIR && fvp->v_type == VDIR) - error = EINVAL; NDFREE(&fromnd, NDF_ONLY_PNBUF); vrele(fromnd.ni_dvp); vrele(fvp); Index: share/man/man9/namei.9 =================================================================== --- share/man/man9/namei.9 (revision 204620) +++ share/man/man9/namei.9 (working copy) @@ -338,8 +338,17 @@ An attempt is made to access a file in a permissions. .It Bq Er ELOOP Too many symbolic links were encountered in translating the pathname. -.It Bq Er EISDIR -An attempt is made to open a directory with write mode specified. +.It Bq Er EINVAL +The last component of the pathname specified for the RENAME operation is +.Ql \&. . +.It Bq Er EEXIST +The root directory +.Pq Ql / +was specified for the CREATE operation. +.It Bq Er EBUSY +The root directory +.Pq Ql / +was specified for the DELETE operation. .It Bq Er EROFS An attempt is made to modify a file or directory on a read-only file system. .El Index: lib/libc/sys/rename.2 =================================================================== --- lib/libc/sys/rename.2 (revision 204620) +++ lib/libc/sys/rename.2 (working copy) @@ -252,6 +252,12 @@ The .Fa to argument is a directory and is not empty. +.It Bq Er EBUSY +Either +.Fa from +or +.Fa to +is the root directory. .El .Pp In addition to the errors returned by the Index: lib/libc/sys/unlink.2 =================================================================== --- lib/libc/sys/unlink.2 (revision 204620) +++ lib/libc/sys/unlink.2 (working copy) @@ -114,8 +114,6 @@ succeeds unless: .Bl -tag -width Er .It Bq Er ENOTDIR A component of the path prefix is not a directory. -.It Bq Er EISDIR -The named file is a directory. .It Bq Er ENAMETOOLONG A component of a pathname exceeded 255 characters, or an entire path name exceeded 1023 characters. --J2SCkAp4GZ/dPZZf--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100305055758.GA1062>