summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorWang Lei <wang840925@gmail.com>2010-08-11 09:37:58 +0100
committerSteve French <sfrench@us.ibm.com>2010-08-11 17:11:28 +0000
commit4a2d789267e00b5a1175ecd2ddefcc78b83fbf09 (patch)
treeee0372ca2719a998fca29e6fe3b9c0a3ceabbfc7 /fs
parentc2e8139c9f797baa46515af6d350c51823736cbb (diff)
DNS: If the DNS server returns an error, allow that to be cached [ver #2]
If the DNS server returns an error, allow that to be cached in the DNS resolver key in lieu of a value. Userspace passes the desired error number as an option in the payload: "#dnserror=<number>" Userspace must map h_errno from the name resolution routines to an appropriate Linux error before passing it up. Something like the following mapping is recommended: [HOST_NOT_FOUND] = ENODATA, [TRY_AGAIN] = EAGAIN, [NO_RECOVERY] = ECONNREFUSED, [NO_DATA] = ENODATA, in lieu of Linux errors specifically for representing name service errors. The filesystem must map these errors appropropriately before passing them to userspace. AFS is made to map ENODATA and EAGAIN to EDESTADDRREQ for the return to userspace; ECONNREFUSED is allowed to stand as is. The error can be seen in /proc/keys as a negative number after the description of the key. Compare, for example, the following key entries: 2f97238c I--Q-- 1 53s 3f010000 0 0 dns_resol afsdb:grand.centrall.org: -61 338bfbbe I--Q-- 1 59m 3f010000 0 0 dns_resol afsdb:grand.central.org: 37 If the error option is supplied in the payload, the main part of the payload is discarded. The key should have an expiry time set by userspace. Signed-off-by: Wang Lei <wang840925@gmail.com> Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/afs/cell.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index ffea35c63879..d0765883430e 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -73,6 +73,10 @@ static struct afs_cell *afs_cell_alloc(const char *name, char *vllist)
if (!vllist || strlen(vllist) < 7) {
ret = dns_query("afsdb", name, namelen, "ipv4", &dvllist, NULL);
if (ret < 0) {
+ if (ret == -ENODATA || ret == -EAGAIN || ret == -ENOKEY)
+ /* translate these errors into something
+ * userspace might understand */
+ ret = -EDESTADDRREQ;
_leave(" = %d", ret);
return ERR_PTR(ret);
}