What are the "struct file_operations" arguments? - linux

I'm implementing a Linux character device driver.
The linux/fs.h header file lists the file_operations without argument names.
e.g.
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, loff_t, loff_t, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
int (*check_flags)(int);
int (*flock) (struct file *, int, struct file_lock *);
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
int (*setlease)(struct file *, long, struct file_lock **);
long (*fallocate)(struct file *file, int mode, loff_t offset,
loff_t len);
};
Where is the documentation that tells me what each argument is? Some are sort-of obvious, but some aren't. I prefer to refer to official documentation if I can, but I just can't find it.
e.g.
int (*fsync) (struct file *, loff_t, loff_t, int datasync);
There are two loff_t arguments. How do I know what they do?
I've been Googling and reading the device driver book, but I can't find any documents that explain what the arguments are for. Some of the arguments have also changed from when LDD3 was written.

The LDD3 book is very useful still to understand the big picture, but it won't help with details (it is for kernel 2.6.10, meanwhile we are marching towards 3.9). The kernelnewbies drivers page is perhaps the most up-to-date, comprehensive resource. For day-to-day changes, LWN regularly comments on API changes and publishes longer overviews for new features. H-online carries a series of articles detailing changes from kernel version to kernel version, with links to discussions and patches.

I had to implement my first linux driver a while back. By far the best thing I think you can do is download the Kernel source for the version you're developing against. Within the kernel source tree there is a directory called /Documentation. I'd start there, last I checked this is the "Official Documentation" for the kernel.
That being said, once you have the source code there really isn't a better documentation than reading the code and seeing what it's used as. For things like this, I'd look through /drivers/fs/ and find an example of where this struct is used and see how they're using it.

There is also now some minimal in-tree documentation at Documentation/filesystems/vfs.rst rendered at: https://www.kernel.org/doc/html/latest/filesystems/locking.html#file-operations but it doesn't really say anything that is not obvious from signatures. They should just put that stuff on Doxygen comments.
I'm also maintaining several runnable examples at: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/9be19ae1cf3f3f346a5bc25f4a4d1e1cbac23cb3#file-operations which might be of interest.

Related

glibc ucontext: how does setcontext set the sigmask?

This is the structure of ucontext_t:
typedef struct ucontext_t
{
unsigned long int __ctx(uc_flags);
struct ucontext_t *uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
sigset_t uc_sigmask;
struct _libc_fpstate __fpregs_mem;
__extension__ unsigned long long int __ssp[4];
} ucontext_t;
I know uc_sigmask specifies the signals to be blocked after a setcontext. But how is it implemented? Is it atomic to set sigmask and set up registers and jmp to to the target rip?

GCD dispatch_set_target_queue function's 1st parameter type

The function prototype is this:
void dispatch_set_target_queue(
dispatch_object_t object,
dispatch_queue_t queue);
typedef union {
struct dispatch_object_s *_do;
struct dispatch_continuation_s *_dc;
struct dispatch_queue_s *_dq;
struct dispatch_queue_attr_s *_dqa;
struct dispatch_group_s *_dg;
struct dispatch_source_s *_ds;
struct dispatch_source_attr_s *_dsa;
struct dispatch_semaphore_s *_dsema;
struct dispatch_data_s *_ddata;
struct dispatch_io_s *_dchannel;
struct dispatch_operation_s *_doperation;
struct dispatch_fld_s *_dfld;
} dispatch_object_t __attribute__((transparent_union));
I am confused why below code could pass compiling???
dispatch_queue_t queueA = dispatch_queue_create("com.effectiveobjectivec.queueA", NULL);
dispatch_queue_t queueB = dispatch_queue_create("com.effectiveobjectivec.queueB", NULL);
dispatch_set_target_queue(queueB, queueA); // will set queueA as queueB's target
I don't see any field in dispatch_object_t Union is a dispatch_queue_t, so how can queueB argument cause no compile errors?
Also. I wonder what "struct dispatch_object_s *_do;" field is? What is "struct dispatch_queue_s *_dq;"?
You can think of dispatch_object_t as the "base class" of all the dispatch object types.
In "plain" C this uses the transparent union GCC extension, which essentially allows all pointer types in the union to be treated interchangeably with the union type when used as a function argument.
the macro below the block you quoted from dispatch/object.h explains the connection with dispatch_queue_t:
#define DISPATCH_DECL(name) typedef struct name##_s *name##_t
and then later on in dispatch/queue.h
DISPATCH_DECL(dispatch_queue);
i.e. dispatch_queue_t matches the _dq member of the transparent union and hence is a valid type to pass to the dispatch_object_t argument of dispatch_set_target_queue.
FWIW in Objective-C and C++ the dispatch_object_t superclass relationship is expressed using the respective object type system, c.f. the other sections in the dispatch_object_t area of dispatch/object.h.

