Reputation: 797
I am recently studying file system in linux. I learned that when we call fopen(), the library call will call malloc() to allocate space for the FILE structure, and inside this FILE structure there will be a buffer for I/0. But later on I found that the write system call actually writes the data to the kernel buffer, So what's the difference between these two buffers?
Upvotes: 12
Views: 12025
Reputation: 330
There is a very big difference between the two buffers, one is kernel
buffer and the other is the user
buffer. So, what basically happens when you do a I/O is that the buffer from the user space is copied into a buffer in the kernel space. The function copy_from_user()
does this task.
Now the question which arises is why do we need two buffers, when the kernel has access into the user space? The reason is that the kernel does not want to read the user buffer directly because both the kernel and the user space has different address spaces and so a valid address in user space might not be a valid address in kernel.
In kernel if a non-valid address is accessed then the system will panic immediately, so the function copy_from_user
does the task of mapping the user space address and the kernel space address and checks if the address is accessible or not. If not then it simply returns EFAULT
(bad address).
Upvotes: 2
Reputation: 1039
You have to understand two things: fwrite()
is a standard library's routine operating on FILE
structure, but write()
is a system call. I bet fwrite()
uses write()
internally. Nothing keeps fwrite()
from providing user space IO-buffering until it is ready to pass your data on to the write()
syscall.
write()
syscall in it's turn goes straight to the kernel and says: "Hey kernel, I've got this user space buffer here. Will you write this one to the storage for me?". And here it's up to the kernel what to do next: it will either go directly to storage to write the data, or, most likely, copy the data to kernel buffer, until it decides it's time to modify storage data.
Turning back to your question. Any kind of buffering is done to accumulate data in order to postpone turning to more expensive operations: standard library may consider invoking syscall on every len
-byte expensive, kernel considers going to hard disk on every syscall expensive and so on.
You might want to read this to see how far buffering goes https://fgiesen.wordpress.com/2015/10/25/reading-and-writing-are-less-symmetric-than-you-probably-think/
Upvotes: 17
Reputation: 715
The FILE structure holds the information about the opened file.this defines the FILE struct members. But in kernel level a file has been accessed by inode, buffer cache.
Data is getting read/write to disk from user space through buffer cache using method copy_to_user and copy_from_user.
Upvotes: 0
Reputation: 72639
The FILE
structure holds the meta data about the opened file (mode, stream position, etc). It is part of the C Standard I/O interface.
The buffer allocated as part of FILE
takes only a limited amount of data (e.g. when the stream is buffered). It is deallocated upon fclose()
. You may even provide your own user space stdio buffer with setvbuf()
.
The kernel buffer receives the file contents written by write()
, whenever the stream is flushed or the associated file descriptor is closed.
Upvotes: 1