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

📄 namei.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 3 页
字号:
chkstk();							if (ret == 0){								/*								   This UMSDOS_lookup does not look very useful.								   It makes sure that the inode of the file will								   be correctly setup (umsdos_patch_inode()) in								   case it is already in use.								   								   Not very efficient ...								   */								struct inode *inode;								new_dir->i_count++;								PRINTK (("rename lookup len %d %d -- ",new_len,new_info.entry.flags));								ret = UMSDOS_lookup (new_dir,new_name,new_len										     ,&inode);chkstk();								if (ret != 0){									printk ("UMSDOS: partial rename for file %s\n"										,new_info.entry.name);								}else{									/*									   Update f_pos so notify_change will succeed									   if the file was already in use.									   */									umsdos_set_dirinfo (inode,new_dir,new_info.f_pos);chkstk();									iput (inode);								}							}						}					}				}else{					/* sticky bit set on new_dir */					PRINTK(("sticky set on new "));					ret = -EPERM;				}			}else{				/* sticky bit set on old_dir */				PRINTK(("sticky set on old "));				ret = -EPERM;			}		}		umsdos_unlockcreate(old_dir);		umsdos_unlockcreate(new_dir);	}	iput (old_dir);	iput (new_dir);	PRINTK (("\n"));	return ret;}/*	Setup un Symbolic link or a (pseudo) hard link	Return a negative error code or 0 if ok.*/static int umsdos_symlink_x(	struct inode * dir,	const char * name,	int len,	const char * symname,	/* name will point to this path */	int mode,	char flags){	/* #Specification: symbolic links / strategy		A symbolic link is simply a file which hold a path. It is		implemented as a normal MSDOS file (not very space efficient :-()		I see 2 different way to do it. One is to place the link data		in unused entry of the EMD file. The other is to have a separate		file dedicated to hold all symbolic links data.		Let's go for simplicity...	*/	struct inode *inode;	int ret;	dir->i_count++;		/* We keep the inode in case we need it */						/* later */	ret = umsdos_create_any (dir,name,len,mode,0,flags,&inode);	PRINTK (("umsdos_symlink ret %d ",ret));	if (ret == 0){		int len = strlen(symname);		struct file filp;		filp.f_pos = 0;		/* Make the inode acceptable to MSDOS */		ret = umsdos_file_write_kmem (inode,&filp,symname,len);		iput (inode);		if (ret >= 0){			if (ret != len){				ret = -EIO;				printk ("UMSDOS: "					"Can't write symbolic link data\n");			}else{				ret = 0;			}		}		if (ret != 0){			UMSDOS_unlink (dir,name,len);			dir = NULL;		}	}	iput (dir);	PRINTK (("\n"));	return ret;}/*	Setup un Symbolic link.	Return a negative error code or 0 if ok.*/int UMSDOS_symlink(	struct inode * dir,	const char * name,	int len,	const char * symname)	/* name will point to this path */{	return umsdos_symlink_x (dir,name,len,symname,S_IFLNK|0777,0);}/*	Add a link to an inode in a directory*/int UMSDOS_link (	struct inode * oldinode,	struct inode * dir,	const char * name,	int len){	/* #Specification: hard link / strategy		Well ... hard link are difficult to implement on top of an		MsDOS fat file system. Unlike UNIX file systems, there are no		inode. A directory entry hold the functionality of the inode		and the entry.		We will used the same strategy as a normal Unix file system		(with inode) except we will do it symbolically (using paths).		Because anything can happen during a DOS session (defragment,		directory sorting, etc...), we can't rely on MsDOS pseudo		inode number to record the link. For this reason, the link		will be done using hidden symbolic links. The following		scenario illustrate how it work.				Given a file /foo/file		#			ln /foo/file /tmp/file2			become internally			mv /foo/file /foo/-LINK1			ln -s /foo/-LINK1 /foo/file			ln -s /foo/-LINK1 /tmp/file2		#		Using this strategy, we can operate on /foo/file or /foo/file2.		We can remove one and keep the other, like a normal Unix hard link.		We can rename /foo/file or /tmp/file2 independently.					The entry -LINK1 will be hidden. It will hold a link count.		When all link are erased, the hidden file is erased too.	*/	/* #Specification: weakness / hard link		The strategy for hard link introduces a side effect that		may or may not be acceptable. Here is the sequence		#		mkdir subdir1		touch subdir1/file		mkdir subdir2		ln    subdir1/file subdir2/file		rm    subdir1/file		rmdir subdir1		rmdir: subdir1: Directory not empty		#		This happen because there is an invisible file (--link) in		subdir1 which is referenced by subdir2/file.		Any idea ?	*/	/* #Specification: weakness / hard link / rename directory		Another weakness of hard link come from the fact that		it is based on hidden symbolic links. Here is an example.		#		mkdir /subdir1		touch /subdir1/file		mkdir /subdir2		ln    /subdir1/file subdir2/file		mv    /subdir1 subdir3		ls -l /subdir2/file		#		Since /subdir2/file is a hidden symbolic link		to /subdir1/..hlinkNNN, accessing it will fail since		/subdir1 does not exist anymore (has been renamed).	*/	int ret = 0;	if (S_ISDIR(oldinode->i_mode)){		/* #Specification: hard link / directory			A hard link can't be made on a directory. EPERM is returned			in this case.		*/		ret = -EPERM;	}else if ((ret = umsdos_nevercreat(dir,name,len,-EPERM))==0){		struct inode *olddir;		ret = umsdos_get_dirowner(oldinode,&olddir);		PRINTK (("umsdos_link dir_owner = %d -> %p [%d] "			,oldinode->u.umsdos_i.i_dir_owner,olddir,olddir->i_count));		if (ret == 0){			struct umsdos_dirent entry;			umsdos_lockcreate2(dir,olddir);			ret = umsdos_inode2entry (olddir,oldinode,&entry);			if (ret == 0){				PRINTK (("umsdos_link :%s: ino %d flags %d "					,entry.name					,oldinode->i_ino,entry.flags));				if (!(entry.flags & UMSDOS_HIDDEN)){					/* #Specification: hard link / first hard link						The first time a hard link is done on a file, this						file must be renamed and hidden. Then an internal						symbolic link must be done on the hidden file.						The second link is done after on this hidden file.						It is expected that the Linux MSDOS file system						keeps the same pseudo inode when a rename operation						is done on a file in the same directory.					*/					struct umsdos_info info;					ret = umsdos_newhidden (olddir,&info);					if (ret == 0){						olddir->i_count+=2;						PRINTK (("olddir[%d] ",olddir->i_count));						ret = umsdos_rename_f (olddir,entry.name							,entry.name_len							,olddir,info.entry.name,info.entry.name_len							,UMSDOS_HIDDEN);						if (ret == 0){							char *path = (char*)kmalloc(PATH_MAX,GFP_KERNEL);							if (path == NULL){								ret = -ENOMEM;							}else{								PRINTK (("olddir[%d] ",olddir->i_count));								ret = umsdos_locate_path (oldinode,path);								PRINTK (("olddir[%d] ",olddir->i_count));								if (ret == 0){									olddir->i_count++;									ret = umsdos_symlink_x (olddir										,entry.name										,entry.name_len,path										,S_IFREG|0777,UMSDOS_HLINK);									if (ret == 0){										dir->i_count++;										ret = umsdos_symlink_x (dir,name,len											,path											,S_IFREG|0777,UMSDOS_HLINK);									}								}								kfree (path);							}						}					}				}else{					char *path = (char*)kmalloc(PATH_MAX,GFP_KERNEL);					if (path == NULL){						ret = -ENOMEM;					}else{						ret = umsdos_locate_path (oldinode,path);						if (ret == 0){							dir->i_count++;							ret = umsdos_symlink_x (dir,name,len,path											,S_IFREG|0777,UMSDOS_HLINK);						}						kfree (path);					}				}			}			umsdos_unlockcreate(olddir);			umsdos_unlockcreate(dir);		}		iput (olddir);	}	if (ret == 0){		struct iattr newattrs;		oldinode->i_nlink++;		newattrs.ia_valid = 0;		ret = UMSDOS_notify_change(oldinode, &newattrs);	}	iput (oldinode);	iput (dir);	PRINTK (("umsdos_link %d\n",ret));	return ret;}/*	Add a new file into the alternate directory.	The file is added to the real MSDOS directory. If successful, it	is then added to the EDM file.	Return the status of the operation. 0 mean success.*/int UMSDOS_create (	struct inode *dir,	const char *name,		/* Name of the file to add */	int len,				/* Length of the name */	int mode,				/* Permission bit + file type ??? */	struct inode **result)	/* Will hold the inode of the newly created */							/* file */{	return umsdos_create_any (dir,name,len,mode,0,0,result);}/*	Add a sub-directory in a directory*/int UMSDOS_mkdir(	struct inode * dir,	const char * name,	int len,	int mode){	int ret = umsdos_nevercreat(dir,name,len,-EEXIST);	if (ret == 0){		struct umsdos_info info;		ret = umsdos_parse (name,len,&info);		PRINTK (("umsdos_mkdir %d\n",ret));		if (ret == 0){			info.entry.mode = mode | S_IFDIR;			info.entry.rdev = 0;			info.entry.uid = current->fsuid;			info.entry.gid = (dir->i_mode & S_ISGID)				? dir->i_gid : current->fsgid;			info.entry.ctime = info.entry.atime = info.entry.mtime				= CURRENT_TIME;			info.entry.flags = 0;			umsdos_lockcreate(dir);			info.entry.nlink = 1;			ret = umsdos_newentry (dir,&info);			PRINTK (("newentry %d ",ret));			if (ret == 0){				dir->i_count++;				ret = msdos_mkdir (dir,info.fake.fname,info.fake.len,mode);				if (ret != 0){					umsdos_delentry (dir,&info,1);					/* #Specification: mkdir / Directory already exist in DOS						We do the same thing as for file creation.						For all user it is an error.					*/				}else{					/* #Specification: mkdir / umsdos directory / create EMD						When we created a new sub-directory in a UMSDOS						directory (one with full UMSDOS semantic), we						create immediately an EMD file in the new						sub-directory so it inherit UMSDOS semantic.					*/					struct inode *subdir;					ret = umsdos_real_lookup (dir,info.fake.fname						,info.fake.len,&subdir);					if (ret == 0){						struct inode *result;						ret = msdos_create (subdir,UMSDOS_EMD_FILE							,UMSDOS_EMD_NAMELEN,S_IFREG|0777,&result);						subdir = NULL;						iput (result);					}					if (ret < 0){						printk ("UMSDOS: Can't create empty --linux-.---\n");					}					iput (subdir);				}

⌨️ 快捷键说明

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