Date: Fri, 31 Oct 2014 09:19:47 +0000 (UTC) From: Mateusz Guzik <mjg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r273894 - head/sys/kern Message-ID: <201410310919.s9V9JlOd002153@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mjg Date: Fri Oct 31 09:19:46 2014 New Revision: 273894 URL: https://svnweb.freebsd.org/changeset/base/273894 Log: filedesc: iterate over fd table only once in fdcopy While here add 'fdused_init' which does not perform unnecessary work. Drop FILEDESC_LOCK_ASSERT from fdisused and rely on callers to hold it when appropriate. This function is only used with INVARIANTS. No functional changes intended. Modified: head/sys/kern/kern_descrip.c Modified: head/sys/kern/kern_descrip.c ============================================================================== --- head/sys/kern/kern_descrip.c Fri Oct 31 09:15:59 2014 (r273893) +++ head/sys/kern/kern_descrip.c Fri Oct 31 09:19:46 2014 (r273894) @@ -238,8 +238,6 @@ static int fdisused(struct filedesc *fdp, int fd) { - FILEDESC_LOCK_ASSERT(fdp); - KASSERT(fd >= 0 && fd < fdp->fd_nfiles, ("file descriptor %d out of range (0, %d)", fd, fdp->fd_nfiles)); @@ -251,14 +249,21 @@ fdisused(struct filedesc *fdp, int fd) * Mark a file descriptor as used. */ static void -fdused(struct filedesc *fdp, int fd) +fdused_init(struct filedesc *fdp, int fd) { - FILEDESC_XLOCK_ASSERT(fdp); - KASSERT(!fdisused(fdp, fd), ("fd=%d is already used", fd)); fdp->fd_map[NDSLOT(fd)] |= NDBIT(fd); +} + +static void +fdused(struct filedesc *fdp, int fd) +{ + + FILEDESC_XLOCK_ASSERT(fdp); + + fdused_init(fdp, fd); if (fd > fdp->fd_lastfile) fdp->fd_lastfile = fd; if (fd == fdp->fd_freefile) @@ -1912,28 +1917,23 @@ fdcopy(struct filedesc *fdp) newfdp->fd_freefile = -1; for (i = 0; i <= fdp->fd_lastfile; ++i) { ofde = &fdp->fd_ofiles[i]; - if (ofde->fde_file != NULL && - ofde->fde_file->f_ops->fo_flags & DFLAG_PASSABLE) { - nfde = &newfdp->fd_ofiles[i]; - *nfde = *ofde; - filecaps_copy(&ofde->fde_caps, &nfde->fde_caps); - fhold(nfde->fde_file); - newfdp->fd_lastfile = i; - } else { + if (ofde->fde_file == NULL || + (ofde->fde_file->f_ops->fo_flags & DFLAG_PASSABLE) == 0) { if (newfdp->fd_freefile == -1) newfdp->fd_freefile = i; + continue; } - } - newfdp->fd_cmask = fdp->fd_cmask; - FILEDESC_SUNLOCK(fdp); - FILEDESC_XLOCK(newfdp); - for (i = 0; i <= newfdp->fd_lastfile; ++i) { - if (newfdp->fd_ofiles[i].fde_file != NULL) - fdused(newfdp, i); + nfde = &newfdp->fd_ofiles[i]; + *nfde = *ofde; + filecaps_copy(&ofde->fde_caps, &nfde->fde_caps); + fhold(nfde->fde_file); + fdused_init(newfdp, i); + newfdp->fd_lastfile = i; } if (newfdp->fd_freefile == -1) newfdp->fd_freefile = i; - FILEDESC_XUNLOCK(newfdp); + newfdp->fd_cmask = fdp->fd_cmask; + FILEDESC_SUNLOCK(fdp); return (newfdp); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201410310919.s9V9JlOd002153>