mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-24 04:34:22 +08:00
net: nfs: add dynamic wait period
This patch tackles the time out problem which leads to break the boot process, when loading file over nfs. The patch does two things. First of all, we just ignore messages that arrive with a rpc_id smaller then the client id. We just interpret this messages as answers to formaly timed out messages. Second, when a time out occurs we double the time to wait, so that we do not stress the server resending the last message. Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com> Tested-by: Enric Balletbo i Serra <eballetbo@gmail.com>
This commit is contained in:
parent
fb4879b3c7
commit
fa84fa708c
74
net/nfs.c
74
net/nfs.c
@ -37,10 +37,14 @@
|
|||||||
# define NFS_TIMEOUT CONFIG_NFS_TIMEOUT
|
# define NFS_TIMEOUT CONFIG_NFS_TIMEOUT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define NFS_RPC_ERR 1
|
||||||
|
#define NFS_RPC_DROP 124
|
||||||
|
|
||||||
static int fs_mounted;
|
static int fs_mounted;
|
||||||
static unsigned long rpc_id;
|
static unsigned long rpc_id;
|
||||||
static int nfs_offset = -1;
|
static int nfs_offset = -1;
|
||||||
static int nfs_len;
|
static int nfs_len;
|
||||||
|
static ulong nfs_timeout = NFS_TIMEOUT;
|
||||||
|
|
||||||
static char dirfh[NFS_FHSIZE]; /* file handle of directory */
|
static char dirfh[NFS_FHSIZE]; /* file handle of directory */
|
||||||
static char filefh[NFS_FHSIZE]; /* file handle of kernel image */
|
static char filefh[NFS_FHSIZE]; /* file handle of kernel image */
|
||||||
@ -399,8 +403,10 @@ rpc_lookup_reply(int prog, uchar *pkt, unsigned len)
|
|||||||
|
|
||||||
debug("%s\n", __func__);
|
debug("%s\n", __func__);
|
||||||
|
|
||||||
if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
|
if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
|
||||||
return -1;
|
return -NFS_RPC_ERR;
|
||||||
|
else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
|
||||||
|
return -NFS_RPC_DROP;
|
||||||
|
|
||||||
if (rpc_pkt.u.reply.rstatus ||
|
if (rpc_pkt.u.reply.rstatus ||
|
||||||
rpc_pkt.u.reply.verifier ||
|
rpc_pkt.u.reply.verifier ||
|
||||||
@ -428,8 +434,10 @@ nfs_mount_reply(uchar *pkt, unsigned len)
|
|||||||
|
|
||||||
memcpy((unsigned char *)&rpc_pkt, pkt, len);
|
memcpy((unsigned char *)&rpc_pkt, pkt, len);
|
||||||
|
|
||||||
if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
|
if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
|
||||||
return -1;
|
return -NFS_RPC_ERR;
|
||||||
|
else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
|
||||||
|
return -NFS_RPC_DROP;
|
||||||
|
|
||||||
if (rpc_pkt.u.reply.rstatus ||
|
if (rpc_pkt.u.reply.rstatus ||
|
||||||
rpc_pkt.u.reply.verifier ||
|
rpc_pkt.u.reply.verifier ||
|
||||||
@ -452,8 +460,10 @@ nfs_umountall_reply(uchar *pkt, unsigned len)
|
|||||||
|
|
||||||
memcpy((unsigned char *)&rpc_pkt, pkt, len);
|
memcpy((unsigned char *)&rpc_pkt, pkt, len);
|
||||||
|
|
||||||
if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
|
if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
|
||||||
return -1;
|
return -NFS_RPC_ERR;
|
||||||
|
else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
|
||||||
|
return -NFS_RPC_DROP;
|
||||||
|
|
||||||
if (rpc_pkt.u.reply.rstatus ||
|
if (rpc_pkt.u.reply.rstatus ||
|
||||||
rpc_pkt.u.reply.verifier ||
|
rpc_pkt.u.reply.verifier ||
|
||||||
@ -475,8 +485,10 @@ nfs_lookup_reply(uchar *pkt, unsigned len)
|
|||||||
|
|
||||||
memcpy((unsigned char *)&rpc_pkt, pkt, len);
|
memcpy((unsigned char *)&rpc_pkt, pkt, len);
|
||||||
|
|
||||||
if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
|
if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
|
||||||
return -1;
|
return -NFS_RPC_ERR;
|
||||||
|
else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
|
||||||
|
return -NFS_RPC_DROP;
|
||||||
|
|
||||||
if (rpc_pkt.u.reply.rstatus ||
|
if (rpc_pkt.u.reply.rstatus ||
|
||||||
rpc_pkt.u.reply.verifier ||
|
rpc_pkt.u.reply.verifier ||
|
||||||
@ -499,8 +511,10 @@ nfs_readlink_reply(uchar *pkt, unsigned len)
|
|||||||
|
|
||||||
memcpy((unsigned char *)&rpc_pkt, pkt, len);
|
memcpy((unsigned char *)&rpc_pkt, pkt, len);
|
||||||
|
|
||||||
if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
|
if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
|
||||||
return -1;
|
return -NFS_RPC_ERR;
|
||||||
|
else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
|
||||||
|
return -NFS_RPC_DROP;
|
||||||
|
|
||||||
if (rpc_pkt.u.reply.rstatus ||
|
if (rpc_pkt.u.reply.rstatus ||
|
||||||
rpc_pkt.u.reply.verifier ||
|
rpc_pkt.u.reply.verifier ||
|
||||||
@ -534,8 +548,10 @@ nfs_read_reply(uchar *pkt, unsigned len)
|
|||||||
|
|
||||||
memcpy((uchar *)&rpc_pkt, pkt, sizeof(rpc_pkt.u.reply));
|
memcpy((uchar *)&rpc_pkt, pkt, sizeof(rpc_pkt.u.reply));
|
||||||
|
|
||||||
if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
|
if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
|
||||||
return -1;
|
return -NFS_RPC_ERR;
|
||||||
|
else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
|
||||||
|
return -NFS_RPC_DROP;
|
||||||
|
|
||||||
if (rpc_pkt.u.reply.rstatus ||
|
if (rpc_pkt.u.reply.rstatus ||
|
||||||
rpc_pkt.u.reply.verifier ||
|
rpc_pkt.u.reply.verifier ||
|
||||||
@ -574,7 +590,8 @@ NfsTimeout(void)
|
|||||||
NetStartAgain();
|
NetStartAgain();
|
||||||
} else {
|
} else {
|
||||||
puts("T ");
|
puts("T ");
|
||||||
NetSetTimeout(NFS_TIMEOUT, NfsTimeout);
|
NetSetTimeout(nfs_timeout + NFS_TIMEOUT * NfsTimeoutCount,
|
||||||
|
NfsTimeout);
|
||||||
NfsSend();
|
NfsSend();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -583,6 +600,7 @@ static void
|
|||||||
NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
|
NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
|
||||||
{
|
{
|
||||||
int rlen;
|
int rlen;
|
||||||
|
int reply;
|
||||||
|
|
||||||
debug("%s\n", __func__);
|
debug("%s\n", __func__);
|
||||||
|
|
||||||
@ -591,19 +609,24 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
|
|||||||
|
|
||||||
switch (NfsState) {
|
switch (NfsState) {
|
||||||
case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
|
case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
|
||||||
rpc_lookup_reply(PROG_MOUNT, pkt, len);
|
if (rpc_lookup_reply(PROG_MOUNT, pkt, len) == -NFS_RPC_DROP)
|
||||||
|
break;
|
||||||
NfsState = STATE_PRCLOOKUP_PROG_NFS_REQ;
|
NfsState = STATE_PRCLOOKUP_PROG_NFS_REQ;
|
||||||
NfsSend();
|
NfsSend();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_PRCLOOKUP_PROG_NFS_REQ:
|
case STATE_PRCLOOKUP_PROG_NFS_REQ:
|
||||||
rpc_lookup_reply(PROG_NFS, pkt, len);
|
if (rpc_lookup_reply(PROG_NFS, pkt, len) == -NFS_RPC_DROP)
|
||||||
|
break;
|
||||||
NfsState = STATE_MOUNT_REQ;
|
NfsState = STATE_MOUNT_REQ;
|
||||||
NfsSend();
|
NfsSend();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_MOUNT_REQ:
|
case STATE_MOUNT_REQ:
|
||||||
if (nfs_mount_reply(pkt, len)) {
|
reply = nfs_mount_reply(pkt, len);
|
||||||
|
if (reply == -NFS_RPC_DROP)
|
||||||
|
break;
|
||||||
|
else if (reply == -NFS_RPC_ERR) {
|
||||||
puts("*** ERROR: Cannot mount\n");
|
puts("*** ERROR: Cannot mount\n");
|
||||||
/* just to be sure... */
|
/* just to be sure... */
|
||||||
NfsState = STATE_UMOUNT_REQ;
|
NfsState = STATE_UMOUNT_REQ;
|
||||||
@ -615,7 +638,10 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_UMOUNT_REQ:
|
case STATE_UMOUNT_REQ:
|
||||||
if (nfs_umountall_reply(pkt, len)) {
|
reply = nfs_umountall_reply(pkt, len);
|
||||||
|
if (reply == -NFS_RPC_DROP)
|
||||||
|
break;
|
||||||
|
else if (reply == -NFS_RPC_ERR) {
|
||||||
puts("*** ERROR: Cannot umount\n");
|
puts("*** ERROR: Cannot umount\n");
|
||||||
net_set_state(NETLOOP_FAIL);
|
net_set_state(NETLOOP_FAIL);
|
||||||
} else {
|
} else {
|
||||||
@ -625,7 +651,10 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_LOOKUP_REQ:
|
case STATE_LOOKUP_REQ:
|
||||||
if (nfs_lookup_reply(pkt, len)) {
|
reply = nfs_lookup_reply(pkt, len);
|
||||||
|
if (reply == -NFS_RPC_DROP)
|
||||||
|
break;
|
||||||
|
else if (reply == -NFS_RPC_ERR) {
|
||||||
puts("*** ERROR: File lookup fail\n");
|
puts("*** ERROR: File lookup fail\n");
|
||||||
NfsState = STATE_UMOUNT_REQ;
|
NfsState = STATE_UMOUNT_REQ;
|
||||||
NfsSend();
|
NfsSend();
|
||||||
@ -638,7 +667,10 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_READLINK_REQ:
|
case STATE_READLINK_REQ:
|
||||||
if (nfs_readlink_reply(pkt, len)) {
|
reply = nfs_readlink_reply(pkt, len);
|
||||||
|
if (reply == -NFS_RPC_DROP)
|
||||||
|
break;
|
||||||
|
else if (reply == -NFS_RPC_ERR) {
|
||||||
puts("*** ERROR: Symlink fail\n");
|
puts("*** ERROR: Symlink fail\n");
|
||||||
NfsState = STATE_UMOUNT_REQ;
|
NfsState = STATE_UMOUNT_REQ;
|
||||||
NfsSend();
|
NfsSend();
|
||||||
@ -654,7 +686,7 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
|
|||||||
|
|
||||||
case STATE_READ_REQ:
|
case STATE_READ_REQ:
|
||||||
rlen = nfs_read_reply(pkt, len);
|
rlen = nfs_read_reply(pkt, len);
|
||||||
NetSetTimeout(NFS_TIMEOUT, NfsTimeout);
|
NetSetTimeout(nfs_timeout, NfsTimeout);
|
||||||
if (rlen > 0) {
|
if (rlen > 0) {
|
||||||
nfs_offset += rlen;
|
nfs_offset += rlen;
|
||||||
NfsSend();
|
NfsSend();
|
||||||
@ -738,7 +770,7 @@ NfsStart(void)
|
|||||||
printf("\nLoad address: 0x%lx\n"
|
printf("\nLoad address: 0x%lx\n"
|
||||||
"Loading: *\b", load_addr);
|
"Loading: *\b", load_addr);
|
||||||
|
|
||||||
NetSetTimeout(NFS_TIMEOUT, NfsTimeout);
|
NetSetTimeout(nfs_timeout, NfsTimeout);
|
||||||
net_set_udp_handler(NfsHandler);
|
net_set_udp_handler(NfsHandler);
|
||||||
|
|
||||||
NfsTimeoutCount = 0;
|
NfsTimeoutCount = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user