Failed to fetch fork details. Try again later.
-
natsuu authored48b1e6fd
Forked from
#DIV/0!队 / proj32-bjtu
Source project has a limited visibility.
/*
* 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;