35e4 The FreeBSD Forums - View Single Post - Help with Inode
Thread: Help with Inode
View Single Post
  #11  
Old January 14th, 2012, 07:06
monkeyboy monkeyboy is offline
Junior Member
 
Join Date: Apr 2009
Posts: 82
Thanks: 4
Thanked 10 Times in 10 Posts
Default

Quote:
Originally Posted by GroupInode View Post
Thank you for your reply monkeyboy.
I have decided to go with your suggestion. I am now stuck as to how is VFS actually triggered in the file system. I read vfs_syscalls.c , vfs_nops.c as well as vfs_ops.c etc.

Now the real puzzle for me is that, for the actual inode and the dinode structures the system calls like stat() and open() have only two arguments. Whereas, the similar system calls specified by VFS have 5 arguments ( most probably taking the form of struct fileops).

I tried to search a lot but couldn't get the actual place where the distinction is made OR where the 2 arguments become 5 arguments and back again. Really need some help with this.

I need to trace

1. How the system calls are invoked
2. Referring which source code files
3. Also need to check the arguments and their return values
4. FINALLY, the transition from the 2 argument format to 5 argument format

Any ideas?
I don't have ready access to full source right now. I can't answer all your questions. However I will try to take a few stabs.

First, I don't think the answers to your questions are really needed to get the work done that you want, assuming that I understand what you are trying to do. The details of how a syscall ends up within vfs_syscalls.c shouldn't matter since, AFAIK, you won't be needing to change any syscalls, the number of arguments or adding any syscalls. I believe all you really need to do is to add a few fields to the struct returned by stat(2). Thus the struct stat returned will have to be larger, but I think that is the only change that you need to make, from a syscall standpoint. Then of course, all utilities that call stat(2) will have to be recompiled, and you will want to add new code in ls(1), perhaps other user commands as you have the energy, like find(1). The tricky ones will be things like dump/restore -- I haven't looked at that issue at all.

I am going mostly from memory here and would need full source to be certain and more detailed, but... the path from syscall to vfs_syscalls.c would be something like this...

A program like ls(1) makes a stat(2) call. It is a C library routine that has its arguments pushed on the stack and then issues a trap instruction (machine dependent). The kernel's trap handler gets control and now you are in kernel space instead of user space. The trap handler determines which syscall was responsible for the trap, presuming it is legal. It is machine dependent: some CPU's encode the syscall number right in the trap instruction, others may have other mechanisms to carry that number into the kernel, like sticking the syscall number in a register.

A list of syscall numbers is in /usr/include/sys/syscall.h . These numbers are actually an index into the table sysent[] which has a structure defined in /usr/include/sys/sysent.h.

This sysent[] table also contains the function pointer to the kernel routine that is to handle the syscall. Its all in the file init_sysent.c.

Remember that the real arguments to the syscall were pushed on the stack in user space. The kernel has to go and fetch them out of user space. IIRC, some implementations have the C library support code fashion an argument block before issuing the trap (I think as pointers immediately following the trap instruction), but in either case, the arguments still live in user space, though short arguments can be passed via the user registers.

As far as return values from the syscall, I believe the kernel sets the value of one of the registers which will be restored during the process of returning from the trap. Other values returned are implemented by having the kernel directly writing user memory, using the pointers presented as arguments to the syscall. This is what happens to return the struct stat from the stat(2) call.

Again, although educational, I don't see why you need to know the details of any of this since, to my understanding, your mods shouldn't have to change any of this. Instead look into the kernel side of stat(2) and the definition of struct stat and start by adding extra fields (muid, mgid) to it, set by vn_stat() -- It looks to me that the business end of stat(2) is indeed in vn_stat(). So that part looks pretty easy...

More later... Let's see if you can make the simple mods to struct stat and vn_stat and have ls(1) get the new info...

(to be really explicit, add the fields st_muid and st_mgid to struct stat, then in vn_stat(), set them to something like sb->st_muid = 42; sb->st_mgid = 43; then recompile the kernel and at least ls.c if not the world (probably safer since all programs that call stat(2) will now be broken. If you don't want to change the sizeof struct stat at this early stage (wise), it looks like there is some extra padding currently there that could be used to start with).

Last edited by DutchDaemon; January 20th, 2012 at 21:41. Reason: Proper formatting: http://forums.freebsd.org/showthread.php?t=8816
Reply With Quote
The Following User Says Thank You to monkeyboy For This Useful Post:
GroupInode (August 13th, 2012)
 
0