免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 11695 | 回复: 36
打印 上一主题 下一主题

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

论坛徽章:
0
跳转到指定楼层
[收藏(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
36 [报告]
发表于 2014-07-23 12:50 |只看该作者
说明buf不是你认为的struct,而是与之差不多的某个struct

论坛徽章:
0
35 [报告]
发表于 2014-07-22 12:31 |只看该作者
如何能够把kernel debug弄开呢?
有没有一些内核调试的教程可以参考一下...起码可以像Windows或者Linux那样双机进入源码调试呢?


回复 34# orian


   

论坛徽章:
0
34 [报告]
发表于 2014-07-20 01:50 |只看该作者
dbx提供了很多信息,多看看至少结构能搞清楚,也可以吧kernel debug弄开,信息更多。

论坛徽章:
0
33 [报告]
发表于 2014-07-18 11:16 |只看该作者
这个真不知可以怎么猜了,主要的方向也不知道对不对.
按我理解是b_flags设置了B_XPAGER, buf的内容被交换到page中.
而访问具体page的数据,只能通过cross memory了.

关于page和cross memory,我都没有相关经验,所以希望大神能够给点提点~

回复 31# orian


   

论坛徽章:
0
32 [报告]
发表于 2014-07-18 10:31 |只看该作者
deadbeef是初始化内存的时候故意填的数据,用来帮助debug的。

你不知道buf的结构,当然就只能猜了,猜对了中大奖。

论坛徽章:
0
31 [报告]
发表于 2014-07-18 10:03 |只看该作者
啊?!deadbeef更像是一些magic code之类吧...地址错误怎么其他数据都这么有规律?

不公开的意思是知道了buf head也没办法获得buf的内容?

回复 29# orian


   

论坛徽章:
0
30 [报告]
发表于 2014-07-18 04:23 |只看该作者
ibm不公开的

公开的提示是你看到deadbeef就说明地址错误。

论坛徽章:
0
29 [报告]
发表于 2014-07-17 11:31 |只看该作者
似乎我之前搞错了一些东西,所以弄糊涂了.

出现疑问的buf的典型数据

b_dev=8000000a0000000d, b_flags=880c8080, b_blkno=15a00, b_bcount=20000, b_baddr=7e0000, real_mem=17dbf000
遍历其b_back可得到相似的buf数据
b_dev=deadbeef, b_flags=40c0080, b_blkno=3f08, b_bcount=1000, b_baddr=7e1000
b_dev=deadbeef, b_flags=40c0080, b_blkno=3f10, b_bcount=1000, b_baddr=7e2000
b_dev=deadbeef, b_flags=40c0080, b_blkno=3f18, b_bcount=1000, b_baddr=7e3000
...

而普通的buf数据
b_dev=8000000a0000000d, b_flags=80c8000, b_blkno=117b8, b_bcount=1000 b_baddr=f1000a100219f000
b_baddr指向的数据与IO完成后,对应设备的偏移上的数据一致

而第一种有疑问的数,发现其b_flags的B_XPAGER被设定
#define        B_XPAGER        (long)0x80000000        /* D_XPAGER */

尝试xmemdma64(&pbuf->b_xmemd, pbuf->b_baddr, XMEM_HIDE);来获取其数据的真是内存地址, 得到real_mem=17dbf000似乎也不是想要的结果.

实在找不到对这种External pager buffer的相关更详细的说明,希望大神能够给点提示!

论坛徽章:
0
28 [报告]
发表于 2014-07-13 23:38 |只看该作者
你没有源码,ibm也没有公开,单看几个数据对上了,并不能说明任何问题,很多structure的大部分内容甚至关键数据的位置都是相同的,但还是有差异,这要自己慢慢琢磨,比较。

那个是典型的链表结构,如果不知道怎么用,看任何一本数据结构的计算机书都有介绍。

学而不思则罔,思而不学则殆。你困惑是思的太多。

论坛徽章:
0
27 [报告]
发表于 2014-07-13 12:07 |只看该作者
拦截到的是buf应该没错了,因为其他信息,例如b_dev b_blkno b_count都没错,而且b_baddr只有在B_AGE设定了之后才有错.

关于
        struct        buf *b_forw;                /* hash list forward link         */
        struct        buf *b_back;                /* hash list backward link         */
        struct        buf *av_forw;                /* free list forward link         */
        struct        buf *av_back;                /* free list backward link         */

如何可以遍历全部链表呢?按我理解,是知道数值为0表示链表的尽头吗?

还是,和buf差不多的另一个结构,是指bufx?

好困惑啊...{:3_188:}


回复 25# orian


   
  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP