免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 11273 | 回复: 35

[高级应用] 关于AIX 虚拟文件系统 [复制链接]

论坛徽章:
0
发表于 2014-06-30 00:45 |显示全部楼层
大家好,小弟看了sinister大神的AIX 内核的虚拟文件系统框架的文章http://blog.sina.com.cn/s/blog_53ac45970100g25e.html

有一些疑问希望有研究的高手给点小提示

进入kdb, 查看vfs
(0)> vfs
                           GFS             DATA TYPE    FLAGS

  1 F1000A10008C0910 02D80378 F1000A001AED0080 JFS2    DEVMOUNT
... /dev/hd4 mounted over /
  2 F1000A10008C0A10 02D80378 F1000A001AEB2480 JFS2    DEVMOUNT
... /dev/hd2 mounted over /usr
  3 F1000A10008C1810 02D80378 F1000A001AE75080 JFS2    DEVMOUNT
... /dev/hd9var mounted over /var
  4 F1000A10008C0810 02D80378 F1000A001AEC6880 JFS2    DEVMOUNT
... /dev/hd3 mounted over /tmp


查看vfs F1000A10008C0910
(0)> vfs F1000A10008C0910
                           GFS             DATA TYPE    FLAGS

0 F1000A10008C0910 02D80378 F1000A001AED0080 JFS2    DEVMOUNT
... /dev/hd4 mounted over /

vfs_next..... F1000A10008C0A10 vfs_gfs...... 0000000002D80378
vfs_mntd..... F1000A001AEE0420 vfs_mntdover. 0000000000000000
vfs_vnodes... F1000A001AEE0420 vfs_count.... 00000001
vfs_data..... F1000A001AED0080 vfs_number... 00000001
vfs_mdata.... F1000A0000AB2280 vfs_bsize.... 00001000
vfs_lock@.... F1000A10008C0960 vfs_lock..... 0000000000000000
vfs_rasb..... F1000A0019D66D00
vmt_revision. 00000001 vmt_length... 00000078 vmt_vfsnumber 00000001
vmt_fsid..... 8000000A00000004 0000000000000000
vmt_time..... 53AD9C1A vmt_flags.... 00000004
vmt_gfstype.. 00000000
vfs_type..... 00000000 vfs_ops...... j2_vfsops
@vmt_data.... F1000A0000AB22AC


查看vnode F1000A001AEE0420
(0)> vnode F1000A001AEE0420
                      COUNT            GNODE             VFSP TYPE FLAGS

   0 F1000A001AEE0420    42 F1000A001AEE00B0 F1000A10008C0910 DIR  ROOT
v_flag.... 00000001 v_count... 0000002A
v_vfsgen.. 00000000 v_vfsp.... F1000A10008C0910
v_lock@... F1000A001AEE0430 v_lock.... 0000000000000000
v_mvfsp... 0000000000000000 v_gnode... F1000A001AEE00B0
v_next.... 0000000000000000 v_vfsnext. F1000A002727A020
v_vfsprev. 0000000000000000 v_pfsvnode 0000000000000000
v_audit... 0000000000000000 v_flag.... ROOT


查看相应的gnode F1000A001AEE00B0
(0)> gnode F1000A001AEE00B0
GNODE............ F1000A001AEE00B0 F1000A001AEE00B0
gn_type....... 00000002 gn_flags...... FFFF8000
gn_seg........ 0000000000000000
gn_mwrcnt..... 00000000 gn_mrdcnt..... 00000000 gn_rdcnt...... 00000001
gn_wrcnt...... 00000000 gn_excnt...... 00000000 gn_rshcnt..... 00000000
gn_ops........ 00000000022B3098 j2_vnops
gn_vnode...... F1000A001AEE0420 gn_rdev....... 8000000A00000004
gn_chan....... 00000000 gn_reclk_event 00000000FFFFFFFF
gn_reclk_lock@ F1000A001AEE00F8 gn_reclk_lock. 0000000000000000
gn_filocks.... 0000000000000000 gn_data....... F1000A001AEE0080
gn_type....... DIR gn_flags...... XPAGER

