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

📄 namei.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 2 页
字号:
{	struct buffer_head	*bh;	struct inode		*inode;	char			*p;	unsigned long		 tmp;	int			 i, maxlen;	char			 c, lc;	pr_debug("AFFS: symlink(%lu,\"%.*s\" -> \"%s\")\n",dir->i_ino,len,name,symname);		maxlen = 4 * AFFS_I2HSIZE(dir) - 1;	inode  = affs_new_inode(dir);	if (!inode) {		iput(dir);		return -ENOSPC;	}	inode->i_op   = &affs_symlink_inode_operations;	inode->i_mode = S_IFLNK | 0777;	inode->u.affs_i.i_protect = mode_to_prot(inode->i_mode);	bh = affs_bread(inode->i_dev,inode->i_ino,AFFS_I2BSIZE(inode));	if (!bh) {		iput(dir);		inode->i_nlink = 0;		inode->i_dirt  = 1;		iput(inode);		return -EIO;	}	i  = 0;	p  = ((struct slink_front *)bh->b_data)->symname;	lc = '/';	if (*symname == '/') {		while (*symname == '/')			symname++;		while (inode->i_sb->u.affs_sb.s_volume[i])	/* Cannot overflow */			*p++ = inode->i_sb->u.affs_sb.s_volume[i++];	}	while (i < maxlen && (c = *symname++)) {		if (c == '.' && lc == '/' && *symname == '.' && symname[1] == '/') {			*p++ = '/';			i++;			symname += 2;			lc = '/';		} else if (c == '.' && lc == '/' && *symname == '/') {			symname++;			lc = '/';		} else {			*p++ = c;			lc   = c;			i++;		}		if (lc == '/')			while (*symname == '/')				symname++;	}	*p = 0;	mark_buffer_dirty(bh,1);	affs_brelse(bh);	inode->i_dirt = 1;	bh = affs_find_entry(dir,name,len,&tmp);	if (bh) {		inode->i_nlink = 0;		iput(inode);		affs_brelse(bh);		iput(dir);		return -EEXIST;	}	i = affs_add_entry(dir,NULL,inode,name,len,ST_SOFTLINK);	if (i) {		inode->i_nlink = 0;		inode->i_dirt  = 1;		iput(inode);		affs_brelse(bh);		iput(dir);		return i;	}	iput(dir);	iput(inode);		return 0;}intaffs_link(struct inode *oldinode, struct inode *dir, const char *name, int len){	struct inode		*inode;	struct buffer_head	*bh;	unsigned long		 i;	int			 error;		pr_debug("AFFS: link(%lu,%lu,\"%.*s\")\n",oldinode->i_ino,dir->i_ino,len,name);	bh = affs_find_entry(dir,name,len,&i);	if (bh) {		affs_brelse(bh);		iput(oldinode);		iput(dir);		return -EEXIST;	}	if (oldinode->u.affs_i.i_hlink) {		i = oldinode->u.affs_i.i_original;		iput(oldinode);		oldinode = iget(dir->i_sb,i);		if (!oldinode) {			printk("AFFS: link(): original does not exist.\n");			iput(dir);			return -ENOENT;		}	}	inode = affs_new_inode(dir);	if (!inode) {		iput(oldinode);		iput(dir);		return -ENOSPC;	}	inode->i_op                = oldinode->i_op;	inode->i_mode              = oldinode->i_mode;	inode->i_uid               = oldinode->i_uid;	inode->i_gid               = oldinode->i_gid;	inode->u.affs_i.i_protect  = mode_to_prot(inode->i_mode);	inode->u.affs_i.i_original = oldinode->i_ino;	inode->u.affs_i.i_hlink    = 1;	if (S_ISDIR(oldinode->i_mode))		error = affs_add_entry(dir,oldinode,inode,name,len,ST_LINKDIR);	else		error = affs_add_entry(dir,oldinode,inode,name,len,ST_LINKFILE);	if (error) {		inode->i_nlink = 0;		inode->i_dirt  = 1;	}	iput(dir);	iput(inode);	iput(oldinode);	return error;}static intsubdir(struct inode * new_inode, struct inode * old_inode){    int ino;    int result;    new_inode->i_count++;    result = 0;    for (;;) {        if (new_inode == old_inode) {	    result = 1;	    break;	}	if (new_inode->i_dev != old_inode->i_dev)	    break;	ino = new_inode->i_ino;	if (affs_lookup(new_inode,"..",2,&new_inode))	    break;	if (new_inode->i_ino == ino)	    break;    }    iput(new_inode);    return result;}/* I'm afraid this might not be race proof. Maybe next time. */intaffs_rename(struct inode *old_dir, const char *old_name, int old_len,	    struct inode *new_dir, const char *new_name, int new_len,	    int must_be_dir){	struct inode		*old_inode;	struct inode		*new_inode;	struct buffer_head	*old_bh;	struct buffer_head	*new_bh;	unsigned long		 old_ino;	unsigned long		 new_ino;	int			 retval;	pr_debug("AFFS: rename(old=%lu,\"%*s\" to new=%lu,\"%*s\")\n",old_dir->i_ino,old_len,old_name,		 new_dir->i_ino,new_len,new_name);		if (new_len > 30)		new_len = 30;	goto start_up;retry:	affs_brelse(old_bh);	affs_brelse(new_bh);	iput(new_inode);	iput(old_inode);	current->counter = 0;	schedule();start_up:	old_inode = new_inode = NULL;	old_bh    = new_bh = NULL;	retval    = -ENOENT;	old_bh = affs_find_entry(old_dir,old_name,old_len,&old_ino);	if (!old_bh)		goto end_rename;	old_inode = __iget(old_dir->i_sb,old_ino,0);	if (!old_inode)		goto end_rename;	if (must_be_dir && !S_ISDIR(old_inode->i_mode))		goto end_rename;	new_bh = affs_find_entry(new_dir,new_name,new_len,&new_ino);	if (new_bh) {		new_inode = __iget(new_dir->i_sb,new_ino,0);		if (!new_inode) {		/* What does this mean? */			affs_brelse(new_bh);			new_bh = NULL;		}	}	if (new_inode == old_inode) {		/* Won't happen */		retval = 0;		goto end_rename;	}	if (new_inode && S_ISDIR(new_inode->i_mode)) {		retval = -EISDIR;		if (!S_ISDIR(old_inode->i_mode))			goto end_rename;		retval = -EINVAL;		if (subdir(new_dir,old_inode))			goto end_rename;		retval = -ENOTEMPTY;		if (!empty_dir(new_bh,AFFS_I2HSIZE(new_inode)))			goto end_rename;		retval = -EBUSY;		if (new_inode->i_count > 1)			goto end_rename;	}	if (S_ISDIR(old_inode->i_mode)) {		retval = -ENOTDIR;		if (new_inode && !S_ISDIR(new_inode->i_mode))			goto end_rename;		retval = -EINVAL;		if (subdir(new_dir,old_inode))			goto end_rename;		if (affs_parent_ino(old_inode) != old_dir->i_ino)			goto end_rename;	}	/* Unlink destination if existent */	if (new_inode) {		if ((retval = affs_fix_hash_pred(new_dir,affs_hash_name(new_name,new_len,		                                 AFFS_I2FSTYPE(new_dir),AFFS_I2HSIZE(new_dir)) + 6,						 new_ino,						 FILE_END(new_bh->b_data,new_dir)->hash_chain)))			goto retry;		if ((retval = affs_fixup(new_bh,new_inode)))			goto retry;		mark_buffer_dirty(new_bh,1);		new_dir->i_version = ++event;		new_dir->i_dirt    = 1;		new_inode->i_nlink = 0;		new_inode->i_dirt  = 1;	}	retval = affs_fix_hash_pred(old_dir,affs_hash_name(old_name,old_len,AFFS_I2FSTYPE(old_dir),				    AFFS_I2HSIZE(old_dir)) + 6,old_ino,				    FILE_END(old_bh->b_data,old_dir)->hash_chain);	if (retval)		goto retry;	retval = affs_add_entry(new_dir,NULL,old_inode,new_name,new_len,				htonl(FILE_END(old_bh->b_data,old_dir)->secondary_type));	new_dir->i_ctime   = new_dir->i_mtime = old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;	new_dir->i_version = ++event;	old_dir->i_version = ++event;	new_dir->i_dirt    = 1;	old_dir->i_dirt    = 1;	mark_buffer_dirty(old_bh,1);	end_rename:	affs_brelse(old_bh);	affs_brelse(new_bh);	iput(new_inode);	iput(old_inode);	iput(old_dir);	iput(new_dir);	return retval;}intaffs_fixup(struct buffer_head *bh, struct inode *inode){	int			 key, link_key;	int			 type;	struct buffer_head	*nbh;	struct inode		*ofinode;	type = htonl(FILE_END(bh->b_data,inode)->secondary_type);	if (type == ST_LINKFILE || type == ST_LINKDIR) {		key = htonl(LINK_END(bh->b_data,inode)->original);		LINK_END(bh->b_data,inode)->original = 0;		if (!key) {			printk("AFFS: fixup(): hard link without original: ino=%lu\n",inode->i_ino);			return -ENOENT;		}		if (!(ofinode = iget(inode->i_sb,key)))			return -ENOENT;		type = affs_fix_link_pred(ofinode,inode->i_ino,					  FILE_END(bh->b_data,inode)->link_chain);		iput(ofinode);		return type;	} else if (type == ST_FILE || type == ST_USERDIR) {		if ((key = htonl(FILE_END(bh->b_data,inode)->link_chain))) {			/* Get first link, turn it to a file */			if (!(ofinode = iget(inode->i_sb,key))) {				printk("AFFS: fixup(): cannot read inode %u\n",key);				return -ENOENT;			}			if (!ofinode->u.affs_i.i_hlink) {				printk("AFFS: fixup(): first link to %lu (%u) is not a link?\n",					inode->i_ino,key);				iput(ofinode);				return -ENOENT;			}			if (!(nbh = affs_bread(inode->i_dev,key,AFFS_I2BSIZE(inode)))) {				printk("AFFS: fixup(): cannot read block %u\n",key);				iput(ofinode);				return -ENOENT;			}			lock_super(inode->i_sb);			memcpy(nbh->b_data + 8,bh->b_data + 8,AFFS_I2BSIZE(inode) - 208);			FILE_END(nbh->b_data,inode)->byte_size = FILE_END(bh->b_data,inode)->									  byte_size;			FILE_END(nbh->b_data,inode)->extension = FILE_END(bh->b_data,inode)->									  extension;			FILE_END(nbh->b_data,inode)->secondary_type = FILE_END(bh->b_data,inode)->									  secondary_type;			FILE_END(nbh->b_data,inode)->original = 0;			ofinode->u.affs_i.i_original = 0;			ofinode->u.affs_i.i_hlink    = 0;			ofinode->i_size              = inode->i_size;			ofinode->i_uid               = inode->i_uid;			ofinode->i_gid               = inode->i_gid;			ofinode->i_dirt              = 1;			link_key                     = ofinode->i_ino;			/* Let all remaining links point to the new file */			while (1) {				affs_fix_checksum(AFFS_I2BSIZE(inode),nbh->b_data,5);				mark_buffer_dirty(nbh,1);				key = htonl(FILE_END(nbh->b_data,inode)->link_chain);				affs_brelse(nbh);				iput(ofinode);				if (!key || !(nbh = affs_bread(inode->i_dev,key,AFFS_I2BSIZE(inode))))					break;				if ((ofinode = iget(inode->i_sb,key))) {					if (!ofinode->u.affs_i.i_hlink)						printk("AFFS: fixup() inode %u in link chain is "						       "not a link\n",key);					ofinode->u.affs_i.i_original = link_key;					ofinode->i_dirt              = 1;					FILE_END(nbh->b_data,inode)->original = htonl(link_key);				} else					printk("AFFS: fixup(): cannot get inode %u\n",key);			}			/* Turn old inode to a link */			inode->u.affs_i.i_hlink = 1;			unlock_super(inode->i_sb);		}		return 0;	} else if (type == ST_SOFTLINK) {		return 0;	} else {		printk("AFFS: fixup(): secondary type=%d\n",type);		return -EBADF;	}}

⌨️ 快捷键说明

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