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

📄 namei.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 3 页
字号:
	de->start = 0;	de->starthi = 0;	fat_date_unix2dos(dir->i_mtime,&de->time,&de->date);	de->ctime_ms = 0;	de->ctime = de->time;	de->adate = de->cdate = de->date;	de->size = 0;	fat_mark_buffer_dirty(sb, bh, 1);	if ((dot = iget(dir->i_sb,ino)) != NULL)		vfat_read_inode(dot);	if (!dot) return -EIO;	dot->i_mtime = dot->i_atime = CURRENT_TIME;	dot->i_dirt = 1;	if (isdot) {		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;	} else {		dot->i_size = parent->i_size;		MSDOS_I(dot)->i_start = MSDOS_I(parent)->i_start;		MSDOS_I(dot)->i_logstart = MSDOS_I(parent)->i_logstart;		dot->i_nlink = parent->i_nlink;	}	iput(dot);	PRINTK(("vfat_create_a_dotdir 2\n"));	return 0;}static int vfat_create_dotdirs(struct inode *dir, struct inode *parent){	struct super_block *sb = dir->i_sb;	int res;	struct buffer_head *bh;	struct msdos_dir_entry *de;	loff_t offset;	PRINTK(("vfat_create_dotdirs 1\n"));	if ((res = fat_add_cluster(dir)) < 0) return res;	PRINTK(("vfat_create_dotdirs 2\n"));	offset = 0;	bh = NULL;	if ((res = fat_get_entry(dir,&offset,&bh,&de)) < 0) return res;		PRINTK(("vfat_create_dotdirs 3\n"));	res = vfat_create_a_dotdir(dir, parent, bh, de, res, MSDOS_DOT, 1);	PRINTK(("vfat_create_dotdirs 4\n"));	if (res < 0) {		fat_brelse(sb, bh);		return res;	}	PRINTK(("vfat_create_dotdirs 5\n"));	if ((res = fat_get_entry(dir,&offset,&bh,&de)) < 0) {		fat_brelse(sb, bh);		return res;	}	PRINTK(("vfat_create_dotdirs 6\n"));	res = vfat_create_a_dotdir(dir, parent, bh, de, res, MSDOS_DOTDOT, 0);	PRINTK(("vfat_create_dotdirs 7\n"));	fat_brelse(sb, bh);	return res;}/***** See if directory is empty */static int vfat_empty(struct inode *dir){	struct super_block *sb = dir->i_sb;	loff_t pos;	struct buffer_head *bh;	struct msdos_dir_entry *de;	if (dir->i_count > 1)		return -EBUSY;	if (MSDOS_I(dir)->i_start) { /* may be zero in mkdir */		pos = 0;		bh = NULL;		while (fat_get_entry(dir,&pos,&bh,&de) > -1) {			/* Skip extended filename entries */			if (de->attr == ATTR_EXT) continue;			if (!IS_FREE(de->name) && strncmp(de->name,MSDOS_DOT,			    MSDOS_NAME) && strncmp(de->name,MSDOS_DOTDOT,			    MSDOS_NAME)) {				fat_brelse(sb, bh);				return -ENOTEMPTY;			}		}		if (bh)			fat_brelse(sb, bh);	}	return 0;}static int vfat_rmdir_free_ino(struct inode *dir,struct buffer_head *bh,     struct msdos_dir_entry *de,int ino){	struct super_block *sb = dir->i_sb;	struct inode *inode;	int res;	if (ino < 0) return -EINVAL;	if (!(inode = iget(dir->i_sb,ino))) return -ENOENT;	if (!S_ISDIR(inode->i_mode)) {		iput(inode);		return -ENOTDIR;	}	if (dir->i_dev != inode->i_dev || dir == inode) {		iput(inode);		return -EBUSY;	}	res = vfat_empty(inode);	if (res) {		iput(inode);		return res;	}	inode->i_nlink = 0;	inode->i_mtime = dir->i_mtime = CURRENT_TIME;	inode->i_atime = dir->i_atime = CURRENT_TIME;	dir->i_nlink--;	inode->i_dirt = dir->i_dirt = 1;	de->name[0] = DELETED_FLAG;	fat_mark_buffer_dirty(sb, bh, 1);	iput(inode);	return 0;}static int vfat_unlink_free_ino(struct inode *dir,struct buffer_head *bh,     struct msdos_dir_entry *de,int ino,int nospc){	struct super_block *sb = dir->i_sb;	struct inode *inode;	if (!(inode = iget(dir->i_sb,ino))) return -ENOENT;	if ((!S_ISREG(inode->i_mode) && nospc) || IS_IMMUTABLE(inode)) {		iput(inode);		return -EPERM;	}	inode->i_nlink = 0;	inode->i_mtime = dir->i_mtime = CURRENT_TIME;	inode->i_atime = dir->i_atime = CURRENT_TIME;	dir->i_version = ++event;	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);	iput(inode);	return 0;}static int vfat_remove_entry(struct inode *dir,struct slot_info *sinfo,     struct buffer_head **bh,struct msdos_dir_entry **de,     int is_dir,int nospc){	struct super_block *sb = dir->i_sb;	loff_t offset;	int res, i;	/* remove the shortname */	offset = sinfo->shortname_offset;	res = fat_get_entry(dir, &offset, bh, de);	if (res < 0) return res;	if (is_dir) {		res = vfat_rmdir_free_ino(dir,*bh,*de,res);	} else {		res = vfat_unlink_free_ino(dir,*bh,*de,res,nospc);	}	if (res < 0) return res;			/* remove the longname */	offset = sinfo->longname_offset;	for (i = sinfo->long_slots; i > 0; --i) {		res = fat_get_entry(dir, &offset, bh, de);		if (res < 0) {			printk("vfat_remove_entry: problem 1\n");			continue;		}		(*de)->name[0] = DELETED_FLAG;		(*de)->attr = 0;		fat_mark_buffer_dirty(sb, *bh, 1);	}	return 0;}static int vfat_rmdirx(struct inode *dir,const char *name,int len){	struct super_block *sb = dir->i_sb;	int res;	struct buffer_head *bh;	struct msdos_dir_entry *de;	struct slot_info sinfo;	bh = NULL;	res = -EPERM;	if (name[0] == '.' && (len == 1 || (len == 2 && name[1] == '.')))		goto rmdir_done;	res = vfat_find(dir,name,len,1,0,0,&sinfo);	if (res >= 0 && sinfo.total_slots > 0) {		res = vfat_remove_entry(dir,&sinfo,&bh,&de,1,0);		if (res > 0) {			res = 0;		}		dir->i_version = ++event;	}rmdir_done:	fat_brelse(sb, bh);	return res;}/***** Remove a directory */int vfat_rmdir(struct inode *dir,const char *name,int len){	int res;	res = vfat_rmdirx(dir, name, len);	iput(dir);	return res;}static int vfat_unlinkx(	struct inode *dir,	const char *name,	int len,	int nospc)	/* Flag special file ? */{	struct super_block *sb = dir->i_sb;	int res;	struct buffer_head *bh;	struct msdos_dir_entry *de;	struct slot_info sinfo;	bh = NULL;	res = vfat_find(dir,name,len,1,0,0,&sinfo);	if (res >= 0 && sinfo.total_slots > 0) {		res = vfat_remove_entry(dir,&sinfo,&bh,&de,0,nospc);		if (res > 0) {			res = 0;		}	}	fat_brelse(sb, bh);	return res;}int vfat_mkdir(struct inode *dir,const char *name,int len,int mode){	struct inode *inode;	int res;	fat_lock_creation();	if ((res = vfat_create_entry(dir,name,len,1,&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 */	res = vfat_create_dotdirs(inode, dir);	fat_unlock_creation();	MSDOS_I(inode)->i_busy = 0;	iput(inode);	iput(dir);	if (res < 0) {		if (vfat_rmdir(dir,name,len) < 0)			fat_fs_panic(dir->i_sb,"rmdir in mkdir failed");	}	return res;}/***** Unlink, as called for msdosfs */int vfat_unlink(struct inode *dir,const char *name,int len){	int res;	res = vfat_unlinkx (dir,name,len,1);	iput(dir);	return res;}/***** Unlink, as called for uvfatfs */int vfat_unlink_uvfat(struct inode *dir,const char *name,int len){	int res;	res = vfat_unlinkx (dir,name,len,0);	iput(dir);	return res;} int vfat_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;	struct buffer_head *old_bh,*new_bh,*dotdot_bh;	struct msdos_dir_entry *old_de,*new_de,*dotdot_de;	loff_t old_offset,new_offset,old_longname_offset;	int old_slots,old_ino,new_ino,dotdot_ino,ino;	struct inode *old_inode, *new_inode, *dotdot_inode, *walk;	int res, is_dir, i;	int locked = 0;	struct slot_info sinfo;	PRINTK(("vfat_rename 1\n"));	if (old_dir == new_dir && old_len == new_len &&	    strncmp(old_name, new_name, old_len) == 0)		return 0;	old_bh = new_bh = NULL;	old_inode = new_inode = NULL;	res = vfat_find(old_dir,old_name,old_len,1,0,0,&sinfo);	PRINTK(("vfat_rename 2\n"));	if (res < 0) goto rename_done;	old_slots = sinfo.total_slots;	old_longname_offset = sinfo.longname_offset;	old_offset = sinfo.shortname_offset;	old_ino = sinfo.ino;	res = fat_get_entry(old_dir, &old_offset, &old_bh, &old_de);	PRINTK(("vfat_rename 3\n"));	if (res < 0) goto rename_done;	res = -ENOENT;	if (!(old_inode = iget(old_dir->i_sb,old_ino)))		goto rename_done;	is_dir = S_ISDIR(old_inode->i_mode);	if (must_be_dir && !is_dir)		goto rename_done;	if (is_dir) {		if ((old_dir->i_dev != new_dir->i_dev) ||		    (old_ino == new_dir->i_ino)) {			res = -EINVAL;			goto rename_done;		}		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) {				res = ino;				goto rename_done;			}			if (ino == old_ino) {				res = -EINVAL;				goto rename_done;			}			if (!(walk = iget(new_dir->i_sb,ino))) {				res = -EIO;				goto rename_done;			}		}		iput(walk);	}	res = vfat_find(new_dir,new_name,new_len,1,0,is_dir,&sinfo);	PRINTK(("vfat_rename 4\n"));	if (res > -1) {		int new_is_dir;		PRINTK(("vfat_rename 5\n"));		/* Filename currently exists.  Need to delete it */		new_offset = sinfo.shortname_offset;		res = fat_get_entry(new_dir, &new_offset, &new_bh, &new_de);		PRINTK(("vfat_rename 6\n"));		if (res < 0) goto rename_done;		if (!(new_inode = iget(new_dir->i_sb,res)))			goto rename_done;		new_is_dir = S_ISDIR(new_inode->i_mode);		iput(new_inode);		if (new_is_dir) {			PRINTK(("vfat_rename 7\n"));			res = vfat_rmdirx(new_dir,new_name,new_len);			PRINTK(("vfat_rename 8\n"));			if (res < 0) goto rename_done;		} else {			/* Is this the same file, different case? */			if (new_inode != old_inode) {				PRINTK(("vfat_rename 9\n"));				res = vfat_unlinkx(new_dir,new_name,new_len,1);				PRINTK(("vfat_rename 10\n"));				if (res < 0) goto rename_done;			}		}	}	PRINTK(("vfat_rename 11\n"));	fat_lock_creation(); locked = 1;	res = vfat_find(new_dir,new_name,new_len,1,1,is_dir,&sinfo);	PRINTK(("vfat_rename 12\n"));	if (res < 0) goto rename_done;	new_offset = sinfo.shortname_offset;	new_ino = sinfo.ino;	res = fat_get_entry(new_dir, &new_offset, &new_bh, &new_de);	PRINTK(("vfat_rename 13\n"));	if (res < 0) goto rename_done;	new_de->attr = old_de->attr;	new_de->time = old_de->time;	new_de->date = old_de->date;	new_de->ctime_ms = old_de->ctime_ms;	new_de->cdate = old_de->cdate;	new_de->adate = old_de->adate;	new_de->start = old_de->start;	new_de->starthi = old_de->starthi;	new_de->size = old_de->size;	if (!(new_inode = iget(new_dir->i_sb,new_ino))) goto rename_done;	PRINTK(("vfat_rename 14\n"));	/* At this point, we have the inodes of the old file and the	 * new file.  We need to transfer all information from the old	 * inode to the new inode and then delete the slots of the old	 * entry	 */	vfat_read_inode(new_inode);	MSDOS_I(old_inode)->i_busy = 1;	MSDOS_I(old_inode)->i_linked = new_inode;	MSDOS_I(new_inode)->i_oldlink = old_inode;	fat_cache_inval_inode(old_inode);	PRINTK(("vfat_rename 15: old_slots=%d\n",old_slots));	old_inode->i_dirt = 1;	old_dir->i_version = ++event;	/* remove the old entry */	for (i = old_slots; i > 0; --i) {		res = fat_get_entry(old_dir, &old_longname_offset, &old_bh, &old_de);		if (res < 0) {			printk("vfat_unlinkx: problem 1\n");			continue;		}		old_de->name[0] = DELETED_FLAG;		old_de->attr = 0;		fat_mark_buffer_dirty(sb, old_bh, 1);	}	PRINTK(("vfat_rename 15b\n"));	fat_mark_buffer_dirty(sb, new_bh, 1);	dcache_add(new_dir, new_name, new_len, new_ino);	/* XXX: There is some code in the original MSDOS rename that	 * is not duplicated here and it might cause a problem in	 * certain circumstances.	 */		if (S_ISDIR(old_inode->i_mode)) {		if ((res = 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);			res = -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);	}	if (res > 0) res = 0;rename_done:	if (locked)		fat_unlock_creation();	if (old_bh)		fat_brelse(sb, old_bh);	if (new_bh)		fat_brelse(sb, new_bh);	if (old_inode)		iput(old_inode);	iput(old_dir);	iput(new_dir);	return res;}/* Public inode operations for the VFAT fs */struct inode_operations vfat_dir_inode_operations = {	&fat_dir_operations,	/* default directory file-ops */	vfat_create,		/* create */	vfat_lookup,		/* lookup */	NULL,			/* link */	vfat_unlink,		/* unlink */	NULL,			/* symlink */	vfat_mkdir,		/* mkdir */	vfat_rmdir,		/* rmdir */	NULL,			/* mknod */	vfat_rename,		/* rename */	NULL,			/* readlink */	NULL,			/* follow_link */	NULL,			/* readpage */	NULL,			/* writepage */	fat_bmap,		/* bmap */	NULL,			/* truncate */	NULL			/* permission */};void vfat_read_inode(struct inode *inode){	fat_read_inode(inode, &vfat_dir_inode_operations);}#ifdef MODULEint init_module(void){	return init_vfat_fs();}void cleanup_module(void){	unregister_filesystem(&vfat_fs_type);}#endif /* ifdef MODULE *//* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only.  This must remain at the end * of the file. * --------------------------------------------------------------------------- * Local variables: * c-indent-level: 8 * c-brace-imaginary-offset: 0 * c-brace-offset: -8 * c-argdecl-indent: 8 * c-label-offset: -8 * c-continued-statement-offset: 8 * c-continued-brace-offset: 0 * End: */

⌨️ 快捷键说明

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