查看gn_ops结构
(0)> dd 00000000022B3098 20
j2_vnops+000000: 00000000032223E8 0000000003222400  ....."#......"$.
j2_vnops+000010: 0000000003222418 0000000003222430  ....."$......"$0
j2_vnops+000020: 0000000003222448 0000000003222460  ....."$H....."$`
j2_vnops+000030: 0000000003222478 0000000003222490  ....."$x....."$.
j2_vnops+000040: 00000000032224A8 0000000003222418  ....."$......"$.
j2_vnops+000050: 0000000003222328 00000000032224C0  ....."#(....."$.
j2_vnops+000060: 00000000032224D8 00000000032224F0  ....."$......"$.
j2_vnops+000070: 0000000003222508 0000000003222520  ....."%......"%
j2_vnops+000080: 0000000003222538 0000000003222550  ....."%8....."%P
j2_vnops+000090: 0000000003222568 0000000003222418  ....."%h....."$.
j2_vnops+0000A0: 0000000003222580 0000000003222418  ....."%......"$.
j2_vnops+0000B0: 0000000003222598 00000000032225E0  ....."%......"%.
j2_vnops+0000C0: 00000000032225F8 0000000003222610  ....."%......"&.
j2_vnops+0000D0: 0000000003222628 0000000003222418  ....."&(....."$.
j2_vnops+0000E0: 0000000003221F98 0000000003222610  ....."......."&.
j2_vnops+0000F0: 0000000003222310 0000000003222310  ....."#......"#.

vnodeops 的结构
struct vnodeops {
      
        int        (*vn_link)(struct vnode *, struct vnode *, char *,
                        struct ucred *);
        int        (*vn_mkdir)(struct vnode *, char *, int, struct ucred *);
        int        (*vn_mknod)(struct vnode *, caddr_t, int,
                        dev_t, struct ucred *);
        int        (*vn_remove)(struct vnode *, struct vnode *, char *,
                        struct ucred *);
        int        (*vn_rename)(struct vnode *, struct vnode *, caddr_t,
                        struct vnode *,struct vnode *,caddr_t,struct ucred *);
        int        (*vn_rmdir)(struct vnode *, struct vnode *, char *,
                        struct ucred *);
      
        int        (*vn_lookup)(struct vnode *, struct vnode **, char *, int,
                        struct vattr *, struct ucred *);
        int        (*vn_fid)(struct vnode *, struct fileid *, struct ucred *);
      
        int        (*vn_open)(struct vnode *, int, int, caddr_t *, struct ucred *);
        int        (*vn_create)(struct vnode *, struct vnode **, int, caddr_t,
                        int, caddr_t *, struct ucred *);
        int        (*vn_hold)(struct vnode *);
        int        (*vn_rele)(struct vnode *);
        int        (*vn_close)(struct vnode *, int, caddr_t, struct ucred *);
        int        (*vn_map)(struct vnode *, caddr_t, uint, uint, uint,
                        struct ucred *);
        int        (*vn_unmap)(struct vnode *, int, struct ucred *);
      
        int        (*vn_access)(struct vnode *, int, int, struct ucred *);
        int        (*vn_getattr)(struct vnode *, struct vattr *, struct ucred *);
        int        (*vn_setattr)(struct vnode *, int, int, int, int,
                        struct ucred *);
      
#ifdef _LONG_LONG
        int        (*vn_fclear)(struct vnode *, int, offset_t, offset_t,
                        caddr_t, struct ucred *);
#else
        int        (*vn_fclear)();
#endif
        int        (*vn_fsync)(struct vnode *, int, int, struct ucred *);

#ifdef _LONG_LONG
        int        (*vn_ftrunc)(struct vnode *, int, offset_t, caddr_t,
                        struct ucred *);
#else
        int        (*vn_ftrunc)();
#endif
        int        (*vn_rdwr)(struct vnode *, enum uio_rw, int, struct uio *,
                        int, caddr_t, struct vattr *, struct ucred *);
#ifdef _LONG_LONG
        int        (*vn_lockctl)(struct vnode *, offset_t, struct eflock *, int,
                        int (*)(), ulong *, struct ucred *);
#else
        int        (*vn_lockctl)();
#endif
      
        int        (*vn_ioctl)(struct vnode *, int, caddr_t, size_t, int,
                        struct ucred *);
        int        (*vn_readlink)(struct vnode *, struct uio *, struct ucred *);
        int        (*vn_select)(struct vnode *, int, ushort, ushort *, void (*)(),
                        caddr_t, struct ucred *);
        int        (*vn_symlink)(struct vnode *, char *, char *, struct ucred *);
        int        (*vn_readdir)(struct vnode *, struct uio *, struct ucred *);
      
        int        (*vn_strategy)(struct vnode *, struct buf *, struct ucred *);
      
        int        (*vn_revoke)(struct vnode *, int, int, struct vattr *,
                        struct ucred *);
        int        (*vn_getacl)(struct vnode *, struct uio *, struct ucred *);
        int        (*vn_setacl)(struct vnode *, struct uio *, struct ucred *);
        int        (*vn_getpcl)(struct vnode *, struct uio *, struct ucred *);
        int        (*vn_setpcl)(struct vnode *, struct uio *, struct ucred *);
};

#ifdef _KERNEL


可见,有部分函数指针,包括vn_mknod, vn_create, vn_rdwr等四五个函数都指向了0000000003222418
dd 0000000003222418可得
(0)> dd 0000000003222418
j2_obsolete+000000: 0000000000335660 0000000003243F48  .....3V`.....$?H

