Chinaunix首页 | 论坛 | 博客
  • 博客访问: 382905
  • 博文数量: 43
  • 博客积分: 1493
  • 博客等级: 上尉
  • 技术积分: 660
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-01 10:57
文章分类

全部博文(43)

文章存档

2015年(1)

2013年(1)

2011年(6)

2010年(13)

2009年(13)

2008年(9)

分类: LINUX

2008-11-04 21:47:52

                   Lkd学习

对象模型学习:

 

struct kobject {
        char                    *k_name;
        char                    name[KOBJ_NAME_LEN];
        struct kref             kref;
        struct list_head        entry;
        struct kobject          *parent;
        struct kset             *kset;
        struct kobj_type        *ktype;
        struct dentry           *dentry;
};

k_name代表了在个kobject的名字;

如果k_name的长度小于KOBJ_NAME_LEN,这样的话名字就存储在name里面,而k_name则指向这里(这倒是一个好办法,只多了一个指针就能处理所有的情况,而且还在多数情况下用name而不会造成多少空间的浪费,高明!);

Parent成员是用来指向它的父亲的,这样就形成了一个树型结构;

Dentry成员指向它在sysfs中的dentry结构也就是目录信息;

Kref类型:

struct kref {
        atomic_t refcount;
};

表示对这个object的引用数目,当这个数为0 的时候就会被释放内存(调用的函数是ktype指向的release函数);

使用它之前需要初始化:

void kref_init(struct kref *kref)
{
        atomic_set(&kref->refcount, 1);
}
//以下是增加对kref的引用;
void kref_get(struct kref *kref)
{
        WARN_ON(!atomic_read(&kref->refcount));
        atomic_inc(&kref->refcount);
}
//以下是减少对kref的引用;
void kref_put(struct kref *kref, void (*release) (struct kref *kref))
{
        WARN_ON(release == NULL);
        WARN_ON(release == (void (*)(struct kref *))kfree);
 
        if (atomic_dec_and_test(&kref->refcount))
                release(kref);
}

 

Ktype的类型:

struct kobj_type {

        void (*release)(struct kobject *);//kobject的引用为0的时候就会被执行,用于释放内存等等;

        struct sysfs_ops        *sysfs_ops;//这里的描述请见后面

        struct attribute        **default_attrs;//这里就是一些属性,如果通过sysfs查看的话就是那些在文件目录下的文件,里面是设置的值,最后一个entry必须为null

};

struct sysfs_ops类型:

struct sysfs_ops {
        /* method invoked on read of a sysfs file */
        ssize_t (*show) (struct kobject *kobj,
                         struct attribute *attr,
                         char *buffer);
 
        /* method invoked on write of a sysfs file */
        ssize_t (*store) (struct kobject *kobj,
                          struct attribute *attr,
                          const char *buffer,
                          size_t size);
};

这里的show函数在用户调用read的时候会被调用,比如用户调用cat /sys/***的时候就会调用这个函数;

同样store就是实现的那个写的函数;

struct attribute的类型:

struct attribute {
        char             *name;    /* attribute's name */
        struct module    *owner;   /* owning module, if any */
        mode_t           mode;     /* permissions */
};
这个函数用来创建一个特定的属性,也就是我们看到的sys目录下的某个特定的文件:
int sysfs_create_file(struct kobject *kobj, const struct attribute *attr);
相反的动作是由:
void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr);
来完成的;

Kset的类型:

struct kset {
        struct subsystem         *subsys;
        struct kobj_type         *ktype;
        struct list_head         list;
        struct kobject           kobj;
        struct kset_hotplug_ops  *hotplug_ops;
};

它的存在的目的是想把这个kobject归于某一类,从list这个成员就可以看出,它将要被链在一个链表中去的;

 

struct subsystem的类型:

struct subsystem {
        struct kset             kset;
        struct rw_semaphore     rwsem;
};

 

 

struct cdev {
        struct kobject          kobj;
        struct module           *owner;
        struct file_operations  *ops;
        struct list_head        list;
        dev_t                   dev;
        unsigned int            count;
};

这里是想说明kobject对象本身并不那么重要,它只是寄存在别人的身上;

 

 

Kobject的使用例子:

 

kobj = kmalloc(sizeof (*kobj), GFP_KERNEL);
if (!kobj)
        return -ENOMEM; 
memset(kobj, 0, sizeof (*kobj));
kobj->kset = kset;
kobj->parent = parent_kobj;
kobject_init(kobj);
//然后就是设置名字,调用函数:
int kobject_set_name(struct kobject * kobj, const char * fmt, ...);

 

