* open() of device special files @ 2011-08-15 15:36 J. Bruce Fields 2011-08-15 16:03 ` Myklebust, Trond 0 siblings, 1 reply; 19+ messages in thread From: J. Bruce Fields @ 2011-08-15 15:36 UTC (permalink / raw) To: Trond Myklebust, linux-nfs; +Cc: steved How is the client supposed to handle opens of device special files? On a 3.1-rc1-based client to a linux server over v4.0 I'm seeing it try an OPEN call and failing when it gets an INVAL return. This looks like bogus client behavior (OPEN should fail on such files), unless the server has the error return wrong and the client's using an OPEN error to recover. If I first stat the device and then open it then it works as expected (the client does an open of the local device). I'm a bit annoyed at myself as I have a feeling we've discussed this before but I can't find a reference now. --b. ^ permalink raw reply [flat|nested] 19+ messages in thread
* RE: open() of device special files 2011-08-15 15:36 open() of device special files J. Bruce Fields @ 2011-08-15 16:03 ` Myklebust, Trond 2011-08-15 21:25 ` J. Bruce Fields 2011-08-17 1:40 ` J. Bruce Fields 0 siblings, 2 replies; 19+ messages in thread From: Myklebust, Trond @ 2011-08-15 16:03 UTC (permalink / raw) To: J. Bruce Fields, linux-nfs; +Cc: steved > -----Original Message----- > From: J. Bruce Fields [mailto:bfields@fieldses.org] > Sent: Monday, August 15, 2011 11:37 AM > To: Myklebust, Trond; linux-nfs@vger.kernel.org > Cc: steved@redhat.com > Subject: open() of device special files > > How is the client supposed to handle opens of device special files? On > a 3.1-rc1-based client to a linux server over v4.0 I'm seeing it try an > OPEN call and failing when it gets an INVAL return. > > This looks like bogus client behavior (OPEN should fail on such files), > unless the server has the error return wrong and the client's using an > OPEN error to recover. > > If I first stat the device and then open it then it works as expected > (the client does an open of the local device). > > I'm a bit annoyed at myself as I have a feeling we've discussed this > before but I can't find a reference now. Hmm... NFS4ERR_INVAL means 'invalid argument', which is not the case here; all the arguments that the client is passing to the server are valid, however the file cannot be opened because the pathname resolves on the server to a file of the wrong type. I can't see any other error definition that is "obviously correct", but it looks to me as if NFS4ERR_SYMLINK might be the closest thing. One reason is the dot-x file defines NFS4ERR_SYMLINK as meaning "should be file/directory". The other reason is that NFS4ERR_SYMLINK should _always_ trigger the correct behaviour on a client: a fresh lookup of the component. Cheers Trond ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: open() of device special files 2011-08-15 16:03 ` Myklebust, Trond @ 2011-08-15 21:25 ` J. Bruce Fields 2011-08-15 22:23 ` J. Bruce Fields ` (3 more replies) 2011-08-17 1:40 ` J. Bruce Fields 1 sibling, 4 replies; 19+ messages in thread From: J. Bruce Fields @ 2011-08-15 21:25 UTC (permalink / raw) To: Myklebust, Trond; +Cc: linux-nfs, steved, nfsv4 On Mon, Aug 15, 2011 at 09:03:30AM -0700, Myklebust, Trond wrote: > > -----Original Message----- > > From: J. Bruce Fields [mailto:bfields@fieldses.org] > > How is the client supposed to handle opens of device special files? > On > > a 3.1-rc1-based client to a linux server over v4.0 I'm seeing it try > an > > OPEN call and failing when it gets an INVAL return. > > > > This looks like bogus client behavior (OPEN should fail on such > files), > > unless the server has the error return wrong and the client's using an > > OPEN error to recover. > > > > If I first stat the device and then open it then it works as expected > > (the client does an open of the local device). > > > > I'm a bit annoyed at myself as I have a feeling we've discussed this > > before but I can't find a reference now. > > Hmm... NFS4ERR_INVAL means 'invalid argument', which is not the case > here; all the arguments that the client is passing to the server are > valid, however the file cannot be opened because the pathname resolves > on the server to a file of the wrong type. > > I can't see any other error definition that is "obviously correct", but > it looks to me as if NFS4ERR_SYMLINK might be the closest thing. One > reason is the dot-x file defines NFS4ERR_SYMLINK as meaning "should be > file/directory". The other reason is that NFS4ERR_SYMLINK should > _always_ trigger the correct behaviour on a client: a fresh lookup of > the component. Confirmed the fix; I'll apply. But that's tricky--we should be document it for other server implementers if it's the right thing to do (working group list cc'd). --b. commit 3d83c016da8652f30dcac372772b67d68f33bfbd Author: J. Bruce Fields <bfields@redhat.com> Date: Mon Aug 15 16:55:02 2011 -0400 nfsd4: return nfserr_symlink on v4 OPEN of non-regular file Without this, an attempt to open a device special file without first stat'ing it will fail. Signed-off-by: J. Bruce Fields <bfields@redhat.com> diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 90c6aa6..cc8eb8d 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -69,6 +69,17 @@ nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type) return nfserr_notdir; else if ((mode & S_IFMT) == S_IFDIR) return nfserr_isdir; + /* + * err_symlink is our catch-all error in the v4 case; this + * looks odd, but: + * - the comment next to ERR_SYMLINK in file is + * "should be file/directory" + * - we happen to know this will cause the linux v4 + * client to do the right thing on attempts to open + * something other than a regular file: + */ + else if (rqstp->rq_vers == 4) + return nfserr_symlink; else return nfserr_inval; } ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: open() of device special files 2011-08-15 21:25 ` J. Bruce Fields @ 2011-08-15 22:23 ` J. Bruce Fields 2011-08-15 22:27 ` J. Bruce Fields 2011-08-16 5:03 ` Myklebust, Trond 2011-08-15 22:28 ` J. Bruce Fields ` (2 subsequent siblings) 3 siblings, 2 replies; 19+ messages in thread From: J. Bruce Fields @ 2011-08-15 22:23 UTC (permalink / raw) To: Myklebust, Trond; +Cc: linux-nfs, steved, nfsv4 On Mon, Aug 15, 2011 at 05:25:39PM -0400, J. Bruce Fields wrote: > On Mon, Aug 15, 2011 at 09:03:30AM -0700, Myklebust, Trond wrote: > > > -----Original Message----- > > > From: J. Bruce Fields [mailto:bfields@fieldses.org] > > > How is the client supposed to handle opens of device special files? > > On > > > a 3.1-rc1-based client to a linux server over v4.0 I'm seeing it try > > an > > > OPEN call and failing when it gets an INVAL return. > > > > > > This looks like bogus client behavior (OPEN should fail on such > > files), > > > unless the server has the error return wrong and the client's using an > > > OPEN error to recover. > > > > > > If I first stat the device and then open it then it works as expected > > > (the client does an open of the local device). > > > > > > I'm a bit annoyed at myself as I have a feeling we've discussed this > > > before but I can't find a reference now. > > > > Hmm... NFS4ERR_INVAL means 'invalid argument', which is not the case > > here; all the arguments that the client is passing to the server are > > valid, however the file cannot be opened because the pathname resolves > > on the server to a file of the wrong type. The long description of NFS4ERR_INVAL from rfc 3530: "Invalid argument or unsupported argument for an operation. Two examples are attempting a READLINK on an object other than a symbolic link or specifying a value for an enum field that is not defined in the protocol (e.g., nfs_ftype4)." So the text does recommend NFS4ERR_INVAL for the case where the operation doesn't make sense for the type of object given. (In the readlink example there's no pathname resolution, though). EINVAL seems to be used in the kernel for some such cases as well (e.g. attempt to truncate a device special file). > > I can't see any other error definition that is "obviously correct", but > > it looks to me as if NFS4ERR_SYMLINK might be the closest thing. One > > reason is the dot-x file defines NFS4ERR_SYMLINK as meaning "should be > > file/directory". And this seems more a coincidence due to vagueness resulting from the need for a single-line comment; the longer description is: "NFS4ERR_SYMLINK The current filehandle provided for a LOOKUP is not a directory but a symbolic link. Also used if the final component of the OPEN path is a symbolic link." > > The other reason is that NFS4ERR_SYMLINK should > > _always_ trigger the correct behaviour on a client: a fresh lookup of > > the component. > > Confirmed the fix; I'll apply. Applying anyway for compatibility with existing clients, but this all seems a little weird. --b. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: open() of device special files 2011-08-15 22:23 ` J. Bruce Fields @ 2011-08-15 22:27 ` J. Bruce Fields 2011-08-16 5:04 ` Myklebust, Trond 2011-08-16 5:03 ` Myklebust, Trond 1 sibling, 1 reply; 19+ messages in thread From: J. Bruce Fields @ 2011-08-15 22:27 UTC (permalink / raw) To: Myklebust, Trond; +Cc: linux-nfs, steved, nfsv4 On Mon, Aug 15, 2011 at 06:23:36PM -0400, J. Bruce Fields wrote: > On Mon, Aug 15, 2011 at 05:25:39PM -0400, J. Bruce Fields wrote: > > On Mon, Aug 15, 2011 at 09:03:30AM -0700, Myklebust, Trond wrote: > > > > -----Original Message----- > > > > From: J. Bruce Fields [mailto:bfields@fieldses.org] > > > > How is the client supposed to handle opens of device special files? > > > On > > > > a 3.1-rc1-based client to a linux server over v4.0 I'm seeing it try > > > an > > > > OPEN call and failing when it gets an INVAL return. > > > > > > > > This looks like bogus client behavior (OPEN should fail on such > > > files), > > > > unless the server has the error return wrong and the client's using an > > > > OPEN error to recover. > > > > > > > > If I first stat the device and then open it then it works as expected > > > > (the client does an open of the local device). > > > > > > > > I'm a bit annoyed at myself as I have a feeling we've discussed this > > > > before but I can't find a reference now. > > > > > > Hmm... NFS4ERR_INVAL means 'invalid argument', which is not the case > > > here; all the arguments that the client is passing to the server are > > > valid, however the file cannot be opened because the pathname resolves > > > on the server to a file of the wrong type. > > The long description of NFS4ERR_INVAL from rfc 3530: > > "Invalid argument or unsupported argument for an operation. Two > examples are attempting a READLINK on an object other than a > symbolic link or specifying a value for an enum field that is > not defined in the protocol (e.g., nfs_ftype4)." > > So the text does recommend NFS4ERR_INVAL for the case where the > operation doesn't make sense for the type of object given. (In the > readlink example there's no pathname resolution, though). > > EINVAL seems to be used in the kernel for some such cases as well (e.g. > attempt to truncate a device special file). > > > > I can't see any other error definition that is "obviously correct", but > > > it looks to me as if NFS4ERR_SYMLINK might be the closest thing. One > > > reason is the dot-x file defines NFS4ERR_SYMLINK as meaning "should be > > > file/directory". > > And this seems more a coincidence due to vagueness resulting from the > need for a single-line comment; the longer description is: > > "NFS4ERR_SYMLINK The current filehandle provided for a LOOKUP is > not a directory but a symbolic link. Also used > if the final component of the OPEN path is a > symbolic link." > > > > The other reason is that NFS4ERR_SYMLINK should > > > _always_ trigger the correct behaviour on a client: a fresh lookup of > > > the component. > > > > Confirmed the fix; I'll apply. > > Applying anyway for compatibility with existing clients, but this all > seems a little weird. And the change also makes a bunch of pynfs tests fail, complaining that various operations against incompatible types should have returned INVAL and not SYMLINK. Not that I'm convinced pynfs is correct--at the very least it should have accepted a range of errors for those tests, I think--but anyone else that ran pynfs against their server may have assumed it pynfs was correct in these cases.... --b. ^ permalink raw reply [flat|nested] 19+ messages in thread
* RE: open() of device special files 2011-08-15 22:27 ` J. Bruce Fields @ 2011-08-16 5:04 ` Myklebust, Trond 2011-08-16 11:03 ` J. Bruce Fields 0 siblings, 1 reply; 19+ messages in thread From: Myklebust, Trond @ 2011-08-16 5:04 UTC (permalink / raw) To: J. Bruce Fields; +Cc: linux-nfs, steved, nfsv4 > -----Original Message----- > From: J. Bruce Fields [mailto:bfields@fieldses.org] > Sent: Monday, August 15, 2011 6:27 PM > To: Myklebust, Trond > Cc: linux-nfs@vger.kernel.org; steved@redhat.com; nfsv4@ietf.org > Subject: Re: open() of device special files > > On Mon, Aug 15, 2011 at 06:23:36PM -0400, J. Bruce Fields wrote: > > On Mon, Aug 15, 2011 at 05:25:39PM -0400, J. Bruce Fields wrote: > > > On Mon, Aug 15, 2011 at 09:03:30AM -0700, Myklebust, Trond wrote: > > > > > -----Original Message----- > > > > > From: J. Bruce Fields [mailto:bfields@fieldses.org] > > > > > How is the client supposed to handle opens of device special > files? > > > > On > > > > > a 3.1-rc1-based client to a linux server over v4.0 I'm seeing > it try > > > > an > > > > > OPEN call and failing when it gets an INVAL return. > > > > > > > > > > This looks like bogus client behavior (OPEN should fail on such > > > > files), > > > > > unless the server has the error return wrong and the client's > using an > > > > > OPEN error to recover. > > > > > > > > > > If I first stat the device and then open it then it works as > expected > > > > > (the client does an open of the local device). > > > > > > > > > > I'm a bit annoyed at myself as I have a feeling we've discussed > this > > > > > before but I can't find a reference now. > > > > > > > > Hmm... NFS4ERR_INVAL means 'invalid argument', which is not the > case > > > > here; all the arguments that the client is passing to the server > are > > > > valid, however the file cannot be opened because the pathname > resolves > > > > on the server to a file of the wrong type. > > > > The long description of NFS4ERR_INVAL from rfc 3530: > > > > "Invalid argument or unsupported argument for an operation. Two > > examples are attempting a READLINK on an object other than a > > symbolic link or specifying a value for an enum field that is > > not defined in the protocol (e.g., nfs_ftype4)." > > > > So the text does recommend NFS4ERR_INVAL for the case where the > > operation doesn't make sense for the type of object given. (In the > > readlink example there's no pathname resolution, though). > > > > EINVAL seems to be used in the kernel for some such cases as well > (e.g. > > attempt to truncate a device special file). > > > > > > I can't see any other error definition that is "obviously > correct", but > > > > it looks to me as if NFS4ERR_SYMLINK might be the closest thing. > One > > > > reason is the dot-x file defines NFS4ERR_SYMLINK as meaning > "should be > > > > file/directory". > > > > And this seems more a coincidence due to vagueness resulting from the > > need for a single-line comment; the longer description is: > > > > "NFS4ERR_SYMLINK The current filehandle provided for a LOOKUP is > > not a directory but a symbolic link. Also used > > if the final component of the OPEN path is a > > symbolic link." > > > > > > The other reason is that NFS4ERR_SYMLINK should > > > > _always_ trigger the correct behaviour on a client: a fresh > lookup of > > > > the component. > > > > > > Confirmed the fix; I'll apply. > > > > Applying anyway for compatibility with existing clients, but this all > > seems a little weird. > > And the change also makes a bunch of pynfs tests fail, complaining that > various operations against incompatible types should have returned > INVAL > and not SYMLINK. > > Not that I'm convinced pynfs is correct--at the very least it should > have accepted a range of errors for those tests, I think--but anyone > else that ran pynfs against their server may have assumed it pynfs was > correct in these cases.... Pynfs is not an authoritative source for anything. Trond ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: open() of device special files 2011-08-16 5:04 ` Myklebust, Trond @ 2011-08-16 11:03 ` J. Bruce Fields 0 siblings, 0 replies; 19+ messages in thread From: J. Bruce Fields @ 2011-08-16 11:03 UTC (permalink / raw) To: Myklebust, Trond; +Cc: linux-nfs, steved, nfsv4 On Mon, Aug 15, 2011 at 10:04:29PM -0700, Myklebust, Trond wrote: > > -----Original Message----- > > From: J. Bruce Fields [mailto:bfields@fieldses.org] > > And the change also makes a bunch of pynfs tests fail, complaining > that > > various operations against incompatible types should have returned > > INVAL > > and not SYMLINK. > > > > Not that I'm convinced pynfs is correct--at the very least it should > > have accepted a range of errors for those tests, I think--but anyone > > else that ran pynfs against their server may have assumed it pynfs was > > correct in these cases.... > > Pynfs is not an authoritative source for anything. We should say that, for what it's worth. (Below.) But it's just another reason why servers may have been written to return something other than err_symlink.... I have in the past had to tell developers of more than one server that fixing error returns to make pynfs happy may not be a good idea. --b. diff --git a/README b/README index 0c34b2a..ecb2aa6 100644 --- a/README +++ b/README @@ -12,3 +12,9 @@ in place. For more details about 4.0 and 4.1 testing, see nfs4.0/README and nfs4.1/README, respectively. For information about automatic code generation from an XDR file, see xdr/README. + +Note that test results should *not* be considered authoritative +statements about the protocol--if you find that a server fails a test, +you should consult the rfc's and think carefully before assuming that +the server is at fault. (However, we do appreciate patches if you +find a test that requires incorrect behavior.) ^ permalink raw reply related [flat|nested] 19+ messages in thread
* RE: open() of device special files 2011-08-15 22:23 ` J. Bruce Fields 2011-08-15 22:27 ` J. Bruce Fields @ 2011-08-16 5:03 ` Myklebust, Trond 2011-08-16 10:49 ` J. Bruce Fields 1 sibling, 1 reply; 19+ messages in thread From: Myklebust, Trond @ 2011-08-16 5:03 UTC (permalink / raw) To: J. Bruce Fields; +Cc: linux-nfs, steved, nfsv4 > -----Original Message----- > From: J. Bruce Fields [mailto:bfields@fieldses.org] > Sent: Monday, August 15, 2011 6:24 PM > To: Myklebust, Trond > Cc: linux-nfs@vger.kernel.org; steved@redhat.com; nfsv4@ietf.org > Subject: Re: open() of device special files > > On Mon, Aug 15, 2011 at 05:25:39PM -0400, J. Bruce Fields wrote: > > On Mon, Aug 15, 2011 at 09:03:30AM -0700, Myklebust, Trond wrote: > > > > -----Original Message----- > > > > From: J. Bruce Fields [mailto:bfields@fieldses.org] > > > > How is the client supposed to handle opens of device special > files? > > > On > > > > a 3.1-rc1-based client to a linux server over v4.0 I'm seeing it > try > > > an > > > > OPEN call and failing when it gets an INVAL return. > > > > > > > > This looks like bogus client behavior (OPEN should fail on such > > > files), > > > > unless the server has the error return wrong and the client's > using an > > > > OPEN error to recover. > > > > > > > > If I first stat the device and then open it then it works as > expected > > > > (the client does an open of the local device). > > > > > > > > I'm a bit annoyed at myself as I have a feeling we've discussed > this > > > > before but I can't find a reference now. > > > > > > Hmm... NFS4ERR_INVAL means 'invalid argument', which is not the > case > > > here; all the arguments that the client is passing to the server > are > > > valid, however the file cannot be opened because the pathname > resolves > > > on the server to a file of the wrong type. > > The long description of NFS4ERR_INVAL from rfc 3530: > > "Invalid argument or unsupported argument for an operation. Two > examples are attempting a READLINK on an object other than a > symbolic link or specifying a value for an enum field that is > not defined in the protocol (e.g., nfs_ftype4)." > > So the text does recommend NFS4ERR_INVAL for the case where the > operation doesn't make sense for the type of object given. (In the > readlink example there's no pathname resolution, though). Right. In the case of readlink, you pass a file handle, which points to an object for which you _can_ check the type before attempting the readlink operation. OPEN (and LOOKUP, RENAME, REMOVE,...) takes a filename, which could point to anything. There is no way for the client to know a priori the type of the object being pointed to. > EINVAL seems to be used in the kernel for some such cases as well (e.g. > attempt to truncate a device special file). My reading of the manpages and the posix spec is that truncate() will return EINVAL if and only if the length argument is wrong. Ftruncate() will in addition return EINVAL if the file descriptor points to a non-regular file (the assumption presumably being that you should have tried to fstat() first). IOW: The criterion that they apply is that "if the user should have known better" then EINVAL is correct. If there is no way for the user to be sure a priori, then it is not. So, for instance, rmdir() will not return EINVAL if you try to apply it to a file. > > > I can't see any other error definition that is "obviously correct", > but > > > it looks to me as if NFS4ERR_SYMLINK might be the closest thing. > One > > > reason is the dot-x file defines NFS4ERR_SYMLINK as meaning "should > be > > > file/directory". > > And this seems more a coincidence due to vagueness resulting from the > need for a single-line comment; the longer description is: > > "NFS4ERR_SYMLINK The current filehandle provided for a LOOKUP is > not a directory but a symbolic link. Also used > if the final component of the OPEN path is a > symbolic link." > > > > The other reason is that NFS4ERR_SYMLINK should > > > _always_ trigger the correct behaviour on a client: a fresh lookup > of > > > the component. > > > > Confirmed the fix; I'll apply. > > Applying anyway for compatibility with existing clients, but this all > seems a little weird. Agreed, but it appears to be a case that has been missed when we defined OPEN. Trond ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: open() of device special files 2011-08-16 5:03 ` Myklebust, Trond @ 2011-08-16 10:49 ` J. Bruce Fields 0 siblings, 0 replies; 19+ messages in thread From: J. Bruce Fields @ 2011-08-16 10:49 UTC (permalink / raw) To: Myklebust, Trond; +Cc: linux-nfs, steved, nfsv4 On Mon, Aug 15, 2011 at 10:03:49PM -0700, Myklebust, Trond wrote: > > -----Original Message----- > > From: J. Bruce Fields [mailto:bfields@fieldses.org] > > The long description of NFS4ERR_INVAL from rfc 3530: > > > > "Invalid argument or unsupported argument for an operation. Two > > examples are attempting a READLINK on an object other than a > > symbolic link or specifying a value for an enum field that is > > not defined in the protocol (e.g., nfs_ftype4)." > > > > So the text does recommend NFS4ERR_INVAL for the case where the > > operation doesn't make sense for the type of object given. (In the > > readlink example there's no pathname resolution, though). > > Right. In the case of readlink, you pass a file handle, which points to > an object for which you _can_ check the type before attempting the > readlink operation. > > OPEN (and LOOKUP, RENAME, REMOVE,...) takes a filename, which could > point to anything. There is no way for the client to know a priori the > type of the object being pointed to. > > > EINVAL seems to be used in the kernel for some such cases as well > (e.g. > > attempt to truncate a device special file). > > My reading of the manpages and the posix spec is that truncate() will > return EINVAL if and only if the length argument is wrong. Ftruncate() > will in addition return EINVAL if the file descriptor points to a > non-regular file (the assumption presumably being that you should have > tried to fstat() first). > > IOW: The criterion that they apply is that "if the user should have > known better" then EINVAL is correct. If there is no way for the user to > be sure a priori, then it is not. So, for instance, rmdir() will not > return EINVAL if you try to apply it to a file. That's perfectly logical, but, taking the example of (f)truncate: - truncate(2) as far as I can tell doesn't specify behavior for truncate in this case, only for ftruncate. - http://pubs.opengroup.org/onlinepubs/009695399/ says behavior is undefined for ftruncate, and says nothing for truncate. - linux actually returns EINVAL in both cases: $ sudo mknod tmp c 1 3 -m 666 $ make trunc-vs-ftrunc cc trunc-vs-ftrunc.c -o trunc-vs-ftrunc $ ./trunc-vs-ftrunc tmp trunc-vs-ftrunc: truncate: Invalid argument trunc-vs-ftrunc: ftruncate: Invalid argument But I don't really know why I'm arguing here--I don't disagree. You have a reasonable way to define EINVAL. This just appears to be easy to get wrong.... --b. trunc-vs-ftrunc.c: #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <err.h> int main(int argc, char *argv[]) { int fd, ret; if (argc != 2) errx(1, "usage: %s path\n", argv[0]); ret = truncate(argv[1], 0); if (ret) warn("truncate"); fd = open(argv[1], O_WRONLY); if (fd < 0) err(1, "open"); ret = ftruncate(fd, 0); if (ret) warn("ftruncate"); } ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: open() of device special files 2011-08-15 21:25 ` J. Bruce Fields 2011-08-15 22:23 ` J. Bruce Fields @ 2011-08-15 22:28 ` J. Bruce Fields 2011-08-15 22:30 ` [PATCH 1/5] nfsd4: clean up S_IS -> NF4 file type mapping J. Bruce Fields ` (4 more replies) 2011-08-16 11:32 ` [nfsv4] open() of device special files Steve Dickson 2011-08-17 0:52 ` J. Bruce Fields 3 siblings, 5 replies; 19+ messages in thread From: J. Bruce Fields @ 2011-08-15 22:28 UTC (permalink / raw) To: Myklebust, Trond; +Cc: linux-nfs, steved On Mon, Aug 15, 2011 at 05:25:39PM -0400, J. Bruce Fields wrote: > Confirmed the fix; I'll apply. Also found some opportunity for cleanups while I was there, as follows. --b. ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/5] nfsd4: clean up S_IS -> NF4 file type mapping 2011-08-15 22:28 ` J. Bruce Fields @ 2011-08-15 22:30 ` J. Bruce Fields 2011-08-15 22:30 ` [PATCH 2/5] nfsd4: return nfserr_symlink on v4 OPEN of non-regular file J. Bruce Fields ` (3 subsequent siblings) 4 siblings, 0 replies; 19+ messages in thread From: J. Bruce Fields @ 2011-08-15 22:30 UTC (permalink / raw) To: linux-nfs; +Cc: J. Bruce Fields A slightly unconventional approach to make the code more compact I could live with, but let's give the poor reader *some* chance. Signed-off-by: J. Bruce Fields <bfields@redhat.com> --- fs/nfsd/nfs4xdr.c | 21 ++++++++++++++------- 1 files changed, 14 insertions(+), 7 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index c8bf405..42ef8ff 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1760,12 +1760,19 @@ static __be32 nfsd4_encode_fs_locations(struct svc_rqst *rqstp, return 0; } -static u32 nfs4_ftypes[16] = { - NF4BAD, NF4FIFO, NF4CHR, NF4BAD, - NF4DIR, NF4BAD, NF4BLK, NF4BAD, - NF4REG, NF4BAD, NF4LNK, NF4BAD, - NF4SOCK, NF4BAD, NF4LNK, NF4BAD, -}; +static u32 nfs4_file_type(umode_t mode) +{ + switch (mode & S_IFMT) { + case S_IFIFO: return NF4FIFO; + case S_IFCHR: return NF4CHR; + case S_IFDIR: return NF4DIR; + case S_IFBLK: return NF4BLK; + case S_IFLNK: return NF4LNK; + case S_IFREG: return NF4REG; + case S_IFSOCK: return NF4SOCK; + default: return NF4BAD; + }; +} static __be32 nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group, @@ -1954,7 +1961,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, if (bmval0 & FATTR4_WORD0_TYPE) { if ((buflen -= 4) < 0) goto out_resource; - dummy = nfs4_ftypes[(stat.mode & S_IFMT) >> 12]; + dummy = nfs4_file_type(stat.mode); if (dummy == NF4BAD) goto out_serverfault; WRITE32(dummy); -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 2/5] nfsd4: return nfserr_symlink on v4 OPEN of non-regular file 2011-08-15 22:28 ` J. Bruce Fields 2011-08-15 22:30 ` [PATCH 1/5] nfsd4: clean up S_IS -> NF4 file type mapping J. Bruce Fields @ 2011-08-15 22:30 ` J. Bruce Fields 2011-08-15 22:30 ` [PATCH 3/5] nfsd4: fix incorrect comment in nfsd4_set_nfs4_acl J. Bruce Fields ` (2 subsequent siblings) 4 siblings, 0 replies; 19+ messages in thread From: J. Bruce Fields @ 2011-08-15 22:30 UTC (permalink / raw) To: linux-nfs; +Cc: J. Bruce Fields Without this, an attempt to open a device special file without first stat'ing it will fail. Signed-off-by: J. Bruce Fields <bfields@redhat.com> --- fs/nfsd/nfsfh.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 90c6aa6..cc8eb8d 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -69,6 +69,17 @@ nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type) return nfserr_notdir; else if ((mode & S_IFMT) == S_IFDIR) return nfserr_isdir; + /* + * err_symlink is our catch-all error in the v4 case; this + * looks odd, but: + * - the comment next to ERR_SYMLINK in file is + * "should be file/directory" + * - we happen to know this will cause the linux v4 + * client to do the right thing on attempts to open + * something other than a regular file: + */ + else if (rqstp->rq_vers == 4) + return nfserr_symlink; else return nfserr_inval; } -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 3/5] nfsd4: fix incorrect comment in nfsd4_set_nfs4_acl 2011-08-15 22:28 ` J. Bruce Fields 2011-08-15 22:30 ` [PATCH 1/5] nfsd4: clean up S_IS -> NF4 file type mapping J. Bruce Fields 2011-08-15 22:30 ` [PATCH 2/5] nfsd4: return nfserr_symlink on v4 OPEN of non-regular file J. Bruce Fields @ 2011-08-15 22:30 ` J. Bruce Fields 2011-08-15 22:30 ` [PATCH 4/5] nfsd: open-code special directory-hardlink check J. Bruce Fields 2011-08-15 22:30 ` [PATCH 5/5] nfsd: clean up nfsd_mode_check() J. Bruce Fields 4 siblings, 0 replies; 19+ messages in thread From: J. Bruce Fields @ 2011-08-15 22:30 UTC (permalink / raw) To: linux-nfs; +Cc: J. Bruce Fields Zero means "I don't care what kind of file this is". And that's probably what we want--acls are also settable at least on directories, and if the filesystem doesn't want them on other objects, leave it to it to complain. Signed-off-by: J. Bruce Fields <bfields@redhat.com> --- fs/nfsd/vfs.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index fd0acca..556ca2b 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -502,7 +502,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, unsigned int flags = 0; /* Get inode */ - error = fh_verify(rqstp, fhp, 0 /* S_IFREG */, NFSD_MAY_SATTR); + error = fh_verify(rqstp, fhp, 0, NFSD_MAY_SATTR); if (error) return error; -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 4/5] nfsd: open-code special directory-hardlink check 2011-08-15 22:28 ` J. Bruce Fields ` (2 preceding siblings ...) 2011-08-15 22:30 ` [PATCH 3/5] nfsd4: fix incorrect comment in nfsd4_set_nfs4_acl J. Bruce Fields @ 2011-08-15 22:30 ` J. Bruce Fields 2011-08-15 22:30 ` [PATCH 5/5] nfsd: clean up nfsd_mode_check() J. Bruce Fields 4 siblings, 0 replies; 19+ messages in thread From: J. Bruce Fields @ 2011-08-15 22:30 UTC (permalink / raw) To: linux-nfs; +Cc: J. Bruce Fields We allow the fh_verify caller to specify that any object *except* those of a given type is allowed, by passing a negative type. But only one caller actually uses it. Open-code that check in the one caller. Signed-off-by: J. Bruce Fields <bfields@redhat.com> --- fs/nfsd/nfsfh.c | 9 --------- fs/nfsd/vfs.c | 6 ++++-- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index cc8eb8d..dc0f9ff 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -61,7 +61,6 @@ static int nfsd_acceptable(void *expv, struct dentry *dentry) static inline __be32 nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type) { - /* Type can be negative when creating hardlinks - not to a dir */ if (type > 0 && (mode & S_IFMT) != type) { if (rqstp->rq_vers == 4 && (mode & S_IFMT) == S_IFLNK) return nfserr_symlink; @@ -83,14 +82,6 @@ nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type) else return nfserr_inval; } - if (type < 0 && (mode & S_IFMT) == -type) { - if (rqstp->rq_vers == 4 && (mode & S_IFMT) == S_IFLNK) - return nfserr_symlink; - else if (type == -S_IFDIR) - return nfserr_isdir; - else - return nfserr_notdir; - } return 0; } diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 556ca2b..4c22870 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1632,10 +1632,12 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, err = fh_verify(rqstp, ffhp, S_IFDIR, NFSD_MAY_CREATE); if (err) goto out; - err = fh_verify(rqstp, tfhp, -S_IFDIR, NFSD_MAY_NOP); + err = fh_verify(rqstp, tfhp, 0, NFSD_MAY_NOP); if (err) goto out; - + err = nfserr_isdir; + if (S_ISDIR(tfhp->fh_dentry->d_inode->i_mode)) + goto out; err = nfserr_perm; if (!len) goto out; -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5/5] nfsd: clean up nfsd_mode_check() 2011-08-15 22:28 ` J. Bruce Fields ` (3 preceding siblings ...) 2011-08-15 22:30 ` [PATCH 4/5] nfsd: open-code special directory-hardlink check J. Bruce Fields @ 2011-08-15 22:30 ` J. Bruce Fields 2011-08-15 22:48 ` J. Bruce Fields 4 siblings, 1 reply; 19+ messages in thread From: J. Bruce Fields @ 2011-08-15 22:30 UTC (permalink / raw) To: linux-nfs; +Cc: J. Bruce Fields Add some more comments, simplify logic, do & S_IFMT just once, name "type" more helpfully. Signed-off-by: J. Bruce Fields <bfields@redhat.com> --- fs/nfsd/nfsfh.c | 52 +++++++++++++++++++++++++++++----------------------- 1 files changed, 29 insertions(+), 23 deletions(-) diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index dc0f9ff..b4fd50e 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -59,30 +59,36 @@ static int nfsd_acceptable(void *expv, struct dentry *dentry) * the write call). */ static inline __be32 -nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type) +nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int requested) { - if (type > 0 && (mode & S_IFMT) != type) { - if (rqstp->rq_vers == 4 && (mode & S_IFMT) == S_IFLNK) - return nfserr_symlink; - else if (type == S_IFDIR) - return nfserr_notdir; - else if ((mode & S_IFMT) == S_IFDIR) - return nfserr_isdir; - /* - * err_symlink is our catch-all error in the v4 case; this - * looks odd, but: - * - the comment next to ERR_SYMLINK in file is - * "should be file/directory" - * - we happen to know this will cause the linux v4 - * client to do the right thing on attempts to open - * something other than a regular file: - */ - else if (rqstp->rq_vers == 4) - return nfserr_symlink; - else - return nfserr_inval; - } - return 0; + mode &= S_IFMT; + + if (requested == 0) /* the caller doesn't care */ + return 0; + if (mode == requested) + return 0; + /* + * v4 has an error more specific than err_notdir which we should + * return in preference to err_notdir: + */ + if (rqstp->rq_vers == 4 && mode == S_IFLNK) + return nfserr_symlink; + if (requested == S_IFDIR) + return nfserr_notdir; + if (mode == S_IFDIR) + return nfserr_isdir; + /* + * err_symlink is our catch-all error in the v4 case; this + * looks odd, but: + * - the comment next to ERR_SYMLINK in file is + * "should be file/directory" + * - we happen to know this will cause the linux v4 + * client to do the right thing on attempts to open + * something other than a regular file: + */ + if (rqstp->rq_vers == 4) + return nfserr_symlink; + return nfserr_inval; } static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 5/5] nfsd: clean up nfsd_mode_check() 2011-08-15 22:30 ` [PATCH 5/5] nfsd: clean up nfsd_mode_check() J. Bruce Fields @ 2011-08-15 22:48 ` J. Bruce Fields 0 siblings, 0 replies; 19+ messages in thread From: J. Bruce Fields @ 2011-08-15 22:48 UTC (permalink / raw) To: J. Bruce Fields; +Cc: linux-nfs Also noticed while auditing these error returns. There's all kinds of weird crap in here. --b. commit fe0a6f4711dba408fb771a402876db33ffe219bf Author: J. Bruce Fields <bfields@redhat.com> Date: Mon Aug 15 18:39:32 2011 -0400 nfsd4: it's OK to return nfserr_symlink The nfsd4 code has a bunch of special exceptions for error returns which map nfserr_symlink to other errors. In fact, the spec makes it clear that nfserr_symlink is to be preferred over less specific errors where possible. The patch that introduced it back in 2.6.4 is "kNFSd: correct symlink related error returns.", which claims that these special exceptions are represent an NFSv4 break from v2/v3 tradition--when in fact the symlink error was introduced with v4. I suspect what happened was pynfs tests were written that were overly faithful to the (known-incomplete) rfc3530 error return lists, and then code was fixed up mindlessly to make the tests pass. Delete these unnecessary exceptions. Signed-off-by: J. Bruce Fields <bfields@redhat.com> diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 9bf0a66..3b159ab 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -473,11 +473,8 @@ nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, *p++ = nfssvc_boot.tv_sec; *p++ = nfssvc_boot.tv_usec; - status = nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset, + return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset, commit->co_count); - if (status == nfserr_symlink) - status = nfserr_inval; - return status; } static __be32 @@ -492,8 +489,6 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, NFSD_MAY_CREATE); - if (status == nfserr_symlink) - status = nfserr_notdir; if (status) return status; @@ -719,8 +714,6 @@ nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, return nfserr_grace; status = nfsd_unlink(rqstp, &cstate->current_fh, 0, remove->rm_name, remove->rm_namelen); - if (status == nfserr_symlink) - return nfserr_notdir; if (!status) { fh_unlock(&cstate->current_fh); set_change_info(&remove->rm_cinfo, &cstate->current_fh); @@ -751,8 +744,6 @@ nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, (S_ISDIR(cstate->save_fh.fh_dentry->d_inode->i_mode) && S_ISDIR(cstate->current_fh.fh_dentry->d_inode->i_mode))) status = nfserr_exist; - else if (status == nfserr_symlink) - status = nfserr_notdir; if (!status) { set_change_info(&rename->rn_sinfo, &cstate->current_fh); @@ -892,8 +883,6 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, write->wr_bytes_written = cnt; - if (status == nfserr_symlink) - status = nfserr_inval; return status; } diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 3787ec1..aa0a36e 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -4179,12 +4179,8 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, if (!nfsd4_has_session(cstate) && STALE_CLIENTID(&lockt->lt_clientid)) goto out; - if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) { - dprintk("NFSD: nfsd4_lockt: fh_verify() failed!\n"); - if (status == nfserr_symlink) - status = nfserr_inval; + if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) goto out; - } inode = cstate->current_fh.fh_dentry->d_inode; locks_init_lock(&file_lock); diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 42ef8ff..2834ee2 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2766,8 +2766,6 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen, &maxcount); - if (nfserr == nfserr_symlink) - nfserr = nfserr_inval; if (nfserr) return nfserr; eof = (read->rd_offset + maxcount >= @@ -2893,8 +2891,6 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4 readdir->common.err == nfserr_toosmall && readdir->buffer == page) nfserr = nfserr_toosmall; - if (nfserr == nfserr_symlink) - nfserr = nfserr_notdir; if (nfserr) goto err_no_verf; ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [nfsv4] open() of device special files 2011-08-15 21:25 ` J. Bruce Fields 2011-08-15 22:23 ` J. Bruce Fields 2011-08-15 22:28 ` J. Bruce Fields @ 2011-08-16 11:32 ` Steve Dickson 2011-08-17 0:52 ` J. Bruce Fields 3 siblings, 0 replies; 19+ messages in thread From: Steve Dickson @ 2011-08-16 11:32 UTC (permalink / raw) To: J. Bruce Fields; +Cc: Myklebust, Trond, linux-nfs, nfsv4 On 08/15/2011 05:25 PM, J. Bruce Fields wrote: > On Mon, Aug 15, 2011 at 09:03:30AM -0700, Myklebust, Trond wrote: >>> -----Original Message----- >>> From: J. Bruce Fields [mailto:bfields@fieldses.org] >>> How is the client supposed to handle opens of device special files? >> On >>> a 3.1-rc1-based client to a linux server over v4.0 I'm seeing it try >> an >>> OPEN call and failing when it gets an INVAL return. >>> >>> This looks like bogus client behavior (OPEN should fail on such >> files), >>> unless the server has the error return wrong and the client's using an >>> OPEN error to recover. >>> >>> If I first stat the device and then open it then it works as expected >>> (the client does an open of the local device). >>> >>> I'm a bit annoyed at myself as I have a feeling we've discussed this >>> before but I can't find a reference now. >> >> Hmm... NFS4ERR_INVAL means 'invalid argument', which is not the case >> here; all the arguments that the client is passing to the server are >> valid, however the file cannot be opened because the pathname resolves >> on the server to a file of the wrong type. >> >> I can't see any other error definition that is "obviously correct", but >> it looks to me as if NFS4ERR_SYMLINK might be the closest thing. One >> reason is the dot-x file defines NFS4ERR_SYMLINK as meaning "should be >> file/directory". The other reason is that NFS4ERR_SYMLINK should >> _always_ trigger the correct behaviour on a client: a fresh lookup of >> the component. > > Confirmed the fix; I'll apply. Confirmed! The following open now works with all NFS versions: int main (void) { int fd; char buf[20]; size_t nbytes; ssize_t bytes_read; nbytes = sizeof(buf); fd = open("/mnt/dev/urandom", O_RDONLY|O_NOCTTY|O_NONBLOCK); if (fd < 0) { perror("open"); exit(1); } bytes_read = read(fd, buf, nbytes); return 0; } Thanks! steved. > > But that's tricky--we should be document it for other server > implementers if it's the right thing to do (working group list cc'd). > > --b. > > commit 3d83c016da8652f30dcac372772b67d68f33bfbd > Author: J. Bruce Fields <bfields@redhat.com> > Date: Mon Aug 15 16:55:02 2011 -0400 > > nfsd4: return nfserr_symlink on v4 OPEN of non-regular file > > Without this, an attempt to open a device special file without first > stat'ing it will fail. > > Signed-off-by: J. Bruce Fields <bfields@redhat.com> > > diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c > index 90c6aa6..cc8eb8d 100644 > --- a/fs/nfsd/nfsfh.c > +++ b/fs/nfsd/nfsfh.c > @@ -69,6 +69,17 @@ nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type) > return nfserr_notdir; > else if ((mode & S_IFMT) == S_IFDIR) > return nfserr_isdir; > + /* > + * err_symlink is our catch-all error in the v4 case; this > + * looks odd, but: > + * - the comment next to ERR_SYMLINK in file is > + * "should be file/directory" > + * - we happen to know this will cause the linux v4 > + * client to do the right thing on attempts to open > + * something other than a regular file: > + */ > + else if (rqstp->rq_vers == 4) > + return nfserr_symlink; > else > return nfserr_inval; > } ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: open() of device special files 2011-08-15 21:25 ` J. Bruce Fields ` (2 preceding siblings ...) 2011-08-16 11:32 ` [nfsv4] open() of device special files Steve Dickson @ 2011-08-17 0:52 ` J. Bruce Fields 3 siblings, 0 replies; 19+ messages in thread From: J. Bruce Fields @ 2011-08-17 0:52 UTC (permalink / raw) To: Myklebust, Trond; +Cc: linux-nfs, steved, nfsv4 > Confirmed the fix; I'll apply. Actually that changed NFS4ERR_INVAL's to NFS4ERR_SYMLINK's all over the place, which I'd rather not do; the following just affects the OPEN. --b. commit 618459ca1f7613f0dde4f09138e9acbe02690264 Author: J. Bruce Fields <bfields@redhat.com> Date: Mon Aug 15 16:55:02 2011 -0400 nfsd4: return nfserr_symlink on v4 OPEN of non-regular file Without this, an attempt to open a device special file without first stat'ing it will fail. Signed-off-by: J. Bruce Fields <bfields@redhat.com> diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 9bf0a66..d784ceb 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -168,6 +168,24 @@ do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs return status; } +static __be32 nfsd_check_obj_isreg(struct svc_fh *fh) +{ + umode_t mode = fh->fh_dentry->d_inode->i_mode; + + if (S_ISREG(mode)) + return nfs_ok; + if (S_ISDIR(mode)) + return nfserr_isdir; + /* + * Using err_symlink as our catch-all case may look odd; but + * there's no other obvious error for this case in 4.0, and we + * happen to know that it will cause the linux v4 client to do + * the right thing on attempts to open something other than a + * regular file. + */ + return nfserr_symlink; +} + static __be32 do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) { @@ -216,6 +234,9 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o status = nfsd_lookup(rqstp, current_fh, open->op_fname.data, open->op_fname.len, &resfh); fh_unlock(current_fh); + if (status) + goto out; + status = nfsd_check_obj_isreg(&resfh); } if (status) goto out; ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: open() of device special files 2011-08-15 16:03 ` Myklebust, Trond 2011-08-15 21:25 ` J. Bruce Fields @ 2011-08-17 1:40 ` J. Bruce Fields 1 sibling, 0 replies; 19+ messages in thread From: J. Bruce Fields @ 2011-08-17 1:40 UTC (permalink / raw) To: Myklebust, Trond; +Cc: linux-nfs, steved On Mon, Aug 15, 2011 at 09:03:30AM -0700, Myklebust, Trond wrote: > Hmm... NFS4ERR_INVAL means 'invalid argument', which is not the case > here; all the arguments that the client is passing to the server are > valid, however the file cannot be opened because the pathname resolves > on the server to a file of the wrong type. > > I can't see any other error definition that is "obviously correct", but > it looks to me as if NFS4ERR_SYMLINK might be the closest thing. One > reason is the dot-x file defines NFS4ERR_SYMLINK as meaning "should be > file/directory". The other reason is that NFS4ERR_SYMLINK should > _always_ trigger the correct behaviour on a client: a fresh lookup of > the component. By the way, note rfc 5661 is unambiguous: the server should return WRONG_TYPE. I haven't looked into fixing that yet on either client or server side yet. --b. ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2011-08-17 1:40 UTC | newest] Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-08-15 15:36 open() of device special files J. Bruce Fields 2011-08-15 16:03 ` Myklebust, Trond 2011-08-15 21:25 ` J. Bruce Fields 2011-08-15 22:23 ` J. Bruce Fields 2011-08-15 22:27 ` J. Bruce Fields 2011-08-16 5:04 ` Myklebust, Trond 2011-08-16 11:03 ` J. Bruce Fields 2011-08-16 5:03 ` Myklebust, Trond 2011-08-16 10:49 ` J. Bruce Fields 2011-08-15 22:28 ` J. Bruce Fields 2011-08-15 22:30 ` [PATCH 1/5] nfsd4: clean up S_IS -> NF4 file type mapping J. Bruce Fields 2011-08-15 22:30 ` [PATCH 2/5] nfsd4: return nfserr_symlink on v4 OPEN of non-regular file J. Bruce Fields 2011-08-15 22:30 ` [PATCH 3/5] nfsd4: fix incorrect comment in nfsd4_set_nfs4_acl J. Bruce Fields 2011-08-15 22:30 ` [PATCH 4/5] nfsd: open-code special directory-hardlink check J. Bruce Fields 2011-08-15 22:30 ` [PATCH 5/5] nfsd: clean up nfsd_mode_check() J. Bruce Fields 2011-08-15 22:48 ` J. Bruce Fields 2011-08-16 11:32 ` [nfsv4] open() of device special files Steve Dickson 2011-08-17 0:52 ` J. Bruce Fields 2011-08-17 1:40 ` J. Bruce Fields
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.