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

📄 intrep.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		  "name = \"%s\", deleted = %d\n",		  raw_inode->ino, raw_inode->version,		  ((name && *name) ? name : ""), raw_inode->deleted));	/* If there doesn't exist an associated jffs_file, then	   create, initialize and insert one into the file system.  */	if (!f && !(f = jffs_find_file(c, raw_inode->ino))) {		if (!(f = jffs_create_file(c, raw_inode))) {			return -ENOMEM;		}		jffs_insert_file_into_hash(f);		insert_into_tree = 1;	}	node->ino = raw_inode->ino;	node->version = raw_inode->version;	node->data_size = raw_inode->dsize;	node->fm_offset = sizeof(struct jffs_raw_inode) + raw_inode->nsize			  + JFFS_GET_PAD_BYTES(raw_inode->nsize);	node->name_size = raw_inode->nsize;	/* Now insert the node at the correct position into the file's	   version list.  */	if (!f->version_head) {		/* This is the first node.  */		f->version_head = node;		f->version_tail = node;		node->version_prev = 0;		node->version_next = 0;		f->highest_version = node->version;		update_name = 1;		f->mode = raw_inode->mode;		f->uid = raw_inode->uid;		f->gid = raw_inode->gid;		f->atime = raw_inode->atime;		f->mtime = raw_inode->mtime;		f->ctime = raw_inode->ctime;		f->deleted = raw_inode->deleted;	}	else if ((f->highest_version < node->version)		 || (node->version == 0)) {		/* Insert at the end of the list.  I.e. this node is the		   oldest one so far.  */		node->version_prev = f->version_tail;		node->version_next = 0;		f->version_tail->version_next = node;		f->version_tail = node;		f->highest_version = node->version;		update_name = 1;		f->pino = raw_inode->pino;		f->mode = raw_inode->mode;		f->uid = raw_inode->uid;		f->gid = raw_inode->gid;		f->atime = raw_inode->atime;		f->mtime = raw_inode->mtime;		f->ctime = raw_inode->ctime;		f->deleted = raw_inode->deleted;	}	else if (f->version_head->version > node->version) {		/* Insert at the bottom of the list.  */		node->version_prev = 0;		node->version_next = f->version_head;		f->version_head->version_prev = node;		f->version_head = node;		if (!f->name) {			update_name = 1;		}		if (raw_inode->deleted) {			f->deleted = raw_inode->deleted;		}	}	else {		struct jffs_node *n;		int newer_name = 0;		/* Search for the insertion position starting from		   the tail (newest node).  */		for (n = f->version_tail; n; n = n->version_prev) {			if (n->version < node->version) {				node->version_prev = n;				node->version_next = n->version_next;				node->version_next->version_prev = node;				n->version_next = node;				if (!newer_name) {					update_name = 1;				}				break;			}			if (n->name_size) {				newer_name = 1;			}		}	}	/* Perhaps update the name.  */	if (raw_inode->nsize && update_name && name && *name && (name != f->name)) {		if (f->name) {			kfree(f->name);			DJM(no_name--);		}		if (!(f->name = (char *) kmalloc(raw_inode->nsize + 1,						 GFP_KERNEL))) {			return -ENOMEM;		}		DJM(no_name++);		memcpy(f->name, name, raw_inode->nsize);		f->name[raw_inode->nsize] = '\0';		f->nsize = raw_inode->nsize;		D3(printk("jffs_insert_node(): Updated the name of "			  "the file to \"%s\".\n", name));	}	if (!c->building_fs) {		D3(printk("jffs_insert_node(): ---------------------------"			  "------------------------------------------- 1\n"));		if (insert_into_tree) {			jffs_insert_file_into_tree(f);		}		if (f->deleted) {			/* Mark all versions of the node as obsolete.  */			jffs_possibly_delete_file(f);		}		else {			if (node->data_size || node->removed_size) {				jffs_update_file(f, node);			}			jffs_remove_redundant_nodes(f);		}		jffs_garbage_collect_trigger(c);		D3(printk("jffs_insert_node(): ---------------------------"			  "------------------------------------------- 2\n"));	}	return 0;} /* jffs_insert_node()  *//* Unlink a jffs_node from the version list it is in.  */static inline voidjffs_unlink_node_from_version_list(struct jffs_file *f,				   struct jffs_node *node){	if (node->version_prev) {		node->version_prev->version_next = node->version_next;	} else {		f->version_head = node->version_next;	}	if (node->version_next) {		node->version_next->version_prev = node->version_prev;	} else {		f->version_tail = node->version_prev;	}}/* Unlink a jffs_node from the range list it is in.  */static inline voidjffs_unlink_node_from_range_list(struct jffs_file *f, struct jffs_node *node){	if (node->range_prev) {		node->range_prev->range_next = node->range_next;	}	else {		f->range_head = node->range_next;	}	if (node->range_next) {		node->range_next->range_prev = node->range_prev;	}	else {		f->range_tail = node->range_prev;	}}/* Function used by jffs_remove_redundant_nodes() below.  This function   classifies what kind of information a node adds to a file.  */static inline __u8jffs_classify_node(struct jffs_node *node){	__u8 mod_type = JFFS_MODIFY_INODE;	if (node->name_size) {		mod_type |= JFFS_MODIFY_NAME;	}	if (node->data_size || node->removed_size) {		mod_type |= JFFS_MODIFY_DATA;	}	return mod_type;}/* Remove redundant nodes from a file.  Mark the on-flash memory   as dirty.  */intjffs_remove_redundant_nodes(struct jffs_file *f){	struct jffs_node *newest_node;	struct jffs_node *cur;	struct jffs_node *prev;	__u8 newest_type;	__u8 mod_type;	__u8 node_with_name_later = 0;	if (!(newest_node = f->version_tail)) {		return 0;	}	/* What does the `newest_node' modify?  */	newest_type = jffs_classify_node(newest_node);	node_with_name_later = newest_type & JFFS_MODIFY_NAME;	D3(printk("jffs_remove_redundant_nodes(): ino: %u, name: \"%s\", "		  "newest_type: %u\n", f->ino, (f->name ? f->name : ""),		  newest_type));	/* Traverse the file's nodes and determine which of them that are	   superfluous.  Yeah, this might look very complex at first	   glance but it is actually very simple.  */	for (cur = newest_node->version_prev; cur; cur = prev) {		prev = cur->version_prev;		mod_type = jffs_classify_node(cur);		if ((mod_type <= JFFS_MODIFY_INODE)		    || ((newest_type & JFFS_MODIFY_NAME)			&& (mod_type			    <= (JFFS_MODIFY_INODE + JFFS_MODIFY_NAME)))		    || (cur->data_size == 0 && cur->removed_size			&& !cur->version_prev && node_with_name_later)) {			/* Yes, this node is redundant. Remove it.  */			D2(printk("jffs_remove_redundant_nodes(): "				  "Removing node: ino: %u, version: %u, "				  "mod_type: %u\n", cur->ino, cur->version,				  mod_type));			jffs_unlink_node_from_version_list(f, cur);			jffs_fmfree(f->c->fmc, cur->fm, cur);			kfree(cur);			DJM(no_jffs_node--);		}		else {			node_with_name_later |= (mod_type & JFFS_MODIFY_NAME);		}	}	return 0;}/* Insert a file into the hash table.  */intjffs_insert_file_into_hash(struct jffs_file *f){	int i = f->ino % f->c->hash_len;	D3(printk("jffs_insert_file_into_hash(): f->ino: %u\n", f->ino));	list_add(&f->hash, &f->c->hash[i]);	return 0;}/* Insert a file into the file system tree.  */intjffs_insert_file_into_tree(struct jffs_file *f){	struct jffs_file *parent;	D3(printk("jffs_insert_file_into_tree(): name: \"%s\"\n",		  (f->name ? f->name : "")));	if (!(parent = jffs_find_file(f->c, f->pino))) {		if (f->pino == 0) {			f->c->root = f;			f->parent = 0;			f->sibling_prev = 0;			f->sibling_next = 0;			return 0;		}		else {			D1(printk("jffs_insert_file_into_tree(): Found "				  "inode with no parent and pino == %u\n",				  f->pino));			return -1;		}	}	f->parent = parent;	f->sibling_next = parent->children;	if (f->sibling_next) {		f->sibling_next->sibling_prev = f;	}	f->sibling_prev = 0;	parent->children = f;	return 0;}/* Remove a file from the hash table.  */intjffs_unlink_file_from_hash(struct jffs_file *f){	D3(printk("jffs_unlink_file_from_hash(): f: 0x%p, "		  "ino %u\n", f, f->ino));	list_del(&f->hash);	return 0;}/* Just remove the file from the parent's children.  Don't free   any memory.  */intjffs_unlink_file_from_tree(struct jffs_file *f){	D3(printk("jffs_unlink_file_from_tree(): ino: %d, pino: %d, name: "		  "\"%s\"\n", f->ino, f->pino, (f->name ? f->name : "")));	if (f->sibling_prev) {		f->sibling_prev->sibling_next = f->sibling_next;	}	else if (f->parent) {	        D3(printk("f->parent=%p\n", f->parent));		f->parent->children = f->sibling_next;	}	if (f->sibling_next) {		f->sibling_next->sibling_prev = f->sibling_prev;	}	return 0;}/* Find a file with its inode number.  */struct jffs_file *jffs_find_file(struct jffs_control *c, __u32 ino){	struct jffs_file *f;	int i = ino % c->hash_len;	struct list_head *tmp;	D3(printk("jffs_find_file(): ino: %u\n", ino));	for (tmp = c->hash[i].next; tmp != &c->hash[i]; tmp = tmp->next) {		f = list_entry(tmp, struct jffs_file, hash);		if (ino != f->ino)			continue;		D3(printk("jffs_find_file(): Found file with ino "			       "%u. (name: \"%s\")\n",			       ino, (f->name ? f->name : ""));		);		return f;	}	D3(printk("jffs_find_file(): Didn't find file "			 "with ino %u.\n", ino);	);	return NULL;}/* Find a file in a directory.  We are comparing the names.  */struct jffs_file *jffs_find_child(struct jffs_file *dir, const char *name, int len){	struct jffs_file *f;	D3(printk("jffs_find_child()\n"));	for (f = dir->children; f; f = f->sibling_next) {		if (f->name		    && !strncmp(f->name, name, len)		    && f->name[len] == '\0') {			break;		}	}	D3(if (f) {		printk("jffs_find_child(): Found \"%s\".\n", f->name);	}	else {		char *copy = (char *) kmalloc(len + 1, GFP_KERNEL);		if (copy) {			memcpy(copy, name, len);			copy[len] = '\0';		}		printk("jffs_find_child(): Didn't find the file \"%s\".\n",		       (copy ? copy : ""));		if (copy) {			kfree(copy);		}	});	return f;}/* Write a raw inode that takes up a certain amount of space in the flash   memory.  At the end of the flash device, there is often space that is   impossible to use.  At these times we want to mark this space as not   used.  In the cases when the amount of space is greater or equal than   a struct jffs_raw_inode, we write a "dummy node" that takes up this   space.  The space after the raw inode, if it exists, is left as it is.   Since this space after the raw inode contains JFFS_EMPTY_BITMASK bytes,   we can compute the checksum of it; we don't have to manipulate it any   further.   If the space left on the device is less than the size of a struct   jffs_raw_inode, this space is filled with JFFS_DIRTY_BITMASK bytes.   No raw inode is written this time.  */static intjffs_write_dummy_node(struct jffs_control *c, struct jffs_fm *dirty_fm){	struct jffs_fmcontrol *fmc = c->fmc;	int err;	D1(printk("jffs_write_dummy_node(): dirty_fm->offset = 0x%08x, "		  "dirty_fm->size = %u\n",		  dirty_fm->offset, dirty_fm->size));	if (dirty_fm->size >= sizeof(struct jffs_raw_inode)) {		struct jffs_raw_inode raw_inode;		memset(&raw_inode, 0, sizeof(struct jffs_raw_inode));		raw_inode.magic = JFFS_MAGIC_BITMASK;		raw_inode.dsize = dirty_fm->size				  - sizeof(struct jffs_raw_inode);		raw_inode.dchksum = raw_inode.dsize * 0xff;		raw_inode.chksum		= jffs_checksum(&raw_inode, sizeof(struct jffs_raw_inode));		if ((err = flash_safe_write(fmc->mtd,					    dirty_fm->offset,					    (u_char *)&raw_inode,					    sizeof(struct jffs_raw_inode)))		    < 0) {			printk(KERN_ERR "JFFS: jffs_write_dummy_node: "			       "flash_safe_write failed!\n");			return err;		}	}	else {		flash_safe_acquire(fmc->mtd);		flash_memset(fmc->mtd, dirty_fm->offset, 0, dirty_fm->size);		flash_safe_release(fmc->mtd);	}	D3(printk("jffs_write_dummy_node(): Leaving...\n"));	return 0;}/* Write a raw inode, possibly its name and possibly some data.  */intjffs_write_node(struct jffs_control *c, struct jffs_node *node,		struct jffs_raw_inode *raw_inode,		const char *name, const unsigned char *data,		int recoverable,		struct jffs_file *f){	struct jffs_fmcontrol *fmc = c->fmc;	struct jffs_fm *fm = NULL;	__u32 pos;	int err;	__u32 slack = 0;	__u32 total_name_size = raw_inode->nsize				+ JFFS_GET_PAD_BYTES(raw_inode->nsize);	__u32 total_data_size = raw_inode->dsize				+ JFFS_GET_PAD_BYTES(raw_inode->dsize);	__u32 total_size = sizeof(struct jffs_raw_inode)			   + total_name_size + total_data_size;		/* If this node isn't something that will eventually let	   GC free even more space, then don't allow it unless	   there's at least max_chunk_size space still available	*/	if (!recoverable)		slack = fmc->max_chunk_size;			/* Fire the retrorockets and shoot the fruiton torpedoes, sir!  */	ASSERT(if (!node) {		printk("jffs_write_node(): node == NULL\n");		return -EINVAL;	});	ASSERT(if (raw_inode && raw_inode->nsize && !name) {		printk("*** jffs_write_node(): nsize = %u but name == NULL\n",		       raw_inode->nsize);		return -EINVAL;	});	D1(printk("jffs_write_node(): filename = \"%s\", ino = %u, "		  "total_size = %u\n",		  (name ? name : ""), raw_inode->ino,		  total_size));	jffs_fm_write_lock(fmc);

⌨️ 快捷键说明

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