//以下是去增加一个kobject的引用记数的;

struct kobject * kobject_get(struct kobject *kobj);
//以下是去减少一个kobject的引用记数的;
void kobject_put(struct kobject *kobj);
kobject的生成并不会直接exportsysfs,而需要调用下面这个函数:
int kobject_add(struct kobject *kobj);

这个kobject的位置是由它里面的 parent成员决定的,如果它不存在则由成员kset里面的kobject来决定的,也就是说会自动加到它的parent的子目录里面去的,如果这两个成员都为null则认为它是根设备了;

一般情况下你只需要调用

int kobject_register(struct kobject *kobj)

就完成了kobject的初始化和加入到sysfs中去的工作;

同样的

void kobject_del(struct kobject *kobj);//sysfs去掉

kobject_put()//释放kobject

两个函数的功能就等同于

void kobject_unregister(struct kobject * kobj)

 

 

 

                     事件模型

Kernelnetlink来实现内核和用户层之间的交互;

也就是用户只需要调用socketAF_NETLINK作为参数就可以监听和传递内核消息了;

从内核里面向用户空间发送消息只需要调用:

int kobject_uevent(struct kobject *kobj,
                   enum kobject_action action,
                   struct attribute *attr);

这个版本是可以睡眠的,而不能睡眠的版本是:

int kobject_uevent_atomic(struct kobject *kobj,
                          enum kobject_action action,
                          struct attribute *attr);

 

 

 

 

 

 

 

                                 VFS的学习                     

Unix提供了四种抽象:

文件,目录,i节点,挂载点;

linu里面目录也是文件;

I节点主要是存储file metadata

而超块存储的是fs metadata,也包括单独的文件信息;

The four primary object types of the VFS are

·         The superblock object, which represents a specific mounted filesystem.

·         The inode object, which represents a specific file.

·         The dentry object, which represents a directory entry, a single component of a path.

·         The file object, which represents an open file as associated with a process.

我觉得这段话说得非常清楚!

也就是说:

超块是描述特定的挂载的文件系统;

I节点描述一个特定的文件;

目录结构代表一个路径的实体;

File结构代表一个打开的文件相关联于一个特定的进程;

·         The super_operations object, which contains the methods that the kernel can invoke on a specific filesystem, such as read_inode() and sync_fs().

·         The inode_operations object, which contains the methods that the kernel can invoke on a specific file, such as create() and link().

·         The dentry_operations object, which contains the methods that the kernel can invoke on a specific directory entry, such as d_compare() and d_delete().

·         The file object, which contains the methods that a process can invoke on an open file, such as read() and write().

这段话的意思是说:

对于超块的操作都由超块本身提供,比如read_inode,sync_fs;

对于inode的操作都由inode来提供,比如create,link;

对于dentry的操作由dentry来提供,比如d_compare,d_delete;

对于file的操作是由file来提供,比如readwrite

这也说明了vfs的实现都是面向对象风格的;

 

下面分别讲解这几个数据结构:

struct super_block {
        struct list_head        s_list;            /* list of all superblocks */
        dev_t                   s_dev;             /* identifier */
        unsigned long           s_blocksize;       /* block size in bytes */
        unsigned long           s_old_blocksize;   /* old block size in bytes */
        unsigned char           s_blocksize_bits;  /* block size in bits */
        unsigned char           s_dirt;            /* dirty flag */
        unsigned long long      s_maxbytes;        /* max file size */
        struct file_system_type s_type;            /* filesystem type */
        struct super_operations s_op;              /* superblock methods */
        struct dquot_operations *dq_op;            /* quota methods */
        struct quotactl_ops     *s_qcop;           /* quota control methods */
        struct export_operations *s_export_op;     /* export methods */
        unsigned long            s_flags;          /* mount flags */
        unsigned long            s_magic;          /* filesystem's magic number */
        struct dentry            *s_root;          /* directory mount point */
        struct rw_semaphore      s_umount;         /* unmount semaphore */
        struct semaphore         s_lock;           /* superblock semaphore */
        int                      s_count;          /* superblock ref count */
        int                      s_syncing;        /* filesystem syncing flag */
        int                      s_need_sync_fs;   /* not-yet-synced flag */
        atomic_t                 s_active;         /* active reference count */
        void                     *s_security;      /* security module */
        struct list_head         s_dirty;          /* list of dirty inodes */
        struct list_head         s_io;             /* list of writebacks */
        struct hlist_head        s_anon;           /* anonymous dentries */
        struct list_head         s_files;          /* list of assigned files */
        struct block_device      *s_bdev;          /* associated block device */
        struct list_head         s_instances;      /* instances of this fs */
        struct quota_info        s_dquot;          /* quota-specific options */
        char                     s_id[32];         /* text name */
        void                     *s_fs_info;       /* filesystem-specific info */
        struct semaphore         s_vfs_rename_sem; /* rename semaphore */
};

 

 

 

 

 

