From patchwork Thu Dec 6 10:11:50 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthias Brugger X-Patchwork-Id: 204211 X-Patchwork-Delegate: joe.hershberger@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 3B0012C0253 for ; Thu, 6 Dec 2012 22:42:10 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id E4AA54A23D; Thu, 6 Dec 2012 12:42:08 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id aAnFwms9lSTr; Thu, 6 Dec 2012 12:42:08 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id E1A024A23F; Thu, 6 Dec 2012 12:41:50 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 0C12E4A163 for ; Thu, 6 Dec 2012 11:12:02 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id S0oS2FFs6oKd for ; Thu, 6 Dec 2012 11:12:01 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-we0-f172.google.com (mail-we0-f172.google.com [74.125.82.172]) by theia.denx.de (Postfix) with ESMTPS id 4DDAA4A14B for ; Thu, 6 Dec 2012 11:11:59 +0100 (CET) Received: by mail-we0-f172.google.com with SMTP id r3so2409278wey.3 for ; Thu, 06 Dec 2012 02:11:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer; bh=MJCJbSFVULc5UUr8CDS+fldVYxxbJnc16qhAk2unWXo=; b=Aanj99lwujFkXbkM/CG1VrRr0H/YXr/GRaibREvNeyuazRczm0YV73lye9uEVjdPsd DbHqWSSMXf5f6oEyL//YyMP6JpcjCFlrer5NFef83MI8EQygtATIRYqmF3968MKL28WY bnZRlk1AbKxy5GKcFMt8vVVfb+4DJ24YAGyEQxUAtJtcdMSVVYlsotPA9ceXytEYsovi 4lzARdvaQfl9CNPwW+NzYBYni7LH2QzjlFbfen2dSOWKSeJW2wZZ44ojXYfoSiO31c+/ TJWxFTt4Ykd1QLZxE7bPw+x5e045ZhDEw6zhXik74Hy0A+392gaWe7Lyax6BP+H/WiOY Ka5A== Received: by 10.216.195.204 with SMTP id p54mr436351wen.9.1354788718371; Thu, 06 Dec 2012 02:11:58 -0800 (PST) Received: from localhost.localdomain (43.Red-2-139-180.staticIP.rima-tde.net. [2.139.180.43]) by mx.google.com with ESMTPS id i2sm22497703wiw.3.2012.12.06.02.11.56 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 06 Dec 2012 02:11:57 -0800 (PST) From: Matthias Brugger To: joe.hershberger@gmail.com, wd@denx.de, u-boot@lists.denx.de Date: Thu, 6 Dec 2012 11:11:50 +0100 Message-Id: <1354788710-15238-1-git-send-email-matthias.bgg@gmail.com> X-Mailer: git-send-email 1.7.9.5 X-Mailman-Approved-At: Thu, 06 Dec 2012 12:41:48 +0100 Subject: [U-Boot] [PATCH] net: nfs: Fixing error when mounting with time outs X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de When reading more then one file via nfs and in the mount/unmountall process occurs a time out the boot process will be aborted, although eventually the respons from the NFS server arrives. This patch does not increment the rpc_id for the communication with the server when we resend a command timed out previously. Apart if we receive responses from the server with an old RPC ID (smaller then in the u-boot state machine) we don't interpret that as an error but just drop the message and wait for the response corresponding to the last message sent. Signed-off-by: Matthias Brugger --- net/nfs.c | 107 ++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 37 deletions(-) diff --git a/net/nfs.c b/net/nfs.c index 7f2393f..756d4d3 100644 --- a/net/nfs.c +++ b/net/nfs.c @@ -37,8 +37,11 @@ # define NFS_TIMEOUT CONFIG_NFS_TIMEOUT #endif +#define NFS_RPC_ERR 1 +#define NFS_RPC_DROP 124 + static int fs_mounted; -static unsigned long rpc_id; +static unsigned long rpc_id = 1; static int nfs_offset = -1; static int nfs_len; @@ -179,7 +182,7 @@ rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen) int pktlen; int sport; - id = ++rpc_id; + id = rpc_id; pkt.u.call.id = htonl(id); pkt.u.call.type = htonl(MSG_CALL); pkt.u.call.rpcvers = htonl(2); /* use RPC version 2 */ @@ -357,10 +360,13 @@ RPC request dispatcher **************************************************************************/ static void -NfsSend(void) +NfsSend(uint8_t resend) { debug("%s\n", __func__); + if (resend == 0) + rpc_id++; + switch (NfsState) { case STATE_PRCLOOKUP_PROG_MOUNT_REQ: rpc_lookup_req(PROG_MOUNT, 1); @@ -399,8 +405,10 @@ rpc_lookup_reply(int prog, uchar *pkt, unsigned len) 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 || rpc_pkt.u.reply.verifier || @@ -428,8 +436,10 @@ nfs_mount_reply(uchar *pkt, unsigned 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; + if (ntohl(rpc_pkt.u.reply.id) < rpc_id) + return -NFS_RPC_DROP; if (rpc_pkt.u.reply.rstatus || rpc_pkt.u.reply.verifier || @@ -452,13 +462,15 @@ nfs_umountall_reply(uchar *pkt, unsigned 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 || rpc_pkt.u.reply.verifier || rpc_pkt.u.reply.astatus) - return -1; + return -NFS_RPC_ERR; fs_mounted = 0; memset(dirfh, 0, sizeof(dirfh)); @@ -475,14 +487,16 @@ nfs_lookup_reply(uchar *pkt, unsigned 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 || rpc_pkt.u.reply.verifier || rpc_pkt.u.reply.astatus || rpc_pkt.u.reply.data[0]) - return -1; + return -NFS_RPC_ERR; memcpy(filefh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE); @@ -499,14 +513,16 @@ nfs_readlink_reply(uchar *pkt, unsigned 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 || rpc_pkt.u.reply.verifier || rpc_pkt.u.reply.astatus || rpc_pkt.u.reply.data[0]) - return -1; + return -NFS_RPC_ERR; rlen = ntohl(rpc_pkt.u.reply.data[1]); /* new path length */ @@ -534,8 +550,10 @@ nfs_read_reply(uchar *pkt, unsigned len) 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 || rpc_pkt.u.reply.verifier || @@ -575,7 +593,7 @@ NfsTimeout(void) } else { puts("T "); NetSetTimeout(NFS_TIMEOUT, NfsTimeout); - NfsSend(); + NfsSend(1); } } @@ -583,6 +601,7 @@ static void NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len) { int rlen; + int reply; debug("%s\n", __func__); @@ -591,31 +610,39 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len) switch (NfsState) { 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; - NfsSend(); + NfsSend(0); break; 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; - NfsSend(); + NfsSend(0); break; 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"); /* just to be sure... */ NfsState = STATE_UMOUNT_REQ; - NfsSend(); + NfsSend(0); } else { NfsState = STATE_LOOKUP_REQ; - NfsSend(); + NfsSend(0); } break; 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"); net_set_state(NETLOOP_FAIL); } else { @@ -625,30 +652,36 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len) break; 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"); NfsState = STATE_UMOUNT_REQ; - NfsSend(); + NfsSend(0); } else { NfsState = STATE_READ_REQ; nfs_offset = 0; nfs_len = NFS_READ_SIZE; - NfsSend(); + NfsSend(0); } break; 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"); NfsState = STATE_UMOUNT_REQ; - NfsSend(); + NfsSend(0); } else { debug("Symlink --> %s\n", nfs_path); nfs_filename = basename(nfs_path); nfs_path = dirname(nfs_path); NfsState = STATE_MOUNT_REQ; - NfsSend(); + NfsSend(0); } break; @@ -657,16 +690,16 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len) NetSetTimeout(NFS_TIMEOUT, NfsTimeout); if (rlen > 0) { nfs_offset += rlen; - NfsSend(); + NfsSend(0); } else if ((rlen == -NFSERR_ISDIR) || (rlen == -NFSERR_INVAL)) { /* symbolic link */ NfsState = STATE_READLINK_REQ; - NfsSend(); + NfsSend(0); } else { if (!rlen) nfs_download_state = NETLOOP_SUCCESS; NfsState = STATE_UMOUNT_REQ; - NfsSend(); + NfsSend(0); } break; } @@ -751,5 +784,5 @@ NfsStart(void) /* zero out server ether in case the server ip has changed */ memset(NetServerEther, 0, 6); - NfsSend(); + NfsSend(0); }