站長資訊網
最全最豐富的資訊網站

linux有內核文件操作函數嗎

linux有內核文件操作函數,例filp_open()函數可用于打開文件、vfs_read()函數可用于讀取文件、vfs_write()函數可用于寫文件、filp_close()函數可用于關閉文件。在vfs_read和vfs_write函數中,其第二個參數指向的用戶空間的內存地址,如果直接使用內核空間的指針,則會返回“-EFALUT”。

linux有內核文件操作函數嗎

本教程操作環境:linux7.3系統、Dell G3電腦。

1. 內核空間文件操作

功能 函數原型
打開文件 struct file *filp_open(const char *filename, int flags, int mode)
讀文件 ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
寫文件 ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
關閉文件 int filp_close(struct file *filp, fl_owner_t id)

2. 內核空間與用戶空間

在vfs_read和vfs_write函數中,其參數buf指向的用戶空間的內存地址,如果我們直接使用內核空間的指針,則會返回-EFALUT。這是因為使用的緩沖區超過了用戶空間的地址范圍。一般系統調用會要求你使用的緩沖區不能在內核區。這個可以用set_fs()、get_fs()來解決。

include/asm/uaccess.h中,有如下定義:

#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })  #define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)  #define USER_DS MAKE_MM_SEG(PAGE_OFFSET)  #define get_ds() (KERNEL_DS)  #define get_fs() (current->addr_limit)  #define set_fs(x) (current->addr_limit = (x))
登錄后復制

如果使用,如下:

mm_segment_t fs = get_fs();  set_fs(KERNEL_FS);  //vfs_write();  vfs_read();  set_fs(fs);
登錄后復制

詳盡解釋:系統調用本來是提供給用戶空間的程序訪問的,所以,對傳遞給它的參數(比如上面的buf),它默認會認為來自用戶空間,在read或write()函數中,為了保護內核空間,一般會用get_fs()得到的值來和USER_DS進行比較,從而防止用戶空間程序“蓄意”破壞內核空間;而現在要在內核空間使用系統調用,此時傳遞給read或write()的參數地址就是內核空間的地址了,在USER_DS之上(USER_DS ~ KERNEL_DS),如果不做任何其它處理,在write()函數中,會認為該地址超過了USER_DS范圍,所以會認為是用戶空間的“蓄意破壞”,從而不允許進一步的執行;為了解決這個問題set_fs(KERNEL_DS)將其能訪問的空間限制擴大到KERNEL_DS,這樣就可以在內核順利使用系統調用了!

3.Linux struct inode結構

