As I understand, the lookup function in VFS works as follows, for resolving the path /x/y (where y is a directory). First, the inode of / is stored in the superblock, and is pointed to by the dentry of superblock. The kernel calls lookup to look for x in the inode of /, and passes it the dentry of x. What I then do is attach the passed dentry of x a new inode. Then, I expect, the kernel would call lookup, pass it the inode of x I created and the dentry of y, I then should create an inode of y and attach it to the dentry of x. However, when I do this implementation, and do an "ls /x/y", lookup is only called for x, but not for y (I used printk to know that). Is there something wrong in my logic?
I am writing a simple pseudo file system driver, that is merely responsible for resolving a Path, and according to its contents, communicates with a user-level API.
Here is the code of inode_operations.lookup! I am just testing my logic with it, but something is wrong. What I am trying to do is to resolve the path to reach the deepest directory (or inode), so I would fill its contents later with file_operations.readdir. In this code, I only create an inode for each request and attach it to the passed dentry.
With this code, and when doing "ls /x/y/", lookup is not called on y. It is only called on x. However, if I do "ls /x/" I do get the results I hard coded in readdir (note: there is no logic in readdir, it fills the results irregardless of the passed file structure contents).
Code:
my_lookup(struct inode *parent_inode, struct dentry *dentry, struct nameidata *nameidata) {
printk("my_lookup:\t");
printk(dentry->d_name.name);
printk("\n");
// i is a global variable.
struct inode *file_inode iget(parent_inode->i_sb, FILE_INODE_NUMBER + i);
i++;
if(!file_inode) {
printk("Can't allocate the inode\n");
return ERR_PTR(-EACCES);
}
file_inode->i_size = file_size; // some fixed value
file_inode->i_mode = S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH|DT_DIR;
file_inode->i_op = &my_iops;
file_inode->i_sb = parent_inode->i_sb;
d_add(dentry, file_inode);
out:
return NULL;
}
I know my question might be answered in proc's code, but disecting it would require some time I am short of. :-(