Blame view
fs/yaffs2/yaffs_packedtags2.c
5.4 KB
0e8cc8bd9 YAFFS2 import |
1 2 3 |
/* * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. * |
753ac6108 u-boot: Update ya... |
4 |
* Copyright (C) 2002-2011 Aleph One Ltd. |
0e8cc8bd9 YAFFS2 import |
5 6 7 8 9 10 11 12 13 14 15 |
* for Toby Churchill Ltd and Brightstar Engineering * * Created by Charles Manning <charles@aleph1.co.uk> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include "yaffs_packedtags2.h" #include "yportenv.h" |
753ac6108 u-boot: Update ya... |
16 |
#include "yaffs_trace.h" |
0e8cc8bd9 YAFFS2 import |
17 18 19 20 21 22 23 24 25 |
/* This code packs a set of extended tags into a binary structure for * NAND storage */ /* Some of the information is "extra" struff which can be packed in to * speed scanning * This is defined by having the EXTRA_HEADER_INFO_FLAG set. */ |
753ac6108 u-boot: Update ya... |
26 |
/* Extra flags applied to chunk_id */ |
0e8cc8bd9 YAFFS2 import |
27 28 29 30 31 |
#define EXTRA_HEADER_INFO_FLAG 0x80000000 #define EXTRA_SHRINK_FLAG 0x40000000 #define EXTRA_SHADOWS_FLAG 0x20000000 #define EXTRA_SPARE_FLAGS 0x10000000 |
753ac6108 u-boot: Update ya... |
32 |
#define ALL_EXTRA_FLAGS 0xf0000000 |
0e8cc8bd9 YAFFS2 import |
33 34 35 |
/* Also, the top 4 bits of the object Id are set to the object type. */ #define EXTRA_OBJECT_TYPE_SHIFT (28) |
753ac6108 u-boot: Update ya... |
36 |
#define EXTRA_OBJECT_TYPE_MASK ((0x0f) << EXTRA_OBJECT_TYPE_SHIFT) |
0e8cc8bd9 YAFFS2 import |
37 |
|
753ac6108 u-boot: Update ya... |
38 39 |
static void yaffs_dump_packed_tags2_tags_only( const struct yaffs_packed_tags2_tags_only *ptt) |
0e8cc8bd9 YAFFS2 import |
40 |
{ |
753ac6108 u-boot: Update ya... |
41 42 43 |
yaffs_trace(YAFFS_TRACE_MTD, "packed tags obj %d chunk %d byte %d seq %d", ptt->obj_id, ptt->chunk_id, ptt->n_bytes, ptt->seq_number); |
0e8cc8bd9 YAFFS2 import |
44 |
} |
753ac6108 u-boot: Update ya... |
45 |
static void yaffs_dump_packed_tags2(const struct yaffs_packed_tags2 *pt) |
0e8cc8bd9 YAFFS2 import |
46 |
{ |
753ac6108 u-boot: Update ya... |
47 |
yaffs_dump_packed_tags2_tags_only(&pt->t); |
0e8cc8bd9 YAFFS2 import |
48 |
} |
753ac6108 u-boot: Update ya... |
49 |
static void yaffs_dump_tags2(const struct yaffs_ext_tags *t) |
0e8cc8bd9 YAFFS2 import |
50 |
{ |
753ac6108 u-boot: Update ya... |
51 52 53 54 55 |
yaffs_trace(YAFFS_TRACE_MTD, "ext.tags eccres %d blkbad %d chused %d obj %d chunk%d byte %d del %d ser %d seq %d", t->ecc_result, t->block_bad, t->chunk_used, t->obj_id, t->chunk_id, t->n_bytes, t->is_deleted, t->serial_number, t->seq_number); |
0e8cc8bd9 YAFFS2 import |
56 |
|
753ac6108 u-boot: Update ya... |
57 |
} |
0e8cc8bd9 YAFFS2 import |
58 |
|
753ac6108 u-boot: Update ya... |
59 60 61 62 63 64 65 66 67 68 69 |
static int yaffs_check_tags_extra_packable(const struct yaffs_ext_tags *t) { if (t->chunk_id != 0 || !t->extra_available) return 0; /* Check if the file size is too long to store */ if (t->extra_obj_type == YAFFS_OBJECT_TYPE_FILE && (t->extra_file_size >> 31) != 0) return 0; return 1; } |
0e8cc8bd9 YAFFS2 import |
70 |
|
753ac6108 u-boot: Update ya... |
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
void yaffs_pack_tags2_tags_only(struct yaffs_packed_tags2_tags_only *ptt, const struct yaffs_ext_tags *t) { ptt->chunk_id = t->chunk_id; ptt->seq_number = t->seq_number; ptt->n_bytes = t->n_bytes; ptt->obj_id = t->obj_id; /* Only store extra tags for object headers. * If it is a file then only store if the file size is short\ * enough to fit. */ if (yaffs_check_tags_extra_packable(t)) { /* Store the extra header info instead */ /* We save the parent object in the chunk_id */ ptt->chunk_id = EXTRA_HEADER_INFO_FLAG | t->extra_parent_id; if (t->extra_is_shrink) ptt->chunk_id |= EXTRA_SHRINK_FLAG; if (t->extra_shadows) ptt->chunk_id |= EXTRA_SHADOWS_FLAG; ptt->obj_id &= ~EXTRA_OBJECT_TYPE_MASK; ptt->obj_id |= (t->extra_obj_type << EXTRA_OBJECT_TYPE_SHIFT); if (t->extra_obj_type == YAFFS_OBJECT_TYPE_HARDLINK) ptt->n_bytes = t->extra_equiv_id; else if (t->extra_obj_type == YAFFS_OBJECT_TYPE_FILE) ptt->n_bytes = (unsigned) t->extra_file_size; else ptt->n_bytes = 0; |
0e8cc8bd9 YAFFS2 import |
101 |
} |
753ac6108 u-boot: Update ya... |
102 103 |
yaffs_dump_packed_tags2_tags_only(ptt); yaffs_dump_tags2(t); |
0e8cc8bd9 YAFFS2 import |
104 |
} |
753ac6108 u-boot: Update ya... |
105 106 |
void yaffs_pack_tags2(struct yaffs_packed_tags2 *pt, const struct yaffs_ext_tags *t, int tags_ecc) |
0e8cc8bd9 YAFFS2 import |
107 |
{ |
753ac6108 u-boot: Update ya... |
108 |
yaffs_pack_tags2_tags_only(&pt->t, t); |
0e8cc8bd9 YAFFS2 import |
109 |
|
753ac6108 u-boot: Update ya... |
110 111 112 113 114 |
if (tags_ecc) yaffs_ecc_calc_other((unsigned char *)&pt->t, sizeof(struct yaffs_packed_tags2_tags_only), &pt->ecc); } |
0e8cc8bd9 YAFFS2 import |
115 |
|
753ac6108 u-boot: Update ya... |
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
void yaffs_unpack_tags2_tags_only(struct yaffs_ext_tags *t, struct yaffs_packed_tags2_tags_only *ptt) { memset(t, 0, sizeof(struct yaffs_ext_tags)); if (ptt->seq_number == 0xffffffff) return; t->block_bad = 0; t->chunk_used = 1; t->obj_id = ptt->obj_id; t->chunk_id = ptt->chunk_id; t->n_bytes = ptt->n_bytes; t->is_deleted = 0; t->serial_number = 0; t->seq_number = ptt->seq_number; /* Do extra header info stuff */ if (ptt->chunk_id & EXTRA_HEADER_INFO_FLAG) { t->chunk_id = 0; t->n_bytes = 0; t->extra_available = 1; t->extra_parent_id = ptt->chunk_id & (~(ALL_EXTRA_FLAGS)); t->extra_is_shrink = ptt->chunk_id & EXTRA_SHRINK_FLAG ? 1 : 0; t->extra_shadows = ptt->chunk_id & EXTRA_SHADOWS_FLAG ? 1 : 0; t->extra_obj_type = ptt->obj_id >> EXTRA_OBJECT_TYPE_SHIFT; t->obj_id &= ~EXTRA_OBJECT_TYPE_MASK; if (t->extra_obj_type == YAFFS_OBJECT_TYPE_HARDLINK) t->extra_equiv_id = ptt->n_bytes; else t->extra_file_size = ptt->n_bytes; } yaffs_dump_packed_tags2_tags_only(ptt); yaffs_dump_tags2(t); } |
0e8cc8bd9 YAFFS2 import |
153 |
|
753ac6108 u-boot: Update ya... |
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
void yaffs_unpack_tags2(struct yaffs_ext_tags *t, struct yaffs_packed_tags2 *pt, int tags_ecc) { enum yaffs_ecc_result ecc_result = YAFFS_ECC_RESULT_NO_ERROR; if (pt->t.seq_number != 0xffffffff && tags_ecc) { /* Chunk is in use and we need to do ECC */ struct yaffs_ecc_other ecc; int result; yaffs_ecc_calc_other((unsigned char *)&pt->t, sizeof(struct yaffs_packed_tags2_tags_only), &ecc); result = yaffs_ecc_correct_other((unsigned char *)&pt->t, sizeof(struct yaffs_packed_tags2_tags_only), &pt->ecc, &ecc); switch (result) { case 0: ecc_result = YAFFS_ECC_RESULT_NO_ERROR; break; case 1: ecc_result = YAFFS_ECC_RESULT_FIXED; break; case -1: ecc_result = YAFFS_ECC_RESULT_UNFIXED; break; default: ecc_result = YAFFS_ECC_RESULT_UNKNOWN; |
0e8cc8bd9 YAFFS2 import |
183 184 |
} } |
753ac6108 u-boot: Update ya... |
185 |
yaffs_unpack_tags2_tags_only(t, &pt->t); |
0e8cc8bd9 YAFFS2 import |
186 |
|
753ac6108 u-boot: Update ya... |
187 |
t->ecc_result = ecc_result; |
0e8cc8bd9 YAFFS2 import |
188 |
|
753ac6108 u-boot: Update ya... |
189 190 |
yaffs_dump_packed_tags2(pt); yaffs_dump_tags2(t); |
0e8cc8bd9 YAFFS2 import |
191 |
} |