Linux中,文件创建的时间是怎么保存的?
今天在微信群里有人提問,如果創(chuàng)建一個文件,創(chuàng)建這個文件的時間是保存在哪里的。
所以就查到了這篇文章。
===
在介紹inode結構體之前先做一個鏈接文件的實驗:
1.創(chuàng)建一個普通的文件test.txt,并寫入內容查看,如下
2.創(chuàng)建test.txt的硬鏈接文件,并測試如下:
3.創(chuàng)建test.txt的軟連接文件并測試,如下:
4.ls命令查看文件相關信息,如下:
根據現(xiàn)象可以發(fā)現(xiàn),test.txt文件的硬鏈接文件test_hardlink的inode號和原文件一樣,而它的軟鏈接文件tesrt_softlink的inode號就和原文件不一樣,根據了解我們知道硬鏈接文件是原來文件的副本只是文件名不一樣而已,軟連接文件是一個新的文件(實際上硬鏈接文件在磁盤上和原文件使用的是同一個inode節(jié)點,軟連接文件使用不同的inode節(jié)點來管理文件)。
那么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,不過兩者是有區(qū)別的,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;//硬鏈接個數(shù)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;//文件中位于最后一個塊的字節(jié)數(shù)unsigned?int????????i_blkbits;//以bit為單位的塊的大小blkcnt_t????????i_blocks;//文件使用塊的數(shù)目#ifdef?__NEED_I_SIZE_ORDEREDseqcount_t??????i_size_seqcount;//對i_size進行串行計數(shù) #endif/*?Misc?*/unsigned?long???????i_state;//inode狀態(tài),可以是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;//引用計數(shù)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//存儲文件系統(tǒng)或者設備的私有信息void????????????*i_private;?/*?fs?or?device?private?pointer?*/ };實際上,inode是VFS使用的一個對象,用于存放內核在操作文件或目錄時所需要的全部信息。索引節(jié)點有兩種,一種是這里所說的VFS索引節(jié)點,存在內存中;另一種是具體文件系統(tǒng)的索引節(jié)點,存在于磁盤上,使用時將其讀入內存填充VFS的索引節(jié)點,之后對VFS索引節(jié)點的任何修改都將寫回磁盤更新磁盤的索引節(jié)點。
對于inod需要知道:
1)對于Unix風格的文件系統(tǒng)來說,這些信息可以從磁盤索引節(jié)點直接讀入。如果一個文件 系統(tǒng)沒有索引節(jié)點,那么不管這些相關信息在磁盤上市怎么存放的,文件系統(tǒng)都必須從中提取這些信息。沒有索引的文件系統(tǒng)通常將文件的描述信息作為文件的一部分來存放。這些文件系統(tǒng)與Unix風格的文件系統(tǒng)不同,沒有將數(shù)據與控制信息分開存放。而有些現(xiàn)代的文件系統(tǒng)使用數(shù)據庫來存儲文件的數(shù)據。但是不管哪種情況、采用哪種方式,索引節(jié)點對象必須在內存中創(chuàng)建,以便文件系統(tǒng)來使用。
2)一個索引節(jié)點代表了文件系統(tǒng)的一個文件,在文件創(chuàng)建時創(chuàng)建文件刪除時銷毀,但是索引節(jié)點僅在當文件被訪問時,才在內存中創(chuàng)建,且無論有多少個副本訪問這個文件,inode只存在一份。
3)inode只是用于描述文件的元數(shù)據信息,并不是文件的數(shù)據,文件的數(shù)據會根據inode的信息存放在一個數(shù)據塊中(例如:test.txt文件ls -l看到的信息就是它的屬性元信息,“hello”數(shù)據存放在另一個數(shù)據塊中)。
4)可以簡單理解為ls -l 看到的就是此文件的inode信息。
5)inode可以描述像普通文件、目錄這樣的磁盤文件,他也可以描述設備或者管道這樣的文件,不過這些特殊的文件一般只存在inode塊不分配數(shù)據塊(因為索引節(jié)點中有一些特殊文件相關的項,比如i_pipe項就指向一個代表有名管道的數(shù)據結構,i_bdev塊設備結構體,i_cdev指向字符設備結構體。這三個指針被放在一個共用體中,因為一個給定的索引節(jié)點每次只能表示三者之一(或者均不))。
6)有時,某些文件系統(tǒng)可能并不能完整地包含索引節(jié)點結構體所要求的所有信息。例如,有的文件系統(tǒng)可能并不記錄文件的訪問時間,這時,該文件系統(tǒng)可以在實現(xiàn)中選擇合適的辦法來解決和這個問題。它可以在i_atime中存儲0,或者讓i_atime等于i_mtime,或者只在內存中更新i_atime而不將其寫回磁盤,或者由文件系統(tǒng) 的實現(xiàn)者來決定。
介紹完了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;下面介紹常用的各種借口函數(shù):
在給定的節(jié)點上,可能是由VFS執(zhí)行這些函數(shù),也可能由具體的文件系統(tǒng)執(zhí)行:
該函數(shù)在在特定目錄中尋找索引節(jié)點,改索引節(jié)點要對應于dentry中給出的文件名。
struct?dentry?*?(*lookup)?(struct?inode?*dir,struct?dentry?*dentry?,?unsigned?int?)該函數(shù)在在特定目錄中尋找索引節(jié)點,改索引節(jié)點要對應于dentry中給出的文件名。
int?(*create)?(struct?inode?*dir,struct?dentry?*dentry?,?umode_t?mode,?bool?)VFS通過系統(tǒng)調用create()和open()來調用改函數(shù),從而為dentry對象創(chuàng)建一個新的索引節(jié)點。在創(chuàng)建時使用mode指定初始模式
int?(link)?(struct?dentry?*old_denrty,struct?inode?dir,struct?dentry?*dentry);該函數(shù)被系統(tǒng)調用link()調用,用來創(chuàng)建硬鏈接。硬鏈接名稱由dentry指定,連接對象是dir目錄中old_denrty目錄項所代表的文件。
int?(unlink)?(struct?inode?*dir,struct?dentry?dentry);該函數(shù)被系統(tǒng)調用ulink()調用,從目錄dir中刪除由目錄項dentry指定的索引節(jié)點對象。
int?(*symlink)?(struct?inode?*dir,struct?dentry?*dentry?,const?char?*symname);該函數(shù)被系統(tǒng)調用symlink()調用,創(chuàng)建符號鏈接。改符號鏈接的名稱由symname指定,連接對象是dir目錄中的dentry目錄項。
int?(*mkdir)?(struct?inode?*dir,struct?dentry?*dentry?,umode_t?mode);該函數(shù)被系統(tǒng)調用mkdir()調用,創(chuàng)建一個新的目錄。創(chuàng)建時使用mode指定初始模式。
int?(*rmdir)?(struct?inode?*dir,struct?dentry?*dentry?);該函數(shù)被系統(tǒng)調用rmdir()調用,刪除dir目錄中的dentry 目錄項代表的文件。
int?(*mknod)?(struct?inode?*dir,struct?dentry?*dentry?,umode_t?mode,dev_t?rdev);該函數(shù)被系統(tǒng)調用mknod()調用,創(chuàng)建特殊文件(設備文件、命名管道或套接字)。要創(chuàng)建的文件在dir目錄中,其目錄項為dentry,關聯(lián)的設備為rdev,初始權限有mode指定。
int?(*rename)?(struct?inode?*old_dir,?struct?dentry?*old_dentry?,struct?inode?*new_dir?,struct?dentry?*new_dentry?);VFS調用該函數(shù)來移動文件。文件路徑在old_dir目錄中,源文件由old_dentry目錄項指定,目標路徑在new_dir中,目標文件由new_dentry指定。
推薦閱讀:
專輯|Linux文章匯總
專輯|程序人生
專輯|C語言
我的知識小密圈
關注公眾號,后臺回復「1024」獲取學習資料網盤鏈接。
歡迎點贊,關注,轉發(fā),在看,您的每一次鼓勵,我都將銘記于心~
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結
以上是生活随笔為你收集整理的Linux中,文件创建的时间是怎么保存的?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 宇视录像机激活海康摄像头的密码是什么?
- 下一篇: Linux 资料大全