yaffs_packedtags2.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  3. *
  4. * Copyright (C) 2002-2007 Aleph One Ltd.
  5. * for Toby Churchill Ltd and Brightstar Engineering
  6. *
  7. * Created by Charles Manning <charles@aleph1.co.uk>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 as
  11. * published by the Free Software Foundation.
  12. */
  13. #include "yaffs_packedtags2.h"
  14. #include "yportenv.h"
  15. #include "yaffs_tagsvalidity.h"
  16. /* This code packs a set of extended tags into a binary structure for
  17. * NAND storage
  18. */
  19. /* Some of the information is "extra" struff which can be packed in to
  20. * speed scanning
  21. * This is defined by having the EXTRA_HEADER_INFO_FLAG set.
  22. */
  23. /* Extra flags applied to chunkId */
  24. #define EXTRA_HEADER_INFO_FLAG 0x80000000
  25. #define EXTRA_SHRINK_FLAG 0x40000000
  26. #define EXTRA_SHADOWS_FLAG 0x20000000
  27. #define EXTRA_SPARE_FLAGS 0x10000000
  28. #define ALL_EXTRA_FLAGS 0xF0000000
  29. /* Also, the top 4 bits of the object Id are set to the object type. */
  30. #define EXTRA_OBJECT_TYPE_SHIFT (28)
  31. #define EXTRA_OBJECT_TYPE_MASK ((0x0F) << EXTRA_OBJECT_TYPE_SHIFT)
  32. static void yaffs_DumpPackedTags2(const yaffs_PackedTags2 * pt)
  33. {
  34. T(YAFFS_TRACE_MTD,
  35. (TSTR("packed tags obj %d chunk %d byte %d seq %d" TENDSTR),
  36. pt->t.objectId, pt->t.chunkId, pt->t.byteCount,
  37. pt->t.sequenceNumber));
  38. }
  39. static void yaffs_DumpTags2(const yaffs_ExtendedTags * t)
  40. {
  41. T(YAFFS_TRACE_MTD,
  42. (TSTR
  43. ("ext.tags eccres %d blkbad %d chused %d obj %d chunk%d byte "
  44. "%d del %d ser %d seq %d"
  45. TENDSTR), t->eccResult, t->blockBad, t->chunkUsed, t->objectId,
  46. t->chunkId, t->byteCount, t->chunkDeleted, t->serialNumber,
  47. t->sequenceNumber));
  48. }
  49. void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t)
  50. {
  51. pt->t.chunkId = t->chunkId;
  52. pt->t.sequenceNumber = t->sequenceNumber;
  53. pt->t.byteCount = t->byteCount;
  54. pt->t.objectId = t->objectId;
  55. if (t->chunkId == 0 && t->extraHeaderInfoAvailable) {
  56. /* Store the extra header info instead */
  57. /* We save the parent object in the chunkId */
  58. pt->t.chunkId = EXTRA_HEADER_INFO_FLAG
  59. | t->extraParentObjectId;
  60. if (t->extraIsShrinkHeader) {
  61. pt->t.chunkId |= EXTRA_SHRINK_FLAG;
  62. }
  63. if (t->extraShadows) {
  64. pt->t.chunkId |= EXTRA_SHADOWS_FLAG;
  65. }
  66. pt->t.objectId &= ~EXTRA_OBJECT_TYPE_MASK;
  67. pt->t.objectId |=
  68. (t->extraObjectType << EXTRA_OBJECT_TYPE_SHIFT);
  69. if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK) {
  70. pt->t.byteCount = t->extraEquivalentObjectId;
  71. } else if (t->extraObjectType == YAFFS_OBJECT_TYPE_FILE) {
  72. pt->t.byteCount = t->extraFileLength;
  73. } else {
  74. pt->t.byteCount = 0;
  75. }
  76. }
  77. yaffs_DumpPackedTags2(pt);
  78. yaffs_DumpTags2(t);
  79. #ifndef YAFFS_IGNORE_TAGS_ECC
  80. {
  81. yaffs_ECCCalculateOther((unsigned char *)&pt->t,
  82. sizeof(yaffs_PackedTags2TagsPart),
  83. &pt->ecc);
  84. }
  85. #endif
  86. }
  87. void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt)
  88. {
  89. memset(t, 0, sizeof(yaffs_ExtendedTags));
  90. yaffs_InitialiseTags(t);
  91. if (pt->t.sequenceNumber != 0xFFFFFFFF) {
  92. /* Page is in use */
  93. #ifdef YAFFS_IGNORE_TAGS_ECC
  94. {
  95. t->eccResult = YAFFS_ECC_RESULT_NO_ERROR;
  96. }
  97. #else
  98. {
  99. yaffs_ECCOther ecc;
  100. int result;
  101. yaffs_ECCCalculateOther((unsigned char *)&pt->t,
  102. sizeof
  103. (yaffs_PackedTags2TagsPart),
  104. &ecc);
  105. result =
  106. yaffs_ECCCorrectOther((unsigned char *)&pt->t,
  107. sizeof
  108. (yaffs_PackedTags2TagsPart),
  109. &pt->ecc, &ecc);
  110. switch(result){
  111. case 0:
  112. t->eccResult = YAFFS_ECC_RESULT_NO_ERROR;
  113. break;
  114. case 1:
  115. t->eccResult = YAFFS_ECC_RESULT_FIXED;
  116. break;
  117. case -1:
  118. t->eccResult = YAFFS_ECC_RESULT_UNFIXED;
  119. break;
  120. default:
  121. t->eccResult = YAFFS_ECC_RESULT_UNKNOWN;
  122. }
  123. }
  124. #endif
  125. t->blockBad = 0;
  126. t->chunkUsed = 1;
  127. t->objectId = pt->t.objectId;
  128. t->chunkId = pt->t.chunkId;
  129. t->byteCount = pt->t.byteCount;
  130. t->chunkDeleted = 0;
  131. t->serialNumber = 0;
  132. t->sequenceNumber = pt->t.sequenceNumber;
  133. /* Do extra header info stuff */
  134. if (pt->t.chunkId & EXTRA_HEADER_INFO_FLAG) {
  135. t->chunkId = 0;
  136. t->byteCount = 0;
  137. t->extraHeaderInfoAvailable = 1;
  138. t->extraParentObjectId =
  139. pt->t.chunkId & (~(ALL_EXTRA_FLAGS));
  140. t->extraIsShrinkHeader =
  141. (pt->t.chunkId & EXTRA_SHRINK_FLAG) ? 1 : 0;
  142. t->extraShadows =
  143. (pt->t.chunkId & EXTRA_SHADOWS_FLAG) ? 1 : 0;
  144. t->extraObjectType =
  145. pt->t.objectId >> EXTRA_OBJECT_TYPE_SHIFT;
  146. t->objectId &= ~EXTRA_OBJECT_TYPE_MASK;
  147. if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK) {
  148. t->extraEquivalentObjectId = pt->t.byteCount;
  149. } else {
  150. t->extraFileLength = pt->t.byteCount;
  151. }
  152. }
  153. }
  154. yaffs_DumpPackedTags2(pt);
  155. yaffs_DumpTags2(t);
  156. }