kern_descrip.c (87905) | kern_descrip.c (89306) |
---|---|
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 87905 2001-12-14 19:02:57Z jlemon $ | 39 * $FreeBSD: head/sys/kern/kern_descrip.c 89306 2002-01-13 11:58:06Z alfred $ |
40 */ 41 42#include "opt_compat.h" 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/lock.h> 47#include <sys/malloc.h> --- 56 unchanged lines hidden (view full) --- 104static int badfo_close __P((struct file *fp, struct thread *td)); 105 106/* 107 * Descriptor management. 108 */ 109struct filelist filehead; /* head of list of open files */ 110int nfiles; /* actual number of open files */ 111extern int cmask; | 40 */ 41 42#include "opt_compat.h" 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/lock.h> 47#include <sys/malloc.h> --- 56 unchanged lines hidden (view full) --- 104static int badfo_close __P((struct file *fp, struct thread *td)); 105 106/* 107 * Descriptor management. 108 */ 109struct filelist filehead; /* head of list of open files */ 110int nfiles; /* actual number of open files */ 111extern int cmask; |
112struct sx filelist_lock; /* sx to protect filelist */ |
|
112 113/* 114 * System calls on descriptors. 115 */ 116#ifndef _SYS_SYSPROTO_H_ 117struct getdtablesize_args { 118 int dummy; 119}; --- 38 unchanged lines hidden (view full) --- 158 struct dup2_args *uap; 159{ 160 struct proc *p = td->td_proc; 161 register struct filedesc *fdp = td->td_proc->p_fd; 162 register u_int old = uap->from, new = uap->to; 163 int i, error; 164 165 mtx_lock(&Giant); | 113 114/* 115 * System calls on descriptors. 116 */ 117#ifndef _SYS_SYSPROTO_H_ 118struct getdtablesize_args { 119 int dummy; 120}; --- 38 unchanged lines hidden (view full) --- 159 struct dup2_args *uap; 160{ 161 struct proc *p = td->td_proc; 162 register struct filedesc *fdp = td->td_proc->p_fd; 163 register u_int old = uap->from, new = uap->to; 164 int i, error; 165 166 mtx_lock(&Giant); |
167 FILEDESC_LOCK(fdp); |
|
166retry: 167 if (old >= fdp->fd_nfiles || 168 fdp->fd_ofiles[old] == NULL || 169 new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur || 170 new >= maxfilesperproc) { | 168retry: 169 if (old >= fdp->fd_nfiles || 170 fdp->fd_ofiles[old] == NULL || 171 new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur || 172 new >= maxfilesperproc) { |
173 FILEDESC_UNLOCK(fdp); |
|
171 error = EBADF; 172 goto done2; 173 } 174 if (old == new) { 175 td->td_retval[0] = new; | 174 error = EBADF; 175 goto done2; 176 } 177 if (old == new) { 178 td->td_retval[0] = new; |
179 FILEDESC_UNLOCK(fdp); |
|
176 error = 0; 177 goto done2; 178 } 179 if (new >= fdp->fd_nfiles) { | 180 error = 0; 181 goto done2; 182 } 183 if (new >= fdp->fd_nfiles) { |
180 if ((error = fdalloc(td, new, &i))) | 184 if ((error = fdalloc(td, new, &i))) { 185 FILEDESC_UNLOCK(fdp); |
181 goto done2; | 186 goto done2; |
187 } |
|
182 if (new != i) 183 panic("dup2: fdalloc"); 184 /* 185 * fdalloc() may block, retest everything. 186 */ 187 goto retry; 188 } 189 error = do_dup(fdp, (int)old, (int)new, td->td_retval, td); --- 21 unchanged lines hidden (view full) --- 211{ 212 register struct filedesc *fdp; 213 u_int old; 214 int new, error; 215 216 mtx_lock(&Giant); 217 old = uap->fd; 218 fdp = td->td_proc->p_fd; | 188 if (new != i) 189 panic("dup2: fdalloc"); 190 /* 191 * fdalloc() may block, retest everything. 192 */ 193 goto retry; 194 } 195 error = do_dup(fdp, (int)old, (int)new, td->td_retval, td); --- 21 unchanged lines hidden (view full) --- 217{ 218 register struct filedesc *fdp; 219 u_int old; 220 int new, error; 221 222 mtx_lock(&Giant); 223 old = uap->fd; 224 fdp = td->td_proc->p_fd; |
225 FILEDESC_LOCK(fdp); |
|
219 if (old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL) { | 226 if (old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL) { |
227 FILEDESC_UNLOCK(fdp); |
|
220 error = EBADF; 221 goto done2; 222 } | 228 error = EBADF; 229 goto done2; 230 } |
223 if ((error = fdalloc(td, 0, &new))) | 231 if ((error = fdalloc(td, 0, &new))) { 232 FILEDESC_UNLOCK(fdp); |
224 goto done2; | 233 goto done2; |
234 } |
|
225 error = do_dup(fdp, (int)old, new, td->td_retval, td); 226done2: 227 mtx_unlock(&Giant); 228 return (error); 229} 230 231/* 232 * The file control system call. --- 17 unchanged lines hidden (view full) --- 250 register struct proc *p = td->td_proc; 251 register struct filedesc *fdp; 252 register struct file *fp; 253 register char *pop; 254 struct vnode *vp; 255 int i, tmp, error = 0, flg = F_POSIX; 256 struct flock fl; 257 u_int newmin; | 235 error = do_dup(fdp, (int)old, new, td->td_retval, td); 236done2: 237 mtx_unlock(&Giant); 238 return (error); 239} 240 241/* 242 * The file control system call. --- 17 unchanged lines hidden (view full) --- 260 register struct proc *p = td->td_proc; 261 register struct filedesc *fdp; 262 register struct file *fp; 263 register char *pop; 264 struct vnode *vp; 265 int i, tmp, error = 0, flg = F_POSIX; 266 struct flock fl; 267 u_int newmin; |
268 struct proc *leaderp; |
|
258 259 mtx_lock(&Giant); 260 261 fdp = p->p_fd; | 269 270 mtx_lock(&Giant); 271 272 fdp = p->p_fd; |
273 FILEDESC_LOCK(fdp); |
|
262 if ((unsigned)uap->fd >= fdp->fd_nfiles || 263 (fp = fdp->fd_ofiles[uap->fd]) == NULL) { | 274 if ((unsigned)uap->fd >= fdp->fd_nfiles || 275 (fp = fdp->fd_ofiles[uap->fd]) == NULL) { |
276 FILEDESC_UNLOCK(fdp); |
|
264 error = EBADF; 265 goto done2; 266 } 267 pop = &fdp->fd_ofileflags[uap->fd]; 268 269 switch (uap->cmd) { 270 case F_DUPFD: 271 newmin = uap->arg; 272 if (newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur || 273 newmin >= maxfilesperproc) { | 277 error = EBADF; 278 goto done2; 279 } 280 pop = &fdp->fd_ofileflags[uap->fd]; 281 282 switch (uap->cmd) { 283 case F_DUPFD: 284 newmin = uap->arg; 285 if (newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur || 286 newmin >= maxfilesperproc) { |
287 FILEDESC_UNLOCK(fdp); |
|
274 error = EINVAL; 275 break; 276 } | 288 error = EINVAL; 289 break; 290 } |
277 if ((error = fdalloc(td, newmin, &i))) | 291 if ((error = fdalloc(td, newmin, &i))) { 292 FILEDESC_UNLOCK(fdp); |
278 break; | 293 break; |
294 } |
|
279 error = do_dup(fdp, uap->fd, i, td->td_retval, td); 280 break; 281 282 case F_GETFD: 283 td->td_retval[0] = *pop & 1; | 295 error = do_dup(fdp, uap->fd, i, td->td_retval, td); 296 break; 297 298 case F_GETFD: 299 td->td_retval[0] = *pop & 1; |
300 FILEDESC_UNLOCK(fdp); |
|
284 break; 285 286 case F_SETFD: 287 *pop = (*pop &~ 1) | (uap->arg & 1); | 301 break; 302 303 case F_SETFD: 304 *pop = (*pop &~ 1) | (uap->arg & 1); |
305 FILEDESC_UNLOCK(fdp); |
|
288 break; 289 290 case F_GETFL: | 306 break; 307 308 case F_GETFL: |
309 FILE_LOCK(fp); 310 FILEDESC_UNLOCK(fdp); |
|
291 td->td_retval[0] = OFLAGS(fp->f_flag); | 311 td->td_retval[0] = OFLAGS(fp->f_flag); |
312 FILE_UNLOCK(fp); |
|
292 break; 293 294 case F_SETFL: 295 fhold(fp); | 313 break; 314 315 case F_SETFL: 316 fhold(fp); |
317 FILEDESC_UNLOCK(fdp); |
|
296 fp->f_flag &= ~FCNTLFLAGS; 297 fp->f_flag |= FFLAGS(uap->arg & ~O_ACCMODE) & FCNTLFLAGS; 298 tmp = fp->f_flag & FNONBLOCK; 299 error = fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, td); 300 if (error) { 301 fdrop(fp, td); 302 break; 303 } --- 6 unchanged lines hidden (view full) --- 310 fp->f_flag &= ~FNONBLOCK; 311 tmp = 0; 312 (void)fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, td); 313 fdrop(fp, td); 314 break; 315 316 case F_GETOWN: 317 fhold(fp); | 318 fp->f_flag &= ~FCNTLFLAGS; 319 fp->f_flag |= FFLAGS(uap->arg & ~O_ACCMODE) & FCNTLFLAGS; 320 tmp = fp->f_flag & FNONBLOCK; 321 error = fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, td); 322 if (error) { 323 fdrop(fp, td); 324 break; 325 } --- 6 unchanged lines hidden (view full) --- 332 fp->f_flag &= ~FNONBLOCK; 333 tmp = 0; 334 (void)fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, td); 335 fdrop(fp, td); 336 break; 337 338 case F_GETOWN: 339 fhold(fp); |
340 FILEDESC_UNLOCK(fdp); |
|
318 error = fo_ioctl(fp, FIOGETOWN, (caddr_t)td->td_retval, td); 319 fdrop(fp, td); 320 break; 321 322 case F_SETOWN: 323 fhold(fp); | 341 error = fo_ioctl(fp, FIOGETOWN, (caddr_t)td->td_retval, td); 342 fdrop(fp, td); 343 break; 344 345 case F_SETOWN: 346 fhold(fp); |
347 FILEDESC_UNLOCK(fdp); |
|
324 error = fo_ioctl(fp, FIOSETOWN, (caddr_t)&uap->arg, td); 325 fdrop(fp, td); 326 break; 327 328 case F_SETLKW: 329 flg |= F_WAIT; 330 /* Fall into F_SETLK */ 331 332 case F_SETLK: 333 if (fp->f_type != DTYPE_VNODE) { | 348 error = fo_ioctl(fp, FIOSETOWN, (caddr_t)&uap->arg, td); 349 fdrop(fp, td); 350 break; 351 352 case F_SETLKW: 353 flg |= F_WAIT; 354 /* Fall into F_SETLK */ 355 356 case F_SETLK: 357 if (fp->f_type != DTYPE_VNODE) { |
358 FILEDESC_UNLOCK(fdp); |
|
334 error = EBADF; 335 break; 336 } 337 vp = (struct vnode *)fp->f_data; | 359 error = EBADF; 360 break; 361 } 362 vp = (struct vnode *)fp->f_data; |
338 | |
339 /* 340 * copyin/lockop may block 341 */ 342 fhold(fp); | 363 /* 364 * copyin/lockop may block 365 */ 366 fhold(fp); |
367 FILEDESC_UNLOCK(fdp); 368 vp = (struct vnode *)fp->f_data; 369 |
|
343 /* Copy in the lock structure */ 344 error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl, 345 sizeof(fl)); 346 if (error) { 347 fdrop(fp, td); 348 break; 349 } 350 if (fl.l_whence == SEEK_CUR) { --- 8 unchanged lines hidden (view full) --- 359 } 360 361 switch (fl.l_type) { 362 case F_RDLCK: 363 if ((fp->f_flag & FREAD) == 0) { 364 error = EBADF; 365 break; 366 } | 370 /* Copy in the lock structure */ 371 error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl, 372 sizeof(fl)); 373 if (error) { 374 fdrop(fp, td); 375 break; 376 } 377 if (fl.l_whence == SEEK_CUR) { --- 8 unchanged lines hidden (view full) --- 386 } 387 388 switch (fl.l_type) { 389 case F_RDLCK: 390 if ((fp->f_flag & FREAD) == 0) { 391 error = EBADF; 392 break; 393 } |
394 PROC_LOCK(p); |
|
367 p->p_flag |= P_ADVLOCK; | 395 p->p_flag |= P_ADVLOCK; |
368 error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK, | 396 leaderp = p->p_leader; 397 PROC_UNLOCK(p); 398 error = VOP_ADVLOCK(vp, (caddr_t)leaderp, F_SETLK, |
369 &fl, flg); 370 break; 371 case F_WRLCK: 372 if ((fp->f_flag & FWRITE) == 0) { 373 error = EBADF; 374 break; 375 } | 399 &fl, flg); 400 break; 401 case F_WRLCK: 402 if ((fp->f_flag & FWRITE) == 0) { 403 error = EBADF; 404 break; 405 } |
406 PROC_LOCK(p); |
|
376 p->p_flag |= P_ADVLOCK; | 407 p->p_flag |= P_ADVLOCK; |
377 error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK, | 408 leaderp = p->p_leader; 409 PROC_UNLOCK(p); 410 error = VOP_ADVLOCK(vp, (caddr_t)leaderp, F_SETLK, |
378 &fl, flg); 379 break; 380 case F_UNLCK: | 411 &fl, flg); 412 break; 413 case F_UNLCK: |
381 error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_UNLCK, | 414 PROC_LOCK(p); 415 leaderp = p->p_leader; 416 PROC_UNLOCK(p); 417 error = VOP_ADVLOCK(vp, (caddr_t)leaderp, F_UNLCK, |
382 &fl, F_POSIX); 383 break; 384 default: 385 error = EINVAL; 386 break; 387 } 388 fdrop(fp, td); 389 break; 390 391 case F_GETLK: 392 if (fp->f_type != DTYPE_VNODE) { | 418 &fl, F_POSIX); 419 break; 420 default: 421 error = EINVAL; 422 break; 423 } 424 fdrop(fp, td); 425 break; 426 427 case F_GETLK: 428 if (fp->f_type != DTYPE_VNODE) { |
429 FILEDESC_UNLOCK(fdp); |
|
393 error = EBADF; 394 break; 395 } 396 vp = (struct vnode *)fp->f_data; 397 /* 398 * copyin/lockop may block 399 */ 400 fhold(fp); | 430 error = EBADF; 431 break; 432 } 433 vp = (struct vnode *)fp->f_data; 434 /* 435 * copyin/lockop may block 436 */ 437 fhold(fp); |
438 FILEDESC_UNLOCK(fdp); 439 vp = (struct vnode *)fp->f_data; 440 |
|
401 /* Copy in the lock structure */ 402 error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl, 403 sizeof(fl)); 404 if (error) { 405 fdrop(fp, td); 406 break; 407 } 408 if (fl.l_type != F_RDLCK && fl.l_type != F_WRLCK && --- 17 unchanged lines hidden (view full) --- 426 &fl, F_POSIX); 427 fdrop(fp, td); 428 if (error == 0) { 429 error = copyout((caddr_t)&fl, 430 (caddr_t)(intptr_t)uap->arg, sizeof(fl)); 431 } 432 break; 433 default: | 441 /* Copy in the lock structure */ 442 error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl, 443 sizeof(fl)); 444 if (error) { 445 fdrop(fp, td); 446 break; 447 } 448 if (fl.l_type != F_RDLCK && fl.l_type != F_WRLCK && --- 17 unchanged lines hidden (view full) --- 466 &fl, F_POSIX); 467 fdrop(fp, td); 468 if (error == 0) { 469 error = copyout((caddr_t)&fl, 470 (caddr_t)(intptr_t)uap->arg, sizeof(fl)); 471 } 472 break; 473 default: |
474 FILEDESC_UNLOCK(fdp); |
|
434 error = EINVAL; 435 break; 436 } 437done2: 438 mtx_unlock(&Giant); 439 return (error); 440} 441 442/* 443 * Common code for dup, dup2, and fcntl(F_DUPFD). | 475 error = EINVAL; 476 break; 477 } 478done2: 479 mtx_unlock(&Giant); 480 return (error); 481} 482 483/* 484 * Common code for dup, dup2, and fcntl(F_DUPFD). |
485 * filedesc must be locked, but will be unlocked as a side effect. |
|
444 */ 445static int 446do_dup(fdp, old, new, retval, td) 447 register struct filedesc *fdp; 448 register int old, new; 449 register_t *retval; 450 struct thread *td; 451{ 452 struct file *fp; 453 struct file *delfp; 454 | 486 */ 487static int 488do_dup(fdp, old, new, retval, td) 489 register struct filedesc *fdp; 490 register int old, new; 491 register_t *retval; 492 struct thread *td; 493{ 494 struct file *fp; 495 struct file *delfp; 496 |
497 FILEDESC_LOCK_ASSERT(fdp, MA_OWNED); 498 |
|
455 /* 456 * Save info on the descriptor being overwritten. We have 457 * to do the unmap now, but we cannot close it without 458 * introducing an ownership race for the slot. 459 */ 460 delfp = fdp->fd_ofiles[new]; 461#if 0 462 if (delfp && (fdp->fd_ofileflags[new] & UF_MAPPED)) --- 6 unchanged lines hidden (view full) --- 469 fp = fdp->fd_ofiles[old]; 470 fdp->fd_ofiles[new] = fp; 471 fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE; 472 fhold(fp); 473 if (new > fdp->fd_lastfile) 474 fdp->fd_lastfile = new; 475 *retval = new; 476 | 499 /* 500 * Save info on the descriptor being overwritten. We have 501 * to do the unmap now, but we cannot close it without 502 * introducing an ownership race for the slot. 503 */ 504 delfp = fdp->fd_ofiles[new]; 505#if 0 506 if (delfp && (fdp->fd_ofileflags[new] & UF_MAPPED)) --- 6 unchanged lines hidden (view full) --- 513 fp = fdp->fd_ofiles[old]; 514 fdp->fd_ofiles[new] = fp; 515 fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE; 516 fhold(fp); 517 if (new > fdp->fd_lastfile) 518 fdp->fd_lastfile = new; 519 *retval = new; 520 |
521 FILEDESC_UNLOCK(fdp); 522 |
|
477 /* 478 * If we dup'd over a valid file, we now own the reference to it 479 * and must dispose of it using closef() semantics (as if a 480 * close() were performed on it). 481 */ 482 if (delfp) 483 (void) closef(delfp, td); 484 return (0); --- 142 unchanged lines hidden (view full) --- 627{ 628 register struct filedesc *fdp; 629 register struct file *fp; 630 register int fd = uap->fd; 631 int error = 0; 632 633 mtx_lock(&Giant); 634 fdp = td->td_proc->p_fd; | 523 /* 524 * If we dup'd over a valid file, we now own the reference to it 525 * and must dispose of it using closef() semantics (as if a 526 * close() were performed on it). 527 */ 528 if (delfp) 529 (void) closef(delfp, td); 530 return (0); --- 142 unchanged lines hidden (view full) --- 673{ 674 register struct filedesc *fdp; 675 register struct file *fp; 676 register int fd = uap->fd; 677 int error = 0; 678 679 mtx_lock(&Giant); 680 fdp = td->td_proc->p_fd; |
681 FILEDESC_LOCK(fdp); |
|
635 if ((unsigned)fd >= fdp->fd_nfiles || 636 (fp = fdp->fd_ofiles[fd]) == NULL) { | 682 if ((unsigned)fd >= fdp->fd_nfiles || 683 (fp = fdp->fd_ofiles[fd]) == NULL) { |
684 FILEDESC_UNLOCK(fdp); |
|
637 error = EBADF; 638 goto done2; 639 } 640#if 0 641 if (fdp->fd_ofileflags[fd] & UF_MAPPED) 642 (void) munmapfd(td, fd); 643#endif 644 fdp->fd_ofiles[fd] = NULL; 645 fdp->fd_ofileflags[fd] = 0; 646 647 /* 648 * we now hold the fp reference that used to be owned by the descriptor 649 * array. 650 */ 651 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 652 fdp->fd_lastfile--; 653 if (fd < fdp->fd_freefile) 654 fdp->fd_freefile = fd; | 685 error = EBADF; 686 goto done2; 687 } 688#if 0 689 if (fdp->fd_ofileflags[fd] & UF_MAPPED) 690 (void) munmapfd(td, fd); 691#endif 692 fdp->fd_ofiles[fd] = NULL; 693 fdp->fd_ofileflags[fd] = 0; 694 695 /* 696 * we now hold the fp reference that used to be owned by the descriptor 697 * array. 698 */ 699 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 700 fdp->fd_lastfile--; 701 if (fd < fdp->fd_freefile) 702 fdp->fd_freefile = fd; |
655 if (fd < fdp->fd_knlistsize) | 703 if (fd < fdp->fd_knlistsize) { 704 FILEDESC_UNLOCK(fdp); |
656 knote_fdclose(td, fd); | 705 knote_fdclose(td, fd); |
706 } else 707 FILEDESC_UNLOCK(fdp); 708 |
|
657 error = closef(fp, td); 658done2: 659 mtx_unlock(&Giant); 660 return(error); 661} 662 663#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 664/* --- 86 unchanged lines hidden (view full) --- 751 struct thread *td; 752 register struct nfstat_args *uap; 753{ 754 struct file *fp; 755 struct stat ub; 756 struct nstat nub; 757 int error; 758 | 709 error = closef(fp, td); 710done2: 711 mtx_unlock(&Giant); 712 return(error); 713} 714 715#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 716/* --- 86 unchanged lines hidden (view full) --- 803 struct thread *td; 804 register struct nfstat_args *uap; 805{ 806 struct file *fp; 807 struct stat ub; 808 struct nstat nub; 809 int error; 810 |
759 mtx_lock(&Giant); | |
760 if ((error = fget(td, uap->fd, &fp)) != 0) 761 goto done2; 762 error = fo_stat(fp, &ub, td); 763 if (error == 0) { 764 cvtnstat(&ub, &nub); 765 error = copyout((caddr_t)&nub, (caddr_t)uap->sb, sizeof (nub)); 766 } 767 fdrop(fp, td); --- 19 unchanged lines hidden (view full) --- 787fpathconf(td, uap) 788 struct thread *td; 789 register struct fpathconf_args *uap; 790{ 791 struct file *fp; 792 struct vnode *vp; 793 int error; 794 | 811 if ((error = fget(td, uap->fd, &fp)) != 0) 812 goto done2; 813 error = fo_stat(fp, &ub, td); 814 if (error == 0) { 815 cvtnstat(&ub, &nub); 816 error = copyout((caddr_t)&nub, (caddr_t)uap->sb, sizeof (nub)); 817 } 818 fdrop(fp, td); --- 19 unchanged lines hidden (view full) --- 838fpathconf(td, uap) 839 struct thread *td; 840 register struct fpathconf_args *uap; 841{ 842 struct file *fp; 843 struct vnode *vp; 844 int error; 845 |
846 fp = ffind_hold(td, uap->fd); 847 if (fp == NULL) 848 return (EBADF); |
|
795 mtx_lock(&Giant); 796 if ((error = fget(td, uap->fd, &fp)) != 0) 797 goto done2; 798 799 switch (fp->f_type) { 800 case DTYPE_PIPE: 801 case DTYPE_SOCKET: 802 if (uap->name != _PC_PIPE_BUF) { | 849 mtx_lock(&Giant); 850 if ((error = fget(td, uap->fd, &fp)) != 0) 851 goto done2; 852 853 switch (fp->f_type) { 854 case DTYPE_PIPE: 855 case DTYPE_SOCKET: 856 if (uap->name != _PC_PIPE_BUF) { |
857 fdrop(fp, td); |
|
803 error = EINVAL; 804 goto done2; 805 } 806 td->td_retval[0] = PIPE_BUF; 807 error = 0; 808 break; 809 case DTYPE_FIFO: 810 case DTYPE_VNODE: --- 21 unchanged lines hidden (view full) --- 832 struct thread *td; 833 int want; 834 int *result; 835{ 836 struct proc *p = td->td_proc; 837 register struct filedesc *fdp = td->td_proc->p_fd; 838 register int i; 839 int lim, last, nfiles; | 858 error = EINVAL; 859 goto done2; 860 } 861 td->td_retval[0] = PIPE_BUF; 862 error = 0; 863 break; 864 case DTYPE_FIFO: 865 case DTYPE_VNODE: --- 21 unchanged lines hidden (view full) --- 887 struct thread *td; 888 int want; 889 int *result; 890{ 891 struct proc *p = td->td_proc; 892 register struct filedesc *fdp = td->td_proc->p_fd; 893 register int i; 894 int lim, last, nfiles; |
840 struct file **newofile; | 895 struct file **newofile, **oldofile; |
841 char *newofileflags; 842 | 896 char *newofileflags; 897 |
898 FILEDESC_LOCK_ASSERT(fdp, MA_OWNED); 899 |
|
843 /* 844 * Search for a free descriptor starting at the higher 845 * of want or fd_freefile. If that fails, consider 846 * expanding the ofile array. 847 */ 848 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc); 849 for (;;) { 850 last = min(fdp->fd_nfiles, lim); --- 15 unchanged lines hidden (view full) --- 866 * No space in current array. Expand? 867 */ 868 if (fdp->fd_nfiles >= lim) 869 return (EMFILE); 870 if (fdp->fd_nfiles < NDEXTENT) 871 nfiles = NDEXTENT; 872 else 873 nfiles = 2 * fdp->fd_nfiles; | 900 /* 901 * Search for a free descriptor starting at the higher 902 * of want or fd_freefile. If that fails, consider 903 * expanding the ofile array. 904 */ 905 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc); 906 for (;;) { 907 last = min(fdp->fd_nfiles, lim); --- 15 unchanged lines hidden (view full) --- 923 * No space in current array. Expand? 924 */ 925 if (fdp->fd_nfiles >= lim) 926 return (EMFILE); 927 if (fdp->fd_nfiles < NDEXTENT) 928 nfiles = NDEXTENT; 929 else 930 nfiles = 2 * fdp->fd_nfiles; |
931 FILEDESC_UNLOCK(fdp); |
|
874 MALLOC(newofile, struct file **, nfiles * OFILESIZE, 875 M_FILEDESC, M_WAITOK); | 932 MALLOC(newofile, struct file **, nfiles * OFILESIZE, 933 M_FILEDESC, M_WAITOK); |
934 FILEDESC_LOCK(fdp); |
|
876 877 /* 878 * deal with file-table extend race that might have occured 879 * when malloc was blocked. 880 */ 881 if (fdp->fd_nfiles >= nfiles) { | 935 936 /* 937 * deal with file-table extend race that might have occured 938 * when malloc was blocked. 939 */ 940 if (fdp->fd_nfiles >= nfiles) { |
941 FILEDESC_UNLOCK(fdp); |
|
882 FREE(newofile, M_FILEDESC); | 942 FREE(newofile, M_FILEDESC); |
943 FILEDESC_LOCK(fdp); |
|
883 continue; 884 } 885 newofileflags = (char *) &newofile[nfiles]; 886 /* 887 * Copy the existing ofile and ofileflags arrays 888 * and zero the new portion of each array. 889 */ 890 bcopy(fdp->fd_ofiles, newofile, 891 (i = sizeof(struct file *) * fdp->fd_nfiles)); 892 bzero((char *)newofile + i, nfiles * sizeof(struct file *) - i); 893 bcopy(fdp->fd_ofileflags, newofileflags, 894 (i = sizeof(char) * fdp->fd_nfiles)); 895 bzero(newofileflags + i, nfiles * sizeof(char) - i); 896 if (fdp->fd_nfiles > NDFILE) | 944 continue; 945 } 946 newofileflags = (char *) &newofile[nfiles]; 947 /* 948 * Copy the existing ofile and ofileflags arrays 949 * and zero the new portion of each array. 950 */ 951 bcopy(fdp->fd_ofiles, newofile, 952 (i = sizeof(struct file *) * fdp->fd_nfiles)); 953 bzero((char *)newofile + i, nfiles * sizeof(struct file *) - i); 954 bcopy(fdp->fd_ofileflags, newofileflags, 955 (i = sizeof(char) * fdp->fd_nfiles)); 956 bzero(newofileflags + i, nfiles * sizeof(char) - i); 957 if (fdp->fd_nfiles > NDFILE) |
897 FREE(fdp->fd_ofiles, M_FILEDESC); | 958 oldofile = fdp->fd_ofiles; 959 else 960 oldofile = NULL; |
898 fdp->fd_ofiles = newofile; 899 fdp->fd_ofileflags = newofileflags; 900 fdp->fd_nfiles = nfiles; 901 fdexpand++; | 961 fdp->fd_ofiles = newofile; 962 fdp->fd_ofileflags = newofileflags; 963 fdp->fd_nfiles = nfiles; 964 fdexpand++; |
965 if (oldofile != NULL) 966 FREE(oldofile, M_FILEDESC); |
|
902 } 903 return (0); 904} 905 906/* 907 * Check to see whether n user file descriptors 908 * are available to the process p. 909 */ 910int 911fdavail(td, n) 912 struct thread *td; 913 register int n; 914{ 915 struct proc *p = td->td_proc; 916 register struct filedesc *fdp = td->td_proc->p_fd; 917 register struct file **fpp; 918 register int i, lim, last; 919 | 967 } 968 return (0); 969} 970 971/* 972 * Check to see whether n user file descriptors 973 * are available to the process p. 974 */ 975int 976fdavail(td, n) 977 struct thread *td; 978 register int n; 979{ 980 struct proc *p = td->td_proc; 981 register struct filedesc *fdp = td->td_proc->p_fd; 982 register struct file **fpp; 983 register int i, lim, last; 984 |
985 FILEDESC_LOCK_ASSERT(fdp, MA_OWNED); 986 |
|
920 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc); 921 if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0) 922 return (1); 923 924 last = min(fdp->fd_nfiles, lim); 925 fpp = &fdp->fd_ofiles[fdp->fd_freefile]; 926 for (i = last - fdp->fd_freefile; --i >= 0; fpp++) { 927 if (*fpp == NULL && --n <= 0) --- 11 unchanged lines hidden (view full) --- 939 register struct thread *td; 940 struct file **resultfp; 941 int *resultfd; 942{ 943 struct proc *p = td->td_proc; 944 register struct file *fp, *fq; 945 int error, i; 946 | 987 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc); 988 if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0) 989 return (1); 990 991 last = min(fdp->fd_nfiles, lim); 992 fpp = &fdp->fd_ofiles[fdp->fd_freefile]; 993 for (i = last - fdp->fd_freefile; --i >= 0; fpp++) { 994 if (*fpp == NULL && --n <= 0) --- 11 unchanged lines hidden (view full) --- 1006 register struct thread *td; 1007 struct file **resultfp; 1008 int *resultfd; 1009{ 1010 struct proc *p = td->td_proc; 1011 register struct file *fp, *fq; 1012 int error, i; 1013 |
1014 sx_xlock(&filelist_lock); |
|
947 if (nfiles >= maxfiles) { | 1015 if (nfiles >= maxfiles) { |
1016 sx_xunlock(&filelist_lock); |
|
948 tablefull("file"); 949 return (ENFILE); 950 } | 1017 tablefull("file"); 1018 return (ENFILE); 1019 } |
1020 nfiles++; 1021 sx_xunlock(&filelist_lock); |
|
951 /* 952 * Allocate a new file descriptor. 953 * If the process has file descriptor zero open, add to the list 954 * of open files at that point, otherwise put it at the front of 955 * the list of open files. 956 */ | 1022 /* 1023 * Allocate a new file descriptor. 1024 * If the process has file descriptor zero open, add to the list 1025 * of open files at that point, otherwise put it at the front of 1026 * the list of open files. 1027 */ |
957 nfiles++; | |
958 MALLOC(fp, struct file *, sizeof(struct file), M_FILE, M_WAITOK | M_ZERO); 959 960 /* 961 * wait until after malloc (which may have blocked) returns before 962 * allocating the slot, else a race might have shrunk it if we had 963 * allocated it before the malloc. 964 */ | 1028 MALLOC(fp, struct file *, sizeof(struct file), M_FILE, M_WAITOK | M_ZERO); 1029 1030 /* 1031 * wait until after malloc (which may have blocked) returns before 1032 * allocating the slot, else a race might have shrunk it if we had 1033 * allocated it before the malloc. 1034 */ |
1035 FILEDESC_LOCK(p->p_fd); |
|
965 if ((error = fdalloc(td, 0, &i))) { | 1036 if ((error = fdalloc(td, 0, &i))) { |
1037 FILEDESC_UNLOCK(p->p_fd); 1038 sx_xlock(&filelist_lock); |
|
966 nfiles--; | 1039 nfiles--; |
1040 sx_xunlock(&filelist_lock); |
|
967 FREE(fp, M_FILE); 968 return (error); 969 } | 1041 FREE(fp, M_FILE); 1042 return (error); 1043 } |
1044 mtx_init(&fp->f_mtx, "file structure", MTX_DEF); 1045 fp->f_gcflag = 0; |
|
970 fp->f_count = 1; 971 fp->f_cred = crhold(p->p_ucred); 972 fp->f_ops = &badfileops; 973 fp->f_seqcount = 1; | 1046 fp->f_count = 1; 1047 fp->f_cred = crhold(p->p_ucred); 1048 fp->f_ops = &badfileops; 1049 fp->f_seqcount = 1; |
1050 FILEDESC_UNLOCK(p->p_fd); 1051 sx_xlock(&filelist_lock); 1052 FILEDESC_LOCK(p->p_fd); |
|
974 if ((fq = p->p_fd->fd_ofiles[0])) { 975 LIST_INSERT_AFTER(fq, fp, f_list); 976 } else { 977 LIST_INSERT_HEAD(&filehead, fp, f_list); 978 } 979 p->p_fd->fd_ofiles[i] = fp; | 1053 if ((fq = p->p_fd->fd_ofiles[0])) { 1054 LIST_INSERT_AFTER(fq, fp, f_list); 1055 } else { 1056 LIST_INSERT_HEAD(&filehead, fp, f_list); 1057 } 1058 p->p_fd->fd_ofiles[i] = fp; |
1059 FILEDESC_UNLOCK(p->p_fd); 1060 sx_xunlock(&filelist_lock); |
|
980 if (resultfp) 981 *resultfp = fp; 982 if (resultfd) 983 *resultfd = i; 984 return (0); 985} 986 987/* 988 * Free a file descriptor. 989 */ 990void 991ffree(fp) 992 register struct file *fp; 993{ | 1061 if (resultfp) 1062 *resultfp = fp; 1063 if (resultfd) 1064 *resultfd = i; 1065 return (0); 1066} 1067 1068/* 1069 * Free a file descriptor. 1070 */ 1071void 1072ffree(fp) 1073 register struct file *fp; 1074{ |
1075 |
|
994 KASSERT((fp->f_count == 0), ("ffree: fp_fcount not 0!")); | 1076 KASSERT((fp->f_count == 0), ("ffree: fp_fcount not 0!")); |
1077 sx_xlock(&filelist_lock); |
|
995 LIST_REMOVE(fp, f_list); | 1078 LIST_REMOVE(fp, f_list); |
996 crfree(fp->f_cred); | |
997 nfiles--; | 1079 nfiles--; |
1080 sx_xunlock(&filelist_lock); 1081 crfree(fp->f_cred); 1082 mtx_destroy(&fp->f_mtx); |
|
998 FREE(fp, M_FILE); 999} 1000 1001/* 1002 * Build a new filedesc structure. 1003 */ 1004struct filedesc * 1005fdinit(td) 1006 struct thread *td; 1007{ 1008 register struct filedesc0 *newfdp; 1009 register struct filedesc *fdp = td->td_proc->p_fd; 1010 1011 MALLOC(newfdp, struct filedesc0 *, sizeof(struct filedesc0), 1012 M_FILEDESC, M_WAITOK | M_ZERO); | 1083 FREE(fp, M_FILE); 1084} 1085 1086/* 1087 * Build a new filedesc structure. 1088 */ 1089struct filedesc * 1090fdinit(td) 1091 struct thread *td; 1092{ 1093 register struct filedesc0 *newfdp; 1094 register struct filedesc *fdp = td->td_proc->p_fd; 1095 1096 MALLOC(newfdp, struct filedesc0 *, sizeof(struct filedesc0), 1097 M_FILEDESC, M_WAITOK | M_ZERO); |
1098 mtx_init(&newfdp->fd_fd.fd_mtx, "filedesc structure", MTX_DEF); 1099 FILEDESC_LOCK(&newfdp->fd_fd); |
|
1013 newfdp->fd_fd.fd_cdir = fdp->fd_cdir; 1014 if (newfdp->fd_fd.fd_cdir) 1015 VREF(newfdp->fd_fd.fd_cdir); 1016 newfdp->fd_fd.fd_rdir = fdp->fd_rdir; 1017 if (newfdp->fd_fd.fd_rdir) 1018 VREF(newfdp->fd_fd.fd_rdir); 1019 newfdp->fd_fd.fd_jdir = fdp->fd_jdir; 1020 if (newfdp->fd_fd.fd_jdir) 1021 VREF(newfdp->fd_fd.fd_jdir); 1022 1023 /* Create the file descriptor table. */ 1024 newfdp->fd_fd.fd_refcnt = 1; 1025 newfdp->fd_fd.fd_cmask = cmask; 1026 newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles; 1027 newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags; 1028 newfdp->fd_fd.fd_nfiles = NDFILE; 1029 newfdp->fd_fd.fd_knlistsize = -1; | 1100 newfdp->fd_fd.fd_cdir = fdp->fd_cdir; 1101 if (newfdp->fd_fd.fd_cdir) 1102 VREF(newfdp->fd_fd.fd_cdir); 1103 newfdp->fd_fd.fd_rdir = fdp->fd_rdir; 1104 if (newfdp->fd_fd.fd_rdir) 1105 VREF(newfdp->fd_fd.fd_rdir); 1106 newfdp->fd_fd.fd_jdir = fdp->fd_jdir; 1107 if (newfdp->fd_fd.fd_jdir) 1108 VREF(newfdp->fd_fd.fd_jdir); 1109 1110 /* Create the file descriptor table. */ 1111 newfdp->fd_fd.fd_refcnt = 1; 1112 newfdp->fd_fd.fd_cmask = cmask; 1113 newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles; 1114 newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags; 1115 newfdp->fd_fd.fd_nfiles = NDFILE; 1116 newfdp->fd_fd.fd_knlistsize = -1; |
1117 FILEDESC_UNLOCK(&newfdp->fd_fd); |
|
1030 1031 return (&newfdp->fd_fd); 1032} 1033 1034/* 1035 * Share a filedesc structure. 1036 */ 1037struct filedesc * 1038fdshare(p) 1039 struct proc *p; 1040{ | 1118 1119 return (&newfdp->fd_fd); 1120} 1121 1122/* 1123 * Share a filedesc structure. 1124 */ 1125struct filedesc * 1126fdshare(p) 1127 struct proc *p; 1128{ |
1129 FILEDESC_LOCK(p->p_fd); |
|
1041 p->p_fd->fd_refcnt++; | 1130 p->p_fd->fd_refcnt++; |
1131 FILEDESC_UNLOCK(p->p_fd); |
|
1042 return (p->p_fd); 1043} 1044 1045/* 1046 * Copy a filedesc structure. 1047 */ 1048struct filedesc * 1049fdcopy(td) 1050 struct thread *td; 1051{ 1052 register struct filedesc *newfdp, *fdp = td->td_proc->p_fd; 1053 register struct file **fpp; | 1132 return (p->p_fd); 1133} 1134 1135/* 1136 * Copy a filedesc structure. 1137 */ 1138struct filedesc * 1139fdcopy(td) 1140 struct thread *td; 1141{ 1142 register struct filedesc *newfdp, *fdp = td->td_proc->p_fd; 1143 register struct file **fpp; |
1054 register int i; | 1144 register int i, j; |
1055 1056 /* Certain daemons might not have file descriptors. */ 1057 if (fdp == NULL) 1058 return (NULL); 1059 | 1145 1146 /* Certain daemons might not have file descriptors. */ 1147 if (fdp == NULL) 1148 return (NULL); 1149 |
1150 FILEDESC_LOCK_ASSERT(fdp, MA_OWNED); 1151 1152 FILEDESC_UNLOCK(fdp); |
|
1060 MALLOC(newfdp, struct filedesc *, sizeof(struct filedesc0), 1061 M_FILEDESC, M_WAITOK); | 1153 MALLOC(newfdp, struct filedesc *, sizeof(struct filedesc0), 1154 M_FILEDESC, M_WAITOK); |
1155 FILEDESC_LOCK(fdp); |
|
1062 bcopy(fdp, newfdp, sizeof(struct filedesc)); | 1156 bcopy(fdp, newfdp, sizeof(struct filedesc)); |
1157 FILEDESC_UNLOCK(fdp); 1158 bzero(&newfdp->fd_mtx, sizeof(newfdp->fd_mtx)); 1159 mtx_init(&newfdp->fd_mtx, "filedesc structure", MTX_DEF); |
|
1063 if (newfdp->fd_cdir) 1064 VREF(newfdp->fd_cdir); 1065 if (newfdp->fd_rdir) 1066 VREF(newfdp->fd_rdir); 1067 if (newfdp->fd_jdir) 1068 VREF(newfdp->fd_jdir); 1069 newfdp->fd_refcnt = 1; 1070 1071 /* 1072 * If the number of open files fits in the internal arrays 1073 * of the open file structure, use them, otherwise allocate 1074 * additional memory for the number of descriptors currently 1075 * in use. 1076 */ | 1160 if (newfdp->fd_cdir) 1161 VREF(newfdp->fd_cdir); 1162 if (newfdp->fd_rdir) 1163 VREF(newfdp->fd_rdir); 1164 if (newfdp->fd_jdir) 1165 VREF(newfdp->fd_jdir); 1166 newfdp->fd_refcnt = 1; 1167 1168 /* 1169 * If the number of open files fits in the internal arrays 1170 * of the open file structure, use them, otherwise allocate 1171 * additional memory for the number of descriptors currently 1172 * in use. 1173 */ |
1174 FILEDESC_LOCK(fdp); 1175 newfdp->fd_lastfile = fdp->fd_lastfile; 1176 newfdp->fd_nfiles = fdp->fd_nfiles; |
|
1077 if (newfdp->fd_lastfile < NDFILE) { 1078 newfdp->fd_ofiles = ((struct filedesc0 *) newfdp)->fd_dfiles; 1079 newfdp->fd_ofileflags = 1080 ((struct filedesc0 *) newfdp)->fd_dfileflags; 1081 i = NDFILE; 1082 } else { 1083 /* 1084 * Compute the smallest multiple of NDEXTENT needed 1085 * for the file descriptors currently in use, 1086 * allowing the table to shrink. 1087 */ | 1177 if (newfdp->fd_lastfile < NDFILE) { 1178 newfdp->fd_ofiles = ((struct filedesc0 *) newfdp)->fd_dfiles; 1179 newfdp->fd_ofileflags = 1180 ((struct filedesc0 *) newfdp)->fd_dfileflags; 1181 i = NDFILE; 1182 } else { 1183 /* 1184 * Compute the smallest multiple of NDEXTENT needed 1185 * for the file descriptors currently in use, 1186 * allowing the table to shrink. 1187 */ |
1188retry: |
|
1088 i = newfdp->fd_nfiles; 1089 while (i > 2 * NDEXTENT && i > newfdp->fd_lastfile * 2) 1090 i /= 2; | 1189 i = newfdp->fd_nfiles; 1190 while (i > 2 * NDEXTENT && i > newfdp->fd_lastfile * 2) 1191 i /= 2; |
1192 FILEDESC_UNLOCK(fdp); |
|
1091 MALLOC(newfdp->fd_ofiles, struct file **, i * OFILESIZE, 1092 M_FILEDESC, M_WAITOK); | 1193 MALLOC(newfdp->fd_ofiles, struct file **, i * OFILESIZE, 1194 M_FILEDESC, M_WAITOK); |
1195 FILEDESC_LOCK(fdp); 1196 newfdp->fd_lastfile = fdp->fd_lastfile; 1197 newfdp->fd_nfiles = fdp->fd_nfiles; 1198 j = newfdp->fd_nfiles; 1199 while (j > 2 * NDEXTENT && j > newfdp->fd_lastfile * 2) 1200 j /= 2; 1201 if (i != j) { 1202 /* 1203 * The size of the original table has changed. 1204 * Go over once again. 1205 */ 1206 FILEDESC_UNLOCK(fdp); 1207 FREE(newfdp->fd_ofiles, M_FILEDESC); 1208 FILEDESC_LOCK(fdp); 1209 newfdp->fd_lastfile = fdp->fd_lastfile; 1210 newfdp->fd_nfiles = fdp->fd_nfiles; 1211 goto retry; 1212 } |
|
1093 newfdp->fd_ofileflags = (char *) &newfdp->fd_ofiles[i]; 1094 } 1095 newfdp->fd_nfiles = i; 1096 bcopy(fdp->fd_ofiles, newfdp->fd_ofiles, i * sizeof(struct file **)); 1097 bcopy(fdp->fd_ofileflags, newfdp->fd_ofileflags, i * sizeof(char)); 1098 1099 /* 1100 * kq descriptors cannot be copied. --- 12 unchanged lines hidden (view full) --- 1113 newfdp->fd_knlist = NULL; 1114 newfdp->fd_knlistsize = -1; 1115 newfdp->fd_knhash = NULL; 1116 newfdp->fd_knhashmask = 0; 1117 } 1118 1119 fpp = newfdp->fd_ofiles; 1120 for (i = newfdp->fd_lastfile; i-- >= 0; fpp++) { | 1213 newfdp->fd_ofileflags = (char *) &newfdp->fd_ofiles[i]; 1214 } 1215 newfdp->fd_nfiles = i; 1216 bcopy(fdp->fd_ofiles, newfdp->fd_ofiles, i * sizeof(struct file **)); 1217 bcopy(fdp->fd_ofileflags, newfdp->fd_ofileflags, i * sizeof(char)); 1218 1219 /* 1220 * kq descriptors cannot be copied. --- 12 unchanged lines hidden (view full) --- 1233 newfdp->fd_knlist = NULL; 1234 newfdp->fd_knlistsize = -1; 1235 newfdp->fd_knhash = NULL; 1236 newfdp->fd_knhashmask = 0; 1237 } 1238 1239 fpp = newfdp->fd_ofiles; 1240 for (i = newfdp->fd_lastfile; i-- >= 0; fpp++) { |
1121 if (*fpp != NULL) | 1241 if (*fpp != NULL) { |
1122 fhold(*fpp); | 1242 fhold(*fpp); |
1243 } |
|
1123 } 1124 return (newfdp); 1125} 1126 1127/* 1128 * Release a filedesc structure. 1129 */ 1130void 1131fdfree(td) 1132 struct thread *td; 1133{ 1134 register struct filedesc *fdp = td->td_proc->p_fd; 1135 struct file **fpp; 1136 register int i; 1137 1138 /* Certain daemons might not have file descriptors. */ 1139 if (fdp == NULL) 1140 return; 1141 | 1244 } 1245 return (newfdp); 1246} 1247 1248/* 1249 * Release a filedesc structure. 1250 */ 1251void 1252fdfree(td) 1253 struct thread *td; 1254{ 1255 register struct filedesc *fdp = td->td_proc->p_fd; 1256 struct file **fpp; 1257 register int i; 1258 1259 /* Certain daemons might not have file descriptors. */ 1260 if (fdp == NULL) 1261 return; 1262 |
1142 if (--fdp->fd_refcnt > 0) | 1263 FILEDESC_LOCK(fdp); 1264 if (--fdp->fd_refcnt > 0) { 1265 FILEDESC_UNLOCK(fdp); |
1143 return; | 1266 return; |
1267 } |
|
1144 /* 1145 * we are the last reference to the structure, we can 1146 * safely assume it will not change out from under us. 1147 */ | 1268 /* 1269 * we are the last reference to the structure, we can 1270 * safely assume it will not change out from under us. 1271 */ |
1272 FILEDESC_UNLOCK(fdp); |
|
1148 fpp = fdp->fd_ofiles; 1149 for (i = fdp->fd_lastfile; i-- >= 0; fpp++) { 1150 if (*fpp) 1151 (void) closef(*fpp, td); 1152 } 1153 if (fdp->fd_nfiles > NDFILE) 1154 FREE(fdp->fd_ofiles, M_FILEDESC); 1155 if (fdp->fd_cdir) 1156 vrele(fdp->fd_cdir); 1157 if (fdp->fd_rdir) 1158 vrele(fdp->fd_rdir); 1159 if (fdp->fd_jdir) 1160 vrele(fdp->fd_jdir); 1161 if (fdp->fd_knlist) 1162 FREE(fdp->fd_knlist, M_KQUEUE); 1163 if (fdp->fd_knhash) 1164 FREE(fdp->fd_knhash, M_KQUEUE); | 1273 fpp = fdp->fd_ofiles; 1274 for (i = fdp->fd_lastfile; i-- >= 0; fpp++) { 1275 if (*fpp) 1276 (void) closef(*fpp, td); 1277 } 1278 if (fdp->fd_nfiles > NDFILE) 1279 FREE(fdp->fd_ofiles, M_FILEDESC); 1280 if (fdp->fd_cdir) 1281 vrele(fdp->fd_cdir); 1282 if (fdp->fd_rdir) 1283 vrele(fdp->fd_rdir); 1284 if (fdp->fd_jdir) 1285 vrele(fdp->fd_jdir); 1286 if (fdp->fd_knlist) 1287 FREE(fdp->fd_knlist, M_KQUEUE); 1288 if (fdp->fd_knhash) 1289 FREE(fdp->fd_knhash, M_KQUEUE); |
1290 mtx_destroy(&fdp->fd_mtx); |
|
1165 FREE(fdp, M_FILEDESC); 1166} 1167 1168/* 1169 * For setugid programs, we don't want to people to use that setugidness 1170 * to generate error messages which write to a file which otherwise would 1171 * otherwise be off-limits to the process. 1172 * --- 26 unchanged lines hidden (view full) --- 1199 /* Certain daemons might not have file descriptors. */ 1200 if (fdp == NULL) 1201 return; 1202 1203 /* 1204 * note: fdp->fd_ofiles may be reallocated out from under us while 1205 * we are blocked in a close. Be careful! 1206 */ | 1291 FREE(fdp, M_FILEDESC); 1292} 1293 1294/* 1295 * For setugid programs, we don't want to people to use that setugidness 1296 * to generate error messages which write to a file which otherwise would 1297 * otherwise be off-limits to the process. 1298 * --- 26 unchanged lines hidden (view full) --- 1325 /* Certain daemons might not have file descriptors. */ 1326 if (fdp == NULL) 1327 return; 1328 1329 /* 1330 * note: fdp->fd_ofiles may be reallocated out from under us while 1331 * we are blocked in a close. Be careful! 1332 */ |
1333 FILEDESC_LOCK(fdp); |
|
1207 for (i = 0; i <= fdp->fd_lastfile; i++) { 1208 if (i > 2) 1209 break; 1210 if (fdp->fd_ofiles[i] && is_unsafe(fdp->fd_ofiles[i])) { 1211 struct file *fp; 1212 1213#if 0 1214 if ((fdp->fd_ofileflags[i] & UF_MAPPED) != 0) 1215 (void) munmapfd(td, i); 1216#endif | 1334 for (i = 0; i <= fdp->fd_lastfile; i++) { 1335 if (i > 2) 1336 break; 1337 if (fdp->fd_ofiles[i] && is_unsafe(fdp->fd_ofiles[i])) { 1338 struct file *fp; 1339 1340#if 0 1341 if ((fdp->fd_ofileflags[i] & UF_MAPPED) != 0) 1342 (void) munmapfd(td, i); 1343#endif |
1217 if (i < fdp->fd_knlistsize) | 1344 if (i < fdp->fd_knlistsize) { 1345 FILEDESC_UNLOCK(fdp); |
1218 knote_fdclose(td, i); | 1346 knote_fdclose(td, i); |
1347 FILEDESC_LOCK(fdp); 1348 } |
|
1219 /* 1220 * NULL-out descriptor prior to close to avoid 1221 * a race while close blocks. 1222 */ 1223 fp = fdp->fd_ofiles[i]; 1224 fdp->fd_ofiles[i] = NULL; 1225 fdp->fd_ofileflags[i] = 0; 1226 if (i < fdp->fd_freefile) 1227 fdp->fd_freefile = i; | 1349 /* 1350 * NULL-out descriptor prior to close to avoid 1351 * a race while close blocks. 1352 */ 1353 fp = fdp->fd_ofiles[i]; 1354 fdp->fd_ofiles[i] = NULL; 1355 fdp->fd_ofileflags[i] = 0; 1356 if (i < fdp->fd_freefile) 1357 fdp->fd_freefile = i; |
1358 FILEDESC_UNLOCK(fdp); |
|
1228 (void) closef(fp, td); | 1359 (void) closef(fp, td); |
1360 FILEDESC_LOCK(fdp); |
|
1229 } 1230 } 1231 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 1232 fdp->fd_lastfile--; | 1361 } 1362 } 1363 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 1364 fdp->fd_lastfile--; |
1365 FILEDESC_UNLOCK(fdp); |
|
1233} 1234 1235/* 1236 * Close any files on exec? 1237 */ 1238void 1239fdcloseexec(td) 1240 struct thread *td; 1241{ 1242 struct filedesc *fdp = td->td_proc->p_fd; 1243 register int i; 1244 1245 /* Certain daemons might not have file descriptors. */ 1246 if (fdp == NULL) 1247 return; 1248 | 1366} 1367 1368/* 1369 * Close any files on exec? 1370 */ 1371void 1372fdcloseexec(td) 1373 struct thread *td; 1374{ 1375 struct filedesc *fdp = td->td_proc->p_fd; 1376 register int i; 1377 1378 /* Certain daemons might not have file descriptors. */ 1379 if (fdp == NULL) 1380 return; 1381 |
1382 FILEDESC_LOCK(fdp); 1383 |
|
1249 /* 1250 * We cannot cache fd_ofiles or fd_ofileflags since operations 1251 * may block and rip them out from under us. 1252 */ 1253 for (i = 0; i <= fdp->fd_lastfile; i++) { 1254 if (fdp->fd_ofiles[i] != NULL && 1255 (fdp->fd_ofileflags[i] & UF_EXCLOSE)) { 1256 struct file *fp; 1257 1258#if 0 1259 if (fdp->fd_ofileflags[i] & UF_MAPPED) 1260 (void) munmapfd(td, i); 1261#endif | 1384 /* 1385 * We cannot cache fd_ofiles or fd_ofileflags since operations 1386 * may block and rip them out from under us. 1387 */ 1388 for (i = 0; i <= fdp->fd_lastfile; i++) { 1389 if (fdp->fd_ofiles[i] != NULL && 1390 (fdp->fd_ofileflags[i] & UF_EXCLOSE)) { 1391 struct file *fp; 1392 1393#if 0 1394 if (fdp->fd_ofileflags[i] & UF_MAPPED) 1395 (void) munmapfd(td, i); 1396#endif |
1262 if (i < fdp->fd_knlistsize) | 1397 if (i < fdp->fd_knlistsize) { 1398 FILEDESC_UNLOCK(fdp); |
1263 knote_fdclose(td, i); | 1399 knote_fdclose(td, i); |
1400 FILEDESC_LOCK(fdp); 1401 } |
|
1264 /* 1265 * NULL-out descriptor prior to close to avoid 1266 * a race while close blocks. 1267 */ 1268 fp = fdp->fd_ofiles[i]; 1269 fdp->fd_ofiles[i] = NULL; 1270 fdp->fd_ofileflags[i] = 0; 1271 if (i < fdp->fd_freefile) 1272 fdp->fd_freefile = i; | 1402 /* 1403 * NULL-out descriptor prior to close to avoid 1404 * a race while close blocks. 1405 */ 1406 fp = fdp->fd_ofiles[i]; 1407 fdp->fd_ofiles[i] = NULL; 1408 fdp->fd_ofileflags[i] = 0; 1409 if (i < fdp->fd_freefile) 1410 fdp->fd_freefile = i; |
1411 FILEDESC_UNLOCK(fdp); |
|
1273 (void) closef(fp, td); | 1412 (void) closef(fp, td); |
1413 FILEDESC_LOCK(fdp); |
|
1274 } 1275 } 1276 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 1277 fdp->fd_lastfile--; | 1414 } 1415 } 1416 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 1417 fdp->fd_lastfile--; |
1418 FILEDESC_UNLOCK(fdp); |
|
1278} 1279 1280/* 1281 * Internal form of close. 1282 * Decrement reference count on file structure. 1283 * Note: td may be NULL when closing a file 1284 * that was being passed in a message. 1285 */ --- 24 unchanged lines hidden (view full) --- 1310 vp = (struct vnode *)fp->f_data; 1311 (void) VOP_ADVLOCK(vp, (caddr_t)td->td_proc->p_leader, 1312 F_UNLCK, &lf, F_POSIX); 1313 } 1314 return (fdrop(fp, td)); 1315} 1316 1317/* | 1419} 1420 1421/* 1422 * Internal form of close. 1423 * Decrement reference count on file structure. 1424 * Note: td may be NULL when closing a file 1425 * that was being passed in a message. 1426 */ --- 24 unchanged lines hidden (view full) --- 1451 vp = (struct vnode *)fp->f_data; 1452 (void) VOP_ADVLOCK(vp, (caddr_t)td->td_proc->p_leader, 1453 F_UNLCK, &lf, F_POSIX); 1454 } 1455 return (fdrop(fp, td)); 1456} 1457 1458/* |
1459 * Find the struct file 'fd' in process 'p' and bump it's refcount 1460 * struct file is not locked on return. 1461 */ 1462struct file * 1463ffind_hold(td, fd) 1464 struct thread *td; 1465 int fd; 1466{ 1467 struct filedesc *fdp; 1468 struct file *fp; 1469 1470 if (td == NULL || (fdp = td->td_proc->p_fd) == NULL) 1471 return (NULL); 1472 FILEDESC_LOCK(fdp); 1473 if (fd < 0 || fd >= fdp->fd_nfiles || 1474 (fp = fdp->fd_ofiles[fd]) == NULL || 1475 fp->f_ops == &badfileops) 1476 fp = NULL; 1477 else 1478 fhold(fp); 1479 FILEDESC_UNLOCK(fdp); 1480 return (fp); 1481} 1482 1483/* 1484 * Find the struct file 'fd' in process 'p' and bump it's refcount, 1485 * struct file is locked on return. 1486 */ 1487struct file * 1488ffind_lock(td, fd) 1489 struct thread *td; 1490 int fd; 1491{ 1492 struct filedesc *fdp; 1493 struct file *fp; 1494 1495 if (td == NULL || (fdp = td->td_proc->p_fd) == NULL) 1496 return (NULL); 1497 FILEDESC_LOCK(fdp); 1498 if (fd < 0 || fd >= fdp->fd_nfiles || 1499 (fp = fdp->fd_ofiles[fd]) == NULL || 1500 fp->f_ops == &badfileops) { 1501 fp = NULL; 1502 } else { 1503 FILE_LOCK(fp); 1504 fhold_locked(fp); 1505 } 1506 FILEDESC_UNLOCK(fdp); 1507 return (fp); 1508} 1509 1510int 1511fdrop(fp, td) 1512 struct file *fp; 1513 struct thread *td; 1514{ 1515 1516 FILE_LOCK(fp); 1517 return (fdrop_locked(fp, td)); 1518} 1519 1520/* |
|
1318 * Extract the file pointer associated with the specified descriptor for 1319 * the current user process. If no error occured 0 is returned, *fpp 1320 * will be set to the file pointer, and the file pointer's ref count 1321 * will be bumped. Use fdrop() to drop it. If an error occured the 1322 * non-zero error is returned and *fpp is set to NULL. 1323 * 1324 * This routine requires Giant for the moment. Once enough of the 1325 * system is converted over to this and other encapsulated APIs we --- 147 unchanged lines hidden (view full) --- 1473 */ 1474void 1475fputsock(struct socket *so) 1476{ 1477 sorele(so); 1478} 1479 1480int | 1521 * Extract the file pointer associated with the specified descriptor for 1522 * the current user process. If no error occured 0 is returned, *fpp 1523 * will be set to the file pointer, and the file pointer's ref count 1524 * will be bumped. Use fdrop() to drop it. If an error occured the 1525 * non-zero error is returned and *fpp is set to NULL. 1526 * 1527 * This routine requires Giant for the moment. Once enough of the 1528 * system is converted over to this and other encapsulated APIs we --- 147 unchanged lines hidden (view full) --- 1676 */ 1677void 1678fputsock(struct socket *so) 1679{ 1680 sorele(so); 1681} 1682 1683int |
1481fdrop(fp, td) | 1684fdrop_locked(fp, td) |
1482 struct file *fp; 1483 struct thread *td; 1484{ 1485 struct flock lf; 1486 struct vnode *vp; 1487 int error; 1488 | 1685 struct file *fp; 1686 struct thread *td; 1687{ 1688 struct flock lf; 1689 struct vnode *vp; 1690 int error; 1691 |
1489 if (--fp->f_count > 0) | 1692 FILE_LOCK_ASSERT(fp, MA_OWNED); 1693 1694 if (--fp->f_count > 0) { 1695 FILE_UNLOCK(fp); |
1490 return (0); | 1696 return (0); |
1697 } |
|
1491 if (fp->f_count < 0) 1492 panic("fdrop: count < 0"); 1493 if ((fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) { 1494 lf.l_whence = SEEK_SET; 1495 lf.l_start = 0; 1496 lf.l_len = 0; 1497 lf.l_type = F_UNLCK; 1498 vp = (struct vnode *)fp->f_data; | 1698 if (fp->f_count < 0) 1699 panic("fdrop: count < 0"); 1700 if ((fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) { 1701 lf.l_whence = SEEK_SET; 1702 lf.l_start = 0; 1703 lf.l_len = 0; 1704 lf.l_type = F_UNLCK; 1705 vp = (struct vnode *)fp->f_data; |
1706 FILE_UNLOCK(fp); |
|
1499 (void) VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK); | 1707 (void) VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK); |
1500 } | 1708 } else 1709 FILE_UNLOCK(fp); |
1501 if (fp->f_ops != &badfileops) 1502 error = fo_close(fp, td); 1503 else 1504 error = 0; 1505 ffree(fp); 1506 return (error); 1507} 1508 --- 13 unchanged lines hidden (view full) --- 1522 * MPSAFE 1523 */ 1524/* ARGSUSED */ 1525int 1526flock(td, uap) 1527 struct thread *td; 1528 register struct flock_args *uap; 1529{ | 1710 if (fp->f_ops != &badfileops) 1711 error = fo_close(fp, td); 1712 else 1713 error = 0; 1714 ffree(fp); 1715 return (error); 1716} 1717 --- 13 unchanged lines hidden (view full) --- 1731 * MPSAFE 1732 */ 1733/* ARGSUSED */ 1734int 1735flock(td, uap) 1736 struct thread *td; 1737 register struct flock_args *uap; 1738{ |
1530 register struct filedesc *fdp = td->td_proc->p_fd; | |
1531 register struct file *fp; 1532 struct vnode *vp; 1533 struct flock lf; 1534 int error; 1535 | 1739 register struct file *fp; 1740 struct vnode *vp; 1741 struct flock lf; 1742 int error; 1743 |
1536 mtx_lock(&Giant); 1537 1538 if ((unsigned)uap->fd >= fdp->fd_nfiles || 1539 (fp = fdp->fd_ofiles[uap->fd]) == NULL) { 1540 error = EBADF; 1541 goto done2; 1542 } | 1744 fp = ffind_hold(td, uap->fd); 1745 if (fp == NULL) 1746 return (EBADF); |
1543 if (fp->f_type != DTYPE_VNODE) { | 1747 if (fp->f_type != DTYPE_VNODE) { |
1544 error = EOPNOTSUPP; 1545 goto done2; | 1748 fdrop(fp, td); 1749 return (EOPNOTSUPP); |
1546 } | 1750 } |
1751 1752 mtx_lock(&Giant); |
|
1547 vp = (struct vnode *)fp->f_data; 1548 lf.l_whence = SEEK_SET; 1549 lf.l_start = 0; 1550 lf.l_len = 0; 1551 if (uap->how & LOCK_UN) { 1552 lf.l_type = F_UNLCK; | 1753 vp = (struct vnode *)fp->f_data; 1754 lf.l_whence = SEEK_SET; 1755 lf.l_start = 0; 1756 lf.l_len = 0; 1757 if (uap->how & LOCK_UN) { 1758 lf.l_type = F_UNLCK; |
1759 FILE_LOCK(fp); |
|
1553 fp->f_flag &= ~FHASLOCK; | 1760 fp->f_flag &= ~FHASLOCK; |
1761 FILE_UNLOCK(fp); |
|
1554 error = VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK); 1555 goto done2; 1556 } 1557 if (uap->how & LOCK_EX) 1558 lf.l_type = F_WRLCK; 1559 else if (uap->how & LOCK_SH) 1560 lf.l_type = F_RDLCK; 1561 else { 1562 error = EBADF; 1563 goto done2; 1564 } | 1762 error = VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK); 1763 goto done2; 1764 } 1765 if (uap->how & LOCK_EX) 1766 lf.l_type = F_WRLCK; 1767 else if (uap->how & LOCK_SH) 1768 lf.l_type = F_RDLCK; 1769 else { 1770 error = EBADF; 1771 goto done2; 1772 } |
1773 FILE_LOCK(fp); |
|
1565 fp->f_flag |= FHASLOCK; | 1774 fp->f_flag |= FHASLOCK; |
1566 if (uap->how & LOCK_NB) 1567 error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK); 1568 else 1569 error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK|F_WAIT); | 1775 FILE_UNLOCK(fp); 1776 error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, 1777 (uap->how & LOCK_NB) ? F_FLOCK : F_FLOCK | F_WAIT); |
1570done2: | 1778done2: |
1779 fdrop(fp, td); |
|
1571 mtx_unlock(&Giant); 1572 return (error); 1573} 1574 1575/* 1576 * File Descriptor pseudo-device driver (/dev/fd/). 1577 * 1578 * Opening minor device N dup()s the file (if any) connected to file --- 35 unchanged lines hidden (view full) --- 1614 register struct file *wfp; 1615 struct file *fp; 1616 1617 /* 1618 * If the to-be-dup'd fd number is greater than the allowed number 1619 * of file descriptors, or the fd to be dup'd has already been 1620 * closed, then reject. 1621 */ | 1780 mtx_unlock(&Giant); 1781 return (error); 1782} 1783 1784/* 1785 * File Descriptor pseudo-device driver (/dev/fd/). 1786 * 1787 * Opening minor device N dup()s the file (if any) connected to file --- 35 unchanged lines hidden (view full) --- 1823 register struct file *wfp; 1824 struct file *fp; 1825 1826 /* 1827 * If the to-be-dup'd fd number is greater than the allowed number 1828 * of file descriptors, or the fd to be dup'd has already been 1829 * closed, then reject. 1830 */ |
1831 FILEDESC_LOCK(fdp); |
|
1622 if ((u_int)dfd >= fdp->fd_nfiles || 1623 (wfp = fdp->fd_ofiles[dfd]) == NULL) { | 1832 if ((u_int)dfd >= fdp->fd_nfiles || 1833 (wfp = fdp->fd_ofiles[dfd]) == NULL) { |
1834 FILEDESC_UNLOCK(fdp); |
|
1624 return (EBADF); 1625 } 1626 1627 /* 1628 * There are two cases of interest here. 1629 * 1630 * For ENODEV simply dup (dfd) to file descriptor 1631 * (indx) and return. --- 5 unchanged lines hidden (view full) --- 1637 * Any other error code is just returned. 1638 */ 1639 switch (error) { 1640 case ENODEV: 1641 /* 1642 * Check that the mode the file is being opened for is a 1643 * subset of the mode of the existing descriptor. 1644 */ | 1835 return (EBADF); 1836 } 1837 1838 /* 1839 * There are two cases of interest here. 1840 * 1841 * For ENODEV simply dup (dfd) to file descriptor 1842 * (indx) and return. --- 5 unchanged lines hidden (view full) --- 1848 * Any other error code is just returned. 1849 */ 1850 switch (error) { 1851 case ENODEV: 1852 /* 1853 * Check that the mode the file is being opened for is a 1854 * subset of the mode of the existing descriptor. 1855 */ |
1645 if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag) | 1856 FILE_LOCK(wfp); 1857 if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag) { 1858 FILE_UNLOCK(wfp); 1859 FILEDESC_UNLOCK(fdp); |
1646 return (EACCES); | 1860 return (EACCES); |
1861 } |
|
1647 fp = fdp->fd_ofiles[indx]; 1648#if 0 1649 if (fp && fdp->fd_ofileflags[indx] & UF_MAPPED) 1650 (void) munmapfd(td, indx); 1651#endif 1652 fdp->fd_ofiles[indx] = wfp; 1653 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; | 1862 fp = fdp->fd_ofiles[indx]; 1863#if 0 1864 if (fp && fdp->fd_ofileflags[indx] & UF_MAPPED) 1865 (void) munmapfd(td, indx); 1866#endif 1867 fdp->fd_ofiles[indx] = wfp; 1868 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; |
1654 fhold(wfp); | 1869 fhold_locked(wfp); 1870 FILE_UNLOCK(wfp); |
1655 if (indx > fdp->fd_lastfile) 1656 fdp->fd_lastfile = indx; | 1871 if (indx > fdp->fd_lastfile) 1872 fdp->fd_lastfile = indx; |
1873 if (fp != NULL) 1874 FILE_LOCK(fp); 1875 FILEDESC_UNLOCK(fdp); |
|
1657 /* 1658 * we now own the reference to fp that the ofiles[] array 1659 * used to own. Release it. 1660 */ | 1876 /* 1877 * we now own the reference to fp that the ofiles[] array 1878 * used to own. Release it. 1879 */ |
1661 if (fp) 1662 fdrop(fp, td); | 1880 if (fp != NULL) 1881 fdrop_locked(fp, td); |
1663 return (0); 1664 1665 case ENXIO: 1666 /* 1667 * Steal away the file pointer from dfd, and stuff it into indx. 1668 */ 1669 fp = fdp->fd_ofiles[indx]; 1670#if 0 1671 if (fp && fdp->fd_ofileflags[indx] & UF_MAPPED) 1672 (void) munmapfd(td, indx); 1673#endif 1674 fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd]; 1675 fdp->fd_ofiles[dfd] = NULL; 1676 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; 1677 fdp->fd_ofileflags[dfd] = 0; 1678 1679 /* | 1882 return (0); 1883 1884 case ENXIO: 1885 /* 1886 * Steal away the file pointer from dfd, and stuff it into indx. 1887 */ 1888 fp = fdp->fd_ofiles[indx]; 1889#if 0 1890 if (fp && fdp->fd_ofileflags[indx] & UF_MAPPED) 1891 (void) munmapfd(td, indx); 1892#endif 1893 fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd]; 1894 fdp->fd_ofiles[dfd] = NULL; 1895 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; 1896 fdp->fd_ofileflags[dfd] = 0; 1897 1898 /* |
1680 * we now own the reference to fp that the ofiles[] array 1681 * used to own. Release it. 1682 */ 1683 if (fp) 1684 fdrop(fp, td); 1685 /* | |
1686 * Complete the clean up of the filedesc structure by 1687 * recomputing the various hints. 1688 */ 1689 if (indx > fdp->fd_lastfile) { 1690 fdp->fd_lastfile = indx; 1691 } else { 1692 while (fdp->fd_lastfile > 0 && 1693 fdp->fd_ofiles[fdp->fd_lastfile] == NULL) { 1694 fdp->fd_lastfile--; 1695 } 1696 if (dfd < fdp->fd_freefile) 1697 fdp->fd_freefile = dfd; 1698 } | 1899 * Complete the clean up of the filedesc structure by 1900 * recomputing the various hints. 1901 */ 1902 if (indx > fdp->fd_lastfile) { 1903 fdp->fd_lastfile = indx; 1904 } else { 1905 while (fdp->fd_lastfile > 0 && 1906 fdp->fd_ofiles[fdp->fd_lastfile] == NULL) { 1907 fdp->fd_lastfile--; 1908 } 1909 if (dfd < fdp->fd_freefile) 1910 fdp->fd_freefile = dfd; 1911 } |
1912 if (fp != NULL) 1913 FILE_LOCK(fp); 1914 FILEDESC_UNLOCK(fdp); 1915 1916 /* 1917 * we now own the reference to fp that the ofiles[] array 1918 * used to own. Release it. 1919 */ 1920 if (fp != NULL) 1921 fdrop_locked(fp, td); |
|
1699 return (0); 1700 1701 default: | 1922 return (0); 1923 1924 default: |
1925 FILEDESC_UNLOCK(fdp); |
|
1702 return (error); 1703 } 1704 /* NOTREACHED */ 1705} 1706 1707/* 1708 * Get file structures. 1709 */ 1710static int 1711sysctl_kern_file(SYSCTL_HANDLER_ARGS) 1712{ 1713 int error; 1714 struct file *fp; 1715 | 1926 return (error); 1927 } 1928 /* NOTREACHED */ 1929} 1930 1931/* 1932 * Get file structures. 1933 */ 1934static int 1935sysctl_kern_file(SYSCTL_HANDLER_ARGS) 1936{ 1937 int error; 1938 struct file *fp; 1939 |
1940 sx_slock(&filelist_lock); |
|
1716 if (!req->oldptr) { 1717 /* 1718 * overestimate by 10 files 1719 */ | 1941 if (!req->oldptr) { 1942 /* 1943 * overestimate by 10 files 1944 */ |
1720 return (SYSCTL_OUT(req, 0, sizeof(filehead) + 1721 (nfiles + 10) * sizeof(struct file))); | 1945 error = SYSCTL_OUT(req, 0, sizeof(filehead) + 1946 (nfiles + 10) * sizeof(struct file)); 1947 sx_sunlock(&filelist_lock); 1948 return (error); |
1722 } 1723 1724 error = SYSCTL_OUT(req, (caddr_t)&filehead, sizeof(filehead)); | 1949 } 1950 1951 error = SYSCTL_OUT(req, (caddr_t)&filehead, sizeof(filehead)); |
1725 if (error) | 1952 if (error) { 1953 sx_sunlock(&filelist_lock); |
1726 return (error); | 1954 return (error); |
1955 } |
|
1727 1728 /* 1729 * followed by an array of file structures 1730 */ 1731 LIST_FOREACH(fp, &filehead, f_list) { 1732 error = SYSCTL_OUT(req, (caddr_t)fp, sizeof (struct file)); | 1956 1957 /* 1958 * followed by an array of file structures 1959 */ 1960 LIST_FOREACH(fp, &filehead, f_list) { 1961 error = SYSCTL_OUT(req, (caddr_t)fp, sizeof (struct file)); |
1733 if (error) | 1962 if (error) { 1963 sx_sunlock(&filelist_lock); |
1734 return (error); | 1964 return (error); |
1965 } |
|
1735 } | 1966 } |
1967 sx_sunlock(&filelist_lock); |
|
1736 return (0); 1737} 1738 1739SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD, 1740 0, 0, sysctl_kern_file, "S,file", "Entire file table"); 1741 1742SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, CTLFLAG_RW, 1743 &maxfilesperproc, 0, "Maximum files allowed open per process"); --- 93 unchanged lines hidden (view full) --- 1837 struct thread *td; 1838{ 1839 1840 return (EBADF); 1841} 1842 1843SYSINIT(fildescdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR, 1844 fildesc_drvinit,NULL) | 1968 return (0); 1969} 1970 1971SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD, 1972 0, 0, sysctl_kern_file, "S,file", "Entire file table"); 1973 1974SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, CTLFLAG_RW, 1975 &maxfilesperproc, 0, "Maximum files allowed open per process"); --- 93 unchanged lines hidden (view full) --- 2069 struct thread *td; 2070{ 2071 2072 return (EBADF); 2073} 2074 2075SYSINIT(fildescdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR, 2076 fildesc_drvinit,NULL) |
2077 2078static void filelistinit __P((void *)); 2079SYSINIT(select, SI_SUB_LOCK, SI_ORDER_FIRST, filelistinit, NULL) 2080 2081/* ARGSUSED*/ 2082static void 2083filelistinit(dummy) 2084 void *dummy; 2085{ 2086 sx_init(&filelist_lock, "filelist lock"); 2087} |
|