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

📄 namei.c

📁 《嵌入式系统设计与实例开发实验教材二源码》Linux内核移植与编译实验
💻 C
📖 第 1 页 / 共 3 页
字号:
	de->size = 0;out_free:	free_page(page);	return res;}/* We can't get "." or ".." here - VFS takes care of those cases */static int vfat_build_slots(struct inode *dir, const char *name, int len,			    struct msdos_dir_slot *ds, int *slots, int is_dir){	int res, xlate;	xlate = MSDOS_SB(dir->i_sb)->options.unicode_xlate;	res = vfat_valid_longname(name, len, xlate);	if (res < 0)		return res;	return vfat_fill_slots(dir, ds, name, len, slots, is_dir, xlate);}static int vfat_add_entry(struct inode *dir,struct qstr* qname,			  int is_dir, struct vfat_slot_info *sinfo_out,			  struct buffer_head **bh, struct msdos_dir_entry **de){	struct super_block *sb = dir->i_sb;	struct msdos_dir_slot *dir_slots;	loff_t offset;	int slots, slot;	int res, len;	struct msdos_dir_entry *dummy_de;	struct buffer_head *dummy_bh;	int dummy_ino;	loff_t dummy;	dir_slots = (struct msdos_dir_slot *)	       kmalloc(sizeof(struct msdos_dir_slot) * MSDOS_SLOTS, GFP_KERNEL);	if (dir_slots == NULL)		return -ENOMEM;	len = qname->len;	while (len && qname->name[len-1] == '.')		len--;	res = fat_search_long(dir, qname->name, len,			      (MSDOS_SB(sb)->options.name_check != 's')			      || !MSDOS_SB(sb)->options.posixfs,			      &dummy, &dummy);	if (res > 0) /* found */		res = -EEXIST;	if (res)		goto cleanup;	res = vfat_build_slots(dir, qname->name, len,			       dir_slots, &slots, is_dir);	if (res < 0)		goto cleanup;	/* build the empty directory entry of number of slots */	offset = fat_add_entries(dir, slots, &dummy_bh, &dummy_de, &dummy_ino);	if (offset < 0) {		res = offset;		goto cleanup;	}	fat_brelse(sb, dummy_bh);	/* Now create the new entry */	*bh = NULL;	for (slot = 0; slot < slots; slot++) {		if (fat_get_entry(dir, &offset, bh, de, &sinfo_out->ino) < 0) {			res = -EIO;			goto cleanup;		}		memcpy(*de, dir_slots + slot, sizeof(struct msdos_dir_slot));		fat_mark_buffer_dirty(sb, *bh);	}	res = 0;	/* update timestamp */	dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME;	mark_inode_dirty(dir);	fat_date_unix2dos(dir->i_mtime, &(*de)->time, &(*de)->date);	(*de)->ctime = (*de)->time;	(*de)->adate = (*de)->cdate = (*de)->date;	fat_mark_buffer_dirty(sb, *bh);	/* slots can't be less than 1 */	sinfo_out->long_slots = slots - 1;	sinfo_out->longname_offset =		offset - sizeof(struct msdos_dir_slot) * slots;cleanup:	kfree(dir_slots);	return res;}static int vfat_find(struct inode *dir,struct qstr* qname,	struct vfat_slot_info *sinfo, struct buffer_head **last_bh,	struct msdos_dir_entry **last_de){	struct super_block *sb = dir->i_sb;	loff_t offset;	int res,len;	len = qname->len;	while (len && qname->name[len-1] == '.') 		len--;	res = fat_search_long(dir, qname->name, len,			(MSDOS_SB(sb)->options.name_check != 's'),			&offset,&sinfo->longname_offset);	if (res>0) {		sinfo->long_slots = res-1;		if (fat_get_entry(dir,&offset,last_bh,last_de,&sinfo->ino)>=0)			return 0;		res = -EIO;	} 	return res ? res : -ENOENT;}struct dentry *vfat_lookup(struct inode *dir,struct dentry *dentry){	int res;	struct vfat_slot_info sinfo;	struct inode *inode;	struct dentry *alias;	struct buffer_head *bh = NULL;	struct msdos_dir_entry *de;	int table;		PRINTK2(("vfat_lookup: name=%s, len=%d\n", 		 dentry->d_name.name, dentry->d_name.len));	table = (MSDOS_SB(dir->i_sb)->options.name_check == 's') ? 2 : 0;	dentry->d_op = &vfat_dentry_ops[table];	inode = NULL;	res = vfat_find(dir,&dentry->d_name,&sinfo,&bh,&de);	if (res < 0) {		table++;		goto error;	}	inode = fat_build_inode(dir->i_sb, de, sinfo.ino, &res);	fat_brelse(dir->i_sb, bh);	if (res)		return ERR_PTR(res);	alias = d_find_alias(inode);	if (alias) {		if (d_invalidate(alias)==0)			dput(alias);		else {			iput(inode);			return alias;		}			}error:	dentry->d_op = &vfat_dentry_ops[table];	dentry->d_time = dentry->d_parent->d_inode->i_version;	d_add(dentry,inode);	return NULL;}int vfat_create(struct inode *dir,struct dentry* dentry,int mode){	struct super_block *sb = dir->i_sb;	struct inode *inode = NULL;	struct buffer_head *bh = NULL;	struct msdos_dir_entry *de;	struct vfat_slot_info sinfo;	int res;	res = vfat_add_entry(dir, &dentry->d_name, 0, &sinfo, &bh, &de);	if (res < 0)		return res;	inode = fat_build_inode(sb, de, sinfo.ino, &res);	fat_brelse(sb, bh);	if (!inode)		return res;	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;	mark_inode_dirty(inode);	inode->i_version = ++event;	dir->i_version = event;	dentry->d_time = dentry->d_parent->d_inode->i_version;	d_instantiate(dentry,inode);	return 0;}static void vfat_remove_entry(struct inode *dir,struct vfat_slot_info *sinfo,     struct buffer_head *bh, struct msdos_dir_entry *de){	struct super_block *sb = dir->i_sb;	loff_t offset;	int i,ino;	/* remove the shortname */	dir->i_mtime = CURRENT_TIME;	dir->i_atime = CURRENT_TIME;	dir->i_version = ++event;	mark_inode_dirty(dir);	de->name[0] = DELETED_FLAG;	fat_mark_buffer_dirty(sb, bh);	/* remove the longname */	offset = sinfo->longname_offset; de = NULL;	for (i = sinfo->long_slots; i > 0; --i) {		if (fat_get_entry(dir, &offset, &bh, &de, &ino) < 0)			continue;		de->name[0] = DELETED_FLAG;		de->attr = 0;		fat_mark_buffer_dirty(sb, bh);	}	if (bh) fat_brelse(sb, bh);}int vfat_rmdir(struct inode *dir,struct dentry* dentry){	int res;	struct vfat_slot_info sinfo;	struct buffer_head *bh = NULL;	struct msdos_dir_entry *de;	res = fat_dir_empty(dentry->d_inode);	if (res)		return res;	res = vfat_find(dir,&dentry->d_name,&sinfo, &bh, &de);	if (res<0)		return res;	dentry->d_inode->i_nlink = 0;	dentry->d_inode->i_mtime = CURRENT_TIME;	dentry->d_inode->i_atime = CURRENT_TIME;	fat_detach(dentry->d_inode);	mark_inode_dirty(dentry->d_inode);	/* releases bh */	vfat_remove_entry(dir,&sinfo,bh,de);	dir->i_nlink--;	return 0;}int vfat_unlink(struct inode *dir, struct dentry* dentry){	int res;	struct vfat_slot_info sinfo;	struct buffer_head *bh = NULL;	struct msdos_dir_entry *de;	PRINTK1(("vfat_unlink: %s\n", dentry->d_name.name));	res = vfat_find(dir,&dentry->d_name,&sinfo,&bh,&de);	if (res < 0)		return res;	dentry->d_inode->i_nlink = 0;	dentry->d_inode->i_mtime = CURRENT_TIME;	dentry->d_inode->i_atime = CURRENT_TIME;	fat_detach(dentry->d_inode);	mark_inode_dirty(dentry->d_inode);	/* releases bh */	vfat_remove_entry(dir,&sinfo,bh,de);	return res;}int vfat_mkdir(struct inode *dir,struct dentry* dentry,int mode){	struct super_block *sb = dir->i_sb;	struct inode *inode = NULL;	struct vfat_slot_info sinfo;	struct buffer_head *bh = NULL;	struct msdos_dir_entry *de;	int res;	res = vfat_add_entry(dir, &dentry->d_name, 1, &sinfo, &bh, &de);	if (res < 0)		return res;	inode = fat_build_inode(sb, de, sinfo.ino, &res);	if (!inode)		goto out;	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;	mark_inode_dirty(inode);	inode->i_version = ++event;	dir->i_version = event;	dir->i_nlink++;	inode->i_nlink = 2; /* no need to mark them dirty */	res = fat_new_dir(inode, dir, 1);	if (res < 0)		goto mkdir_failed;	dentry->d_time = dentry->d_parent->d_inode->i_version;	d_instantiate(dentry,inode);out:	fat_brelse(sb, bh);	return res;mkdir_failed:	inode->i_nlink = 0;	inode->i_mtime = CURRENT_TIME;	inode->i_atime = CURRENT_TIME;	fat_detach(inode);	mark_inode_dirty(inode);	/* releases bh */	vfat_remove_entry(dir,&sinfo,bh,de);	iput(inode);	dir->i_nlink--;	return res;} int vfat_rename(struct inode *old_dir,struct dentry *old_dentry,		struct inode *new_dir,struct dentry *new_dentry){	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;	int dotdot_ino;	struct inode *old_inode, *new_inode;	int res, is_dir;	struct vfat_slot_info old_sinfo,sinfo;	old_bh = new_bh = dotdot_bh = NULL;	old_inode = old_dentry->d_inode;	new_inode = new_dentry->d_inode;	res = vfat_find(old_dir,&old_dentry->d_name,&old_sinfo,&old_bh,&old_de);	PRINTK3(("vfat_rename 2\n"));	if (res < 0) goto rename_done;	is_dir = S_ISDIR(old_inode->i_mode);	if (is_dir && (res = fat_scan(old_inode,MSDOS_DOTDOT,&dotdot_bh,				&dotdot_de,&dotdot_ino)) < 0)		goto rename_done;	if (new_dentry->d_inode) {		res = vfat_find(new_dir,&new_dentry->d_name,&sinfo,&new_bh,				&new_de);		if (res < 0 || MSDOS_I(new_inode)->i_location != sinfo.ino) {			/* WTF??? Cry and fail. */			printk(KERN_WARNING "vfat_rename: fs corrupted\n");			goto rename_done;		}		if (is_dir) {			res = fat_dir_empty(new_inode);			if (res)				goto rename_done;		}		fat_detach(new_inode);	} else {		res = vfat_add_entry(new_dir,&new_dentry->d_name,is_dir,&sinfo,					&new_bh,&new_de);		if (res < 0) goto rename_done;	}	new_dir->i_version = ++event;	/* releases old_bh */	vfat_remove_entry(old_dir,&old_sinfo,old_bh,old_de);	old_bh=NULL;	fat_detach(old_inode);	fat_attach(old_inode, sinfo.ino);	mark_inode_dirty(old_inode);	old_dir->i_version = ++event;	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;	mark_inode_dirty(old_dir);	if (new_inode) {		new_inode->i_nlink--;		new_inode->i_ctime=CURRENT_TIME;	}	if (is_dir) {		int start = MSDOS_I(new_dir)->i_logstart;		dotdot_de->start = CT_LE_W(start);		dotdot_de->starthi = CT_LE_W(start>>16);		fat_mark_buffer_dirty(sb, dotdot_bh);		old_dir->i_nlink--;		if (new_inode) {			new_inode->i_nlink--;		} else {			new_dir->i_nlink++;			mark_inode_dirty(new_dir);		}	}rename_done:	fat_brelse(sb, dotdot_bh);	fat_brelse(sb, old_bh);	fat_brelse(sb, new_bh);	return res;}/* Public inode operations for the VFAT fs */struct inode_operations vfat_dir_inode_operations = {	create:		vfat_create,	lookup:		vfat_lookup,	unlink:		vfat_unlink,	mkdir:		vfat_mkdir,	rmdir:		vfat_rmdir,	rename:		vfat_rename,	setattr:	fat_notify_change,};struct super_block *vfat_read_super(struct super_block *sb,void *data,				    int silent){	struct super_block *res;  	MSDOS_SB(sb)->options.isvfat = 1;	res = fat_read_super(sb, data, silent, &vfat_dir_inode_operations);	if (res == NULL)		return NULL;	if (parse_options((char *) data, &(MSDOS_SB(sb)->options))) {		MSDOS_SB(sb)->options.dotsOK = 0;		if (MSDOS_SB(sb)->options.posixfs) {			MSDOS_SB(sb)->options.name_check = 's';		}		if (MSDOS_SB(sb)->options.name_check != 's') {			sb->s_root->d_op = &vfat_dentry_ops[0];		} else {			sb->s_root->d_op = &vfat_dentry_ops[2];		}	}	return res;}

⌨️ 快捷键说明

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