[Help] How to Replace File Operations in File System?
Hi list, I am a newbie in linux kernel programming. Recently I got stuck in a problem when doing practice in file system programming. I hope this list is the right place I can turn to. I want to replace some file operations of files in a certain directory,so that data can be decrypted/encrypted through read/write system call. So I: #1: Find the directory inode, save its original inode operation table,then replace the table: kern_path(pathname, LOOKUP_FOLLOW, &target_dir_path); lower_iops = target_dir_path.dentry->d_inode->i_op; target_dir_path.dentry->d_inode->i_op = &my_iops; #2: In my_iops, I mainly changed ".lookup" function like this to achive my goal -- replace the file operation table of all files in the directory. static struct dentry *my_inode_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct dentry *ret_dentry; ret_dentry = lower_iops->lookup(dir,dentry,nd); if (!ret_dentry) goto out; ret_dentry->d_inode->i_fop = &my_fops; out: return ret_dentry; } Things turns out that replacement of inode operation table of directory is successful but the changes in file operations are not functional: system works as it used to, totally ignore my_fops! I have no idea how to fix it. Can anybody help? Thanks for your attention! Regards Freeman Zhang
Hi, On Thursday 13 February 2014 07:40 AM, freeman wrote:
Hi list,
I am a newbie in linux kernel programming. Recently I got stuck in a problem when doing practice in file system programming. I hope this list is the right place I can turn to.
I want to replace some file operations of files in a certain directory,so that data can be decrypted/encrypted through read/write system call. So I:
#1: Find the directory inode, save its original inode operation table,then replace the table:
kern_path(pathname, LOOKUP_FOLLOW, &target_dir_path); lower_iops = target_dir_path.dentry->d_inode->i_op; target_dir_path.dentry->d_inode->i_op = &my_iops;
I assume that you are writing your own stackable filesystem. Take a look at WRAPFS[1] and ecryptfs[2]. As a matter of fact, ecryptfs does what you are expecting. To do this, you need to set your superblock operations for the lower directory inode so the VFS use your filesystem instead of the original filesystem. Important steps to look are: 1. get lower superblock from the lower directory inode 2. assign this superblock as an overlay for your own superblock. 3. Set your own superblock operations for the new superblock 4. get a root inode for your superblock using the lower directory inode 5. While you are getting the inode, you can set the file operations on this inode which will help you achieve your case. The point to note that you need to interpose the inodes with VFS so that everything would be routed to your filesystem. -- Abhijit. [1]http://wrapfs.filesystems.org/ [2]http://ecryptfs.org/
#2: In my_iops, I mainly changed ".lookup" function like this to achive my goal -- replace the file operation table of all files in the directory.
static struct dentry *my_inode_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct dentry *ret_dentry;
ret_dentry = lower_iops->lookup(dir,dentry,nd); if (!ret_dentry) goto out; ret_dentry->d_inode->i_fop = &my_fops; out: return ret_dentry; }
Things turns out that replacement of inode operation table of directory is successful but the changes in file operations are not functional: system works as it used to, totally ignore my_fops!
I have no idea how to fix it. Can anybody help? Thanks for your attention! Regards
Freeman Zhang
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
For encrypt/decrypt on file operations, a stackable filesystem needs to exist between VFS and the lower filesystem(suppose ext4) and that is what wrapfs and ecryptfs does. Regards, Saket Sinha
Hi, On Thu, Feb 13, 2014 at 12:14 PM, Abhijit Chandrakant Pawar < abhi.c.pawar@gmail.com> wrote:
Hi,
On Thursday 13 February 2014 07:40 AM, freeman wrote:
Hi list,
I am a newbie in linux kernel programming. Recently I got stuck in a problem when doing practice in file system programming. I hope this list is the right place I can turn to.
I want to replace some file operations of files in a certain directory,so that data can be decrypted/encrypted through read/write system call. So I:
#1: Find the directory inode, save its original inode operation table,then replace the table:
kern_path(pathname, LOOKUP_FOLLOW, &target_dir_path); lower_iops = target_dir_path.dentry->d_inode->i_op; target_dir_path.dentry->d_inode->i_op = &my_iops;
I assume that you are writing your own stackable filesystem. Take a look at WRAPFS[1] and ecryptfs[2]. As a matter of fact, ecryptfs does what you are expecting.
To do this, you need to set your superblock operations for the lower directory inode so the VFS use your filesystem instead of the original filesystem. Important steps to look are: 1. get lower superblock from the lower directory inode 2. assign this superblock as an overlay for your own superblock. 3. Set your own superblock operations for the new superblock 4. get a root inode for your superblock using the lower directory inode 5. While you are getting the inode, you can set the file operations on this inode which will help you achieve your case.
The point to note that you need to interpose the inodes with VFS so that everything would be routed to your filesystem.
-- Abhijit. [1]http://wrapfs.filesystems.org/ [2]http://ecryptfs.org/
#2: In my_iops, I mainly changed ".lookup" function like this to achive my goal -- replace the file operation table of all files in the directory.
static struct dentry *my_inode_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct dentry *ret_dentry;
ret_dentry = lower_iops->lookup(dir,dentry,nd); if (!ret_dentry) goto out; ret_dentry->d_inode->i_fop = &my_fops; out: return ret_dentry; }
Things turns out that replacement of inode operation table of directory is successful but the changes in file operations are not functional: system works as it used to, totally ignore my_fops!
I have no idea how to fix it. Can anybody help? Thanks for your attention! Regards
Freeman Zhang
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Freeman - What you are doing seems to be correct - you may have missed some pointer some where. Which file system are you using, are you writing a layer on an existing file system or changing the code of a file system Try adding some debug messages whenever you change the operations which prints the dentry->name of the file, you will get an idea that the correct file's operations are getting modified. -- Regards, Rishi Agrawal
Hi Rishi, Thanks for your reply! I'm sorry that the description of the problem was not clear. I am writing a module(not a filesystem) to replace some operation pointers of Ext4. Just now, I try to print the dentry->name as you said. It seems that I'm modifying the right files. I'm wonderring if my idea is bad: I changed operations of a file both in ->create and ->lookup in inode operations of direcotry. And test the module like this: echo hello > hello (for dir_inode->create and f->write) cat hello (for f->read) Will the file operations be changed back? Or what I modified is some copies of real objects because of the complex caching mechanism? Regards Freeman Zhang
Hi On Thu, Feb 13, 2014 at 6:58 PM, freeman <freeman.zhang1992@gmail.com>wrote:
Hi Rishi,
Thanks for your reply!
I'm sorry that the description of the problem was not clear.
I am writing a module(not a filesystem) to replace some operation pointers of Ext4. Just now, I try to print the dentry->name as you said. It seems that I'm modifying the right files.
I'm wonderring if my idea is bad: I changed operations of a file both in ->create and ->lookup in inode operations of direcotry. And test the module like this:
echo hello > hello (for dir_inode->create and f->write) cat hello (for f->read)
Will the file operations be changed back? Or what I modified is some copies of real objects because of the complex caching mechanism?
Regards
Freeman Zhang
The operations will not change back until your object gets destroyed, whatever be the type of the object. Caching will not cause any issue here. Maybe if you can send the code we can have a look at it. -- Regards, Rishi Agrawal
Hi
The operations will not change back until your object gets destroyed, whatever be the type of the object.
Caching will not cause any issue here.
Maybe if you can send the code we can have a look at it.
-- Regards, Rishi Agrawal Hi Rishi,
It's very nice of you willing to help check my code! I'm now very excited - problem solved! I spent half a day beautifying my code yesterday (so that it won't annoy you that much), and find there is a problem: Every time there is a read/write system call, I saved the lower file ops and address space ops. In their replacement(upper operations), I invoked lower ones. There's a possibility that it might saved the upper operations as lower ones if I open them twice in a short time. At this point, upper operation invoke itself! So I check the operations before truly save and replace them and, it works! Thanks to you and all the amazing people in this amazing list that helped me, now I get both wrapfs and my own non-filesystem module functional for my future work on transparent encryption, and most importantly, I've learned and enjoyed a lot! Regards Freeman Zhang
Hi Abhijit and Saket, Thank you very much for your reply! I did some study on eCryptfs before. I think eCrytfs is a " big ideas for small business". Implementation of a totally new filesystem is quite complex for me to imitate and study. So with the elicitation from eCryptfs, I have this idea to design a simplified module(not another filesystem) to do transparent en/decrypting, by replacing some main function pointers. Thanks to you, now I know there is WRAPFS, which I think is perfectly suitable for my project--short, easy, and highly extendable. If I still cannot fix this problem, I would like to turn to WRAPFS! Much thanks! Freeman Zhang
On Thu, 13 Feb 2014 21:26:43 +0800, freeman said:
eCryptfs, I have this idea to design a simplified module(not another filesystem) to do transparent en/decrypting, by
Doing it transparently is harder than it looks. Key management is a bitch. (Hint - there's a reason why ecryptfs does it the way it does, rather than the simpler way you're attempting to do it...)
On 15 Feb 2014, Valdis.Kletnieks@vt.edu said:
On Thu, 13 Feb 2014 21:26:43 +0800, freeman said:
eCryptfs, I have this idea to design a simplified module(not another filesystem) to do transparent en/decrypting, by Doing it transparently is harder than it looks. Key management is a bitch.
(Hint - there's a reason why ecryptfs does it the way it does, rather than the simpler way you're attempting to do it...) Hi Valdis,
Thanks for your hint! There is no wonder that I got stuck when studying key management of eCryptfs.I think I should pay much more attention to it. Any idea of how to deal with key management? openPGP file format, multitudinous authentication in eCryptfs really make me give up! Regards Freeman
Wrapfs is the most basic stackable filesystem in the linux kernel. After this ecryptfs comes which has been developed using the foundation of Wrapfs. The developer is also the same - Erez Zadok from StonyBrook University. You can contact him for more details Regards, Saket Sinha
participants (5)
-
Abhijit Chandrakant Pawar -
freeman -
Rishi Agrawal -
Saket Sinha -
Valdis.Kletnieks@vt.edu