afs: Stop abusing ENOENT
authorAndrew Deason <adeason@sinenomine.net>
Sat, 14 Feb 2015 00:08:25 +0000 (18:08 -0600)
committerBenjamin Kaduk <kaduk@mit.edu>
Sat, 22 Aug 2015 04:51:28 +0000 (00:51 -0400)
commit2aa4cb047596b654a175f5a22197c2923002a271
treec9f3483ade55aab998d0ae6d1d309d28582643f3
parenta19728ba55f30a41799855b49c5cf6c07c840f87
afs: Stop abusing ENOENT

When looking up a file, the ENOENT error code is supposed to be used
if we know that the target filename does not exist. That is, the
situation is a user or application error; they specified a filename
that was not previously created.

Currently, though, we use ENOENT for a variety of different
situations, such as:

 - After successfully looking up a directory entry, we fail to
   afs_GetDCache or afs_GetVCache on the FID for that entry.

 - We encounter an invalid mount point, in certain code paths.

In each of these situations, an ENOENT error code is incorrect, since
the target filename does indeed exist and these situations may be
caused by network or administrative errors. An ENOENT error implies
that the user may be able to then create the target filename, which is
not true most of the time in the above situations.

In addition, on LINUX we return a negative dcache entry when we
encounter an ENOENT error on lookup. This means that if any of the
above scenarios occur, Linux would cache the fact that that directory
entry did not exist, and return ENOENT for future lookups. This was
worked around in one of the changes in commit
652f3bd9cb7a5d7833a760ba50ef7c2c67214bba to always invalidate such
negative dentries, but at the cost of performance (since this caused
negative lookups to never be cached).

To avoid all of these issues, just don't use ENOENT in these
situations. For simple non-disconnected afs_GetDCache or afs_GetVCache
errors, return EIO, since we have encountered an error that is
internal to AFS (either the underlying data is inconsistent, or we
have a network error, or something else). In disconnected operation,
return ENETDOWN like in other disconnected code paths, since often the
root cause is due to us not having network access. When a bad
mountpoint is encountered, return ENODEV, since that is what we use
elsewhere in the code when encountering a bad mountpoint.

It is also noteworthy that this changes removes the translation of
VNOVNODE into ENOENT, since a nonexistent vnode is not the same as a
nonexistent filename, as described above. Some code paths have special
behavior for this situation (ignoring the error in some cases where it
does not matter). These code paths should be okay with this change,
since all of them examine error codes that have not been translated
through afs_CheckCode.

Some useless references to ENOENT were also removed in
src/afs/LINUX*/osi_misc.c. These did not result in incorrect behavior,
but removing them makes searching for bad ENOENT references easier.

Change-Id: Ib01e4309e44b532f843d53c8de2eae613e397bf6
Reviewed-on: http://gerrit.openafs.org/11788
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
26 files changed:
src/afs/AIX/osi_vfsops.c
src/afs/DARWIN/osi_vfsops.c
src/afs/FBSD/osi_vfsops.c
src/afs/HPUX/osi_vfsops.c
src/afs/IRIX/osi_vfsops.c
src/afs/IRIX/osi_vnodeops.c
src/afs/LINUX/osi_misc.c
src/afs/LINUX/osi_vfsops.c
src/afs/LINUX/osi_vnodeops.c
src/afs/NBSD/osi_vfsops.c
src/afs/OBSD/osi_vfsops.c
src/afs/SOLARIS/osi_vfsops.c
src/afs/SOLARIS/osi_vnodeops.c
src/afs/UKERNEL/osi_vfsops.c
src/afs/VNOPS/afs_vnop_create.c
src/afs/VNOPS/afs_vnop_dirops.c
src/afs/VNOPS/afs_vnop_lookup.c
src/afs/VNOPS/afs_vnop_readdir.c
src/afs/VNOPS/afs_vnop_remove.c
src/afs/VNOPS/afs_vnop_rename.c
src/afs/VNOPS/afs_vnop_symlink.c
src/afs/VNOPS/afs_vnop_write.c
src/afs/afs_disconnected.c
src/afs/afs_error.c
src/afs/afs_pioctl.c
src/afs/afs_vcache.c