|
@@ -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)
|
|
|
|
- return -1;
|
|
|
|
|
|
+ if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
|
|
|
|
+ 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)
|
|
|
|
- return -1;
|
|
|
|
|
|
+ if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
|
|
|
|
+ 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)
|
|
|
|
- return -1;
|
|
|
|
|
|
+ if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
|
|
|
|
+ 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)
|
|
|
|
- return -1;
|
|
|
|
|
|
+ if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
|
|
|
|
+ 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)
|
|
|
|
- return -1;
|
|
|
|
|
|
+ if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
|
|
|
|
+ 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)
|
|
|
|
- return -1;
|
|
|
|
|
|
+ if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
|
|
|
|
+ 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;
|