超块分配:

alloc_super()

超块最重要的操作函数列表:

struct super_operations {
        struct inode *(*alloc_inode) (struct super_block *sb);
        void (*destroy_inode) (struct inode *);
        void (*read_inode) (struct inode *);
        void (*dirty_inode) (struct inode *);
        void (*write_inode) (struct inode *, int);
        void (*put_inode) (struct inode *);
        void (*drop_inode) (struct inode *);
        void (*delete_inode) (struct inode *);
        void (*put_super) (struct super_block *);
        void (*write_super) (struct super_block *);
        int (*sync_fs) (struct super_block *, int);
        void (*write_super_lockfs) (struct super_block *);
        void (*unlockfs) (struct super_block *);
        int (*statfs) (struct super_block *, struct statfs *);
        int (*remount_fs) (struct super_block *, int *, char *);
        void (*clear_inode) (struct inode *);
        void (*umount_begin) (struct super_block *);
        int (*show_options) (struct seq_file *, struct vfsmount *);
};

 

I节点的成员:

struct inode {
        struct hlist_node       i_hash;              /* hash list */
        struct list_head        i_list;              /* list of inodes */
        struct list_head        i_dentry;            /* list of dentries *///i节点对应的dentry,有可能有连接存在所以是一个链表;
        unsigned long           i_ino;               /* inode number */
        atomic_t                i_count;             /* reference counter */
        umode_t                 i_mode;              /* access permissions */
        unsigned int            i_nlink;             /* number of hard links */
        uid_t                   i_uid;               /* user id of owner */
        gid_t                   i_gid;               /* group id of owner */
        kdev_t                  i_rdev;              /* real device node */
        loff_t                  i_size;              /* file size in bytes */
        struct timespec         i_atime;             /* last access time */
        struct timespec         i_mtime;             /* last modify time */
        struct timespec         i_ctime;             /* last change time */
        unsigned int            i_blkbits;           /* block size in bits */
        unsigned long           i_blksize;           /* block size in bytes */
        unsigned long           i_version;           /* version number */
        unsigned long           i_blocks;            /* file size in blocks */
        unsigned short          i_bytes;             /* bytes consumed */
        spinlock_t              i_lock;              /* spinlock */
        struct rw_semaphore     i_alloc_sem;         /* nests inside of i_sem */
        struct semaphore        i_sem;               /* inode semaphore */
        struct inode_operations *i_op;               /* inode ops table */
        struct file_operations  *i_fop;              /* default inode ops */
        struct super_block      *i_sb;               /* associated superblock */
        struct file_lock        *i_flock;            /* file lock list */
        struct address_space    *i_mapping;          /* associated mapping */
        struct address_space    i_data;              /* mapping for device */
        struct dquot            *i_dquot[MAXQUOTAS]; /* disk quotas for inode */
        struct list_head        i_devices;           /* list of block devices */
        struct pipe_inode_info  *i_pipe;             /* pipe information */
        struct block_device     *i_bdev;             /* block device driver */
        unsigned long           i_dnotify_mask;      /* directory notify mask */
        struct dnotify_struct   *i_dnotify;          /* dnotify */
        unsigned long           i_state;             /* state flags */
        unsigned long           dirtied_when;        /* first dirtying time */
        unsigned int            i_flags;             /* filesystem flags */
        unsigned char           i_sock;              /* is this a socket? */
        atomic_t                i_writecount;        /* count of writers */
        void                    *i_security;         /* security module */
        __u32                   i_generation;        /* inode version number */
        union {
                void            *generic_ip;         /* filesystem-specific info */
        } u;
};
I节点的操作函数;
struct inode_operations {
        int (*create) (struct inode *, struct dentry *,int);
        struct dentry * (*lookup) (struct inode *, struct dentry *);
        int (*link) (struct dentry *, struct inode *, struct dentry *);
        int (*unlink) (struct inode *, struct dentry *);
        int (*symlink) (struct inode *, struct dentry *, const char *);
        int (*mkdir) (struct inode *, struct dentry *, int);
        int (*rmdir) (struct inode *, struct dentry *);
        int (*mknod) (struct inode *, struct dentry *, int, dev_t);
        int (*rename) (struct inode *, struct dentry *,
                       struct inode *, struct dentry *);
        int (*readlink) (struct dentry *, char *, int);
        int (*follow_link) (struct dentry *, struct nameidata *);
        int (*put_link) (struct dentry *, struct nameidata *);
        void (*truncate) (struct inode *);
        int (*permission) (struct inode *, int);
        int (*setattr) (struct dentry *, struct iattr *);
        int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *);
        int (*setxattr) (struct dentry *, const char *,
                         const void *, size_t, int);
        ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
        ssize_t (*listxattr) (struct dentry *, char *, size_t);
        int (*removexattr) (struct dentry *, const char *);
};

 

 

 

struct dentry {
        atomic_t                 d_count;      /* usage count */
        unsigned long            d_vfs_flags;  /* dentry cache flags */
        spinlock_t               d_lock;       /* per-dentry lock */
        struct inode             *d_inode;     /* associated inode */
        struct list_head         d_lru;        /* unused list */
        struct list_head         d_child;      /* list of dentries within */
        struct list_head         d_subdirs;    /* subdirectories */
        struct list_head         d_alias;      /* list of alias inodes */
        unsigned long            d_time;       /* revalidate time */
        struct dentry_operations *d_op;        /* dentry operations table */
        struct super_block       *d_sb;        /* superblock of file */
        unsigned int             d_flags;      /* dentry flags */
        int                      d_mounted;    /* is this a mount point? */
        void                     *d_fsdata;    /* filesystem-specific data */
        struct rcu_head          d_rcu;        /* RCU locking */
        struct dcookie_struct    *d_cookie;    /* cookie */
        struct dentry            *d_parent;    /* dentry object of parent */
        struct qstr              d_name;       /* dentry name */
        struct hlist_node        d_hash;       /* list of hash table entries */
        struct hlist_head        *d_bucket;    /* hash bucket */
        unsigned char            d_iname[DNAME_INLINE_LEN_MIN]; /* short name */
};

Dentry有三种状态,usedunusednegative

 

·         Lists of "used" dentries that are linked off their associated inode via the i_dentry field of the inode object. Because a given inode can have multiple links, there might be multiple dentry objects; consequently, a list is used.

·         A doubly linked "least recently used" list of unused and negative dentry objects. The list is insertion sorted by time, such that entries toward the head of the list are newest. When the kernel must remove entries to reclaim memory, the entries are removed from the tail; those are the oldest and presumably have the least chance of being used in the near future.

·         A hash table and hashing function used to quickly resolve a given path into the associated dentry object.

 

 

 

 

Dentry操作函数:

struct dentry_operations {
        int (*d_revalidate) (struct dentry *, int);
        int (*d_hash) (struct dentry *, struct qstr *);
        int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
        int (*d_delete) (struct dentry *);
        void (*d_release) (struct dentry *);
        void (*d_iput) (struct dentry *, struct inode *);
};

 

 

The file object is used to represent a file opened by a process.

 

struct file {
        struct list_head       f_list;        /* list of file objects */
        struct dentry          *f_dentry;     /* associated dentry object */
        struct vfsmount        *f_vfsmnt;     /* associated mounted fs */
        struct file_operations *f_op;         /* file operations table */
        atomic_t               f_count;       /* file object's usage count */
        unsigned int           f_flags;       /* flags specified on open */
        mode_t                 f_mode;        /* file access mode */
        loff_t                 f_pos;         /* file offset (file pointer) */
        struct fown_struct     f_owner;       /* owner data for signals */
        unsigned int           f_uid;         /* user's UID */
        unsigned int           f_gid;         /* user's GID */
        int                    f_error;       /* error code */
        struct file_ra_state   f_ra;          /* read-ahead state */
        unsigned long          f_version;     /* version number */
        void                   *f_security;   /* security module */
        void                   *private_data; /* tty driver hook */
        struct list_head       f_ep_links;    /* list of eventpoll links */
        spinlock_t             f_ep_lock;     /* eventpoll lock */
        struct address_space   *f_mapping;    /* page cache mapping */
};

 

File结构的操作函数:

