diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-10-13 06:35:58 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2007-10-13 06:35:58 -0400 |
commit | b534e70cf5529378a1ed994492641ec0330554eb (patch) | |
tree | d0257ffa39a331cad12e855122cb1e540b0eac41 /fs/jffs2/scan.c | |
parent | 69ca4378aa376cf2c49657d4f6951da56c27cd3a (diff) |
[JFFS2] Handle dirents on the flash with embedded zero bytes in names.
In three places: summary scan, normal scan, REF_PRISTINE GC.
Just truncate at the NUL, since that was the correct thing to do in the
only case where this (inexplicable) breakage has been seen.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2/scan.c')
-rw-r--r-- | fs/jffs2/scan.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 35ef8d83366f..272872d27fd5 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
@@ -1004,6 +1004,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo | |||
1004 | { | 1004 | { |
1005 | struct jffs2_full_dirent *fd; | 1005 | struct jffs2_full_dirent *fd; |
1006 | struct jffs2_inode_cache *ic; | 1006 | struct jffs2_inode_cache *ic; |
1007 | uint32_t checkedlen; | ||
1007 | uint32_t crc; | 1008 | uint32_t crc; |
1008 | int err; | 1009 | int err; |
1009 | 1010 | ||
@@ -1024,12 +1025,18 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo | |||
1024 | 1025 | ||
1025 | pseudo_random += je32_to_cpu(rd->version); | 1026 | pseudo_random += je32_to_cpu(rd->version); |
1026 | 1027 | ||
1027 | fd = jffs2_alloc_full_dirent(rd->nsize+1); | 1028 | /* Should never happen. Did. (OLPC trac #4184)*/ |
1029 | checkedlen = strnlen(rd->name, rd->nsize); | ||
1030 | if (checkedlen < rd->nsize) { | ||
1031 | printk(KERN_ERR "Dirent at %08x has zeroes in name. Truncating to %d chars\n", | ||
1032 | ofs, checkedlen); | ||
1033 | } | ||
1034 | fd = jffs2_alloc_full_dirent(checkedlen+1); | ||
1028 | if (!fd) { | 1035 | if (!fd) { |
1029 | return -ENOMEM; | 1036 | return -ENOMEM; |
1030 | } | 1037 | } |
1031 | memcpy(&fd->name, rd->name, rd->nsize); | 1038 | memcpy(&fd->name, rd->name, checkedlen); |
1032 | fd->name[rd->nsize] = 0; | 1039 | fd->name[checkedlen] = 0; |
1033 | 1040 | ||
1034 | crc = crc32(0, fd->name, rd->nsize); | 1041 | crc = crc32(0, fd->name, rd->nsize); |
1035 | if (crc != je32_to_cpu(rd->name_crc)) { | 1042 | if (crc != je32_to_cpu(rd->name_crc)) { |
@@ -1055,7 +1062,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo | |||
1055 | fd->next = NULL; | 1062 | fd->next = NULL; |
1056 | fd->version = je32_to_cpu(rd->version); | 1063 | fd->version = je32_to_cpu(rd->version); |
1057 | fd->ino = je32_to_cpu(rd->ino); | 1064 | fd->ino = je32_to_cpu(rd->ino); |
1058 | fd->nhash = full_name_hash(fd->name, rd->nsize); | 1065 | fd->nhash = full_name_hash(fd->name, checkedlen); |
1059 | fd->type = rd->type; | 1066 | fd->type = rd->type; |
1060 | jffs2_add_fd_to_list(c, fd, &ic->scan_dents); | 1067 | jffs2_add_fd_to_list(c, fd, &ic->scan_dents); |
1061 | 1068 | ||