yaffs_yaffs2.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599
  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. if (!dev->param.is_yaffs2)
  105. return 1; /* disqualification only applies to yaffs2. */
  106. if (!bi->has_shrink_hdr)
  107. return 1; /* can gc */
  108. yaffs2_find_oldest_dirty_seq(dev);
  109. /* Can't do gc of this block if there are any blocks older than this one that have
  110. * discarded pages.
  111. */
  112. return (bi->seq_number <= dev->oldest_dirty_seq);
  113. }
  114. /*
  115. * yaffs2_find_refresh_block()
  116. * periodically finds the oldest full block by sequence number for refreshing.
  117. * Only for yaffs2.
  118. */
  119. u32 yaffs2_find_refresh_block(struct yaffs_dev * dev)
  120. {
  121. u32 b;
  122. u32 oldest = 0;
  123. u32 oldest_seq = 0;
  124. struct yaffs_block_info *bi;
  125. if (!dev->param.is_yaffs2)
  126. return oldest;
  127. /*
  128. * If refresh period < 10 then refreshing is disabled.
  129. */
  130. if (dev->param.refresh_period < 10)
  131. return oldest;
  132. /*
  133. * Fix broken values.
  134. */
  135. if (dev->refresh_skip > dev->param.refresh_period)
  136. dev->refresh_skip = dev->param.refresh_period;
  137. if (dev->refresh_skip > 0)
  138. return oldest;
  139. /*
  140. * Refresh skip is now zero.
  141. * We'll do a refresh this time around....
  142. * Update the refresh skip and find the oldest block.
  143. */
  144. dev->refresh_skip = dev->param.refresh_period;
  145. dev->refresh_count++;
  146. bi = dev->block_info;
  147. for (b = dev->internal_start_block; b <= dev->internal_end_block; b++) {
  148. if (bi->block_state == YAFFS_BLOCK_STATE_FULL) {
  149. if (oldest < 1 || bi->seq_number < oldest_seq) {
  150. oldest = b;
  151. oldest_seq = bi->seq_number;
  152. }
  153. }
  154. bi++;
  155. }
  156. if (oldest > 0) {
  157. yaffs_trace(YAFFS_TRACE_GC,
  158. "GC refresh count %d selected block %d with seq_number %d",
  159. dev->refresh_count, oldest, oldest_seq);
  160. }
  161. return oldest;
  162. }
  163. int yaffs2_checkpt_required(struct yaffs_dev *dev)
  164. {
  165. int nblocks;
  166. if (!dev->param.is_yaffs2)
  167. return 0;
  168. nblocks = dev->internal_end_block - dev->internal_start_block + 1;
  169. return !dev->param.skip_checkpt_wr &&
  170. !dev->read_only && (nblocks >= YAFFS_CHECKPOINT_MIN_BLOCKS);
  171. }
  172. int yaffs_calc_checkpt_blocks_required(struct yaffs_dev *dev)
  173. {
  174. int retval;
  175. if (!dev->param.is_yaffs2)
  176. return 0;
  177. if (!dev->checkpoint_blocks_required && yaffs2_checkpt_required(dev)) {
  178. /* Not a valid value so recalculate */
  179. int n_bytes = 0;
  180. int n_blocks;
  181. int dev_blocks =
  182. (dev->param.end_block - dev->param.start_block + 1);
  183. n_bytes += sizeof(struct yaffs_checkpt_validity);
  184. n_bytes += sizeof(struct yaffs_checkpt_dev);
  185. n_bytes += dev_blocks * sizeof(struct yaffs_block_info);
  186. n_bytes += dev_blocks * dev->chunk_bit_stride;
  187. n_bytes +=
  188. (sizeof(struct yaffs_checkpt_obj) +
  189. sizeof(u32)) * (dev->n_obj);
  190. n_bytes += (dev->tnode_size + sizeof(u32)) * (dev->n_tnodes);
  191. n_bytes += sizeof(struct yaffs_checkpt_validity);
  192. n_bytes += sizeof(u32); /* checksum */
  193. /* Round up and add 2 blocks to allow for some bad blocks, so add 3 */
  194. n_blocks =
  195. (n_bytes /
  196. (dev->data_bytes_per_chunk *
  197. dev->param.chunks_per_block)) + 3;
  198. dev->checkpoint_blocks_required = n_blocks;
  199. }
  200. retval = dev->checkpoint_blocks_required - dev->blocks_in_checkpt;
  201. if (retval < 0)
  202. retval = 0;
  203. return retval;
  204. }
  205. /*--------------------- Checkpointing --------------------*/
  206. static int yaffs2_wr_checkpt_validity_marker(struct yaffs_dev *dev, int head)
  207. {
  208. struct yaffs_checkpt_validity cp;
  209. memset(&cp, 0, sizeof(cp));
  210. cp.struct_type = sizeof(cp);
  211. cp.magic = YAFFS_MAGIC;
  212. cp.version = YAFFS_CHECKPOINT_VERSION;
  213. cp.head = (head) ? 1 : 0;
  214. return (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp)) ? 1 : 0;
  215. }
  216. static int yaffs2_rd_checkpt_validity_marker(struct yaffs_dev *dev, int head)
  217. {
  218. struct yaffs_checkpt_validity cp;
  219. int ok;
  220. ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));
  221. if (ok)
  222. ok = (cp.struct_type == sizeof(cp)) &&
  223. (cp.magic == YAFFS_MAGIC) &&
  224. (cp.version == YAFFS_CHECKPOINT_VERSION) &&
  225. (cp.head == ((head) ? 1 : 0));
  226. return ok ? 1 : 0;
  227. }
  228. static void yaffs2_dev_to_checkpt_dev(struct yaffs_checkpt_dev *cp,
  229. struct yaffs_dev *dev)
  230. {
  231. cp->n_erased_blocks = dev->n_erased_blocks;
  232. cp->alloc_block = dev->alloc_block;
  233. cp->alloc_page = dev->alloc_page;
  234. cp->n_free_chunks = dev->n_free_chunks;
  235. cp->n_deleted_files = dev->n_deleted_files;
  236. cp->n_unlinked_files = dev->n_unlinked_files;
  237. cp->n_bg_deletions = dev->n_bg_deletions;
  238. cp->seq_number = dev->seq_number;
  239. }
  240. static void yaffs_checkpt_dev_to_dev(struct yaffs_dev *dev,
  241. struct yaffs_checkpt_dev *cp)
  242. {
  243. dev->n_erased_blocks = cp->n_erased_blocks;
  244. dev->alloc_block = cp->alloc_block;
  245. dev->alloc_page = cp->alloc_page;
  246. dev->n_free_chunks = cp->n_free_chunks;
  247. dev->n_deleted_files = cp->n_deleted_files;
  248. dev->n_unlinked_files = cp->n_unlinked_files;
  249. dev->n_bg_deletions = cp->n_bg_deletions;
  250. dev->seq_number = cp->seq_number;
  251. }
  252. static int yaffs2_wr_checkpt_dev(struct yaffs_dev *dev)
  253. {
  254. struct yaffs_checkpt_dev cp;
  255. u32 n_bytes;
  256. u32 n_blocks =
  257. (dev->internal_end_block - dev->internal_start_block + 1);
  258. int ok;
  259. /* Write device runtime values */
  260. yaffs2_dev_to_checkpt_dev(&cp, dev);
  261. cp.struct_type = sizeof(cp);
  262. ok = (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp));
  263. /* Write block info */
  264. if (ok) {
  265. n_bytes = n_blocks * sizeof(struct yaffs_block_info);
  266. ok = (yaffs2_checkpt_wr(dev, dev->block_info, n_bytes) ==
  267. n_bytes);
  268. }
  269. /* Write chunk bits */
  270. if (ok) {
  271. n_bytes = n_blocks * dev->chunk_bit_stride;
  272. ok = (yaffs2_checkpt_wr(dev, dev->chunk_bits, n_bytes) ==
  273. n_bytes);
  274. }
  275. return ok ? 1 : 0;
  276. }
  277. static int yaffs2_rd_checkpt_dev(struct yaffs_dev *dev)
  278. {
  279. struct yaffs_checkpt_dev cp;
  280. u32 n_bytes;
  281. u32 n_blocks =
  282. (dev->internal_end_block - dev->internal_start_block + 1);
  283. int ok;
  284. ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));
  285. if (!ok)
  286. return 0;
  287. if (cp.struct_type != sizeof(cp))
  288. return 0;
  289. yaffs_checkpt_dev_to_dev(dev, &cp);
  290. n_bytes = n_blocks * sizeof(struct yaffs_block_info);
  291. ok = (yaffs2_checkpt_rd(dev, dev->block_info, n_bytes) == n_bytes);
  292. if (!ok)
  293. return 0;
  294. n_bytes = n_blocks * dev->chunk_bit_stride;
  295. ok = (yaffs2_checkpt_rd(dev, dev->chunk_bits, n_bytes) == n_bytes);
  296. return ok ? 1 : 0;
  297. }
  298. static void yaffs2_obj_checkpt_obj(struct yaffs_checkpt_obj *cp,
  299. struct yaffs_obj *obj)
  300. {
  301. cp->obj_id = obj->obj_id;
  302. cp->parent_id = (obj->parent) ? obj->parent->obj_id : 0;
  303. cp->hdr_chunk = obj->hdr_chunk;
  304. cp->variant_type = obj->variant_type;
  305. cp->deleted = obj->deleted;
  306. cp->soft_del = obj->soft_del;
  307. cp->unlinked = obj->unlinked;
  308. cp->fake = obj->fake;
  309. cp->rename_allowed = obj->rename_allowed;
  310. cp->unlink_allowed = obj->unlink_allowed;
  311. cp->serial = obj->serial;
  312. cp->n_data_chunks = obj->n_data_chunks;
  313. if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE)
  314. cp->size_or_equiv_obj = obj->variant.file_variant.file_size;
  315. else if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK)
  316. cp->size_or_equiv_obj = obj->variant.hardlink_variant.equiv_id;
  317. }
  318. static int taffs2_checkpt_obj_to_obj(struct yaffs_obj *obj,
  319. struct yaffs_checkpt_obj *cp)
  320. {
  321. struct yaffs_obj *parent;
  322. if (obj->variant_type != cp->variant_type) {
  323. yaffs_trace(YAFFS_TRACE_ERROR,
  324. "Checkpoint read object %d type %d chunk %d does not match existing object type %d",
  325. cp->obj_id, cp->variant_type, cp->hdr_chunk,
  326. obj->variant_type);
  327. return 0;
  328. }
  329. obj->obj_id = cp->obj_id;
  330. if (cp->parent_id)
  331. parent = yaffs_find_or_create_by_number(obj->my_dev,
  332. cp->parent_id,
  333. YAFFS_OBJECT_TYPE_DIRECTORY);
  334. else
  335. parent = NULL;
  336. if (parent) {
  337. if (parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
  338. yaffs_trace(YAFFS_TRACE_ALWAYS,
  339. "Checkpoint read object %d parent %d type %d chunk %d Parent type, %d, not directory",
  340. cp->obj_id, cp->parent_id,
  341. cp->variant_type, cp->hdr_chunk,
  342. parent->variant_type);
  343. return 0;
  344. }
  345. yaffs_add_obj_to_dir(parent, obj);
  346. }
  347. obj->hdr_chunk = cp->hdr_chunk;
  348. obj->variant_type = cp->variant_type;
  349. obj->deleted = cp->deleted;
  350. obj->soft_del = cp->soft_del;
  351. obj->unlinked = cp->unlinked;
  352. obj->fake = cp->fake;
  353. obj->rename_allowed = cp->rename_allowed;
  354. obj->unlink_allowed = cp->unlink_allowed;
  355. obj->serial = cp->serial;
  356. obj->n_data_chunks = cp->n_data_chunks;
  357. if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE)
  358. obj->variant.file_variant.file_size = cp->size_or_equiv_obj;
  359. else if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK)
  360. obj->variant.hardlink_variant.equiv_id = cp->size_or_equiv_obj;
  361. if (obj->hdr_chunk > 0)
  362. obj->lazy_loaded = 1;
  363. return 1;
  364. }
  365. static int yaffs2_checkpt_tnode_worker(struct yaffs_obj *in,
  366. struct yaffs_tnode *tn, u32 level,
  367. int chunk_offset)
  368. {
  369. int i;
  370. struct yaffs_dev *dev = in->my_dev;
  371. int ok = 1;
  372. if (tn) {
  373. if (level > 0) {
  374. for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++) {
  375. if (tn->internal[i]) {
  376. ok = yaffs2_checkpt_tnode_worker(in,
  377. tn->
  378. internal
  379. [i],
  380. level -
  381. 1,
  382. (chunk_offset
  383. <<
  384. YAFFS_TNODES_INTERNAL_BITS)
  385. + i);
  386. }
  387. }
  388. } else if (level == 0) {
  389. u32 base_offset =
  390. chunk_offset << YAFFS_TNODES_LEVEL0_BITS;
  391. ok = (yaffs2_checkpt_wr
  392. (dev, &base_offset,
  393. sizeof(base_offset)) == sizeof(base_offset));
  394. if (ok)
  395. ok = (yaffs2_checkpt_wr
  396. (dev, tn,
  397. dev->tnode_size) == dev->tnode_size);
  398. }
  399. }
  400. return ok;
  401. }
  402. static int yaffs2_wr_checkpt_tnodes(struct yaffs_obj *obj)
  403. {
  404. u32 end_marker = ~0;
  405. int ok = 1;
  406. if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE) {
  407. ok = yaffs2_checkpt_tnode_worker(obj,
  408. obj->variant.file_variant.top,
  409. obj->variant.file_variant.
  410. top_level, 0);
  411. if (ok)
  412. ok = (yaffs2_checkpt_wr
  413. (obj->my_dev, &end_marker,
  414. sizeof(end_marker)) == sizeof(end_marker));
  415. }
  416. return ok ? 1 : 0;
  417. }
  418. static int yaffs2_rd_checkpt_tnodes(struct yaffs_obj *obj)
  419. {
  420. u32 base_chunk;
  421. int ok = 1;
  422. struct yaffs_dev *dev = obj->my_dev;
  423. struct yaffs_file_var *file_stuct_ptr = &obj->variant.file_variant;
  424. struct yaffs_tnode *tn;
  425. int nread = 0;
  426. ok = (yaffs2_checkpt_rd(dev, &base_chunk, sizeof(base_chunk)) ==
  427. sizeof(base_chunk));
  428. while (ok && (~base_chunk)) {
  429. nread++;
  430. /* Read level 0 tnode */
  431. tn = yaffs_get_tnode(dev);
  432. if (tn) {
  433. ok = (yaffs2_checkpt_rd(dev, tn, dev->tnode_size) ==
  434. dev->tnode_size);
  435. } else {
  436. ok = 0;
  437. }
  438. if (tn && ok)
  439. ok = yaffs_add_find_tnode_0(dev,
  440. file_stuct_ptr,
  441. base_chunk, tn) ? 1 : 0;
  442. if (ok)
  443. ok = (yaffs2_checkpt_rd
  444. (dev, &base_chunk,
  445. sizeof(base_chunk)) == sizeof(base_chunk));
  446. }
  447. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  448. "Checkpoint read tnodes %d records, last %d. ok %d",
  449. nread, base_chunk, ok);
  450. return ok ? 1 : 0;
  451. }
  452. static int yaffs2_wr_checkpt_objs(struct yaffs_dev *dev)
  453. {
  454. struct yaffs_obj *obj;
  455. struct yaffs_checkpt_obj cp;
  456. int i;
  457. int ok = 1;
  458. struct list_head *lh;
  459. /* Iterate through the objects in each hash entry,
  460. * dumping them to the checkpointing stream.
  461. */
  462. for (i = 0; ok && i < YAFFS_NOBJECT_BUCKETS; i++) {
  463. list_for_each(lh, &dev->obj_bucket[i].list) {
  464. if (lh) {
  465. obj =
  466. list_entry(lh, struct yaffs_obj, hash_link);
  467. if (!obj->defered_free) {
  468. yaffs2_obj_checkpt_obj(&cp, obj);
  469. cp.struct_type = sizeof(cp);
  470. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  471. "Checkpoint write object %d parent %d type %d chunk %d obj addr %p",
  472. cp.obj_id, cp.parent_id,
  473. cp.variant_type, cp.hdr_chunk, obj);
  474. ok = (yaffs2_checkpt_wr
  475. (dev, &cp,
  476. sizeof(cp)) == sizeof(cp));
  477. if (ok
  478. && obj->variant_type ==
  479. YAFFS_OBJECT_TYPE_FILE)
  480. ok = yaffs2_wr_checkpt_tnodes
  481. (obj);
  482. }
  483. }
  484. }
  485. }
  486. /* Dump end of list */
  487. memset(&cp, 0xFF, sizeof(struct yaffs_checkpt_obj));
  488. cp.struct_type = sizeof(cp);
  489. if (ok)
  490. ok = (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp));
  491. return ok ? 1 : 0;
  492. }
  493. static int yaffs2_rd_checkpt_objs(struct yaffs_dev *dev)
  494. {
  495. struct yaffs_obj *obj;
  496. struct yaffs_checkpt_obj cp;
  497. int ok = 1;
  498. int done = 0;
  499. struct yaffs_obj *hard_list = NULL;
  500. while (ok && !done) {
  501. ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));
  502. if (cp.struct_type != sizeof(cp)) {
  503. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  504. "struct size %d instead of %d ok %d",
  505. cp.struct_type, (int)sizeof(cp), ok);
  506. ok = 0;
  507. }
  508. yaffs_trace(YAFFS_TRACE_CHECKPOINT,
  509. "Checkpoint read object %d parent %d type %d chunk %d ",
  510. cp.obj_id, cp.parent_id, cp.variant_type,
  511. cp.hdr_chunk);
  512. if (ok && cp.obj_id == ~0) {
  513. done = 1;
  514. } else if (ok) {
  515. obj =
  516. yaffs_find_or_create_by_number(dev, cp.obj_id,
  517. cp.variant_type);
  518. if (obj) {
  519. ok = taffs2_checkpt_obj_to_obj(obj, &cp);
  520. if (!ok)
  521. break;
  522. if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE) {
  523. ok = yaffs2_rd_checkpt_tnodes(obj);
  524. } else if (obj->variant_type ==
  525. YAFFS_OBJECT_TYPE_HARDLINK) {
  526. obj->hard_links.next =
  527. (struct list_head *)hard_list;
  528. hard_list = obj;
  529. }
  530. } else {
  531. ok = 0;
  532. }
  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. }
  745. yaffs_release_temp_buffer(dev, local_buffer, __LINE__);
  746. /* If we were out of space then reverse any chunks we've added */
  747. if (!small_increase_ok)
  748. yaffs_resize_file_down(obj, old_file_size);
  749. }
  750. if (!small_increase_ok &&
  751. obj->parent &&
  752. obj->parent->obj_id != YAFFS_OBJECTID_UNLINKED &&
  753. obj->parent->obj_id != YAFFS_OBJECTID_DELETED) {
  754. /* Write a hole start header with the old file size */
  755. yaffs_update_oh(obj, NULL, 0, 1, 0, NULL);
  756. }
  757. return result;
  758. }
  759. struct yaffs_block_index {
  760. int seq;
  761. int block;
  762. };
  763. static int yaffs2_ybicmp(const void *a, const void *b)
  764. {
  765. int aseq = ((struct yaffs_block_index *)a)->seq;
  766. int bseq = ((struct yaffs_block_index *)b)->seq;
  767. int ablock = ((struct yaffs_block_index *)a)->block;
  768. int bblock = ((struct yaffs_block_index *)b)->block;
  769. if (aseq == bseq)
  770. return ablock - bblock;
  771. else
  772. return aseq - bseq;
  773. }
  774. int yaffs2_scan_backwards(struct yaffs_dev *dev)
  775. {
  776. struct yaffs_ext_tags tags;
  777. int blk;
  778. int block_iter;
  779. int start_iter;
  780. int end_iter;
  781. int n_to_scan = 0;
  782. int chunk;
  783. int result;
  784. int c;
  785. int deleted;
  786. enum yaffs_block_state state;
  787. struct yaffs_obj *hard_list = NULL;
  788. struct yaffs_block_info *bi;
  789. u32 seq_number;
  790. struct yaffs_obj_hdr *oh;
  791. struct yaffs_obj *in;
  792. struct yaffs_obj *parent;
  793. int n_blocks = dev->internal_end_block - dev->internal_start_block + 1;
  794. int is_unlinked;
  795. u8 *chunk_data;
  796. int file_size;
  797. int is_shrink;
  798. int found_chunks;
  799. int equiv_id;
  800. int alloc_failed = 0;
  801. struct yaffs_block_index *block_index = NULL;
  802. int alt_block_index = 0;
  803. yaffs_trace(YAFFS_TRACE_SCAN,
  804. "yaffs2_scan_backwards starts intstartblk %d intendblk %d...",
  805. dev->internal_start_block, dev->internal_end_block);
  806. dev->seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER;
  807. block_index = kmalloc(n_blocks * sizeof(struct yaffs_block_index),
  808. GFP_NOFS);
  809. if (!block_index) {
  810. block_index =
  811. vmalloc(n_blocks * sizeof(struct yaffs_block_index));
  812. alt_block_index = 1;
  813. }
  814. if (!block_index) {
  815. yaffs_trace(YAFFS_TRACE_SCAN,
  816. "yaffs2_scan_backwards() could not allocate block index!"
  817. );
  818. return YAFFS_FAIL;
  819. }
  820. dev->blocks_in_checkpt = 0;
  821. chunk_data = yaffs_get_temp_buffer(dev, __LINE__);
  822. /* Scan all the blocks to determine their state */
  823. bi = dev->block_info;
  824. for (blk = dev->internal_start_block; blk <= dev->internal_end_block;
  825. blk++) {
  826. yaffs_clear_chunk_bits(dev, blk);
  827. bi->pages_in_use = 0;
  828. bi->soft_del_pages = 0;
  829. yaffs_query_init_block_state(dev, blk, &state, &seq_number);
  830. bi->block_state = state;
  831. bi->seq_number = seq_number;
  832. if (bi->seq_number == YAFFS_SEQUENCE_CHECKPOINT_DATA)
  833. bi->block_state = state = YAFFS_BLOCK_STATE_CHECKPOINT;
  834. if (bi->seq_number == YAFFS_SEQUENCE_BAD_BLOCK)
  835. bi->block_state = state = YAFFS_BLOCK_STATE_DEAD;
  836. yaffs_trace(YAFFS_TRACE_SCAN_DEBUG,
  837. "Block scanning block %d state %d seq %d",
  838. blk, state, seq_number);
  839. if (state == YAFFS_BLOCK_STATE_CHECKPOINT) {
  840. dev->blocks_in_checkpt++;
  841. } else if (state == YAFFS_BLOCK_STATE_DEAD) {
  842. yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
  843. "block %d is bad", blk);
  844. } else if (state == YAFFS_BLOCK_STATE_EMPTY) {
  845. yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "Block empty ");
  846. dev->n_erased_blocks++;
  847. dev->n_free_chunks += dev->param.chunks_per_block;
  848. } else if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
  849. /* Determine the highest sequence number */
  850. if (seq_number >= YAFFS_LOWEST_SEQUENCE_NUMBER &&
  851. seq_number < YAFFS_HIGHEST_SEQUENCE_NUMBER) {
  852. block_index[n_to_scan].seq = seq_number;
  853. block_index[n_to_scan].block = blk;
  854. n_to_scan++;
  855. if (seq_number >= dev->seq_number)
  856. dev->seq_number = seq_number;
  857. } else {
  858. /* TODO: Nasty sequence number! */
  859. yaffs_trace(YAFFS_TRACE_SCAN,
  860. "Block scanning block %d has bad sequence number %d",
  861. blk, seq_number);
  862. }
  863. }
  864. bi++;
  865. }
  866. yaffs_trace(YAFFS_TRACE_SCAN, "%d blocks to be sorted...", n_to_scan);
  867. cond_resched();
  868. /* Sort the blocks by sequence number */
  869. sort(block_index, n_to_scan, sizeof(struct yaffs_block_index),
  870. yaffs2_ybicmp, NULL);
  871. cond_resched();
  872. yaffs_trace(YAFFS_TRACE_SCAN, "...done");
  873. /* Now scan the blocks looking at the data. */
  874. start_iter = 0;
  875. end_iter = n_to_scan - 1;
  876. yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "%d blocks to scan", n_to_scan);
  877. /* For each block.... backwards */
  878. for (block_iter = end_iter; !alloc_failed && block_iter >= start_iter;
  879. block_iter--) {
  880. /* Cooperative multitasking! This loop can run for so
  881. long that watchdog timers expire. */
  882. cond_resched();
  883. /* get the block to scan in the correct order */
  884. blk = block_index[block_iter].block;
  885. bi = yaffs_get_block_info(dev, blk);
  886. state = bi->block_state;
  887. deleted = 0;
  888. /* For each chunk in each block that needs scanning.... */
  889. found_chunks = 0;
  890. for (c = dev->param.chunks_per_block - 1;
  891. !alloc_failed && c >= 0 &&
  892. (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
  893. state == YAFFS_BLOCK_STATE_ALLOCATING); c--) {
  894. /* Scan backwards...
  895. * Read the tags and decide what to do
  896. */
  897. chunk = blk * dev->param.chunks_per_block + c;
  898. result = yaffs_rd_chunk_tags_nand(dev, chunk, NULL,
  899. &tags);
  900. /* Let's have a good look at this chunk... */
  901. if (!tags.chunk_used) {
  902. /* An unassigned chunk in the block.
  903. * If there are used chunks after this one, then
  904. * it is a chunk that was skipped due to failing the erased
  905. * check. Just skip it so that it can be deleted.
  906. * But, more typically, We get here when this is an unallocated
  907. * chunk and his means that either the block is empty or
  908. * this is the one being allocated from
  909. */
  910. if (found_chunks) {
  911. /* This is a chunk that was skipped due to failing the erased check */
  912. } else if (c == 0) {
  913. /* We're looking at the first chunk in the block so the block is unused */
  914. state = YAFFS_BLOCK_STATE_EMPTY;
  915. dev->n_erased_blocks++;
  916. } else {
  917. if (state ==
  918. YAFFS_BLOCK_STATE_NEEDS_SCANNING
  919. || state ==
  920. YAFFS_BLOCK_STATE_ALLOCATING) {
  921. if (dev->seq_number ==
  922. bi->seq_number) {
  923. /* this is the block being allocated from */
  924. yaffs_trace(YAFFS_TRACE_SCAN,
  925. " Allocating from %d %d",
  926. blk, c);
  927. state =
  928. YAFFS_BLOCK_STATE_ALLOCATING;
  929. dev->alloc_block = blk;
  930. dev->alloc_page = c;
  931. dev->
  932. alloc_block_finder =
  933. blk;
  934. } else {
  935. /* This is a partially written block that is not
  936. * the current allocation block.
  937. */
  938. yaffs_trace(YAFFS_TRACE_SCAN,
  939. "Partially written block %d detected",
  940. blk);
  941. }
  942. }
  943. }
  944. dev->n_free_chunks++;
  945. } else if (tags.ecc_result == YAFFS_ECC_RESULT_UNFIXED) {
  946. yaffs_trace(YAFFS_TRACE_SCAN,
  947. " Unfixed ECC in chunk(%d:%d), chunk ignored",
  948. blk, c);
  949. dev->n_free_chunks++;
  950. } else if (tags.obj_id > YAFFS_MAX_OBJECT_ID ||
  951. tags.chunk_id > YAFFS_MAX_CHUNK_ID ||
  952. (tags.chunk_id > 0
  953. && tags.n_bytes > dev->data_bytes_per_chunk)
  954. || tags.seq_number != bi->seq_number) {
  955. yaffs_trace(YAFFS_TRACE_SCAN,
  956. "Chunk (%d:%d) with bad tags:obj = %d, chunk_id = %d, n_bytes = %d, ignored",
  957. blk, c, tags.obj_id,
  958. tags.chunk_id, tags.n_bytes);
  959. dev->n_free_chunks++;
  960. } else if (tags.chunk_id > 0) {
  961. /* chunk_id > 0 so it is a data chunk... */
  962. unsigned int endpos;
  963. u32 chunk_base =
  964. (tags.chunk_id -
  965. 1) * dev->data_bytes_per_chunk;
  966. found_chunks = 1;
  967. yaffs_set_chunk_bit(dev, blk, c);
  968. bi->pages_in_use++;
  969. in = yaffs_find_or_create_by_number(dev,
  970. tags.obj_id,
  971. YAFFS_OBJECT_TYPE_FILE);
  972. if (!in) {
  973. /* Out of memory */
  974. alloc_failed = 1;
  975. }
  976. if (in &&
  977. in->variant_type == YAFFS_OBJECT_TYPE_FILE
  978. && chunk_base <
  979. in->variant.file_variant.shrink_size) {
  980. /* This has not been invalidated by a resize */
  981. if (!yaffs_put_chunk_in_file
  982. (in, tags.chunk_id, chunk, -1)) {
  983. alloc_failed = 1;
  984. }
  985. /* File size is calculated by looking at the data chunks if we have not
  986. * seen an object header yet. Stop this practice once we find an object header.
  987. */
  988. endpos = chunk_base + tags.n_bytes;
  989. if (!in->valid && /* have not got an object header yet */
  990. in->variant.file_variant.
  991. scanned_size < endpos) {
  992. in->variant.file_variant.
  993. scanned_size = endpos;
  994. in->variant.file_variant.
  995. file_size = endpos;
  996. }
  997. } else if (in) {
  998. /* This chunk has been invalidated by a resize, or a past file deletion
  999. * so delete the chunk*/
  1000. yaffs_chunk_del(dev, chunk, 1,
  1001. __LINE__);
  1002. }
  1003. } else {
  1004. /* chunk_id == 0, so it is an ObjectHeader.
  1005. * Thus, we read in the object header and make the object
  1006. */
  1007. found_chunks = 1;
  1008. yaffs_set_chunk_bit(dev, blk, c);
  1009. bi->pages_in_use++;
  1010. oh = NULL;
  1011. in = NULL;
  1012. if (tags.extra_available) {
  1013. in = yaffs_find_or_create_by_number(dev,
  1014. tags.
  1015. obj_id,
  1016. tags.
  1017. extra_obj_type);
  1018. if (!in)
  1019. alloc_failed = 1;
  1020. }
  1021. if (!in ||
  1022. (!in->valid && dev->param.disable_lazy_load)
  1023. || tags.extra_shadows || (!in->valid
  1024. && (tags.obj_id ==
  1025. YAFFS_OBJECTID_ROOT
  1026. || tags.
  1027. obj_id ==
  1028. YAFFS_OBJECTID_LOSTNFOUND)))
  1029. {
  1030. /* If we don't have valid info then we need to read the chunk
  1031. * TODO In future we can probably defer reading the chunk and
  1032. * living with invalid data until needed.
  1033. */
  1034. result = yaffs_rd_chunk_tags_nand(dev,
  1035. chunk,
  1036. chunk_data,
  1037. NULL);
  1038. oh = (struct yaffs_obj_hdr *)chunk_data;
  1039. if (dev->param.inband_tags) {
  1040. /* Fix up the header if they got corrupted by inband tags */
  1041. oh->shadows_obj =
  1042. oh->inband_shadowed_obj_id;
  1043. oh->is_shrink =
  1044. oh->inband_is_shrink;
  1045. }
  1046. if (!in) {
  1047. in = yaffs_find_or_create_by_number(dev, tags.obj_id, oh->type);
  1048. if (!in)
  1049. alloc_failed = 1;
  1050. }
  1051. }
  1052. if (!in) {
  1053. /* TODO Hoosterman we have a problem! */
  1054. yaffs_trace(YAFFS_TRACE_ERROR,
  1055. "yaffs tragedy: Could not make object for object %d at chunk %d during scan",
  1056. tags.obj_id, chunk);
  1057. continue;
  1058. }
  1059. if (in->valid) {
  1060. /* We have already filled this one.
  1061. * We have a duplicate that will be discarded, but
  1062. * we first have to suck out resize info if it is a file.
  1063. */
  1064. if ((in->variant_type ==
  1065. YAFFS_OBJECT_TYPE_FILE) && ((oh
  1066. &&
  1067. oh->
  1068. type
  1069. ==
  1070. YAFFS_OBJECT_TYPE_FILE)
  1071. ||
  1072. (tags.
  1073. extra_available
  1074. &&
  1075. tags.
  1076. extra_obj_type
  1077. ==
  1078. YAFFS_OBJECT_TYPE_FILE)))
  1079. {
  1080. u32 this_size =
  1081. (oh) ? oh->
  1082. file_size :
  1083. tags.extra_length;
  1084. u32 parent_obj_id =
  1085. (oh) ? oh->parent_obj_id :
  1086. tags.extra_parent_id;
  1087. is_shrink =
  1088. (oh) ? oh->
  1089. is_shrink :
  1090. tags.extra_is_shrink;
  1091. /* If it is deleted (unlinked at start also means deleted)
  1092. * we treat the file size as being zeroed at this point.
  1093. */
  1094. if (parent_obj_id ==
  1095. YAFFS_OBJECTID_DELETED
  1096. || parent_obj_id ==
  1097. YAFFS_OBJECTID_UNLINKED) {
  1098. this_size = 0;
  1099. is_shrink = 1;
  1100. }
  1101. if (is_shrink
  1102. && in->variant.file_variant.
  1103. shrink_size > this_size)
  1104. in->variant.
  1105. file_variant.
  1106. shrink_size =
  1107. this_size;
  1108. if (is_shrink)
  1109. bi->has_shrink_hdr = 1;
  1110. }
  1111. /* Use existing - destroy this one. */
  1112. yaffs_chunk_del(dev, chunk, 1,
  1113. __LINE__);
  1114. }
  1115. if (!in->valid && in->variant_type !=
  1116. (oh ? oh->type : tags.extra_obj_type))
  1117. yaffs_trace(YAFFS_TRACE_ERROR,
  1118. "yaffs tragedy: Bad object type, %d != %d, for object %d at chunk %d during scan",
  1119. oh ?
  1120. oh->type : tags.extra_obj_type,
  1121. in->variant_type, tags.obj_id,
  1122. chunk);
  1123. if (!in->valid &&
  1124. (tags.obj_id == YAFFS_OBJECTID_ROOT ||
  1125. tags.obj_id ==
  1126. YAFFS_OBJECTID_LOSTNFOUND)) {
  1127. /* We only load some info, don't fiddle with directory structure */
  1128. in->valid = 1;
  1129. if (oh) {
  1130. in->yst_mode = oh->yst_mode;
  1131. yaffs_load_attribs(in, oh);
  1132. in->lazy_loaded = 0;
  1133. } else {
  1134. in->lazy_loaded = 1;
  1135. }
  1136. in->hdr_chunk = chunk;
  1137. } else if (!in->valid) {
  1138. /* we need to load this info */
  1139. in->valid = 1;
  1140. in->hdr_chunk = chunk;
  1141. if (oh) {
  1142. in->variant_type = oh->type;
  1143. in->yst_mode = oh->yst_mode;
  1144. yaffs_load_attribs(in, oh);
  1145. if (oh->shadows_obj > 0)
  1146. yaffs_handle_shadowed_obj
  1147. (dev,
  1148. oh->shadows_obj,
  1149. 1);
  1150. yaffs_set_obj_name_from_oh(in,
  1151. oh);
  1152. parent =
  1153. yaffs_find_or_create_by_number
  1154. (dev, oh->parent_obj_id,
  1155. YAFFS_OBJECT_TYPE_DIRECTORY);
  1156. file_size = oh->file_size;
  1157. is_shrink = oh->is_shrink;
  1158. equiv_id = oh->equiv_id;
  1159. } else {
  1160. in->variant_type =
  1161. tags.extra_obj_type;
  1162. parent =
  1163. yaffs_find_or_create_by_number
  1164. (dev, tags.extra_parent_id,
  1165. YAFFS_OBJECT_TYPE_DIRECTORY);
  1166. file_size = tags.extra_length;
  1167. is_shrink =
  1168. tags.extra_is_shrink;
  1169. equiv_id = tags.extra_equiv_id;
  1170. in->lazy_loaded = 1;
  1171. }
  1172. in->dirty = 0;
  1173. if (!parent)
  1174. alloc_failed = 1;
  1175. /* directory stuff...
  1176. * hook up to parent
  1177. */
  1178. if (parent && parent->variant_type ==
  1179. YAFFS_OBJECT_TYPE_UNKNOWN) {
  1180. /* Set up as a directory */
  1181. parent->variant_type =
  1182. YAFFS_OBJECT_TYPE_DIRECTORY;
  1183. INIT_LIST_HEAD(&parent->
  1184. variant.dir_variant.children);
  1185. } else if (!parent
  1186. || parent->variant_type !=
  1187. YAFFS_OBJECT_TYPE_DIRECTORY) {
  1188. /* Hoosterman, another problem....
  1189. * We're trying to use a non-directory as a directory
  1190. */
  1191. yaffs_trace(YAFFS_TRACE_ERROR,
  1192. "yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
  1193. );
  1194. parent = dev->lost_n_found;
  1195. }
  1196. yaffs_add_obj_to_dir(parent, in);
  1197. is_unlinked = (parent == dev->del_dir)
  1198. || (parent == dev->unlinked_dir);
  1199. if (is_shrink) {
  1200. /* Mark the block as having a shrink header */
  1201. bi->has_shrink_hdr = 1;
  1202. }
  1203. /* Note re hardlinks.
  1204. * Since we might scan a hardlink before its equivalent object is scanned
  1205. * we put them all in a list.
  1206. * After scanning is complete, we should have all the objects, so we run
  1207. * through this list and fix up all the chains.
  1208. */
  1209. switch (in->variant_type) {
  1210. case YAFFS_OBJECT_TYPE_UNKNOWN:
  1211. /* Todo got a problem */
  1212. break;
  1213. case YAFFS_OBJECT_TYPE_FILE:
  1214. if (in->variant.
  1215. file_variant.scanned_size <
  1216. file_size) {
  1217. /* This covers the case where the file size is greater
  1218. * than where the data is
  1219. * This will happen if the file is resized to be larger
  1220. * than its current data extents.
  1221. */
  1222. in->variant.
  1223. file_variant.
  1224. file_size =
  1225. file_size;
  1226. in->variant.
  1227. file_variant.
  1228. scanned_size =
  1229. file_size;
  1230. }
  1231. if (in->variant.file_variant.
  1232. shrink_size > file_size)
  1233. in->variant.
  1234. file_variant.
  1235. shrink_size =
  1236. file_size;
  1237. break;
  1238. case YAFFS_OBJECT_TYPE_HARDLINK:
  1239. if (!is_unlinked) {
  1240. in->variant.
  1241. hardlink_variant.
  1242. equiv_id = equiv_id;
  1243. in->hard_links.next =
  1244. (struct list_head *)
  1245. hard_list;
  1246. hard_list = in;
  1247. }
  1248. break;
  1249. case YAFFS_OBJECT_TYPE_DIRECTORY:
  1250. /* Do nothing */
  1251. break;
  1252. case YAFFS_OBJECT_TYPE_SPECIAL:
  1253. /* Do nothing */
  1254. break;
  1255. case YAFFS_OBJECT_TYPE_SYMLINK:
  1256. if (oh) {
  1257. in->variant.
  1258. symlink_variant.
  1259. alias =
  1260. yaffs_clone_str(oh->
  1261. alias);
  1262. if (!in->variant.
  1263. symlink_variant.
  1264. alias)
  1265. alloc_failed =
  1266. 1;
  1267. }
  1268. break;
  1269. }
  1270. }
  1271. }
  1272. } /* End of scanning for each chunk */
  1273. if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
  1274. /* If we got this far while scanning, then the block is fully allocated. */
  1275. state = YAFFS_BLOCK_STATE_FULL;
  1276. }
  1277. bi->block_state = state;
  1278. /* Now let's see if it was dirty */
  1279. if (bi->pages_in_use == 0 &&
  1280. !bi->has_shrink_hdr &&
  1281. bi->block_state == YAFFS_BLOCK_STATE_FULL) {
  1282. yaffs_block_became_dirty(dev, blk);
  1283. }
  1284. }
  1285. yaffs_skip_rest_of_block(dev);
  1286. if (alt_block_index)
  1287. vfree(block_index);
  1288. else
  1289. kfree(block_index);
  1290. /* Ok, we've done all the scanning.
  1291. * Fix up the hard link chains.
  1292. * We should now have scanned all the objects, now it's time to add these
  1293. * hardlinks.
  1294. */
  1295. yaffs_link_fixup(dev, hard_list);
  1296. yaffs_release_temp_buffer(dev, chunk_data, __LINE__);
  1297. if (alloc_failed)
  1298. return YAFFS_FAIL;
  1299. yaffs_trace(YAFFS_TRACE_SCAN, "yaffs2_scan_backwards ends");
  1300. return YAFFS_OK;
  1301. }