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 --- |