Getting inode from path in Linux Kernel - linux

I'm currently trying to get an inode for a given pathname in a kernel function. All I have available is the full pathname. I've tried attempts like:
user_path_at(AT_FDCWD, buffer, LOOKUP_FOLLOW, &path);
But the dentry in that given path isn't valid, it seems to turn out. Then I thought perhaps trying stat() and getting the inode number from that. However, that only gives me a number, not a struct inode. I don't know of a way to convert an inode number to an inode without grabbing an existing inode and traversing the entire list of inodes. And I don't even know if that would work. But I certainly don't want to do that.
Is there any simple way to get a struct inode from a char *pathname inside the kernel?

stat() will give you the inode of a file in the "st_ino" field.
Sorry, initial misunderstanding of the question.
If you want the actual inode structure within the kernel, I'm pretty certain the kernel itself wouldn't walk an array or list looking for the inode number (unless the list is very small). Since the code to the kernel is publicly available, you should be able to find out how it does it, then do the same.

There is no easy way since struct inode is part of the kernel and you are in user space. It all depends on the particular filesystem implementation. Are you sure that info in stat struct is not enough for your needs?
Anyway, this link might help.

Related

Resolving file descriptor to file name / file path

I am currently developing a simple kernel module that can steal system calls such as open, read, write and replace them with a simple function which logs the files being opened, read, written, into a file and return the original system calls.
My query is, I am able to get the File Descriptor in read and write system calls, but I am not able to understand how to obtain file name using the same.
Currently I am able to access the file structure associated with given FD using following code:
struct file *file;
file = fcheck(fd);
This file structure has two important entities in it, which are of my concern I believe:
f_path
f_inode
Can anybody help me get dentry or inode or the path name associated with this fd using the file structure associated with it?
Is my approach correct? Or do I need to do something different?
I am using Ubuntu 14.04 and my kernel version is 3.19.0-25-generic, for the kernel module development.
.f_inode is actually an inode.
.f_path->dentry is a dentry.
Traversing this dentry via ->d_parent link, until f_path.mnt.mnt_root dentry will be touched, and collecting dentry->d_name components, will construct the file's path, relative to the mount point. This is done, e.g., with d_path, but in more carefull way.
Instead of fcheck(fd), which should be used inside RCU read section, you can also use fget(fd), which should be paired with fput().
The approach is completely incorrect - see http://www.watson.org/~robert/2007woot/
Linux already has a reliable mechanism for doing this thing (audit). If you want to implement it anyway (for fun I presume), you want to place your hooks roughly where audit is doing that. Chances are LSM hooks are in appropriate places, have not checked.

What kind of macro correspond to what kind of file system in linux

What kind of macro correspond to what kind of file system in linux.
in ReadHat linux
Here is [a Link] http://lxr.free-electrons.com/source/include/uapi/linux/magic.h#L24
Eg:
#define EXT2_SUPER_MAGIC 0xEF53
#define EXT3_SUPER_MAGIC 0xEF53
#define EXT4_SUPER_MAGIC 0xEF53
------------------------------> are file system EXT2/EXT3/EXT4
what is the others?// HFS、NFS、XFS、JFS、Minix fs ......
Thanks!
The magic.h file you refer to isn't really usable to identify filesystems by their format's magic numbers. For one thing, it gives magic numbers for some filesystems but it doesn't say anything about where in the filesystem's on-disk format to look for it! For example, the 0xef53 magic number you cite for ext* must be found by looking at offset 0x438 from the start of the filesystem whereas the magic number in an XFS filesystem is found right at the beginning (byte offset 0) and you can look for reiserfs's magic number at offset 0x10034. It is not even strictly necessary for a filesystem to be identifiable by magic number – it's just good practice. As such, that magic.h file can never really be complete nor useful.
If you want to identify different types of filesystems, I suggest using file. You can look at the filesystems magic file from its source code. It contains matching rules for most of the filesystem types you mentioned.
Note: you mentioned NFS too. As NFS is a network filesystem and doesn't have any on-disk format, how could it have a magic number like the others?
This is an old question, but I will provide my perspective for anyone digs it up as I did looking for the reason why linux/magic.h seems incomplete and I see no definition for XFS_SUPER_MAGIC or the value I believe it should be in any system header files.
It depends on what you are trying to accomplish. If, for example, you are trying to read from some media that you don’t know the formatting of then Celada is correct you are going to need more information about the layout of that file system and in cases like NFS it may be that the magic number does not make sense.
However, if you are using the statfs() system call to determine what type of file system an inode is on, perhaps looking at dirent entries or something of that nature then the magic numbers in linux/magic.h identify file systems fairly well as far as i can tell. Unfortunately there appear to be gaps as I’ve discovered looking for one for XFS. Which by the way seems to be returned from statfs() as 0x58465342. For better or worse (likely worse unfortunately), I have for now:
#include <linux/magic.h>
#ifndef XFS_SUPER_MAGIC
#define XFS_SUPER_MAGIC 0x58465342
#endif

Can inode and crtime be used as a unique file identifier?

