I am currently learning how to write Linux device drivers and I have trouble understanding "struct file". I am using the book Linux Device Drivers 3rd edition to help me out.
This is what I understood.
a. struct file represents an open file thus, when open is called in the device driver module, the kernel will create a struct file that includes everything related to the device driver.
b. If you want to pass around this instance of the device driver then one has to pass a pointer to the particular struct file that was created by the kernel after open()
c. file->private_data will always return a pointer to the device.
Another question related to this is the field "f_pos". The book says that the driver can read this value if it wants to know the current position in the file. This is what I understand from it.
d. If struct foo_dev and if the total amount of memory used by this driver to store data is X then f_pos points to the current position in that block of memory reserved by the driver.
How much of what I understood is right and please correct me where I am wrong.
Thanks,
Mir
This is in addition to what andrew has said ...
a) struct FILE is provided by kernel, but it is meant as an interface between kernel and one application.
b) In other words, you cannot pass around FILE structure between multiple applications for sharing a device. The only exception where it is possible to share is between parent & child processes. To access a device or device drivers simultaneously from multiple applications, each app. shall have to call open on the device & create a FILE struct of its own. It is up to the driver whether to allow simultaneous accesses or not. Kernel has no say here.
c) private_data is exactly what it says. Data that's private to device driver. Application or library can use this field to communicate data that is very specific for the device driver.
The struct file is created by the kernel and represents the kernels view of your device it allows the kernel to map from a file handle to the device.
The struct file only contains the data the kernels upper layers needs, this is unlikely to be everything you need for your driver, if you need extra storage to track your devices status (and generally you will) you need to allocate the memory for your structure yourself either in the open function or more normally when you detect your hardware.
If you do allocate storage then you can use the file->private_data to allow you to get from the struct file thats passed to your driver by read / write / etc to your structure.
How the file->private_data is used is up to the driver, the kernel doesn't touch it. Its just there for the drivers use.
The f_pos field is a legacy from the kernel using the same struct file for devices and files. It is an index into a file were the next operation will happen, it depends on your device if this makes sense, if your device supports some form of random access (say a ram device) then using f_pos and implementing lseek might make sense, if you hardware is sequential then f_pos is normally irrelevant.