CPU architecture:ARM920T
Author:ce123(http://blog.csdn.net/ce123)
Let's first post the source code of the expand_files function:
- int expand_files(struct files_struct *files, int nr)
- {
- int err, expand = 0;
- struct fdtable *fdt;
- fdt = files_fdtable(files);
- if (nr >= fdt->max_fdset || nr >= fdt->max_fds) { // We have analyzed in the previous article that initially max_fdset = 1024, max_fds = 32
- if (fdt->max_fdset >= NR_OPEN || //#define NR_OPEN (1024*1024) /* Absolute upper limit on fd num */
- fdt->max_fds >= NR_OPEN || nr >= NR_OPEN) {
- err = -EMFILE; //neither max_fdset nor max_fds can be greater than NR_OPEN, otherwise -EMFILE is returned, indicating that too many files are opened
- goto out;
- }
- expand = 1;
- if ((err = expand_fdtable(files, nr)))//actually expand
- goto out;
- }
- err = expand;
- out:
- return err;
- }
The expand_files function performs some checks and then calls expand_fdtable to expand the file descriptor table. The expand_fdtable function is analyzed below.
- static int expand_fdtable(struct files_struct *files, int nr)
- __releases(files->file_lock)
- __acquires(files->file_lock)
- {
- int error = 0;
- struct fdtable *fdt;
- struct fdtable *nfdt = NULL;
- spin_unlock(&files->file_lock);
- nfdt = alloc_fdtable(nr); //Recreate a new fdtable based on nr
- if (!nfdt) {
- error = -ENOMEM;
- spin_lock(&files->file_lock);
- goto out;
- }
- spin_lock(&files->file_lock);
- fdt = files_fdtable(files);
- /*
- * Check again since another task may have expanded the
- * fd table while we dropped the lock
- */
- if (nr >= fdt->max_fds || nr >= fdt->max_fdset) { //nr value must be greater than max_fds and max_fdset values. Checking again here is to prevent another process from expanding
- copy_fdtable(nfdt, fdt); //Copy the contents of the old fdtable to the new fdtable
- } else {
- /* Somebody expanded while we dropped file_lock */
- spin_unlock(&files->file_lock);
- __free_fdtable(nfdt);
- spin_lock(&files->file_lock);
- goto out;
- }
- rcu_assign_pointer(files->fdt, nfdt); //Replace the old fdtable with the new one
- free_fdtable(fdt); //Release the old fdtable
- out:
- return error;
- }
- static struct fdtable *alloc_fdtable(int nr)
- {
- struct fdtable *fdt = NULL;
- int nfds = 0;
- fd_set *new_openset = NULL, *new_execset = NULL;
- struct file **new_fds;
- fdt = kmalloc(sizeof(*fdt), GFP_KERNEL);
- if (!fdt)
- goto out;
- memset(fdt, 0, sizeof(*fdt));
- nfds = __FD_SETSIZE; //#define __FD_SETSIZE 1024
- // #define PAGE_SHIFT 12
- // #define PAGE_SIZE (1UL << PAGE_SHIFT)
- /* Expand to the max in easy steps */
- do {
- if (nfds < (PAGE_SIZE * 8))//dfds = 1024
- nfds = PAGE_SIZE * 8;
- else {
- nfds = nfds * 2;
- if (nfds > NR_OPEN)
- nfds = NR_OPEN;
- }
- } while (nfds <= nr); //When expanding for the first time, nr should be equal to 32
- new_openset = alloc_fdset(nfds); // allocate open file bitmap
- new_execset = alloc_fdset(nfds);
- if (!new_openset || !new_execset)
- goto out;
- fdt->open_fds = new_openset;
- fdt->close_on_exec = new_execset;
- fdt->max_fdset = nfds; //Update max_fdset value, now the value is 32k
- nfds = NR_OPEN_DEFAULT;//nfds = 32
- /*
- * Expand to the max in easy steps, and keep expanding it until
- * we have enough for the requested fd array size.
- */
- do {
- #if NR_OPEN_DEFAULT < 256
- if (nfds < 256)
- nfds = 256;//nfds = 256(32->256->1024)
- //Cannot exceed 1024, because it is checked at the very beginning and must be less than current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
- else
- #endif
- if (nfds < (PAGE_SIZE / sizeof(struct file *)))
- nfds = PAGE_SIZE / sizeof(struct file *);
- else {
- nfds = nfds * 2;
- if (nfds > NR_OPEN)
- nfds = NR_OPEN;
- }
- } while (nfds <= nr);
- new_fds = alloc_fd_array(nfds); // allocate file descriptor array
- if (!new_fds)
- goto out;
- fdt->fd = new_fds;
- fdt->max_fds = nfds; //Update max_fds
- fdt->free_files = NULL;
- return fdt;
- out:
- if (new_openset)
- free_fdset(new_openset, nfds);
- if (new_execset)
- free_fdset(new_execset, nfds);
- kfree(fdt);
- return NULL;
- }
Previous article:Likely and Unlikely in the Linux Kernel
Next article:File descriptors in the Linux kernel (V) -- allocation of fd -- locate_fd
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- [Sipeed LicheeRV 86 Panel Review] Debian Python + Serial Communication
- What is the 5G battle about?
- Zero-based development of WIFI devices
- Fundamentals of mmWave Sensors (mmWave Training Series)
- Tuya Smart Module SDK Development Course Series - 2. Introduction to Tuya IoT Platform
- C2000 Software Serial Interface (SCI) Implementation Method
- Differences between different versions of TI's ZigBee protocol stack
- Studying Things to Gain Knowledge 05: Dimensions and Elementary Functions
- How much does it cost to build a TMR magnetoresistive switch from development to manufacturing?
- The new version is so beautiful, I decided not to update it for the time being!