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

📄 namei.c,v

📁 linux-0.10 对于想了解linux内核,而又不想花太多精力的人,最好就是这种低版本,而具有核心价值的程序
💻 C,V
📖 第 1 页 / 共 2 页
字号:
	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;	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;	}	bh = find_entry(&dir,basename,namelen,&de);	if (!bh) {		iput(dir);		return -ENOENT;	}	if (!permission(dir,MAY_WRITE)) {		iput(dir);		brelse(bh);		return -EPERM;	}	if (!(inode = iget(dir->i_dev, de->inode))) {		iput(dir);		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;	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;	}	inode = iget(dir->i_dev, de->inode);	if (!inode) {		printk("iget failed in delete (%04x:%d)",dir->i_dev,de->inode);		iput(dir);		brelse(bh);		return -ENOENT;	}	if (S_ISDIR(inode->i_mode)) {		iput(inode);		iput(dir);		brelse(bh);		return -EPERM;	}	/*	 * If the directory has the sticky bit, the user must either	 * own the file or own the directory or be the superuser to 	 * delete a file in that directory.  This is typically used 	 * for /tmp and /usr/tmp.	 */	if ((dir->i_mode & S_ISVTX) && (current->euid != inode->i_uid) &&	    (current->euid != dir->i_uid) && !suser()) {		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--;	inode->i_dirt = 1;	inode->i_ctime = CURRENT_TIME;	iput(inode);	iput(dir);	return 0;}int sys_link(const char * oldname, const char * newname){	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;}@1.1log@Initial revision@text@d43 1a43 3	if (!(current->uid && current->euid))		mode=0777;	else if (current->uid==inode->i_uid || current->euid==inode->i_uid)d45 1a45 1	else if (current->gid==inode->i_gid || current->egid==inode->i_gid)d47 3a49 1	return mode & mask & 0007;d371 1d397 1a397 1	    permission(inode,ACC_MODE(flag))!=ACC_MODE(flag)) {d416 1a416 1	if (current->euid && current->uid)d467 1a467 1	if (current->euid && current->uid)d591 1a591 1	if (current->euid && current->uid)d683 13@

⌨️ 快捷键说明

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