* Build a new filedesc structure from another. * * If fdp is not NULL, return with it shared locked. */
| 2122 | * If fdp is not NULL, return with it shared locked. |
| 2123 | */ |
| 2124 | struct filedesc * |
| 2125 | fdinit(struct filedesc *fdp, bool prepfiles, int *lastfile) |
| 2126 | { |
| 2127 | struct filedesc0 *newfdp0; |
| 2128 | struct filedesc *newfdp; |
| 2129 | |
| 2130 | if (prepfiles) |
| 2131 | MPASS(lastfile != NULL); |
| 2132 | else |
| 2133 | MPASS(lastfile == NULL); |
| 2134 | |
| 2135 | newfdp0 = uma_zalloc(filedesc0_zone, M_WAITOK | M_ZERO); |
| 2136 | newfdp = &newfdp0->fd_fd; |
| 2137 | |
| 2138 | /* Create the file descriptor table. */ |
| 2139 | FILEDESC_LOCK_INIT(newfdp); |
| 2140 | refcount_init(&newfdp->fd_refcnt, 1); |
| 2141 | refcount_init(&newfdp->fd_holdcnt, 1); |
| 2142 | newfdp->fd_map = newfdp0->fd_dmap; |
| 2143 | newfdp->fd_files = (struct fdescenttbl *)&newfdp0->fd_dfiles; |
| 2144 | newfdp->fd_files->fdt_nfiles = NDFILE; |
| 2145 | |
| 2146 | if (fdp == NULL) |
| 2147 | return (newfdp); |
| 2148 | |
| 2149 | FILEDESC_SLOCK(fdp); |
| 2150 | if (!prepfiles) { |
| 2151 | FILEDESC_SUNLOCK(fdp); |
| 2152 | return (newfdp); |
| 2153 | } |
| 2154 | |
| 2155 | for (;;) { |
| 2156 | *lastfile = fdlastfile(fdp); |
| 2157 | if (*lastfile < newfdp->fd_nfiles) |
| 2158 | break; |
| 2159 | FILEDESC_SUNLOCK(fdp); |
| 2160 | fdgrowtable(newfdp, *lastfile + 1); |
| 2161 | FILEDESC_SLOCK(fdp); |
| 2162 | } |
| 2163 | |
| 2164 | return (newfdp); |
| 2165 | } |
| 2166 | |
| 2167 | /* |
| 2168 | * Build a pwddesc structure from another. |
no test coverage detected