diff options
Diffstat (limited to 'fs/nffs')
-rw-r--r-- | fs/nffs/src/nffs.c | 10 | ||||
-rw-r--r-- | fs/nffs/src/nffs_block.c | 3 | ||||
-rw-r--r-- | fs/nffs/src/nffs_cache.c | 8 | ||||
-rw-r--r-- | fs/nffs/src/nffs_hash.c | 2 | ||||
-rw-r--r-- | fs/nffs/src/nffs_inode.c | 4 | ||||
-rw-r--r-- | fs/nffs/src/nffs_priv.h | 4 | ||||
-rw-r--r-- | fs/nffs/src/nffs_restore.c | 60 |
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); } } |