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

📄 namei.cpp

📁 JFFS的源代码
💻 CPP
字号:

#include "../jffs/jffstypes.h"
#include "../jffs/fcntl.h"
#include "../jffs/errno.h"
#include "../jffs/stat.h"
#include "../jffs/fs.h"

/*
 * lookup() looks up one part of a pathname, using the fs-dependent
 * routines (currently minix_lookup) for it. It also checks for
 * fathers (pseudo-roots, mount-points)
 */
int lookup(struct inode * dir,const char * name, int len,
           struct inode ** result)
{
	struct super_block * sb;
	int perm;

	*result = (struct inode *)NULL;
	if (!dir)
		return -ENOENT;

	if (!dir->i_op || !dir->i_op->lookup) {
		iput(dir);
		return -ENOTDIR;
	}
	if (!len) {
		*result = dir;
		return 0;
	}
	return dir->i_op->lookup(dir, name, len, result);
}

int follow_link(struct inode * dir, struct inode * inode,
	int flag, int mode, struct inode ** res_inode)
{
	if (!dir || !inode) {
		/*iput(dir);
		iput(inode);*/
		*res_inode = (struct inode *)NULL;
		return -ENOENT;
	}
	if (!inode->i_op || !inode->i_op->follow_link) {
		/*iput(dir);*/
		*res_inode = inode;
		return 0;
	}
	return inode->i_op->follow_link(dir,inode,flag,mode,res_inode);
}

/*
 *	dir_namei()
 *
 * dir_namei() returns the inode of the directory of the
 * specified name, and the name within that directory.
 */
/*pathname需以'\0'结尾, 要求绝对路径 */
static int dir_namei(const char *pathname, int *namelen, const char **name,
                     struct inode * base, struct inode **res_inode)
{
	char c;
	const char * thisname;
	int len,error;
	struct inode * inode;
	//struct inode bbase;

	//base = &bbase;
	*res_inode = (struct inode *)NULL;
	/*只处理绝对路径, fdk文件传送, 自己循环查询*/
	if ((c = *pathname) == '/') {
		/*iput(base); base为NULL*/
		base = current_fs.root;
		//memcpy(base, current_fs.root, sizeof(struct inode));
		pathname++;
		/*base->i_count++;*/
	}
	else 
		return -ENOTDIR;
		
	while (1) {
		thisname = pathname;
		for(len=0;(c = *(pathname++))&&(c != '/');len++)
			/* nothing */ ;
		if (!c)
			break;
		/*base->i_count++;*/
		error = lookup(base, thisname, len, &inode); 
		if (error) {
			/*iput(base);*/
			return error;
		}
		//memcpy(base, &inode, sizeof(
		base = inode;
		/*在follow_link中更新base, ?follow_link的意义*/ 
		/*error = follow_link(base,inode,0,0,&base);
		if (error)
			return error;*/
	}
	
	if (!base->i_op || !base->i_op->lookup) {
		/*iput(base);*/
		return -ENOTDIR;
	}
	*name = thisname;
	*namelen = len;
	*res_inode = base;
	return 0;
}

/*
 *	open_namei()
 *
 * namei for open - this is in fact almost the whole open-routine.
 *
 * Note that the low bits of "flag" aren't the same as in the open
 * system call - they are 00 - no permissions needed
 *			  01 - read permission needed
 *			  10 - write permission needed
 *			  11 - read/write permissions needed
 * which is a lot more logical, and also allows the "no perm" needed
 * for symlinks (where the permissions are checked later).
 */
int open_namei(const char * pathname, int flag, int mode,
               struct inode ** res_inode, struct inode * base)
{
	const char * basename;
	int namelen,error;
	struct inode * dir, *inode;

	error = dir_namei(pathname, &namelen, &basename, base, &dir);
	if (error)
		return error;
	if (!namelen) {			/* special case: '/usr/' etc */
		if (flag & 2) {
			iput(dir);
			return -EISDIR;
		}
		*res_inode=dir;
		return 0;
	}
	dir->i_count++;		/* lookup eats the dir */
	if (flag & O_CREAT) {
		/*???down(&dir->i_sem);*/
		error = lookup(dir, basename, namelen, &inode);
		if (!error) {
			if (flag & O_EXCL) {
				iput(inode);
				error = -EEXIST;
			}
		} else if (IS_RDONLY(dir))
			error = -EROFS;
		else if (!dir->i_op || !dir->i_op->create)
			error = -EACCES;
		else {
			dir->i_count++;		/* create eats the dir */
			error = dir->i_op->create(dir, basename, namelen, mode, res_inode);
			/*???up(&dir->i_sem);*/
			iput(dir);
			return error;
		}
		/*???up(&dir->i_sem);TODO*/
	} else
		error = lookup(dir, basename, namelen, &inode);
	if (error) {
		iput(dir);
		return error;
	}
	if (S_ISDIR(inode->i_mode) && (flag & 2)) {
		iput(inode);
		return -EISDIR;
	}
	if (IS_RDONLY(inode) && (flag & 2)) {
		iput(inode);
		return -EROFS;
	}
	/*
	 * An append-only file must be opened in append mode for writing
	 * Additionally, we must disallow O_TRUNC -- cevans
	 */
	if (IS_APPEND(inode) && (((flag & FMODE_WRITE) && !(flag & O_APPEND)) || (flag & O_TRUNC))) {
		iput(inode);
		return -EPERM;
	}
	if (flag & O_TRUNC) {
		/*error = do_truncate(inode, 0);
		if (error) {
			iput(inode);
			return error;
		}*/
	} 
	
