Forked from #DIV/0!队 / proj32-bjtu
Source project has a limited visibility.
nodelist.c 9.74 KiB
/*
 * nodelist.c
 *  Created on: 2021/5/10
 *      Author: ueyudiud
 */
#include "nffs.h"
#include "nffs_node.h"
#include "nffs_ext.h"
void nffsJoinFdList(n_dev* dev, n_dirent* dir_in, n_dirent** list) {
	n_dirent** prev = list;
	n_dirent* dir;
	while ((dir = *prev) != NULL && dir->_name_hash <= dir_in->_name_hash) {
		if (dir->_name_hash == dir_in->_name_hash &&
			strcmp((char const*) dir_in->_name, (char const*) dir->_name) == 0) {
			if (dir_in->_ver < dir->_ver) {
				nffsMarkNodeObsolete(dev, dir_in->_ref);
				nffsFreeDirent(dir_in);
			else {
				dir_in->_next = dir->_next;
				if (dir->_ref != NULL)
					nffsMarkNodeObsolete(dev, dir->_ref);
				nffsFreeDirent(dir);
				*prev = dir_in;
			return;
		prev = &dir->_next;
	dir_in->_next = *prev;
	*prev = dir_in;
n_code nffsJoinDirtySpace(n_dev* dev, n_block* block, n_u32 size) {
	if (size == 0)
		return NMF_SUCC;
	/* illegal instruction? */
	nmfAssume(size > block->_free_size, "Dirty space size 0x%x larger than free size 0x%x.",
			size,
			block->_free_size);
	if (block->_tail_node != NULL && ref_obsolete(block->_tail_node)) {
		dev->_dirty_size += size;
		dev->_free_size -= size;
		block->_dirty_size += size;
		block->_free_size -= size;
	else {
		n_u32 off = block->_offset + dev->_param._bytes_per_block - block->_free_size;
		off |= REF_OBSOLETE;
		nffsJoinNodeRef(dev, block, off, size, NULL);
	return NMF_SUCC;
n_raw_node_ref* nffsJoinNodeRef(n_dev* dev, n_block* block, n_u32 off, n_u32 size, n_inode* node) {
	n_raw_node_ref* ref = block->_tail_node;
	while (!is_empty_ref(ref)) {
		ref = ref_next_raw(ref);
	ref->_off = off;
	if (block->_head_node == NULL) {
		block->_head_node = ref;
		nmfAssume(block->_offset == ref->_off, "Block offset not match to ref offset\n");
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
nmfAssume(ref_offset(ref) == block->_offset + dev->_param._bytes_per_block - block->_free_size, "Adding new ref %p at (0x%08x-0x%08x) not immediately after previous.\n", ref, ref_offset(ref), ref_offset(ref) + size); block->_tail_node = ref; ref = block->_tail_node; nmfLog(NMF_ENTITY_SELF, NMF_DBG_LEVEL_INFO, "Last ref node at %p is (%08x,%p)\n", ref, ref->_off, ref->_next); while (!is_empty_ref(ref)) { ref = ref_next_raw(ref); } nmfLog(NMF_ENTITY_SELF, NMF_DBG_LEVEL_INFO, "New ref node is %p (%08x becomes %08x,%p) with length of 0x%x\n", ref, ref->_off, off, ref->_next, size); ref->_off = off; if (!block->_head_node) { block->_head_node = ref; } block->_tail_node = ref; if (node != NULL) { /* 将节点加入到node的节点链表中 */ ref->_next = node->_ref; node->_ref = ref; } else { ref->_next = NULL; } /* flags? */ switch (ref_status(ref)) { case REF_UNCHECKED: dev->_unchecked_size += size; block->_unchecked_size += size; break; case REF_PRISTINE: case REF_NORMAL: dev->_used_size += size; block->_used_size += size; break; case REF_OBSOLETE: dev->_dirty_size += size; block->_dirty_size += size; break; } dev->_free_size -= size; block->_free_size -= size; return ref; } void nffsFreeAllRawNodeRefs(n_dev* dev) { for (n_u32 i = 0; i < dev->_param._block_per_total; ++i) { n_raw_node_ref* self = dev->_blocks[i]._head_node; while (is_link_ref(&self[NFFS_REF_PER_BLOCK])) { n_raw_node_ref* next = self->_next; nffsFreeRawRefBlock(self); self = next; } dev->_blocks[i]._head_node = NULL; dev->_blocks[i]._tail_node = NULL; } }
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
void nffsFreeAllINodes(n_dev* dev) { for (n_u32 i = 0; i < dev->_inode_capacity; ++i) { n_inode* self = dev->_inode_caches[i]; while (self != NULL) { n_inode* next = self->_next; nffsFreeINode(self); self = next; } dev->_inode_caches[i] = NULL; } } n_inode* nffsGetINode(n_dev* dev, n_u32 ino) { n_inode* node = dev->_inode_caches[ino % dev->_inode_capacity]; while (node != NULL && node->_ino < ino) { node = node->_next; } return node != NULL && node->_ino == ino ? node : NULL; } void nffsAddINode(n_dev* dev, n_inode* node) { if (node->_ino == 0) { node->_ino = ++dev->_next_ino; } n_inode** slot = &dev->_inode_caches[node->_ino % dev->_inode_capacity]; n_inode* prev; while ((prev = *slot) != NULL && prev->_ino < node->_ino) { slot = &prev->_next; } node->_next = *slot; *slot = node; } void nffsDelINode(n_dev* dev, n_inode* node) { n_inode** slot = &dev->_inode_caches[node->_ino % dev->_inode_capacity]; n_inode* prev; while ((prev = *slot) != NULL && prev->_ino < node->_ino) { slot = &prev->_next; } if (prev == node) { *slot = node->_next; } /* TODO 应当在某些状态不在这个函数中释放内存 */ nffsFreeINode(node); } n_u32 nffsRefLen(n_dev* dev, n_block* block, n_raw_node_ref* ref) { uint32_t ref_end; n_raw_node_ref*next_ref = ref_next(ref); if (next_ref) ref_end = ref_offset(next_ref); else { if (block == NULL) block = &dev->_blocks[ref->_off / dev->_param._bytes_per_block]; /* Last node in block. Use free_space */ nmfAssume(ref != block->_tail_node, "ref %p @0x%08x is not jeb->last_node (%p @0x%08x)\n", ref, ref_offset(ref), block->_tail_node, block->_tail_node ? ref_offset(block->_tail_node) : 0); ref_end = block->_offset + dev->_param._bytes_per_block - block->_free_size;