This is more or less a question about methodology and rationale than anything. In programming various kernel modules for Linux, I'm confounded by what I consider to be a clunky way of designing functions. For example, to retrieve the inode of a file given its path, I had to use something like:
struct inode *inode;
struct path path;
kern_path(path_name, LOOKUP_FOLLOW, &path);
inode = path.dentry->d_inode;
Why not just a function that works like:
struct inode inode;
struct path path = kern_path(path_name, LOOKUP_FOLLOW);
inode = path.dentry->d_inode;
Seems much more intuitive.
And what would you do with the int
that kern_path
returns?
It's important for functions to be able to return some kind of error code so the user can ensure the function succeeded. There are two obvious options:
Return the error code.
This means you must take the other value that you'd like to return as a parameter.
Return the value.
This means you must take the error code as a parameter.
Since you can only return 1 value in C, you've got to take something as a parameter, as ultimately you want to return two things to the user (the error code and the value).
The kernel is a C program with special constraints. In particular, the call stack is not allowed to be deep (IIRC, it is limited to 4Kbytes).
When you return a struct
, the ABI (see the x86-64 ABI ...) mandates that (except for some short struct
fitting in two words) the returned struct
goes thru the stack. So such a style would favor quite big stack frames, hence would more easily meet the stack limit.
BTW, the usual style would be to return some integer error code, and modify the data pointed by argument pointers.
On x86-64/Linux returning a structure of two scalar values (integers, pointers, enums, doubles, ....) is definitely worth it, see this.
That has a benefit of reducing copying memory blocks back and forth.
Using this methodology allows the invoked function to only modify certain parts of the passed in struct and no memory is being copied at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With