与FAT32一样,NTFS也有自己的构建inode的方法,这点也没什么好说的,就是一个生成文件编号的算法,只要不重复,怎么生都行。
写文件也是类似的,也是先如page,然后再由后备设备刷到磁盘上。
在NTFS文件系统上就看看怎么读吧,因为它的写功能通常是关闭的,开起来能不能用也不知道。
读文件
了解文件操作,关键点是文件系统的struct file_operations
变量的赋值。NTFS的在kernel/fs/ntfs/file.c,ntfs_file_open
里面也是接到VFS的open,NTFS关于open的自定义操作很少,就不研究了。
const struct file_operations ntfs_file_ops = {
.llseek = generic_file_llseek, /* Seek inside file. */
.read = new_sync_read, /* Read from file. */
.read_iter = generic_file_read_iter, /* Async read from file. */
#ifdef NTFS_RW
.write = do_sync_write, /* Write to file. */
.aio_write = ntfs_file_aio_write, /* Async write to file. */
/*.release = ,*/ /* Last file is closed. See
fs/ext2/file.c::
ext2_release_file() for
how to use this to discard
preallocated space for
write opened files. */
.fsync = ntfs_file_fsync, /* Sync a file to disk. */
/*.aio_fsync = ,*/ /* Sync all outstanding async
i/o operations on a
kiocb. */
#endif /* NTFS_RW */
/*.ioctl = ,*/ /* Perform function on the
mounted filesystem. */
.mmap = generic_file_mmap, /* Mmap file. */
.open = ntfs_file_open, /* Open file. */
.splice_read = generic_file_splice_read /* Zero-copy data send with
the data source being on
the ntfs partition. We do
not need to care about the
data destination. */
/*.sendpage = ,*/ /* Zero-copy data send with
the data destination being
on the ntfs partition. We
do not need to care about
the data source. */
};
new_sync_read
是读操作,仔细看一下可知,它实际上用filp->f_op->read_iter
调用的是.read_iter=
generic_file_read_iter
这个函数。
ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
{
struct iovec iov = { .iov_base = buf, .iov_len = len };
struct kiocb kiocb;
struct iov_iter iter;
ssize_t ret;
init_sync_kiocb(&kiocb, filp);
kiocb.ki_pos = *ppos;
kiocb.ki_nbytes = len;
iov_iter_init(&iter, READ, &iov, 1, len);
ret = filp->f_op->read_iter(&kiocb, &iter);
if (-EIOCBQUEUED == ret)
ret = wait_on_sync_kiocb(&kiocb);
*ppos = kiocb.ki_pos;
return ret;
}
然后到do_generic_file_read里面的copy_page_to_iter
,一个page就被拷贝到用户的buffer了。
当然,在此之前要先readpage,要让page的内容与磁盘内容一致,这样拷贝给用户的才是磁盘内容。readpage的出发点当然在do_generic_file_read里面,但是我们其实可以不分析这里,因为关于文件的page操作每个文件系统都要定义清楚,不管这个函数怎么执行,都要调用到那些操作。与FAT32类似,那些操作就是一个struct address_space_operations
变量,就是const struct address_space_operations ntfs_normal_aops
,在kernel/fs/ntfs/aops.c
const struct address_space_operations ntfs_normal_aops = {
.readpage = ntfs_readpage,
#ifdef NTFS_RW
.writepage = ntfs_writepage,
.set_page_dirty = __set_page_dirty_buffers,
#endif /* NTFS_RW */
.bmap = ntfs_bmap,
.migratepage = buffer_migrate_page,
.is_partially_uptodate = block_is_partially_uptodate,
.error_remove_page = generic_error_remove_page,
};
下次我们要分析一下
ntfs_readpage
这个函数。
网友评论