[Midnightbsd-cvs] src [9724] trunk/lib/libstand/nfs.c: fix some nfs issues

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Fri Dec 22 15:26:53 EST 2017


Revision: 9724
          http://svnweb.midnightbsd.org/src/?rev=9724
Author:   laffer1
Date:     2017-12-22 15:26:52 -0500 (Fri, 22 Dec 2017)
Log Message:
-----------
fix some nfs issues

Modified Paths:
--------------
    trunk/lib/libstand/nfs.c

Modified: trunk/lib/libstand/nfs.c
===================================================================
--- trunk/lib/libstand/nfs.c	2017-12-22 20:24:16 UTC (rev 9723)
+++ trunk/lib/libstand/nfs.c	2017-12-22 20:26:52 UTC (rev 9724)
@@ -181,6 +181,7 @@
 	uint32_t fhsize;
 	u_char fh[NFS_V3MAXFHSIZE];
 	struct nfsv3_fattrs fa;	/* all in network order */
+	uint64_t cookie;
 };
 #endif	/* OLD_NFSV2 */
 
@@ -486,6 +487,9 @@
 	desc->destip = rootip;
 	if ((error = nfs_getrootfh(desc, rootpath, nfs_root_node.fh)))
 		return (error);
+	nfs_root_node.fa.fa_type  = htonl(NFDIR);
+	nfs_root_node.fa.fa_mode  = htonl(0755);
+	nfs_root_node.fa.fa_nlink = htonl(2);
 	nfs_root_node.iodesc = desc;
 
 	fh = &nfs_root_node.fh[0];
@@ -498,14 +502,15 @@
 	setenv("boot.nfsroot.path", rootpath, 1);
 	setenv("boot.nfsroot.nfshandle", buf, 1);
 
+	/* Allocate file system specific data structure */
+	currfd = malloc(sizeof(*newfd));
+	if (currfd == NULL) {
+		error = ENOMEM;
+		goto out;
+	}
+
 #ifndef NFS_NOSYMLINK
-	/* Fake up attributes for the root dir. */
-	fa = &nfs_root_node.fa;
-	fa->fa_type  = htonl(NFDIR);
-	fa->fa_mode  = htonl(0755);
-	fa->fa_nlink = htonl(2);
-
-	currfd = &nfs_root_node;
+	bcopy(&nfs_root_node, currfd, sizeof(*currfd));
 	newfd = 0;
 
 	cp = path = strdup(upath);
@@ -533,7 +538,6 @@
 		/* allocate file system specific data structure */
 		newfd = malloc(sizeof(*newfd));
 		newfd->iodesc = currfd->iodesc;
-		newfd->off = 0;
 
 		/*
 		 * Get next component of path name.
@@ -585,11 +589,8 @@
 			 * If relative pathname, restart at parent directory.
 			 */
 			cp = namebuf;
-			if (*cp == '/') {
-				if (currfd != &nfs_root_node)
-					free(currfd);
-				currfd = &nfs_root_node;
-			}
+			if (*cp == '/')
+				bcopy(&nfs_root_node, currfd, sizeof(*currfd));
 
 			free(newfd);
 			newfd = 0;
@@ -597,8 +598,7 @@
 			continue;
 		}
 
-		if (currfd != &nfs_root_node)
-			free(currfd);
+		free(currfd);
 		currfd = newfd;
 		newfd = 0;
 	}
@@ -611,14 +611,12 @@
 	if (path)
 		free(path);
 #else
-        /* allocate file system specific data structure */
-        currfd = malloc(sizeof(*currfd));
         currfd->iodesc = desc;
-        currfd->off = 0;
 
         error = nfs_lookupfh(&nfs_root_node, upath, currfd);
 #endif
 	if (!error) {
+		currfd->off = 0;
 		f->f_fsdata = (void *)currfd;
 		return (0);
 	}
@@ -628,10 +626,7 @@
 		printf("nfs_open: %s lookupfh failed: %s\n",
 		    path, strerror(error));
 #endif
-#ifndef NFS_NOSYMLINK
-	if (currfd != &nfs_root_node)
-#endif
-		free(currfd);
+	free(currfd);
 
 	return (error);
 }
@@ -646,7 +641,7 @@
 		printf("nfs_close: fp=0x%lx\n", (u_long)fp);
 #endif
 
-	if (fp != &nfs_root_node && fp)
+	if (fp)
 		free(fp);
 	f->f_fsdata = (void *)0;
 
