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

📄 fs-ecos.c

📁 老版本的mtd-snap
💻 C
📖 第 1 页 / 共 4 页
字号:
		// stop if there are more than the configured maximum		if (m - &cyg_mtab[0] >= CYGNUM_FILEIO_MTAB_MAX) {			m = &cyg_mtab_end;			break;		}		if (m->valid && strcmp(m->fsname, "jffs3") == 0 &&		    strcmp(m->devname, mte->devname) == 0) {			jffs3_sb = (struct super_block *) m->data;		}	}	if (jffs3_sb == NULL) {		jffs3_sb = malloc(sizeof (struct super_block));		if (jffs3_sb == NULL)			return ENOMEM;		c = JFFS3_SB_INFO(jffs3_sb);		memset(jffs3_sb, 0, sizeof (struct super_block));		jffs3_sb->s_dev = t;		c->inocache_list = malloc(sizeof(struct jffs3_inode_cache *) * INOCACHE_HASHSIZE);		if (!c->inocache_list) {			free(jffs3_sb);			return ENOMEM;		}		memset(c->inocache_list, 0, sizeof(struct jffs3_inode_cache *) * INOCACHE_HASHSIZE);                if (n_fs_mounted++ == 0) {                        jffs3_create_slab_caches(); // No error check, cannot fail			jffs3_compressors_init(); 		}		err = jffs3_read_super(jffs3_sb);		if (err) {                        if (--n_fs_mounted == 0) {                                jffs3_destroy_slab_caches();				jffs3_compressors_exit();			}                        			free(jffs3_sb);			free(c->inocache_list);			return err;		}		jffs3_sb->s_root->i_parent = jffs3_sb->s_root;	// points to itself, no dotdot paths above mountpoint		jffs3_sb->s_root->i_cache_prev = NULL;	// root inode, so always null		jffs3_sb->s_root->i_cache_next = NULL;		jffs3_sb->s_root->i_count = 1;	// Ensures the root inode is always in ram until umount		D2(printf("jffs3_mount erasing pending blocks\n"));#ifdef CYGOPT_FS_JFFS3_WRITE		if (!jffs3_is_readonly(c))		    jffs3_erase_pending_blocks(c,0);#endif#ifdef CYGOPT_FS_JFFS3_GCTHREAD		jffs3_start_garbage_collect_thread(c);#endif	}	mte->data = (CYG_ADDRWORD) jffs3_sb;	jffs3_sb->s_mount_count++;	mte->root = (cyg_dir) jffs3_sb->s_root;	D2(printf("jffs3_mounted superblock at %x\n", mte->root));	return ENOERR;}extern cyg_dir cyg_cdir_dir;extern cyg_mtab_entry *cyg_cdir_mtab_entry;// -------------------------------------------------------------------------// jffs3_umount()// Unmount the filesystem. static int jffs3_umount(cyg_mtab_entry * mte){	struct _inode *root = (struct _inode *) mte->root;	struct super_block *jffs3_sb = root->i_sb;	struct jffs3_sb_info *c = JFFS3_SB_INFO(jffs3_sb);        struct jffs3_full_dirent *fd, *next;	D2(printf("jffs3_umount\n"));	// Only really umount if this is the only mount	if (jffs3_sb->s_mount_count == 1) {		icache_evict(root, NULL);		if (root->i_cache_next != NULL)	{			struct _inode *inode = root;			printf("Refuse to unmount.\n");			while (inode) {				printf("Ino #%u has use count %d\n",				       inode->i_ino, inode->i_count);				inode = inode->i_cache_next;			}			// root icount was set to 1 on mount			return EBUSY;                }		if (root->i_count == 2 &&		    cyg_cdir_mtab_entry == mte &&		    cyg_cdir_dir == (cyg_dir)root &&		    !strcmp(mte->name, "/")) {			/* If we were mounted on root, there's no			   way for the cwd to change out and free 			   the file system for unmounting. So we hack			   it -- if cwd is '/' we unset it. Perhaps			   we should allow chdir(NULL) to unset			   cyg_cdir_dir? */			cyg_cdir_dir = CYG_DIR_NULL;			jffs3_iput(root);		}		/* Argh. The fileio code sets this; never clears it */		if (cyg_cdir_mtab_entry == mte)			cyg_cdir_mtab_entry = NULL;		if (root->i_count != 1) {			printf("Ino #1 has use count %d\n",			       root->i_count);			return EBUSY;		}#ifdef CYGOPT_FS_JFFS3_GCTHREAD		jffs3_stop_garbage_collect_thread(c);#endif		jffs3_iput(root);	// Time to free the root inode		// free directory entries		for (fd = root->jffs3_i.dents; fd; fd = next) {		  next=fd->next;		  jffs3_free_full_dirent(fd);		}		free(root);		//Clear root inode		//root_i = NULL;		// Clean up the super block and root inode		jffs3_free_ino_caches(c);		jffs3_free_raw_node_refs(c);		free(c->blocks);		free(c->inocache_list);		free(jffs3_sb);		// Clear superblock & root pointer		mte->root = CYG_DIR_NULL;                mte->data = 0;		mte->fs->data = 0;	// fstab entry, visible to all mounts. No current mount		// That's all folks.		D2(printf("jffs3_umount No current mounts\n"));	} else {		jffs3_sb->s_mount_count--;        }        if (--n_fs_mounted == 0) {                jffs3_destroy_slab_caches();        		jffs3_compressors_exit();	}	return ENOERR;}// -------------------------------------------------------------------------// jffs3_open()// Open a file for reading or writing.static int jffs3_open(cyg_mtab_entry * mte, cyg_dir dir, const char *name,		      int mode, cyg_file * file){	jffs3_dirsearch ds;	struct _inode *node = NULL;	int err;	D2(printf("jffs3_open\n"));	/* If no chdir has been called and we were the first file system	   mounted, we get called with dir == NULL. Deal with it */	if (!dir)		dir = mte->root;#ifndef CYGOPT_FS_JFFS3_WRITE	if (mode & (O_CREAT|O_TRUNC|O_WRONLY))		return EROFS;#endif	init_dirsearch(&ds, (struct _inode *) dir, name);	err = jffs3_find(&ds);	if (err == ENOENT) {#ifdef CYGOPT_FS_JFFS3_WRITE		if (ds.last && (mode & O_CREAT)) {			// No node there, if the O_CREAT bit is set then we must			// create a new one. The dir and name fields of the dirsearch			// object will have been updated so we know where to put it.			err = jffs3_create(ds.dir, ds.name, S_IRUGO|S_IXUGO|S_IWUSR|S_IFREG, &node);			if (err != 0) {                                //Possible orphaned inode on the flash - but will be gc'd                          	jffs3_iput(ds.dir);                                return err;			}			err = ENOERR;		}#endif	} else if (err == ENOERR) {		// The node exists. If the O_CREAT and O_EXCL bits are set, we		// must fail the open.		if ((mode & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) {			jffs3_iput(ds.node);			err = EEXIST;		} else			node = ds.node;	}	// Finished with the directory now 	jffs3_iput(ds.dir);	if (err != ENOERR)		return err;	// Check that we actually have a file here	if (S_ISDIR(node->i_mode)) {		jffs3_iput(node);		return EISDIR;	}#ifdef CYGOPT_FS_JFFS3_WRITE	if (mode & O_TRUNC) {		struct jffs3_inode_info *f = JFFS3_INODE_INFO(node);		struct jffs3_sb_info *c = JFFS3_SB_INFO(node->i_sb);		// If the O_TRUNC bit is set we must clean out the file data.		node->i_size = 0;		jffs3_truncate_fraglist(c, &f->fragtree, 0);		// Update file times		node->i_ctime = node->i_mtime = cyg_timestamp();	}#endif	// Initialise the file object	file->f_flag |= mode & CYG_FILE_MODE_MASK;	file->f_type = CYG_FILE_TYPE_FILE;	file->f_ops = &jffs3_fileops;	file->f_offset = (mode & O_APPEND) ? node->i_size : 0;	file->f_data = (CYG_ADDRWORD) node;	file->f_xops = 0;	return ENOERR;}#ifdef CYGOPT_FS_JFFS3_WRITE// -------------------------------------------------------------------------// jffs3_ops_unlink()// Remove a file link from its directory.static int jffs3_ops_unlink(cyg_mtab_entry * mte, cyg_dir dir, const char *name){	jffs3_dirsearch ds;	int err;	D2(printf("jffs3_ops_unlink\n"));	init_dirsearch(&ds, (struct _inode *) dir, name);	err = jffs3_find(&ds);	if (err != ENOERR) {		jffs3_iput(ds.dir);		return err;	}	// Cannot unlink directories, use rmdir() instead	if (S_ISDIR(ds.node->i_mode)) {		jffs3_iput(ds.dir);		jffs3_iput(ds.node);		return EPERM;	}	// Delete it from its directory	err = jffs3_unlink(ds.dir, ds.node, ds.name);	jffs3_iput(ds.dir);	jffs3_iput(ds.node);	return -err;}// -------------------------------------------------------------------------// jffs3_ops_mkdir()// Create a new directory.static int jffs3_ops_mkdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name){	jffs3_dirsearch ds;	int err;	D2(printf("jffs3_ops_mkdir\n"));	init_dirsearch(&ds, (struct _inode *) dir, name);	err = jffs3_find(&ds);	if (err == ENOENT) {		if (ds.last) {			// The entry does not exist, and it is the last element in			// the pathname, so we can create it here.			err = -jffs3_mkdir(ds.dir, ds.name, S_IRUGO|S_IXUGO|S_IWUSR);		}		// If this was not the last element, then an intermediate		// directory does not exist.	} else {		// If there we no error, something already exists with that		// name, so we cannot create another one.		jffs3_iput(ds.node);		if (err == ENOERR)			err = EEXIST;	}	jffs3_iput(ds.dir);	return err;}// -------------------------------------------------------------------------// jffs3_ops_rmdir()// Remove a directory.static int jffs3_ops_rmdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name){	jffs3_dirsearch ds;	int err;	D2(printf("jffs3_ops_rmdir\n"));	init_dirsearch(&ds, (struct _inode *) dir, name);	err = jffs3_find(&ds);	if (err != ENOERR) {		jffs3_iput(ds.dir);		return err;	}	// Check that this is actually a directory.	if (!S_ISDIR(ds.node->i_mode)) {		jffs3_iput(ds.dir);		jffs3_iput(ds.node);		return EPERM;	}	err = jffs3_rmdir(ds.dir, ds.node, ds.name);	jffs3_iput(ds.dir);	jffs3_iput(ds.node);	return -err;}// -------------------------------------------------------------------------// jffs3_ops_rename()// Rename a file/dir.static int jffs3_ops_rename(cyg_mtab_entry * mte, cyg_dir dir1,			    const char *name1, cyg_dir dir2, const char *name2){	jffs3_dirsearch ds1, ds2;	int err;	D2(printf("jffs3_ops_rename\n"));	init_dirsearch(&ds1, (struct _inode *) dir1, name1);	err = jffs3_find(&ds1);	if (err != ENOERR) {		jffs3_iput(ds1.dir);		return err;	}	init_dirsearch(&ds2, (struct _inode *) dir2, name2);	err = jffs3_find(&ds2);	// Allow through renames to non-existent objects.	if (ds2.last && err == ENOENT) {		ds2.node = NULL;		err = ENOERR;	}	if (err != ENOERR) {		jffs3_iput(ds1.dir);		jffs3_iput(ds1.node);		jffs3_iput(ds2.dir);		return err;	}	// Null rename, just return	if (ds1.node == ds2.node) {		err = ENOERR;		goto out;	}	// First deal with any entry that is at the destination	if (ds2.node) {		// Check that we are renaming like-for-like		if (!S_ISDIR(ds1.node->i_mode) && S_ISDIR(ds2.node->i_mode)) {			err = EISDIR;			goto out;		}		if (S_ISDIR(ds1.node->i_mode) && !S_ISDIR(ds2.node->i_mode)) {			err = ENOTDIR;			goto out;		}		// Now delete the destination directory entry		/* Er, what happened to atomicity of rename()? */		err = -jffs3_unlink(ds2.dir, ds2.node, ds2.name);		if (err != 0)			goto out;	}	// Now we know that there is no clashing node at the destination,	// make a new direntry at the destination and delete the old entry	// at the source.	err = -jffs3_rename(ds1.dir, ds1.node, ds1.name, ds2.dir, ds2.name);	// Update directory times	if (!err)		ds1.dir->i_ctime =		    ds1.dir->i_mtime =		    ds2.dir->i_ctime = ds2.dir->i_mtime = cyg_timestamp(); out:	jffs3_iput(ds1.dir);	jffs3_iput(ds1.node);	if (S_ISDIR(ds1.node->i_mode)) {		/* Renamed a directory to elsewhere... so fix up its		   i_parent pointer and the i_counts of its old and		   new parents. */		jffs3_iput(ds1.node->i_parent);		ds1.node->i_parent = ds2.dir;		/* We effectively increase its use count by not... */	} else {		jffs3_iput(ds2.dir); /* ... doing this */	}	if (ds2.node)		jffs3_iput(ds2.node); 	return -err;}// -------------------------------------------------------------------------// jffs3_ops_link()// Make a new directory entry for a file.static int jffs3_ops_link(cyg_mtab_entry * mte, cyg_dir dir1, const char *name1,			  cyg_dir dir2, const char *name2, int type){	jffs3_dirsearch ds1, ds2;	int err;	D2(printf("jffs3_ops_link\n"));	// Only do hard links for now in this filesystem	if (type != CYG_FSLINK_HARD)		return EINVAL;	init_dirsearch(&ds1, (struct _inode *) dir1, name1);	err = jffs3_find(&ds1);	if (err != ENOERR) {		jffs3_iput(ds1.dir);		return err;	}	init_dirsearch(&ds2, (struct _inode *) dir2, name2);	err = jffs3_find(&ds2);	// Don't allow links to existing objects	if (err == ENOERR) {		jffs3_iput(ds1.dir);		jffs3_iput(ds1.node);		jffs3_iput(ds2.dir);		jffs3_iput(ds2.node);		return EEXIST;	}	// Allow through links to non-existing terminal objects	if (ds2.last && err == ENOENT) {		ds2.node = NULL;		err = ENOERR;	}	if (err != ENOERR) {		jffs3_iput(ds1.dir);		jffs3_iput(ds1.node);		jffs3_iput(ds2.dir);		return err;	}	// Now we know that there is no existing node at the destination,	// make a new direntry at the destination.	err = jffs3_link(ds1.node, ds2.dir, ds2.name);	if (err == 0)		ds1.node->i_ctime =		    ds2.dir->i_ctime = ds2.dir->i_mtime = cyg_timestamp();	jffs3_iput(ds1.dir);	jffs3_iput(ds1.node);	jffs3_iput(ds2.dir);	return -err;}#endif /* CYGOPT_FS_JFFS3_WRITE */// -------------------------------------------------------------------------// jffs3_opendir()

⌨️ 快捷键说明

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