Deleted Added
full compact
kern_descrip.c (115540) kern_descrip.c (115702)
1/*
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

--- 22 unchanged lines hidden (view full) ---

31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94
1/*
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

--- 22 unchanged lines hidden (view full) ---

31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94
39 * $FreeBSD: head/sys/kern/kern_descrip.c 115540 2003-05-31 20:16:44Z phk $
39 * $FreeBSD: head/sys/kern/kern_descrip.c 115702 2003-06-02 16:05:32Z tegge $
40 */
41
42#include "opt_compat.h"
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/syscallsubr.h>
47#include <sys/sysproto.h>

--- 20 unchanged lines hidden (view full) ---

68#include <sys/socketvar.h>
69#include <sys/signalvar.h>
70
71#include <vm/vm.h>
72#include <vm/vm_extern.h>
73#include <vm/uma.h>
74
75static MALLOC_DEFINE(M_FILEDESC, "file desc", "Open file descriptor table");
40 */
41
42#include "opt_compat.h"
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/syscallsubr.h>
47#include <sys/sysproto.h>

--- 20 unchanged lines hidden (view full) ---

68#include <sys/socketvar.h>
69#include <sys/signalvar.h>
70
71#include <vm/vm.h>
72#include <vm/vm_extern.h>
73#include <vm/uma.h>
74
75static MALLOC_DEFINE(M_FILEDESC, "file desc", "Open file descriptor table");
76static MALLOC_DEFINE(M_FILEDESC_TO_LEADER, "file desc to leader",
77 "file desc to leader structures");
76static MALLOC_DEFINE(M_SIGIO, "sigio", "sigio structures");
77
78static uma_zone_t file_zone;
79
80static d_open_t fdopen;
81#define NUMFDESC 64
82
83#define CDEV_MAJOR 22

--- 367 unchanged lines hidden (view full) ---

