yaffs_yaffs2.c 37 KB

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