@@ -761,6 +756,7 @@
 	struct nfs_readdir_data *rd;
 	struct nfs_readdir_off  *roff = NULL;
 	static char *buf;
+	static struct nfs_iodesc *pfp = NULL;
 	static n_long cookie = 0;
 	size_t cc;
 	n_long eof;
@@ -774,13 +770,14 @@
 		u_char d[NFS_READDIRSIZE];
 	} rdata;
 
-	if (cookie == 0) {
+	if (fp != pfp || fp->off != cookie) {
+		pfp = NULL;
 	refill:
 		args = &sdata.d;
 		bzero(args, sizeof(*args));
 
 		bcopy(fp->fh, args->fh, NFS_FHSIZE);
-		args->cookie = htonl(cookie);
+		args->cookie = htonl(fp->off);
 		args->count  = htonl(NFS_READDIRSIZE);
 
 		cc = rpc_call(fp->iodesc, NFS_PROG, NFS_VER2, NFSPROC_READDIR,
@@ -790,6 +787,8 @@
 		roff = (struct nfs_readdir_off *)buf;
 		if (ntohl(roff->cookie) != 0)
 			return EIO;
+		pfp = fp;
+		cookie = fp->off;
 	}
 	roff = (struct nfs_readdir_off *)buf;
 
@@ -810,7 +809,7 @@
 
 	buf += (sizeof(struct nfs_readdir_data) + roundup(htonl(rd->len),4));
 	roff = (struct nfs_readdir_off *)buf;
-	cookie = ntohl(roff->cookie);
+	fp->off = cookie = ntohl(roff->cookie);
 	return 0;
 }
 #else	/* !OLD_NFSV2 */
@@ -1133,6 +1132,9 @@
 	if ((error = nfs_getrootfh(desc, rootpath, &nfs_root_node.fhsize,
 	    nfs_root_node.fh)))
 		return (error);
+	nfs_root_node.fa.fa_type  = htonl(NFDIR);
+	nfs_root_node.fa.fa_mode  = htonl(0755);
+	nfs_root_node.fa.fa_nlink = htonl(2);
 	nfs_root_node.iodesc = desc;
 
 	fh = &nfs_root_node.fh[0];
@@ -1147,14 +1149,14 @@
 	sprintf(buf, "%d", nfs_root_node.fhsize);
 	setenv("boot.nfsroot.nfshandlelen", buf, 1);
 
+	/* Allocate file system specific data structure */
+	currfd = malloc(sizeof(*newfd));
+	if (currfd == NULL) {
+		error = ENOMEM;
+		goto out;
+	}
 #ifndef NFS_NOSYMLINK
-	/* Fake up attributes for the root dir. */
-	fa = &nfs_root_node.fa;
-	fa->fa_type  = htonl(NFDIR);
-	fa->fa_mode  = htonl(0755);
-	fa->fa_nlink = htonl(2);
-
-	currfd = &nfs_root_node;
+	bcopy(&nfs_root_node, currfd, sizeof(*currfd));
 	newfd = 0;
 
 	cp = path = strdup(upath);
@@ -1186,7 +1188,6 @@
 			goto out;
 		}
 		newfd->iodesc = currfd->iodesc;
-		newfd->off = 0;
 
 		/*
 		 * Get next component of path name.
@@ -1238,11 +1239,8 @@
 			 * If relative pathname, restart at parent directory.
 			 */
 			cp = namebuf;
-			if (*cp == '/') {
-				if (currfd != &nfs_root_node)
-					free(currfd);
-				currfd = &nfs_root_node;
-			}
+			if (*cp == '/')
+				bcopy(&nfs_root_node, currfd, sizeof(*currfd));
 
 			free(newfd);
 			newfd = 0;
@@ -1250,8 +1248,7 @@
 			continue;
 		}
 
-		if (currfd != &nfs_root_node)
-			free(currfd);
+		free(currfd);
 		currfd = newfd;
 		newfd = 0;
 	}
@@ -1262,17 +1259,13 @@
 	free(newfd);
 	free(path);
 #else
-	/* allocate file system specific data structure */
-	currfd = malloc(sizeof(*currfd));
-	if (currfd != NULL) {
-		currfd->iodesc = desc;
-		currfd->off = 0;
+	currfd->iodesc = desc;
 
-		error = nfs_lookupfh(&nfs_root_node, upath, currfd);
-	} else
-		error = ENOMEM;
+	error = nfs_lookupfh(&nfs_root_node, upath, currfd);
 #endif
 	if (!error) {
+		currfd->off = 0;
+		currfd->cookie = 0;
 		f->f_fsdata = (void *)currfd;
 		return (0);
 	}
