字符设备(二)之主要数据结构

来源:互联网 发布:android 源码在线查看 编辑:程序博客网 时间:2024/05/29 15:25

一.linux文件系统和字符设备驱动

应用程序和VFS之间的接口是系统调用,而VFS和磁盘文件系以及普通设备之间接口是file_operation结构体成员函数,这个结构包含打开,关闭,读,写等各种对文件的操作

字符设备上层不涉及到磁盘,所以字符设备的file_operation成员函数直接由设备驱动提供。file_operation是字符设备的操作核心。

1.file结构体

文件结构体代表一个文件(若是设备,则为设备文件),系统中每个打开的文件在内核中都有个一个struct file,由内核在打开文件的时候创建,并传递给在文件上进行
操作的任何函数,在文件的所有实例都关闭后,内核释放这个数据结构。

struct file {/* * fu_list becomes invalid after file_free is called and queued via * fu_rcuhead for RCU freeing */union {//共用体不同时刻占用同一段内存struct list_headfu_list;struct rcu_head fu_rcuhead;//2.6新加入的锁机制} f_u;struct pathf_path;#define f_dentryf_path.dentry//目录入口#define f_vfsmntf_path.mntconst struct file_operations*f_op;//和文件关联的操作spinlock_tf_lock;  /* f_ep_links, f_flags, no IRQ */atomic_long_tf_count;unsigned int f_flags;//文件标识,O_RDONLY,O_NONBLOCK,O_SYNCfmode_tf_mode;//文件读写模式loff_tf_pos;struct fown_structf_owner;const struct cred*f_cred;struct file_ra_statef_ra;u64f_version;#ifdef CONFIG_SECURITYvoid*f_security;#endif/* needed for tty driver, and maybe others */void*private_data;//文件私有数据#ifdef CONFIG_EPOLL/* Used by fs/eventpoll.c to link all the hooks to this file */struct list_headf_ep_links;#endif /* #ifdef CONFIG_EPOLL */struct address_space*f_mapping;#ifdef CONFIG_DEBUG_WRITECOUNTunsigned long f_mnt_write_state;#endif};
要点:文件读写模式mode,标识f_flags,私有数据指针private_data,广泛用于设备驱动中,指向自定义用于描述设备的结构体。

驱动程序中常用如下类似代码检测用户打开文件的读写方式

if(file->f_mode & FMODE_WRITE){}if(file->f_mode & FMODE_READ){}
以下代码用于判断以阻塞还是非阻塞方式打开设备

if(file->f_flags & O_NONBLOCK)pr_debug("open: non-blocking\n");elsepr_debug("open: blocking\n");
2.inode结构体

VFS inode包含文件的各种信息,eg:大小,权限等,是linux管理文件系统的最小单位,也是文件系统连接任何子目录,文件的桥梁

struct inode {struct hlist_nodei_hash;struct list_headi_list;/* backing dev IO list */struct list_headi_sb_list;struct list_headi_dentry;unsigned longi_ino;atomic_ti_count;unsigned inti_nlink;uid_ti_uid;//inode拥有者的idgid_ti_gid;//inode所属的群组iddev_ti_rdev;//若是设备文件,记录设备的设备号u64i_version;loff_ti_size;#ifdef __NEED_I_SIZE_ORDEREDseqcount_ti_size_seqcount;#endifstruct timespeci_atime;//inode最近一次存钱时间struct timespeci_mtime;//inode最近一次修改时间struct timespeci_ctime;//inode的产生时间blkcnt_ti_blocks;//inode所使用的block数,一个block为512byteunsigned inti_blkbits;//inode做I/O时的区块大小unsigned short          i_bytes;umode_ti_mode;//inode的权限spinlock_ti_lock;/* i_blocks, i_bytes, maybe i_size */struct mutexi_mutex;struct rw_semaphorei_alloc_sem;const struct inode_operations*i_op;const struct file_operations*i_fop;/* former ->i_op->default_file_ops */struct super_block*i_sb;struct file_lock*i_flock;struct address_space*i_mapping;struct address_spacei_data;#ifdef CONFIG_QUOTAstruct dquot*i_dquot[MAXQUOTAS];#endifstruct list_headi_devices;union {struct pipe_inode_info*i_pipe;struct block_device*i_bdev;//块设备struct cdev*i_cdev;//字符设备};__u32i_generation;#ifdef CONFIG_FSNOTIFY__u32i_fsnotify_mask; /* all events this inode cares about */struct hlist_headi_fsnotify_mark_entries; /* fsnotify mark entries */#endif#ifdef CONFIG_INOTIFYstruct list_headinotify_watches; /* watches on this inode */struct mutexinotify_mutex;/* protects the watches list */#endifunsigned longi_state;unsigned longdirtied_when;/* jiffies of first dirtying */unsigned inti_flags;atomic_ti_writecount;#ifdef CONFIG_SECURITYvoid*i_security;#endif#ifdef CONFIG_FS_POSIX_ACLstruct posix_acl*i_acl;struct posix_acl*i_default_acl;#endifvoid*i_private; /* fs or device private pointer */};
二.file_operations结构体

struct file_operations {struct module *owner;//一般为THIS_MODULEloff_t (*llseek) (struct file *, loff_t, int);//修改文件当前读写位置ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);//从设备中同步读写数据,成功则返回读取的字节数,失败返回负值ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);//向设备发送数据,成功返回写入的字节数ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, 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);//执行设备I/O控制命令long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);long (*compat_ioctl) (struct file *, unsigned int, unsigned long);int (*mmap) (struct file *, struct vm_area_struct *);//用于请求将设备内存映射到进程地址空间int (*open) (struct inode *, struct file *);int (*flush) (struct file *, fl_owner_t id);int (*release) (struct inode *, struct file *);int (*fsync) (struct file *, struct dentry *, int datasync);int (*aio_fsync) (struct kiocb *, int datasync);int (*fasync) (int, struct file *, int);int (*lock) (struct file *, int, struct file_lock *);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);int (*flock) (struct file *, int, struct file_lock *);ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);int (*setlease)(struct file *, long, struct file_lock **);};



原创粉丝点击