451 register_t *retval;
452 struct thread *td;
453{
454 struct filedesc *fdp;
455 struct proc *p;
456 struct file *fp;
457 struct file *delfp;
458 int error, newfd;
78static MALLOC_DEFINE(M_SIGIO, "sigio", "sigio structures");
79
80static uma_zone_t file_zone;
81
82static d_open_t fdopen;
83#define NUMFDESC 64
84
85#define CDEV_MAJOR 22

--- 367 unchanged lines hidden (view full) ---

453 register_t *retval;
454 struct thread *td;
455{
456 struct filedesc *fdp;
457 struct proc *p;
458 struct file *fp;
459 struct file *delfp;
460 int error, newfd;
461 int holdleaders;
459
460 p = td->td_proc;
461 fdp = p->p_fd;
462
463 /*
464 * Verify we have a valid descriptor to dup from and possibly to
465 * dup to.
466 */

--- 48 unchanged lines hidden (view full) ---

515 KASSERT(old != new, ("new fd is same as old"));
516
517 /*
518 * Save info on the descriptor being overwritten. We have
519 * to do the unmap now, but we cannot close it without
520 * introducing an ownership race for the slot.
521 */
522 delfp = fdp->fd_ofiles[new];
462
463 p = td->td_proc;
464 fdp = p->p_fd;
465
466 /*
467 * Verify we have a valid descriptor to dup from and possibly to
468 * dup to.
469 */

--- 48 unchanged lines hidden (view full) ---

518 KASSERT(old != new, ("new fd is same as old"));
519
520 /*
521 * Save info on the descriptor being overwritten. We have
522 * to do the unmap now, but we cannot close it without
523 * introducing an ownership race for the slot.
524 */
525 delfp = fdp->fd_ofiles[new];
526 if (delfp != NULL && p->p_fdtol != NULL) {
527 /*
528 * Ask fdfree() to sleep to ensure that all relevant
529 * process leaders can be traversed in closef().
530 */
531 fdp->fd_holdleaderscount++;
532 holdleaders = 1;
533 } else
534 holdleaders = 0;
523 KASSERT(delfp == NULL || type == DUP_FIXED,
524 ("dup() picked an open file"));
525#if 0
526 if (delfp && (fdp->fd_ofileflags[new] & UF_MAPPED))
527 (void) munmapfd(td, new);
528#endif
529
530 /*

--- 10 unchanged lines hidden (view full) ---

541 * If we dup'd over a valid file, we now own the reference to it
542 * and must dispose of it using closef() semantics (as if a
543 * close() were performed on it).
544 */
545 if (delfp) {
546 mtx_lock(&Giant);
547 (void) closef(delfp, td);
548 mtx_unlock(&Giant);
535 KASSERT(delfp == NULL || type == DUP_FIXED,
536 ("dup() picked an open file"));
537#if 0
538 if (delfp && (fdp->fd_ofileflags[new] & UF_MAPPED))
539 (void) munmapfd(td, new);
540#endif
541
542 /*

--- 10 unchanged lines hidden (view full) ---

553 * If we dup'd over a valid file, we now own the reference to it
554 * and must dispose of it using closef() semantics (as if a
555 * close() were performed on it).
556 */
557 if (delfp) {
558 mtx_lock(&Giant);
559 (void) closef(delfp, td);
560 mtx_unlock(&Giant);
561 if (holdleaders) {
562 FILEDESC_LOCK(fdp);
563 fdp->fd_holdleaderscount--;
564 if (fdp->fd_holdleaderscount == 0 &&
565 fdp->fd_holdleaderswakeup != 0) {
566 fdp->fd_holdleaderswakeup = 0;
567 wakeup(&fdp->fd_holdleaderscount);
568 }
569 FILEDESC_UNLOCK(fdp);
570 }
549 }
550 return (0);
551}
552
553/*
554 * If sigio is on the list associated with a process or process group,
555 * disable signalling from the device, remove sigio from the list and
556 * free sigio.

--- 231 unchanged lines hidden (view full) ---

788int
789close(td, uap)
790 struct thread *td;
791 struct close_args *uap;
792{
793 struct filedesc *fdp;
794 struct file *fp;
795 int fd, error;
571 }
572 return (0);
573}
574
575/*
576 * If sigio is on the list associated with a process or process group,
577 * disable signalling from the device, remove sigio from the list and
578 * free sigio.

--- 231 unchanged lines hidden (view full) ---

810int
811close(td, uap)
812 struct thread *td;
813 struct close_args *uap;
814{
815 struct filedesc *fdp;
816 struct file *fp;
817 int fd, error;
818 int holdleaders;
796
797 fd = uap->fd;
798 error = 0;
819
820 fd = uap->fd;
821 error = 0;
822 holdleaders = 0;
799 fdp = td->td_proc->p_fd;
800 mtx_lock(&Giant);
801 FILEDESC_LOCK(fdp);
802 if ((unsigned)fd >= fdp->fd_nfiles ||
803 (fp = fdp->fd_ofiles[fd]) == NULL) {
804 FILEDESC_UNLOCK(fdp);
805 error = EBADF;
806 goto done2;
807 }
808#if 0
809 if (fdp->fd_ofileflags[fd] & UF_MAPPED)
810 (void) munmapfd(td, fd);
811#endif
812 fdp->fd_ofiles[fd] = NULL;
813 fdp->fd_ofileflags[fd] = 0;
823 fdp = td->td_proc->p_fd;
824 mtx_lock(&Giant);
825 FILEDESC_LOCK(fdp);
826 if ((unsigned)fd >= fdp->fd_nfiles ||
827 (fp = fdp->fd_ofiles[fd]) == NULL) {
828 FILEDESC_UNLOCK(fdp);
829 error = EBADF;
830 goto done2;
831 }
832#if 0
833 if (fdp->fd_ofileflags[fd] & UF_MAPPED)
834 (void) munmapfd(td, fd);
835#endif
836 fdp->fd_ofiles[fd] = NULL;
837 fdp->fd_ofileflags[fd] = 0;
838 if (td->td_proc->p_fdtol != NULL) {
839 /*
840 * Ask fdfree() to sleep to ensure that all relevant
841 * process leaders can be traversed in closef().
842 */
843 fdp->fd_holdleaderscount++;
844 holdleaders = 1;
845 }
814
815 /*
816 * we now hold the fp reference that used to be owned by the descriptor
817 * array.
818 */
819 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
820 fdp->fd_lastfile--;
821 if (fd < fdp->fd_freefile)
822 fdp->fd_freefile = fd;
823 if (fd < fdp->fd_knlistsize) {
824 FILEDESC_UNLOCK(fdp);
825 knote_fdclose(td, fd);
826 } else
827 FILEDESC_UNLOCK(fdp);
828
829 error = closef(fp, td);
830done2:
831 mtx_unlock(&Giant);
846
847 /*
848 * we now hold the fp reference that used to be owned by the descriptor
849 * array.
850 */
851 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
852 fdp->fd_lastfile--;
853 if (fd < fdp->fd_freefile)
854 fdp->fd_freefile = fd;
855 if (fd < fdp->fd_knlistsize) {
856 FILEDESC_UNLOCK(fdp);
857 knote_fdclose(td, fd);
858 } else
859 FILEDESC_UNLOCK(fdp);
860
861 error = closef(fp, td);
862done2:
863 mtx_unlock(&Giant);
864 if (holdleaders) {
865 FILEDESC_LOCK(fdp);
866 fdp->fd_holdleaderscount--;
867 if (fdp->fd_holdleaderscount == 0 &&
868 fdp->fd_holdleaderswakeup != 0) {
869 fdp->fd_holdleaderswakeup = 0;
870 wakeup(&fdp->fd_holdleaderscount);
871 }
872 FILEDESC_UNLOCK(fdp);
873 }
832 return (error);
833}
834
835#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
836/*
837 * Return status information about a file descriptor.
838 */
839#ifndef _SYS_SYSPROTO_H_