How to get base address of struct proc_dir_entry

Is there any struct that one of its fields contain a pointer to proc_dir_entry? and such a pointer to proc_inode struct?
For example field files or mm of task_struct points to files_struct and mm_struct.

Malloc a struct within a struct?

I decided to use structs in this program to keep it organized so I now have a chain of structs. My question is if I must malloc a struct that is within another struct. For example:
typedef struct OnlineS {
struct BBSIS *bbsi;
struct BBVIS *bbvi;
struct VBVIS *vbvi;
} *OnlineP;
typedef struct BBSIS{
struct FirstFitS *ff;
struct BestFitS *bf;
struct NextFitS *nf;
int itemNum;
int binNum;
int binMin;
int binMax;
int *items;
}*BBSIP;
And so on, so would my declaration and mallocs look like?
OnlineP on = malloc(sizeof (struct OnlineS));
on->bbsi = malloc(sizeof (struct BBSIS));
on->bbsi->bf = malloc(sizeof (struct BestFitS));
on->bbsi->nf = malloc(sizeof (struct NextFitS));
on->bbsi->ff = malloc(sizeof (struct FirstFitS));
on->bbvi = malloc(sizeof (struct BBVIS));
on->bbvi->bf = malloc(sizeof (struct BestFitS));
//ETC
If you use pointers to structs within a struct you must manage memory for that as well. (malloc/free)
If tou use structs within a struct you do not manage memory for the internal structures. Since they are part of the outer struct there is no need to.
You use pointer to structs in your outer struc so you must use malloc and free.
First allocate memory for your outer struct, then set all pointers to the inner structs to null or allocate memory for it.
There is no struct in your struct.
There is a pointer in your struct, and the memory for the pointer was allocated.
Consider the following construct:
typedef struct node {
struct node* next;
}
(Which is very common - a linked list)
How many nodes should it allocate?

C typedef struct redefinition, different basic types

First time posting here. I have problem about referencing a typedef struct from separate files. Example:
main.c //menus and variables declaration
#include <stdio.h>
#include <string.h>
#include "person.h"
#include "person.c"
person persondata[50] ;
person.h //typedef struct{...}person;
typedef struct
{
char name[50];
}person;
person.c //functions
extern persondata[];
void copy()
{
strcpy(persondata[0].name, "John");
}
I keep getting error: left of ".name" must have struct/union type and redefinition, different basic types
How am I supposed to fix this reference?
Typically you would #include "person.h" so as to make the declaration of person visible, and then you would change the persondata declaration to:
extern person persondata[];
... i.e. specify its type.
Write
extern person persondata[];
instead.
This should do the trick.
If you don't give it the correct type, the compiler won't know that persondata is an array of persons.
extern persondata[]; is implicitly equivalent to extern int persondata[]; (the compiler assumes int if you don't specify a type). You need extern person persondata[];.
Also, the compiler needs to be able to see the definition of person in person.c, so add #include "person.h" at the top of the file.
You need:
#include "person.h"
person persondata[10];

Resources