EncoreDeng 发表于 2014-06-30 00:45

关于AIX 虚拟文件系统

大家好,小弟看了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 DIRROOT
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层上是如何进行.

致谢!!









orian 发表于 2014-06-30 07:54

j2_obsolate是给aix421以前版本vnode格式call入口留下的,现在这几个对应的call都不用了

EncoreDeng 发表于 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

orian 发表于 2014-06-30 11:43

只有你自己写的kernel extension程序可能用vn_rdwr,aix自己不用这几个函数的,没什么困惑。普通用户程序用read/write之类的,最后都是由pager内存直接映像写磁盘,没vn_rdwr什么事情。

EncoreDeng 发表于 2014-06-30 13:03

受教!
pager内存直接映像写磁盘, 是否有一些相关文章对此详述?
拜谢!!

回复 4# orian


   

EncoreDeng 发表于 2014-06-30 16:00

orian哥哥,您说的pager内存直接映像写磁盘是指vn_strategy?
通过kdb看到相应的j2函数为j2PagerStrategy.

orian 发表于 2014-06-30 23:11

          是

EncoreDeng 发表于 2014-07-01 00:51

谢谢!我先研究一下。
另外是否有一些资料对此有比较详细的讲解呢?
比如当上层应用调用read/write时,内核如何处理然后调用到vn_strategy.
read/write参数是如何体现到struct buf上?

回复 7# orian


   

orian 发表于 2014-07-01 06:57

那要看源码的,aix不是开源的吧?

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

EncoreDeng 发表于 2014-07-02 15:38

似乎在网上找不到freebsd的源码下载...

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

回复 9# orian


   
页: [1] 2 3 4
查看完整版本: 关于AIX 虚拟文件系统