Alloc fd
Retired DISLab
450 /* 451 * allocate a file descriptor, mark it busy. 452 */ 453 int __alloc_fd(struct files_struct *files, 454 unsigned start, unsigned end, unsigned flags) 455 { 456 unsigned int fd; 457 int error; 458 struct fdtable *fdt; 459 460 spin_lock(&files->file_lock); 461 repeat: 462 fdt = files_fdtable(files); 463 fd = start; 464 if (fd < files->next_fd) 465 fd = files->next_fd; 466 467 if (fd < fdt->max_fds) 468 fd = find_next_zero_bit(fdt->open_fds, fdt->max_fds, fd); 469 470 /* 471 * N.B. For clone tasks sharing a files structure, this test 472 * will limit the total number of files that can be opened. 473 */ 474 error = -EMFILE; 475 if (fd >= end) 476 goto out; 477 478 error = expand_files(files, fd); 479 if (error < 0) 480 goto out; 481 482 /* 483 * If we needed to expand the fs array we 484 * might have blocked - try again. 485 */ 486 if (error) 487 goto repeat; 488 489 if (start <= files->next_fd) 490 files->next_fd = fd + 1; 491 492 __set_open_fd(fd, fdt); 493 if (flags & O_CLOEXEC) 494 __set_close_on_exec(fd, fdt); 495 else 496 __clear_close_on_exec(fd, fdt); 497 error = fd; 498 #if 1 499 /* Sanity check */ 500 if (rcu_dereference_raw(fdt->fd[fd]) != NULL) { 501 printk(KERN_WARNING "alloc_fd: slot %d not NULL!\n", fd); 502 rcu_assign_pointer(fdt->fd[fd], NULL); 503 } 504 #endif 505 506 out: 507 spin_unlock(&files->file_lock); 508 return error; 509 }