将内核内存写入 ext2 块
对于大学作业,我们必须修改 ext2 文件系统,以便在文件小于 60 字节时将文件存储在 inode 的块指针中,并在文件增长到大于该值时移动到常规块存储。
我从 2.6 Linux 内核源代码(按照说明)复制了 ext2 代码,然后从那里开始。
当文件增长超过 60 字节时,我需要将当前 inode 的块指针数组中的所有数据复制到实际块中。所以,我需要将内核内存写入 ext2 块。对 do_sync_write
的简单调用在这里不起作用,因为它占用用户空间内存。
我查看了 do_sync_write 的实现,但不太确定如何复制它的功能,而是使用内核内存。
这是我当前对该特定部分的实现(不起作用):
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);
编辑:
我查看了符号链接。基本上,ext2 有“快速符号链接”的概念;即链接名称长度小于 60 字节。如果它是快速符号链接,数据将存储在块指针中。这很容易做到,我已经对常规文件实现了这一点。如果链接不是快速符号链接,则数据的处理方式与常规文件相同。我想我又回到了原点。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我设法弄清楚了。它需要获取 struct buffer_head 实例并读取/写入其中的数据。通过循环遍历逻辑块号并使用 ext2_get_block 来检索块(如果需要的话分配它们),然后使用 sb_getblk 获取实际缓冲区并写入它。我已在我的博客。
I managed to figure it out. It required getting
struct buffer_head
instances and reading/writing the data in them. By looping through the logical block numbers and using toext2_get_block
to retrieve blocks (allocating them if necessary) and then usingsb_getblk
to get the real buffer out and write to it. I've posted an implementation on my blog.愚蠢的家庭作业。
该代码不起作用。尝试 mmap() 并死掉。
Dumb homework assignment.
The code does not work. Try mmap() and die.