You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/04/28 02:14:03 UTC
[04/50] [abbrv] incubator-mynewt-core git commit: nffs - blocks were
missing from end of files.
nffs - blocks were missing from end of files.
There was a bug in how nffs determines which block comes last in a file
inode. This process is still horribly inefficient (MYNEWT-161), but it
should at least work now.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/3abe7404
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/3abe7404
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/3abe7404
Branch: refs/heads/master
Commit: 3abe7404b76f6025483486a64646f02acdca24b8
Parents: 27605cb
Author: Christopher Collins <cc...@apache.org>
Authored: Mon Apr 18 20:09:26 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Tue Apr 19 14:32:22 2016 -0700
----------------------------------------------------------------------
fs/nffs/src/nffs_restore.c | 132 +++++++++++++++++++++++-----------------
1 file changed, 76 insertions(+), 56 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3abe7404/fs/nffs/src/nffs_restore.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/nffs_restore.c b/fs/nffs/src/nffs_restore.c
index 947a359..8f9c9f8 100644
--- a/fs/nffs/src/nffs_restore.c
+++ b/fs/nffs/src/nffs_restore.c
@@ -218,6 +218,76 @@ nffs_restore_inode_from_dummy_entry(struct nffs_inode *out_inode,
out_inode->ni_inode_entry = inode_entry;
}
+static int
+nffs_restore_find_file_end_block(struct nffs_hash_entry *block_entry)
+{
+ struct nffs_inode_entry *inode_entry;
+ struct nffs_block block;
+ int rc;
+
+ rc = nffs_block_from_hash_entry(&block, block_entry);
+ assert(rc == 0);
+
+ inode_entry = block.nb_inode_entry;
+
+ /* Make sure the parent inode (file) points to the latest data block
+ * restored so far.
+ *
+ * XXX: This is an O(n) operation (n = # of blocks in the file), and is
+ * horribly inefficient for large files. MYNEWT-161 has been opened to
+ * address this.
+ */
+ if (inode_entry->nie_last_block_entry == NULL) {
+ /* This is the first data block restored for this file. */
+ inode_entry->nie_last_block_entry = block_entry;
+ NFFS_LOG(DEBUG, "setting last block: %u\n", block_entry->nhe_id);
+ } else {
+ /* Determine if this this data block comes after our current idea of
+ * the file's last data block.
+ */
+
+ rc = nffs_block_find_predecessor(
+ block_entry, inode_entry->nie_last_block_entry->nhe_id);
+ switch (rc) {
+ case 0:
+ /* The currently-last block is a predecessor of the new block; the
+ * new block comes later.
+ */
+ NFFS_LOG(DEBUG, "replacing last block: %u --> %u\n",
+ inode_entry->nie_last_block_entry->nhe_id,
+ block_entry->nhe_id);
+ inode_entry->nie_last_block_entry = block_entry;
+ break;
+
+ case FS_ENOENT:
+ break;
+
+ default:
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+
+static int
+nffs_restore_find_file_ends(void)
+{
+ struct nffs_hash_entry *block_entry;
+ int rc;
+ int i;
+
+ NFFS_HASH_FOREACH(block_entry, i) {
+ if (!nffs_hash_id_is_inode(block_entry->nhe_id)) {
+ rc = nffs_restore_find_file_end_block(block_entry);
+ assert(rc == 0);
+ }
+ }
+
+ return 0;
+}
+
/**
* Performs a sweep of the RAM representation at the end of a successful
* restore. The sweep phase performs the following actions of each inode in
@@ -483,13 +553,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=%d\n",
+ NFFS_LOG(DEBUG, "restoring file; id=0x%08x\n",
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=%d\n",
+ NFFS_LOG(DEBUG, "restoring dir; id=0x%08x\n",
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;
@@ -619,7 +689,7 @@ nffs_restore_block(const struct nffs_disk_block *disk_block, uint8_t area_idx,
nffs_restore_largest_block_data_len = disk_block->ndb_data_len;
}
- NFFS_LOG(DEBUG, "restoring block; id=%u seq=%u inode_id=%u prev_id=%u "
+ 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,
disk_block->ndb_data_len);
@@ -632,59 +702,6 @@ nffs_restore_block(const struct nffs_disk_block *disk_block, uint8_t area_idx,
}
}
- /* Make sure the parent inode (file) points to the latest data block
- * restored so far.
- *
- * XXX: This is an O(n) operation (n = # of blocks in the file), and is
- * horribly inefficient for large files. MYNEWT-161 has been opened to
- * address this.
- */
- if (inode_entry->nie_last_block_entry == NULL) {
- /* This is the first data block restored for this file. */
- inode_entry->nie_last_block_entry = entry;
- NFFS_LOG(DEBUG, "setting last block: %u\n", entry->nhe_id);
- } else {
- /* Determine if this this data block comes after our current idea of
- * the file's last data block.
- */
-
- rc = nffs_block_find_predecessor(
- entry, inode_entry->nie_last_block_entry->nhe_id);
- switch (rc) {
- case 0:
- /* The currently-last block is a predecessor of the new block; the
- * new block comes later.
- */
- NFFS_LOG(DEBUG, "replacing last block: %u --> %u\n",
- inode_entry->nie_last_block_entry->nhe_id,
- entry->nhe_id);
- inode_entry->nie_last_block_entry = entry;
- break;
-
- case FS_ENOENT:
- /* The currently-last block is not a known predecessor of the new
- * block. There are two possibilities:
- * (1) The new block comes before the currently-last block.
- * (2) The new block comes later, but the two blocks are not
- * chained in RAM yet because an intervening block has yet
- * to be restored.
- * If we can find the new block by searching backwards from the
- * currently-last black, then (1) is true. Otherwise, (2) is true.
- */
- rc = nffs_block_find_predecessor(
- inode_entry->nie_last_block_entry, entry->nhe_id);
- if (rc == FS_ENOENT) {
- inode_entry->nie_last_block_entry = entry;
- NFFS_LOG(DEBUG, "replacing last block: %u --> %u\n",
- inode_entry->nie_last_block_entry->nhe_id,
- entry->nhe_id);
- }
- break;
-
- default:
- return rc;
- }
- }
return 0;
@@ -1135,6 +1152,9 @@ nffs_restore_full(const struct nffs_area_desc *area_descs)
goto err;
}
+ /* Find the last block in each file inode. */
+ nffs_restore_find_file_ends();
+
/* Delete from RAM any objects that were invalidated when subsequent areas
* were restored.
*/