cephfs kernel client针对打开文件的操作代码

77次阅读
没有评论

共计 5010 个字符,预计需要花费 13 分钟才能阅读完成。

这篇文章给大家分享的是有关 cephfs kernel client 针对打开文件的操作代码的内容。丸趣 TV 小编觉得挺实用的,因此分享给大家做个参考,一起跟随丸趣 TV 小编过来看看吧。

针对打开文件的操作主要体现在 struct file_operations 数据结构中。在 cephfs kernel client 中具体实现如下:

const struct file_operations ceph_file_fops = {

   .open = ceph_open,

   .release = ceph_release,

   .llseek = ceph_llseek,

   .read_iter = ceph_read_iter,

   .write_iter = ceph_write_iter,

   .mmap = ceph_mmap,

   .fsync = ceph_fsync,

   .lock = ceph_lock,

   .flock = ceph_flock,

   .splice_read = generic_file_splice_read,

   .splice_write = iter_file_splice_write,

   .unlocked_ioctl = ceph_ioctl,

   .compat_ioctl   = ceph_ioctl,

   .fallocate   = ceph_fallocate,

};

ceph_open(struct inode *inode, struct file *file)    该函数在打开文件时被调用

|__调用 prepare_open_request() 函数来创建 ceph_mds_request 请求

|__调用 ceph_mdsc_do_request() 函数将 ceph_mds_request 请求同步的发送给 mds 进程

|__调用 ceph_init_file() 函数创建 ceph_file_info 数据结构且将该数据结构放入到 file- private_data 中

ceph_release(struct inode *inode, struct file *file)    该函数在关闭文件时被调用

|__调用 ceph_put_fmode() 函数减少打开文件的引用次数,若引用次数为 0,则从本地 cache 中删除该文件

ceph_llseek(struct file *file, loff_t offset, int whence)

|__若 whence 是 SEEK_END|SEEK_DATA|SEEK_HOLE

  |__调用 ceph_do_getattr() 函数从 mds 集群中获取指定 inode 的 attrs 属性

|__调用 i_size_read() 函数得到当前 inode 的实际大小

|__根据 whence 的值调整 offset 的值

|__调用 vfs_setpos() 函数设置文件的当前位置为 offset

ceph_read_iter(struct kiocb *iocb, struct iov_iter *to)    该函数在读取文件内容的时候被调用

|__调用 ceph_get_caps() 函数得到 caps

|__对于同步读数据操作来说

  |__若 iocb- ki_flags IOCB_DIRECT

    |__调用 ceph_direct_read_write() 函数从 osds 集群中读取数据

  |__若!iocb- ki_flags IOCB_DIRECT

    |__调用 ceph_sync_read() 函数从 osds 集群中读取数据

|__对于非同步读取数据操作来说

  |__调用 generic_file_read_iter() 函数实现异步数据的读取操作

ceph_write_iter(structd kiocb *iocb, struct iov_iter *from)    执行写操作时调用该函数执行

|__调用 generic_write_check() 函数在实际写之前进行必要的检查

|__调用 ceph_get_caps() 得到写权限

|__对于同步写操作

   |__对于 iocb- ki_flags IOCB_DIRECT

     |__调用 ceph_direct_read_write() 函数向 osds 集群中写入数据

   |__对于! iocb- ki_flags IOCB_DIRECT

     |__调用 ceph_sync_write() 函数向 osds 集群中红写入数据

|__对于非同步写操作

   |__调用 generic_perform_write() 函数执行写操作

ceph_mmap(struct file *file, struct vm_area_struct *vma)      将文件内容影射到内存的操作时调用该函数执行

|__设置 vma 的 vm_ops=ceph_vmops

ceph_fsync(struct file *file, loff_t start , loff_t end, int datasync)

|__调用 ceph_sync_write_wait() 函数等待 inode 上所有未完成的 osd 请求执行完毕

|__调用 try_flush_caps() 函数将所有 dirty 的 caps 刷回到 mds

|__调用 unsafe_request_wait() 函数等待 inode 上所有针对 mds 请求执行完毕

ceph_lock(struct file *file, int cmd, struct file_lock *fl)        当用户态程序执行 fcntl lock 时调用该函数执行

|__调用 ceph_lock_message() 函数创建文件锁命令请求后,将该请求发送给 mds 集群

ceph_flock(struct file *file, int cmd, struct file_lock *fl)

|__调用 ceph_lock_message() 函数创建文件锁命令请求后,将该请求发送给 mds 集群

ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

