svn commit: r263946 - stable/10/sys/fs/tmpfs

Bryan Drewery bdrewery at FreeBSD.org
Sun Mar 30 18:22:11 UTC 2014


Author: bdrewery
Date: Sun Mar 30 18:22:10 2014
New Revision: 263946
URL: http://svnweb.freebsd.org/changeset/base/263946

Log:
  MFC r263131,r263174,r263175:
  
    Tmpfs readdir() redundant logic and code readability cleanup.
  
    r263131:
      Cleanup redundant logic and add some comments to help explain how it works
      in lieu of potentially less clear code.
  
    r263174:
      Rename cnt to maxcookies and change its use as the condition for when to
      lookup cookies to be less obscure.
  
    r263175:
      Add missing FALLTHROUGH comment in tmpfs_dir_getdents for looking up '.'
      and '..'.

Modified:
  stable/10/sys/fs/tmpfs/tmpfs_subr.c
  stable/10/sys/fs/tmpfs/tmpfs_vnops.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/fs/tmpfs/tmpfs_subr.c
==============================================================================
--- stable/10/sys/fs/tmpfs/tmpfs_subr.c	Sun Mar 30 17:59:32 2014	(r263945)
+++ stable/10/sys/fs/tmpfs/tmpfs_subr.c	Sun Mar 30 18:22:10 2014	(r263946)
@@ -348,6 +348,9 @@ tmpfs_dirent_hash(const char *name, u_in
 static __inline off_t
 tmpfs_dirent_cookie(struct tmpfs_dirent *de)
 {
+	if (de == NULL)
+		return (TMPFS_DIRCOOKIE_EOF);
+
 	MPASS(de->td_cookie >= TMPFS_DIRCOOKIE_MIN);
 
 	return (de->td_cookie);
@@ -1144,7 +1147,7 @@ tmpfs_dir_getdotdotdent(struct tmpfs_nod
  * error code if another error happens.
  */
 int
-tmpfs_dir_getdents(struct tmpfs_node *node, struct uio *uio, int cnt,
+tmpfs_dir_getdents(struct tmpfs_node *node, struct uio *uio, int maxcookies,
     u_long *cookies, int *ncookies)
 {
 	struct tmpfs_dir_cursor dc;
@@ -1155,25 +1158,33 @@ tmpfs_dir_getdents(struct tmpfs_node *no
 	TMPFS_VALIDATE_DIR(node);
 
 	off = 0;
+
+	/*
+	 * Lookup the node from the current offset.  The starting offset of
+	 * 0 will lookup both '.' and '..', and then the first real entry,
+	 * or EOF if there are none.  Then find all entries for the dir that
+	 * fit into the buffer.  Once no more entries are found (de == NULL),
+	 * the offset is set to TMPFS_DIRCOOKIE_EOF, which will cause the next
+	 * call to return 0.
+	 */
 	switch (uio->uio_offset) {
 	case TMPFS_DIRCOOKIE_DOT:
 		error = tmpfs_dir_getdotdent(node, uio);
 		if (error != 0)
 			return (error);
 		uio->uio_offset = TMPFS_DIRCOOKIE_DOTDOT;
-		if (cnt != 0)
+		if (cookies != NULL)
 			cookies[(*ncookies)++] = off = uio->uio_offset;
+		/* FALLTHROUGH */
 	case TMPFS_DIRCOOKIE_DOTDOT:
 		error = tmpfs_dir_getdotdotdent(node, uio);
 		if (error != 0)
 			return (error);
 		de = tmpfs_dir_first(node, &dc);
-		if (de == NULL)
-			uio->uio_offset = TMPFS_DIRCOOKIE_EOF;
-		else
-			uio->uio_offset = tmpfs_dirent_cookie(de);
-		if (cnt != 0)
+		uio->uio_offset = tmpfs_dirent_cookie(de);
+		if (cookies != NULL)
 			cookies[(*ncookies)++] = off = uio->uio_offset;
+		/* EOF. */
 		if (de == NULL)
 			return (0);
 		break;
@@ -1183,7 +1194,7 @@ tmpfs_dir_getdents(struct tmpfs_node *no
 		de = tmpfs_dir_lookup_cookie(node, uio->uio_offset, &dc);
 		if (de == NULL)
 			return (EINVAL);
-		if (cnt != 0)
+		if (cookies != NULL)
 			off = tmpfs_dirent_cookie(de);
 	}
 
@@ -1251,25 +1262,19 @@ tmpfs_dir_getdents(struct tmpfs_node *no
 		error = uiomove(&d, d.d_reclen, uio);
 		if (error == 0) {
 			de = tmpfs_dir_next(node, &dc);
-			if (cnt != 0) {
-				if (de == NULL)
-					off = TMPFS_DIRCOOKIE_EOF;
-				else
-					off = tmpfs_dirent_cookie(de);
-				MPASS(*ncookies < cnt);
+			if (cookies != NULL) {
+				off = tmpfs_dirent_cookie(de);
+				MPASS(*ncookies < maxcookies);
 				cookies[(*ncookies)++] = off;
 			}
 		}
 	} while (error == 0 && uio->uio_resid > 0 && de != NULL);
 
-	/* Update the offset and cache. */
-	if (cnt == 0) {
-		if (de == NULL)
-			off = TMPFS_DIRCOOKIE_EOF;
-		else
-			off = tmpfs_dirent_cookie(de);
-	}
+	/* Skip setting off when using cookies as it is already done above. */
+	if (cookies == NULL)
+		off = tmpfs_dirent_cookie(de);
 
+	/* Update the offset and cache. */
 	uio->uio_offset = off;
 	node->tn_dir.tn_readdir_lastn = off;
 	node->tn_dir.tn_readdir_lastp = de;

Modified: stable/10/sys/fs/tmpfs/tmpfs_vnops.c
==============================================================================
--- stable/10/sys/fs/tmpfs/tmpfs_vnops.c	Sun Mar 30 17:59:32 2014	(r263945)
+++ stable/10/sys/fs/tmpfs/tmpfs_vnops.c	Sun Mar 30 18:22:10 2014	(r263946)
@@ -1199,32 +1199,38 @@ tmpfs_readdir(struct vop_readdir_args *v
 
 	int error;
 	ssize_t startresid;
-	int cnt = 0;
+	int maxcookies;
 	struct tmpfs_node *node;
 
 	/* This operation only makes sense on directory nodes. */
 	if (vp->v_type != VDIR)
 		return ENOTDIR;
 
+	maxcookies = 0;
 	node = VP_TO_TMPFS_DIR(vp);
 
 	startresid = uio->uio_resid;
 
+	/* Allocate cookies for NFS and compat modules. */
 	if (cookies != NULL && ncookies != NULL) {
-		cnt = howmany(node->tn_size, sizeof(struct tmpfs_dirent)) + 2;
-		*cookies = malloc(cnt * sizeof(**cookies), M_TEMP, M_WAITOK);
+		maxcookies = howmany(node->tn_size,
+		    sizeof(struct tmpfs_dirent)) + 2;
+		*cookies = malloc(maxcookies * sizeof(**cookies), M_TEMP,
+		    M_WAITOK);
 		*ncookies = 0;
 	}
 
-	if (cnt == 0)
+	if (cookies == NULL)
 		error = tmpfs_dir_getdents(node, uio, 0, NULL, NULL);
 	else
-		error = tmpfs_dir_getdents(node, uio, cnt, *cookies, ncookies);
+		error = tmpfs_dir_getdents(node, uio, maxcookies, *cookies,
+		    ncookies);
 
+	/* Buffer was filled without hitting EOF. */
 	if (error == EJUSTRETURN)
 		error = (uio->uio_resid != startresid) ? 0 : EINVAL;
 
-	if (error != 0 && cnt != 0)
+	if (error != 0 && cookies != NULL)
 		free(*cookies, M_TEMP);
 
 	if (eofflag != NULL)


More information about the svn-src-all mailing list