I have a file indexing database on Linux. Currently I use file path as an identifier.
But if a file is moved/renamed, its path is changed and I cannot match my DB record to the new file and have to delete/recreate the record. Even worse, if a directory is moved/renamed, then I have to delete/recreate records for all files and nested directories.
I would like to use inode number as a unique file identifier, but inode number can be reused if file is deleted and another file created.
So, I wonder whether I can use a pair of {inode,crtime} as a unique file identifier.
I hope to use i_crtime on ext4 and creation_time on NTFS.
In my limited testing (with ext4) inode and crtime do, indeed, remain unchanged when renaming or moving files or directories within the same file system.
So, the question is whether there are cases when inode or crtime of a file may change.
For example, can fsck or defragmentation or partition resizing change inode or crtime or a file?
Interesting that
http://msdn.microsoft.com/en-us/library/aa363788%28VS.85%29.aspx says:
"In the NTFS file system, a file keeps the same file ID until it is deleted."
but also:
"In some cases, the file ID for a file can change over time."
So, what are those cases they mentioned?
Note that I studied similar questions:
How to determine the uniqueness of a file in linux?
Executing 'mv A B': Will the 'inode' be changed?
Best approach to detecting a move or rename to a file in Linux?
but they do not answer my question.
{device_nr,inode_nr} are a unique identifier for an inode within a system
moving a file to a different directory does not change its inode_nr
the linux inotify interface enables you to monitor changes to inodes (either files or directories)
Extra notes:
moving files across filesystems is handled differently. (it is infact copy+delete)
networked filesystems (or a mounted NTFS) can not always guarantee the stability of inodenumbers
Microsoft is not a unix vendor, its documentation does not cover Unix or its filesystems, and should be ignored (except for NTFS's internals)
Extra text: the old Unix adagium "everything is a file" should in fact be: "everything is an inode". The inode carries all the metainformation about a file (or directory, or a special file) except the name. The filename is in fact only a directory entry that happens to link to the particular inode. Moving a file implies: creating a new link to the same inode, end deleting the old directory entry that linked to it.
The inode metatata can be obtained by the stat() and fstat() ,and lstat() system calls.
The allocation and management of i-nodes in Unix is dependent upon the filesystem. So, for each filesystem, the answer may vary.
For the Ext3 filesystem (the most popular), i-nodes are reused, and thus cannot be used as a unique file identifier, nor is does reuse occur according to any predictable pattern.
In Ext3, i-nodes are tracked in a bit vector, each bit representing a single i-node number. When an i-node is freed, it's bit is set to zero. When a new i-node is needed, the bit vector is searched for the first zero-bit and the i-node number (which may have been previously allocated to another file) is reused.
This may lead to the naive conclusion that the lowest numbered available i-node will be the one reused. However, the Ext3 file system is complex and highly optimised, so no assumptions should be made about when and how i-node numbers can be reused, even though they clearly will.
From the source code for ialloc.c, where i-nodes are allocated:
There are two policies for allocating an inode. If the new inode is a
directory, then a forward search is made for a block group with both
free space and a low directory-to-inode ratio; if that fails, then of
he groups with above-average free space, that group with the fewest
directories already is chosen. For other inodes, search forward from
the parent directory's block group to find a free inode.
The source code that manages this for Ext3 is called ialloc and the definitive version is here: https://github.com/torvalds/linux/blob/master/fs/ext3/ialloc.c
I guess the dB application would need to consider the case where the file is subject to restoration from backup, which would preserve the file crtime, but not the inode number.

Kernel security modules: i_security in struct inode

my question is probably again pretty simple, but I did not find anything. I am writing a Linux Security Module. As you might know the struct inode in the kernel contains one field i_security to save security relevant information for the LSM. Now just to make sure: Is it safe to assume that no user (not even root) will be able to read or write this value, i.e. can this value really be accessed only from kernel space?
The reason for my question is, that it is obvious that some inode data can be accessed from userspace (through systemcalls I guess, but still using chmod etc. you are able to change some values in an inode) and now I wonder if that doesn't mean, that all inode data (also the i_security) can be accessed from user space somehow.
Cheers
Yes. You can use grep or ack to scan kernel code for i_security, and you can find it is modified only by files under security/ directory, and cannot be modified by user applications, since they have no direct access to the i_security field.

In a linux kernel module, how can I get inode of a known path

In a linux kernel module (i.e. working in kernel space), I have a path of a file.
Which function(s) can be used to get the inode of that file. Specifically I need to get the "inode *" pointing to the file's inode.
You don't have to open the file. There is a lookup function available in kernel which translates char *name to struct nameidata. Please refer to path_lookup.
You may also want to take a look at how path resolution algorithm works, here.
You can use the filp_open function, but as stated in the comment of the function, opening files in kernel module is not something you want to do.
Here is a function that will return the struct file for your path. From there I think you can go to the inode
Bonus : May be this is not what you intend to do, but here is an article on file reading / writing from the kernel, and why you don't want to do it.
Based on my experience with kernel, I suggest that you always go for top level functions like path_lookup rather than functions in the middle.

Resources