After some research and a host of failed attempts, I was able to find a simple procedure to read the contents of a file sitting in memory. It should be noted that I am currently working with a 2.4.18-3 or otherwise known as redhat 7.3 stock kernel. After opening a file, I use the function bread() to pull the buffer_head structure into memory. The bread() function looks like:
struct buffer_head *bread(parition device, logical block number, block size);
By partition device, I refer to something like /dev/hda2 and not /dev/hda. This is because the logical block number used is based off of the file system of the partition. Now the logical block number is something I have not figured out yet, so for now I hardcode it. My teacher stated today that it should be located in the i_data array of the ext2 inode. If so it would be something like:
inode->u.ext2_i.i_data[];
The element of the array would depend on the number of block for this file, of course.
So the buffer_head structure returned by bread() has the char * b_data that points to the actual data of the file placed in memory. Now you may want to add in something like, “of course dumb ass it says that in the comment next to the b_data element”. And I would say, “True but it is the bread() function that brings it to the table, not that awful getblk() function I was using for a week before that drove me crazy.” I “touched the sides... buzzzzzz!” with that one (remember it’s like playing operation with a pair of pliers for me).
So finding the data sitting in memory was a big deal. Of course there is not time to celebrate; it is time to write. I read in Understanding the Linux Kernel 2nd edition that all you have to do is mark the page/buffer dirty and sit back wait for it to be wrote to disk. Well that sounded simple, and for the life of me, I not sure why it didn’t work for me. I tried:
set_bit(BH_Dirty, &bh->b_state); // no success
SetPageDirty(bh->b_page); // no success
write_inode_now(inode, 0); // why not try this, no success
Ok, I can’t write now. And my deadline is fast approaching to complete this project. So in the interest of graduating, my teacher stated (today) that we are placing the Accessing a File Data in Memory on the back burner. The focus now, back to bmap. Shit that sucks, but it is my fault. It I would have got it work, I would be in business and exclusively working within the kernel.
So now I am going to customize (aka strip out non-essential crap) bmap to perform a few simple tasks that I will need it to do (basically moving data in and out of slack space). Then build an interactive kernel module to fulfill the slack space file system requirements. Those requirements are basically building and maintaining the structures. And intercepting system calls to prevent the loss of slack data. Oh did I mention that? I am going to redirect system calls? Well that is why I am working in 2.4. Spent a *few* weeks attempting to redirect system calls in 2.6 and I found out there is no /dev/kmem in fedora. That is the jist of that story, but I have some code I could still try to redirect 2.6 system calls.
Now if you are like most people you are thinking, “uhm redirection of syscalls is the devil’s work, and you will go to windows... err I mean hell.” Yea I know. I presented the option of interception at the VFS layer to my teacher. It didn’t fly.
Final thought. Even though I feel I am coping out by using bmap for user space manipulation of slack space, I did get a big kick out of poking around in the kernel. You can’t possibly appreciate the intelligence and raw wisdom of kernel developers until you ‘read and work with the code’. Or for me blindly stumble in the kernel, knocking over structures and stepping on raw memory.
My deepest admiration for kernel developers and contributors.