Description

atomic t

count

Number of processes sharing this table

rwlock t

file lock

Read/write spin lock for the table fields

int

max fds

Current maximum number of file objects

int

max fdset

Current maximum number of file descriptors

int

next_fd

Maximum file descriptors ever allocated plus 1

struct file **

fd

Pointer to array of file object pointers

fd_set *

close on exec

Pointer to file descriptors to be closed on exec( )

fd_set *

open fds

Pointer to open file descriptors

fd set

close on exec init

Initial set of file descriptors to be closed on exec( )

fd set

open fds init

Initial set of file descriptors

struct file **

fd array

Initial array of file object pointers

The fd field points to an array of pointers to file objects. The size of the array is stored in the max_fds field. Usually, fd points to the fd_array field of the files_struct structure, which includes 32 file object pointers. If the process opens more than 32 files, the kernel allocates a new, larger array of file pointers and stores its address in the fd fields; it also updates the max_fds field.

For every file with an entry in the fd array, the array index is the file descriptor. Usually, the first element (index 0) of the array is associated with the standard input of the process, the second with the standard output, and the third with the standard error (see Figure 12-3). Unix processes use the file descriptor as the main file identifier. Notice that, thanks to the dup( ), dup2( ), and fcntl( ) system calls, two file descriptors may refer to the same opened fileā€”that is, two elements of the array could point to the same file object. Users see this all the time when they use shell constructs like 2>&1 to redirect the standard error to the standard output.

A process cannot use more than nr_open (usually, 1, 048 ,576) file descriptors. The kernel also enforces a dynamic bound on the maximum number of file descriptors in the rlim[RLiMiT_NOFiLE] structure of the process descriptor; this value is usually 1,024, but it can be raised if the process has root privileges.

The open_fds field initially contains the address of the open_fds_init field, which is a bitmap that identifies the file descriptors of currently opened files. The max_fdset field stores the number of bits in the bitmap. Since the fd_set data structure includes 1,024 bits, there is usually no need to expand the size of the bitmap. However, the kernel may dynamically expand the size of the bitmap if this turns out to be necessary, much as in the case of the array of file objects.

Figure 12-3. The fd array

Figure 12-3. The fd array

The kernel provides an fget( ) function to be invoked when the kernel starts using a file object. This function receives as its parameter a file descriptor fd . It returns the address in current->files->fd[fd] (that is, the address of the corresponding file object), or null if no file corresponds to fd . In the first case, fget( ) increments the file object usage counter f_count by 1.

The kernel also provides an fput( ) function to be invoked when a kernel control path finishes using a file object. This function receives as its parameter the address of a file object and decrements its usage counter, f_count. Moreover, if this field becomes 0, the function invokes the release method of the file operations (if defined), releases the associated dentry object and filesystem descriptor, decrements the i_writecount field in the inode object (if the file was opened for writing), and finally moves the file object from the "in use" list to the "unused" one.

I [email protected] RuBoard

Was this article helpful?

0 0

Post a comment