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

📄 dir.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 2 页
字号:
		{			return;		}		dir->nused -= 1;		i = dir;	}}voidsmb_init_root(struct smb_server *server){	struct smb_inode_info *root = &(server->root);	root->state = SMB_INODE_LOOKED_UP;	root->nused = 1;	root->dir = NULL;	root->next = root->prev = root;	return;}voidsmb_free_all_inodes(struct smb_server *server){	/* Here nothing should be to do. I do not know whether it's	   better to leave some memory allocated or be stuck in an	   endless loop */#if 1	struct smb_inode_info *root = &(server->root);	if (root->next != root)	{		printk("smb_free_all_inodes: INODES LEFT!!!\n");	}	while (root->next != root)	{		printk("smb_free_all_inodes: freeing inode\n");		smb_free_inode_info(root->next);		/* In case we have an endless loop.. */		schedule();	}#endif	return;}/* This has to be called when a connection has gone down, so that all   file-handles we got from the server are invalid */voidsmb_invalidate_all_inodes(struct smb_server *server){	struct smb_inode_info *ino = &(server->root);	do	{		ino->finfo.opened = 0;		ino = ino->next;	}	while (ino != &(server->root));	return;}static intcompare_filename(const struct smb_server *server,		 const char *s1, int len, struct smb_dirent *entry){	if (len != entry->len)	{#if 0		/* Check whether the entry is about to be removed */		if (!entry->len)			printk("SMBFS: dead entry %s\n", entry->name);#endif		return 1;	}	if (server->case_handling == CASE_DEFAULT)	{		return strncasecmp(s1, entry->name, len);	}	return strncmp(s1, entry->name, len);}/* * Search for the smb_inode_info that belongs to this name, * currently by a complete linear search through the inodes * belonging to this filesystem. * * Note that this returns files as well as directories. */static struct smb_inode_info *smb_find_dir_inode(struct inode *parent, const char *name, int len){	struct smb_server *server = SMB_SERVER(parent);	struct smb_inode_info *dir = SMB_INOP(parent);	struct smb_inode_info *result = &(server->root);	if (name == NULL)	{		return NULL;	}	if ((len == 1) && (name[0] == '.'))	{		return dir;	}	if ((len == 2) && (name[0] == '.') && (name[1] == '.'))	{		return dir->dir;	}	do	{		if (result->dir == dir)		{			if (compare_filename(server, name, len,					     &(result->finfo)) == 0)			{				return result;			}		}		result = result->next;	}	while (result != &(server->root));	return NULL;}static intsmb_lookup(struct inode *dir, const char *name, int len,	   struct inode **result){	struct smb_dirent finfo;	struct smb_inode_info *result_info;	int error;	int found_in_cache;	struct smb_inode_info *new_inode_info = NULL;	*result = NULL;	if (!dir || !S_ISDIR(dir->i_mode))	{		printk("smb_lookup: inode is NULL or not a directory.\n");		iput(dir);		return -ENOENT;	}	DDPRINTK("smb_lookup: %s\n", name);	/* Fast cheat for . */	if (len == 0 || (len == 1 && name[0] == '.'))	{		*result = dir;		return 0;	}	/* ..and for .. */	if (len == 2 && name[0] == '.' && name[1] == '.')	{		struct smb_inode_info *parent = SMB_INOP(dir)->dir;		if (parent->state == SMB_INODE_CACHED)		{			parent->state = SMB_INODE_LOOKED_UP;		}		*result = iget(dir->i_sb, smb_info_ino(parent));		iput(dir);		if (*result == 0)		{			return -EACCES;		}		return 0;	}	result_info = smb_find_dir_inode(dir, name, len);      in_tree:	if (result_info != NULL)	{		if (result_info->state == SMB_INODE_CACHED)		{			result_info->state = SMB_INODE_LOOKED_UP;		}		*result = iget(dir->i_sb, smb_info_ino(result_info));		iput(dir);		if (new_inode_info != NULL)		{			smb_kfree_s(new_inode_info,				    sizeof(struct smb_inode_info));		}		if (*result == NULL)		{			return -EACCES;		}		return 0;	}	/* If the file is in the dir cache, we do not have to ask the	   server. */	found_in_cache = 0;	if ((dir->i_dev == c_dev) && (dir->i_ino == c_ino) && (c_size != 0))	{		int first = c_last_returned_index;		int i;		i = first;		do		{			if (compare_filename(SMB_SERVER(dir), name, len,					     &(c_entry[i])) == 0)			{				finfo = c_entry[i];				found_in_cache = 1;				break;			}			i = (i + 1) % c_size;		}		while (i != first);	}	if (found_in_cache == 0)	{		DPRINTK("smb_lookup: not found in cache: %s\n", name);		if (len > SMB_MAXNAMELEN)		{			iput(dir);			return -ENAMETOOLONG;		}		error = smb_proc_getattr(dir, name, len, &finfo);		if (error < 0)		{			iput(dir);			return error;		}		finfo.f_ino = smb_fresh_inodes(SMB_SERVER(dir), 1);	}	new_inode_info = smb_kmalloc(sizeof(struct smb_inode_info),				     GFP_KERNEL);	/* Here somebody else might have inserted the inode */	result_info = smb_find_dir_inode(dir, name, len);	if (result_info != NULL)	{		goto in_tree;	}	if (new_inode_info == NULL)	{		iput(dir);		return -ENOMEM;	}	new_inode_info->finfo = finfo;	DPRINTK("attr: %x\n", finfo.attr);	if ((*result = smb_iget(dir, new_inode_info)) == NULL)	{		iput(dir);		return -EACCES;	}	DDPRINTK("smb_lookup: %s => %lu\n", name, (unsigned long) result_info);	iput(dir);	return 0;}static intsmb_create(struct inode *dir, const char *name, int len, int mode,	   struct inode **result){	int error;	struct smb_dirent entry;	struct smb_inode_info *new_inode_info;	*result = NULL;	if (!dir || !S_ISDIR(dir->i_mode))	{		printk("smb_create: inode is NULL or not a directory\n");		iput(dir);		return -ENOENT;	}	new_inode_info = smb_kmalloc(sizeof(struct smb_inode_info),				     GFP_KERNEL);	if (new_inode_info == NULL)	{		iput(dir);		return -ENOMEM;	}	error = smb_proc_create(dir, name, len, 0, CURRENT_TIME);	if (error < 0)	{		smb_kfree_s(new_inode_info, sizeof(struct smb_inode_info));		iput(dir);		return error;	}	smb_invalid_dir_cache(dir->i_ino);	if ((error = smb_proc_getattr(dir, name, len, &entry)) < 0)	{		smb_kfree_s(new_inode_info, sizeof(struct smb_inode_info));		iput(dir);		return error;	}	entry.f_ino = smb_fresh_inodes(SMB_SERVER(dir), 1);	new_inode_info->finfo = entry;	if ((*result = smb_iget(dir, new_inode_info)) == NULL)	{		iput(dir);		return error;	}	iput(dir);	return 0;}static intsmb_mkdir(struct inode *dir, const char *name, int len, int mode){	int error;	if (!dir || !S_ISDIR(dir->i_mode))	{		iput(dir);		return -EINVAL;	}	if ((error = smb_proc_mkdir(dir, name, len)) == 0)	{		smb_invalid_dir_cache(dir->i_ino);	}	iput(dir);	return error;}static intsmb_rmdir(struct inode *dir, const char *name, int len){	int error;	if (!dir || !S_ISDIR(dir->i_mode))	{		printk("smb_rmdir: inode is NULL or not a directory\n");		iput(dir);		return -ENOENT;	}	if (smb_find_dir_inode(dir, name, len) != NULL)	{		error = -EBUSY;	} else	{		if ((error = smb_proc_rmdir(dir, name, len)) == 0)		{			smb_invalid_dir_cache(dir->i_ino);		}	}	iput(dir);	return error;}static intsmb_unlink(struct inode *dir, const char *name, int len){	int error;	if (!dir || !S_ISDIR(dir->i_mode))	{		printk("smb_unlink: inode is NULL or not a directory\n");		iput(dir);		return -ENOENT;	}	if (smb_find_dir_inode(dir, name, len) != NULL)	{		error = -EBUSY;	} else	{		if ((error = smb_proc_unlink(dir, name, len)) == 0)		{			smb_invalid_dir_cache(dir->i_ino);		}	}	iput(dir);	return error;}static intsmb_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){	int res;	if (!old_dir || !S_ISDIR(old_dir->i_mode))	{		printk("smb_rename: old inode is NULL or not a directory\n");		res = -ENOENT;		goto finished;	}	if (!new_dir || !S_ISDIR(new_dir->i_mode))	{		printk("smb_rename: new inode is NULL or not a directory\n");		res = -ENOENT;		goto finished;	}	if ((smb_find_dir_inode(old_dir, old_name, old_len) != NULL)	    || (smb_find_dir_inode(new_dir, new_name, new_len) != NULL))	{		res = -EBUSY;		goto finished;	}	res = smb_proc_mv(old_dir, old_name, old_len,			  new_dir, new_name, new_len);	if (res == -EEXIST)	{		int res1 = smb_proc_unlink(old_dir, new_name, new_len);		if (res1 == 0)		{			res = smb_proc_mv(old_dir, old_name, old_len,					  new_dir, new_name, new_len);		}	}	if (res == 0)	{		smb_invalid_dir_cache(old_dir->i_ino);		smb_invalid_dir_cache(new_dir->i_ino);	}      finished:	iput(old_dir);	iput(new_dir);	return res;}

⌨️ 快捷键说明

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