yaffs_yaffs2.c 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700
  1. /*
  2. * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  3. *
  4. * Copyright (C) 2002-2010 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_guts.h"
  14. #include "yaffs_trace.h"
  15. #include "yaffs_yaffs2.h"
  16. #include "yaffs_checkptrw.h"
  17. #include "yaffs_bitmap.h"
  18. #include "yaffs_nand.h"
  19. #include "yaffs_getblockinfo.h"
  20. #include "yaffs_verify.h"
  21. #include "yaffs_attribs.h"
  22. /*
  23. * Checkpoints are really no benefit on very small partitions.
  24. *
  25. * To save space on small partitions don't bother with checkpoints unless
  26. * the partition is at least this big.
  27. */
  28. #define YAFFS_CHECKPOINT_MIN_BLOCKS 60
  29. #define YAFFS_SMALL_HOLE_THRESHOLD 4
  30. /*
  31. * Oldest Dirty Sequence Number handling.
  32. */
  33. /* yaffs_calc_oldest_dirty_seq()
  34. * yaffs2_find_oldest_dirty_seq()
  35. * Calculate the oldest dirty sequence number if we don't know it.
  36. */
  37. void yaffs_calc_oldest_dirty_seq(struct yaffs_dev *dev)
  38. {
  39. int i;
  40. unsigned seq;
  41. unsigned block_no = 0;
  42. struct yaffs_block_info *b;
  43. if (!dev->param.is_yaffs2)
  44. return;
  45. /* Find the oldest dirty sequence number. */
  46. seq = dev->seq_number + 1;
  47. b = dev->block_info;
  48. for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) {
  49. if (b->block_state == YAFFS_BLOCK_STATE_FULL &&
  50. (b->pages_in_use - b->soft_del_pages) <
  51. dev->param.chunks_per_block && b->seq_number < seq) {
  52. seq = b->seq_number;
  53. block_no = i;
  54. }
  55. b++;
  56. }
  57. if (block_no) {
  58. dev->oldest_dirty_seq = seq;
  59. dev->oldest_dirty_block = block_no;
  60. }
  61. }
  62. void yaffs2_find_oldest_dirty_seq(struct yaffs_dev *dev)
  63. {
  64. if (!dev->param.is_yaffs2)
  65. return;
  66. if (!dev->oldest_dirty_seq)
  67. yaffs_calc_oldest_dirty_seq(dev);
  68. }
  69. /*
  70. * yaffs_clear_oldest_dirty_seq()
  71. * Called when a block is erased or marked bad. (ie. when its seq_number
  72. * becomes invalid). If the value matches the oldest then we clear
  73. * dev->oldest_dirty_seq to force its recomputation.
  74. */
  75. void yaffs2_clear_oldest_dirty_seq(struct yaffs_dev *dev,
  76. struct yaffs_block_info *bi)
  77. {
  78. if (!dev->param.is_yaffs2)
  79. return;
  80. if (!bi || bi->seq_number == dev->oldest_dirty_seq) {
  81. dev->oldest_dirty_seq = 0;
  82. dev->oldest_dirty_block = 0;
  83. }
  84. }
  85. /*
  86. * yaffs2_update_oldest_dirty_seq()
  87. * Update the oldest dirty sequence number whenever we dirty a block.
  88. * Only do this if the oldest_dirty_seq is actually being tracked.
  89. */
  90. void yaffs2_update_oldest_dirty_seq(struct yaffs_dev *dev, unsigned block_no,
  91. struct yaffs_block_info *bi)
  92. {
  93. if (!dev->param.is_yaffs2)
  94. return;
  95. if (dev->oldest_dirty_seq) {
  96. if (dev->oldest_dirty_seq > bi->seq_number) {
  97. dev->oldest_dirty_seq = bi->seq_number;
  98. dev->oldest_dirty_block = block_no;
  99. }
  100. }
  101. }
  102. int yaffs_block_ok_for_gc(struct yaffs_dev *dev, struct yaffs_block_info *bi)
  103. {
  104. int ret = 0;
  105. if (!dev->param.is_yaffs2)
  106. return 1; /* disqualification only applies to yaffs2. */
  107. if (!bi->has_shrink_hdr)
  108. return 1; /* can gc */
  109. yaffs2_find_oldest_dirty_seq(dev);
  110. /* Can't do gc of this block if there are any blocks older than this one that have
  111. * discarded pages.
  112. */
  113. ret = (bi->seq_number <= dev->oldest_dirty_seq);
  114. return ret;
  115. }
  116. /*
  117. * yaffs2_find_refresh_block()
  118. * periodically finds the oldest full block by sequence number for refreshing.
  119. * Only for yaffs2.
  120. */
  121. u32 yaffs2_find_refresh_block(struct yaffs_dev *dev)
  122. {
  123. u32 b;
  124. u32 oldest = 0;
  125. u32 oldest_seq = 0;
  126. struct yaffs_block_info *bi;
  127. if (!dev->param.is_yaffs2)
  128. return oldest;
  129. /*
  130. * If refresh period < 10 then refreshing is disabled.
  131. */
  132. if (dev->param.refresh_period < 10)
  133. return oldest;
  134. /*
  135. * Fix broken values.
  136. */
  137. if (dev->refresh_skip > dev->param.refresh_period)
  138. dev->refresh_skip = dev->param.refresh_period;
  139. if (dev->refresh_skip > 0)
  140. return oldest;
  141. /*
  142. * Refresh skip is now zero.
  143. * We'll do a refresh this time around....
  144. * Update the refresh skip and find the oldest block.
  145. */
  146. dev->refresh_skip = dev->param.refresh_period;
  147. dev->refresh_count++;
  148. bi = dev->block_info;
  149. for (b = dev->internal_start_block; b <= dev->internal_end_block; b++) {
  150. if (bi->block_state == YAFFS_BLOCK_STATE_FULL) {
  151. if (oldest < 1 || bi->seq_number < oldest_seq) {
  152. oldest = b;
  153. oldest_seq = bi->seq_number;
  154. }
  155. }
  156. bi++;
  157. }
  158. if (oldest > 0) {
  159. yaffs_trace(YAFFS_TRACE_GC,
  160. "GC refresh count %d selected block %d with seq_number %d",
  161. dev->refresh_count, oldest, oldest_seq);
  162. }
  163. return oldest;
  164. }
  165. int yaffs2_checkpt_required(struct yaffs_dev *dev)
  166. {
  167. int nblocks;
  168. if (!dev->param.is_yaffs2)
  169. return 0;
  170. nblocks = dev->internal_end_block - dev->internal_start_block + 1;
  171. return !dev->param.skip_checkpt_wr &&
  172. !dev->read_only && (nblocks >= YAFFS_CHECKPOINT_MIN_BLOCKS);
  173. }
  174. int yaffs_calc_checkpt_blocks_required(struct yaffs_dev *dev)
  175. {
  176. int retval;
  177. if (!dev->param.is_yaffs2)
  178. return 0;
  179. if (!dev->checkpoint_blocks_required && yaffs2_checkpt_required(dev)) {
  180. /* Not a valid value so recalculate */
  181. int n_bytes = 0;
  182. int n_blocks;
  183. int dev_blocks =
  184. (dev->param.end_block - dev->param.start_block + 1);
  185. n_bytes += sizeof(struct yaffs_checkpt_validity);
  186. n_bytes += sizeof(struct yaffs_checkpt_dev);
  187. n_bytes += dev_blocks * sizeof(struct yaffs_block_info);
  188. n_bytes += dev_blocks * dev->chunk_bit_stride;
  189. n_bytes +=
  190. (sizeof(struct yaffs_checkpt_obj) +
  191. sizeof(u32)) * (dev->n_obj);
  192. n_bytes += (dev->tnode_size + sizeof(u32)) * (dev->n_tnodes);
  193. n_bytes += sizeof(struct yaffs_checkpt_validity);
  194. n_bytes += sizeof(u32); /* checksum */
  195. /* Round up and add 2 blocks to allow for some bad blocks, so add 3 */
  196. n_blocks =
  197. (n_bytes /
  198. (dev->data_bytes_per_chunk *
  199. dev->param.chunks_per_block)) + 3;
  200. dev->checkpoint_blocks_required = n_blocks;
  201. }
  202. retval = dev->checkpoint_blocks_required - dev->blocks_in_checkpt;
  203. if (retval < 0)
  204. retval = 0;
  205. return retval;
  206. }
  207. /*--------------------- Checkpointing --------------------*/
  208. static int yaffs2_wr_checkpt_validity_marker(struct yaffs_dev *dev, int head)
  209. {
  210. struct yaffs_checkpt_validity cp;
  211. memset(&cp, 0, sizeof(cp));
  212. cp.struct_type = sizeof(cp);
  213. cp.magic = YAFFS_MAGIC;
  214. cp.version = YAFFS_CHECKPOINT_VERSION;
  215. cp.head = (head) ? 1 : 0;
  216. return (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp)) ? 1 : 0;
  217. }
  218. static int yaffs2_rd_checkpt_validity_marker(struct yaffs_dev *dev, int head)
  219. {
  220. struct yaffs_checkpt_validity cp;
  221. int ok;
  222. ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));
  223. if (ok)
  224. ok = (cp.struct_type == sizeof(cp)) &&
  225. (cp.magic == YAFFS_MAGIC) &&
  226. (cp.version == YAFFS_CHECKPOINT_VERSION) &&
  227. (cp.head == ((head) ? 1 : 0));
  228. return ok ? 1 : 0;
  229. }
  230. static void yaffs2_dev_to_checkpt_dev(struct yaffs_checkpt_dev *cp,
  231. struct yaffs_dev *dev)
  232. {
  233. cp->n_erased_blocks = dev->n_erased_blocks;
  234. cp->alloc_block = dev->alloc_block;
  235. cp->alloc_page = dev->alloc_page;
  236. cp->n_free_chunks = dev->n_free_chunks;
  237. cp->n_deleted_files = dev->n_deleted_files;
  238. cp->n_unlinked_files = dev->n_unlinked_files;
  239. cp->n_bg_deletions = dev->n_bg_deletions;
  240. cp->seq_number = dev->seq_number;
  241. }
  242. static void yaffs_checkpt_dev_to_dev(struct yaffs_dev *dev,
  243. struct yaffs_checkpt_dev *cp)
  244. {
  245. dev->n_erased_blocks = cp->n_erased_blocks;
  246. dev->alloc_block = cp->alloc_block;
  247. dev->alloc_page = cp->alloc_page;
  248. dev->n_free_chunks = cp->n_free_chunks;
  249. dev->n_deleted_files = cp->n_deleted_files;
  250. dev->n_unlinked_files = cp->n_unlinked_files;
  251. dev->n_bg_deletions = cp->n_bg_deletions;
  252. dev->seq_number = cp->seq_number;
  253. }
  254. static int yaffs2_wr_checkpt_dev(struct yaffs_dev *dev)
  255. {
  256. struct yaffs_checkpt_dev cp;
  257. u32 n_bytes;
  258. u32 n_blocks =
  259. (dev->internal_end_block - dev->internal_start_block + 1);
  260. int ok;
  261. /* Write device runtime values */
  262. yaffs2_dev_to_checkpt_dev(&cp, dev);
  263. cp.struct_type = sizeof(cp);
  264. ok = (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp));
  265. /* Write block info */
  266. if (ok) {
  267. n_bytes = n_blocks * sizeof(struct yaffs_block_info);
  268. ok = (yaffs2_checkpt_wr(dev, dev->block_info, n_bytes) ==
  269. n_bytes);
  270. }
  271. /* Write chunk bits */
  272. if (ok) {
  273. n_bytes = n_blocks * dev->chunk_bit_stride;
  274. ok = (yaffs2_checkpt_wr(dev, dev->chunk_bits, n_bytes) ==
  275. n_bytes);
  276. }
  277. return ok ? 1 : 0;
  278. }
  279. static int yaffs2_rd_checkpt_dev(struct yaffs_dev *dev)
  280. {
  281. struct yaffs_checkpt_dev cp;
  282. u32 n_bytes;
  283. u32 n_blocks =
  284. (dev->internal_end_block - dev->internal_start_block + 1);
  285. int ok;
  286. ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));
  287. if (!ok)
  288. return 0;
  289. if (cp.struct_type != sizeof(cp))
  290. return 0;
  291. yaffs_checkpt_dev_to_dev(dev, &cp);
  292. n_bytes = n_blocks * sizeof(struct yaffs_block_info);
  293. ok = (yaffs2_checkpt_rd(dev, dev->block_info, n_bytes) == n_bytes);
  294. if (!ok)
  295. return 0;
  296. n_bytes = n_blocks * dev->chunk_bit_stride;
  297. ok = (yaffs2_checkpt_rd(dev, dev->chunk_bits, n_bytes) == n_bytes);
  298. return ok ? 1 : 0;
  299. }
  300. static void yaffs2_obj_checkpt_obj(struct yaffs_checkpt_obj *cp,
  301. struct yaffs_obj *obj)
  302. {
  303. cp->obj_id = obj->obj_id;
  304. cp->parent_id = (obj->parent) ? obj->parent->obj_id : 0;
  305. cp->hdr_chunk = obj->hdr_chunk;
  306. cp->variant_type = obj->variant_type;
  307. cp->deleted = obj->deleted;
  308. cp->soft_del = obj->soft_del;
  309. cp->unlinked = obj->unlinked;
  310. cp->fake = obj->fake;
  311. cp->rename_allowed = obj->rename_allowed;
  312. cp->unlink_allowed = obj->unlink_allowed;
  313. cp->serial = obj->serial;
  314. cp->n_data_chunks = obj->n_data_chunks;
  315. if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE)
  316. cp->size_or_equiv_obj = obj->variant.file_variant.file_size;
  317. else if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK)
  318. cp->size_or_equiv_obj = obj->variant.hardlink_variant.equiv_id;
  319. }
  320. static int taffs2_checkpt_obj_to_obj(struct yaffs_obj *obj,
  321. struct yaffs_checkpt_obj *cp)
  322. {
  323. struct yaffs_obj *parent;
  324. if (obj->variant_type != cp->variant_type) {
  325. yaffs_trace(YAFFS_TRACE_ERROR,
  326. "Checkpoint read object %d type %d chunk %d does not match existing object type %d",
  327. cp->obj_id, cp->variant_type, cp->hdr_chunk,
  328. obj->variant_type);
  329. return 0;
  330. }
  331. obj->obj_id = cp->obj_id;
  332. if (cp->parent_id)
  333. parent = yaffs_find_or_create_by_number(obj->my_dev,
  334. cp->parent_id,
  335. YAFFS_OBJECT_TYPE_DIRECTORY);
  336. else
  337. parent = NULL;
  338. if (parent) {
  339. if (parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
  340. yaffs_trace(YAFFS_TRACE_ALWAYS,
  341. "Checkpoint read object %d parent %d type %d chunk %d Parent type, %d, not directory",
  342. cp->obj_id, cp->parent_id,
  343. cp->variant_type, cp->hdr_chunk,
  344. parent->variant_type);
  345. return 0;
  346. }
  347. yaffs_add_obj_to_dir(parent, obj);
  348. }
  349. obj->hdr_chunk = cp->hdr_chunk;
  350. obj->variant_type = cp->variant_type;
  351. obj->deleted = cp->deleted;
  352. obj->soft_del = cp->soft_del;
  353. obj->unlinked = cp->unlinked;
  354. obj->fake = cp->fake;
  355. obj->rename_allowed = cp->rename_allowed;
  356. obj->unlink_allowed = cp->unlink_allowed;
  357. obj->serial = cp->serial;
  358. obj->n_data_chunks = cp->n_data_chunks;
  359. if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE)
  360. obj->variant.file_variant.file_size = cp->size_or_equiv_obj;
  361. else if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK)
  362. obj->variant.hardlink_variant.equiv_id = cp->size_or_equiv_obj;
  363. if (obj->hdr_chunk > 0)
  364. obj->lazy_loaded = 1;
  365. return 1;
  366. }
  367. static int yaffs2_checkpt_tnode_worker(struct yaffs_obj *in,
  368. struct yaffs_tnode *tn, u32 level,
  369. int chunk_offset)
  370. {
  371. int i;
  372. struct yaffs_dev *dev = in->my_dev;
  373. int ok = 1;
  374. if (tn) {
  375. if (level > 0) {
  376. for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++) {
  377. if (tn->internal[i]) {
  378. ok = yaffs2_checkpt_tnode_worker(in,
  379. tn->
  380. internal
  381. [i],
  382. level -
  383. 1,
  384. (chunk_offset
  385. <<
  386. YAFFS_TNODES_INTERNAL_BITS)
  387. + i);
  388. }
  389. }
  390. } else if (level == 0) {
  391. u32 base_offset =
  392. chunk_offset << YAFFS_TNODES_LEVEL0_BITS;
  393. ok = (yaffs2_checkpt_wr
  394. (dev, &base_offset,
  395. sizeof(base_offset)) == sizeof(base_offset));
  396. if (ok)
  397. ok = (yaffs2_checkpt_wr
  398. (dev, tn,
  399. dev->tnode_size) == dev->tnode_size);
  400. }
  401. }
  402. return ok;
  403. }
  404. static int yaffs2_wr_checkpt_tnodes(struct yaffs_obj *obj)
  405. {
  406. u32 end_marker = ~0;
  407. int ok = 1;
  408. if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE) {
  409. ok = yaffs2_checkpt_tnode_worker(obj,
  410. obj->variant.file_variant.top,
  411. obj->variant.file_variant.
  412. top_level, 0);
  413. if (ok)
  414. ok = (yaffs2_checkpt_wr
  415. (obj->my_dev, &end_marker,
  416. sizeof(end_marker)) == sizeof(end_marker));
  417. }
  418. return ok ? 1 : 0;
  419. }
  420. static int yaffs2_rd_checkpt_tnodes(struct yaffs_obj *obj)
  421. {
  422. u32 base_chunk;
  423. int ok = 1;
  424. struct yaffs_dev *dev = obj->my_dev;
  425. struct yaffs_file_var *file_struct_ptr = &obj->variant.file_variant;
  426. struct yaffs_tnode *tn;
  427. int nread = 0;
  428. ok = (yaffs2_checkpt_rd(dev, &base_chunk, sizeof(base_chunk)) ==
  429. sizeof(base_chunk));
  430. while (ok && (~base_chunk)) {
  431. nread++;
  432. /* Read level 0 tnode */
  433. tn = yaffs_get_tnode(dev);
  434. if (tn)
  435. ok = (yaffs2_checkpt_rd(dev, tn, dev->tnode_size) ==
  436. dev->tnode_size);
  437. else
  438. ok = 0;
  439. if (tn && ok)
  440. ok = yaffs_add_find_tnode_0(dev,
  441. file_struct_ptr,
  442. base_chunk, tn) ? 1 : 0;
  443. if (ok)
  444. ok = (yaffs2_checkpt_rd
  445. (dev, &base_chunk,
  446. sizeof(base_chunk)) == sizeof(base_chunk));
  447. }
  448. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  449. "Checkpoint read tnodes %d records, last %d. ok %d",
  450. nread, base_chunk, ok);
  451. return ok ? 1 : 0;
  452. }
  453. static int yaffs2_wr_checkpt_objs(struct yaffs_dev *dev)
  454. {
  455. struct yaffs_obj *obj;
  456. struct yaffs_checkpt_obj cp;
  457. int i;
  458. int ok = 1;
  459. struct list_head *lh;
  460. /* Iterate through the objects in each hash entry,
  461. * dumping them to the checkpointing stream.
  462. */
  463. for (i = 0; ok && i < YAFFS_NOBJECT_BUCKETS; i++) {
  464. list_for_each(lh, &dev->obj_bucket[i].list) {
  465. if (lh) {
  466. obj =
  467. list_entry(lh, struct yaffs_obj, hash_link);
  468. if (!obj->defered_free) {
  469. yaffs2_obj_checkpt_obj(&cp, obj);
  470. cp.struct_type = sizeof(cp);
  471. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  472. "Checkpoint write object %d parent %d type %d chunk %d obj addr %p",
  473. cp.obj_id, cp.parent_id,
  474. cp.variant_type, cp.hdr_chunk, obj);
  475. ok = (yaffs2_checkpt_wr
  476. (dev, &cp,
  477. sizeof(cp)) == sizeof(cp));
  478. if (ok
  479. && obj->variant_type ==
  480. YAFFS_OBJECT_TYPE_FILE)
  481. ok = yaffs2_wr_checkpt_tnodes
  482. (obj);
  483. }
  484. }
  485. }
  486. }
  487. /* Dump end of list */
  488. memset(&cp, 0xFF, sizeof(struct yaffs_checkpt_obj));
  489. cp.struct_type = sizeof(cp);
  490. if (ok)
  491. ok = (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp));
  492. return ok ? 1 : 0;
  493. }
  494. static int yaffs2_rd_checkpt_objs(struct yaffs_dev *dev)
  495. {
  496. struct yaffs_obj *obj;
  497. struct yaffs_checkpt_obj cp;
  498. int ok = 1;
  499. int done = 0;
  500. struct yaffs_obj *hard_list = NULL;
  501. while (ok && !done) {
  502. ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));
  503. if (cp.struct_type != sizeof(cp)) {
  504. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  505. "struct size %d instead of %d ok %d",
  506. cp.struct_type, (int)sizeof(cp), ok);
  507. ok = 0;
  508. }
  509. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  510. "Checkpoint read object %d parent %d type %d chunk %d ",
  511. cp.obj_id, cp.parent_id, cp.variant_type,
  512. cp.hdr_chunk);
  513. if (ok && cp.obj_id == ~0) {
  514. done = 1;
  515. } else if (ok) {
  516. obj =
  517. yaffs_find_or_create_by_number(dev, cp.obj_id,
  518. cp.variant_type);
  519. if (obj) {
  520. ok = taffs2_checkpt_obj_to_obj(obj, &cp);
  521. if (!ok)
  522. break;
  523. if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE)
  524. ok = yaffs2_rd_checkpt_tnodes(obj);
  525. else if (obj->variant_type ==
  526. YAFFS_OBJECT_TYPE_HARDLINK) {
  527. obj->hard_links.next =
  528. (struct list_head *)hard_list;
  529. hard_list = obj;
  530. }
  531. } else
  532. ok = 0;
  533. }
  534. }
  535. if (ok)
  536. yaffs_link_fixup(dev, hard_list);
  537. return ok ? 1 : 0;
  538. }
  539. static int yaffs2_wr_checkpt_sum(struct yaffs_dev *dev)
  540. {
  541. u32 checkpt_sum;
  542. int ok;
  543. yaffs2_get_checkpt_sum(dev, &checkpt_sum);
  544. ok = (yaffs2_checkpt_wr(dev, &checkpt_sum, sizeof(checkpt_sum)) ==
  545. sizeof(checkpt_sum));
  546. if (!ok)
  547. return 0;
  548. return 1;
  549. }
  550. static int yaffs2_rd_checkpt_sum(struct yaffs_dev *dev)
  551. {
  552. u32 checkpt_sum0;
  553. u32 checkpt_sum1;
  554. int ok;
  555. yaffs2_get_checkpt_sum(dev, &checkpt_sum0);
  556. ok = (yaffs2_checkpt_rd(dev, &checkpt_sum1, sizeof(checkpt_sum1)) ==
  557. sizeof(checkpt_sum1));
  558. if (!ok)
  559. return 0;
  560. if (checkpt_sum0 != checkpt_sum1)
  561. return 0;
  562. return 1;
  563. }
  564. static int yaffs2_wr_checkpt_data(struct yaffs_dev *dev)
  565. {
  566. int ok = 1;
  567. if (!yaffs2_checkpt_required(dev)) {
  568. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  569. "skipping checkpoint write");
  570. ok = 0;
  571. }
  572. if (ok)
  573. ok = yaffs2_checkpt_open(dev, 1);
  574. if (ok) {
  575. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  576. "write checkpoint validity");
  577. ok = yaffs2_wr_checkpt_validity_marker(dev, 1);
  578. }
  579. if (ok) {
  580. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  581. "write checkpoint device");
  582. ok = yaffs2_wr_checkpt_dev(dev);
  583. }
  584. if (ok) {
  585. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  586. "write checkpoint objects");
  587. ok = yaffs2_wr_checkpt_objs(dev);
  588. }
  589. if (ok) {
  590. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  591. "write checkpoint validity");
  592. ok = yaffs2_wr_checkpt_validity_marker(dev, 0);
  593. }
  594. if (ok)
  595. ok = yaffs2_wr_checkpt_sum(dev);
  596. if (!yaffs_checkpt_close(dev))
  597. ok = 0;
  598. if (ok)
  599. dev->is_checkpointed = 1;
  600. else
  601. dev->is_checkpointed = 0;
  602. return dev->is_checkpointed;
  603. }
  604. static int yaffs2_rd_checkpt_data(struct yaffs_dev *dev)
  605. {
  606. int ok = 1;
  607. if (!dev->param.is_yaffs2)
  608. ok = 0;
  609. if (ok && dev->param.skip_checkpt_rd) {
  610. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  611. "skipping checkpoint read");
  612. ok = 0;
  613. }
  614. if (ok)
  615. ok = yaffs2_checkpt_open(dev, 0); /* open for read */
  616. if (ok) {
  617. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  618. "read checkpoint validity");
  619. ok = yaffs2_rd_checkpt_validity_marker(dev, 1);
  620. }
  621. if (ok) {
  622. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  623. "read checkpoint device");
  624. ok = yaffs2_rd_checkpt_dev(dev);
  625. }
  626. if (ok) {
  627. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  628. "read checkpoint objects");
  629. ok = yaffs2_rd_checkpt_objs(dev);
  630. }
  631. if (ok) {
  632. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  633. "read checkpoint validity");
  634. ok = yaffs2_rd_checkpt_validity_marker(dev, 0);
  635. }
  636. if (ok) {
  637. ok = yaffs2_rd_checkpt_sum(dev);
  638. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  639. "read checkpoint checksum %d", ok);
  640. }
  641. if (!yaffs_checkpt_close(dev))
  642. ok = 0;
  643. if (ok)
  644. dev->is_checkpointed = 1;
  645. else
  646. dev->is_checkpointed = 0;
  647. return ok ? 1 : 0;
  648. }
  649. void yaffs2_checkpt_invalidate(struct yaffs_dev *dev)
  650. {
  651. if (dev->is_checkpointed || dev->blocks_in_checkpt > 0) {
  652. dev->is_checkpointed = 0;
  653. yaffs2_checkpt_invalidate_stream(dev);
  654. }
  655. if (dev->param.sb_dirty_fn)
  656. dev->param.sb_dirty_fn(dev);
  657. }
  658. int yaffs_checkpoint_save(struct yaffs_dev *dev)
  659. {
  660. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  661. "save entry: is_checkpointed %d",
  662. dev->is_checkpointed);
  663. yaffs_verify_objects(dev);
  664. yaffs_verify_blocks(dev);
  665. yaffs_verify_free_chunks(dev);
  666. if (!dev->is_checkpointed) {
  667. yaffs2_checkpt_invalidate(dev);
  668. yaffs2_wr_checkpt_data(dev);
  669. }
  670. yaffs_trace(YAFFS_TRACE_CHECKPOINT | YAFFS_TRACE_MOUNT,
  671. "save exit: is_checkpointed %d",
  672. dev->is_checkpointed);
  673. return dev->is_checkpointed;
  674. }
  675. int yaffs2_checkpt_restore(struct yaffs_dev *dev)
  676. {
  677. int retval;
  678. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  679. "restore entry: is_checkpointed %d",
  680. dev->is_checkpointed);
  681. retval = yaffs2_rd_checkpt_data(dev);
  682. if (dev->is_checkpointed) {
  683. yaffs_verify_objects(dev);
  684. yaffs_verify_blocks(dev);
  685. yaffs_verify_free_chunks(dev);
  686. }
  687. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  688. "restore exit: is_checkpointed %d",
  689. dev->is_checkpointed);
  690. return retval;
  691. }
  692. int yaffs2_handle_hole(struct yaffs_obj *obj, loff_t new_size)
  693. {
  694. /* if new_size > old_file_size.
  695. * We're going to be writing a hole.
  696. * If the hole is small then write zeros otherwise write a start of hole marker.
  697. */
  698. loff_t old_file_size;
  699. int increase;
  700. int small_hole;
  701. int result = YAFFS_OK;
  702. struct yaffs_dev *dev = NULL;
  703. u8 *local_buffer = NULL;
  704. int small_increase_ok = 0;
  705. if (!obj)
  706. return YAFFS_FAIL;
  707. if (obj->variant_type != YAFFS_OBJECT_TYPE_FILE)
  708. return YAFFS_FAIL;
  709. dev = obj->my_dev;
  710. /* Bail out if not yaffs2 mode */
  711. if (!dev->param.is_yaffs2)
  712. return YAFFS_OK;
  713. old_file_size = obj->variant.file_variant.file_size;
  714. if (new_size <= old_file_size)
  715. return YAFFS_OK;
  716. increase = new_size - old_file_size;
  717. if (increase < YAFFS_SMALL_HOLE_THRESHOLD * dev->data_bytes_per_chunk &&
  718. yaffs_check_alloc_available(dev, YAFFS_SMALL_HOLE_THRESHOLD + 1))
  719. small_hole = 1;
  720. else
  721. small_hole = 0;
  722. if (small_hole)
  723. local_buffer = yaffs_get_temp_buffer(dev, __LINE__);
  724. if (local_buffer) {
  725. /* fill hole with zero bytes */
  726. int pos = old_file_size;
  727. int this_write;
  728. int written;
  729. memset(local_buffer, 0, dev->data_bytes_per_chunk);
  730. small_increase_ok = 1;
  731. while (increase > 0 && small_increase_ok) {
  732. this_write = increase;
  733. if (this_write > dev->data_bytes_per_chunk)
  734. this_write = dev->data_bytes_per_chunk;
  735. written =
  736. yaffs_do_file_wr(obj, local_buffer, pos, this_write,
  737. 0);
  738. if (written == this_write) {
  739. pos += this_write;
  740. increase -= this_write;
  741. } else
  742. small_increase_ok = 0;
  743. }
  744. yaffs_release_temp_buffer(dev, local_buffer, __LINE__);
  745. /* If we were out of space then reverse any chunks we've added */
  746. if (!small_increase_ok)
  747. yaffs_resize_file_down(obj, old_file_size);
  748. }
  749. if (!small_increase_ok &&
  750. obj->parent &&
  751. obj->parent->obj_id != YAFFS_OBJECTID_UNLINKED &&
  752. obj->parent->obj_id != YAFFS_OBJECTID_DELETED)
  753. /* Write a hole start header with the old file size */
  754. yaffs_update_oh(obj, NULL, 0, 1, 0, NULL);
  755. return result;
  756. }
  757. struct yaffs_block_index {
  758. unsigned int seq;
  759. int block;
  760. };
  761. static int yaffs2_ybicmp(const void *a, const void *b)
  762. {
  763. unsigned int aseq = ((struct yaffs_block_index *)a)->seq;
  764. unsigned int bseq = ((struct yaffs_block_index *)b)->seq;
  765. int ablock = ((struct yaffs_block_index *)a)->block;
  766. int bblock = ((struct yaffs_block_index *)b)->block;
  767. if (aseq == bseq)
  768. return ablock - bblock;
  769. if (aseq > bseq)
  770. return 1;
  771. else
  772. return -1;
  773. /*
  774. else
  775. return aseq - bseq;*/
  776. }
  777. #ifdef YAFFS_MVG_TEST_ERASECHEKFF
  778. static int yaffs_ScanCheckEraseClean(struct yaffs_dev *dev,
  779. int chunkInNAND, int page)
  780. {
  781. int retval = YAFFS_OK;
  782. u8 *data = yaffs_get_temp_buffer(dev, __LINE__);
  783. struct yaffs_ext_tags tags;
  784. int result;
  785. result = yaffs_rd_chunk_tags_nand(dev, chunkInNAND, data, &tags);
  786. if (tags.ecc_result > YAFFS_ECC_RESULT_NO_ERROR)
  787. retval = YAFFS_FAIL;
  788. if (!yaffs_check_ff(data, dev->data_bytes_per_chunk) || tags.chunk_used) {
  789. pr_err("Chunk %d not erased", chunkInNAND);
  790. retval = YAFFS_FAIL;
  791. /*add debug by jinling.ke*/
  792. pr_err("yaffsdebug Scan CheckChunk chunk:%d addr:0x%x chunkUsed:%d page:%d\n",
  793. chunkInNAND, chunkInNAND * dev->data_bytes_per_chunk, tags.chunk_used, page);
  794. mtk_dump_byte(&tags, sizeof(struct yaffs_ext_tags), 0);
  795. }
  796. yaffs_release_temp_buffer(dev, data, __LINE__);
  797. return retval;
  798. }
  799. #endif
  800. int yaffs2_scan_backwards(struct yaffs_dev *dev)
  801. {
  802. struct yaffs_ext_tags tags;
  803. int blk;
  804. int block_iter;
  805. int start_iter;
  806. int end_iter;
  807. int n_to_scan = 0;
  808. int chunk;
  809. int result;
  810. int c;
  811. int deleted;
  812. enum yaffs_block_state state;
  813. struct yaffs_obj *hard_list = NULL;
  814. struct yaffs_block_info *bi;
  815. u32 seq_number;
  816. struct yaffs_obj_hdr *oh;
  817. struct yaffs_obj *in;
  818. struct yaffs_obj *parent;
  819. int n_blocks = dev->internal_end_block - dev->internal_start_block + 1;
  820. int is_unlinked;
  821. u8 *chunk_data;
  822. u32 file_size;
  823. int is_shrink;
  824. int found_chunks;
  825. int equiv_id;
  826. int alloc_failed = 0;
  827. /*power loss*/
  828. int check_on = 0;
  829. int i;
  830. int retv = 0;
  831. int check_block = 20;
  832. /*power loss*/
  833. struct yaffs_block_index *block_index = NULL;
  834. int alt_block_index = 0;
  835. yaffs_trace(YAFFS_TRACE_SCAN,
  836. "yaffs2_scan_backwards starts intstartblk %d intendblk %d...",
  837. dev->internal_start_block, dev->internal_end_block);
  838. dev->seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER;
  839. block_index = kcalloc(n_blocks, sizeof(struct yaffs_block_index),
  840. GFP_NOFS);
  841. if (!block_index) {
  842. block_index =
  843. vmalloc(n_blocks * sizeof(struct yaffs_block_index));
  844. alt_block_index = 1;
  845. }
  846. if (!block_index) {
  847. yaffs_trace(YAFFS_TRACE_SCAN,
  848. "yaffs2_scan_backwards() could not allocate block index!"
  849. );
  850. return YAFFS_FAIL;
  851. }
  852. dev->blocks_in_checkpt = 0;
  853. chunk_data = yaffs_get_temp_buffer(dev, __LINE__);
  854. /* Scan all the blocks to determine their state */
  855. bi = dev->block_info;
  856. for (blk = dev->internal_start_block; blk <= dev->internal_end_block;
  857. blk++) {
  858. yaffs_clear_chunk_bits(dev, blk);
  859. bi->pages_in_use = 0;
  860. bi->soft_del_pages = 0;
  861. yaffs_query_init_block_state(dev, blk, &state, &seq_number);
  862. bi->block_state = state;
  863. bi->seq_number = seq_number;
  864. if (bi->seq_number == YAFFS_SEQUENCE_CHECKPOINT_DATA)
  865. bi->block_state = state = YAFFS_BLOCK_STATE_CHECKPOINT;
  866. if (bi->seq_number == YAFFS_SEQUENCE_BAD_BLOCK)
  867. bi->block_state = state = YAFFS_BLOCK_STATE_DEAD;
  868. yaffs_trace(YAFFS_TRACE_SCAN_DEBUG,
  869. "Block scanning block %d state %d seq %d",
  870. blk, state, seq_number);
  871. if (state == YAFFS_BLOCK_STATE_CHECKPOINT) {
  872. dev->blocks_in_checkpt++;
  873. } else if (state == YAFFS_BLOCK_STATE_DEAD) {
  874. yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
  875. "block %d is bad", blk);
  876. } else if (state == YAFFS_BLOCK_STATE_EMPTY) {
  877. #ifdef YAFFS_MVG_TEST_ERASECHEKFF
  878. for (c = 0; c < dev->param.chunks_per_block; c++)
  879. yaffs_ScanCheckEraseClean(dev, blk * dev->param.chunks_per_block + c, c);
  880. #endif
  881. /*erase all empty block when scan*/
  882. if (!yaffs_erase_block(dev, blk)) {
  883. dev->n_erase_failures++;
  884. yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
  885. "**>> Erasure failed %d", blk);
  886. continue;
  887. }
  888. yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "Block empty ");
  889. dev->n_erased_blocks++;
  890. dev->n_free_chunks += dev->param.chunks_per_block;
  891. } else if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
  892. /* Determine the highest sequence number */
  893. if (seq_number >= YAFFS_LOWEST_SEQUENCE_NUMBER &&
  894. seq_number < YAFFS_HIGHEST_SEQUENCE_NUMBER) {
  895. block_index[n_to_scan].seq = seq_number;
  896. block_index[n_to_scan].block = blk;
  897. n_to_scan++;
  898. if (seq_number >= dev->seq_number)
  899. dev->seq_number = seq_number;
  900. } else {
  901. /* TODO: Nasty sequence number! */
  902. yaffs_trace(YAFFS_TRACE_SCAN,
  903. "Block scanning block %d has bad sequence number %d",
  904. blk, seq_number);
  905. }
  906. }
  907. bi++;
  908. }
  909. yaffs_trace(YAFFS_TRACE_SCAN, "%d blocks to be sorted...", n_to_scan);
  910. cond_resched();
  911. /* Sort the blocks by sequence number */
  912. sort(block_index, n_to_scan, sizeof(struct yaffs_block_index),
  913. yaffs2_ybicmp, NULL);
  914. cond_resched();
  915. yaffs_trace(YAFFS_TRACE_SCAN, "...done");
  916. /* Now scan the blocks looking at the data. */
  917. start_iter = 0;
  918. end_iter = n_to_scan - 1;
  919. yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "%d blocks to scan", n_to_scan);
  920. #ifdef YAFFS_MVG_TEST_DUMP_SCAN_SEQ
  921. pr_err("yaffsdebug scandumpblockseq devn:%s scann:%d s:%d e:%d\n",
  922. dev->param.name, n_to_scan, dev->internal_start_block, dev->internal_end_block);
  923. if (!strcmp(dev->param.name, "userdata")) {/*only dump userdata partition seq num.*/
  924. unsigned int *buf = kmalloc(n_to_scan * 4, GFP_NOFS);
  925. unsigned int *p = buf;
  926. unsigned short int *sp;
  927. for (block_iter = end_iter; block_iter >= start_iter; block_iter--)
  928. *p++ = block_index[block_iter].seq;
  929. mtk_dump_word(buf, n_to_scan * 4, 0, 1);
  930. sp = (unsigned short int *)buf;
  931. for (block_iter = end_iter; block_iter >= start_iter; block_iter--)
  932. *sp++ = block_index[block_iter].block;
  933. pr_err("yaffsdebug scandumpblocknum:\n");
  934. mtk_dump_hword(buf, n_to_scan * 2, 0, 1);
  935. kfree(buf);
  936. }
  937. #endif
  938. /* For each block.... backwards */
  939. for (block_iter = end_iter; !alloc_failed && block_iter >= start_iter;
  940. block_iter--) {
  941. /* Cooperative multitasking! This loop can run for so
  942. long that watchdog timers expire. */
  943. cond_resched();
  944. check_on = 1;
  945. /* get the block to scan in the correct order */
  946. blk = block_index[block_iter].block;
  947. bi = yaffs_get_block_info(dev, blk);
  948. state = bi->block_state;
  949. deleted = 0;
  950. /* For each chunk in each block that needs scanning.... */
  951. found_chunks = 0;
  952. for (c = dev->param.chunks_per_block - 1;
  953. !alloc_failed && c >= 0 &&
  954. (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
  955. state == YAFFS_BLOCK_STATE_ALLOCATING); c--) {
  956. /* Scan backwards...
  957. * Read the tags and decide what to do
  958. */
  959. chunk = blk * dev->param.chunks_per_block + c;
  960. result = yaffs_rd_chunk_tags_nand(dev, chunk, chunk_data,
  961. &tags);
  962. /* Let's have a good look at this chunk... */
  963. if (!tags.chunk_used) {
  964. /* An unassigned chunk in the block.
  965. * If there are used chunks after this one, then
  966. * it is a chunk that was skipped due to failing the erased
  967. * check. Just skip it so that it can be deleted.
  968. * But, more typically, We get here when this is an unallocated
  969. * chunk and his means that either the block is empty or
  970. * this is the one being allocated from
  971. */
  972. if (found_chunks) {
  973. /* This is a chunk that was skipped due to failing the erased check */
  974. } else if (c == 0) {
  975. /* We're looking at the first chunk in the block so the block is unused */
  976. state = YAFFS_BLOCK_STATE_EMPTY;
  977. dev->n_erased_blocks++;
  978. } else {
  979. if (state != YAFFS_BLOCK_STATE_NEEDS_SCANNING &&
  980. state != YAFFS_BLOCK_STATE_ALLOCATING) {
  981. dev->n_free_chunks++;
  982. continue;
  983. }
  984. if (dev->seq_number == bi->seq_number) {
  985. /* this is the block being allocated from */
  986. yaffs_trace(YAFFS_TRACE_SCAN,
  987. " Allocating from %d %d",
  988. blk, c);
  989. state = YAFFS_BLOCK_STATE_ALLOCATING;
  990. dev->alloc_block = blk;
  991. dev->alloc_page = c;
  992. dev->alloc_block_finder = blk;
  993. } else
  994. /* This is a partially written block that is not
  995. * the current allocation block.
  996. */
  997. yaffs_trace(YAFFS_TRACE_SCAN,
  998. "Partially written block %d detected", blk);
  999. }
  1000. dev->n_free_chunks++;
  1001. continue;
  1002. } else if (tags.ecc_result == YAFFS_ECC_RESULT_UNFIXED) {
  1003. yaffs_trace(YAFFS_TRACE_SCAN,
  1004. " Unfixed ECC in chunk(%d:%d), chunk ignored",
  1005. blk, c);
  1006. dev->n_free_chunks++;
  1007. continue;
  1008. } else if (tags.obj_id > YAFFS_MAX_OBJECT_ID ||
  1009. tags.chunk_id > YAFFS_MAX_CHUNK_ID ||
  1010. (tags.chunk_id > 0
  1011. && tags.n_bytes > dev->data_bytes_per_chunk)
  1012. || tags.seq_number != bi->seq_number) {
  1013. yaffs_trace(YAFFS_TRACE_SCAN,
  1014. "Chunk (%d:%d) with bad tags:obj = %d, chunk_id = %d, n_bytes = %d, ignored",
  1015. blk, c, tags.obj_id,
  1016. tags.chunk_id, tags.n_bytes);
  1017. dev->n_free_chunks++;
  1018. continue;
  1019. }
  1020. /*add by jiequn*/
  1021. if (check_on && (check_block > 0)) {
  1022. struct yaffs_ext_tags tempTags;
  1023. u8 *buffer = yaffs_get_temp_buffer(dev, __LINE__);
  1024. retv = 0;
  1025. for (i = 0; i < 8; i++) {
  1026. int result;
  1027. result = yaffs_rd_chunk_tags_nand(dev, chunk, buffer, &tempTags);
  1028. if (YAFFS_ECC_RESULT_UNFIXED == tempTags.ecc_result) {
  1029. retv = -1;
  1030. break;
  1031. } else if (memcmp(buffer, chunk_data, dev->data_bytes_per_chunk) ||
  1032. tempTags.obj_id != tags.obj_id ||
  1033. tempTags.chunk_id != tags.chunk_id ||
  1034. tempTags.n_bytes != tags.n_bytes) {
  1035. retv = -2;
  1036. break;
  1037. }
  1038. }
  1039. if (retv < 0) {
  1040. dev->n_free_chunks++;
  1041. pr_err("yaffsdebug re-check page fail!retv:%d i:%d eccr:%d cb:%d sn:%d\n",
  1042. retv, i, tags.ecc_result, check_block, bi->seq_number);
  1043. check_on = 0;
  1044. check_block--;
  1045. #ifdef YAFFS_MVG_TEST_DEBUG_LOG
  1046. pr_err("dump data cant fixed ecc!chunk:%d addr:0x%x\n",
  1047. chunk, chunk * dev->data_bytes_per_chunk);
  1048. mtk_dump_byte(chunk_data, dev->data_bytes_per_chunk, 0);
  1049. pr_err("dump tag\n");
  1050. mtk_dump_byte(&tags, sizeof(struct yaffs_ext_tags), 0);
  1051. pr_err("dump tmpdata cant fixed ecc!chunk:%d addr:0x%x\n",
  1052. chunk, chunk * dev->data_bytes_per_chunk);
  1053. mtk_dump_byte(buffer, dev->data_bytes_per_chunk, 0);
  1054. pr_err("dump tmptag\n");
  1055. mtk_dump_byte(&tempTags, sizeof(struct yaffs_ext_tags), 0);
  1056. #endif
  1057. yaffs_release_temp_buffer(dev, buffer, __LINE__);
  1058. continue;
  1059. }
  1060. yaffs_release_temp_buffer(dev, buffer, __LINE__);
  1061. check_on = 0;
  1062. check_block--;
  1063. }
  1064. /*add by jiequn*/
  1065. if (tags.chunk_id > 0) {
  1066. /* chunk_id > 0 so it is a data chunk... */
  1067. unsigned int endpos;
  1068. u32 chunk_base = (tags.chunk_id - 1) * dev->data_bytes_per_chunk;
  1069. found_chunks = 1;
  1070. yaffs_set_chunk_bit(dev, blk, c);
  1071. bi->pages_in_use++;
  1072. in = yaffs_find_or_create_by_number(dev,
  1073. tags.obj_id,
  1074. YAFFS_OBJECT_TYPE_FILE);
  1075. if (!in) {
  1076. /* Out of memory */
  1077. alloc_failed = 1;
  1078. }
  1079. if (in &&
  1080. in->variant_type == YAFFS_OBJECT_TYPE_FILE
  1081. && chunk_base <
  1082. in->variant.file_variant.shrink_size) {
  1083. /* This has not been invalidated by a resize */
  1084. if (!yaffs_put_chunk_in_file
  1085. (in, tags.chunk_id, chunk, -1)) {
  1086. alloc_failed = 1;
  1087. }
  1088. /* File size is calculated by looking at the data chunks if we have not
  1089. * seen an object header yet. Stop this practice once we find an object
  1090. * header.
  1091. */
  1092. endpos = chunk_base + tags.n_bytes;
  1093. if (!in->valid && /* have not got an object header yet */
  1094. in->variant.file_variant.
  1095. scanned_size < endpos) {
  1096. in->variant.file_variant.
  1097. scanned_size = endpos;
  1098. in->variant.file_variant.
  1099. file_size = endpos;
  1100. }
  1101. } else if (in) {
  1102. /* This chunk has been invalidated by a resize, or a past file deletion
  1103. * so delete the chunk*/
  1104. yaffs_chunk_del(dev, chunk, 1,
  1105. __LINE__);
  1106. }
  1107. continue;
  1108. }
  1109. /* chunk_id == 0, so it is an ObjectHeader.
  1110. * Thus, we read in the object header and make the object
  1111. */
  1112. found_chunks = 1;
  1113. yaffs_set_chunk_bit(dev, blk, c);
  1114. bi->pages_in_use++;
  1115. oh = NULL;
  1116. in = NULL;
  1117. if (tags.extra_available) {
  1118. in = yaffs_find_or_create_by_number(dev,
  1119. tags.obj_id,
  1120. tags.extra_obj_type);
  1121. if (!in)
  1122. alloc_failed = 1;
  1123. }
  1124. if (!in ||
  1125. (!in->valid && dev->param.disable_lazy_load)
  1126. || tags.extra_shadows || (!in->valid
  1127. && (tags.obj_id ==
  1128. YAFFS_OBJECTID_ROOT
  1129. || tags.
  1130. obj_id ==
  1131. YAFFS_OBJECTID_LOSTNFOUND))) {
  1132. /* If we don't have valid info then we need to read the chunk
  1133. * TODO In future we can probably defer reading the chunk and
  1134. * living with invalid data until needed.
  1135. */
  1136. result = yaffs_rd_chunk_tags_nand(dev, chunk, chunk_data, NULL);
  1137. oh = (struct yaffs_obj_hdr *)chunk_data;
  1138. if (dev->param.inband_tags) {
  1139. /* Fix up the header if they got corrupted by inband tags */
  1140. oh->shadows_obj =
  1141. oh->inband_shadowed_obj_id;
  1142. oh->is_shrink =
  1143. oh->inband_is_shrink;
  1144. }
  1145. if (!in) {
  1146. in = yaffs_find_or_create_by_number(dev, tags.obj_id, oh->type);
  1147. if (!in)
  1148. alloc_failed = 1;
  1149. }
  1150. }
  1151. if (!in) {
  1152. /* TODO Hoosterman we have a problem! */
  1153. yaffs_trace(YAFFS_TRACE_ERROR,
  1154. "yaffs tragedy: Could not make object for object %d at chunk %d during scan",
  1155. tags.obj_id, chunk);
  1156. continue;
  1157. }
  1158. if (in->valid) {
  1159. /* We have already filled this one.
  1160. * We have a duplicate that will be discarded, but
  1161. * we first have to suck out resize info if it is a file.
  1162. */
  1163. if ((in->variant_type ==
  1164. YAFFS_OBJECT_TYPE_FILE) && ((oh
  1165. &&
  1166. oh->
  1167. type
  1168. ==
  1169. YAFFS_OBJECT_TYPE_FILE)
  1170. ||
  1171. (tags.
  1172. extra_available
  1173. &&
  1174. tags.
  1175. extra_obj_type
  1176. ==
  1177. YAFFS_OBJECT_TYPE_FILE))) {
  1178. u32 this_size =
  1179. (oh) ? oh->
  1180. file_size :
  1181. tags.extra_length;
  1182. u32 parent_obj_id =
  1183. (oh) ? oh->parent_obj_id :
  1184. tags.extra_parent_id;
  1185. is_shrink =
  1186. (oh) ? oh->
  1187. is_shrink :
  1188. tags.extra_is_shrink;
  1189. /* If it is deleted (unlinked at start also means deleted)
  1190. * we treat the file size as being zeroed at this point.
  1191. */
  1192. if (parent_obj_id ==
  1193. YAFFS_OBJECTID_DELETED
  1194. || parent_obj_id ==
  1195. YAFFS_OBJECTID_UNLINKED) {
  1196. this_size = 0;
  1197. is_shrink = 1;
  1198. }
  1199. if (is_shrink
  1200. && in->variant.file_variant.
  1201. shrink_size > this_size)
  1202. in->variant.
  1203. file_variant.
  1204. shrink_size =
  1205. this_size;
  1206. if (is_shrink)
  1207. bi->has_shrink_hdr = 1;
  1208. }
  1209. /* Use existing - destroy this one. */
  1210. yaffs_chunk_del(dev, chunk, 1,
  1211. __LINE__);
  1212. }
  1213. if (!in->valid && in->variant_type !=
  1214. (oh ? oh->type : tags.extra_obj_type))
  1215. yaffs_trace(YAFFS_TRACE_ERROR,
  1216. "yaffs tragedy: Bad object type, %d != %d, for object %d at chunk %d during scan",
  1217. oh ?
  1218. oh->type : tags.extra_obj_type,
  1219. in->variant_type, tags.obj_id,
  1220. chunk);
  1221. if (!in->valid &&
  1222. (tags.obj_id == YAFFS_OBJECTID_ROOT ||
  1223. tags.obj_id ==
  1224. YAFFS_OBJECTID_LOSTNFOUND)) {
  1225. /* We only load some info, don't fiddle with directory structure */
  1226. in->valid = 1;
  1227. if (oh) {
  1228. in->yst_mode = oh->yst_mode;
  1229. yaffs_load_attribs(in, oh);
  1230. in->lazy_loaded = 0;
  1231. } else
  1232. in->lazy_loaded = 1;
  1233. in->hdr_chunk = chunk;
  1234. } else if (!in->valid) {
  1235. /* we need to load this info */
  1236. in->valid = 1;
  1237. in->hdr_chunk = chunk;
  1238. if (oh) {
  1239. in->variant_type = oh->type;
  1240. in->yst_mode = oh->yst_mode;
  1241. yaffs_load_attribs(in, oh);
  1242. if (oh->shadows_obj > 0)
  1243. yaffs_handle_shadowed_obj
  1244. (dev,
  1245. oh->shadows_obj,
  1246. 1);
  1247. yaffs_set_obj_name_from_oh(in,
  1248. oh);
  1249. parent =
  1250. yaffs_find_or_create_by_number
  1251. (dev, oh->parent_obj_id,
  1252. YAFFS_OBJECT_TYPE_DIRECTORY);
  1253. file_size = oh->file_size;
  1254. is_shrink = oh->is_shrink;
  1255. equiv_id = oh->equiv_id;
  1256. } else {
  1257. in->variant_type =
  1258. tags.extra_obj_type;
  1259. parent =
  1260. yaffs_find_or_create_by_number
  1261. (dev, tags.extra_parent_id,
  1262. YAFFS_OBJECT_TYPE_DIRECTORY);
  1263. file_size = tags.extra_length;
  1264. is_shrink =
  1265. tags.extra_is_shrink;
  1266. equiv_id = tags.extra_equiv_id;
  1267. in->lazy_loaded = 1;
  1268. }
  1269. in->dirty = 0;
  1270. if (!parent)
  1271. alloc_failed = 1;
  1272. /* directory stuff...
  1273. * hook up to parent
  1274. */
  1275. if (parent && parent->variant_type ==
  1276. YAFFS_OBJECT_TYPE_UNKNOWN) {
  1277. /* Set up as a directory */
  1278. parent->variant_type =
  1279. YAFFS_OBJECT_TYPE_DIRECTORY;
  1280. INIT_LIST_HEAD(&parent->
  1281. variant.dir_variant.children);
  1282. } else if (!parent
  1283. || parent->variant_type !=
  1284. YAFFS_OBJECT_TYPE_DIRECTORY) {
  1285. /* Hoosterman, another problem....
  1286. * We're trying to use a non-directory as a directory
  1287. */
  1288. yaffs_trace(YAFFS_TRACE_ERROR,
  1289. "yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
  1290. );
  1291. parent = dev->lost_n_found;
  1292. }
  1293. yaffs_add_obj_to_dir(parent, in);
  1294. is_unlinked = (parent == dev->del_dir)
  1295. || (parent == dev->unlinked_dir);
  1296. if (is_shrink) {
  1297. /* Mark the block as having a shrink header */
  1298. bi->has_shrink_hdr = 1;
  1299. }
  1300. /* Note re hardlinks.
  1301. * Since we might scan a hardlink before its equivalent object is
  1302. * scanned we put them all in a list.
  1303. * After scanning is complete, we should have all the objects, so we run
  1304. * through this list and fix up all the chains.
  1305. */
  1306. switch (in->variant_type) {
  1307. case YAFFS_OBJECT_TYPE_UNKNOWN:
  1308. /* Todo got a problem */
  1309. break;
  1310. case YAFFS_OBJECT_TYPE_FILE:
  1311. if (in->variant.file_variant.scanned_size < file_size) {
  1312. /* This covers the case where the file size is greater
  1313. * than where the data is
  1314. * This will happen if the file is resized to be larger
  1315. * than its current data extents.
  1316. */
  1317. in->variant.file_variant.file_size = file_size;
  1318. in->variant.file_variant.scanned_size = file_size;
  1319. }
  1320. if (in->variant.file_variant.
  1321. shrink_size > file_size)
  1322. in->variant.file_variant.shrink_size = file_size;
  1323. break;
  1324. case YAFFS_OBJECT_TYPE_HARDLINK:
  1325. if (!is_unlinked) {
  1326. in->variant.hardlink_variant.equiv_id = equiv_id;
  1327. in->hard_links.next = (struct list_head *)hard_list;
  1328. hard_list = in;
  1329. }
  1330. break;
  1331. case YAFFS_OBJECT_TYPE_DIRECTORY:
  1332. /* Do nothing */
  1333. break;
  1334. case YAFFS_OBJECT_TYPE_SPECIAL:
  1335. /* Do nothing */
  1336. break;
  1337. case YAFFS_OBJECT_TYPE_SYMLINK:
  1338. if (!oh)
  1339. break;
  1340. in->variant.symlink_variant.alias = yaffs_clone_str(oh->alias);
  1341. if (!in->variant.symlink_variant.alias)
  1342. alloc_failed = 1;
  1343. break;
  1344. }
  1345. }
  1346. } /* End of scanning for each chunk */
  1347. if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
  1348. /* If we got this far while scanning, then the block is fully allocated. */
  1349. state = YAFFS_BLOCK_STATE_FULL;
  1350. }
  1351. bi->block_state = state;
  1352. /* Now let's see if it was dirty */
  1353. if (bi->pages_in_use == 0 &&
  1354. !bi->has_shrink_hdr &&
  1355. bi->block_state == YAFFS_BLOCK_STATE_FULL) {
  1356. yaffs_block_became_dirty(dev, blk);
  1357. }
  1358. }
  1359. yaffs_skip_rest_of_block(dev);
  1360. if (alt_block_index)
  1361. vfree(block_index);
  1362. else
  1363. kfree(block_index);
  1364. /* Ok, we've done all the scanning.
  1365. * Fix up the hard link chains.
  1366. * We should now have scanned all the objects, now it's time to add these
  1367. * hardlinks.
  1368. */
  1369. yaffs_link_fixup(dev, hard_list);
  1370. yaffs_release_temp_buffer(dev, chunk_data, __LINE__);
  1371. if (alloc_failed)
  1372. return YAFFS_FAIL;
  1373. yaffs_trace(YAFFS_TRACE_SCAN, "yaffs2_scan_backwards ends");
  1374. return YAFFS_OK;
  1375. }