Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9727
  • 博文数量: 4
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 40
  • 用 户 组: 普通用户
  • 注册时间: 2014-09-03 21:26
文章分类
文章存档

2015年(4)

我的朋友

分类: LINUX

2015-07-02 23:03:47

如下只是自己分析sysfs_init源码的注释,如有不对处,请帮忙指出,谢谢。

1. sysfs_init

点击(此处)折叠或打开

  1. int __init sysfs_init(void)
  2. {
  3.     int err = -ENOMEM;

  4.     sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache",
  5.                      sizeof(struct sysfs_dirent),
  6.                      0, 0, NULL);
  7.     if (!sysfs_dir_cachep)
  8.         goto out;

  9.     err = sysfs_inode_init();
  10.     if (err)
  11.         goto out_err;

  12.     err = register_filesystem(&sysfs_fs_type);/* 将sysfs文件系统注册到vfs中 */
  13.     if (!err) {
  14.         sysfs_mnt = kern_mount(&sysfs_fs_type);/* 加载sysfs文件系统 */
  15.         if (IS_ERR(sysfs_mnt)) {
  16.             printk(KERN_ERR "sysfs: could not mount!\n");
  17.             err = PTR_ERR(sysfs_mnt);
  18.             sysfs_mnt = NULL;
  19.             unregister_filesystem(&sysfs_fs_type);
  20.             goto out_err;
  21.         }
  22.     } else
  23.         goto out_err;
  24. out:
  25.     return err;
  26. out_err:
  27.     kmem_cache_destroy(sysfs_dir_cachep);
  28.     sysfs_dir_cachep = NULL;
  29.     goto out;
  30. }
第17的kern_mount函数的解析可以看:blog.chinaunix.net/uid-29325905-id-5105756.html
总结:sysfs_init,主要将sysfs文件系统注册到系统中,并加载了一个sysfs的文件系统。

2. sysfs_mount

点击(此处)折叠或打开

  1. static struct dentry *sysfs_mount(struct file_system_type *fs_type,
  2.     int flags, const char *dev_name, void *data)/* 获取sysfs文件系统的super_block实例,并获取该实例中的root inode与dentry实例 */
  3. {
  4.     struct sysfs_super_info *info;
  5.     enum kobj_ns_type type;
  6.     struct super_block *sb;
  7.     int error;

  8.     if (!(flags & MS_KERNMOUNT) && !current_user_ns()->may_mount_sysfs)
  9.         return ERR_PTR(-EPERM);

  10.     info = kzalloc(sizeof(*info), GFP_KERNEL);/* 从12到17行,获取sysfs文件系统的一个类似索引结构 */
  11.     if (!info)
  12.         return ERR_PTR(-ENOMEM);

  13.     for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++)
  14.         info->ns[type] = kobj_ns_grab_current(type);

  15.     sb = sget(fs_type, sysfs_test_super, sysfs_set_super, flags, info); /* 按照@info的索引,从@fs_type文件系统中按照@sysfs_test_super方法查找对应super_block,如果没有则申请一个super_block并按照@sysfs_set_super方法设置 */
  16.     if (IS_ERR(sb) || sb->s_fs_info != info)
  17.         free_sysfs_super_info(info);
  18.     if (IS_ERR(sb))
  19.         return ERR_CAST(sb);
  20.     if (!sb->s_root) {
  21.         error = sysfs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0);/* 给@sb实例获取对应的的root inode和dentry */
  22.         if (error) {
  23.             deactivate_locked_super(sb);
  24.             return ERR_PTR(error);
  25.         }
  26.         sb->s_flags |= MS_ACTIVE;
  27.     }

  28.     return dget(sb->s_root);
  29. }
总结:每次加载一个sysfs文件系统时,都会调用到该方法。该方法实现了获取super_block和root inode,root dentry.

3.sysfs_fill_super

点击(此处)折叠或打开

  1. static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
  2. {
  3.     struct inode *inode;
  4.     struct dentry *root;

  5.     sb->s_blocksize = PAGE_CACHE_SIZE;/* 初始化super_block. */
  6.     sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
  7.     sb->s_magic = SYSFS_MAGIC;
  8.     sb->s_op = &sysfs_ops;
  9.     sb->s_time_gran = 1;

  10.     /* get root inode, initialize and unlock it */
  11.     mutex_lock(&sysfs_mutex);
  12.     inode = sysfs_get_inode(sb, &sysfs_root);/* 获取super_block的root inode实例 */
  13.     mutex_unlock(&sysfs_mutex);
  14.     if (!inode) {
  15.         pr_debug("sysfs: could not get root inode\n");
  16.         return -ENOMEM;
  17.     }

  18.     /* instantiate and link root dentry */
  19.     root = d_make_root(inode);/* 由root inode获取root dentry实例 */
  20.     if (!root) {
  21.         pr_debug("%s: could not get root dentry!\n",__func__);
  22.         return -ENOMEM;
  23.     }
  24.     root->d_fsdata = &sysfs_root;
  25.     sb->s_root = root;
  26.     sb->s_d_op = &sysfs_dentry_ops;
  27.     return 0;
  28. }
