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

📄 namei.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 2 页
字号:
	de->name[0] = DELETED_FLAG;	fat_mark_buffer_dirty(sb, bh, 1);	res = 0;rmdir_done:	fat_brelse(sb, bh);	iput(dir);	iput(inode);	return res;}/***** Make a directory */int msdos_mkdir(struct inode *dir,const char *name,int len,int mode){	struct super_block *sb = dir->i_sb;	struct buffer_head *bh;	struct msdos_dir_entry *de;	struct inode *inode,*dot;	char msdos_name[MSDOS_NAME];	int ino,res,is_hid;	if ((res = msdos_format_name(MSDOS_SB(dir->i_sb)->options.name_check,				     name,len,msdos_name,0,				     MSDOS_SB(dir->i_sb)->options.dotsOK)) < 0) {		iput(dir);		return res;	}	is_hid = (name[0]=='.') && (msdos_name[0]!='.');	fat_lock_creation();	if (fat_scan(dir,msdos_name,&bh,&de,&ino,SCAN_ANY) >= 0) {		fat_unlock_creation();		fat_brelse(sb, bh);		iput(dir);		return -EEXIST; 	}	if ((res = msdos_create_entry(dir,msdos_name,len,1,is_hid,				      &inode)) < 0) {		fat_unlock_creation();		iput(dir);		return res;	}	dir->i_nlink++;	inode->i_nlink = 2; /* no need to mark them dirty */	MSDOS_I(inode)->i_busy = 1; /* prevent lookups */	if ((res = fat_add_cluster(inode)) < 0) goto mkdir_error;	if ((res = msdos_create_entry(inode,MSDOS_DOT,1,1,0,&dot)) < 0)		goto mkdir_error;	dot->i_size = inode->i_size; /* doesn't grow in the 2nd create_entry */	MSDOS_I(dot)->i_start = MSDOS_I(inode)->i_start;	MSDOS_I(dot)->i_logstart = MSDOS_I(inode)->i_logstart;	dot->i_nlink = inode->i_nlink;	dot->i_dirt = 1;	iput(dot);	if ((res = msdos_create_entry(inode,MSDOS_DOTDOT,2,1,0,&dot)) < 0)		goto mkdir_error;	fat_unlock_creation();	dot->i_size = dir->i_size;	MSDOS_I(dot)->i_start = MSDOS_I(dir)->i_start;	MSDOS_I(dot)->i_logstart = MSDOS_I(dir)->i_logstart;	dot->i_nlink = dir->i_nlink;	dot->i_dirt = 1;	MSDOS_I(inode)->i_busy = 0;	iput(dot);	iput(inode);	iput(dir);	return 0;mkdir_error:	iput(inode);	if (msdos_rmdir(dir,name,len) < 0)		fat_fs_panic(dir->i_sb,"rmdir in mkdir failed");	fat_unlock_creation();	return res;}/***** Unlink a file */static int msdos_unlinkx(	struct inode *dir,	const char *name,	int len,	int nospc)	/* Flag special file ? */{	struct super_block *sb = dir->i_sb;	int res,ino;	struct buffer_head *bh;	struct msdos_dir_entry *de;	struct inode *inode;	bh = NULL;	inode = NULL;	if ((res = msdos_find(dir,name,len,&bh,&de,&ino)) < 0)		goto unlink_done;	if (!(inode = iget(dir->i_sb,ino))) {		res = -ENOENT;		goto unlink_done;	}	if (!S_ISREG(inode->i_mode) && nospc){		res = -EPERM;		goto unlink_done;	}	if (IS_IMMUTABLE(inode)){		res = -EPERM;		goto unlink_done;	}	inode->i_nlink = 0;	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;	MSDOS_I(inode)->i_busy = 1;	inode->i_dirt = dir->i_dirt = 1;	de->name[0] = DELETED_FLAG;	fat_mark_buffer_dirty(sb, bh, 1);unlink_done:	fat_brelse(sb, bh);	iput(inode);	iput(dir);	return res;}/***** Unlink, as called for msdosfs */int msdos_unlink(struct inode *dir,const char *name,int len){	return msdos_unlinkx (dir,name,len,1);}/***** Unlink, as called for umsdosfs */int msdos_unlink_umsdos(struct inode *dir,const char *name,int len){	return msdos_unlinkx (dir,name,len,0);}/***** Rename within a directory */static int rename_same_dir(struct inode *old_dir,char *old_name,int old_len,    struct inode *new_dir,char *new_name,int new_len,    struct buffer_head *old_bh,    struct msdos_dir_entry *old_de,int old_ino,int is_hid){	struct super_block *sb = old_dir->i_sb;	struct buffer_head *new_bh;	struct msdos_dir_entry *new_de;	struct inode *new_inode,*old_inode;	int new_ino,exists,error;	if (!strncmp(old_name,new_name,MSDOS_NAME)) goto set_hid;	exists = fat_scan(new_dir,new_name,&new_bh,&new_de,&new_ino,SCAN_ANY) >= 0;	if (*(unsigned char *) old_de->name == DELETED_FLAG) {		if (exists)			fat_brelse(sb, new_bh);		return -ENOENT;	}	if (exists) {		if (!(new_inode = iget(new_dir->i_sb,new_ino))) {			fat_brelse(sb, new_bh);			return -EIO;		}		error = S_ISDIR(new_inode->i_mode)			? (old_de->attr & ATTR_DIR)				? msdos_empty(new_inode)				: -EPERM			: (old_de->attr & ATTR_DIR)				? -EPERM				: 0;		if (!error && (old_de->attr & ATTR_SYS)) error = -EPERM;		if (error) {			iput(new_inode);			fat_brelse(sb, new_bh);			return error;		}		if (S_ISDIR(new_inode->i_mode)) {			new_dir->i_nlink--;			new_dir->i_dirt = 1;		}		new_inode->i_nlink = 0;		MSDOS_I(new_inode)->i_busy = 1;		new_inode->i_dirt = 1;		new_de->name[0] = DELETED_FLAG;		fat_mark_buffer_dirty(sb, new_bh, 1);		dcache_add(new_dir, new_name, new_len, new_ino);		iput(new_inode);		fat_brelse(sb, new_bh);	}	memcpy(old_de->name,new_name,MSDOS_NAME);set_hid:	old_de->attr = is_hid		? (old_de->attr | ATTR_HIDDEN)		: (old_de->attr &~ ATTR_HIDDEN);	fat_mark_buffer_dirty(sb, old_bh, 1);	/* update binary info for conversion, i_attrs */	if ((old_inode = iget(old_dir->i_sb,old_ino)) != NULL) {		MSDOS_I(old_inode)->i_attrs = is_hid			? (MSDOS_I(old_inode)->i_attrs |  ATTR_HIDDEN)			: (MSDOS_I(old_inode)->i_attrs &~ ATTR_HIDDEN);		iput(old_inode);	}	return 0;}/***** Rename across directories - a nonphysical move */static int rename_diff_dir(struct inode *old_dir,char *old_name,int old_len,    struct inode *new_dir,char *new_name,int new_len,    struct buffer_head *old_bh,    struct msdos_dir_entry *old_de,int old_ino,int is_hid){	struct super_block *sb = old_dir->i_sb;	struct buffer_head *new_bh,*free_bh,*dotdot_bh;	struct msdos_dir_entry *new_de,*free_de,*dotdot_de;	struct inode *old_inode,*new_inode,*free_inode,*dotdot_inode,*walk;	int new_ino,free_ino,dotdot_ino;	int error,exists,ino;	if (old_dir->i_dev != new_dir->i_dev) return -EINVAL;	if (old_ino == new_dir->i_ino) return -EINVAL;	if (!(walk = iget(new_dir->i_sb,new_dir->i_ino))) return -EIO;	/* prevent moving directory below itself */	while (walk->i_ino != MSDOS_ROOT_INO) {		ino = fat_parent_ino(walk,1);		iput(walk);		if (ino < 0) return ino;		if (ino == old_ino) return -EINVAL;		if (!(walk = iget(new_dir->i_sb,ino))) return -EIO;	}	iput(walk);	/* find free spot */	while ((error = fat_scan(new_dir,NULL,&free_bh,&free_de,&free_ino,	    SCAN_ANY)) < 0) {		if (error != -ENOENT) return error;		error = fat_add_cluster(new_dir);		if (error) return error;	}	exists = fat_scan(new_dir,new_name,&new_bh,&new_de,&new_ino,SCAN_ANY) >= 0;	if (!(old_inode = iget(old_dir->i_sb,old_ino))) {		fat_brelse(sb, free_bh);		if (exists)			fat_brelse(sb, new_bh);		return -EIO;	}	if (*(unsigned char *) old_de->name == DELETED_FLAG) {		iput(old_inode);		fat_brelse(sb, free_bh);		if (exists)			fat_brelse(sb, new_bh);		return -ENOENT;	}	new_inode = NULL; /* to make GCC happy */	if (exists) {  /* Trash the old file! */		if (!(new_inode = iget(new_dir->i_sb,new_ino))) {			iput(old_inode);			fat_brelse(sb, new_bh);			return -EIO;		}		error = S_ISDIR(new_inode->i_mode)			? (old_de->attr & ATTR_DIR)				? msdos_empty(new_inode)				: -EPERM			: (old_de->attr & ATTR_DIR)				? -EPERM				: 0;		if (!error && (old_de->attr & ATTR_SYS)) error = -EPERM;		if (error) {			iput(new_inode);			iput(old_inode);			fat_brelse(sb, new_bh);			return error;		}		new_inode->i_nlink = 0;		MSDOS_I(new_inode)->i_busy = 1;		new_inode->i_dirt = 1;		new_de->name[0] = DELETED_FLAG;		fat_mark_buffer_dirty(sb, new_bh, 1);	}	memcpy(free_de,old_de,sizeof(struct msdos_dir_entry));	memcpy(free_de->name,new_name,MSDOS_NAME);	free_de->attr = is_hid		? (free_de->attr|ATTR_HIDDEN)		: (free_de->attr&~ATTR_HIDDEN);	if (!(free_inode = iget(new_dir->i_sb,free_ino))) {		free_de->name[0] = DELETED_FLAG;/*  Don't mark free_bh as dirty. Both states are supposed to be equivalent. */		fat_brelse(sb, free_bh);		if (exists) {			iput(new_inode);			fat_brelse(sb, new_bh);		}		return -EIO;	}	if (exists && S_ISDIR(new_inode->i_mode)) {		new_dir->i_nlink--;		new_dir->i_dirt = 1;	}	msdos_read_inode(free_inode);	MSDOS_I(old_inode)->i_busy = 1;	MSDOS_I(old_inode)->i_linked = free_inode;	MSDOS_I(free_inode)->i_oldlink = old_inode;	fat_cache_inval_inode(old_inode);	old_inode->i_dirt = 1;	old_de->name[0] = DELETED_FLAG;	fat_mark_buffer_dirty(sb, old_bh, 1);	fat_mark_buffer_dirty(sb, free_bh, 1);	if (exists) {		MSDOS_I(new_inode)->i_depend = free_inode;		MSDOS_I(free_inode)->i_old = new_inode;		/* Two references now exist to free_inode so increase count */		free_inode->i_count++;		/* free_inode is put after putting new_inode and old_inode */		iput(new_inode);		dcache_add(new_dir, new_name, new_len, new_ino);		fat_brelse(sb, new_bh);	}	if (S_ISDIR(old_inode->i_mode)) {		if ((error = fat_scan(old_inode,MSDOS_DOTDOT,&dotdot_bh,		    &dotdot_de,&dotdot_ino,SCAN_ANY)) < 0) goto rename_done;		if (!(dotdot_inode = iget(old_inode->i_sb,dotdot_ino))) {			fat_brelse(sb, dotdot_bh);			error = -EIO;			goto rename_done;		}		MSDOS_I(dotdot_inode)->i_start = MSDOS_I(new_dir)->i_start;		MSDOS_I(dotdot_inode)->i_logstart = MSDOS_I(new_dir)->i_logstart;		dotdot_de->start = CT_LE_W(MSDOS_I(new_dir)->i_logstart);		dotdot_de->starthi = CT_LE_W((MSDOS_I(new_dir)->i_logstart) >> 16);		dotdot_inode->i_dirt = 1;		fat_mark_buffer_dirty(sb, dotdot_bh, 1);		old_dir->i_nlink--;		new_dir->i_nlink++;		/* no need to mark them dirty */		dotdot_inode->i_nlink = new_dir->i_nlink;		iput(dotdot_inode);		fat_brelse(sb, dotdot_bh);	}	error = 0;rename_done:	fat_brelse(sb, free_bh);	iput(old_inode);	return error;}/***** Rename, a wrapper for rename_same_dir & rename_diff_dir */int msdos_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 super_block *sb = old_dir->i_sb;	char old_msdos_name[MSDOS_NAME],new_msdos_name[MSDOS_NAME];	struct buffer_head *old_bh;	struct msdos_dir_entry *old_de;	int old_ino,error;	int is_hid,old_hid; /* if new file and old file are hidden */	if ((error = msdos_format_name(MSDOS_SB(old_dir->i_sb)->options.name_check,				       old_name,old_len,old_msdos_name,1,				       MSDOS_SB(old_dir->i_sb)->options.dotsOK))	    < 0) goto rename_done;	if ((error = msdos_format_name(MSDOS_SB(new_dir->i_sb)->options.name_check,				       new_name,new_len,new_msdos_name,0,				       MSDOS_SB(new_dir->i_sb)->options.dotsOK))	    < 0) goto rename_done;	is_hid = (new_name[0]=='.') && (new_msdos_name[0]!='.');	old_hid = (old_name[0]=='.') && (old_msdos_name[0]!='.');	if ((error = fat_scan(old_dir,old_msdos_name,&old_bh,&old_de,	    &old_ino,old_hid?SCAN_HID:SCAN_NOTHID)) < 0) goto rename_done;	fat_lock_creation();	if (old_dir == new_dir)		error = rename_same_dir(old_dir,old_msdos_name,old_len,new_dir,		    new_msdos_name,new_len,old_bh,old_de,old_ino,is_hid);	else error = rename_diff_dir(old_dir,old_msdos_name,old_len,new_dir,		    new_msdos_name,new_len,old_bh,old_de,old_ino,is_hid);	fat_unlock_creation();	fat_brelse(sb, old_bh);rename_done:	iput(old_dir);	iput(new_dir);	return error;}/* The public inode operations for the msdos fs */struct inode_operations msdos_dir_inode_operations = {	&fat_dir_operations,	/* default directory file-ops */	msdos_create,		/* create */	msdos_lookup,		/* lookup */	NULL,			/* link */	msdos_unlink,		/* unlink */	NULL,			/* symlink */	msdos_mkdir,		/* mkdir */	msdos_rmdir,		/* rmdir */	NULL,			/* mknod */	msdos_rename,		/* rename */	NULL,			/* readlink */	NULL,			/* follow_link */	NULL,			/* readpage */	NULL,			/* writepage */	fat_bmap,		/* bmap */	NULL,			/* truncate */	NULL			/* permission */};void msdos_read_inode(struct inode *inode){	fat_read_inode(inode, &msdos_dir_inode_operations);}#ifdef MODULEint init_module(void){	return init_msdos_fs();}void cleanup_module(void){	unregister_filesystem(&msdos_fs_type);}#endif

⌨️ 快捷键说明

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