Reading raw bytes from inode in kernel space

Using C and working from inside kernel space, is it possible to read the i_flags data directly from the inode and see the full unsigned long value, rather than the value / settings of only the supported flags?

I am using kernel 3.10.0 on Centos 7 on top of Oracle VirtualBox.

I'm sorry if this question doesn't make sense, I'm pretty new to this and trying to educate myself on how things work. I have been struggling with this for some time and have read so many different things that I am getting more and more confused.

To put it simply, I'm trying to read the i_flags field in a variable and then check the state of the individual bits (perhaps using test_bit?) Whether they represent flags that are supported or implemented in the kernel or elsewhere. I think this data can be accessed from raw 32-bit data in the i_flags field?

Should I read x number of bytes from an inode starting at a given location? Or is there an easier "read" method that I just can't see? Can this be done?

Any pointers would be greatly appreciated.

Horn

Additional Information -

Here is the code that I am using to link to i_flags -

printk(KERN_INFO "inode value = %lu\n", file_inode(file)->i_flags); 

      

I don't understand if this is the equivalent of the suggested format below -

unsigned int flags = inode_pointer->i_flags

      

My version prints 0 even though the "e" flag is on by default. Shouldn't there be a value other than 0 indicating the "e" flag?

If I use chattr to add the "a" and "i" flags, it now returns 12 in the i_flags field, which makes sense. However, if I add the "d" flag, I still see 12.

If I get the original value from the inode field (i_flags), shouldn't turning on the "d" bit cause the value to change?

thank

Horn

Additional Information -

Here's what I did to check the values.

rls is a copy of / usr / bin / ls. The following commands show the addition of "i" and "a" to / usr / bin / rls. Lsattr then confirms that these flags are set.

sudo chattr + ia / usr / bin / rls

lsattr / usr / bin / rls ---- ia ------- e--

Running "rls" causes the output of the above printk statement to be logged to / var / log / messages. The flag value is 12 because i and a are set.

RLS

06.29 14:46:15 localhost kernel: inode value open_exec lu = 12

Then add the "d" flag.

sudo chattr + d / usr / bin / rls

And run lsattr against rls to see a flag showing the "d" flag set

lsattr / usr / bin / rls

---- iad ------ e--

Run "rls" again, flags value remains 12

RLS

06.29 14:53:21 localhost kernel: inode value open_exec lu = 12

Shouldn't i_flag be something else with the "d" flag added?

Thank,

Horn

+3


source to share


1 answer


If I understand correctly, you have a memory address struct inode

and you want to be able to read the i_flag

entire field instead of using bitwise operations to check for a specific flag.

If so, you can simply do:

 unsigned int flags = inode_pointer->i_flags

      



i_flags

- it's just unsigned int

(at least in 3.10.0) and you can access it just like any other unsigned int

. Since we view it as a flag, normal operations such as multiplication are usually not performed on it, but it is consistent and should be done by programmers. The compiler does not know or care whether it is used unsigned int

as a group of flags (as in the case i_flags

), where each bit has some meaning, or whether it is used as an integer, where it is a single number.

Update

I believe (but honestly, I'm not 100% sure) the problem is that some of the attributes chattr

don't map to bit values i_flag

. You can find the bitmasks used from i_flag

here . For example, it chattr

a

matches S_APPEND

, which has a value of 4, which is the same as what you see, but I can't find anything that matches d

in the bitmax list i_flag

.

0


source







All Articles