|
View:
New views
15 Messages
—
Rating Filter:
Alert me
|
|
|
rmdir(2) and mkdir(2) both return EISDIR for argument "/"hi there,
i dug up this old pr http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/59739 and was surprised it still remains valid for 9-CURRENT. indeed running the following code: #include <sys/stat.h> #include <errno.h> #include <stdio.h> #include <unistd.h> main() { rmdir("/"); printf("rmdir errno: %d\n", errno); mkdir("/", 511); printf("mkdir errno: %d\n", errno); } returns: rmdir errno: 21 mkdir errno: 21 which is EISDIR. as the pr already said EISDIR isn't mentioned at all in mkdir(2) or rmdir(2). so i guess this should either get fixed or we add a "BUGS" section to both manuals where this problem gets mentioned. alex _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
|
|
Re: rmdir(2) and mkdir(2) both return EISDIR for argument "/"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; } ... -- Alex Dupre _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
|
|
Re: rmdir(2) and mkdir(2) both return EISDIR for argument "/"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; > } > ... 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. alex --- vfs_lookup.c 2009-11-06 16:14:41.000000000 +0100 +++ /usr/src/sys/kern/vfs_lookup.c 2009-11-06 16:13:19.000000000 +0100 @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: head/sys/kern/vfs_lookup.c 195939 2009-07-29 07:44:43Z rwatson $"); #include "opt_kdtrace.h" #include "opt_ktrace.h" @@ -563,8 +563,12 @@ error = ENOTDIR; goto bad; } - if (cnp->cn_nameiop != LOOKUP) { - error = EISDIR; + if (cnp->cn_nameiop != LOOKUP && cnp->cn_nameiop == DELETE) { + error = EBUSY; + goto bad; + } + if (cnp->cn_nameiop != LOOKUP && cnp->cn_nameiop == CREATE) { + error = EEXIST; goto bad; } if (wantparent) { _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
|
|
Re: rmdir(2) and mkdir(2) both return EISDIR for argument "/"Alexander Best ha scritto:
> thanks a lot for finding the problem in the src. what do you think of the > patch attached to this message? I'm sorry, but I haven't enough knowledge about this subsystem to judge your patch. Someone else should jump in. -- Alex Dupre _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
|
|
Re: rmdir(2) and mkdir(2) both return EISDIR for argument "/"Alex Dupre schrieb am 2009-11-06:
> Alexander Best ha scritto: > > thanks a lot for finding the problem in the src. what do you think > > of the > > patch attached to this message? > I'm sorry, but I haven't enough knowledge about this subsystem to > judge > your patch. Someone else should jump in. neither do i. ;) i fear the patch is just a dirty hack and probably breaks tons of conventions. ;) i'll post the patch as followup to the PR and see what happens. thanks again for having a look at the problem and pointing out the responsible code. alex _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
|
|
Re: rmdir(2) and mkdir(2) both return EISDIR for argument "/"On Fri, 06 Nov 2009 16:32:22 +0100 (CET)
Alexander Best <alexbestms@...> 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 _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
|
|
Re: rmdir(2) and mkdir(2) both return EISDIR for argument "/"Gary Jennejohn schrieb am 2009-11-06:
> On Fri, 06 Nov 2009 16:32:22 +0100 (CET) > Alexander Best <alexbestms@...> 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 good point. cn_nameiop can be either LOOKUP, CREATE, RENAME, or DELETE. i'll check if maybe errno is also set incorrectly when RENAME is used and hack up a better patch which will handle all possible cn_nameiop values. thanks for pointing this out. alex _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
|
|
Re: rmdir(2) and mkdir(2) both return EISDIR for argument "/"Gary Jennejohn schrieb am 2009-11-06:
> On Fri, 06 Nov 2009 16:32:22 +0100 (CET) > Alexander Best <alexbestms@...> 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? cheers. alex --- vfs_lookup.c 2009-11-06 16:14:41.000000000 +0100 +++ /usr/src/sys/kern/vfs_lookup.c 2009-11-06 17:41:40.000000000 +0100 @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: head/sys/kern/vfs_lookup.c 195939 2009-07-29 07:44:43Z rwatson $"); #include "opt_kdtrace.h" #include "opt_ktrace.h" @@ -563,6 +563,15 @@ error = ENOTDIR; goto bad; } + if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) { + error = EBUSY; + goto bad; + } + if (cnp->cn_nameiop == CREATE) { + error = EEXIST; + goto bad; + } + /* XXX This block might not be needed. */ if (cnp->cn_nameiop != LOOKUP) { error = EISDIR; goto bad; _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
|
|
Re: rmdir(2) and mkdir(2) both return EISDIR for argument "/"On Fri, 06 Nov 2009 17:43:06 +0100 (CET)
Alexander Best <alexbestms@...> wrote: > Gary Jennejohn schrieb am 2009-11-06: > > On Fri, 06 Nov 2009 16:32:22 +0100 (CET) > > Alexander Best <alexbestms@...> 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 _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
|
|
Re: rmdir(2) and mkdir(2) both return EISDIR for argument "/"Gary Jennejohn schrieb am 2009-11-06:
> On Fri, 06 Nov 2009 17:43:06 +0100 (CET) > Alexander Best <alexbestms@...> wrote: > > Gary Jennejohn schrieb am 2009-11-06: > > > On Fri, 06 Nov 2009 16:32:22 +0100 (CET) > > > Alexander Best <alexbestms@...> 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 that would be an option. however in the case of rmdir(2) EINVAL and EBUYS would both fit. depends whether be forbid deletion of / because it is a mountpoint or because / is actually /. and paths ending with . are forbidden as arg in rmdir(2). i guess we have to take a look at the POSIX specs before we can decide how to handle this. also i've discovered that permission checks for / seem to be handled differently than any other dir. on my machine /usr is a mountpoint. doing rmdir /usr returns EACCES as regular user and EBUSY as superuser. doing rmdir / as regular user however doesn't seem to check permission but returns EBUSY right away. but that's not a problem i guess. this is probably happening because the kern/vfs_lookup.c code is being executed before anything else (including permission checks). i'll have a look what POSIX has to say about the return values. but i agree with you. returning EINVAL seems logical. alex. _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
|
|
Re: rmdir(2) and mkdir(2) both return EISDIR for argument "/"Alexander Best schrieb am 2009-11-06:
> Gary Jennejohn schrieb am 2009-11-06: > > On Fri, 06 Nov 2009 17:43:06 +0100 (CET) > > Alexander Best <alexbestms@...> wrote: > > > Gary Jennejohn schrieb am 2009-11-06: > > > > On Fri, 06 Nov 2009 16:32:22 +0100 (CET) > > > > Alexander Best <alexbestms@...> 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 > that would be an option. however in the case of rmdir(2) EINVAL and > EBUYS > would both fit. depends whether be forbid deletion of / because it is > a > mountpoint or because / is actually /. and paths ending with . are > forbidden > as arg in rmdir(2). > i guess we have to take a look at the POSIX specs before we can > decide how to > handle this. > also i've discovered that permission checks for / seem to be handled > differently than any other dir. on my machine /usr is a mountpoint. > doing > rmdir /usr returns EACCES as regular user and EBUSY as superuser. > doing rmdir > / as regular user however doesn't seem to check permission but > returns EBUSY > right away. but that's not a problem i guess. this is probably > happening > because the kern/vfs_lookup.c code is being executed before anything > else > (including permission checks). > i'll have a look what POSIX has to say about the return values. but i > agree > with you. returning EINVAL seems logical. > alex. ok. here it goes. POSIX says: rmdir() [http://www.opengroup.org/onlinepubs/9699919799/functions/rmdir.html#tag_16_618]: If the directory is the root directory or the current working directory of any process, it is unspecified whether the function succeeds, or whether it shall fail and set errno to [EBUSY]. mkdir() [http://www.opengroup.org/onlinepubs/9699919799/functions/mkdir.html#tag_16_372]: nothing regarding /. rename() [http://www.opengroup.org/onlinepubs/9699919799/functions/rename.html#tag_16_614]: If either pathname argument refers to a path whose final component is either dot or dot-dot, rename() shall fail. so at least rmdir() should return EBUSY. also POSIX defines EBUSY for return() which isn't documented in our return(2) manual. alex _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
|
|
Re: rmdir(2) and mkdir(2) both return EISDIR for argument "/"Alexander Best schrieb am 2009-11-06:
> Alexander Best schrieb am 2009-11-06: > > Gary Jennejohn schrieb am 2009-11-06: > > > On Fri, 06 Nov 2009 17:43:06 +0100 (CET) > > > Alexander Best <alexbestms@...> wrote: > > > > Gary Jennejohn schrieb am 2009-11-06: > > > > > On Fri, 06 Nov 2009 16:32:22 +0100 (CET) > > > > > Alexander Best <alexbestms@...> 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 > > that would be an option. however in the case of rmdir(2) EINVAL and > > EBUYS > > would both fit. depends whether be forbid deletion of / because it > > is > > a > > mountpoint or because / is actually /. and paths ending with . are > > forbidden > > as arg in rmdir(2). > > i guess we have to take a look at the POSIX specs before we can > > decide how to > > handle this. > > also i've discovered that permission checks for / seem to be > > handled > > differently than any other dir. on my machine /usr is a mountpoint. > > doing > > rmdir /usr returns EACCES as regular user and EBUSY as superuser. > > doing rmdir > > / as regular user however doesn't seem to check permission but > > returns EBUSY > > right away. but that's not a problem i guess. this is probably > > happening > > because the kern/vfs_lookup.c code is being executed before > > anything > > else > > (including permission checks). > > i'll have a look what POSIX has to say about the return values. but > > i > > agree > > with you. returning EINVAL seems logical. > > alex. > ok. here it goes. POSIX says: > rmdir() > [http://www.opengroup.org/onlinepubs/9699919799/functions/rmdir.html#tag_16_618]: > If the directory is the root directory or the current working > directory of any > process, it is unspecified whether the function succeeds, or whether > it shall > fail and set errno to [EBUSY]. > mkdir() > [http://www.opengroup.org/onlinepubs/9699919799/functions/mkdir.html#tag_16_372]: > nothing regarding /. > rename() > [http://www.opengroup.org/onlinepubs/9699919799/functions/rename.html#tag_16_614]: > If either pathname argument refers to a path whose final component is > either > dot or dot-dot, rename() shall fail. > so at least rmdir() should return EBUSY. also POSIX defines EBUSY for > return() > which isn't documented in our return(2) manual. > alex this is getting a bit more complicated now. i've had a look at kern/vfs_syscalls.c where the basic rmdir(), rename() and mkdir() cals are being defined. looks like they themself set certain errno values, but those values get overwritten by kern/vfs_lookup.c i guess the right approach would be this one: if rmdir(), rename() or mkdir() is called with / set errno=EISDIR in kern/vfs_lookup.c. then in kern/vfs_syscalls.c do something like if(errno == EISDIR) return XXX; XXX being EBUSY for rmdir(), EINVAL for rename(), etc. i'll see if i can get this sorted out. alex _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
|
|
Re: rmdir(2) and mkdir(2) both return EISDIR for argument "/"Gary Jennejohn schrieb am 2009-11-06:
> On Fri, 06 Nov 2009 17:43:06 +0100 (CET) > Alexander Best <alexbestms@...> wrote: > > Gary Jennejohn schrieb am 2009-11-06: > > > On Fri, 06 Nov 2009 16:32:22 +0100 (CET) > > > Alexander Best <alexbestms@...> 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 here's a completely new patch. all the changes are in kern/vfs_syscall.c. so kern/vfs_lookup.c now stays just the way it is (please revert any changes from the previous patches i posted). after applying the patch this is the output from a slightly modified version of the test app i attached in my very first post: rmdir errno: 16 (EBUSY) <- EBUSY is required by POSIX mkdir errno: 17 (EEXIST) rename errno: 22 (EINVAL) these are the results when called with "/" as arg. the output doesn't differ if run with or without superuser privileges. when run with "." as arg this is the output as regular user: rmdir errno: 22 (EINVAL) mkdir errno: 17 (EEXIST) rename errno: 13 (EACCES) and as superuser: rmdir errno: 22 (EINVAL) mkdir errno: 17 (EEXIST) rename errno: 22 (EINVAL) does this look reasonable? would be nice if mkdir and rmdir would also check privileges at first like rename, but that's a different story i guess. ;) alex --- vfs_syscalls.c 2009-11-06 22:07:08.000000000 +0100 +++ /usr/src/sys/kern/vfs_syscalls.c 2009-11-06 21:37:47.000000000 +0100 @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: head/sys/kern/vfs_syscalls.c 196887 2009-09-06 11:44:46Z kib $"); #include "opt_compat.h" #include "opt_kdtrace.h" @@ -3587,8 +3587,12 @@ AUDITVNODE1, pathseg, old, oldfd, td); #endif - if ((error = namei(&fromnd)) != 0) + if ((error = namei(&fromnd)) != 0) { + /* Translate error code for rename("/", "dir2"). */ + if (error == EISDIR) + error = EINVAL; return (error); + } fvfslocked = NDHASGIANT(&fromnd); tvfslocked = 0; #ifdef MAC @@ -3737,8 +3741,12 @@ NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, segflg, path, fd, td); nd.ni_cnd.cn_flags |= WILLBEDIR; - if ((error = namei(&nd)) != 0) + if ((error = namei(&nd)) != 0) { + /* Translate error code for mkdir("/"). */ + if (error == EISDIR) + error = EEXIST; return (error); + } vfslocked = NDHASGIANT(&nd); vp = nd.ni_vp; if (vp != NULL) { @@ -3825,10 +3833,15 @@ bwillwrite(); NDINIT_AT(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE | AUDITVNODE1, pathseg, path, fd, td); - if ((error = namei(&nd)) != 0) + if ((error = namei(&nd)) != 0) { + /* Translate error code for rmdir("/"). */ + if (error == EISDIR) + error = EBUSY; return (error); + } vfslocked = NDHASGIANT(&nd); vp = nd.ni_vp; + /* XXX namei() takes care of this case. */ if (vp->v_type != VDIR) { error = ENOTDIR; goto out; @@ -3841,6 +3854,7 @@ goto out; } /* + * XXX namei() takes care of this case. * The root of a mounted filesystem cannot be deleted. */ if (vp->v_vflag & VV_ROOT) { _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
|
|
Re: rmdir(2) and mkdir(2) both return EISDIR for argument "/"On Fri, 06 Nov 2009 22:09:49 +0100 (CET)
Alexander Best <alexbestms@...> wrote: > here's a completely new patch. all the changes are in kern/vfs_syscall.c. so > kern/vfs_lookup.c now stays just the way it is (please revert any changes from > the previous patches i posted). > > after applying the patch this is the output from a slightly modified version > of the test app i attached in my very first post: > > rmdir errno: 16 (EBUSY) <- EBUSY is required by POSIX > mkdir errno: 17 (EEXIST) > rename errno: 22 (EINVAL) > > these are the results when called with "/" as arg. the output doesn't differ > if run with or without superuser privileges. > > when run with "." as arg this is the output as regular user: > > rmdir errno: 22 (EINVAL) > mkdir errno: 17 (EEXIST) > rename errno: 13 (EACCES) > > and as superuser: > > rmdir errno: 22 (EINVAL) > mkdir errno: 17 (EEXIST) > rename errno: 22 (EINVAL) > > does this look reasonable? would be nice if mkdir and rmdir would also check > privileges at first like rename, but that's a different story i guess. ;) > The only problem I see with this is that vfs_syscall.c now has knowledge about the internal details of vfs_lookup.c Maybe just mention in the comments that this is the case and could be a problem if vfs_lookup.c is changed for some reason? That's what I do when I have to use something like this. But we don't want to turn this into a gigantic bikeshed - we already have enough of those. --- Gary Jennejohn _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
|
|
Re: rmdir(2) and mkdir(2) both return EISDIR for argument "/"Gary Jennejohn schrieb am 2009-11-07:
> On Fri, 06 Nov 2009 22:09:49 +0100 (CET) > Alexander Best <alexbestms@...> wrote: > > here's a completely new patch. all the changes are in > > kern/vfs_syscall.c. so > > kern/vfs_lookup.c now stays just the way it is (please revert any > > changes from > > the previous patches i posted). > > after applying the patch this is the output from a slightly > > modified version > > of the test app i attached in my very first post: > > rmdir errno: 16 (EBUSY) <- EBUSY is required by POSIX > > mkdir errno: 17 (EEXIST) > > rename errno: 22 (EINVAL) > > these are the results when called with "/" as arg. the output > > doesn't differ > > if run with or without superuser privileges. > > when run with "." as arg this is the output as regular user: > > rmdir errno: 22 (EINVAL) > > mkdir errno: 17 (EEXIST) > > rename errno: 13 (EACCES) > > and as superuser: > > rmdir errno: 22 (EINVAL) > > mkdir errno: 17 (EEXIST) > > rename errno: 22 (EINVAL) > > does this look reasonable? would be nice if mkdir and rmdir would > > also check > > privileges at first like rename, but that's a different story i > > guess. ;) > The only problem I see with this is that vfs_syscall.c now has > knowledge > about the internal details of vfs_lookup.c > Maybe just mention in the comments that this is the case and could be > a problem if vfs_lookup.c is changed for some reason? That's what I > do when I have to use something like this. > But we don't want to turn this into a gigantic bikeshed - we already > have enough of those. > --- > Gary Jennejohn well like you said there are 2 possibilities of dealing with this: 1. in vfs_lookup.c or 2. in vfs_syscall.c personally i think vfs_syscall.c is the better solution. i only tested rmdir(), rename() and mkdir(). however lots of other apps/functions might be depending on vfs_lookup.c and are expecting namei() to return EISDIR for arg="/". if we change this behaviour we might break a lot of other stuff. also looking at vfs_syscall.c shows that a lot of code in there already depends and knows about vfs_lookup.c internal details. so we wouldn't be changing the whole vfs_syscall.c semantics. but you're right. this is the perfect topic for a bikeshed. ;) i'll wait for a few more days and if nobody has a problem with the last patch i'll submitted it as followup to kern/59739. thanks a lot for your help. :) cheers. alex _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
| Free embeddable forum powered by Nabble | Forum Help |