/*索引節點對象由inode結構體表示,定義文件在linux/fs.h中 */ struct inode {         struct hlist_node       i_hash;              /* 哈希表 */         struct list_head        i_list;              /* 索引節點鏈表 */         struct list_head        i_dentry;            /* 目錄項鏈表 */         unsigned long           i_ino;               /* 節點號 */         atomic_t                i_count;             /* 引用記數 */         umode_t                 i_mode;              /* 訪問權限控制 */         unsigned int            i_nlink;             /* 硬鏈接數 */         uid_t                   i_uid;               /* 使用者id */         gid_t                   i_gid;               /* 使用者id組 */         kdev_t                  i_rdev;              /* 實設備標識符 */         loff_t                  i_size;              /* 以字節為單位的文件大小 */         struct timespec         i_atime;             /* 最后訪問時間 */         struct timespec         i_mtime;             /* 最后修改(modify)時間 */         struct timespec         i_ctime;             /* 最后改變(change)時間 */         unsigned int            i_blkbits;           /* 以位為單位的塊大小 */         unsigned long           i_blksize;           /* 以字節為單位的塊大小 */         unsigned long           i_version;           /* 版本號 */         unsigned long           i_blocks;            /* 文件的塊數 */         unsigned short          i_bytes;             /* 使用的字節數 */         spinlock_t              i_lock;              /* 自旋鎖 */         struct rw_semaphore     i_alloc_sem;         /* 索引節點信號量 */         struct inode_operations *i_op;               /* 索引節點操作表 */         struct file_operations  *i_fop;              /* 默認的索引節點操作 */         struct super_block      *i_sb;               /* 相關的超級塊 */         struct file_lock        *i_flock;            /* 文件鎖鏈表 */         struct address_space    *i_mapping;          /* 相關的地址映射 */         struct address_space    i_data;              /* 設備地址映射 */         struct dquot            *i_dquot[MAXQUOTAS]; /* 節點的磁盤限額 */         struct list_head        i_devices;           /* 塊設備鏈表 */         struct pipe_inode_info  *i_pipe;             /* 管道信息 */         struct block_device     *i_bdev;             /* 塊設備驅動 */         unsigned long           i_dnotify_mask;      /* 目錄通知掩碼 */         struct dnotify_struct   *i_dnotify;          /* 目錄通知 */         unsigned long           i_state;             /* 狀態標志 */         unsigned long           dirtied_when;        /* 首次修改時間 */         unsigned int            i_flags;             /* 文件系統標志 */         unsigned char           i_sock;              /* 可能是個套接字吧 */         atomic_t                i_writecount;        /* 寫者記數 */         void                    *i_security;         /* 安全模塊 */         __u32                   i_generation;        /* 索引節點版本號 */         union {                 void            *generic_ip;         /* 文件特殊信息 */         } u; };  /* *索引節點的操作inode_operations定義在linux/fs.h中 */ struct inode_operations {         int (*create) (struct inode *, struct dentry *,int);         /*VFS通過系統調用create()和open()來調用該函數,從而為dentry對象創建一個新的索引節點。在創建時使用mode制定初始模式*/         struct dentry * (*lookup) (struct inode *, struct dentry *);         /*該韓式在特定目錄中尋找索引節點,該索引節點要對應于dentry中給出的文件名*/         int (*link) (struct dentry *, struct inode *, struct dentry *);         /*該函數被系統調用link()電泳,用來創建硬連接。硬鏈接名稱由dentry參數指定,連接對象是dir目錄中ld_dentry目錄想所代表的文件*/         int (*unlink) (struct inode *, struct dentry *);         /*該函數被系統調用unlink()調用,從目錄dir中刪除由目錄項dentry制動的索引節點對象*/         int (*symlink) (struct inode *, struct dentry *, const char *);         /*該函數被系統電泳symlik()調用,創建符號連接,該符號連接名稱由symname指定,連接對象是dir目錄中的dentry目錄項*/         int (*mkdir) (struct inode *, struct dentry *, int);         /*該函數被mkdir()調用,創建一個新魯姆。創建時使用mode制定的初始模式*/         int (*rmdir) (struct inode *, struct dentry *);         /*該函數被系統調用rmdir()調用,刪除dir目錄中的dentry目錄項代表的文件*/         int (*mknod) (struct inode *, struct dentry *, int, dev_t);         /*該函數被系統調用mknod()調用,創建特殊文件(設備文件、命名管道或套接字)。要創建的文件放在dir目錄中,其目錄項問dentry,關聯的設備為rdev,初始權限由mode指定*/         int (*rename) (struct inode *, struct dentry *,                        struct inode *, struct dentry *);         /*VFS調用該函數來移動文件。文件源路徑在old_dir目錄中,源文件由old_dentry目錄項所指定,目標路徑在new_dir目錄中,目標文件由new_dentry指定*/         int (*readlink) (struct dentry *, char *, int);         /*該函數被系統調用readlink()調用,拷貝數據到特定的緩沖buffer中。拷貝的數據來自dentry指定的符號鏈接,最大拷貝大小可達到buflen字節*/         int (*follow_link) (struct dentry *, struct nameidata *);         /*該函數由VFS調用,從一個符號連接查找他指向的索引節點,由dentry指向的連接被解析*/         int (*put_link) (struct dentry *, struct nameidata *);         /*在follow_link()調用之后,該函數由vfs調用進行清楚工作*/         void (*truncate) (struct inode *);         /*該函數由VFS調用,修改文件的大小,在調用之前,索引節點的i_size項必須被設置成預期的大小*/         int (*permission) (struct inode *, int);         /*該函數用來檢查給低昂的inode所代表的文件是否允許特定的訪問模式,如果允許特定的訪問模式,返回0,否則返回負值的錯誤碼。多數文件系統 都將此區域設置為null,使用VFS提供的通用方法進行檢查,這種檢查操作僅僅比較索引及誒但對象中的訪問模式位是否和mask一致,比較復雜的系統, 比如支持訪問控制鏈(ACL)的文件系統,需要使用特殊的permission()方法*/         int (*setattr) (struct dentry *, struct iattr *);         /*該函數被notify_change調用,在修改索引節點之后,通知發生了改變事件*/         int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *);         /*在通知索引節點需要從磁盤中更新時,VFS會調用該函數*/         int (*setxattr) (struct dentry *, const char *,                          const void *, size_t, int);         /*該函數由VFS調用,向dentry指定的文件設置擴展屬性,屬性名為name,值為value*/         ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);         /*該函數被VFS調用,向value中拷貝給定文件的擴展屬性name對應的數值*/         ssize_t (*listxattr) (struct dentry *, char *, size_t);         /*該函數將特定文件所有屬性別表拷貝到一個緩沖列表中*/         int (*removexattr) (struct dentry *, const char *);         /*該函數從給定文件中刪除指定的屬性*/ };
登錄后復制

