From owner-svn-src-all@FreeBSD.ORG Sun Mar 30 18:22:11 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id D2291F91; Sun, 30 Mar 2014 18:22:11 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B2390B57; Sun, 30 Mar 2014 18:22:11 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s2UIMBuA011689; Sun, 30 Mar 2014 18:22:11 GMT (envelope-from bdrewery@svn.freebsd.org) Received: (from bdrewery@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s2UIMBc4011686; Sun, 30 Mar 2014 18:22:11 GMT (envelope-from bdrewery@svn.freebsd.org) Message-Id: <201403301822.s2UIMBc4011686@svn.freebsd.org> From: Bryan Drewery Date: Sun, 30 Mar 2014 18:22:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r263946 - stable/10/sys/fs/tmpfs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 30 Mar 2014 18:22:11 -0000 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)