设置layout
来源:互联网 发布:滚动屏软件 编辑:程序博客网 时间:2024/05/17 05:56
layout需要MDS、DS和客户端三方共同支持,当客户端通过GETATTR请求获取了layout类型后,还需要检查自己是否支持这种类型,客户端检查、设置layout的函数是set_pnfs_layoutdriver()。
RFC5661定义了三种layout,三种layout的编号依次为
enum pnfs_layouttype { LAYOUT_NFSV4_1_FILES = 1, LAYOUT_OSD2_OBJECTS = 2, LAYOUT_BLOCK_VOLUME = 3,};layout编号从1开始,0是一个保留序号,不允许出现编号为0的layout类型。
客户端与pNFS相关的数据结构是struct pnfs_layoutdriver_type,这个数据结构很恐怖,包含了很多函数:
struct pnfs_layoutdriver_type { // 这个数据结构链接到全局链表pnfs_modules_tbl中 struct list_head pnfs_tblid; const u32 id; // 这种layout类型的编号. const char *name; // 这种layout类型的名称 struct module *owner; // 模块 unsigned flags; // 一些标志位 int (*set_layoutdriver) (struct nfs_server *, const struct nfs_fh *); int (*clear_layoutdriver) (struct nfs_server *); struct pnfs_layout_hdr * (*alloc_layout_hdr) (struct inode *inode, gfp_t gfp_flags); void (*free_layout_hdr) (struct pnfs_layout_hdr *); struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr, gfp_t gfp_flags); void (*free_lseg) (struct pnfs_layout_segment *lseg); /* test for nfs page cache coalescing */ const struct nfs_pageio_ops *pg_read_ops; const struct nfs_pageio_ops *pg_write_ops; struct pnfs_ds_commit_info *(*get_ds_info) (struct inode *inode); void (*mark_request_commit) (struct nfs_page *req, struct pnfs_layout_segment *lseg, struct nfs_commit_info *cinfo); void (*clear_request_commit) (struct nfs_page *req, struct nfs_commit_info *cinfo); int (*scan_commit_lists) (struct nfs_commit_info *cinfo, int max); void (*recover_commit_reqs) (struct list_head *list, struct nfs_commit_info *cinfo); int (*commit_pagelist)(struct inode *inode, struct list_head *mds_pages, int how, struct nfs_commit_info *cinfo); /* * Return PNFS_ATTEMPTED to indicate the layout code has attempted * I/O, else return PNFS_NOT_ATTEMPTED to fall back to normal NFS */ enum pnfs_try_status (*read_pagelist) (struct nfs_read_data *nfs_data); enum pnfs_try_status (*write_pagelist) (struct nfs_write_data *nfs_data, int how); void (*free_deviceid_node) (struct nfs4_deviceid_node *); void (*encode_layoutreturn) (struct pnfs_layout_hdr *layoutid, struct xdr_stream *xdr, const struct nfs4_layoutreturn_args *args); void (*cleanup_layoutcommit) (struct nfs4_layoutcommit_data *data); void (*encode_layoutcommit) (struct pnfs_layout_hdr *layoutid, struct xdr_stream *xdr, const struct nfs4_layoutcommit_args *args);};
现在暂时不讲这些函数,后面用到的时候再讲。file layout中这个数据结构定义如下:
static struct pnfs_layoutdriver_type filelayout_type = { .id = LAYOUT_NFSV4_1_FILES, .name = "LAYOUT_NFSV4_1_FILES", .owner = THIS_MODULE, .alloc_layout_hdr = filelayout_alloc_layout_hdr, .free_layout_hdr = filelayout_free_layout_hdr, .alloc_lseg = filelayout_alloc_lseg, .free_lseg = filelayout_free_lseg, .pg_read_ops = &filelayout_pg_read_ops, .pg_write_ops = &filelayout_pg_write_ops, .get_ds_info = &filelayout_get_ds_info, .mark_request_commit = filelayout_mark_request_commit, .clear_request_commit = filelayout_clear_request_commit, .scan_commit_lists = filelayout_scan_commit_lists, .recover_commit_reqs = filelayout_recover_commit_reqs, .commit_pagelist = filelayout_commit_pagelist, .read_pagelist = filelayout_read_pagelist, .write_pagelist = filelayout_write_pagelist, .free_deviceid_node = filelayout_free_deveiceid_node,};
这个数据结构保存在struct nfs_server中了,表示这个NFS文件系统使用的layout类型。
struct nfs_server { ...... struct pnfs_layoutdriver_type *pnfs_curr_ld; ......}另外,客户端还定义了一个全局链表pnfs_modules_tbl,这个链表中保存的也是struct pnfs_layoutdriver_type。因为layout最多有三种类型,因此这个链表中最多有三个元素。现在可以讲解了set_pnfs_layoutdriver()。
voidset_pnfs_layoutdriver(struct nfs_server *server, const struct nfs_fh *mntfh, u32 id){ struct pnfs_layoutdriver_type *ld_type = NULL; // 编号为0的layout类型已经预留了,表示不使用layout. if (id == 0) goto out_no_driver;// EXCHGID4_FLAG_USE_PNFS_MDS、EXCHGID4_FLAG_USE_NON_PNFS表示服务器角色,// 这些标志位是通过EXCHANGE_ID获取的. if (!(server->nfs_client->cl_exchange_flags & (EXCHGID4_FLAG_USE_NON_PNFS | EXCHGID4_FLAG_USE_PNFS_MDS))) { printk(KERN_ERR "NFS: %s: id %u cl_exchange_flags 0x%x\n", __func__, id, server->nfs_client->cl_exchange_flags); goto out_no_driver; }// 在全局链表pnfs_modules_tbl中查找是否已经加载这个layout驱动了. ld_type = find_pnfs_driver(id); if (!ld_type) { // 这个内核模块还没有加载 // nfs_layout_nfsv41_files.ko blocklayoutdriver.ko objlayoutdriver.ko// 好吧,加载这个内核模块. request_module("%s-%u", LAYOUT_NFSV4_1_MODULE_PREFIX, id); ld_type = find_pnfs_driver(id); // 再次查找 if (!ld_type) { // 还是没有找到,只好出错了. dprintk("%s: No pNFS module found for %u.\n", __func__, id); goto out_no_driver; } }// 客户端已经加载这个layout驱动程序了// 关联到这个nfs_server结构中. server->pnfs_curr_ld = ld_type; // 如果layoutdriver定义了set_layoutdriver,就需要先执行这个函数 // file layout没有定义这个函数,因此就不看了。 if (ld_type->set_layoutdriver && ld_type->set_layoutdriver(server, mntfh)) { // 但是函数执行过程中出错了 printk(KERN_ERR "NFS: %s: Error initializing pNFS layout " "driver %u.\n", __func__, id); module_put(ld_type->owner); goto out_no_driver; } /* Bump the MDS count */// 增加NFS客户端源数据服务器的数量 atomic_inc(&server->nfs_client->cl_mds_count); dprintk("%s: pNFS module for %u set\n", __func__, id); return;out_no_driver: dprintk("%s: Using NFSv4 I/O\n", __func__); server->pnfs_curr_ld = NULL;}这个函数逻辑很简单,首先根据从MDS获取的layout类型编号在全局链表pnfs_modules_tbl中查找对应的pnfs_layoutdriver_type结构。如果找到了,说明已经加载这种layout的驱动程序了。如果没有找到,则首先加载这种layout的驱动程序,然后添加到全局链表中。最后设置nfs_server结构中的指针pnfs_curr_ld就可以了。
- 设置layout
- UI layout设置技巧
- layout设置MARGIN
- 动态设置layout高度
- layout的均分设置
- MainWindow 设置layout问题
- PADS Layout 颜色设置
- QT里面的layout设置
- CI框架设置Layout布局
- QMainWindow 和 QWidget 设置layout
- 动态设置Layout的宽高值
- QMainWindow 和 QWidget 设置layout
- android 用代码设置Layout margin属性
- Android 动态设置Layout的显示与否
- PADS Layout中设置板框倒角
- yii action $layout yii模版设置
- cocos2dx-2.X Layout设置大小问题
- zend framework2-不同模块设置不同layout
- oracle 关键词
- ALV参数汇总
- 产品与服务的联系与区别
- 构造函数方面
- Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning
- 设置layout
- Unable to execute dex: Multiple dex files define Lcom/ckt/vas/miles/R$anim
- Selenium实例之登录Mail.163.com发送邮件
- Linux进程基础
- 初识OpenXml
- Struts2教程6:在Action类中获得HttpServletResponse对象的四种方法
- dedecms如何实现类似简介等的单页
- Flex error 2032
- watir不能识别frame解决办法