4.Linux struct file結構
struct file結構體定義在/linux/include/linux/fs.h(Linux 2.6.11內核)中,其原型是:

struct file {         /*          * fu_list becomes invalid after file_free is called and queued via          * fu_rcuhead for RCU freeing          */         union {                 struct list_head        fu_list;                 struct rcu_head         fu_rcuhead;         } f_u;         struct path             f_path; #define f_dentry        f_path.dentry #define f_vfsmnt        f_path.mnt         const struct file_operations    *f_op;         atomic_t                f_count;         unsigned int            f_flags;         mode_t                  f_mode;         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; #ifdef CONFIG_SECURITY         void                    *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_head        f_ep_links;         spinlock_t              f_ep_lock; #endif /* #ifdef CONFIG_EPOLL */         struct address_space    *f_mapping; };
登錄后復制

文 件結構體代表一個打開的文件,系統中的每個打開的文件在內核空間都有一個關聯的struct file。它由內核在打開文件時創建,并傳遞給在文件上進行操作的任何函數。在文件的所有實例都關閉后,內核釋放這個數據結構。在內核創建和驅動源碼 中,struct file的指針通常被命名為file或filp。

贊(0)
分享到: 更多 (0)
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
国产在线高清精品二区色五郎| 无码精品A∨在线观看免费 | 亚洲国产主播精品极品网红| 国产精品自在线天天看片| 伦精品一区二区三区视频| 精品国产乱码久久久久软件 | 日产精品一卡2卡三卡4乱码| 亚洲欧洲精品国产区| 久久精品水蜜桃av综合天堂| 99久久精品日本一区二区免费| 亚洲精品无码不卡| 国产精品视频一区二区三区无码| 91麻豆精品国产| 国产精品夜色视频一级区| 福利姬在线精品观看| 青青青青久久精品国产h久久精品五福影院1421| 亚洲国产日韩在线观频| 国产精品va在线观看无| 日韩精品一区二区三区毛片| 97精品伊人久久大香线蕉| 精品无码专区亚洲| 影院成人区精品一区二区婷婷丽春院影视 | 国内精品免费在线观看| 中文国产成人久久精品小说| 国产精品美女久久久网AV| 亚洲精品网站在线观看不卡无广告| 日韩中文无码有码免费视频| 日韩三级一区二区| 色精品一区二区三区| 美女bbbb精品视频| 亚洲国产成人乱码精品女人久久久不卡| 一区二区精品视频| 国产高清精品一区| 老司机精品视频在线| 亚洲中文久久精品无码| 久久91精品国产91久久户| 精品少妇一区二区三区视频| 国产精品内射后入合集| 久久se精品动漫一区二区三区| 久久亚洲私人国产精品| 亚洲国产精品久久久久秋霞影院|