summaryrefslogtreecommitdiff
path: root/fs/nffs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nffs')
-rw-r--r--fs/nffs/src/nffs.c10
-rw-r--r--fs/nffs/src/nffs_block.c3
-rw-r--r--fs/nffs/src/nffs_cache.c8
-rw-r--r--fs/nffs/src/nffs_hash.c2
-rw-r--r--fs/nffs/src/nffs_inode.c4
-rw-r--r--fs/nffs/src/nffs_priv.h4
-rw-r--r--fs/nffs/src/nffs_restore.c60
7 files changed, 55 insertions, 36 deletions
diff --git a/fs/nffs/src/nffs.c b/fs/nffs/src/nffs.c
index f3b03721..28fdeea6 100644
--- a/fs/nffs/src/nffs.c
+++ b/fs/nffs/src/nffs.c
@@ -118,6 +118,14 @@ nffs_unlock(void)
assert(rc == 0 || rc == OS_NOT_STARTED);
}
+static void
+nffs_stats_init(void)
+{
+ nffs_hashcnt_ins = 0;
+ nffs_hashcnt_rm = 0;
+ nffs_object_count = 0;
+}
+
/**
* Opens a file at the specified path. The result of opening a nonexistent
* file depends on the access flags specified. All intermediate directories
@@ -624,6 +632,8 @@ nffs_init(void)
nffs_cache_clear();
+ nffs_stats_init();
+
rc = os_mutex_init(&nffs_mutex);
if (rc != 0) {
return FS_EOS;
diff --git a/fs/nffs/src/nffs_block.c b/fs/nffs/src/nffs_block.c
index 953e4ddc..d1d291ad 100644
--- a/fs/nffs/src/nffs_block.c
+++ b/fs/nffs/src/nffs_block.c
@@ -255,6 +255,9 @@ nffs_block_delete_from_ram(struct nffs_hash_entry *block_entry)
if (rc == 0 || rc == FS_ECORRUPT) {
/* If file system corruption was detected, the resulting block is still
* valid and can be removed from RAM.
+ * Note that FS_CORRUPT can occur because the owning inode was not
+ * found in the hash table - this can occur during the sweep where
+ * the inodes were deleted ahead of the blocks.
*/
inode_entry = block.nb_inode_entry;
if (inode_entry != NULL &&
diff --git a/fs/nffs/src/nffs_cache.c b/fs/nffs/src/nffs_cache.c
index 51ebc30c..ddbc904d 100644
--- a/fs/nffs/src/nffs_cache.c
+++ b/fs/nffs/src/nffs_cache.c
@@ -313,10 +313,10 @@ nffs_cache_log_block(struct nffs_cache_inode *cache_inode,
{
NFFS_LOG(DEBUG, "id=%u inode=%u flash_off=0x%08x "
"file_off=%u len=%d (entry=%p)\n",
- cache_block->ncb_block.nb_hash_entry->nhe_id,
- cache_inode->nci_inode.ni_inode_entry->nie_hash_entry.nhe_id,
- cache_block->ncb_block.nb_hash_entry->nhe_flash_loc,
- cache_block->ncb_file_offset,
+ (unsigned int)cache_block->ncb_block.nb_hash_entry->nhe_id,
+ (unsigned int)cache_inode->nci_inode.ni_inode_entry->nie_hash_entry.nhe_id,
+ (unsigned int)cache_block->ncb_block.nb_hash_entry->nhe_flash_loc,
+ (unsigned int)cache_block->ncb_file_offset,
cache_block->ncb_block.nb_data_len,
cache_block->ncb_block.nb_hash_entry);
}
diff --git a/fs/nffs/src/nffs_hash.c b/fs/nffs/src/nffs_hash.c
index 805ed26b..299210b3 100644
--- a/fs/nffs/src/nffs_hash.c
+++ b/fs/nffs/src/nffs_hash.c
@@ -156,6 +156,7 @@ nffs_hash_insert(struct nffs_hash_entry *entry)
list = nffs_hash + idx;
SLIST_INSERT_HEAD(list, entry, nhe_next);
+ nffs_hashcnt_ins++;
if (nffs_hash_id_is_inode(entry->nhe_id)) {
nie = nffs_hash_find_inode(entry->nhe_id);
@@ -185,6 +186,7 @@ nffs_hash_remove(struct nffs_hash_entry *entry)
list = nffs_hash + idx;
SLIST_REMOVE(list, entry, nffs_hash_entry, nhe_next);
+ nffs_hashcnt_rm++;
if (nffs_hash_id_is_inode(entry->nhe_id) && nie) {
nffs_inode_unsetflags(nie, NFFS_INODE_FLAG_INHASH);
diff --git a/fs/nffs/src/nffs_inode.c b/fs/nffs/src/nffs_inode.c
index d8b881c3..a72bc827 100644
--- a/fs/nffs/src/nffs_inode.c
+++ b/fs/nffs/src/nffs_inode.c
@@ -114,6 +114,9 @@ nffs_inode_write_disk(const struct nffs_disk_inode *disk_inode,
{
int rc;
+ /* Only the DELETED flag is ever written out to flash */
+ assert((disk_inode->ndi_flags & ~NFFS_INODE_FLAG_DELETED) == 0);
+
rc = nffs_flash_write(area_idx, area_offset, disk_inode,
sizeof *disk_inode);
if (rc != 0) {
@@ -611,6 +614,7 @@ nffs_inode_rename(struct nffs_inode_entry *inode_entry,
disk_inode.ndi_id = inode_entry->nie_hash_entry.nhe_id;
disk_inode.ndi_seq = inode.ni_seq + 1;
disk_inode.ndi_parent_id = nffs_inode_parent_id(&inode);
+ disk_inode.ndi_flags = 0;
disk_inode.ndi_filename_len = filename_len;
if (inode_entry->nie_last_block_entry &&
inode_entry->nie_last_block_entry->nhe_id != NFFS_ID_NONE)
diff --git a/fs/nffs/src/nffs_priv.h b/fs/nffs/src/nffs_priv.h
index b654b85b..47c4e9a6 100644
--- a/fs/nffs/src/nffs_priv.h
+++ b/fs/nffs/src/nffs_priv.h
@@ -236,6 +236,10 @@ struct nffs_dir {
struct nffs_dirent nd_dirent;
};
+uint32_t nffs_hashcnt_ins;
+uint32_t nffs_hashcnt_rm;
+uint32_t nffs_object_count;
+
extern void *nffs_file_mem;
extern void *nffs_block_entry_mem;
extern void *nffs_inode_mem;
diff --git a/fs/nffs/src/nffs_restore.c b/fs/nffs/src/nffs_restore.c
index 83b2ef96..fd425fc3 100644
--- a/fs/nffs/src/nffs_restore.c
+++ b/fs/nffs/src/nffs_restore.c
@@ -282,7 +282,7 @@ nffs_restore_sweep(void)
struct nffs_hash_list *list;
struct nffs_inode inode;
struct nffs_block block;
- int del;
+ int del = 0;
int rc;
int i;
@@ -319,17 +319,6 @@ nffs_restore_sweep(void)
return rc;
}
-#if 0 /* for now, don't preserve corrupted directories */
- /*
- * if this inode doesn't have a parent, move it to
- * the lost_found directory
- */
- if (inode_entry != nffs_root_dir && inode.ni_parent == NULL) {
- rc = nffs_inode_rename(inode_entry,
- nffs_lost_found_dir, NULL);
- }
-#endif
-
if (del) {
/* Remove the inode and all its children from RAM. We
@@ -346,13 +335,19 @@ nffs_restore_sweep(void)
}
} else if (nffs_hash_id_is_block(entry->nhe_id)) {
if (nffs_hash_id_is_dummy(entry->nhe_id)) {
+ del = 1;
nffs_block_delete_from_ram(entry);
} else {
rc = nffs_block_from_hash_entry(&block, entry);
if (rc != 0 && rc != FS_ENOENT) {
+ del = 1;
nffs_block_delete_from_ram(entry);
}
}
+ if (del) {
+ del = 0;
+ next = SLIST_FIRST(list);
+ }
}
entry = next;
@@ -504,7 +499,8 @@ nffs_restore_inode(const struct nffs_disk_inode *disk_inode, uint8_t area_idx,
* Restore this inode even though deleted on disk
* so the additional restored blocks have a place to go
*/
- NFFS_LOG(DEBUG, "restoring deleted inode %x\n", disk_inode->ndi_id);
+ NFFS_LOG(DEBUG, "restoring deleted inode %x\n",
+ (unsigned int)disk_inode->ndi_id);
nffs_inode_setflags(inode_entry, NFFS_INODE_FLAG_DELETED);
}
@@ -629,7 +625,8 @@ nffs_restore_inode(const struct nffs_disk_inode *disk_inode, uint8_t area_idx,
* Restore this inode even though deleted on disk
* so the additional restored blocks have a place to go
*/
- NFFS_LOG(DEBUG, "restoring deleted inode %x\n", disk_inode->ndi_id);
+ NFFS_LOG(DEBUG, "restoring deleted inode %x\n",
+ (unsigned int)disk_inode->ndi_id);
nffs_inode_setflags(inode_entry, NFFS_INODE_FLAG_DELETED);
}
@@ -649,12 +646,6 @@ nffs_restore_inode(const struct nffs_disk_inode *disk_inode, uint8_t area_idx,
if (lastblock_entry != NULL) {
if (lastblock_entry->nhe_id == disk_inode->ndi_lastblock_id) {
inode_entry->nie_last_block_entry = lastblock_entry;
- /*
- * This flag should have been turned unset
- * when the block was restored.
- */
- assert(!nffs_inode_getflags(inode_entry,
- NFFS_INODE_FLAG_DUMMYLSTBLK));
}
} else {
@@ -717,13 +708,13 @@ nffs_restore_inode(const struct nffs_disk_inode *disk_inode, uint8_t area_idx,
if (nffs_hash_id_is_file(inode_entry->nie_hash_entry.nhe_id)) {
NFFS_LOG(DEBUG, "restoring file; id=0x%08x\n",
- inode_entry->nie_hash_entry.nhe_id);
+ (unsigned int)inode_entry->nie_hash_entry.nhe_id);
if (inode_entry->nie_hash_entry.nhe_id >= nffs_hash_next_file_id) {
nffs_hash_next_file_id = inode_entry->nie_hash_entry.nhe_id + 1;
}
} else {
NFFS_LOG(DEBUG, "restoring dir; id=0x%08x\n",
- inode_entry->nie_hash_entry.nhe_id);
+ (unsigned int)inode_entry->nie_hash_entry.nhe_id);
if (inode_entry->nie_hash_entry.nhe_id >= nffs_hash_next_dir_id) {
nffs_hash_next_dir_id = inode_entry->nie_hash_entry.nhe_id + 1;
}
@@ -890,8 +881,11 @@ nffs_restore_block(const struct nffs_disk_block *disk_block, uint8_t area_idx,
}
NFFS_LOG(DEBUG, "restoring block; id=0x%08x seq=%u inode_id=%u prev_id=%u "
- "data_len=%u\n", disk_block->ndb_id, disk_block->ndb_seq,
- disk_block->ndb_inode_id, disk_block->ndb_prev_id,
+ "data_len=%u\n",
+ (unsigned int)disk_block->ndb_id,
+ (unsigned int)disk_block->ndb_seq,
+ (unsigned int)disk_block->ndb_inode_id,
+ (unsigned int)disk_block->ndb_prev_id,
disk_block->ndb_data_len);
inode_entry = nffs_hash_find_inode(disk_block->ndb_inode_id);
@@ -1065,6 +1059,7 @@ nffs_restore_area_contents(int area_idx)
if (rc == FS_ECORRUPT) {
area->na_cur++;
} else {
+ nffs_object_count++; /* total count of restored objects */
area->na_cur += nffs_restore_disk_object_size(&disk_object);
}
break;
@@ -1219,19 +1214,20 @@ nffs_log_contents(void)
if (nffs_hash_id_is_block(entry->nhe_id)) {
rc = nffs_block_from_hash_entry(&block, entry);
assert(rc == 0 || rc == FS_ENOENT);
- NFFS_LOG(DEBUG, "block; id=%u inode_id=", entry->nhe_id);
+ NFFS_LOG(DEBUG, "block; id=%u inode_id=",
+ (unsigned int)entry->nhe_id);
if (block.nb_inode_entry == NULL) {
NFFS_LOG(DEBUG, "null ");
} else {
NFFS_LOG(DEBUG, "%u ",
- block.nb_inode_entry->nie_hash_entry.nhe_id);
+ (unsigned int)block.nb_inode_entry->nie_hash_entry.nhe_id);
}
NFFS_LOG(DEBUG, "prev_id=");
if (block.nb_prev == NULL) {
NFFS_LOG(DEBUG, "null ");
} else {
- NFFS_LOG(DEBUG, "%u ", block.nb_prev->nhe_id);
+ NFFS_LOG(DEBUG, "%u ", (unsigned int)block.nb_prev->nhe_id);
}
NFFS_LOG(DEBUG, "data_len=%u\n", block.nb_data_len);
@@ -1245,7 +1241,7 @@ nffs_log_contents(void)
NFFS_LOG(DEBUG, "null");
} else {
NFFS_LOG(DEBUG, "%x",
- (unsigned int)inode_entry->nie_last_block_entry->nhe_id);
+ (unsigned int)inode_entry->nie_last_block_entry->nhe_id);
}
} else if (rc != 0) {
continue;
@@ -1254,18 +1250,18 @@ nffs_log_contents(void)
if (nffs_hash_id_is_file(entry->nhe_id)) {
NFFS_LOG(DEBUG, "file; id=%u name=%.3s block_id=",
- entry->nhe_id, inode.ni_filename);
+ (unsigned int)entry->nhe_id, inode.ni_filename);
if (inode_entry->nie_last_block_entry == NULL) {
NFFS_LOG(DEBUG, "null");
} else {
NFFS_LOG(DEBUG, "%u",
- inode_entry->nie_last_block_entry->nhe_id);
+ (unsigned int)inode_entry->nie_last_block_entry->nhe_id);
}
NFFS_LOG(DEBUG, "\n");
} else {
inode_entry = (void *)entry;
- NFFS_LOG(DEBUG, "dir; id=%u name=%.3s\n", entry->nhe_id,
- inode.ni_filename);
+ NFFS_LOG(DEBUG, "dir; id=%u name=%.3s\n",
+ (unsigned int)entry->nhe_id, inode.ni_filename);
}
}