struct file_operations {
        struct module *owner;
        loff_t (*llseek) (struct file *, loff_t, int);
        ssize_t (*read) (struct file *, char *, size_t, loff_t *);
        ssize_t (*aio_read) (struct kiocb *, char *, size_t, loff_t);
        ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
        ssize_t (*aio_write) (struct kiocb *, const char *, size_t, loff_t);
        int (*readdir) (struct file *, void *, filldir_t);
        unsigned int (*poll) (struct file *, struct poll_table_struct *);
        int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
        int (*mmap) (struct file *, struct vm_area_struct *);
        int (*open) (struct inode *, struct file *);
        int (*flush) (struct file *);
        int (*release) (struct inode *, struct file *);
        int (*fsync) (struct file *, struct dentry *, int);
        int (*aio_fsync) (struct kiocb *, int);
        int (*fasync) (int, struct file *, int);
        int (*lock) (struct file *, int, struct file_lock *);
        ssize_t (*readv) (struct file *, const struct iovec *,
                          unsigned long, loff_t *);
        ssize_t (*writev) (struct file *, const struct iovec *,
                           unsigned long, loff_t *);
        ssize_t (*sendfile) (struct file *, loff_t *, size_t,
                             read_actor_t, void *);
        ssize_t (*sendpage) (struct file *, struct page *, int,
                             size_t, loff_t *, int);
        unsigned long (*get_unmapped_area) (struct file *, unsigned long,
                                            unsigned long, unsigned long,
                                            unsigned long);
        int (*check_flags) (int flags);
        int (*dir_notify) (struct file *filp, unsigned long arg);
        int (*flock) (struct file *filp, int cmd, struct file_lock *fl);
};

文件系统类型:

struct file_system_type {
        const char              *name;     /* filesystem's name */
        struct subsystem        subsys;    /* sysfs subsystem object */
        int                     fs_flags;  /* filesystem type flags */
 
        /* the following is used to read the superblock off the disk */
        struct super_block      *(*get_sb) (struct file_system_type *, int,
                                            char *, void *);
 
        /* the following is used to terminate access to the superblock */
        void                    (*kill_sb) (struct super_block *);
 
        struct module           *owner;    /* module owning the filesystem */
        struct file_system_type *next;     /* next file_system_type in list */
        struct list_head        fs_supers; /* list of superblock objects */
};

 

The get_sb() function is used to read the superblock from the disk and populate the superblock object when the filesystem is loaded.

它的意思是说,get_sb是被用来读取超块的;

 

 

struct vfsmount {
        struct list_head   mnt_hash;        /* hash table list */
        struct vfsmount    *mnt_parent;     /* parent filesystem */
        struct dentry      *mnt_mountpoint; /* dentry of this mount point */
        struct dentry      *mnt_root;       /* dentry of root of this fs */
        struct super_block *mnt_sb;         /* superblock of this filesystem */
        struct list_head   mnt_mounts;      /* list of children */
        struct list_head   mnt_child;       /* list of children */
        atomic_t           mnt_count;       /* usage count */
        int                mnt_flags;       /* mount flags */
        char               *mnt_devname;    /* device file name */
        struct list_head   mnt_list;        /* list of descriptors */
        struct list_head   mnt_fslink;      /* fs-specific expiry list */
        struct namespace   *mnt_namespace   /* associated namespace */
};

 

进程相关的数据结构:

 

struct files_struct {
        atomic_t    count;              /* structure's usage count */
        spinlock_t  file_lock;          /* lock protecting this structure */
        int         max_fds;            /* maximum number of file objects */
        int         max_fdset;          /* maximum number of file descriptors */
        int         next_fd;            /* next file descriptor number */
        struct file **fd;               /* array of all file objects */
        fd_set      *close_on_exec;     /* file descriptors to close on exec() */
        fd_set      *open_fds;           /* pointer to open file descriptors */
        fd_set      close_on_exec_init; /* initial files to close on exec() */
        fd_set      open_fds_init;      /* initial set of file descriptors */
        struct file *fd_array[NR_OPEN_DEFAULT]; /* default array of file objects */
};

 

struct fs_struct {
        atomic_t        count;       /* structure usage count */
        rwlock_t        lock;        /* lock protecting structure */
        int             umask;       /* default file permissions*/
        struct dentry   *root;       /* dentry of the root directory */
        struct dentry   *pwd;        /* dentry of the current directory */
        struct dentry   *altroot;    /* dentry of the alternative root */
        struct vfsmount *rootmnt;    /* mount object of the root directory */
        struct vfsmount *pwdmnt;     /* mount object of the current directory */
        struct vfsmount *altrootmnt; /* mount object of the alternative root */
};

名字空间:

struct namespace {
        atomic_t            count; /* structure usage count */
        struct vfsmount     *root; /* mount object of root directory */
        struct list_head    list;  /* list of mount points */
        struct rw_semaphore sem;   /* semaphore protecting the namespace */
};

 

 

 

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

上一篇:arm指令学习

下一篇:沒有glib的dbus使用

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