⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 namei.c

📁 一份精简的linux内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	inr = de->inode;/*找到末端文件(bu!=null),于是返回其i节点 */	dev = dir->i_dev;	brelse(bh);	iput(dir);	if (flag & O_EXCL)/*若该文件的标志为独占,则返回该信息 */		return -EEXIST;	if (!(inode=iget(dev,inr)))		return -EACCES;	if ((S_ISDIR(inode->i_mode) && (flag & O_ACCMODE)) ||/*一些权限判断 */	    !permission(inode,ACC_MODE(flag))) {		iput(inode);		return -EPERM;	}	inode->i_atime = CURRENT_TIME;	if (flag & O_TRUNC)		truncate(inode);/*截断文件 */	*res_inode = inode;	return 0;}int sys_mknod(const char * filename, int mode, int dev)/*创建新文件 */{	const char * basename;	int namelen;	struct m_inode * dir, * inode;	struct buffer_head * bh;	struct dir_entry * de;		if (!suser())		return -EPERM;	if (!(dir = dir_namei(filename,&namelen,&basename)))		return -ENOENT;	if (!namelen) {		iput(dir);		return -ENOENT;	}	if (!permission(dir,MAY_WRITE)) {		iput(dir);		return -EPERM;	}	bh = find_entry(&dir,basename,namelen,&de);	if (bh) {/*欲创建的文件已存在 */		brelse(bh);		iput(dir);		return -EEXIST;	}	inode = new_inode(dir->i_dev);/*创建新文件 */	if (!inode) {		iput(dir);		return -ENOSPC;	}	inode->i_mode = mode;	if (S_ISBLK(mode) || S_ISCHR(mode))/*如果是块设备文件或字符设备文件*/		inode->i_zone[0] = dev;	inode->i_mtime = inode->i_atime = CURRENT_TIME;	inode->i_dirt = 1;	bh = add_entry(dir,basename,namelen,&de);	if (!bh) {		iput(dir);		inode->i_nlinks=0;		iput(inode);		return -ENOSPC;	}	de->inode = inode->i_num;	bh->b_dirt = 1;	iput(dir);	iput(inode);	brelse(bh);	return 0;}int sys_mkdir(const char * pathname, int mode)/*创建一个目录(初始时有两个目录项"." "..") */{	const char * basename;	int namelen;	struct m_inode * dir, * inode;	struct buffer_head * bh, *dir_block;	struct dir_entry * de;	if (!suser())		return -EPERM;	if (!(dir = dir_namei(pathname,&namelen,&basename)))		return -ENOENT;	if (!namelen) {		iput(dir);		return -ENOENT;	}	if (!permission(dir,MAY_WRITE)) {		iput(dir);		return -EPERM;	}	bh = find_entry(&dir,basename,namelen,&de);	if (bh) {		brelse(bh);		iput(dir);		return -EEXIST;	}	inode = new_inode(dir->i_dev);	if (!inode) {		iput(dir);		return -ENOSPC;	}	inode->i_size = 32;/*新i节点的文件长度(两个目录的长度"." "..")*/	inode->i_dirt = 1;	inode->i_mtime = inode->i_atime = CURRENT_TIME;	if (!(inode->i_zone[0]=new_block(inode->i_dev))) {/*申请一保存目录项的新数据块 */		iput(dir);		inode->i_nlinks--;		iput(inode);		return -ENOSPC;	}	inode->i_dirt = 1;	if (!(dir_block=bread(inode->i_dev,inode->i_zone[0]))) {/*读入该数据块置缓冲块中,并在其中新建两项"." ".." */		iput(dir);		free_block(inode->i_dev,inode->i_zone[0]);		inode->i_nlinks--;		iput(inode);		return -ERROR;	}	de = (struct dir_entry *) dir_block->b_data;	de->inode=inode->i_num;	strcpy(de->name,".");	de++;	de->inode = dir->i_num;	strcpy(de->name,"..");	inode->i_nlinks = 2;	dir_block->b_dirt = 1;	brelse(dir_block);	inode->i_mode = I_DIRECTORY | (mode & 0777 & ~current->umask);	inode->i_dirt = 1;	bh = add_entry(dir,basename,namelen,&de);/*将新建的目录项加入父目录中 */	if (!bh) {		iput(dir);		free_block(inode->i_dev,inode->i_zone[0]);		inode->i_nlinks=0;		iput(inode);		return -ENOSPC;	}	de->inode = inode->i_num;	bh->b_dirt = 1;	dir->i_nlinks++;	dir->i_dirt = 1;	iput(dir);	iput(inode);	brelse(bh);	return 0;}/* * routine to check that the specified directory is empty (for rmdir) */static int empty_dir(struct m_inode * inode)/*目录是否为空 */{	int nr,block;	int len;	struct buffer_head * bh;	struct dir_entry * de;	len = inode->i_size / sizeof (struct dir_entry);	if (len<2 || !inode->i_zone[0] ||	    !(bh=bread(inode->i_dev,inode->i_zone[0]))) {	    	printk("warning - bad directory on dev %04x\n",inode->i_dev);		return 0;	}	de = (struct dir_entry *) bh->b_data;	if (de[0].inode != inode->i_num || !de[1].inode || /*首先过滤掉"." ".." */	    strcmp(".",de[0].name) || strcmp("..",de[1].name)) {	    	printk("warning - bad directory on dev %04x\n",inode->i_dev);		return 0;	}	nr = 2;	de += 2;	while (nr<len) {		if ((void *) de >= (void *) (bh->b_data+BLOCK_SIZE)) {			brelse(bh);			block=bmap(inode,nr/DIR_ENTRIES_PER_BLOCK);			if (!block) {				nr += DIR_ENTRIES_PER_BLOCK;				continue;			}			if (!(bh=bread(inode->i_dev,block)))				return 0;			de = (struct dir_entry *) bh->b_data;		}		if (de->inode) {			brelse(bh);			return 0;		}		de++;		nr++;	}	brelse(bh);	return 1;}int sys_rmdir(const char * name)/*删除目录*/{	const char * basename;	int namelen;	struct m_inode * dir, * inode;	struct buffer_head * bh;	struct dir_entry * de;	if (!suser())		return -EPERM;	if (!(dir = dir_namei(name,&namelen,&basename)))		return -ENOENT;	if (!namelen) {		iput(dir);		return -ENOENT;	}	if (!permission(dir,MAY_WRITE)) {		iput(dir);		return -EPERM;	}	bh = find_entry(&dir,basename,namelen,&de);	if (!bh) {		iput(dir);		return -ENOENT;	}	if (!(inode = iget(dir->i_dev, de->inode))) {		iput(dir);		brelse(bh);		return -EPERM;	}	if ((dir->i_mode & S_ISVTX) && current->euid && /*??? */	    inode->i_uid != current->euid) {		iput(dir);		iput(inode);		brelse(bh);		return -EPERM;	}	if (inode->i_dev != dir->i_dev || inode->i_count>1) {/*只有在欲删除的目录为另一个文件系统的根目录时才会发生这个情况 */		iput(dir);		iput(inode);		brelse(bh);		return -EPERM;	}	if (inode == dir) {	/* we may not delete ".", but "../dir" is ok */		iput(inode);		iput(dir);		brelse(bh);		return -EPERM;	}	if (!S_ISDIR(inode->i_mode)) {		iput(inode);		iput(dir);		brelse(bh);		return -ENOTDIR;	}	if (!empty_dir(inode)) {		iput(inode);		iput(dir);		brelse(bh);		return -ENOTEMPTY;	}	if (inode->i_nlinks != 2)		printk("empty directory has nlink!=2 (%d)",inode->i_nlinks);	de->inode = 0;/*从父目录中删除该目录项 */	bh->b_dirt = 1;	brelse(bh);	inode->i_nlinks=0;/*实际的删除目录操作,之后iput会执行具体的删除操作 */	inode->i_dirt=1;	dir->i_nlinks--;	dir->i_ctime = dir->i_mtime = CURRENT_TIME;	dir->i_dirt=1;	iput(dir);	iput(inode);	return 0;}int sys_unlink(const char * name)/*删除文件 */{	const char * basename;	int namelen;	struct m_inode * dir, * inode;	struct buffer_head * bh;	struct dir_entry * de;	if (!(dir = dir_namei(name,&namelen,&basename)))		return -ENOENT;	if (!namelen) {		iput(dir);		return -ENOENT;	}	if (!permission(dir,MAY_WRITE)) {		iput(dir);		return -EPERM;	}	bh = find_entry(&dir,basename,namelen,&de);	if (!bh) {		iput(dir);		return -ENOENT;	}	if (!(inode = iget(dir->i_dev, de->inode))) {		iput(dir);		brelse(bh);		return -ENOENT;	}	if ((dir->i_mode & S_ISVTX) && !suser() &&	    current->euid != inode->i_uid &&	    current->euid != dir->i_uid) {		iput(dir);		iput(inode);		brelse(bh);		return -EPERM;	}	if (S_ISDIR(inode->i_mode)) {		iput(inode);		iput(dir);		brelse(bh);		return -EPERM;	}	if (!inode->i_nlinks) {		printk("Deleting nonexistent file (%04x:%d), %d\n",			inode->i_dev,inode->i_num,inode->i_nlinks);		inode->i_nlinks=1;	}	de->inode = 0;/*删除父目录中该文件项 */	bh->b_dirt = 1;	brelse(bh);	inode->i_nlinks--;/*实际的删除文件操作(由于可能有几个目录指向该文件,故只要nlink非0则该文件不会被删除) */	inode->i_dirt = 1;	inode->i_ctime = CURRENT_TIME;	iput(inode);	iput(dir);	return 0;}int sys_link(const char * oldname, const char * newname)/*为已存在的文件新建一个n_link(即使另一个路径也指向该i节点)*/{	struct dir_entry * de;	struct m_inode * oldinode, * dir;	struct buffer_head * bh;	const char * basename;	int namelen;	oldinode=namei(oldname);	if (!oldinode)		return -ENOENT;	if (S_ISDIR(oldinode->i_mode)) {		iput(oldinode);		return -EPERM;	}	dir = dir_namei(newname,&namelen,&basename);	if (!dir) {		iput(oldinode);		return -EACCES;	}	if (!namelen) {		iput(oldinode);		iput(dir);		return -EPERM;	}	if (dir->i_dev != oldinode->i_dev) {		iput(dir);		iput(oldinode);		return -EXDEV;	}	if (!permission(dir,MAY_WRITE)) {		iput(dir);		iput(oldinode);		return -EACCES;	}	bh = find_entry(&dir,basename,namelen,&de);	if (bh) {		brelse(bh);		iput(dir);		iput(oldinode);		return -EEXIST;	}	bh = add_entry(dir,basename,namelen,&de);	if (!bh) {		iput(dir);		iput(oldinode);		return -ENOSPC;	}	de->inode = oldinode->i_num;	bh->b_dirt = 1;	brelse(bh);	iput(dir);	oldinode->i_nlinks++;	oldinode->i_ctime = CURRENT_TIME;	oldinode->i_dirt = 1;	iput(oldinode);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -