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

📄 namei.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  linux/fs/affs/namei.c * *  (c) 1996  Hans-Joachim Widmaier - Rewritten * *  (C) 1993  Ray Burr - Modified for Amiga FFS filesystem. * *  (C) 1991  Linus Torvalds - minix filesystem */#include <linux/sched.h>#include <linux/affs_fs.h>#include <linux/kernel.h>#include <linux/string.h>#include <linux/stat.h>#include <linux/fcntl.h>#include <linux/locks.h>#include <linux/amigaffs.h>#include <asm/segment.h>#include <linux/errno.h>/* Simple toupper() for DOS\1 */static inline unsigned intaffs_toupper(unsigned int ch){	return ch >= 'a' && ch <= 'z' ? ch -= ('a' - 'A') : ch;}/* International toupper() for DOS\3 */static inline unsigned intaffs_intl_toupper(unsigned int ch){	return (ch >= 'a' && ch <= 'z') || (ch >= 0xE0		&& ch <= 0xFE && ch != 0xF7) ?		ch - ('a' - 'A') : ch;}/* * NOTE! unlike strncmp, affs_match returns 1 for success, 0 for failure. */static intaffs_match(const char *name, int len, const char *compare, int dlen, int intl){	if (!compare)		return 0;	if (len > 30)		len = 30;	if (dlen > 30)		dlen = 30;	/* "" means "." ---> so paths like "/usr/lib//libc.a" work */	if (!len && dlen == 1 && compare[0] == '.')		return 1;	if (dlen != len)		return 0;	if (intl) {		while (dlen--) {			if (affs_intl_toupper(*name & 0xFF) != affs_intl_toupper(*compare & 0xFF))				return 0;			name++;			compare++;		}	} else {		while (dlen--) {			if (affs_toupper(*name & 0xFF) != affs_toupper(*compare & 0xFF))				return 0;			name++;			compare++;		}	}	return 1;}intaffs_hash_name(const char *name, int len, int intl, int hashsize){	unsigned int i, x;	if (len > 30)		len = 30;	x = len;	for (i = 0; i < len; i++)		if (intl)			x = (x * 13 + affs_intl_toupper(name[i] & 0xFF)) & 0x7ff;		else			x = (x * 13 + affs_toupper(name[i] & 0xFF)) & 0x7ff;	return x % hashsize;}static struct buffer_head *affs_find_entry(struct inode *dir, const char *name, int namelen,		unsigned long *ino){	struct buffer_head *bh;	int	 intl;	int	 key;	pr_debug("AFFS: find_entry(%.*s)=\n",namelen,name);	intl = AFFS_I2FSTYPE(dir);	bh   = affs_bread(dir->i_dev,dir->i_ino,AFFS_I2BSIZE(dir));	if (!bh)		return NULL;	if (affs_match(name,namelen,".",1,intl)) {		*ino = dir->i_ino;		return bh;	}	if (affs_match(name,namelen,"..",2,intl)) {		*ino = affs_parent_ino(dir);		return bh;	}	key = AFFS_GET_HASHENTRY(bh->b_data,affs_hash_name(name,namelen,intl,AFFS_I2HSIZE(dir)));	for (;;) {		char *cname;		int cnamelen;		affs_brelse(bh);		if (key == 0) {			bh = NULL;			break;		}		bh = affs_bread(dir->i_dev,key,AFFS_I2BSIZE(dir));		if (!bh)			break;		cnamelen = affs_get_file_name(AFFS_I2BSIZE(dir),bh->b_data,&cname);		if (affs_match(name,namelen,cname,cnamelen,intl))			break;		key = htonl(FILE_END(bh->b_data,dir)->hash_chain);	}	*ino = key;	return bh;}intaffs_lookup(struct inode *dir, const char *name, int len, struct inode **result){	int res;	unsigned long ino;	struct buffer_head *bh;	pr_debug("AFFS: lookup(%.*s)\n",len,name);	*result = NULL;	if (!dir)		return -ENOENT;	res = -ENOENT;	if (S_ISDIR(dir->i_mode)) {		if ((bh = affs_find_entry(dir,name,len,&ino))) {			if (FILE_END(bh->b_data,dir)->original)				ino = htonl(FILE_END(bh->b_data,dir)->original);			affs_brelse(bh);			if ((*result = iget(dir->i_sb,ino))) 				res = 0;			else				res = -EACCES;		}	}	iput(dir);	return res;}intaffs_unlink(struct inode *dir, const char *name, int len){	int			 retval;	struct buffer_head	*bh;	unsigned long		 ino;	struct inode		*inode;	pr_debug("AFFS: unlink(dir=%ld,\"%.*s\")\n",dir->i_ino,len,name);	bh      = NULL;	inode   = NULL;	retval  = -ENOENT;	if (!(bh = affs_find_entry(dir,name,len,&ino))) {		goto unlink_done;	}	if (!(inode = iget(dir->i_sb,ino))) {		goto unlink_done;	}	if (S_ISDIR(inode->i_mode)) {		retval = -EPERM;		goto unlink_done;	}	if ((retval = affs_fix_hash_pred(dir,affs_hash_name(name,len,AFFS_I2FSTYPE(dir),					 AFFS_I2HSIZE(dir)) + 6,ino,					 FILE_END(bh->b_data,dir)->hash_chain)))		goto unlink_done;	if ((retval = affs_fixup(bh,inode)))		goto unlink_done;	inode->i_nlink=0;	inode->i_dirt=1;	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;	dir->i_version = ++event;	dir->i_dirt=1;unlink_done:	affs_brelse(bh);	iput(inode);	iput(dir);	return retval;}intaffs_create(struct inode *dir, const char *name, int len, int mode, struct inode **result){	struct inode	*inode;	int		 error;		pr_debug("AFFS: create(%lu,\"%.*s\",0%o)\n",dir->i_ino,len,name,mode);	*result = NULL;	if (!dir || !dir->i_sb) {		iput(dir);		return -EINVAL;	}	inode = affs_new_inode(dir);	if (!inode) {		iput (dir);		return -ENOSPC;	}	inode->i_mode = mode;	if (dir->i_sb->u.affs_sb.s_flags & SF_OFS)		inode->i_op = &affs_file_inode_operations_ofs;	else		inode->i_op = &affs_file_inode_operations;	error = affs_add_entry(dir,NULL,inode,name,len,ST_FILE);	if (error) {		iput(dir);		inode->i_nlink = 0;		inode->i_dirt  = 1;		iput(inode);		return -ENOSPC;	}	inode->u.affs_i.i_protect = mode_to_prot(inode->i_mode);	iput(dir);	*result = inode;	return 0;}intaffs_mkdir(struct inode *dir, const char *name, int len, int mode){	struct inode		*inode;	struct buffer_head	*bh;	unsigned long		 i;	int			 error;		pr_debug("AFFS: mkdir(%lu,\"%.*s\",0%o)\n",dir->i_ino,len,name,mode);	if (!dir || !dir->i_sb) {		iput(dir);		return -EINVAL;	}	bh = affs_find_entry(dir,name,len,&i);	if (bh) {		affs_brelse(bh);		iput(dir);		return -EEXIST;	}	inode = affs_new_inode(dir);	if (!inode) {		iput (dir);		return -ENOSPC;	}	inode->i_op = &affs_dir_inode_operations;	error       = affs_add_entry(dir,NULL,inode,name,len,ST_USERDIR);	if (error) {		iput(dir);		inode->i_nlink = 0;		inode->i_dirt  = 1;		iput(inode);		return error;	}	inode->i_mode = S_IFDIR | (mode & 0777 & ~current->fs->umask);	inode->u.affs_i.i_protect = mode_to_prot(inode->i_mode);	iput(dir);	iput(inode);	return 0;}static intempty_dir(struct buffer_head *bh, int hashsize){	while (--hashsize >= 0) {		if (((struct dir_front *)bh->b_data)->hashtable[hashsize])			return 0;	}	return 1;}intaffs_rmdir(struct inode *dir, const char *name, int len){	int			 retval;	unsigned long		 ino;	struct inode		*inode;	struct buffer_head	*bh;	pr_debug("AFFS: rmdir(dir=%lu,\"%.*s\")\n",dir->i_ino,len,name);	inode  = NULL;	retval = -ENOENT;	if (!(bh = affs_find_entry(dir,name,len,&ino))) {		goto rmdir_done;	}	if (!(inode = iget(dir->i_sb,ino))) {		goto rmdir_done;	}	retval = -EPERM;        if (!fsuser() && current->fsuid != inode->i_uid &&            current->fsuid != dir->i_uid)		goto rmdir_done;	if (inode->i_dev != dir->i_dev)		goto rmdir_done;	if (inode == dir)	/* we may not delete ".", but "../dir" is ok */		goto rmdir_done;	if (!S_ISDIR(inode->i_mode)) {		retval = -ENOTDIR;		goto rmdir_done;	}	if (!empty_dir(bh,AFFS_I2HSIZE(inode))) {		retval = -ENOTEMPTY;		goto rmdir_done;	}	if (inode->i_count > 1) {		retval = -EBUSY;		goto rmdir_done;	}	if ((retval = affs_fix_hash_pred(dir,affs_hash_name(name,len,AFFS_I2FSTYPE(dir),					 AFFS_I2HSIZE(dir)) + 6,ino,					 FILE_END(bh->b_data,dir)->hash_chain)))		goto rmdir_done;	if ((retval = affs_fixup(bh,inode)))		goto rmdir_done;	inode->i_nlink=0;	inode->i_dirt=1;	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;	dir->i_version = ++event;	dir->i_dirt=1;rmdir_done:	iput(dir);	iput(inode);	affs_brelse(bh);	return retval;}intaffs_symlink(struct inode *dir, const char *name, int len, const char *symname)

⌨️ 快捷键说明

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