目录
一、使用ln指令建立文件的软硬链接
1.1 建立软链接
1.2 建立硬链接
二、对于软硬链接的理解
1.1 对于硬链接的理解
1.2 对于软链接的理解
三、软硬链接的应用场景
3.1 软链接的应用场景
3.2 硬链接的应用场景
我们先不管什么是软硬链接,来实操建立一下软硬链接后再来分析
我们可以使用ln指令加上-s选项来建立文件的软链接:
# ln -s 软连接目标文件的文件名 软连接文件的文件名
我们可以看到我们创建了一个软链接:file-soft,该文件的第一个属性为l,表示软连接文件
并且这个软连接的inode编号和目标文件并不相同,因此我们可以先断定该文件是一个独立文件,必有自己的inode属性和内容
我们可以使用ln指令来直接建立文件的硬链接:
# ln 硬连接目标文件的文件名 硬连接文件的文件名
我们可以看到我们创建了一个硬链接:file-hard,这个硬连接的inode编号和目标文件相同,因此我们可以先断定该文件不是独立文件,和目标文件公用一个inode属性和内容
在inode结构体中,有一个联合体,用来记录文件的硬链接的个数:
struct inode {
umode_t i_mode;//文件的访问权限(eg:rwxrwxrwx)
unsigned short i_opflags;
kuid_t i_uid;//inode拥有者id
kgid_t i_gid;//inode拥有者组id
unsigned int i_flags;//inode标志,可以是S_SYNC,S_NOATIME,S_DIRSYNC等
#ifdef CONFIG_FS_POSIX_ACL
struct posix_acl *i_acl;
struct posix_acl *i_default_acl;
#endif
const 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_SECURITY
void *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_ORDERED
seqcount_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_QUOTA
struct 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_pipe
struct block_device *i_bdev;//如果文件是一个块设备则使用i_bdev
struct 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_IMA
atomic_t i_readcount; /* struct files open RO */
#endif
//存储文件系统或者设备的私有信息
void *i_private; /* fs or device private pointer */
};
我们每创建一个硬链接都会使其内部数据++,每删除一个硬链接都会使其内部数据--,只有当其内部数据为0时(代表没有文件名指向该inode节点了),这个inode节点才会被删除
所以硬链接的本质是创建一个新的文件名映射一个已经存在的inode
软链接的文件inode编号和目标文件不一样,但我们来打印看看软链接文件中的内容看看是什么样的:
咦?软链接的文件内容和目标文件内容是一样的
这是因为软连接内部文件内容放的是自己所指向的文件的路径!
所以打印出来的内容是一模一样的,不过软链接有自己独特的inode而已,是一个独立的文件
我们现在来创建一系列连串的目录,再在这个目录里写个程序:
现在我们回到d1所在目录下:
在我们当前路径下想要运行d4目录下的test程序很麻烦,需要加上一连串的目录名:
所以我们可以建立一个软连接来指向d4目录下的test程序:
这样子想要在当前目录下运行d4目录下的程序就很方便了:
所以我们可以通过软链接可以快速定位复杂路径下的文件,Windows操作系统下的快捷方式就是利用了这个原理
我们来看到Linux下的目录:
每个目录下都有.和..这两个标识符,我们来研究研究这两个标识符的inode编号:
我们可以看到.这个文件的inode编号和当前目录文件的inode编号完全相同,这说明了每个目录文件都有.这个硬链接指向自己
再来看看..
我们可以看到.这个文件的inode编号和当前目录的上级目录文件的inode编号完全相同,这说明了每个目录文件的子目录都有..这个硬链接指向自己
我们创建一个目录时,创建的目录里必有..这个硬链接文件指向上级目录,所以每当我们创建目录时上级目录的硬链接数会加1:
我们都知道Linux下的目录时一个多叉树结构,有了..的硬链接加持就可以使每个节点指向上一个节点,形成回溯,最终让用户很自由的切换目录:
那这么说Linux下的所有目录都至少有两个硬链接,一个是自己本身一个是.文件
按照这个规律我们可以用目录的总链接数-2,即可得出该目录下有多少子目录
但万一用户自己给目录文件创建硬链接呢?抱歉,操作系统不允许用户自己给目录创建硬链接:
因为如果让用户随意创建目录的硬链接文件的话会造成Linux的目录结构形成闭环,形成闭环后可能会造成遍历文件时陷入死循环,所以这是不允许的
那Linux目录的..文件本身不是也是形成了环结构嘛?
这是因为Linux系统可以自我识别..文件,而避免陷入循环,而用户创建文件时文件名是不可控的,操作系统并不能识别
本期到这里就全部结束了,下期见~