--- 537 unchanged lines hidden (view full) ---

1377 */
1378void
1379fdfree(td)
1380 struct thread *td;
1381{
1382 struct filedesc *fdp;
1383 struct file **fpp;
1384 int i;
874 return (error);
875}
876
877#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
878/*
879 * Return status information about a file descriptor.
880 */
881#ifndef _SYS_SYSPROTO_H_

--- 537 unchanged lines hidden (view full) ---

1419 */
1420void
1421fdfree(td)
1422 struct thread *td;
1423{
1424 struct filedesc *fdp;
1425 struct file **fpp;
1426 int i;
1427 struct filedesc_to_leader *fdtol;
1428 struct file *fp;
1429 struct vnode *vp;
1430 struct flock lf;
1385
1386 /* Certain daemons might not have file descriptors. */
1387 fdp = td->td_proc->p_fd;
1388 if (fdp == NULL)
1389 return;
1390
1431
1432 /* Certain daemons might not have file descriptors. */
1433 fdp = td->td_proc->p_fd;
1434 if (fdp == NULL)
1435 return;
1436
1437 /* Check for special need to clear POSIX style locks */
1438 fdtol = td->td_proc->p_fdtol;
1439 if (fdtol != NULL) {
1440 FILEDESC_LOCK(fdp);
1441 KASSERT(fdtol->fdl_refcount > 0,
1442 ("filedesc_to_refcount botch: fdl_refcount=%d",
1443 fdtol->fdl_refcount));
1444 if (fdtol->fdl_refcount == 1 &&
1445 (td->td_proc->p_leader->p_flag & P_ADVLOCK) != 0) {
1446 i = 0;
1447 fpp = fdp->fd_ofiles;
1448 for (i = 0, fpp = fdp->fd_ofiles;
1449 i < fdp->fd_lastfile;
1450 i++, fpp++) {
1451 if (*fpp == NULL ||
1452 (*fpp)->f_type != DTYPE_VNODE)
1453 continue;
1454 fp = *fpp;
1455 fhold(fp);
1456 FILEDESC_UNLOCK(fdp);
1457 lf.l_whence = SEEK_SET;
1458 lf.l_start = 0;
1459 lf.l_len = 0;
1460 lf.l_type = F_UNLCK;
1461 vp = fp->f_data;
1462 (void) VOP_ADVLOCK(vp,
1463 (caddr_t)td->td_proc->
1464 p_leader,
1465 F_UNLCK,
1466 &lf,
1467 F_POSIX);
1468 FILEDESC_LOCK(fdp);
1469 fdrop(fp, td);
1470 fpp = fdp->fd_ofiles + i;
1471 }
1472 }
1473 retry:
1474 if (fdtol->fdl_refcount == 1) {
1475 if (fdp->fd_holdleaderscount > 0 &&
1476 (td->td_proc->p_leader->p_flag & P_ADVLOCK) != 0) {
1477 /*
1478 * close() or do_dup() has cleared a reference
1479 * in a shared file descriptor table.
1480 */
1481 fdp->fd_holdleaderswakeup = 1;
1482 msleep(&fdp->fd_holdleaderscount, &fdp->fd_mtx,
1483 PLOCK, "fdlhold", 0);
1484 goto retry;
1485 }
1486 if (fdtol->fdl_holdcount > 0) {
1487 /*
1488 * Ensure that fdtol->fdl_leader
1489 * remains valid in closef().
1490 */
1491 fdtol->fdl_wakeup = 1;
1492 msleep(fdtol, &fdp->fd_mtx,
1493 PLOCK, "fdlhold", 0);
1494 goto retry;
1495 }
1496 }
1497 fdtol->fdl_refcount--;
1498 if (fdtol->fdl_refcount == 0 &&
1499 fdtol->fdl_holdcount == 0) {
1500 fdtol->fdl_next->fdl_prev = fdtol->fdl_prev;
1501 fdtol->fdl_prev->fdl_next = fdtol->fdl_next;
1502 } else
1503 fdtol = NULL;
1504 td->td_proc->p_fdtol = NULL;
1505 FILEDESC_UNLOCK(fdp);
1506 if (fdtol != NULL)
1507 FREE(fdtol, M_FILEDESC_TO_LEADER);
1508 }
1391 FILEDESC_LOCK(fdp);
1392 if (--fdp->fd_refcnt > 0) {
1393 FILEDESC_UNLOCK(fdp);
1394 return;
1395 }
1396
1397 /*
1398 * We are the last reference to the structure, so we can

--- 221 unchanged lines hidden (view full) ---

1620 */
1621int
1622closef(fp, td)
1623 struct file *fp;
1624 struct thread *td;
1625{
1626 struct vnode *vp;
1627 struct flock lf;
1509 FILEDESC_LOCK(fdp);
1510 if (--fdp->fd_refcnt > 0) {
1511 FILEDESC_UNLOCK(fdp);
1512 return;
1513 }
1514
1515 /*
1516 * We are the last reference to the structure, so we can

--- 221 unchanged lines hidden (view full) ---

1738 */
1739int
1740closef(fp, td)
1741 struct file *fp;
1742 struct thread *td;
1743{
1744 struct vnode *vp;
1745 struct flock lf;
1746 struct filedesc_to_leader *fdtol;
1747 struct filedesc *fdp;
1628
1629 if (fp == NULL)
1630 return (0);
1631 /*
1632 * POSIX record locking dictates that any close releases ALL
1633 * locks owned by this process. This is handled by setting
1634 * a flag in the unlock to free ONLY locks obeying POSIX
1635 * semantics, and not to free BSD-style file locks.
1636 * If the descriptor was in a message, POSIX-style locks
1637 * aren't passed with the descriptor.
1638 */
1748
1749 if (fp == NULL)
1750 return (0);
1751 /*
1752 * POSIX record locking dictates that any close releases ALL
1753 * locks owned by this process. This is handled by setting
1754 * a flag in the unlock to free ONLY locks obeying POSIX
1755 * semantics, and not to free BSD-style file locks.
1756 * If the descriptor was in a message, POSIX-style locks
1757 * aren't passed with the descriptor.
1758 */
1639 if (td != NULL && (td->td_proc->p_leader->p_flag & P_ADVLOCK) != 0 &&
1759 if (td != NULL &&
1640 fp->f_type == DTYPE_VNODE) {
1760 fp->f_type == DTYPE_VNODE) {
1641 lf.l_whence = SEEK_SET;
1642 lf.l_start = 0;
1643 lf.l_len = 0;
1644 lf.l_type = F_UNLCK;
1645 vp = fp->f_data;
1646 (void) VOP_ADVLOCK(vp, (caddr_t)td->td_proc->p_leader,
1647 F_UNLCK, &lf, F_POSIX);
1761 if ((td->td_proc->p_leader->p_flag & P_ADVLOCK) != 0) {
1762 lf.l_whence = SEEK_SET;
1763 lf.l_start = 0;
1764 lf.l_len = 0;
1765 lf.l_type = F_UNLCK;
1766 vp = fp->f_data;
1767 (void) VOP_ADVLOCK(vp, (caddr_t)td->td_proc->p_leader,
1768 F_UNLCK, &lf, F_POSIX);
1769 }
1770 fdtol = td->td_proc->p_fdtol;
1771 if (fdtol != NULL) {
1772 /*
1773 * Handle special case where file descriptor table
1774 * is shared between multiple process leaders.
1775 */
1776 fdp = td->td_proc->p_fd;
1777 FILEDESC_LOCK(fdp);
1778 for (fdtol = fdtol->fdl_next;
1779 fdtol != td->td_proc->p_fdtol;
1780 fdtol = fdtol->fdl_next) {
1781 if ((fdtol->fdl_leader->p_flag &
1782 P_ADVLOCK) == 0)
1783 continue;
1784 fdtol->fdl_holdcount++;
1785 FILEDESC_UNLOCK(fdp);
1786 lf.l_whence = SEEK_SET;
1787 lf.l_start = 0;
1788 lf.l_len = 0;
1789 lf.l_type = F_UNLCK;
1790 vp = fp->f_data;
1791 (void) VOP_ADVLOCK(vp,
1792 (caddr_t)fdtol->fdl_leader,
1793 F_UNLCK, &lf, F_POSIX);
1794 FILEDESC_LOCK(fdp);
1795 fdtol->fdl_holdcount--;
1796 if (fdtol->fdl_holdcount == 0 &&
1797 fdtol->fdl_wakeup != 0) {
1798 fdtol->fdl_wakeup = 0;
1799 wakeup(fdtol);
1800 }
1801 }
1802 FILEDESC_UNLOCK(fdp);
1803 }
1648 }
1649 return (fdrop(fp, td));
1650}
1651
1652/*
1653 * Drop reference on struct file passed in, may call closef if the
1654 * reference hits zero.
1655 */

--- 418 unchanged lines hidden (view full) ---

2074
2075 default:
2076 FILEDESC_UNLOCK(fdp);
2077 return (error);
2078 }
2079 /* NOTREACHED */
2080}
2081
1804 }
1805 return (fdrop(fp, td));
1806}
1807
1808/*
1809 * Drop reference on struct file passed in, may call closef if the
1810 * reference hits zero.
1811 */

--- 418 unchanged lines hidden (view full) ---

2230
2231 default:
2232 FILEDESC_UNLOCK(fdp);
2233 return (error);
2234 }
2235 /* NOTREACHED */
2236}
2237
2238
2239struct filedesc_to_leader *
2240filedesc_to_leader_alloc(struct filedesc_to_leader *old,
2241 struct filedesc *fdp,
2242 struct proc *leader)
2243{
2244 struct filedesc_to_leader *fdtol;
2245
2246 MALLOC(fdtol, struct filedesc_to_leader *,
2247 sizeof(struct filedesc_to_leader),
2248 M_FILEDESC_TO_LEADER,
2249 M_WAITOK);
2250 fdtol->fdl_refcount = 1;
2251 fdtol->fdl_holdcount = 0;
2252 fdtol->fdl_wakeup = 0;
2253 fdtol->fdl_leader = leader;
2254 if (old != NULL) {
2255 FILEDESC_LOCK(fdp);
2256 fdtol->fdl_next = old->fdl_next;
2257 fdtol->fdl_prev = old;
2258 old->fdl_next = fdtol;
2259 fdtol->fdl_next->fdl_prev = fdtol;
2260 FILEDESC_UNLOCK(fdp);
2261 } else {
2262 fdtol->fdl_next = fdtol;
2263 fdtol->fdl_prev = fdtol;
2264 }
2265 return fdtol;
2266}
2267
2082/*
2083 * Get file structures.
2084 */
2085static int
2086sysctl_kern_file(SYSCTL_HANDLER_ARGS)
2087{
2088 struct xfile xf;
2089 struct filedesc *fdp;

--- 183 unchanged lines hidden ---
2268/*
2269 * Get file structures.
2270 */
2271static int
2272sysctl_kern_file(SYSCTL_HANDLER_ARGS)
2273{
2274 struct xfile xf;
2275 struct filedesc *fdp;

--- 183 unchanged lines hidden ---