* Allocate a file descriptor for the process. */
| 1893 | * Allocate a file descriptor for the process. |
| 1894 | */ |
| 1895 | int |
| 1896 | fdalloc(struct thread *td, int minfd, int *result) |
| 1897 | { |
| 1898 | struct proc *p = td->td_proc; |
| 1899 | struct filedesc *fdp = p->p_fd; |
| 1900 | int fd, maxfd, allocfd; |
| 1901 | #ifdef RACCT |
| 1902 | int error; |
| 1903 | #endif |
| 1904 | |
| 1905 | FILEDESC_XLOCK_ASSERT(fdp); |
| 1906 | |
| 1907 | if (fdp->fd_freefile > minfd) |
| 1908 | minfd = fdp->fd_freefile; |
| 1909 | |
| 1910 | maxfd = getmaxfd(td); |
| 1911 | |
| 1912 | /* |
| 1913 | * Search the bitmap for a free descriptor starting at minfd. |
| 1914 | * If none is found, grow the file table. |
| 1915 | */ |
| 1916 | fd = fd_first_free(fdp, minfd, fdp->fd_nfiles); |
| 1917 | if (__predict_false(fd >= maxfd)) |
| 1918 | return (EMFILE); |
| 1919 | if (__predict_false(fd >= fdp->fd_nfiles)) { |
| 1920 | allocfd = min(fd * 2, maxfd); |
| 1921 | #ifdef RACCT |
| 1922 | if (RACCT_ENABLED()) { |
| 1923 | error = racct_set_unlocked(p, RACCT_NOFILE, allocfd); |
| 1924 | if (error != 0) |
| 1925 | return (EMFILE); |
| 1926 | } |
| 1927 | #endif |
| 1928 | /* |
| 1929 | * fd is already equal to first free descriptor >= minfd, so |
| 1930 | * we only need to grow the table and we are done. |
| 1931 | */ |
| 1932 | fdgrowtable_exp(fdp, allocfd); |
| 1933 | } |
| 1934 | |
| 1935 | /* |
| 1936 | * Perform some sanity checks, then mark the file descriptor as |
| 1937 | * used and return it to the caller. |
| 1938 | */ |
| 1939 | KASSERT(fd >= 0 && fd < min(maxfd, fdp->fd_nfiles), |
| 1940 | ("invalid descriptor %d", fd)); |
| 1941 | KASSERT(!fdisused(fdp, fd), |
| 1942 | ("fd_first_free() returned non-free descriptor")); |
| 1943 | KASSERT(fdp->fd_ofiles[fd].fde_file == NULL, |
| 1944 | ("file descriptor isn't free")); |
| 1945 | fdused(fdp, fd); |
| 1946 | *result = fd; |
| 1947 | return (0); |
| 1948 | } |
| 1949 | |
| 1950 | /* |
| 1951 | * Allocate n file descriptors for the process. |
no test coverage detected