	*res_inode = inode;
	return 0;
}

int mf_unlink(const char * name)
{
	const char * basename;
	int namelen, error;
	struct inode * dir;

	int fd;
	fd = mf_open((char *)name, 0, 0); /*!!!修改current_fd,get_empty_inode*/
	if(fd == 0) return -1;

	error = dir_namei(name, &namelen, &basename, (struct inode *)NULL, &dir);
	if (error)
		return error;
	if (!namelen) {
		/*iput(dir);*/
		return -EPERM;
	}
	/*if (IS_RDONLY(dir)) {
		iput(dir);
		return -EROFS;
	}*/
	/*if ((error = permission(dir,MAY_WRITE | MAY_EXEC)) != 0) {
		iput(dir);
		return error;
	}*/
	/*
	 * A file cannot be removed from an append-only directory
	 */
	/*if (IS_APPEND(dir)) {
		iput(dir);
		return -EPERM;
	}
	if (!dir->i_op || !dir->i_op->unlink) {
		iput(dir);
		return -EPERM;
	}*/
	/*if (dir->i_sb && dir->i_sb->dq_op)
		dir->i_sb->dq_op->initialize(dir, -1);*/
	/*-down(&dir->i_sem);*/
	error = dir->i_op->unlink(dir,basename,namelen);
	/*-up(&dir->i_sem);*/

	mf_close(fd);
	
	return error;
}

int mf_mkdir(const char * pathname, int mode)
{
	const char * basename;
	int namelen, error;
	struct inode * dir;

	error = dir_namei(pathname, &namelen, &basename, (struct inode *)0, &dir);
	if (error)
		return error;
	if (!namelen) {
		iput(dir);
		return -ENOENT;
	}
	if (IS_RDONLY(dir)) {
		iput(dir);
		return -EROFS;
	}
	/*m* if ((error = permission(dir,MAY_WRITE | MAY_EXEC)) != 0) {
		iput(dir);
		return error;
	}*/
	if (!dir->i_op || !dir->i_op->mkdir) {
		iput(dir);
		return -EPERM;
	}
	dir->i_count++;
	/*m* if (dir->i_sb && dir->i_sb->dq_op)
		dir->i_sb->dq_op->initialize(dir, -1);
	down(&dir->i_sem);*/
	/*m* error = dir->i_op->mkdir(dir, basename, namelen, mode & 01777 & ~current->fs->umask);*/
	error = dir->i_op->mkdir(dir, basename, namelen, mode & 01777);
	/*m* up(&dir->i_sem);*/
	iput(dir);
	return error;
}

int mf_rename(const char * oldname, const char * newname, int must_be_dir)
{
	struct inode * old_dir, * new_dir;
	const char * old_base, * new_base;
	int old_len, new_len, error;

	error = dir_namei(oldname, &old_len, &old_base, ( struct inode *)NULL, &old_dir);
	if (error)
		return error;
	/*if ((error = permission(old_dir,MAY_WRITE | MAY_EXEC)) != 0) {
		iput(old_dir);
		return error;
	}*/
	if (!old_len || (old_base[0] == '.' &&
	    (old_len == 1 || (old_base[1] == '.' &&
	     old_len == 2)))) {
		iput(old_dir);
		return -EPERM;
	}
	error = dir_namei(newname, &new_len, &new_base, ( struct inode *)NULL, &new_dir);
	if (error) {
		iput(old_dir);
		return error;
	}
	/*if ((error = permission(new_dir,MAY_WRITE | MAY_EXEC)) != 0){
		iput(old_dir);
		iput(new_dir);
		return error;
	}*/
	if (!new_len || (new_base[0] == '.' &&
	    (new_len == 1 || (new_base[1] == '.' &&
	     new_len == 2)))) {
		iput(old_dir);
		iput(new_dir);
		return -EPERM;
	}
	if (new_dir->i_dev != old_dir->i_dev) {
		iput(old_dir);
		iput(new_dir);
		return -EXDEV;
	}
	if (IS_RDONLY(new_dir) || IS_RDONLY(old_dir)) {
		iput(old_dir);
		iput(new_dir);
		return -EROFS;
	}
	/*
	 * A file cannot be removed from an append-only directory
	 */
	if (IS_APPEND(old_dir)) {
		iput(old_dir);
		iput(new_dir);
		return -EPERM;
	}
	if (!old_dir->i_op || !old_dir->i_op->rename) {
		iput(old_dir);
		iput(new_dir);
		return -EPERM;
	}
	new_dir->i_count++;
	/*if (new_dir->i_sb && new_dir->i_sb->dq_op)
		new_dir->i_sb->dq_op->initialize(new_dir, -1);
	down(&new_dir->i_sem);*/
	error = old_dir->i_op->rename(old_dir, old_base, old_len, 
		new_dir, new_base, new_len, must_be_dir);
	/*up(&new_dir->i_sem);*/
	iput(new_dir);
	return error;
}

⌨️ 快捷键说明

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