I'm trying to make use of inode's i_private and store a struct with name and block number in it:
struct osffs_inode_private_info* info;
inode->i_private = kzalloc(sizeof(struct osffs_inode_private_info), GFP_KERNEL);
inode->i_private = info;
strncpy(inode->i_private->name, "private succ", OSFFS_MAX_NAME_LEN);
Where the struct is defined as follows:
struct osffs_inode_private_info {
char name[OSFFS_MAX_NAME_LEN];
__be64 block;
};
When I try to compile, I get a warning that I am
"dereferencing a 'void *' pointer"
and an error
"request for member ‘name’ in something not a structure or union"
in the line where I do the strncpy()
.
I know there are many threads/questions about dereferencing a void pointer and it seems like I just have to do a cast or such. But unfortunately, I don't know how to apply that to my problem.
First of all, in your code
inode->i_private = kzalloc(sizeof(struct osffs_inode_private_info), GFP_KERNEL);
inode->i_private = info;
you're leaking memory. In the later statement, you're overwriting the previous pointer in inode->i_private
by assigning to it.
maybe you wanted to do
info = inode->i_private;
That said, the issue in the question is with the said usage of i_private
. This being a void
pointer, cannot be dereferenced.
Quoting C11
, chapter §6.5.2.3, Structure and union members
The first operand of the
->
operator shall have type ‘‘pointer to atomic, qualified, or unqualified structure’’ or ‘‘pointer to atomic, qualified, or unqualified union’’,[...]
That's why, you have to cast the void *
to the pointer-to-required-type to make that eligible to be used as the left-operand for member access operator (->
).
You need to use something like
strncpy( ((struct osffs_inode_private_info *)(inode->i_private))->name,
"private succ",
OSFFS_MAX_NAME_LEN);