|__根据 cmd 的值做不同的处理

   |__cmd==CEPH_IOC_GET_LAYOUT

     |__ceph_ioctl_get_layout()

       |__ceph_do_getattr(CEPH_STAT_CAP_LAYOUT) 从 mds 集群中读取 file 对应的 inode 的 layout 信息到 ceph_inode_info 的 i_layout 中

       |__将 i_layout 信息写入到 struct ceph_ioctl_layout 数据结构中且通过 copy_to_user() 函数将数据返回给用户态

   |__cmd==CEPH_IOC_SET_LAYOUT

     |__ceph_ioctl_set_layout()

       |__调用 copy_from_user() 函数将新的 layout 信息从用户态复制到内核态

       |__调用 ceph_do_getattr() 函数从 mds 集群中读取当前的 layout 信息

       |__调用__validate_layout() 函数检查新设置的 layout 是否有效

       |__调用 ceph_mdsc_create_request() 函数创建 request 请求

       |__调用 ceph_mdsc_do_request() 函数同步的发送 request 请求到 mds 集群

   |__cmd==CEPH_IOC_SET_LAYOUT_POLICY

     |__ceph_ioctl_set_layout_policy()

       |__调用 copy_from_user() 函数将新的 layout 信息从用户态复制到内核态

       |__调用__validate_layout() 函数检查新设置的 layout 是否有效

       |__调用 ceph_mdsc_create_request() 函数创建 request 请求

       |__调用 ceph_mdsc_do_request() 函数同步的发送 request 请求到 mds 集群

   |__cmd==CEPH_IOC_GET_DATALOC          计算 data 所在的 ceph 集群中的位置信息

     |__ceph_ioctl_get_dataloc()

       |__调用 copy_from_user() 函数将 ceph_ioctl_dataloc 信息复制到内核态

       |__调用 ceph_calc_file_object_mapping() 函数计算 ceph_ioctl_dataloc 信息中指定文件所在的 oid 等信息

       |__调用 ceph_object_locator_to_pg() 函数计算出 oid 所在的 pg 信息

       |__调用 ceph_pg_to_acting_primary() 函数计算出 pg 所在的主 osd 信息

       |__调用 copy_to_user() 函数将计算出来的信息发送回给用户态

   |__cmd==CEPH_IOC_LAZYIO              设置 LAZYIO 标识

     |__ceph_ioctl_lazyio()

       |__ 判断 struct ceph_file_info 中的 fmode 是否未设置 CEPH_FILE_MODE_LAZY

         |__设置 struct ceph_file_info 中的 fmode 拥有 CEPH_FILE_MODE_LAZY 标识

         |__更新 ceph_inode_info 中的 i_nr_by_mode 数组

         |__调用 ceph_check_caps() 函数更新 caps

   |__cmd==CEPH_IOC_SYNCIO

     |__ceph_ioctl_syncio()

       |__设置 struct ceph_file_info 结构中的 flags 的 CEPH_F_SYNC 位

ceph_fallocate(struct file *file, int mode, loff_t offset, loff_t length)

|__若 mode==FALLOC_FL_PUNCH_HOLE

   |__调用 ceph_zero_object() 函数在文件的指定 offset 开始到 offset+length 结束的地方设置文件内容为 0

|__若 offset+length size

   |__调用 ceph_inode_set_size() 将文件的大小设置为 offset+length

   |__调用 ceph_check_caps() 函数校验文件 caps 的认证是否有效

针对文件映射到内存的相关操作主要体现在 struct vm_operations_struct 数据结构中,具体内容如下:

static const struct vm_operations_struct ceph_vmops = {

        .fault          = ceph_filemap_fault,

        .page_mkwrite   = ceph_page_mkwrite,

};

ceph_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)    该函数在读取内存中的数据时发生内存缺页的时候被调用

|__调用 find_or_create_page() 函数从物理内存中获取到物理内存页

|__调用__ceph_do_getattr(CEPH_STAT_CAP_INLINE_DATA) 函数从 mds 集群中读取到数据

|__调用 flush_dcache_page() 函数将读取到的数据写入到物理内存页

|__调用 SetPageUptodate() 函数设置该物理内存页已经被更新

|__设置 vmf- page=page,即:将物理内存页添加到虚拟内存中

ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)    当页面从 readonly 状态变迁到 writeable 状态时该函数被调用

|__调用 ceph_update_writeable_page() 函数来设置 vmf- page 页为 writeable 

|__调用 set_page_diry() 函数设置该物理内存页为 dirty 的

感谢各位的阅读!关于“cephfs kernel client 针对打开文件的操作代码”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-16发表,共计5010字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)