小弟对此有比较大的疑问,尤其对于vn_rdwr, 这个应该是文件系统对指定vnode的文件读写接口,而j2_obsolete应该是一个无效的函数.
希望有经验的大神给点提示,一个文件的读写操作在vfs层上是如何进行.

致谢!!









论坛徽章:
0
发表于 2014-06-30 07:54 |显示全部楼层
j2_obsolate是给aix421以前版本vnode格式call入口留下的,现在这几个对应的call都不用了

论坛徽章:
0
发表于 2014-06-30 11:32 |显示全部楼层
本帖最后由 EncoreDeng 于 2014-06-30 11:34 编辑

Hi orian哥哥,能否解释一下,比如我对一个文件做一个写操作,在vfs层上是调用了vnodeops结构里面的那个函数?
按照我原本理解应该是vn_rdwr, 而在j2_vnops中,相应的vn_rdwr却设置为j2_obsolete, 好困惑!
谢谢!
回复 2# orian

论坛徽章:
0
发表于 2014-06-30 11:43 |显示全部楼层
只有你自己写的kernel extension程序可能用vn_rdwr,aix自己不用这几个函数的,没什么困惑。普通用户程序用read/write之类的,最后都是由pager内存直接映像写磁盘,没vn_rdwr什么事情。

论坛徽章:
0
发表于 2014-06-30 13:03 |显示全部楼层
受教!
pager内存直接映像写磁盘, 是否有一些相关文章对此详述?
拜谢!!

回复 4# orian


   

论坛徽章:
0
发表于 2014-06-30 16:00 |显示全部楼层
orian哥哥,您说的pager内存直接映像写磁盘是指vn_strategy?
通过kdb看到相应的j2函数为j2PagerStrategy.

论坛徽章:
0
发表于 2014-06-30 23:11 |显示全部楼层
          是

论坛徽章:
0
发表于 2014-07-01 00:51 |显示全部楼层
谢谢!我先研究一下。
另外是否有一些资料对此有比较详细的讲解呢?
比如当上层应用调用read/write时,内核如何处理然后调用到vn_strategy.
read/write参数是如何体现到struct buf上?

回复 7# orian


   

论坛徽章:
0
发表于 2014-07-01 06:57 |显示全部楼层
那要看源码的,aix不是开源的吧?

freebsd倒是可看,aix和bsd同源,底层差不多。

论坛徽章:
0
发表于 2014-07-02 15:38 |显示全部楼层
似乎在网上找不到freebsd的源码下载...

另外,可以简单解释一下 struct buf 这个结构吗?
IBM官网说得比较含糊 http://www-01.ibm.com/support/kn ... 3qsl4a0chri?lang=en
其实我只是想搞清楚当一个读写操作进行时,读写的数据,偏移等信息是如何反映在这个结构上.
小弟感激不尽!

回复 9# orian


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP