Linux中,文件创建的时间是怎么保存的?

今天在微信群里有人提问,如果创建一个文件,创建这个文件的时间是保存在哪里的。

所以就查到了这篇文章。

===

在介绍inode结构体之前先做一个链接文件的实验:

  • 1.创建一个普通的文件test.txt,并写入内容查看,如下

  • 2.创建test.txt的硬链接文件,并测试如下:

  • 3.创建test.txt的软连接文件并测试,如下:

  • 4.ls命令查看文件相关信息,如下:

根据现象可以发现,test.txt文件的硬链接文件test_hardlink的inode号和原文件一样,而它的软链接文件tesrt_softlink的inode号就和原文件不一样,根据了解我们知道硬链接文件是原来文件的副本只是文件名不一样而已,软连接文件是一个新的文件(实际上硬链接文件在磁盘上和原文件使用的是同一个inode节点,软连接文件使用不同的inode节点来管理文件)。

那么inode究竟是什么,它在内核中处于什么的地位?

下面我们来介绍下内核中的inode结构(大部分做了注释):

struct inode {umode_t         i_mode;//文件的访问权限(eg:rwxrwxrwx)unsigned short      i_opflags;kuid_t          i_uid;//inode拥有者idkgid_t          i_gid;//inode拥有者组idunsigned int        i_flags;//inode标志,可以是S_SYNC,S_NOATIME,S_DIRSYNC等#ifdef CONFIG_FS_POSIX_ACLstruct posix_acl    *i_acl;struct posix_acl    *i_default_acl;
#endifconst struct inode_operations   *i_op;//inode操作struct super_block  *i_sb;//所属的超级快/*address_space并不代表某个地址空间,而是用于描述页高速缓存中的页面的一个文件对应一个address_space,一个address_space与一个偏移量能够确定一个一个也高速缓存中的页面。i_mapping通常指向i_data,不过两者是有区别的,i_mapping表示应该向谁请求页面,i_data表示被改inode读写的页面。*/struct address_space    *i_mapping;#ifdef CONFIG_SECURITYvoid            *i_security;
#endif/* Stat data, not accessed from path walking */unsigned long       i_ino;//inode号/** Filesystems may only read i_nlink directly.  They shall use the* following functions for modification:**    (set|clear|inc|drop)_nlink*    inode_(inc|dec)_link_count*/union {const unsigned int i_nlink;//硬链接个数unsigned int __i_nlink;};dev_t           i_rdev;//如果inode代表设备,i_rdev表示该设备的设备号loff_t          i_size;//文件大小struct timespec     i_atime;//最近一次访问文件的时间struct timespec     i_mtime;//最近一次修改文件的时间struct timespec     i_ctime;//最近一次修改inode的时间spinlock_t      i_lock; /* i_blocks, i_bytes, maybe i_size */unsigned short          i_bytes;//文件中位于最后一个块的字节数unsigned int        i_blkbits;//以bit为单位的块的大小blkcnt_t        i_blocks;//文件使用块的数目#ifdef __NEED_I_SIZE_ORDEREDseqcount_t      i_size_seqcount;//对i_size进行串行计数
#endif/* Misc */unsigned long       i_state;//inode状态,可以是I_NEW,I_LOCK,I_FREEING等struct mutex        i_mutex;//保护inode的互斥锁//inode第一次为脏的时间 以jiffies为单位unsigned long       dirtied_when;   /* jiffies of first dirtying */struct hlist_node   i_hash;//散列表struct list_head    i_wb_list;  /* backing dev IO list */struct list_head    i_lru;      /* inode LRU list */struct list_head    i_sb_list;//超级块链表union {struct hlist_head   i_dentry;//所有引用该inode的目录项形成的链表struct rcu_head     i_rcu;};u64         i_version;//版本号 inode每次修改后递增atomic_t        i_count;//引用计数atomic_t        i_dio_count;atomic_t        i_writecount;//记录有多少个进程以可写的方式打开此文件const struct file_operations    *i_fop; /* former ->i_op->default_file_ops */struct file_lock    *i_flock;//文件锁链表struct address_space    i_data;
#ifdef CONFIG_QUOTAstruct dquot        *i_dquot[MAXQUOTAS];//inode磁盘限额
#endif/*公用同一个驱动的设备形成链表,比如字符设备,在open时,会根据i_rdev字段查找相应的驱动程序,并使i_cdev字段指向找到的cdev,然后inode添加到struct cdev中的list字段形成的链表中*/struct list_head    i_devices;,union {struct pipe_inode_info  *i_pipe;//如果文件是一个管道则使用i_pipestruct block_device *i_bdev;//如果文件是一个块设备则使用i_bdevstruct cdev     *i_cdev;//如果文件是一个字符设备这使用i_cdev};__u32           i_generation;#ifdef CONFIG_FSNOTIFY//目录通知事件掩码__u32           i_fsnotify_mask; /* all events this inode cares about */struct hlist_head   i_fsnotify_marks;
#endif#ifdef CONFIG_IMAatomic_t        i_readcount; /* struct files open RO */
#endif//存储文件系统或者设备的私有信息void            *i_private; /* fs or device private pointer */
};

实际上,inode是VFS使用的一个对象,用于存放内核在操作文件或目录时所需要的全部信息。索引节点有两种,一种是这里所说的VFS索引节点,存在内存中;另一种是具体文件系统的索引节点,存在于磁盘上,使用时将其读入内存填充VFS的索引节点,之后对VFS索引节点的任何修改都将写回磁盘更新磁盘的索引节点。

对于inod需要知道:

1)对于Unix风格的文件系统来说,这些信息可以从磁盘索引节点直接读入。如果一个文件 系统没有索引节点,那么不管这些相关信息在磁盘上市怎么存放的,文件系统都必须从中提取这些信息。没有索引的文件系统通常将文件的描述信息作为文件的一部分来存放。这些文件系统与Unix风格的文件系统不同,没有将数据与控制信息分开存放。而有些现代的文件系统使用数据库来存储文件的数据。但是不管哪种情况、采用哪种方式,索引节点对象必须在内存中创建,以便文件系统来使用。

2)一个索引节点代表了文件系统的一个文件,在文件创建时创建文件删除时销毁,但是索引节点仅在当文件被访问时,才在内存中创建,且无论有多少个副本访问这个文件,inode只存在一份。

3)inode只是用于描述文件的元数据信息,并不是文件的数据,文件的数据会根据inode的信息存放在一个数据块中(例如:test.txt文件ls -l看到的信息就是它的属性元信息,“hello”数据存放在另一个数据块中)。

4)可以简单理解为ls -l 看到的就是此文件的inode信息。

5)inode可以描述像普通文件、目录这样的磁盘文件,他也可以描述设备或者管道这样的文件,不过这些特殊的文件一般只存在inode块不分配数据块(因为索引节点中有一些特殊文件相关的项,比如i_pipe项就指向一个代表有名管道的数据结构,i_bdev块设备结构体,i_cdev指向字符设备结构体。这三个指针被放在一个共用体中,因为一个给定的索引节点每次只能表示三者之一(或者均不))。

6)有时,某些文件系统可能并不能完整地包含索引节点结构体所要求的所有信息。例如,有的文件系统可能并不记录文件的访问时间,这时,该文件系统可以在实现中选择合适的办法来解决和这个问题。它可以在i_atime中存储0,或者让i_atime等于i_mtime,或者只在内存中更新i_atime而不将其写回磁盘,或者由文件系统 的实现者来决定。

介绍完了inode,接下来看看inode的操作i_op:

struct inode_operations {struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);void * (*follow_link) (struct dentry *, struct nameidata *);int (*permission) (struct inode *, int);struct posix_acl * (*get_acl)(struct inode *, int);int (*readlink) (struct dentry *, char __user *,int);void (*put_link) (struct dentry *, struct nameidata *, void *);int (*create) (struct inode *,struct dentry *, umode_t, bool);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 *,umode_t);int (*rmdir) (struct inode *,struct dentry *);int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);int (*rename) (struct inode *, struct dentry *,struct inode *, struct dentry *);int (*setattr) (struct dentry *, struct iattr *);int (*getattr) (struct vfsmount *mnt, 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 *);int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,u64 len);int (*update_time)(struct inode *, struct timespec *, int);int (*atomic_open)(struct inode *, struct dentry *,struct file *, unsigned open_flag,umode_t create_mode, int *opened);int (*tmpfile) (struct inode *, struct dentry *, umode_t);int (*set_acl)(struct inode *, struct posix_acl *, int);
} ____cacheline_aligned;

下面介绍常用的各种借口函数:

在给定的节点上,可能是由VFS执行这些函数,也可能由具体的文件系统执行:

该函数在在特定目录中寻找索引节点,改索引节点要对应于dentry中给出的文件名。

struct dentry * (*lookup) (struct inode *dir,struct dentry *dentry , unsigned int )

该函数在在特定目录中寻找索引节点,改索引节点要对应于dentry中给出的文件名。

int (*create) (struct inode *dir,struct dentry *dentry , umode_t mode, bool )

VFS通过系统调用create()和open()来调用改函数,从而为dentry对象创建一个新的索引节点。在创建时使用mode指定初始模式

int (link) (struct dentry *old_denrty,struct inode dir,struct dentry *dentry);

该函数被系统调用link()调用,用来创建硬链接。硬链接名称由dentry指定,连接对象是dir目录中old_denrty目录项所代表的文件。

