For university assignment, we need to modify the ext2 file system to store files in the inode block pointers if it is less than 60 bytes, and go to the regular block storage when the file is larger than this.
I copied the ext2 code from the Linux linux source kernel (as indicated) and went from there.
When the file size exceeds 60 bytes, I need to copy any data that is currently in the array of pointers to the inode block into real blocks. So, I need to write kernel memory to ext2 blocks. A simple do_sync_write call will not work here because it takes up user space.
I looked at the implementation of do_sync_write , and I'm not quite sure how to replicate what it does, but with kernel memory.
This is my current implementation of this specific part (doesn't 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); 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 symbolic links. Basically, ext2 has the concept of "quick symbolic links"; that is, the channel name is less than 60 bytes. If it is a quick symbolic link, the data is stored in the block pointers. This is easy to do, and I have already implemented this for regular files. If the link is not a quick symbolic link, the data is processed in the same way as regular files. I think I'll be back to square one.