总结:该方法是由super_block实例来获取root inode,root dentry.

4.sysfs_get_inode

点击(此处)折叠或打开

  1. struct inode * sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd)
  2. {
  3.     struct inode *inode;

  4.     inode = iget_locked(sb, sd->s_ino);/* 通过super_block实例获取 sd->s_ino相关的inode, 该情况下是获取super_block的root node*/
  5.     if (inode && (inode->i_state & I_NEW))
  6.         sysfs_init_inode(sd, inode);

  7.     return inode;
  8. }
5.iget_locked (fs/inode.c)

点击(此处)折叠或打开

  1. struct inode *iget_locked(struct super_block *sb, unsigned long ino)
  2. {
  3.     struct hlist_head *head = inode_hashtable + hash(sb, ino);
  4.     struct inode *inode;

  5.     spin_lock(&inode_hash_lock);
  6.     inode = find_inode_fast(sb, head, ino); /* 从inode hash链表@head查找出于@ino相关的inode实例,如果有找到就直接返回该实例 */
  7.     spin_unlock(&inode_hash_lock);
  8.     if (inode) {
  9.         wait_on_inode(inode);
  10.         return inode;
  11.     }

  12.     inode = alloc_inode(sb); /* 申请一个inode实例 */
  13.     if (inode) {
  14.         struct inode *old;

  15.         spin_lock(&inode_hash_lock);
  16.         /* We released the lock, so.. */
  17.         old = find_inode_fast(sb, head, ino);/* 与7行重复动作,再次确定 */
  18.         if (!old) {
  19.             inode->i_ino = ino;/* 给new inode赋予一个唯一的编号标示 */
  20.             spin_lock(&inode->i_lock);
  21.             inode->i_state = I_NEW;
  22.             hlist_add_head(&inode->i_hash, head);/* 将inode加入hash链表中 */
  23.             spin_unlock(&inode->i_lock);
  24.             inode_sb_list_add(inode);/* 将inode加入对应super_block->s_inodes链表中 */
  25.             spin_unlock(&inode_hash_lock);

  26.             /* Return the locked inode with I_NEW set, the
  27.              * caller is responsible for filling in the contents
  28.              */
  29.             return inode;
  30.         }

  31.         /*
  32.          * Uhhuh, somebody else created the same inode under
  33.          * us. Use the old inode instead of the one we just
  34.          * allocated.
  35.          */
  36.         spin_unlock(&inode_hash_lock);
  37.         destroy_inode(inode);
  38.         inode = old;
  39.         wait_on_inode(inode);
  40.     }
  41.     return inode;
  42. }
  43. EXPORT_SYMBOL(iget_locked);



6.sysfs_init_inode

点击(此处)折叠或打开

  1. static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
  2. {
  3.     struct bin_attribute *bin_attr;

  4.     inode->i_private = sysfs_get(sd);/* 根据sysfs系统的要求,再次初始化inode实例 */
  5.     inode->i_mapping->a_ops = &sysfs_aops;
  6.     inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
  7.     inode->i_op = &sysfs_inode_operations;

  8.     set_default_inode_attr(inode, sd->s_mode);/* 将sd->s_mode设置为inode的默认属性 */
  9.     sysfs_refresh_inode(sd, inode);

  10.     /* initialize inode according to type */
  11.     switch (sysfs_type(sd)) {/* 根据sd实例的sysfs_type再次初始化inode实例 */
  12.     case SYSFS_DIR:
  13.         inode->i_op = &sysfs_dir_inode_operations;
  14.         inode->i_fop = &sysfs_dir_operations;
  15.         break;
  16.     case SYSFS_KOBJ_ATTR:
  17.         inode->i_size = PAGE_SIZE;
  18.         inode->i_fop = &sysfs_file_operations;
  19.         break;
  20.     case SYSFS_KOBJ_BIN_ATTR:
  21.         bin_attr = sd->s_bin_attr.bin_attr;
  22.         inode->i_size = bin_attr->size;
  23.         inode->i_fop = &bin_fops;
  24.         break;
  25.     case SYSFS_KOBJ_LINK:
  26.         inode->i_op = &sysfs_symlink_inode_operations;
  27.         break;
  28.     default:
  29.         BUG();
  30.     }

  31.     unlock_new_inode(inode);
  32. }







阅读(1134) | 评论(0) | 转发(0) |
0

上一篇:virtual system file相关数据结构解析

下一篇:没有了

给主人留下些什么吧!~~