summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/jffs2/jffs2_1pass.c87
1 files changed, 47 insertions, 40 deletions
diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c
index 2e569ff..aaeb522 100644
--- a/fs/jffs2/jffs2_1pass.c
+++ b/fs/jffs2/jffs2_1pass.c
@@ -598,14 +598,18 @@ insert_node(struct b_list *list, u32 offset)
*/
static int compare_inodes(struct b_node *new, struct b_node *old)
{
- struct jffs2_raw_inode ojNew;
- struct jffs2_raw_inode ojOld;
- struct jffs2_raw_inode *jNew =
- (struct jffs2_raw_inode *)get_fl_mem(new->offset, sizeof(ojNew), &ojNew);
- struct jffs2_raw_inode *jOld =
- (struct jffs2_raw_inode *)get_fl_mem(old->offset, sizeof(ojOld), &ojOld);
-
- return jNew->version > jOld->version;
+ /*
+ * Only read in the version info from flash, not the entire inode.
+ * This can make a big difference to speed if flash is slow.
+ */
+ u32 new_version;
+ u32 old_version;
+ get_fl_mem(new->offset + offsetof(struct jffs2_raw_inode, version),
+ sizeof(new_version), &new_version);
+ get_fl_mem(old->offset + offsetof(struct jffs2_raw_inode, version),
+ sizeof(old_version), &old_version);
+
+ return new_version > old_version;
}
/* Sort directory entries so all entries in the same directory
@@ -615,42 +619,45 @@ static int compare_inodes(struct b_node *new, struct b_node *old)
*/
static int compare_dirents(struct b_node *new, struct b_node *old)
{
- struct jffs2_raw_dirent ojNew;
- struct jffs2_raw_dirent ojOld;
- struct jffs2_raw_dirent *jNew =
- (struct jffs2_raw_dirent *)get_fl_mem(new->offset, sizeof(ojNew), &ojNew);
- struct jffs2_raw_dirent *jOld =
- (struct jffs2_raw_dirent *)get_fl_mem(old->offset, sizeof(ojOld), &ojOld);
- int cmp;
-
- /* ascending sort by pino */
- if (jNew->pino != jOld->pino)
- return jNew->pino > jOld->pino;
-
- /* pino is the same, so use ascending sort by nsize, so
- * we don't do strncmp unless we really must.
- */
- if (jNew->nsize != jOld->nsize)
- return jNew->nsize > jOld->nsize;
-
- /* length is also the same, so use ascending sort by name
- */
- cmp = strncmp((char *)jNew->name, (char *)jOld->name, jNew->nsize);
- if (cmp != 0)
- return cmp > 0;
-
- /* we have duplicate names in this directory, so use ascending
- * sort by version
+ /*
+ * Using NULL as the buffer for NOR flash prevents the entire node
+ * being read. This makes most comparisons much quicker as only one
+ * or two entries from the node will be used most of the time.
*/
- if (jNew->version > jOld->version) {
- /* since jNew is newer, we know jOld is not valid, so
- * mark it with inode 0 and it will not be used
+ struct jffs2_raw_dirent *jNew = get_node_mem(new->offset, NULL);
+ struct jffs2_raw_dirent *jOld = get_node_mem(old->offset, NULL);
+ int cmp;
+ int ret;
+
+ if (jNew->pino != jOld->pino) {
+ /* ascending sort by pino */
+ ret = jNew->pino > jOld->pino;
+ } else if (jNew->nsize != jOld->nsize) {
+ /*
+ * pino is the same, so use ascending sort by nsize,
+ * so we don't do strncmp unless we really must.
*/
- jOld->ino = 0;
- return 1;
+ ret = jNew->nsize > jOld->nsize;
+ } else {
+ /*
+ * length is also the same, so use ascending sort by name
+ */
+ cmp = strncmp((char *)jNew->name, (char *)jOld->name,
+ jNew->nsize);
+ if (cmp != 0) {
+ ret = cmp > 0;
+ } else {
+ /*
+ * we have duplicate names in this directory,
+ * so use ascending sort by version
+ */
+ ret = jNew->version > jOld->version;
+ }
}
+ put_fl_mem(jNew, NULL);
+ put_fl_mem(jOld, NULL);
- return 0;
+ return ret;
}
#endif