For a university assignment, we have to modify the ext2 file system to store files in the inode's block pointers if it's smaller than 60 bytes, and move to regular block storage once the file grows larger than that.
I copied the ext2 code from the 2.6 linux kernel source (as instructed) and went from there.
When the file grows larger than 60 bytes, I need to copy any data that is currently in the inode's block pointer array into real blocks. So, I need to write kernel memory into ext2 blocks. A simple call to do_sync_write
won't work here because it takes user-space memory.
I've looked at the implementation of do_sync_write
and I'm not really sure how to replicate what it does, but with kernel memory instead.
This is my current implementation of this specific part (does not work):
ssize_t extmod_write(struct file *filp, const char *buf,
size_t len, loff_t *ppos)
{
...
printk(KERN_INFO "Switching to regular file");
temp = kmalloc(inode->i_size, GFP_KERNEL);
memcpy(temp, EXT2_I(inode)->i_data, inode->i_size);
/* Need to clear the block pointers before they are allocated by kernel */
memset(EXT2_I(inode)->i_data, 0, sizeof(EXT2_I(inode)->i_data));
if (do_sync_write(filp, temp, inode->i_size, &dummy) < 0) {
printk(KERN_INFO "DAMN! Writing current buffer failed");
return -EINVAL;
}
kfree(temp);
return do_sync_write(filp, buf, len, ppos);
Edit:
I looked at symlinks. Basically, ext2 has the concept of "fast symlinks"; i.e. the link name is less than 60 bytes long. If it's a fast symlink, the data gets stored in the block pointers. This is easy to do and I've already implemented this for regular files. If the link is a not a fast symlink, the data is handled the same way as regular files. I think I'm back to square one.
memcpy
the link name toEXT2_I(inode)->i_data
. My problem is what if you then want to copy that data to a block. The generic way that the ext2 module does it expects user data. – Somatoplasm