exfat文件系统(五)------文件read和write

 

在开始阐述exfat的fread过程时,先推荐一盘linux的read的博客( http://blog.csdn.net/guopeixin/article/details/5962489),我从这篇文章中学习到很多东西,以便我快速的掌握exfat read流程。

 

exfat的read过程,跟VFS的generanel的read过程完全一致,在开源代码中只是对VFS的标准函数进行了封装而已。具体如下:

 

exfat read函数的层次模型

目前exfat文件系统只分析到Block Layer。

exfat文件系统的read发起点是系统标准函数fread,fread调用系统API函数sys_read,sys_read函数再调用vfs_read,vfs_read函数再调用file->f_op->read()。

而file->f_op->read()实际上就是具体的文件系统向通用Block层注册的一个函数指针。


exfat文件系统在填充inode的时候初始化对应节点的相关操作,具体如下代码

static int exfat_fill_inode(struct inode *inode, FILE_ID_T *fid)
{
struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb);
FS_INFO_T *p_fs = &(sbi->fs_info);
DIR_ENTRY_T info;


memcpy(&(EXFAT_I(inode)->fid), fid, sizeof(FILE_ID_T));


FsReadStat(inode, &info);


EXFAT_I(inode)->i_pos = 0;
EXFAT_I(inode)->target = NULL;
inode->i_uid = sbi->options.fs_uid;
inode->i_gid = sbi->options.fs_gid;
inode->i_version++;
inode->i_generation = get_seconds();


if (info.Attr & ATTR_SUBDIR) { /* directory */
inode->i_generation &= ~1;
inode->i_mode = exfat_make_mode(sbi, info.Attr, S_IRWXUGO);
inode->i_op = &exfat_dir_inode_operations;
inode->i_fop = &exfat_dir_operations;



i_size_write(inode, info.Size);
EXFAT_I(inode)->mmu_private = i_size_read(inode);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,00)
set_nlink(inode, info.NumSubdirs);
#else
inode->i_nlink = info.NumSubdirs;
#endif
} else if (info.Attr & ATTR_SYMLINK) { /* symbolic link */
inode->i_generation |= 1;
inode->i_mode = exfat_make_mode(sbi, info.Attr, S_IRWXUGO);
inode->i_op = &exfat_symlink_inode_operations;



i_size_write(inode, info.Size);
EXFAT_I(inode)->mmu_private = i_size_read(inode);
} else { /* regular file */
inode->i_generation |= 1;
inode->i_mode = exfat_make_mode(sbi, info.Attr, S_IRWXUGO);
inode->i_op = &exfat_file_inode_operations;

inode->i_fop = &exfat_file_operations;
inode->i_mapping->a_ops = &exfat_aops; //注册页面缓冲的一些接口

inode->i_mapping->nrpages = 0;


i_size_write(inode, info.Size);
EXFAT_I(inode)->mmu_private = i_size_read(inode);
}
exfat_save_attr(inode, info.Attr);


inode->i_blocks = ((i_size_read(inode) + (p_fs->cluster_size - 1))
  & ~((loff_t)p_fs->cluster_size - 1)) >> 9;


exfat_time_fat2unix(sbi, &inode->i_mtime, &info.ModifyTimestamp);
exfat_time_fat2unix(sbi, &inode->i_ctime, &info.CreateTimestamp);
exfat_time_fat2unix(sbi, &inode->i_atime, &info.AccessTimestamp);


return 0;
}


从上面的函数看可以发现,exfat创建inode的时候就针对不同的inode(directory, symbolic link,file)初始化了不同的控制。对于file read(fread),我们重点关注相关控制函数的注册和具体实现,代码如下

inode->i_fop = &exfat_file_operations;
inode->i_mapping->a_ops = &exfat_aops; //注册页面缓冲的一些接口


const struct file_operations exfat_file_operations = {
.llseek      = generic_file_llseek,
.read        = do_sync_read,
.write       = do_sync_write,
.aio_read    = generic_file_aio_read,
.aio_write   = generic_file_aio_write,
.mmap        = generic_file_mmap,
.release     = exfat_file_release,
.unlocked_ioctl  = exfat_generic_ioctl,
.fsync       = generic_file_fsync,
.splice_read = generic_file_splice_read,
};

const struct address_space_operations exfat_aops = {
.readpage    = exfat_readpage,
.readpages   = exfat_readpages,
.writepage   = exfat_writepage,
.writepages  = exfat_writepages,
.write_begin = exfat_write_begin,
.write_end   = exfat_write_end,
.direct_IO   = exfat_direct_IO,
.bmap        = _exfat_bmap
};

控制流程图如下:



流程图中mapping->a_ops->readpage(filp, page)实际上是执行exfat_aops.readpage,即exfat_readpage。

exfat_readpag的函数就是调用mpage_readpage函数,函数如下:

static int exfat_readpage(struct file *file, struct page *page)
{
int ret;
ret =  mpage_readpage(page, exfat_get_block);
return ret;
}


static int exfat_readpages(struct file *file, struct address_space *mapping,
  struct list_head *pages, unsigned nr_pages)
{
int ret;
ret =  mpage_readpages(mapping, pages, nr_pages, exfat_get_block);
return ret;
}


static int exfat_writepage(struct page *page, struct writeback_control *wbc)
{
int ret;
ret = block_write_full_page(page, exfat_get_block, wbc);
return ret;
}


static int exfat_writepages(struct address_space *mapping,
struct writeback_control *wbc)
{
int ret;
ret = mpage_writepages(mapping, wbc, exfat_get_block);
return ret;
}


exfat_readpage的控制流程图如下:




到此,exfat文件系统read完成向block设备请求disk mapping,并提交get_block操作。


分析至此,exfat完成了read driver控制,并把控制权交给block driver


linux文件读写参考博客http://blog.chinaunix.net/uid-22111121-id-2678792.html说明

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值