@@ -1282,10 +1275,7 @@
 		printf("nfs_open: %s lookupfh failed: %s\n",
 		    path, strerror(error));
 #endif
-#ifndef NFS_NOSYMLINK
-	if (currfd != &nfs_root_node)
-#endif
-		free(currfd);
+	free(currfd);
 
 	return (error);
 }
@@ -1300,7 +1290,7 @@
 		printf("nfs_close: fp=0x%lx\n", (u_long)fp);
 #endif
 
-	if (fp != &nfs_root_node && fp)
+	if (fp)
 		free(fp);
 	f->f_fsdata = (void *)0;
 
@@ -1414,11 +1404,9 @@
 	struct nfsv3_readdir_repl *repl;
 	struct nfsv3_readdir_entry *rent;
 	static char *buf;
-	static uint32_t cookie0 = 0;
-	static uint32_t cookie1 = 0;
+	static struct nfs_iodesc *pfp = NULL;
+	static uint64_t cookie = 0;
 	size_t cc;
-	static uint32_t cookieverf0 = 0;
-	static uint32_t cookieverf1 = 0;
 	int pos;
 
 	struct args {
@@ -1434,7 +1422,8 @@
 		u_char d[NFS_READDIRSIZE];
 	} rdata;
 
-	if (cookie0 == 0 && cookie1 == 0) {
+	if (fp != pfp || fp->off != cookie) {
+		pfp = NULL;
 	refill:
 		args = &sdata.d;
 		bzero(args, sizeof(*args));
@@ -1442,10 +1431,10 @@
 		args->fhsize = htonl(fp->fhsize);
 		bcopy(fp->fh, args->fhpluscookie, fp->fhsize);
 		pos = roundup(fp->fhsize, sizeof(uint32_t)) / sizeof(uint32_t);
-		args->fhpluscookie[pos++] = cookie0;
-		args->fhpluscookie[pos++] = cookie1;
-		args->fhpluscookie[pos++] = cookieverf0;
-		args->fhpluscookie[pos++] = cookieverf1;
+		args->fhpluscookie[pos++] = htonl(fp->off >> 32);
+		args->fhpluscookie[pos++] = htonl(fp->off);
+		args->fhpluscookie[pos++] = htonl(fp->cookie >> 32);
+		args->fhpluscookie[pos++] = htonl(fp->cookie);
 		args->fhpluscookie[pos] = htonl(NFS_READDIRSIZE);
 
 		cc = rpc_call(fp->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_READDIR,
@@ -1456,8 +1445,10 @@
 		repl = (struct nfsv3_readdir_repl *)buf;
 		if (repl->errno != 0)
 			return (ntohl(repl->errno));
-		cookieverf0 = repl->cookiev0;
-		cookieverf1 = repl->cookiev1;
+		pfp = fp;
+		cookie = fp->off;
+		fp->cookie = ((uint64_t)ntohl(repl->cookiev0) << 32) |
+		    ntohl(repl->cookiev1);
 		buf += sizeof (struct nfsv3_readdir_repl);
 	}
 	rent = (struct nfsv3_readdir_entry *)buf;
@@ -1465,10 +1456,7 @@
 	if (rent->follows == 0) {
 		/* fid0 is actually eof */
 		if (rent->fid0 != 0) {
-			cookie0 = 0;
-			cookie1 = 0;
-			cookieverf0 = 0;
-			cookieverf1 = 0;
+			cookie = 0;
 			return (ENOENT);
 		}
 		goto refill;
@@ -1479,8 +1467,9 @@
 	d->d_name[d->d_namlen] = '\0';
 
 	pos = roundup(d->d_namlen, sizeof(uint32_t)) / sizeof(uint32_t);
-	cookie0 = rent->nameplus[pos++];
-	cookie1 = rent->nameplus[pos++];
+	fp->off = cookie = ((uint64_t)ntohl(rent->nameplus[pos]) << 32) |
+	    ntohl(rent->nameplus[pos + 1]);
+	pos += 2;
 	buf = (u_char *)&rent->nameplus[pos];
 	return (0);
 }



More information about the Midnightbsd-cvs mailing list