/* * Handle NFS version and transport protocol * autonegotiation. * * When no version or protocol is specified on the * command line, mount.nfs negotiates with the server * to determine appropriate settings for the new * mount point. * * Returns TRUE if successful, otherwise FALSE. * "errno" is set to reflect the individual error. */ static int nfs_autonegotiate(struct nfsmount_info *mi) { int result; result = nfs_try_mount_v4(mi); if (result) return result; switch (errno) { case EPROTONOSUPPORT: /* A clear indication that the server or our * client does not support NFS version 4. */ goto fall_back; case ENOENT: /* Legacy Linux servers don't export an NFS * version 4 pseudoroot. */ goto fall_back; case EPERM: /* Linux servers prior to 2.6.25 may return * EPERM when NFS version 4 is not supported. */ goto fall_back; default: return result; } fall_back: return nfs_try_mount_v3v2(mi); }
/* * Handle NFS version and transport protocol * autonegotiation. * * When no version or protocol is specified on the * command line, mount.nfs negotiates with the server * to determine appropriate settings for the new * mount point. * * Returns TRUE if successful, otherwise FALSE. * "errno" is set to reflect the individual error. */ static int nfs_autonegotiate(struct nfsmount_info *mi) { int result; result = nfs_try_mount_v4(mi); if (result) return result; check_errno: switch (errno) { case EPROTONOSUPPORT: /* A clear indication that the server or our * client does not support NFS version 4. */ goto fall_back; case ENOENT: /* Legacy Linux servers don't export an NFS * version 4 pseudoroot. */ goto fall_back; case EPERM: /* Linux servers prior to 2.6.25 may return * EPERM when NFS version 4 is not supported. */ goto fall_back; case ECONNREFUSED: /* UDP-Only servers won't support v4, but maybe it * just isn't ready yet. So try v3, but double-check * with rpcbind for v4. */ result = nfs_try_mount_v3v2(mi, TRUE); if (result == 0 && errno == EAGAIN) { /* v4 server seems to be registered now. */ result = nfs_try_mount_v4(mi); if (result == 0 && errno != ECONNREFUSED) goto check_errno; } return result; default: return result; } fall_back: return nfs_try_mount_v3v2(mi, FALSE); }
/* * This is a single pass through the fg/bg loop. * * Returns TRUE if successful, otherwise FALSE. * "errno" is set to reflect the individual error. */ static int nfs_try_mount(struct nfsmount_info *mi) { int result = 0; switch (mi->version) { case 0: result = nfs_autonegotiate(mi); break; case 2: case 3: result = nfs_try_mount_v3v2(mi, FALSE); break; case 4: result = nfs_try_mount_v4(mi); break; default: errno = EIO; } return result; }