Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Working of Open System Call

I am reading about Memory Mapped Files, the souce says it is faster than traditional methods to open a file or read a file such as an open system call and read system call respectively without giving the description that how open or read system call works.

So here's my question how the open system call works?

As far i know it will load the file into the memory, whereas by using mapped file only their addresses will be saved in the memory and when needed the requested page may be brought into the memory.

I expect clarification over my so far understanding.

EDIT

My previous understanding written above is almost wrong, for coorrect explanation refer to the accepted answer by Pawel.

like image 865
Akashdeep Saluja Avatar asked Dec 15 '22 18:12

Akashdeep Saluja


2 Answers

Since you gave no details I'm assuming you are interested in behavior of Unix-like systems.

Actually open() system call only creates a file descriptor which then may be used by either mmap() or read().

Both memory mapped I/O and standard I/O internally access files on disk through page cache, a buffer in which files are cached in order to reduce number of I/O operations.

Standard I/O approach (using write() and read()) involves performing a system call which then copies data from (or to if you are writing) page cache to a buffer chosen by application. In addition to that non-sequential access requires another system call lseek(). System calls are expensive and so is copying data.

When a file is memory mapped usually a memory region in process address space is mapped directly to page cache, so that all reads and writes of already loaded data can be performed without any additional delay (no system calls, no data copying). Only when an application attempts to access file region that is not already loaded a page fault occurs and the kernel loads required data (whole page) from disk.

EDIT: I see that I also have to explain memory paging. On most modern architectures there is physical memory which is a real piece of hardware and virtual memory which creates address spaces for processes. Kernel decides how addresses in virtual memory are mapped to addresses in physical memory. The smallest unit is a memory page (usually, but not always 4K). It does not have to be 1:1 mapping, for example all virtual memory pages may be mapped to the same physical address.

In memory mapped I/O part of application address space and kernel's page cache are mapped to the same physical memory region, hence program is able to directly access page cache.

like image 101
Paweł Dziepak Avatar answered Dec 30 '22 12:12

Paweł Dziepak


Pawel has beautifully explained how read/writes are performed. Let me explain the original question: How does fopen(3) works: when user space process encounters fopen(defined in libc or any user space library), it translates it into open(2) system call. First, it takes arguments from fopen, writes them into architecture specific registers along with open() syscall number. This number tells kernel the system call user space program wants to run. After loading these register, user space process interrupts kernel(via softirq, traditionally INT 80H on x86) and blocks.

Kernel verifies the arguments provided and access permissions etc, and then either returns error or invokes actual system call which is vfs_open() in this case. vfs_open() checks for available file descriptor in fd array and allocates struct file. The ref counts of accessed file is increased and fd is returned to user program. That's completes the working of open, and of most of the system calls in general.

open() together with read()/write(), followed by close() is undoubtedly much lengthy process than having memory mapped file in buffer cache.

like image 27
Vishal Sahu Avatar answered Dec 30 '22 12:12

Vishal Sahu