vfs学习-sysfs

  1. <PRE class=cpp name="code">/* 
  2.  * 一、说明 
  3.  *  sysfs与设备、驱动相关。系统将驱动的层级结构通过sysfs以 
  4.  * 文件系统的形式展现给用户。在驱动方面涉及到的概念有kobject, 
  5.  * kset,bus,device_driver,device,class等等;而在文件系统方面 
  6.  * 涉及到的概念有inode,dentry,super_block,vfsmount等虚拟文件 
  7.  * 系统方面的内容。既然sysfs也是一种文件系统,就必须提供虚拟 
  8.  * 文件系统相关的数据结构。 
  9.  * 各方面内容:用户-访问文件系统->VFS-访问实际文件系统->sysfs 
  10.  * --映射到->driver体系 
  11.  */  
  12. /* 
  13.  * 二、sysfs文件系统的加载 
  14.  */  
  15.   
  16.    
  17.  //sysfs的mount//   
  18.  /* 
  19.   * 调用过程 
  20.   * start_kernel(/init/main.c)->vfs_caches_init(/fs/dcache.c)-> 
  21.   * mnt_init(/fs/namespace.c)->sysfs_init 
  22.   * 在start_kernel中两个函数是文件系统初始化相关的: 
  23.   * vfs_caches_init_early(),vfs_caches_init(totalram_pages) 
  24.   */  
  25.     
  26.     
  27.  /* 
  28.   * /fs/sysfs/mount.c 
  29.   * 几个全局变量 
  30.   */  
  31. /* 
  32.  * 静态,本文件内函数用,vfsmount代表一个加载的文件系统   
  33.  * 这是sysfs的源头,sysfs_mnt 可找到其根dentry,进而可找到inode,超级块等结构 
  34.  * 生成这个结构的过程就是生成inode dentry super_block并使其相关联的过程。 
  35.  */  
  36. static struct vfsmount *sysfs_mnt;  
  37. //sysfs的sysfs_dirent缓存cache   
  38. struct kmem_cache *sysfs_dir_cachep;  
  39. //sysfs的super_block默认操作   
  40. static const struct super_operations sysfs_ops = {  
  41.     .statfs         = simple_statfs,  
  42.     .drop_inode     = generic_delete_inode,  
  43.     .evict_inode    = sysfs_evict_inode,  
  44.  };  
  45. /* 
  46.  * sysfs的根sysfs_dirent结构,此结构是联系kobject层级体系和vfs层级体系的桥梁 
  47.  * 而sysfs_root对应的就是vfs中的根,即/sys/目录 
  48.  */  
  49. struct sysfs_dirent sysfs_root = {  
  50.     .s_name         = "",  
  51.     .s_count        = ATOMIC_INIT(1),  
  52.     .s_flags        = SYSFS_DIR | (KOBJ_NS_TYPE_NONE << SYSFS_NS_TYPE_SHIFT),  
  53.     .s_mode         = S_IFDIR | S_IRUGO | S_IXUGO,  
  54.     .s_ino          = 1,  
  55. };  
  56.  /* 
  57.   * sysfs的type,用来注册sysfs文件系统的全局变量,静态的,本文件内函数使用维护 
  58.   */  
  59.  static struct file_system_type sysfs_fs_type = {  
  60.     .name           = "sysfs",  
  61.     .mount          = sysfs_mount,  
  62.     .kill_sb        = sysfs_kill_sb,  
  63. }  
  64. //初始化sysfs///   
  65. 目标:生成static struct vfsmount *sysfs_mnt//   
  66.   
  67.  int __init sysfs_init(void)  
  68. {  
  69.     int err = -ENOMEM;  
  70.     //cache缓存申请   
  71.     sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache",  
  72.                   sizeof(struct sysfs_dirent),  
  73.                   0, 0, NULL);  
  74.     if (!sysfs_dir_cachep)  
  75.         goto out;  
  76.     /* 
  77.      * 备用存储设备初始化(bdi),用来存储数据的设备  
  78.      */  
  79.     err = sysfs_inode_init();  
  80.     if (err)  
  81.         goto out_err;  
  82.     /* 
  83.      * 注册文件系统,就是将sysfs_fs_type对应的文件系统加入到内核全局变量 
  84.      * file_system中,它定义在:/fs/filesystems.c文件中,是个静态的,只本文件 
  85.      * 相关函数维护和访问 
  86.      * static struct file_system_type *file_systems; 
  87.      * 
  88.      * 传入的参数是静态全局变量sysfs_fs_type 
  89.      */  
  90.     err = register_filesystem(&sysfs_fs_type);  
  91.     if (!err) {  
  92.         /* 
  93.          * /include/linux/fs.h中定义: 
  94.          * #define kern_mount(type) kern_mount_data(type, NULL) 
  95.          * 本函数最终目的是将文件系统的 vfsmount结构 sysfs_mnt存储起来 
  96.          * 核心就是取到这个结构的值,以备后用 
  97.          * 
  98.          * 传入的参数是静态全局变量sysfs_fs_type 
  99.          */  
  100.         sysfs_mnt = kern_mount(&sysfs_fs_type);  
  101.         if (IS_ERR(sysfs_mnt)) {  
  102.         printk(KERN_ERR "sysfs: could not mount!\n");  
  103.         err = PTR_ERR(sysfs_mnt);  
  104.         sysfs_mnt = NULL;  
  105.         unregister_filesystem(&sysfs_fs_type);  
  106.         goto out_err;  
  107.         }  
  108.     } else  
  109.         goto out_err;  
  110. out:  
  111.     return err;  
  112. out_err:  
  113.     kmem_cache_destroy(sysfs_dir_cachep);  
  114.     sysfs_dir_cachep = NULL;  
  115.     goto out;  
  116. }  
  117. /mount vfsmount生成   
  118. /* 
  119.  * /fs/namespace.c中定义: 
  120.  * 调用vfs_kern_mount进一步处理 
  121.  * 
  122.  * 传入的参数是静态全局变量sysfs_fs_type,data=NULL 
  123.  */  
  124. struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)  
  125. {  
  126.     struct vfsmount *mnt;  
  127.     mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);  
  128.     if (!IS_ERR(mnt)) {  
  129.         real_mount(mnt)->mnt_ns = MNT_NS_INTERNAL;  
  130.     }  
  131.     return mnt;  
  132. }  
  133.    
  134. /* 
  135.  * vfsmount与mount结构:前者是后者的一个成员,都有dentry结构 vfsmount.dentry 
  136.  * mount.mnt_mountpoint都指向子文件系统(sysfs)的根dentry 
  137.  * 
  138.  * /fs/namespace.c中定义 
  139.  *参数: 
  140.  * type=sysfs_fs_type 
  141.  * flags=MS_KERNMOUNT 
  142.  * name= type->name=sysfs_fs_type->name="sysfs" 
  143.  * data=NULL 
  144.  *  
  145.  * 本函数是取得struct vfsmount结构。但需要加载sysfs以取得sysfs的根dentry. 
  146.  * 将根dentry与要返回的vfsmount联系起来。 
  147.  * 申请了一个mount,它体内有一个内嵌的vfsmount(不是指针型的),回头将它返回 
  148.  * 也就是说返回的vfsmount是mount的一个成员结构,通过vfsmount就能找到mount 
  149.  */   
  150.   
  151. struct vfsmount *   
  152. vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)  
  153.  {  
  154.     struct mount *mnt;  
  155.     struct dentry *root;  
  156.    
  157.     if (!type)  
  158.         return ERR_PTR(-ENODEV);  
  159.     //申请一个struct mount结构   
  160.     mnt = alloc_vfsmnt(name);  
  161.     if (!mnt)  
  162.         return ERR_PTR(-ENOMEM);  
  163.    
  164.     if (flags & MS_KERNMOUNT)  
  165.         mnt->mnt.mnt_flags = MNT_INTERNAL;  
  166.     //得到本文件系统的根dentry   
  167.     root = mount_fs(type, flags, name, data);  
  168.     if (IS_ERR(root)) {  
  169.         free_vfsmnt(mnt);  
  170.         return ERR_CAST(root);  
  171.     }  
  172.    
  173.     mnt->mnt.mnt_root = root;  
  174.     mnt->mnt.mnt_sb = root->d_sb;  
  175.     mnt->mnt_mountpoint = mnt->mnt.mnt_root;  
  176.     mnt->mnt_parent = mnt;  
  177.     br_write_lock(&vfsmount_lock);  
  178.     //mount结构通过mnt_instance连接到超级块的s_mounts字段   
  179.     list_add_tail(&mnt->mnt_instance, &root->d_sb->s_mounts);  
  180.     br_write_unlock(&vfsmount_lock);  
  181.     return &mnt->mnt;  
  182.  }  
  183. /* 
  184.  * /fs/super.c中定义 
  185.  * 参数: 
  186.  * type=sysfs_fs_type 
  187.  * flags=MS_KERNMOUNT 
  188.  * name= type->name=sysfs_fs_type->name="sysfs" 
  189.  * data=NULL 
  190.  * 
  191.  * 函数功能: 
  192.  * 根据type加载文件系统并返回它的root dentry 
  193.  */  
  194.  struct dentry *  
  195. mount_fs(struct file_system_type *type, int flags, const char *name, void *data)  
  196. {  
  197.     struct dentry *root;  
  198.     struct super_block *sb;  
  199.     char *secdata = NULL;  
  200.     int error = -ENOMEM;  
  201.   
  202.     if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) {  
  203.         secdata = alloc_secdata();  
  204.         if (!secdata)  
  205.             goto out;  
  206.   
  207.         error = security_sb_copy_data(data, secdata);  
  208.         if (error)  
  209.             goto out_free_secdata;  
  210.     }  
  211.     /* 
  212.      * 调用type的mount函数,. 
  213.      * 即sysfs_fs_type->mount=sysfs_mount()[/fs/sysfs/mount.c] 
  214.      * 整个过程像是这样:对VFS来说,它只要知道文件系统相关信息,并存储起来 
  215.      * 且vfs调用自己定义好的接口来实现mount(其它操作也一样),具体功能 
  216.      * 由具体的文件系统自己定义,只要接口保持一致就行。 
  217.      * 对sysfs来说,它提供具体相关结构的生成,还得靠自己的函数。这些结构 
  218.      * 包括dentry..super_block..mount..vfsmount等,只是把这些信息放在了 
  219.      * 文件系统类型sysfs_fs_type中,等待VFS体系来调用罢了。说白了自己让别人 
  220.      * 管自己,最后还是自己劳动。 
  221.      */  
  222.        
  223.     root = type->mount(type, flags, name, data);  
  224.     if (IS_ERR(root)) {  
  225.         error = PTR_ERR(root);  
  226.         goto out_free_secdata;  
  227.     }  
  228.     sb = root->d_sb;  
  229.     BUG_ON(!sb);  
  230.     WARN_ON(!sb->s_bdi);  
  231.     WARN_ON(sb->s_bdi == &default_backing_dev_info);  
  232.     sb->s_flags |= MS_BORN;  
  233.   
  234.     error = security_sb_kern_mount(sb, flags, secdata);  
  235.     if (error)  
  236.         goto out_sb;   
  237.     ......  
  238.     up_write(&sb->s_umount);  
  239.     free_secdata(secdata);  
  240.     return root;  
  241. out_sb:  
  242.     dput(root);  
  243.     deactivate_locked_super(sb);  
  244. out_free_secdata:  
  245.     free_secdata(secdata);  
  246. out:  
  247.     return ERR_PTR(error);  
  248. }  
  249.    
  250. /* 
  251.  * /fs/sysfs/mount.c 
  252.  * 
  253.  * fs_type=sysfs_fs_type 
  254.  * flags=MS_KERNMOUNT 
  255.  * dev_name= type->name=sysfs_fs_type->name="sysfs" 
  256.  * data=NULL 
  257.  * 
  258.  * 函数功能: 
  259.  * 加载sysfs文件系统,并返回sysfs的root dentry 
  260.  * sb = sget取得super_block 
  261.  * sysfs_fill_super(sb填充sb,并组织与sb相关的根inode dentry以及与 
  262.  * 根dirent sysfs_root关联起来 
  263.  * 最后将根dentry返回 
  264.  */  
  265. static struct dentry *sysfs_mount(struct file_system_type *fs_type,  
  266.     int flags, const char *dev_name, void *data)  
  267. {  
  268.     struct sysfs_super_info *info;  
  269.     enum kobj_ns_type type;  
  270.     struct super_block *sb;  
  271.     int error;  
  272.   
  273.     info = kzalloc(sizeof(*info), GFP_KERNEL);  
  274.     if (!info)  
  275.          return ERR_PTR(-ENOMEM);  
  276.     //命名空间相关   
  277.     for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++)  
  278.          info->ns[type] = kobj_ns_grab_current(type);  
  279.       
  280.     //查询取得,或新创建一个super_block       
  281.     sb = sget(fs_type, sysfs_test_super, sysfs_set_super, flags, info);  
  282.     if (IS_ERR(sb) || sb->s_fs_info != info)  
  283.          free_sysfs_super_info(info);  
  284.     if (IS_ERR(sb))  
  285.          return ERR_CAST(sb);  
  286.     if (!sb->s_root) {  
  287.         //新创建的sb,s_root肯定为空,则需要填充super_block   
  288.          error = sysfs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0);  
  289.          if (error) {  
  290.              deactivate_locked_super(sb);  
  291.              return ERR_PTR(error);  
  292.          }  
  293.          sb->s_flags |= MS_ACTIVE;  
  294.     }  
  295.   
  296.     return dget(sb->s_root);  
  297. }  
  298.   
  299. //超级块生成   
  300. /* 
  301.  * 在/fs/super.c中定义: 
  302.  * fs_type=sysfs_fs_type 
  303.  * sysfs_test_super 
  304.  * sysfs_set_super 
  305.  * flags=MS_KERNMOUNT 
  306.  * data=NULL 
  307.  * 
  308.  * 函数功能: 
  309.  * 在type的super_blocks列表中查找或新创建一个属于type的super_block 
  310.  */  
  311. struct super_block *sget(struct file_system_type *type,  
  312.              int (*test)(struct super_block *,void *),  
  313.              int (*set)(struct super_block *,void *),  
  314.              int flags,  
  315.              void *data)  
  316.  {  
  317.      struct super_block *s = NULL;  
  318.      struct hlist_node *node;  
  319.      struct super_block *old;  
  320.      int err;  
  321.    
  322.  retry:  
  323.     spin_lock(&sb_lock);  
  324.     if (test) {  
  325.         hlist_for_each_entry(old, node, &type->fs_supers, s_instances) {  
  326.         //test不断失败,直到循环结束,old是迭代指针,列表是type->fs_supers   
  327.              if (!test(old, data))  
  328.                  continue;  
  329.              if (!grab_super(old))  
  330.                  goto retry;  
  331.              if (s) {  
  332.                  up_write(&s->s_umount);  
  333.                  destroy_super(s);  
  334.                  s = NULL;  
  335.              }  
  336.              down_write(&old->s_umount);  
  337.              if (unlikely(!(old->s_flags & MS_BORN))) {  
  338.                  deactivate_locked_super(old);  
  339.                  goto retry;  
  340.              }  
  341.              return old;  
  342.          }  
  343.      }  
  344.      //新建的话,s肯定是null   
  345.      if (!s) {  
  346.          spin_unlock(&sb_lock);  
  347.          //申请一个空super_block   
  348.          s = alloc_super(type, flags);  
  349.          if (!s)  
  350.              return ERR_PTR(-ENOMEM);  
  351.          goto retry;  
  352.      }  
  353.     //设置好s的数据   
  354.     err = set(s, data);  
  355.      if (err) {  
  356.          spin_unlock(&sb_lock);  
  357.          up_write(&s->s_umount);  
  358.          destroy_super(s);  
  359.          return ERR_PTR(err);  
  360.      }  
  361.     //设置type,名称,并添加到全系统全局变量super_blocks中去   
  362.     s->s_type = type;  
  363.     strlcpy(s->s_id, type->name, sizeof(s->s_id));  
  364.      list_add_tail(&s->s_list, &super_blocks);  
  365.      hlist_add_head(&s->s_instances, &type->fs_supers);  
  366.      spin_unlock(&sb_lock);  
  367.      get_filesystem(type);  
  368.      //内存管理   
  369.      register_shrinker(&s->s_shrink);  
  370.      return s;  
  371.  }  
  372. /* 
  373.  * 定义在:/fs/sysfs/mount.c 
  374.  * super_block=申请的那个超级块 
  375.  * data=NULL 
  376.  * silent=flags & MS_SILENT ? 1 : 0 
  377.  * 
  378.  * 函数功能: 
  379.  * 给sysfs的super_block填充内容; 根据super_block和sysfs_root这个根dirent 
  380.  * 生成根dentry root的inode。最终将 super_block sysfs_root root dentry  
  381.  * inode 关联起来,就是将VFS需要的那几项组织起来。虽然返回super_block, 
  382.  * 但与super_block相关的内容都处理好了。 
  383.  */   
  384. static int sysfs_fill_super(struct super_block *sb, void *data, int silent)  
  385.   {  
  386.     struct inode *inode;  
  387.     struct dentry *root;  
  388.     
  389.     sb->s_blocksize = PAGE_CACHE_SIZE;  
  390.     sb->s_blocksize_bits = PAGE_CACHE_SHIFT;  
  391.     sb->s_magic = SYSFS_MAGIC;  
  392.     sb->s_op = &sysfs_ops;  
  393.     sb->s_time_gran = 1;  
  394.     
  395.     /* get root inode, initialize and unlock it */  
  396.     mutex_lock(&sysfs_mutex);  
  397.     //生成根dentry root的inode   
  398.     inode = sysfs_get_inode(sb, &sysfs_root);  
  399.     mutex_unlock(&sysfs_mutex);  
  400.     if (!inode) {  
  401.           pr_debug("sysfs: could not get root inode\n");  
  402.           return -ENOMEM;  
  403.     }  
  404.     
  405.     //根据根inode生成根 dentry   
  406.     root = d_make_root(inode);  
  407.     if (!root) {  
  408.           pr_debug("%s: could not get root dentry!\n",__func__);  
  409.           return -ENOMEM;  
  410.     }  
  411.     root->d_fsdata = &sysfs_root;  
  412.     sb->s_root = root;  
  413.     sb->s_d_op = &sysfs_dentry_ops;  
  414.     return 0;  
  415.   }  
  416.     
  417. ///由全局变量sysfs_dirent sysfs_root生成inode///   
  418.  /* 
  419.   * /fs/sysfs/inode.c 
  420.   * 参数:  
  421.   * sb=sysfs的那个super_block 
  422.   * sysfs_dirent=sysfs_root 
  423.   * 
  424.   * 函数功能: 
  425.   * 由sysfs_dirent生成一个inode 
  426.   * 再看看sysfs_root的定义(/fs/sysfs/mount.c) 
  427.   *   struct sysfs_dirent sysfs_root = { 
  428.   *     .s_name         = "", 
  429.   *     .s_count        = ATOMIC_INIT(1), 
  430.   *     .s_flags        = SYSFS_DIR | (KOBJ_NS_TYPE_NONE << SYSFS_NS_TYPE_SHIFT), 
  431.   *     .s_mode         = S_IFDIR | S_IRUGO | S_IXUGO, 
  432.   *     .s_ino          = 1, 
  433.   * }; 
  434.   */  
  435.   struct inode * sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd)  
  436.  {  
  437.     struct inode *inode;  
  438.     //由一个加载的文件系统获得一个inode,由上可知传进去的s_ino=1   
  439.     inode = iget_locked(sb, sd->s_ino);  
  440.     if (inode && (inode->i_state & I_NEW))  
  441.         sysfs_init_inode(sd, inode); //初始化这个inode   
  442.         return inode;  
  443.  }  
  444.  /* 
  445.   * 静态全局变量,inode hash列表,inode_hashtable[hash]是一个相同hash值=hash的列表 
  446.   */  
  447.  static struct hlist_head *inode_hashtable __read_mostly;  
  448.    
  449. /* 
  450.  * /fs/inode.c: 
  451.  * 参数: 
  452.  * sb=sysfs的超级块 
  453.  * ino=sysfs_root.s_ino=1 
  454.  *  
  455.  * 函数功能: 
  456.  * 从一个加载的文件系统中申请一个inode出来 
  457.  * 用到静态全局变量inode_hashtable 
  458.  */  
  459. struct inode *iget_locked(struct super_block *sb, unsigned long ino)  
  460. {  
  461.     struct hlist_head *head = inode_hashtable + hash(sb, ino);  
  462.     struct inode *inode;  
  463.     //@@@@第一次锁申请   
  464.     spin_lock(&inode_hash_lock);  
  465.     //1号inode还没生成,当然找不到了   
  466.     inode = find_inode_fast(sb, head, ino);  
  467.     //@@@@第一次锁释放   
  468.     spin_unlock(&inode_hash_lock);  
  469.     if (inode) {  
  470.         wait_on_inode(inode);  
  471.         return inode;  
  472.     }  
  473.     //生成1号inode,申请inode空间并初始化   
  474.     inode = alloc_inode(sb);  
  475.     if (inode) {  
  476.         struct inode *old;  
  477.         //@@@@第二次锁申请   
  478.         spin_lock(&inode_hash_lock);  
  479.         /* 
  480.          * 因为在两次加锁中间可能有别人申请了本号码的inode, 
  481.          * 所以再查找一次 
  482.          */  
  483.         old = find_inode_fast(sb, head, ino);  
  484.         if (!old) {  
  485.             //如果没找到,就用我们刚才申请的的inode   
  486.             inode->i_ino = ino;  
  487.             spin_lock(&inode->i_lock);  
  488.             //设置状态   
  489.             inode->i_state = I_NEW;  
  490.             hlist_add_head(&inode->i_hash, head);  
  491.             spin_unlock(&inode->i_lock);  
  492.             inode_sb_list_add(inode);  
  493.             spin_unlock(&inode_hash_lock);  
  494.   
  495.             /* Return the locked inode with I_NEW set, the 
  496.              * caller is responsible for filling in the contents 
  497.              */  
  498.             return inode;  
  499.         }  
  500.           
  501.         /* 
  502.          * Uhhuh, somebody else created the same inode under 
  503.          * us. Use the old inode instead of the one we just 
  504.          * allocated. 
  505.          * 执行到这里说明有别人在两锁中间申请了本号码的inode 
  506.          * 则把我们申请的释放掉,然后用别人的那个(old) 
  507.          */  
  508.         spin_unlock(&inode_hash_lock);  
  509.         destroy_inode(inode);  
  510.         inode = old;  
  511.         wait_on_inode(inode);  
  512.     }  
  513.     return inode;  
  514. }  
  515.   
  516. /* 
  517.  * 在fs/sysfs/inode.c中: 
  518.  */  
  519.   
  520.   static const struct address_space_operations sysfs_aops = {  
  521.           .readpage       = simple_readpage,  
  522.           .write_begin    = simple_write_begin,  
  523.           .write_end      = simple_write_end,  
  524.   };  
  525.     
  526.   static struct backing_dev_info sysfs_backing_dev_info = {  
  527.           .name           = "sysfs",  
  528.           .ra_pages       = 0,    /* No readahead */  
  529.           .capabilities   = BDI_CAP_NO_ACCT_AND_WRITEBACK,  
  530.   };  
  531.     
  532.   static const struct inode_operations sysfs_inode_operations ={  
  533.           .permission     = sysfs_permission,  
  534.           .setattr        = sysfs_setattr,  
  535.           .getattr        = sysfs_getattr,  
  536.           .setxattr       = sysfs_setxattr,  
  537.   };  
  538.   
  539. /* 
  540.  * 在fs/sysfs/inode.c中: 
  541.  * 参数 
  542.  * sd=sysfs_root 
  543.  * inode=与sysfs_root对应的1号inode 
  544.  * 功能:初始化inode 
  545.    
  546.  * 再看看sysfs_root的定义(/fs/sysfs/mount.c) 
  547.  *    struct sysfs_dirent sysfs_root = { 
  548.  *      .s_name         = "", 
  549.  *      .s_count        = ATOMIC_INIT(1), 
  550.  *      .s_flags        = SYSFS_DIR | (KOBJ_NS_TYPE_NONE << SYSFS_NS_TYPE_SHIFT), 
  551.  *      .s_mode         = S_IFDIR | S_IRUGO | S_IXUGO, 
  552.  *      .s_ino          = 1, 
  553.  *  }; 
  554.  */  
  555.  static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)  
  556.  {  
  557.     struct bin_attribute *bin_attr;  
  558.     /* 
  559.      * i_private字段存储inode与文件系统相关的信息,在sysfs中存储的是sysfs_dirent结构 
  560.      */  
  561.     inode->i_private = sysfs_get(sd);  
  562.     inode->i_mapping->a_ops = &sysfs_aops;  
  563.     inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;  
  564.     inode->i_op = &sysfs_inode_operations;  
  565.    
  566.     set_default_inode_attr(inode, sd->s_mode);  
  567.     sysfs_refresh_inode(sd, inode);  
  568.    
  569.     /* initialize inode according to type */  
  570.     switch (sysfs_type(sd)) {  
  571.     case SYSFS_DIR:  
  572.         /* 
  573.          * sysfs_root的s_flags是SYSFS_DIR,所以i_op和i_fop指向相应位置 
  574.          */  
  575.          inode->i_op = &sysfs_dir_inode_operations;  
  576.          inode->i_fop = &sysfs_dir_operations;  
  577.          break;  
  578.     case SYSFS_KOBJ_ATTR:  
  579.          inode->i_size = PAGE_SIZE;  
  580.          inode->i_fop = &sysfs_file_operations;  
  581.          break;  
  582.     case SYSFS_KOBJ_BIN_ATTR:  
  583.          bin_attr = sd->s_bin_attr.bin_attr;  
  584.          inode->i_size = bin_attr->size;  
  585.          inode->i_fop = &bin_fops;  
  586.          break;  
  587.     case SYSFS_KOBJ_LINK:  
  588.          inode->i_op = &sysfs_symlink_inode_operations;  
  589.          break;  
  590.     default:  
  591.          BUG();  
  592.     }  
  593.    
  594.     unlock_new_inode(inode);  
  595.  }  
  596.   
  597. /由sysfs_root dirent对应的inode生成dentry///   
  598.   
  599. /* 
  600.  * /fs/dcache.c: 
  601.  * 参数:sysfs_root dirent对应的inode 
  602.  * 功能:生成对应的dentry 
  603.  */  
  604. struct dentry *d_make_root(struct inode *root_inode)  
  605. {  
  606.     struct dentry *res = NULL;  
  607.   
  608.     if (root_inode) {  
  609.         //name变量="/"   
  610.         static const struct qstr name = QSTR_INIT("/", 1);  
  611.         //在sb中申请出一个dentry   
  612.         res = __d_alloc(root_inode->i_sb, &name);  
  613.         if (res)  
  614.             //用inode信息初始化,使之与root_inode关联   
  615.             d_instantiate(res, root_inode);  
  616.         else  
  617.             iput(root_inode);  
  618.     }  
  619.     return res;  
  620. }  
  621.   
  622. /* 
  623.  * /fs/dcache.c: 
  624.  * 从文件系统申请一个dentry 
  625.  */  
  626. struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)  
  627. {  
  628.     struct dentry *dentry;  
  629.     char *dname;  
  630.     //内存申请   
  631.     dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);  
  632.     if (!dentry)  
  633.         return NULL;  
  634.     //名称串内存申请   
  635.     dentry->d_iname[DNAME_INLINE_LEN-1] = 0;  
  636.     if (name->len > DNAME_INLINE_LEN-1) {  
  637.         dname = kmalloc(name->len + 1, GFP_KERNEL);  
  638.         if (!dname) {  
  639.             kmem_cache_free(dentry_cache, dentry);   
  640.             return NULL;  
  641.         }  
  642.     } else  {  
  643.         dname = dentry->d_iname;  
  644.     }         
  645.     //名字复制   
  646.     dentry->d_name.len = name->len;  
  647.     dentry->d_name.hash = name->hash;  
  648.     memcpy(dname, name->name, name->len);  
  649.     dname[name->len] = 0;  
  650.   
  651.     /* Make sure we always see the terminating NUL character */  
  652.     smp_wmb();  
  653.     //名字指针赋值   
  654.     dentry->d_name.name = dname;  
  655.     //下面是各种初始化   
  656.     dentry->d_count = 1;  
  657.     dentry->d_flags = 0;  
  658.     spin_lock_init(&dentry->d_lock);  
  659.     seqcount_init(&dentry->d_seq);  
  660.     dentry->d_inode = NULL;  
  661.     dentry->d_parent = dentry;  
  662.     dentry->d_sb = sb;  
  663.     dentry->d_op = NULL;  
  664.     dentry->d_fsdata = NULL;  
  665.     INIT_HLIST_BL_NODE(&dentry->d_hash);  
  666.     INIT_LIST_HEAD(&dentry->d_lru);  
  667.     INIT_LIST_HEAD(&dentry->d_subdirs);  
  668.     INIT_HLIST_NODE(&dentry->d_alias);  
  669.     INIT_LIST_HEAD(&dentry->d_u.d_child);  
  670.     d_set_d_op(dentry, dentry->d_sb->s_d_op);  
  671.   
  672.     this_cpu_inc(nr_dentry);  
  673.   
  674.     return dentry;  
  675. }  
  676.   
  677. /* 
  678.  * 最终生成了使vfsmount sysfs_mnt=mount.mnt这个全局变量得到赋值后 
  679.  * 以后要找sysfs便可从sysfs_mnt找。因为它是静态的,所以它的值是由 
  680.  * 模块内函数维护的。VFS对一个文件系统要求的inode_root,dentry_root, 
  681.  * super_block等都可以从这个变量找到。 
  682.  * 具体的inode和dentry是在sysfs_lookup时才生成的,没有事先生成。先 
  683.  * 操作dirent的层次,最后返回基于dirent的dentry 
  684.  *  
  685.  *   
  686.  */  
  687.  /* 
  688.   * 三、设备驱动模块kobject等 
  689.   */    
  690.    
  691.  /* 
  692.   * 关系: 
  693.   * kset: 
  694.   *     向下:指向子节点链表 kset->list 
  695.   *     自己:kobj对应,因此kobject不是个指针,所以本kobj能定位到自己的kset 
  696.   *     向上: kobj->parent,kobj->kset(父级kset) 
  697.   * kobject: 
  698.   *     向上: kobject->parent 
  699.   *     横向: entry链入兄弟链表,进入父kset的list字段 
  700.   * sysfs_dirent: 
  701.   *     向上: parent, 
  702.   *     向下: s_dir.children(只能是目录) 
  703.   *     横向: s_rb 
  704.   * 
  705.   *  
  706.   * kobject->sd 指向对应的sysfs_dirent结构 
  707.   * sysfs_dirent->s_ino指向对应的inode号 
  708.   * inode->i_private存储其对应的sysfs_dirent结构 
  709.   * dentry->d_fsdata指向对应的sysfs_dirent结构 
  710.   * inode->i_dentry指向对应dentry列表 
  711.   * dentry->d_inode指向对应的inode 
  712.   * 
  713.   *     kset{kobject} 
  714.   *       ^  7 
  715.   *       |/ 
  716.   *       v 
  717.   *     kobject---->sysfs_dirent<------>inode  
  718.   *                                       ^1 
  719.   *                                       |  
  720.   *                                       v n    
  721.   *                 sysfs_dirent<------dentry 
  722.   */  
  723.    
  724.  /* 
  725.  * kset 是管理kobject的集合,自身体内含有一个kobject,是kset所包含 
  726.  * 子kobject集合的父亲。kset还可以包含其它的kset(kset->kobj->kset?) 
  727.  */    
  728.    
  729. struct kset {//在sysfs目录结构中,kset是个目录   
  730.     struct list_head    list;//子层kobject链表   
  731.     spinlock_t          list_lock;  
  732.     struct  kobject     kobj;//本层kobject,代表sysfs目录结构中的自己   
  733.     const struct kset_uevent_ops *uevent_ops;  
  734. };  
  735.    
  736.    
  737.    
  738. struct kobject {  
  739.     const char              *name;//设备名   
  740.     struct list_head        entry;//链入kset(兄弟链)   
  741.     struct kobject          *parent;//父对象   
  742.     struct kset             *kset;//本对象所属的kset(父集链)   
  743.     struct kobj_type        *ktype;//对象类型描述符   
  744.     /* 
  745.      * dentry,inode相关字段,组成sysfs文件系统层级关系 
  746.      * 每个sysfs节点有一个sysfs_dirent结构 
  747.      */  
  748.     struct sysfs_dirent     *sd;  
  749.     struct kref             kref;//引用计数   
  750.     unsigned int state_initialized:1;  
  751.     unsigned int state_in_sysfs:1;//说明本节点在sysfs中有对应   
  752.     unsigned int state_add_uevent_sent:1;  
  753.     unsigned int state_remove_uevent_sent:1;  
  754.     unsigned int uevent_suppress:1;  
  755. };  
  756. /* 
  757.  * kobject与vfs关联 
  758.  * inode->i_private存储其对应的sysfs_dirent结构 
  759.  * sysfs_dirent.s_ino对应inode节点号 
  760.  * 向上有parent,向下(只能是目录)有s_dir.children 
  761.  * 横向兄弟有s_rb 
  762.  * 这样就形成了一个层级结构 
  763.  */  
  764. struct sysfs_dirent {  
  765.     atomic_t                s_count;  
  766.     atomic_t                s_active;  
  767.     #ifdef CONFIG_DEBUG_LOCK_ALLOC   
  768.         struct lockdep_map      dep_map;  
  769.     #endif   
  770.     struct sysfs_dirent     *s_parent;//父节点   
  771.     const char              *s_name;  
  772.     //兄弟节点,链入父节点的s_dir.children字段   
  773.     struct rb_node          s_rb;  
  774.     union {  
  775.         struct completion       *completion;  
  776.         struct sysfs_dirent     *removed_list;  
  777.     } u;  
  778.     const void              *s_ns; /* namespace tag */  
  779.     unsigned int            s_hash; /* ns + name hash */  
  780.     union {  
  781.         struct sysfs_elem_dir           s_dir;//目录级联用   
  782.         struct sysfs_elem_symlink       s_symlink;  
  783.         struct sysfs_elem_attr          s_attr;  
  784.         struct sysfs_elem_bin_attr      s_bin_attr;  
  785.     };  
  786.     /* 
  787.      * s_flags表明在sysfs中的类型 
  788.      * SYSFS_DIR,SYSFS_KOBJ_ATTR, SYSFS_KOBJ_BIN_ATTR,SYSFS_KOBJ_LINK 
  789.      */  
  790.     unsigned short          s_flags;  
  791.     umode_t                 s_mode;  
  792.     unsigned int            s_ino;//对应的inode节点id号   
  793.     struct sysfs_inode_attrs *s_iattr;  
  794. };  
  795.   
  796.   
  797. /* 
  798.  * sysfs_dirent与dentry的关联,dentry的层次与kobject相同 
  799.  * kobject形成设备、驱动层次,而dentry负责在stsfs中将这个 
  800.  * 层次以文件的形式展示出来 
  801.  * 在v3.6.2/fs/sysfs/inode.c中 
  802.  * sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) 
  803.  * 根据sysfs_dirent生成inode 
  804.  */  
  805. dentry->d_fsdata是void指针,指向sysfs_dirent  
  806.   
  807. struct kobj_type {  
  808.     void (*release)(struct kobject *kobj);//资源释放   
  809.     const struct sysfs_ops *sysfs_ops;//操作   
  810.     struct attribute **default_attrs;//默认属性   
  811.     const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);  
  812.     const void *(*namespace)(struct kobject *kobj);  
  813. };  
  814. struct sysfs_ops {  
  815.     //用户读取数据   
  816.     ssize_t (*show)(struct kobject *, struct attribute *,char *);  
  817.     //用户写入数据   
  818.     ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);  
  819.     const void *(*namespace)(struct kobject *, const struct attribute *);  
  820. };  
  821. //在http://lxr.linux.no/linux+v3.6.2/include/linux/kobject.h中:   
  822. extern const struct sysfs_ops kobj_sysfs_ops;  
  823.   
  824. //在http://lxr.linux.no/linux+v3.6.2/lib/kobject.c中:   
  825. const struct sysfs_ops kobj_sysfs_ops = {  
  826.     .show   = kobj_attr_show,  
  827.     .store  = kobj_attr_store,  
  828. };  
  829.    
  830. struct attribute {  
  831.     const char  *name;//sysfs目录中的文件名   
  832.     umode_t      mode;  
  833. #ifdef CONFIG_DEBUG_LOCK_ALLOC   
  834.     bool                    ignore_lockdep:1;  
  835.     struct lock_class_key   *key;  
  836.     struct lock_class_key   skey;  
  837. #endif   
  838. };  
  839.   
  840. /* 
  841.  * 每个bus_type对应/sys/bus下一个子目录,如/sys/bus/pci 
  842.  * 每个子目录下有两个目录devices,drivers; 前者表示总线上所有设备;  
  843.  * 后者表示与该总线相"关联"的所有驱动程序。另外就是几个处理函数。 
  844.  *  
  845.      
  846.  * 一些结构: 
  847.  * bus_type  
  848.         ->device *dev_root; 
  849.  * device 
  850.         ->device*parent指向父设备 
  851.         ->kobj 
  852.         ->type设备类型 
  853.         ->bus总线 
  854.         ->device_driver *driver申请本结构的驱动程序 
  855.         ->class设备的class 
  856.  * device_driver 
  857.         ->bus_type *bus指向bus 
  858.  * class 
  859.         ->dev_kobj代表class链入层级关系 
  860.    
  861.  */    
  862.     
  863. struct bus_type {//系统总线结构   
  864.     const char              *name;//名称   
  865.     const char              *dev_name;//设备名   
  866.     struct device           *dev_root;//默认根设备   
  867.     struct bus_attribute    *bus_attrs;//默认总线属性   
  868.     struct device_attribute *dev_attrs;//总线上默认设备属性   
  869.     struct driver_attribute *drv_attrs;//总线上默认设备驱动属性   
  870.     int (*match)(struct device *dev, struct device_driver *drv);  
  871.     int (*uevent)(struct device *dev, struct kobj_uevent_env *env);  
  872.     int (*probe)(struct device *dev);  
  873.     int (*remove)(struct device *dev);  
  874.     void (*shutdown)(struct device *dev);  
  875.     int (*suspend)(struct device *dev, pm_message_t state);  
  876.     int (*resume)(struct device *dev);  
  877.     const struct dev_pm_ops *pm;  
  878.     struct iommu_ops *iommu_ops;  
  879.     struct subsys_private *p;//驱动抽象中:bus私有数据   
  880. };  
  881.     
  882. /* 
  883.  *  http://lxr.linux.no/linux+v3.6.2/drivers/base/base.h中: 
  884.  *  subsys_private,driver_private,device_private 
  885.  */    
  886. struct subsys_private {  
  887.     struct kset subsys;//回指定义本subsys的kset   
  888.     struct kset *devices_kset;//device目录   
  889.     struct list_head interfaces;  
  890.     struct mutex mutex;  
  891.     struct kset *drivers_kset;//driver目录?   
  892.     struct klist klist_devices;//用来遍历devices_kset   
  893.     struct klist klist_drivers;//用来遍历drivers_kset   
  894.     //本bus有事件的话,就会通知本链上函数   
  895.     struct blocking_notifier_head bus_notifier;  
  896.     unsigned int drivers_autoprobe:1;  
  897.     struct bus_type *bus;//本结构所相关的bus_type   
  898.     struct kset glue_dirs;  
  899.     struct class *class;//本结构相关的class   
  900. };  
  901.   
  902. struct driver_private {  
  903.     struct kobject kobj;  
  904.     struct klist klist_devices;  
  905.     struct klist_node knode_bus;  
  906.     struct module_kobject *mkobj;  
  907.     struct device_driver *driver;  
  908. };  
  909. struct device_private {  
  910.     struct klist klist_children;  
  911.     struct klist_node knode_parent;  
  912.     struct klist_node knode_driver;  
  913.     struct klist_node knode_bus;  
  914.     struct list_head deferred_probe;  
  915.     void *driver_data;  
  916.     struct device *device;  
  917. };  
  918.   
  919.   
  920.   
  921. /* 
  922.  * kset代表一个目录,它体内的kobject与sysfs关联 
  923.  * 子kobject代表sysfs中的一个文件 
  924.  * subsys_private与bus对应,subsys_private体内有两个子kset代表两个子目录 
  925.  * devices与drivers。  
  926.  * device_private与device结构对应,而device体内有kobject,代表一个设备 
  927.  * driver_private与device_driver对应,driver_private有kobject代表一个驱动 
  928.  * 
  929.  * 分了3类东西, 
  930.  * 第1类在include/linux/kobject.h中,是kset,kobject,sysfs_dirent(与sysfs关联) 
  931.  * 第2类在include/linux/device.h中,  是bus_type,device,device_driver,class 
  932.  * 第3类在drivers/base/base.h中,是subsys_private,driver_private,device_private 
  933.  * 1在抽象,2是设备,3是驱动 
  934.  *  kset含有kobject: 
  935.         ->kobj   本层 
  936.         ->list  子层 
  937.     bus的subsys_private有两个kset 
  938.         ->devices_kset 总线上的设备集合 
  939.         ->drivers_kset 总线相关的驱动集合 
  940.          
  941.     device有个kobject 
  942.         ->kobj 本设备对象的kobject 
  943.     driver_private有个kobject 
  944.         ->kobj 本驱动对象的kobject 
  945.  * 
  946.  */  
  947.   
  948. /* 
  949.  * 二、过程 
  950.  *  
  951.  * 一些全局变量 
  952.  * /drivers/base/core.c: 
  953.     struct kset *devices_kset;系统内所有设备,对应/sys/devices/ 
  954.     /drivers/base/bus.c: 
  955.     这里的两个是静态的,说明只在本文件中有效,也就是只有用本文件中的函数 
  956.     才能访问。 
  957.     static struct kset *bus_kset;系统内所有总线,对应/sys/bus/ 
  958.     static struct kset *system_kset;所有子系统,对应/sys/devices/system 
  959.      
  960.      
  961.     start_kernel->rest_init-创建进程->kernel_init(pid=1)->do_basic_setup 
  962.     ->driver_init[v3.6.2/drivers/base/init.c]->buses_init 
  963.     实际上在driver_init时就涉及许多设备驱动相关的初始化 
  964.  */  
  965. void __init driver_init(void)  
  966. {  
  967.     devtmpfs_init();  
  968.     devices_init();//设备初始化   
  969.     buses_init();//这就是总线初始化   
  970.     classes_init();  
  971.     firmware_init();  
  972.     hypervisor_init();  
  973.     platform_bus_init();  
  974.     cpu_dev_init();  
  975.     memory_dev_init();  
  976. }  
  977. /* 
  978.  * /sys/是sysfs的根,下面的函数就是在根下放几个目录:/sys/devices/,/sys/dev/, 
  979.  * /sys/dev/block/和/sys/dev/char/这几个目录都是"设备(device)相关"的。 
  980.  */  
  981. int __init devices_init(void)  
  982. {  
  983.     devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);  
  984.     if (!devices_kset)  
  985.         return -ENOMEM;  
  986.     dev_kobj = kobject_create_and_add("dev", NULL);  
  987.     if (!dev_kobj)  
  988.         goto dev_kobj_err;  
  989.     sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj);  
  990.     if (!sysfs_dev_block_kobj)  
  991.         goto block_kobj_err;  
  992.     sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj);  
  993.     if (!sysfs_dev_char_kobj)  
  994.         goto char_kobj_err;  
  995.     return 0;  
  996. char_kobj_err:  
  997.     kobject_put(sysfs_dev_block_kobj);  
  998. block_kobj_err:  
  999.     kobject_put(dev_kobj);  
  1000. dev_kobj_err:  
  1001.     kset_unregister(devices_kset);  
  1002.     return -ENOMEM;  
  1003. }  
  1004.   
  1005.   
  1006. /* 
  1007.  * 与上面函数类似,此函数功能是创添加了/sys/bus/和/sys/devices/system/ 
  1008.  */  
  1009. int __init buses_init(void)  
  1010. {     
  1011. //最后一个参数是parent_kobj,就是父节点的kobject,null就直接挂根上/sys/bus/   
  1012.     bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);  
  1013.     if (!bus_kset)  
  1014.         return -ENOMEM;  
  1015.     //父节点为devices_kset->kobj,所以是在/sys/devices/下挂着   
  1016.     system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);  
  1017.     if (!system_kset)  
  1018.         return -ENOMEM;  
  1019.     return 0;  
  1020. }  
  1021. /* 
  1022.  * 顺便提下subsys_system_register函数,在/drivers/base/bus.c中有一句: 
  1023.  * EXPORT_SYMBOL_GPL(subsys_system_register);说明它是被其它模块调用的 
  1024.  * 一个subsys跟一个总线相关。所以此函数调用bus_register来注册一种类型 
  1025.  * 的总线bus_type 
  1026.  * int subsys_system_register(struct bus_type *subsys, 
  1027.  *                              const struct attribute_group **groups) 
  1028.  * 子系统没理解好,子系统注册时用的就是bus_type,一个bus就是 
  1029.  * 一个子系统,一个子系统又可包含更广泛的概念?看代码好像是注册一个 
  1030.  * subsystem就是注册一个bus,因为调用了bus_register 
  1031.  */  
  1032.   
  1033. 添加dir///   
  1034. /* 
  1035.  * 添加kobject对应就是在sysfs添加一个目录,即/sys/xxx/,用函数: 
  1036.  * 在v3.6.2/lib/kobject.c: 
  1037.  * kset_create_and_add->kset_register->kobject_add_internal 
  1038.  * 在kset_create_and_add里会创建一个kset并将它与父级kobject链起来。然后 
  1039.  * 再调用kset_register将本kobject加入sysfs并发送通知事件。 
  1040.  */  
  1041.    
  1042. static int kobject_add_internal(struct kobject *kobj)  
  1043. {  
  1044.     int error = 0;  
  1045.     struct kobject *parent;       
  1046.     if (!kobj)return -ENOENT;     
  1047.     if (!kobj->name || !kobj->name[0]) {        
  1048.         return -EINVAL;  
  1049.     }  
  1050.     //父级kobject引用++,父kobj可能不存在   
  1051.     parent = kobject_get(kobj->parent);    
  1052.     //若kset存在且父节点没取到,再从kset里取一次   
  1053.     if (kobj->kset) {  
  1054.         if (!parent)  
  1055.             parent = kobject_get(&kobj->kset->kobj);  
  1056.             kobj_kset_join(kobj);  
  1057.             kobj->parent = parent;  
  1058.     }     
  1059.     ......  
  1060.     error = create_dir(kobj);  
  1061.     if (error) {  
  1062.         kobj_kset_leave(kobj);  
  1063.         kobject_put(parent);  
  1064.         kobj->parent = NULL;       
  1065.         ......  
  1066.     } else  
  1067.         kobj->state_in_sysfs = 1;      
  1068.         return error;  
  1069.     }  
  1070. /* 
  1071.  * 从create_dir这个函数开始就进入了sysfs流程 
  1072.  */  
  1073. static int create_dir(struct kobject *kobj)  
  1074. {  
  1075.     int error = 0;  
  1076.     error = sysfs_create_dir(kobj);  
  1077.     if (!error) {  
  1078.         error = populate_dir(kobj);  
  1079.         if (error)  
  1080.             sysfs_remove_dir(kobj);  
  1081.         }  
  1082.     return error;  
  1083. }  
  1084. /* 
  1085.  * 在v3.6.2/fs/sysfs/dir.c中: 
  1086.  * int sysfs_create_dir(struct kobject * kobj) 
  1087.  *  
  1088.  * sysfs_create_dir - create a directory for an object. 
  1089.  * @kobj:          object we're creating directory for.  
  1090.  * /sys/ 目录是根,对应的dirent是变量sysfs_root,定义在 
  1091.  *  /fs/sysfs/mount.c#L35 
  1092.  *  struct sysfs_dirent sysfs_root = { 
  1093.  *    .s_name         = "", 
  1094.  *    .s_count        = ATOMIC_INIT(1), 
  1095.  *    .s_flags        = SYSFS_DIR | (KOBJ_NS_TYPE_NONE << SYSFS_NS_TYPE_SHIFT), 
  1096.  *    .s_mode         = S_IFDIR | S_IRUGO | S_IXUGO, 
  1097.  *    .s_ino          = 1, 
  1098.  * }; 
  1099.  * sysfs的级联体系是基于dirent的,设备驱动模型的级联体系是基于kobjet和kset的。 
  1100.  * 在驱动那边kobject和kset的层级被组织好了。 
  1101.  * 当需要"显示"到sysfs时,就调用sysfs_create_dir类似的sysfs函数来创建目录(或文件) 
  1102.  * 如果一个kobject父级为空,说明它是最顶端的,即/sys/下的,把它的父级dirent设置 
  1103.  * 为sysfs_root 
  1104.  *   
  1105.  *  
  1106.  * 而dentry的root("/"目录)是VFS的d_make_root(inode)生成的(/fs/dcache.c),而这个 
  1107.  * inode也是根据sysfs_root生成的。 
  1108.  * 
  1109.  * 硬件<---设备驱动体系----sysfs体系----VFS体系--->用户: 
  1110.  *           kobject   --     dirent --     dentry(动态生成) 
  1111.  *  设备驱动层级: 以kobject为基础,最上层kobject是几个全局变量 
  1112.  *                  如devices_set,bus_set,system_set等  
  1113.  *  sysfs层级:以dirent为基础,最上层是sysfs_root,全局变量 
  1114.  *  VFS层级:以dentry为基础,最上层的是由sysfs_root和vfs函数d_make_root生成的,像 
  1115.  *          其它文件系统一样,存储在super_block里 
  1116.  * 
  1117.  *   
  1118.  *  
  1119.  */  
  1120.  int sysfs_create_dir(struct kobject * kobj)  
  1121.  {  
  1122.     enum kobj_ns_type type;  
  1123.     struct sysfs_dirent *parent_sd, *sd;  
  1124.     const void *ns = NULL;  
  1125.     int error = 0;  
  1126.     BUG_ON(!kobj);  
  1127.     //如果父kobj不存在就用根,直接挂到/sys/   
  1128.     if (kobj->parent)  
  1129.         parent_sd = kobj->parent->sd;  
  1130.     else  
  1131.         parent_sd = &sysfs_root;  
  1132.    
  1133.     if (!parent_sd)  
  1134.         return -ENOENT;  
  1135.    
  1136.     if (sysfs_ns_type(parent_sd))  
  1137.         ns = kobj->ktype->namespace(kobj);  
  1138.     type = sysfs_read_ns_type(kobj);  
  1139.    
  1140.     error = create_dir(kobj, parent_sd, type, ns, kobject_name(kobj), &sd);  
  1141.     if (!error)  
  1142.         kobj->sd = sd;  
  1143.     return error;  
  1144.  }  
  1145.    
  1146. static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,  
  1147.         enum kobj_ns_type type, const void *ns, const char *name,  
  1148.         struct sysfs_dirent **p_sd)  
  1149. {  
  1150.     //S_IFDIR表示目录?   
  1151.     umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;  
  1152.     struct sysfs_addrm_cxt acxt;  
  1153.     struct sysfs_dirent *sd;  
  1154.     int rc;   
  1155.     //申请一个dirent   
  1156.     sd = sysfs_new_dirent(name, mode, SYSFS_DIR);  
  1157.     if (!sd)  
  1158.         return -ENOMEM;  
  1159.       
  1160.     sd->s_flags |= (type << SYSFS_NS_TYPE_SHIFT);  
  1161.     sd->s_ns = ns;  
  1162.     //本节点是个目录,其kobj记录在s_dir成员中(联合体)   
  1163.     sd->s_dir.kobj = kobj;  
  1164.       
  1165.     /* link in */  
  1166.     sysfs_addrm_start(&acxt, parent_sd);  
  1167.     rc = sysfs_add_one(&acxt, sd);//添加   
  1168.     sysfs_addrm_finish(&acxt);  
  1169.       
  1170.     if (rc == 0)  
  1171.         *p_sd = sd;  
  1172.     else  
  1173.         sysfs_put(sd);  
  1174.       
  1175.     return rc;  
  1176. }  
  1177. //向父级dirent 添加一个dirent    
  1178. int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)  
  1179.  {  
  1180.     int ret;  
  1181.     //添加内部函数   
  1182.     ret = __sysfs_add_one(acxt, sd);  
  1183.     if (ret == -EEXIST) {  
  1184.         ......  
  1185.     }   
  1186.     return ret;  
  1187.  }  
  1188.    
  1189.    
  1190. int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)  
  1191. {  
  1192.     struct sysfs_inode_attrs *ps_iattr;  
  1193.     int ret;  
  1194.    
  1195.     if (!!sysfs_ns_type(acxt->parent_sd) != !!sd->s_ns) {  
  1196.          WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",  
  1197.              sysfs_ns_type(acxt->parent_sd)? "required""invalid",  
  1198.              acxt->parent_sd->s_name, sd->s_name);  
  1199.          return -EINVAL;  
  1200.     }  
  1201.     //21位的二元组[ns,name]的hash值(是个UINT)   
  1202.     sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name);  
  1203.     //设置父级dirent   
  1204.     sd->s_parent = sysfs_get(acxt->parent_sd);  
  1205.     //本dirent的兄弟链接   
  1206.     ret = sysfs_link_sibling(sd);  
  1207.     if (ret)  
  1208.         return ret;  
  1209.    
  1210.      /* Update timestamps on the parent */  
  1211.     ps_iattr = acxt->parent_sd->s_iattr;  
  1212.     if (ps_iattr) {  
  1213.         struct iattr *ps_iattrs = &ps_iattr->ia_iattr;  
  1214.         ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME;  
  1215.     }  
  1216.    
  1217.     return 0;  
  1218.  }  
  1219.   
  1220. struct sysfs_elem_dir {  
  1221.     struct kobject *kobj;  
  1222.     unsigned long   subdirs;//本目录子目录数   
  1223.     struct rb_root  children;//子目录的红黑树   
  1224. };  
  1225. //兄弟节点是一个红黑树链接的(rbtree)    
  1226. static int sysfs_link_sibling(struct sysfs_dirent *sd)  
  1227. {  
  1228.     //s_dir 是 sysfs_elem_dir 结构   
  1229.     struct rb_node **node = &sd->s_parent->s_dir.children.rb_node;  
  1230.     struct rb_node *parent = NULL;  
  1231.     //如果将被添加的是一个目录,则父目录的子目录数+=1   
  1232.     if (sysfs_type(sd) == SYSFS_DIR)  
  1233.         sd->s_parent->s_dir.subdirs++;  
  1234.     //红黑树遍历,找到合适位置   
  1235.     while (*node) {  
  1236.         struct sysfs_dirent *pos;  
  1237.         int result;  
  1238.    
  1239.         pos = to_sysfs_dirent(*node);  
  1240.         parent = *node;  
  1241.         result = sysfs_sd_compare(sd, pos);  
  1242.         if (result < 0)  
  1243.             node = &pos->s_rb.rb_left;  
  1244.         else if (result > 0)  
  1245.             node = &pos->s_rb.rb_right;  
  1246.         else  
  1247.             return -EEXIST;  
  1248.     }  
  1249.     /* add new node and rebalance the tree */  
  1250.     rb_link_node(&sd->s_rb, parent, node);  
  1251.     rb_insert_color(&sd->s_rb, &sd->s_parent->s_dir.children);      
  1252.     return 0;  
  1253.  }  
  1254.  添加file   
  1255.    
  1256.  /* 
  1257.   * 添加kobject就是往某个"目录"下添加一个"文件" 
  1258.   * v3.6.2/include/linux/device.h#L117 
  1259.   */  
  1260.  #define bus_register(subsys)                    \   
  1261.  ({                                              \  
  1262.           static struct lock_class_key __key;     \  
  1263.           __bus_register(subsys, &__key); \  
  1264.  })  
  1265.  /* 
  1266.   * 内部函数定义在: 
  1267.   * v3.6.2/drivers/base/bus.c#L923 
  1268.   */  
  1269.     
  1270.  int __bus_register(struct bus_type *bus, struct lock_class_key *key)  
  1271.  {  
  1272.         int retval;  
  1273.         struct subsys_private *priv;  
  1274.         //申请一个结构   
  1275.         priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL);  
  1276.         if (!priv)  
  1277.                  return -ENOMEM;  
  1278.         //与bus联系起来   
  1279.          priv->bus = bus;  
  1280.          bus->p = priv;  
  1281.    
  1282.          BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);  
  1283.         //设置bus的名字,如"USB"   
  1284.         retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);  
  1285.         if (retval)  
  1286.             goto out;  
  1287.         /* 
  1288.          * 前面说过,bus_kset指的是/sys/bus/目录; 一个kobj.kset指的是本 
  1289.          * kobj的父级目录,所以下面这句就是本bus的父目录是/sys/bus/,若为 
  1290.          * USB,则最终形成/sys/bus/usb/ 
  1291.          * / 
  1292.         priv->subsys.kobj.kset = bus_kset; 
  1293.         priv->subsys.kobj.ktype = &bus_ktype; 
  1294.         priv->drivers_autoprobe = 1; 
  1295.         //此函数上面说过,添加一个kset目录,即添加/sys/bus/usb/ 
  1296.         retval = kset_register(&priv->subsys); 
  1297.         if (retval) 
  1298.             goto out; 
  1299.         //为本目录(/sys/bus/usb/)添加一个属性文件 
  1300.         retval = bus_create_file(bus, &bus_attr_uevent); 
  1301.         if (retval) 
  1302.             goto bus_uevent_fail; 
  1303.         //每个总线目录下有个 /devices和/drivers目录 
  1304.          priv->devices_kset = kset_create_and_add("devices", NULL, 
  1305.                                                   &priv->subsys.kobj); 
  1306.          if (!priv->devices_kset) { 
  1307.                  retval = -ENOMEM; 
  1308.                  goto bus_devices_fail; 
  1309.          } 
  1310.   
  1311.          priv->drivers_kset = kset_create_and_add("drivers", NULL, 
  1312.                                                   &priv->subsys.kobj); 
  1313.          if (!priv->drivers_kset) { 
  1314.                  retval = -ENOMEM; 
  1315.                  goto bus_drivers_fail; 
  1316.          } 
  1317.          
  1318.         INIT_LIST_HEAD(&priv->interfaces); 
  1319.         __mutex_init(&priv->mutex, "subsys mutex", key); 
  1320.         klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put); 
  1321.         klist_init(&priv->klist_drivers, NULL, NULL); 
  1322.   
  1323.         retval = add_probe_files(bus); 
  1324.         if (retval) 
  1325.             goto bus_probe_files_fail; 
  1326.   
  1327.         retval = bus_add_attrs(bus); 
  1328.         if (retval) 
  1329.             goto bus_attrs_fail; 
  1330.   
  1331.         pr_debug("bus: '%s': registered\n", bus->name); 
  1332.         return 0; 
  1333.   
  1334.  bus_attrs_fail: 
  1335.          remove_probe_files(bus); 
  1336.  bus_probe_files_fail: 
  1337.          kset_unregister(bus->p->drivers_kset); 
  1338.  bus_drivers_fail: 
  1339.          kset_unregister(bus->p->devices_kset); 
  1340.  bus_devices_fail: 
  1341.          bus_remove_file(bus, &bus_attr_uevent); 
  1342.  bus_uevent_fail: 
  1343.          kset_unregister(&bus->p->subsys); 
  1344.  out: 
  1345.          kfree(bus->p); 
  1346.          bus->p = NULL; 
  1347.          return retval; 
  1348.  } 
  1349.  /* 
  1350.   * v3.6.2/drivers/base/bus.c#L127 
  1351.   */  
  1352. int bus_create_file(struct bus_type *bus, struct bus_attribute *attr)  
  1353. {  
  1354.     int error;  
  1355.     if (bus_get(bus)) {  
  1356.         error = sysfs_create_file(&bus->p->subsys.kobj, &attr->attr);  
  1357.         bus_put(bus);  
  1358.     } else  
  1359.     error = -EINVAL;  
  1360.     return error;  
  1361.  }  
  1362.  //v3.6.2/fs/sysfs/file.c#L571   
  1363.  int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)  
  1364.  {  
  1365.     BUG_ON(!kobj || !kobj->sd || !attr);  
  1366.     //kobj是usb目录的那个kobj   
  1367.     return sysfs_add_file(kobj->sd, attr, SYSFS_KOBJ_ATTR);   
  1368.  }  
  1369.  //v3.6.2/fs/sysfs/file.c#L558   
  1370. int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,  
  1371.                     int type)  
  1372.  {  
  1373.     //dir_sd指的是usb目录   
  1374.     return sysfs_add_file_mode(dir_sd, attr, type, attr->mode);  
  1375.  }  
  1376.    
  1377.    
  1378.  int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,  
  1379.                          const struct attribute *attr, int type, umode_t amode)  
  1380.  {  
  1381.      umode_t mode = (amode & S_IALLUGO) | S_IFREG;  
  1382.      struct sysfs_addrm_cxt acxt;  
  1383.      struct sysfs_dirent *sd;  
  1384.      const void *ns;  
  1385.      int rc;  
  1386.       
  1387.      rc = sysfs_attr_ns(dir_sd->s_dir.kobj, attr, &ns);  
  1388.      if (rc)  
  1389.          return rc;  
  1390.     //目录下文件所用的那个dirent   
  1391.     sd = sysfs_new_dirent(attr->name, mode, type);  
  1392.     if (!sd)  
  1393.         return -ENOMEM;  
  1394.    
  1395.     sd->s_ns = ns;  
  1396.     sd->s_attr.attr = (void *)attr;  
  1397.     sysfs_dirent_init_lockdep(sd);  
  1398.    
  1399.     sysfs_addrm_start(&acxt, dir_sd);  
  1400.     //这里与前面相同了,就是在dirent结构体系中加入一个元素   
  1401.     rc = sysfs_add_one(&acxt, sd);  
  1402.     sysfs_addrm_finish(&acxt);  
  1403.    
  1404.      if (rc)  
  1405.          sysfs_put(sd);  
  1406.    
  1407.      return rc;  
  1408.  }  
  1409.    
  1410.  //文件系统mount过程   
  1411.  /* 
  1412.   * struct path 
  1413.   * /include/linux/path.h 
  1414.   */  
  1415.   struct path {  
  1416.          struct vfsmount *mnt;  
  1417.            struct dentry *dentry;  
  1418.   };  
  1419.   /* 
  1420.    * /fs/namespace.c中的系统调用定义 
  1421.    * SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, 
  1422.    *              char __user *, type, unsigned long, flags, void __user *, data) 
  1423.    * 系统调用mount有5个参数,此函数最后是调用do_mount完成mount任务 
  1424.    */  
  1425. long do_mount(char *dev_name, char *dir_name, char *type_page,  
  1426.                   unsigned long flags, void *data_page)  
  1427. {  
  1428.     ......  
  1429.     //取得挂载点的path结构信息,应该是根文件系统目录   
  1430.     retval = kern_path(dir_name, LOOKUP_FOLLOW, &path);  
  1431.     ......  
  1432.     //如果是新加载的文件系统,执行这里   
  1433.     retval = do_new_mount(&path, type_page, flags, mnt_flags,  
  1434.                     dev_name, data_page)  
  1435. }   
  1436.    
  1437.    
  1438.  1916/* 
  1439. 1917 * create a new mount for userspace and request it to be added into the 
  1440. 1918 * namespace's tree 
  1441. 1919 */  
  1442. 1920static int do_new_mount(struct path *path, char *type, int flags,  
  1443. 1921                        int mnt_flags, char *name, void *data)  
  1444. 1922{  
  1445. 1923        struct vfsmount *mnt;  
  1446. 1924        int err;  
  1447. 1925  
  1448. 1926        if (!type)  
  1449. 1927                return -EINVAL;  
  1450. 1928  
  1451. 1929        /* we need capabilities... */  
  1452. 1930        if (!capable(CAP_SYS_ADMIN))  
  1453. 1931                return -EPERM;  
  1454. 1932        //加载type字串指定的文件系统,过程与rootfs类似   
  1455. 1933        mnt = do_kern_mount(type, flags, name, data);  
  1456. 1934        if (IS_ERR(mnt))  
  1457. 1935                return PTR_ERR(mnt);  
  1458. 1936        //将mnt挂载到path指定的路径上   
  1459. 1937        err = do_add_mount(real_mount(mnt), path, mnt_flags);  
  1460. 1938        if (err)  
  1461. 1939                mntput(mnt);  
  1462. 1940        return err;  
  1463. 1941}  
  1464.    
  1465.    
  1466. /* 
  1467.  * 功能: 
  1468.  *  将newmnt文件系统加载到path指定的vfs路径上 
  1469.  * 参数: 
  1470.  *  newmnt:刚才加载的文件系统 
  1471.  *  path:newmnt需要加载到的vfs路径 
  1472.  * 说明: 
  1473.  *  因为path可能加载了别的文件系统(顶层是rootfs,子层是别的),所以要进入到最 
  1474.  *  内层(最后加载的文件系统)锁住上层mnt 
  1475.  * add a mount into a namespace's mount tree 
  1476.  */  
  1477. 1878static int do_add_mount(struct mount *newmnt, struct path *path, int mnt_flags)  
  1478. 1879{  
  1479. 1880        int err;  
  1480. 1881  
  1481. 1882        mnt_flags &= ~(MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL);  
  1482. 1883  
  1483. 1884        err = lock_mount(path);  
  1484. 1885        if (err)  
  1485. 1886                return err;  
  1486. 1887  
  1487. 1888        err = -EINVAL;  
  1488. 1889        if (unlikely(!check_mnt(real_mount(path->mnt)))) {  
  1489. 1890                /* that's acceptable only for automounts done in private ns */  
  1490. 1891                if (!(mnt_flags & MNT_SHRINKABLE))  
  1491. 1892                        goto unlock;  
  1492. 1893                /* ... and for those we'd better have mountpoint still alive */  
  1493. 1894                if (!real_mount(path->mnt)->mnt_ns)  
  1494. 1895                        goto unlock;  
  1495. 1896        }  
  1496. 1897  
  1497. 1898        /* Refuse the same filesystem on the same mount point */  
  1498. 1899        err = -EBUSY;  
  1499. 1900        if (path->mnt->mnt_sb == newmnt->mnt.mnt_sb &&  
  1500. 1901            path->mnt->mnt_root == path->dentry)  
  1501. 1902                goto unlock;  
  1502. 1903  
  1503. 1904        err = -EINVAL;  
  1504. 1905        if (S_ISLNK(newmnt->mnt.mnt_root->d_inode->i_mode))  
  1505. 1906                goto unlock;  
  1506. 1907  
  1507. 1908        newmnt->mnt.mnt_flags = mnt_flags;  
  1508. 1909        err = graft_tree(newmnt, path);  
  1509. 1910  
  1510. 1911unlock:  
  1511. 1912        unlock_mount(path);  
  1512. 1913        return err;  
  1513. 1914}  
  1514. //锁住父mount/    
  1515.  /* 
  1516.   * 将path指定的最内层mnt锁住,path可能加载了多个文件系统,所以要进入 
  1517.   * 到最内层的 
  1518.   */  
  1519.    
  1520. 1543static int lock_mount(struct path *path)  
  1521. 1544{  
  1522. 1545        struct vfsmount *mnt;  
  1523. 1546retry:  
  1524. 1547        mutex_lock(&path->dentry->d_inode->i_mutex);  
  1525. 1548        if (unlikely(cant_mount(path->dentry))) {  
  1526. 1549                mutex_unlock(&path->dentry->d_inode->i_mutex);  
  1527. 1550                return -ENOENT;  
  1528. 1551        }  
  1529. 1552        down_write(&namespace_sem);  
  1530.             //查找path对应的第一个子mnt   
  1531. 1553        mnt = lookup_mnt(path);  
  1532.             //一直向下一层找,直到下层没有了(llokup_mnt返回0   
  1533. 1554        if (likely(!mnt))  
  1534. 1555                return 0;  
  1535.             /* 
  1536.              * 找到了本层的子层mnt,释放命名空间锁本层inode锁 
  1537.              * 释放路径锁。然后迭代:让path指向子层mnt,和dentry 
  1538.              * 再retry 
  1539.              */  
  1540. 1556        up_write(&namespace_sem);  
  1541. 1557        mutex_unlock(&path->dentry->d_inode->i_mutex);  
  1542. 1558        path_put(path);  
  1543. 1559        path->mnt = mnt;  
  1544. 1560        path->dentry = dget(mnt->mnt_root);  
  1545. 1561        goto retry;  
  1546. 1562}  
  1547.    
  1548.    
  1549. /* 
  1550.  575 * lookup_mnt - Return the first child mount mounted at path 
  1551.  576 */  
  1552.   590struct vfsmount *lookup_mnt(struct path *path)  
  1553.  591{  
  1554.  592        struct mount *child_mnt;  
  1555.  593  
  1556.  594        br_read_lock(&vfsmount_lock);  
  1557.  595        child_mnt = __lookup_mnt(path->mnt, path->dentry, 1);  
  1558.  596        if (child_mnt) {  
  1559.  597                mnt_add_count(child_mnt, 1);  
  1560.  598                br_read_unlock(&vfsmount_lock);  
  1561.  599                return &child_mnt->mnt;  
  1562.  600        } else {  
  1563.  601                br_read_unlock(&vfsmount_lock);  
  1564.  602                return NULL;  
  1565.  603        }  
  1566.  604}  
  1567.    
  1568.    
  1569.    
  1570. /* 
  1571.  * 根据dir指示返回mnt的第一个或最后一个子mnt   
  1572.  * mount_hashtable[hash(mnt, dentry)]的值是一个链表,存储着相同hash值的mnt 
  1573.  * 根据代码大概是,某一个path对应一对mnt dentry,在此path挂载的话,会有mnt1, 
  1574.  * dentry1,再在此path挂载的话,会有mnt2,dentry2并且其父是mnt1,dentry1而并不 
  1575.  * 是mnt和dentry。那意味着hash表项中(&p->mnt_parent->mnt == mnt &&  
  1576.  * p->mnt_mountpoint == dentry)只能成立一次。也就是说同一挂载点的mnt,dentry 
  1577.  * 只可能有一个儿子。(这块不明白) 
  1578.  */  
  1579.  553struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry,  
  1580.  554                              int dir)  
  1581.  555{  
  1582.  556        struct list_head *head = mount_hashtable + hash(mnt, dentry);  
  1583.  557        struct list_head *tmp = head;  
  1584.  558        struct mount *p, *found = NULL;  
  1585.  559  
  1586.  560        for (;;) {  
  1587.                     //顺着来还是倒着来   
  1588.  561                tmp = dir ? tmp->next : tmp->prev;  
  1589.  562                p = NULL;  
  1590.  563                if (tmp == head)  
  1591.  564                        break;  
  1592.  565                p = list_entry(tmp, struct mount, mnt_hash);  
  1593.                     //确定一下关系,因为hash有可能冲突   
  1594.  566                if (&p->mnt_parent->mnt == mnt && p->mnt_mountpoint == dentry) {  
  1595.  567                        found = p;  
  1596.  568                        break;  
  1597.  569                }  
  1598.  570        }  
  1599.  571        return found;  
  1600.  572}  
  1601.  //嫁接子mount到父mount上//   
  1602.    
  1603.    
  1604. 1570static int graft_tree(struct mount *mnt, struct path *path)  
  1605. 1571{  
  1606. 1572        if (mnt->mnt.mnt_sb->s_flags & MS_NOUSER)  
  1607. 1573                return -EINVAL;  
  1608. 1574  
  1609. 1575        if (S_ISDIR(path->dentry->d_inode->i_mode) !=  
  1610. 1576              S_ISDIR(mnt->mnt.mnt_root->d_inode->i_mode))  
  1611. 1577                return -ENOTDIR;  
  1612. 1578  
  1613. 1579        if (d_unlinked(path->dentry))  
  1614. 1580                return -ENOENT;  
  1615. 1581  
  1616. 1582        return attach_recursive_mnt(mnt, path, NULL);  
  1617. 1583}  
  1618.    
  1619.    
  1620.    
  1621.    
  1622. path walk//   
  1623.   
  1624.    
  1625.    
  1626.    
  1627.    
  1628.    
  1629.    
  1630.    
  1631.    
  1632.    
  1633.    
  1634. static int link_path_walk(const char *name, struct nameidata *nd)  
  1635. 1714{  
  1636. 1715        struct path next;  
  1637. 1716        int err;  
  1638. 1717          
  1639. 1718        while (*name=='/')  
  1640. 1719                name++;  
  1641. 1720        if (!*name)  
  1642. 1721                return 0;  
  1643. 1722  
  1644. 1723        /* At this point we know we have a real path component. */  
  1645. 1724        for(;;) {  
  1646. 1725                struct qstr this;  
  1647. 1726                long len;  
  1648. 1727                int type;  
  1649. 1728  
  1650. 1729                err = may_lookup(nd);  
  1651. 1730                if (err)  
  1652. 1731                        break;  
  1653. 1732  
  1654. 1733                len = hash_name(name, &this.hash);  
  1655. 1734                this.name = name;  
  1656. 1735                this.len = len;  
  1657. 1736  
  1658. 1737                type = LAST_NORM;  
  1659. 1738                if (name[0] == '.'switch (len) {  
  1660. 1739                        case 2:  
  1661. 1740                                if (name[1] == '.') {  
  1662. 1741                                        type = LAST_DOTDOT;  
  1663. 1742                                        nd->flags |= LOOKUP_JUMPED;  
  1664. 1743                                }  
  1665. 1744                                break;  
  1666. 1745                        case 1:  
  1667. 1746                                type = LAST_DOT;  
  1668. 1747                }  
  1669. 1748                if (likely(type == LAST_NORM)) {  
  1670. 1749                        struct dentry *parent = nd->path.dentry;  
  1671. 1750                        nd->flags &= ~LOOKUP_JUMPED;  
  1672. 1751                        if (unlikely(parent->d_flags & DCACHE_OP_HASH)) {  
  1673. 1752                                err = parent->d_op->d_hash(parent, nd->inode,  
  1674. 1753                                                           &this);  
  1675. 1754                                if (err < 0)  
  1676. 1755                                        break;  
  1677. 1756                        }  
  1678. 1757                }  
  1679. 1758  
  1680. 1759                if (!name[len])  
  1681. 1760                        goto last_component;  
  1682. 1761                /* 
  1683. 1762                 * If it wasn't NUL, we know it was '/'. Skip that 
  1684. 1763                 * slash, and continue until no more slashes. 
  1685. 1764                 */  
  1686. 1765                do {  
  1687. 1766                        len++;  
  1688. 1767                } while (unlikely(name[len] == '/'));  
  1689. 1768                if (!name[len])  
  1690. 1769                        goto last_component;  
  1691. 1770                name += len;  
  1692. 1771  
  1693. 1772                err = walk_component(nd, &next, &this, type, LOOKUP_FOLLOW);  
  1694. 1773                if (err < 0)  
  1695. 1774                        return err;  
  1696. 1775  
  1697. 1776                if (err) {  
  1698. 1777                        err = nested_symlink(&next, nd);  
  1699. 1778                        if (err)  
  1700. 1779                                return err;  
  1701. 1780                }  
  1702. 1781                if (can_lookup(nd->inode))  
  1703. 1782                        continue;  
  1704. 1783                err = -ENOTDIR;   
  1705. 1784                break;  
  1706. 1785                /* here ends the main loop */  
  1707. 1786  
  1708. 1787last_component:  
  1709. 1788                nd->last = this;  
  1710. 1789                nd->last_type = type;  
  1711. 1790                return 0;  
  1712. 1791        }//for(;;)循环   
  1713. 1792        terminate_walk(nd);  
  1714. 1793        return err;  
  1715. 1794}  
  1716. 1795   
  1717.    
  1718.    
  1719. /* 
  1720.  *  ///opt/soft/abc.txt 
  1721.  */  
  1722.   
  1723. 1713static int link_path_walk(const char *name, struct nameidata *nd)  
  1724. 1714{  
  1725. 1715        struct path next;  
  1726. 1716        int err;  
  1727. 1717        //去前导'/'=opt/soft/abc.txt,让name指向第一个分量开始处   
  1728. 1718        while (*name=='/')  
  1729. 1719                name++;  
  1730. 1720        if (!*name)  
  1731. 1721                return 0;  
  1732. 1722  
  1733. 1723        /* At this point we know we have a real path component. */  
  1734. 1724        for(;;) {//按name分量处理   
  1735. 1725                struct qstr this;//当前分量名,长度   
  1736. 1726                long len;  
  1737. 1727                int type;  
  1738. 1728                //inode 访问检查   
  1739. 1729                err = may_lookup(nd);  
  1740. 1730                if (err)  
  1741. 1731                        break;  
  1742. 1732                  
  1743. 1733                len = hash_name(name, &this.hash);//当前分量hash   
  1744. 1734                this.name = name;//当前分量开始处   
  1745. 1735                this.len = len;//当前分量长度   
  1746. 1736  
  1747. 1737                type = LAST_NORM;//上一个分量正常   
  1748. 1738                if (name[0] == '.'switch (len) {  
  1749. 1739                        case 2:  
  1750. 1740                                if (name[1] == '.') {  
  1751. 1741                                        type = LAST_DOTDOT;//上一分量是"点点"   
  1752. 1742                                        nd->flags |= LOOKUP_JUMPED;  
  1753. 1743                                }  
  1754. 1744                                break;  
  1755. 1745                        case 1:  
  1756. 1746                                type = LAST_DOT;//上一分量是"点"   
  1757. 1747                }  
  1758. 1748                if (likely(type == LAST_NORM)) {  
  1759. 1749                        struct dentry *parent = nd->path.dentry;  
  1760. 1750                        nd->flags &= ~LOOKUP_JUMPED;  
  1761. 1751                        if (unlikely(parent->d_flags & DCACHE_OP_HASH)) {  
  1762. 1752                                err = parent->d_op->d_hash(parent, nd->inode,  
  1763. 1753                                                           &this);  
  1764. 1754                                if (err < 0)  
  1765. 1755                                        break;  
  1766. 1756                        }  
  1767. 1757                }  
  1768. 1758                //*(name+len)==null表示 name即name分量是最后一个:xxx/name'\0'   
  1769. 1759                if (!name[len])  
  1770. 1760                        goto last_component;  
  1771. 1761                /*  
  1772. 1762                 * If it wasn't NUL, we know it was '/'. Skip that  
  1773. 1763                 * slash, and continue until no more slashes.  
  1774.                      * 非null表示name后还有分量,那么过滤掉相应的'/'  
  1775. 1764                 */  
  1776. 1765                do {  
  1777. 1766                        len++;  
  1778. 1767                } while (unlikely(name[len] == '/'));  
  1779. 1768                if (!name[len])  
  1780. 1769                        goto last_component;  
  1781.                     //name指向下一个分量,说不定有下一次for循环   
  1782. 1770                name += len;  
  1783. 1771        //得到当前分量相关的dentry等数据结构存入nd,再循环处理下一分量   
  1784. 1772                err = walk_component(nd, &next, &this, type, LOOKUP_FOLLOW);  
  1785. 1773                if (err < 0)  
  1786. 1774                        return err;  
  1787. 1775  
  1788. 1776                if (err) {//err>0时,处理符号链接   
  1789. 1777                        err = nested_symlink(&next, nd);  
  1790. 1778                        if (err)  
  1791. 1779                                return err;  
  1792. 1780                }  
  1793.                     //err==0时,继续for循环,处理下一分量节点   
  1794. 1781                if (can_lookup(nd->inode))  
  1795. 1782                        continue;  
  1796. 1783                err = -ENOTDIR;   
  1797. 1784                break;  
  1798. 1785                /* here ends the main loop */  
  1799. 1786  
  1800. 1787last_component:  
  1801.                     /* 
  1802.                      * 到这里,this指向的是最后一个分量 
  1803.                      * 到这里函数才能正确地退出,如果是 
  1804.                      * break出去的则表示出错 
  1805.                      */  
  1806. 1788                nd->last = this;  
  1807. 1789                nd->last_type = type;  
  1808. 1790                return 0;  
  1809. 1791        }  
  1810. 1792        terminate_walk(nd);  
  1811. 1793        return err;  
  1812. 1794}  
  1813.   
  1814.   
  1815.   
  1816.   
  1817. /* 
  1818.  *  主要是两种处理方法,一种是查cache,一种是慢速找,最终用到路径上倒数第 
  1819.  *  二个节点的dentry(最后一个的父)相关的inode,然后调用inode->lookup根据 
  1820.  *  设置的name找到相关的dentry 
  1821.  * 
  1822.  *  lookup_fast//rcu列表中查找 
  1823.  *      __d_lookup_rcu 
  1824.  *      __d_lookup 
  1825.  *  lookup_slow 
  1826.  *      __lookup_hash 
  1827.  *          lookup_dcache 
  1828.  *              d_lookup 
  1829.  *                  __d_lookup 
  1830.  *          lookup_real 
  1831.  *              dir->i_op->lookup//调用inode的lookup 
  1832.  */  
  1833. 1475static inline int walk_component(struct nameidata *nd, struct path *path,  
  1834. 1476                struct qstr *name, int type, int follow)  
  1835. 1477{  
  1836. 1478        struct inode *inode;  
  1837. 1479        int err;  
  1838. 1480        /* 
  1839. 1481         * "." and ".." are special - ".." especially so because it has 
  1840. 1482         * to be able to know about the current root directory and 
  1841. 1483         * parent relationships. 
  1842. 1484         */  
  1843. 1485        if (unlikely(type != LAST_NORM))  
  1844. 1486                return handle_dots(nd, type);//点/点点的处理   
  1845. 1487        err = lookup_fast(nd, name, path, &inode);  
  1846. 1488        if (unlikely(err)) {  
  1847. 1489                if (err < 0)  
  1848. 1490                        goto out_err;  
  1849. 1491  
  1850. 1492                err = lookup_slow(nd, name, path);  
  1851. 1493                if (err < 0)  
  1852. 1494                        goto out_err;  
  1853. 1495  
  1854. 1496                inode = path->dentry->d_inode;  
  1855. 1497        }  
  1856. 1498        err = -ENOENT;  
  1857. 1499        if (!inode)  
  1858. 1500                goto out_path_put;  
  1859. 1501  
  1860. 1502        if (should_follow_link(inode, follow)) {  
  1861. 1503                if (nd->flags & LOOKUP_RCU) {  
  1862. 1504                        if (unlikely(unlazy_walk(nd, path->dentry))) {  
  1863. 1505                                err = -ECHILD;  
  1864. 1506                                goto out_err;  
  1865. 1507                        }  
  1866. 1508                }  
  1867. 1509                BUG_ON(inode != path->dentry->d_inode);  
  1868. 1510                return 1;  
  1869. 1511        }  
  1870.             //path内容存入nd   
  1871. 1512        path_to_nameidata(path, nd);  
  1872. 1513        nd->inode = inode;  
  1873. 1514        return 0;  
  1874. 1515  
  1875. 1516out_path_put:  
  1876. 1517        path_to_nameidata(path, nd);  
  1877. 1518out_err:  
  1878. 1519        terminate_walk(nd);  
  1879. 1520        return err;  
  1880. 1521}  
  1881. 1522  
  1882.   
  1883. /* 
  1884.  * 总结: 
  1885.  *  粗略地看了下vfs。具体的fs只需提供相关结构的方法即可,vfs只是一个框架。 
  1886.  *  具体fs满足vfs所需要的接口。比如,vfs查找路径,最终要生成一个dentry, 
  1887.  *  而sysfs以硬件和dirent来级联,但用户调用sysfs的lookup时,sysfs需要根据 
  1888.  *  当前的参数生成一个dentry。vfs不管sysfs内部如何实现。 
  1889.  *  遗留问题: 
  1890.  *  往同一个目录mount多次,其树状结构是什么样的 
  1891.  *  路径查找中所使用的cache系统原理 
  1892.  */  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值