***************************************
重要的資料結構file_operations,file,inode
***************************************/
//file_operations
此結構定義在<linux/fs.h> 是一組函數指標的集合

loff_t參數:是一個long offset , 其長度最少有64bits ?
__user參數:這是一種另類的註解,註明該指標是指向user-space位址,不可直接取值

原型如下:
struct file_operations {
        struct module *owner;/*
            此欄位的作用,是避免模組仍在活動中時,被卸載出核心.
            通常初始化為 THIS_MODULE (所定義的?#64;個巨集)
            幾乎沒有例外
        */
        loff_t (*llseek) (struct file *, loff_t, int); /*
        改變檔案的存取位置,使得下次讀寫在新位置開始
        改變的是file結構裡的loff_t f_pos參數,file結構看後面
        */
        ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);/*
        後面詳細介紹
        */
        ssize_t (*aio_read) (struct kiocb *, char __user *, size_t, loff_t);/*
        類似read,但不同步
        */
        ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);/*
        後面詳細介紹
        */
        ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t, loff_t);/*
        類似write,但不同步
        */
        int (*readdir) (struct file *, void *, filldir_t);/*
            讀取檔案系統上的目錄 詳細操作不詳
        */
        unsigned int (*poll) (struct file *, struct poll_table_struct *);/*
            檢查檔案I/O狀態,下次的讀寫如有停頓,延遲,來不及的情況,應該提供kernel用來休眠等待
            直到可以順利I/O為止,指向NULL則kernel會假設你的裝置永遠都可流暢讀寫,而不會停頓
        */
        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 *);/*
        為了避免資料尚未完全寫出之前,裝置檔被關閉
        process關閉裝置檔時會呼叫flush
        */
        int (*release) (struct inode *, struct file *);/*
        後面詳細介紹
        */
        int (*fsync) (struct file *, struct dentry *, int datasync);/*
        讓應用程式用來將滯留在記憶體中的資料全數確實寫入裝置
        */
        int (*aio_fsync) (struct kiocb *, int datasync);/*
        類似fsynce,但不同步
        */
        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);
        int (*dir_notify)(struct file *filp, unsigned long arg);
        int (*flock) (struct file *, int, struct file_lock *);
};

//初始化
1.
  static struct file_operations fops = {
    .read = device_read,
    .write = device_write,
    .ioctl = device_ioctl,
    .open = device_open,
    .release = device_release
};
2.
  static struct file_operation fops = {
   read: device_read,
   write: device_write,
   ioctl: device_ioctl,
   open: device_open,
   release: device_release
};

//file
此結構定義在<linux/fs.h>
file結構表示已開啟的檔案
每一個file結構都是kernel在收到open系統呼叫時自動建立的
在最後一次close系統呼叫時會被釋放
原型如下:
struct file {
        struct list_head        f_list;
        struct dentry           *f_dentry;/*
        通常不在乎自己在哪個目錄項,
        但會有需要透過file->f_dentry->d_inode來存取inode結構
        */
        struct vfsmount         *f_vfsmnt;
        struct file_operations  *f_op;/*
        指向file_operations結構
        */
        atomic_t                f_count;
        unsigned int            f_flags;/*
        ?
        */
        mode_t                  f_mode;/*
        包含可讀可寫的權限資訊
        */
        int                     f_error;
        loff_t                  f_pos;/*
        目前的讀寫位置
        */
        struct fown_struct      f_owner;
        unsigned int            f_uid, f_gid;
        struct file_ra_state    f_ra;

        unsigned long           f_version;
        void                    *f_security;

        /* needed for tty driver, and maybe others */
        void                    *private_data;/*
        驅動程式可自行運用此指標,典型用法是讓他指向一塊私有資料區
        如果有用到這個,release時要記得釋放此指標的記憶體
        非常好用的功能
        */
    #ifdef CONFIG_EPOLL
        /* Used by fs/eventpoll.c to link all the hooks to this file */
        struct list_head        f_ep_links;
        spinlock_t              f_ep_lock;
    #endif /* #ifdef CONFIG_EPOLL */
        struct address_space    *f_mapping;
};

//inode
kernel內部用inode來表示檔案
不同於file結構
同一個檔案可以被開啟很多次就會有很多file結構
但他們全部指向同一個inode結構

重要的結構內容只有兩個
  dev_t i_rdev;/*
  此欄位含有實際的裝置編號
  可用unsigned int imajor(struct inode* inode);
      unsigned int iminor(struct inode* inode);
      來取得major和minor號碼 原型如下:
         static inline unsigned iminor(struct inode *inode)
         {
                 return MINOR(inode->i_rdev);
         }
         static inline unsigned imajor(struct inode *inode)
         {
                 return MAJOR(inode->i_rdev);
         }
  */
  struct cdev *i_cdev;/*
  用來表示字元裝置的結構,後面會詳談
  */
}

BB 發表在 痞客邦 PIXNET 留言(0) 人氣()