int (unlink) (struct inode *dir,struct dentry dentry);

该函数被系统调用ulink()调用,从目录dir中删除由目录项dentry指定的索引节点对象。

int (*symlink) (struct inode *dir,struct dentry *dentry ,const char *symname);

该函数被系统调用symlink()调用,创建符号链接。改符号链接的名称由symname指定,连接对象是dir目录中的dentry目录项。

int (*mkdir) (struct inode *dir,struct dentry *dentry ,umode_t mode);

该函数被系统调用mkdir()调用,创建一个新的目录。创建时使用mode指定初始模式。

int (*rmdir) (struct inode *dir,struct dentry *dentry );

该函数被系统调用rmdir()调用,删除dir目录中的dentry 目录项代表的文件。

int (*mknod) (struct inode *dir,struct dentry *dentry ,umode_t mode,dev_t rdev);

该函数被系统调用mknod()调用,创建特殊文件(设备文件、命名管道或套接字)。要创建的文件在dir目录中,其目录项为dentry,关联的设备为rdev,初始权限有mode指定。

int (*rename) (struct inode *old_dir, struct dentry *old_dentry ,struct inode *new_dir ,struct dentry *new_dentry );

VFS调用该函数来移动文件。文件路径在old_dir目录中,源文件由old_dentry目录项指定,目标路径在new_dir中,目标文件由new_dentry指定。


推荐阅读:

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

我的知识小密圈

关注公众号,后台回复「1024」获取学习资料网盘链接。

欢迎点赞,关注,转发,在看,您的每一次鼓励,我都将铭记于心~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/466108.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

g2o库报错

g2o库报错&#xff1a; 修改文件可写命令&#xff1a; sudo chmod 777 文件名1.cs.h error: cs.h could not the file报错的文件/usr/local/include/g2o/solvers/csparse/csparse_helper.h改为cs.h的完整路径&#xff1a; //#include <cs.h> #include "/home/z…

Flash与jsp通信类封装

今天写了一个通信类&#xff0c;可以实现和JSp进行数据交互。粘贴在一起&#xff0c;有兴趣可以尝试一下 package { //用于与网页通信的东西 import flash.net.URLLoader; import flash.net.URLRequest; import flash.events.*; import flash.net.URLVariables; import flash.n…

神琪宝贝

团队名称&#xff1a;神琪宝贝团队人员&#xff1a; 姓名&#xff1a;温广琪&#xff08;组长&#xff09;学号&#xff1a;1600802130博客&#xff1a;http://www.cnblogs.com/wenwenwgq/技术&#xff1a;C&#xff0c;Java&#xff0c;python&#xff0c;网站兴趣&#xff1a…

android性能测试工具之dumpsys

补记: MAT(memory analyzer tool )是google 推荐的进行内存使用量分析的工具. 功能全面而强大!!! 首先看一下dumpsys有哪些功能&#xff1a; dumpsys 用来给出手机中所有应用程序的信息&#xff0c;并且也会给出现在手机的状态。 dumpsys [Option] meminfo 显示内存信息 cpuin…

QT —— 应用程序发布

QT应用程序的发布 将QT应用程序打包给其他人使用&#xff0c;需要一些dll动态链接库&#xff1b;在QT的安装目录下&#xff0c;如&#xff1a;D:\QT\4.8.5\bin中寻找&#xff1b;&#xff08;发布的时候选择release版本的可执行程序&#xff09;。 步骤&#xff1a; 1、在桌面新…

Raspbian 中国软件源

花了些时间整理了目前最新的树莓派中国大陆地区的软件源&#xff0c;记下来&#xff0c;希望对大家有帮助。 中国科学技术大学Raspbian http://mirrors.ustc.edu.cn/raspbian/raspbian/ 阿里云Raspbian http://mirrors.aliyun.com/raspbian/raspbian/ 清华大学Raspbian http://…

一经度等于多少千米

一经度等于多少千米&#xff0c;数值是不确定的&#xff0c;不过&#xff0c;该数值的范围为&#xff1a;0km—111km。 经度等于多少千米&#xff0c;是和纬度有密切关系的&#xff0c;经度会随着纬度的变化而变化&#xff0c;其可以根据公式来计算&#xff0c;计算公式为&…

汇顶科技2021秋招笔试

来源于读者投稿&#xff0c;作者Angel。笔试时间&#xff1a;2020.08.24&#xff0c;20&#xff1a;00-21&#xff1a;00提醒&#xff1a;很多大公司秋招在七八月份就要投递简历&#xff0c;九月已经晚了。题型&#xff1a;通用部分单选10道 不定项选择题2道 填空题2道 开放题目…

创业版上市与SAP管理软件系统的关系

最近一直在忙于公司的业务&#xff0c;也有一些偷懒的心理&#xff0c;正在调整自已的心态&#xff0c;所以一段时间没有在自已的BLOG上留下痕迹了。由于客户提及企业目标是创业板上市的话题比较多&#xff0c;因此我一直在关注创业板上市这个内容。由于不是业内的专业人士&…

QT——设置可执行文件图标

QT设置可执行文件图标 软件编译出来的默认的可执行程序的图标是真的丑&#xff0c;建议还是换成漂亮一点的图标。&#xff08;在公司的话&#xff0c;就用公司的logo&#xff0c;需要后缀是ico的&#xff09;。如工程名为&#xff1a;mytest.pro 步骤&#xff1a; 1、创建ico…

安装opencv 、opencv_contrib的方法

安装opencv 、opencv_contrib的方法 opencv4.x版本都可以 opencv 、opencv_contrib内网下载&#xff1a; https://www.raoyunsoft.com/opencv 安装方法&#xff1a; https://copyfuture.com/blogs-details/202211191221591932 官网安装方法&#xff1a; https://docs.opencv.o…

科大讯飞2021笔试题

来源于读者投稿&#xff0c;作者Angel笔试时间&#xff1a;2020.09.12,19&#xff1a;00——21&#xff1a;00岗位&#xff1a;嵌入式软件开发题型&#xff1a;四道编程题&#xff0c;4*1040分题目1、定义一个n*m矩阵&#xff0c;找到两个不在同一行同一列的数字&#xff0c;使…

跨交换机VLAN配置

CCNP实验之&#xff08;跨交换机VLAN&#xff09;<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />跨交换机设置原则:存在一台VLAN服务器&#xff0c;可以存在多台vlan客户端&#xff0c;那么需要配置VTP域。交换机的连接需干线&…

QT——label

QT —— label 1、纯文本&#xff1a;使用setText()设置一个QString QLabel *label new QLabel(this);label->setText("label");label->setStyleSheet("color: red");// label->text(); // 获取文本 2、静态图像&#xff1a;使用setPixmap()设置…

在64位Ubuntu上编译32位程序常见错误

问 题1&#xff1a; 找不到头文件 asm/errno.h 解决办法 &#xff1a; 【/usr/lib/gcc$ 】sudo ln -s x86_64-linux-gnu/asm asm 问题2&#xff1a;找不到gcc静态库&#xff0c;错误描述如下 ~/tools/dnn-offline-htk-32/HTKTools$ gcc -o HBuild -m32 -ansi -D_SVID_SOU…

详细记录丨Realtek RTL8188FU WiFi 驱动移植

1 参考资料 1、芯片数据手册&#xff1a;TL8188FCA.pdf2、驱动移植手册&#xff1a;Quick_Start_Guide_for_Driver_Compilation_and_Installation.pdf3、【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.3.pdf4、Linux 添加 WiFi 驱动&#xff1a;https://blog.csdn.net/sbddbfm/…

我在Freebsd下安装帝国CMS系统整合Discuz的服务器环境配置

编译MYSQL选项&#xff1a;./configure --prefix/home/mysql --enable-assembler --with-charsetgbk --with-extra-charsetsgbk编译完成安装以后&#xff0c;需要对相应的MYSQL目录设置权限&#xff1a;chown -R root:mysql /home/mysqlchown -R mysql:mysql /home/mysql/varch…

C小项目 —— 学生信息管理系统

C小项目 —— 学生信息管理系统实现功能&#xff1a;1. 录入学生信息 2. 显示所有学生信息 3. 按学号查询学生信息 4. 按姓名查询学生信息&#xff08;支持模糊查询&#xff09; 5. 按年龄查询学生信息 6. 修改学生信息 7. 删除学生信息 8. 保存学生信息到文件 9. 从文件载入学…

拆解1968年的美国军用电脑,真的怀疑是“穿越”啊!

来源&#xff1a;数码之家文 | 禅哥这台机器在本人的eBay收藏夹里呆了很久&#xff0c;某日无意间扫了一眼收藏夹&#xff0c;突然发现卖家大降价&#xff0c;只要15刀&#xff0c;还有best offer选项。15刀你买不了吃亏&#xff0c;15刀你买不了上当。事不宜迟果断下手。根据非…

ZJOI2018 Round2 游记

day0 高铁上颓了一部电影,然后闭上眼睛就到了 醒来之后发现被绑了艹,袖子被打了个结,搞了 \(20\) 分钟才解开,真想把绑我的人吊起来 \(xxx\) 公交车上碰到一位长者,被教育了一顿 长者:"你们大学生呐,戴着一副眼镜,肯定不是读书读出来的,玩游戏玩多了吧?" 我:".…