Linux Kernal VFS-Struct file

2021SC@SDUSC

Struct file

Discussed about inode and dentry, it finally comes to struct file, although it's not like a real file we've talked about.Actually, inodes are related to the real file and the kernal use it to operate with all files in need, not struct file.For file system it is not that necessary as inode which is a out-standing sign for a file nor dentry which is used for mapping inode to actual file which has already been stored in Cache.Struct file are mainly for process scheduling.

Users start a process in queue, yet don't really care about the hidden part of file system, just like users cares only about file's name instead of inode.And struct file are exposed to process which is also user himself.We program calls open() and open a file, struct file started to play an important part in recording the context.

Struct file's defination is also in linux/fs.h.

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;
    spinlock_t      f_lock;  /* f_ep_links, f_flags, no IRQ */
    atomic_long_t       f_count;
    unsigned int        f_flags;
    fmode_t         f_mode;
    loff_t          f_pos;
    struct fown_struct  f_owner;
    const struct cred   *f_cred;
    struct file_ra_state    f_ra;

    u64         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;
#endif /* #ifdef CONFIG_EPOLL */
    struct address_space    *f_mapping;
#ifdef CONFIG_DEBUG_WRITECOUNT
    unsigned long f_mnt_write_state;
#endif
};

Some of the useful members are shown as below.

f_mode_t f_mode

File's mode if it's available for reading or writting includeing fmode_read and fmode_write.Though it sounds like permission for opeing or writting a file, you don't have to check it in open() for it has been checked by kernal before the functions' being called.So read or write operations to a file that doesn't have such permission will be denied by kernal, no need for checking again.

loff_t f_pos

Read or write position.Be aware that stuct file is holding context for opening a file.Since a file could be opened several times and even one process can open one file twice or third time, there could be multiple struct files that related to a single file.When a process operationg a file the context messages are to be saved in struct file so it could be used soon.

unsigned int f_flags

A sign for checking.O_nonblock will be check to see if the file is blocked by user,otherwise it is seldom used.

atomic_long_t f_count

Count the number or reference towards the file.

File_struct

file_struct is description to a file in use by process and is a unsigned integer.Every task_struct has  a file_struct list and the file_struct are placed in the list.Each file_struct has a pointer towards a opened file, and an opened file is represented as struct file we discussed above.Remember that struct file actually saves context for opening the file so there could be multiple struct files even there is only one file in operate.

For linux kernal, 3 file_struct are basically used, which is 0/1/2.

file_structfunctionsstdio_stream
0standard inputstdin
1standard outputstdout
2standard errorstderr

The kernal will distribute the mininum number as a newly opened file's file_structure, ranged from 0 to OPEN_MAX-1.

This pictures shows the relationship between inode,dentry as well as file.When we talk about operations later, we will be using this picture.

 

File operations f_op

When opening a file, a struct file will be created by OS to operate such file and f_op aims to the functions that operates the file.Each of the functions are connected to a system call such as open(),fsync().So we finally get closer to the user's stage.

struct file_operations {
    struct module *owner;               
    //指向拥有该模块的指针;
    loff_t (*llseek) (struct file *, loff_t, int);   
    //llseek 方法用作改变文件中的当前读/写位置, 并且新位置作为(正的)返回值. 
    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);  
    //用来从设备中获取数据. 在这个位置的一个空指针导致 read 系统调用以 -EINVAL("Invalid argument") 失败. 一个非负返回值代表了成功读取的字节数( 返回值是一个 "signed size" 类型, 常常是目标平台本地的整数类型).
    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
    //发送数据给设备. 如果 NULL, -EINVAL 返回给调用 write 系统调用的程序. 如果非负, 返回值代表成功写的字节数.
    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);
    //对于设备文件这个成员应当为 NULL; 它用来读取目录, 并且仅对**文件系统**有用.
    unsigned int (*poll) (struct file *, struct poll_table_struct *);
    int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
    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 *);
    //mmap 用来请求将设备内存映射到进程的地址空间. 如果这个方法是 NULL, mmap 系统调用返回 -ENODEV.
    int (*open) (struct inode *, struct file *);
    //打开一个文件
    int (*flush) (struct file *, fl_owner_t id);
    //flush 操作在进程关闭它的设备文件描述符的拷贝时调用;
    int (*release) (struct inode *, struct file *);
    //在文件结构被释放时引用这个操作. 如同 open, release 可以为 NULL.
    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 *);
    //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 **);
};
————————————————
版权声明:本文为CSDN博主「_stark」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/bit_clearoff/article/details/54565044
Thanks for the code.

These operations are the next topic for our blogs.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值