xattr.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257
  1. /*
  2. * JFFS2 -- Journalling Flash File System, Version 2.
  3. *
  4. * Copyright (C) 2006 NEC Corporation
  5. *
  6. * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
  7. *
  8. * For licensing information, see the file 'LICENCE' in this directory.
  9. *
  10. */
  11. #include <linux/kernel.h>
  12. #include <linux/slab.h>
  13. #include <linux/fs.h>
  14. #include <linux/time.h>
  15. #include <linux/pagemap.h>
  16. #include <linux/highmem.h>
  17. #include <linux/crc32.h>
  18. #include <linux/jffs2.h>
  19. #include <linux/xattr.h>
  20. #include <linux/mtd/mtd.h>
  21. #include "nodelist.h"
  22. /* -------- xdatum related functions ----------------
  23. * xattr_datum_hashkey(xprefix, xname, xvalue, xsize)
  24. * is used to calcurate xdatum hashkey. The reminder of hashkey into XATTRINDEX_HASHSIZE is
  25. * the index of the xattr name/value pair cache (c->xattrindex).
  26. * unload_xattr_datum(c, xd)
  27. * is used to release xattr name/value pair and detach from c->xattrindex.
  28. * reclaim_xattr_datum(c)
  29. * is used to reclaim xattr name/value pairs on the xattr name/value pair cache when
  30. * memory usage by cache is over c->xdatum_mem_threshold. Currentry, this threshold
  31. * is hard coded as 32KiB.
  32. * delete_xattr_datum_node(c, xd)
  33. * is used to delete a jffs2 node is dominated by xdatum. When EBS(Erase Block Summary) is
  34. * enabled, it overwrites the obsolete node by myself.
  35. * delete_xattr_datum(c, xd)
  36. * is used to delete jffs2_xattr_datum object. It must be called with 0-value of reference
  37. * counter. (It means how many jffs2_xattr_ref object refers this xdatum.)
  38. * do_verify_xattr_datum(c, xd)
  39. * is used to load the xdatum informations without name/value pair from the medium.
  40. * It's necessary once, because those informations are not collected during mounting
  41. * process when EBS is enabled.
  42. * 0 will be returned, if success. An negative return value means recoverable error, and
  43. * positive return value means unrecoverable error. Thus, caller must remove this xdatum
  44. * and xref when it returned positive value.
  45. * do_load_xattr_datum(c, xd)
  46. * is used to load name/value pair from the medium.
  47. * The meanings of return value is same as do_verify_xattr_datum().
  48. * load_xattr_datum(c, xd)
  49. * is used to be as a wrapper of do_verify_xattr_datum() and do_load_xattr_datum().
  50. * If xd need to call do_verify_xattr_datum() at first, it's called before calling
  51. * do_load_xattr_datum(). The meanings of return value is same as do_verify_xattr_datum().
  52. * save_xattr_datum(c, xd, phys_ofs)
  53. * is used to write xdatum to medium. xd->version will be incremented.
  54. * create_xattr_datum(c, xprefix, xname, xvalue, xsize, phys_ofs)
  55. * is used to create new xdatum and write to medium.
  56. * -------------------------------------------------- */
  57. static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize)
  58. {
  59. int name_len = strlen(xname);
  60. return crc32(xprefix, xname, name_len) ^ crc32(xprefix, xvalue, xsize);
  61. }
  62. static void unload_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
  63. {
  64. /* must be called under down_write(xattr_sem) */
  65. D1(dbg_xattr("%s: xid=%u, version=%u\n", __FUNCTION__, xd->xid, xd->version));
  66. if (xd->xname) {
  67. c->xdatum_mem_usage -= (xd->name_len + 1 + xd->value_len);
  68. kfree(xd->xname);
  69. }
  70. list_del_init(&xd->xindex);
  71. xd->hashkey = 0;
  72. xd->xname = NULL;
  73. xd->xvalue = NULL;
  74. }
  75. static void reclaim_xattr_datum(struct jffs2_sb_info *c)
  76. {
  77. /* must be called under down_write(xattr_sem) */
  78. struct jffs2_xattr_datum *xd, *_xd;
  79. uint32_t target, before;
  80. static int index = 0;
  81. int count;
  82. if (c->xdatum_mem_threshold > c->xdatum_mem_usage)
  83. return;
  84. before = c->xdatum_mem_usage;
  85. target = c->xdatum_mem_usage * 4 / 5; /* 20% reduction */
  86. for (count = 0; count < XATTRINDEX_HASHSIZE; count++) {
  87. list_for_each_entry_safe(xd, _xd, &c->xattrindex[index], xindex) {
  88. if (xd->flags & JFFS2_XFLAGS_HOT) {
  89. xd->flags &= ~JFFS2_XFLAGS_HOT;
  90. } else if (!(xd->flags & JFFS2_XFLAGS_BIND)) {
  91. unload_xattr_datum(c, xd);
  92. }
  93. if (c->xdatum_mem_usage <= target)
  94. goto out;
  95. }
  96. index = (index+1) % XATTRINDEX_HASHSIZE;
  97. }
  98. out:
  99. JFFS2_NOTICE("xdatum_mem_usage from %u byte to %u byte (%u byte reclaimed)\n",
  100. before, c->xdatum_mem_usage, before - c->xdatum_mem_usage);
  101. }
  102. static void delete_xattr_datum_node(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
  103. {
  104. /* must be called under down_write(xattr_sem) */
  105. struct jffs2_raw_xattr rx;
  106. uint32_t length;
  107. int rc;
  108. if (!xd->node) {
  109. JFFS2_WARNING("xdatum (xid=%u) is removed twice.\n", xd->xid);
  110. return;
  111. }
  112. if (jffs2_sum_active()) {
  113. memset(&rx, 0xff, sizeof(struct jffs2_raw_xattr));
  114. rc = jffs2_flash_read(c, ref_offset(xd->node),
  115. sizeof(struct jffs2_unknown_node),
  116. &length, (char *)&rx);
  117. if (rc || length != sizeof(struct jffs2_unknown_node)) {
  118. JFFS2_ERROR("jffs2_flash_read()=%d, req=%u, read=%u at %#08x\n",
  119. rc, sizeof(struct jffs2_unknown_node),
  120. length, ref_offset(xd->node));
  121. }
  122. rc = jffs2_flash_write(c, ref_offset(xd->node), sizeof(rx),
  123. &length, (char *)&rx);
  124. if (rc || length != sizeof(struct jffs2_raw_xattr)) {
  125. JFFS2_ERROR("jffs2_flash_write()=%d, req=%u, wrote=%u ar %#08x\n",
  126. rc, sizeof(rx), length, ref_offset(xd->node));
  127. }
  128. }
  129. spin_lock(&c->erase_completion_lock);
  130. xd->node->next_in_ino = NULL;
  131. spin_unlock(&c->erase_completion_lock);
  132. jffs2_mark_node_obsolete(c, xd->node);
  133. xd->node = NULL;
  134. }
  135. static void delete_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
  136. {
  137. /* must be called under down_write(xattr_sem) */
  138. BUG_ON(xd->refcnt);
  139. unload_xattr_datum(c, xd);
  140. if (xd->node) {
  141. delete_xattr_datum_node(c, xd);
  142. xd->node = NULL;
  143. }
  144. jffs2_free_xattr_datum(xd);
  145. }
  146. static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
  147. {
  148. /* must be called under down_write(xattr_sem) */
  149. struct jffs2_eraseblock *jeb;
  150. struct jffs2_raw_xattr rx;
  151. size_t readlen;
  152. uint32_t crc, totlen;
  153. int rc;
  154. BUG_ON(!xd->node);
  155. BUG_ON(ref_flags(xd->node) != REF_UNCHECKED);
  156. rc = jffs2_flash_read(c, ref_offset(xd->node), sizeof(rx), &readlen, (char *)&rx);
  157. if (rc || readlen != sizeof(rx)) {
  158. JFFS2_WARNING("jffs2_flash_read()=%d, req=%u, read=%u at %#08x\n",
  159. rc, sizeof(rx), readlen, ref_offset(xd->node));
  160. return rc ? rc : -EIO;
  161. }
  162. crc = crc32(0, &rx, sizeof(rx) - 4);
  163. if (crc != je32_to_cpu(rx.node_crc)) {
  164. if (je32_to_cpu(rx.node_crc) != 0xffffffff)
  165. JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
  166. ref_offset(xd->node), je32_to_cpu(rx.hdr_crc), crc);
  167. return EIO;
  168. }
  169. totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len));
  170. if (je16_to_cpu(rx.magic) != JFFS2_MAGIC_BITMASK
  171. || je16_to_cpu(rx.nodetype) != JFFS2_NODETYPE_XATTR
  172. || je32_to_cpu(rx.totlen) != totlen
  173. || je32_to_cpu(rx.xid) != xd->xid
  174. || je32_to_cpu(rx.version) != xd->version) {
  175. JFFS2_ERROR("inconsistent xdatum at %#08x, magic=%#04x/%#04x, "
  176. "nodetype=%#04x/%#04x, totlen=%u/%u, xid=%u/%u, version=%u/%u\n",
  177. ref_offset(xd->node), je16_to_cpu(rx.magic), JFFS2_MAGIC_BITMASK,
  178. je16_to_cpu(rx.nodetype), JFFS2_NODETYPE_XATTR,
  179. je32_to_cpu(rx.totlen), totlen,
  180. je32_to_cpu(rx.xid), xd->xid,
  181. je32_to_cpu(rx.version), xd->version);
  182. return EIO;
  183. }
  184. xd->xprefix = rx.xprefix;
  185. xd->name_len = rx.name_len;
  186. xd->value_len = je16_to_cpu(rx.value_len);
  187. xd->data_crc = je32_to_cpu(rx.data_crc);
  188. /* This JFFS2_NODETYPE_XATTR node is checked */
  189. jeb = &c->blocks[ref_offset(xd->node) / c->sector_size];
  190. totlen = PAD(je32_to_cpu(rx.totlen));
  191. spin_lock(&c->erase_completion_lock);
  192. c->unchecked_size -= totlen; c->used_size += totlen;
  193. jeb->unchecked_size -= totlen; jeb->used_size += totlen;
  194. xd->node->flash_offset = ref_offset(xd->node) | REF_PRISTINE;
  195. spin_unlock(&c->erase_completion_lock);
  196. /* unchecked xdatum is chained with c->xattr_unchecked */
  197. list_del_init(&xd->xindex);
  198. dbg_xattr("success on verfying xdatum (xid=%u, version=%u)\n",
  199. xd->xid, xd->version);
  200. return 0;
  201. }
  202. static int do_load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
  203. {
  204. /* must be called under down_write(xattr_sem) */
  205. char *data;
  206. size_t readlen;
  207. uint32_t crc, length;
  208. int i, ret, retry = 0;
  209. BUG_ON(!xd->node);
  210. BUG_ON(ref_flags(xd->node) != REF_PRISTINE);
  211. BUG_ON(!list_empty(&xd->xindex));
  212. retry:
  213. length = xd->name_len + 1 + xd->value_len;
  214. data = kmalloc(length, GFP_KERNEL);
  215. if (!data)
  216. return -ENOMEM;
  217. ret = jffs2_flash_read(c, ref_offset(xd->node)+sizeof(struct jffs2_raw_xattr),
  218. length, &readlen, data);
  219. if (ret || length!=readlen) {
  220. JFFS2_WARNING("jffs2_flash_read() returned %d, request=%d, readlen=%d, at %#08x\n",
  221. ret, length, readlen, ref_offset(xd->node));
  222. kfree(data);
  223. return ret ? ret : -EIO;
  224. }
  225. data[xd->name_len] = '\0';
  226. crc = crc32(0, data, length);
  227. if (crc != xd->data_crc) {
  228. JFFS2_WARNING("node CRC failed (JFFS2_NODETYPE_XREF)"
  229. " at %#08x, read: 0x%08x calculated: 0x%08x\n",
  230. ref_offset(xd->node), xd->data_crc, crc);
  231. kfree(data);
  232. return EIO;
  233. }
  234. xd->flags |= JFFS2_XFLAGS_HOT;
  235. xd->xname = data;
  236. xd->xvalue = data + xd->name_len+1;
  237. c->xdatum_mem_usage += length;
  238. xd->hashkey = xattr_datum_hashkey(xd->xprefix, xd->xname, xd->xvalue, xd->value_len);
  239. i = xd->hashkey % XATTRINDEX_HASHSIZE;
  240. list_add(&xd->xindex, &c->xattrindex[i]);
  241. if (!retry) {
  242. retry = 1;
  243. reclaim_xattr_datum(c);
  244. if (!xd->xname)
  245. goto retry;
  246. }
  247. dbg_xattr("success on loading xdatum (xid=%u, xprefix=%u, xname='%s')\n",
  248. xd->xid, xd->xprefix, xd->xname);
  249. return 0;
  250. }
  251. static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
  252. {
  253. /* must be called under down_write(xattr_sem);
  254. * rc < 0 : recoverable error, try again
  255. * rc = 0 : success
  256. * rc > 0 : Unrecoverable error, this node should be deleted.
  257. */
  258. int rc = 0;
  259. BUG_ON(xd->xname);
  260. if (!xd->node)
  261. return EIO;
  262. if (unlikely(ref_flags(xd->node) != REF_PRISTINE)) {
  263. rc = do_verify_xattr_datum(c, xd);
  264. if (rc > 0) {
  265. list_del_init(&xd->xindex);
  266. delete_xattr_datum_node(c, xd);
  267. }
  268. }
  269. if (!rc)
  270. rc = do_load_xattr_datum(c, xd);
  271. return rc;
  272. }
  273. static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd, uint32_t phys_ofs)
  274. {
  275. /* must be called under down_write(xattr_sem) */
  276. struct jffs2_raw_xattr rx;
  277. struct jffs2_raw_node_ref *raw;
  278. struct kvec vecs[2];
  279. uint32_t length;
  280. int rc, totlen;
  281. BUG_ON(!xd->xname);
  282. vecs[0].iov_base = &rx;
  283. vecs[0].iov_len = PAD(sizeof(rx));
  284. vecs[1].iov_base = xd->xname;
  285. vecs[1].iov_len = xd->name_len + 1 + xd->value_len;
  286. totlen = vecs[0].iov_len + vecs[1].iov_len;
  287. raw = jffs2_alloc_raw_node_ref();
  288. if (!raw)
  289. return -ENOMEM;
  290. raw->flash_offset = phys_ofs;
  291. /* Setup raw-xattr */
  292. rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
  293. rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR);
  294. rx.totlen = cpu_to_je32(PAD(totlen));
  295. rx.hdr_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_unknown_node) - 4));
  296. rx.xid = cpu_to_je32(xd->xid);
  297. rx.version = cpu_to_je32(++xd->version);
  298. rx.xprefix = xd->xprefix;
  299. rx.name_len = xd->name_len;
  300. rx.value_len = cpu_to_je16(xd->value_len);
  301. rx.data_crc = cpu_to_je32(crc32(0, vecs[1].iov_base, vecs[1].iov_len));
  302. rx.node_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_raw_xattr) - 4));
  303. rc = jffs2_flash_writev(c, vecs, 2, phys_ofs, &length, 0);
  304. if (rc || totlen != length) {
  305. JFFS2_WARNING("jffs2_flash_writev()=%d, req=%u, wrote=%u, at %#08x\n",
  306. rc, totlen, length, phys_ofs);
  307. rc = rc ? rc : -EIO;
  308. if (length) {
  309. raw->flash_offset |= REF_OBSOLETE;
  310. jffs2_add_physical_node_ref(c, raw, PAD(totlen), NULL);
  311. jffs2_mark_node_obsolete(c, raw);
  312. } else {
  313. jffs2_free_raw_node_ref(raw);
  314. }
  315. return rc;
  316. }
  317. /* success */
  318. raw->flash_offset |= REF_PRISTINE;
  319. jffs2_add_physical_node_ref(c, raw, PAD(totlen), NULL);
  320. /* FIXME */ raw->next_in_ino = (void *)xd;
  321. if (xd->node)
  322. delete_xattr_datum_node(c, xd);
  323. xd->node = raw;
  324. dbg_xattr("success on saving xdatum (xid=%u, version=%u, xprefix=%u, xname='%s')\n",
  325. xd->xid, xd->version, xd->xprefix, xd->xname);
  326. return 0;
  327. }
  328. static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
  329. int xprefix, const char *xname,
  330. const char *xvalue, int xsize,
  331. uint32_t phys_ofs)
  332. {
  333. /* must be called under down_write(xattr_sem) */
  334. struct jffs2_xattr_datum *xd;
  335. uint32_t hashkey, name_len;
  336. char *data;
  337. int i, rc;
  338. /* Search xattr_datum has same xname/xvalue by index */
  339. hashkey = xattr_datum_hashkey(xprefix, xname, xvalue, xsize);
  340. i = hashkey % XATTRINDEX_HASHSIZE;
  341. list_for_each_entry(xd, &c->xattrindex[i], xindex) {
  342. if (xd->hashkey==hashkey
  343. && xd->xprefix==xprefix
  344. && xd->value_len==xsize
  345. && !strcmp(xd->xname, xname)
  346. && !memcmp(xd->xvalue, xvalue, xsize)) {
  347. xd->refcnt++;
  348. return xd;
  349. }
  350. }
  351. /* Not found, Create NEW XATTR-Cache */
  352. name_len = strlen(xname);
  353. xd = jffs2_alloc_xattr_datum();
  354. if (!xd)
  355. return ERR_PTR(-ENOMEM);
  356. data = kmalloc(name_len + 1 + xsize, GFP_KERNEL);
  357. if (!data) {
  358. jffs2_free_xattr_datum(xd);
  359. return ERR_PTR(-ENOMEM);
  360. }
  361. strcpy(data, xname);
  362. memcpy(data + name_len + 1, xvalue, xsize);
  363. xd->refcnt = 1;
  364. xd->xid = ++c->highest_xid;
  365. xd->flags |= JFFS2_XFLAGS_HOT;
  366. xd->xprefix = xprefix;
  367. xd->hashkey = hashkey;
  368. xd->xname = data;
  369. xd->xvalue = data + name_len + 1;
  370. xd->name_len = name_len;
  371. xd->value_len = xsize;
  372. xd->data_crc = crc32(0, data, xd->name_len + 1 + xd->value_len);
  373. rc = save_xattr_datum(c, xd, phys_ofs);
  374. if (rc) {
  375. kfree(xd->xname);
  376. jffs2_free_xattr_datum(xd);
  377. return ERR_PTR(rc);
  378. }
  379. /* Insert Hash Index */
  380. i = hashkey % XATTRINDEX_HASHSIZE;
  381. list_add(&xd->xindex, &c->xattrindex[i]);
  382. c->xdatum_mem_usage += (xd->name_len + 1 + xd->value_len);
  383. reclaim_xattr_datum(c);
  384. return xd;
  385. }
  386. /* -------- xref related functions ------------------
  387. * verify_xattr_ref(c, ref)
  388. * is used to load xref information from medium. Because summary data does not
  389. * contain xid/ino, it's necessary to verify once while mounting process.
  390. * delete_xattr_ref_node(c, ref)
  391. * is used to delete a jffs2 node is dominated by xref. When EBS is enabled,
  392. * it overwrites the obsolete node by myself.
  393. * delete_xattr_ref(c, ref)
  394. * is used to delete jffs2_xattr_ref object. If the reference counter of xdatum
  395. * is refered by this xref become 0, delete_xattr_datum() is called later.
  396. * save_xattr_ref(c, ref, phys_ofs)
  397. * is used to write xref to medium.
  398. * create_xattr_ref(c, ic, xd, phys_ofs)
  399. * is used to create a new xref and write to medium.
  400. * jffs2_xattr_delete_inode(c, ic)
  401. * is called to remove xrefs related to obsolete inode when inode is unlinked.
  402. * jffs2_xattr_free_inode(c, ic)
  403. * is called to release xattr related objects when unmounting.
  404. * check_xattr_ref_inode(c, ic)
  405. * is used to confirm inode does not have duplicate xattr name/value pair.
  406. * -------------------------------------------------- */
  407. static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
  408. {
  409. struct jffs2_eraseblock *jeb;
  410. struct jffs2_raw_xref rr;
  411. size_t readlen;
  412. uint32_t crc, totlen;
  413. int rc;
  414. BUG_ON(ref_flags(ref->node) != REF_UNCHECKED);
  415. rc = jffs2_flash_read(c, ref_offset(ref->node), sizeof(rr), &readlen, (char *)&rr);
  416. if (rc || sizeof(rr) != readlen) {
  417. JFFS2_WARNING("jffs2_flash_read()=%d, req=%u, read=%u, at %#08x\n",
  418. rc, sizeof(rr), readlen, ref_offset(ref->node));
  419. return rc ? rc : -EIO;
  420. }
  421. /* obsolete node */
  422. crc = crc32(0, &rr, sizeof(rr) - 4);
  423. if (crc != je32_to_cpu(rr.node_crc)) {
  424. if (je32_to_cpu(rr.node_crc) != 0xffffffff)
  425. JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
  426. ref_offset(ref->node), je32_to_cpu(rr.node_crc), crc);
  427. return EIO;
  428. }
  429. if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK
  430. || je16_to_cpu(rr.nodetype) != JFFS2_NODETYPE_XREF
  431. || je32_to_cpu(rr.totlen) != PAD(sizeof(rr))) {
  432. JFFS2_ERROR("inconsistent xref at %#08x, magic=%#04x/%#04x, "
  433. "nodetype=%#04x/%#04x, totlen=%u/%u\n",
  434. ref_offset(ref->node), je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK,
  435. je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF,
  436. je32_to_cpu(rr.totlen), PAD(sizeof(rr)));
  437. return EIO;
  438. }
  439. ref->ino = je32_to_cpu(rr.ino);
  440. ref->xid = je32_to_cpu(rr.xid);
  441. /* fixup superblock/eraseblock info */
  442. jeb = &c->blocks[ref_offset(ref->node) / c->sector_size];
  443. totlen = PAD(sizeof(rr));
  444. spin_lock(&c->erase_completion_lock);
  445. c->unchecked_size -= totlen; c->used_size += totlen;
  446. jeb->unchecked_size -= totlen; jeb->used_size += totlen;
  447. ref->node->flash_offset = ref_offset(ref->node) | REF_PRISTINE;
  448. spin_unlock(&c->erase_completion_lock);
  449. dbg_xattr("success on verifying xref (ino=%u, xid=%u) at %#08x\n",
  450. ref->ino, ref->xid, ref_offset(ref->node));
  451. return 0;
  452. }
  453. static void delete_xattr_ref_node(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
  454. {
  455. struct jffs2_raw_xref rr;
  456. uint32_t length;
  457. int rc;
  458. if (jffs2_sum_active()) {
  459. memset(&rr, 0xff, sizeof(rr));
  460. rc = jffs2_flash_read(c, ref_offset(ref->node),
  461. sizeof(struct jffs2_unknown_node),
  462. &length, (char *)&rr);
  463. if (rc || length != sizeof(struct jffs2_unknown_node)) {
  464. JFFS2_ERROR("jffs2_flash_read()=%d, req=%u, read=%u at %#08x\n",
  465. rc, sizeof(struct jffs2_unknown_node),
  466. length, ref_offset(ref->node));
  467. }
  468. rc = jffs2_flash_write(c, ref_offset(ref->node), sizeof(rr),
  469. &length, (char *)&rr);
  470. if (rc || length != sizeof(struct jffs2_raw_xref)) {
  471. JFFS2_ERROR("jffs2_flash_write()=%d, req=%u, wrote=%u at %#08x\n",
  472. rc, sizeof(rr), length, ref_offset(ref->node));
  473. }
  474. }
  475. spin_lock(&c->erase_completion_lock);
  476. ref->node->next_in_ino = NULL;
  477. spin_unlock(&c->erase_completion_lock);
  478. jffs2_mark_node_obsolete(c, ref->node);
  479. ref->node = NULL;
  480. }
  481. static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
  482. {
  483. /* must be called under down_write(xattr_sem) */
  484. struct jffs2_xattr_datum *xd;
  485. BUG_ON(!ref->node);
  486. delete_xattr_ref_node(c, ref);
  487. xd = ref->xd;
  488. xd->refcnt--;
  489. if (!xd->refcnt)
  490. delete_xattr_datum(c, xd);
  491. jffs2_free_xattr_ref(ref);
  492. }
  493. static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref, uint32_t phys_ofs)
  494. {
  495. /* must be called under down_write(xattr_sem) */
  496. struct jffs2_raw_node_ref *raw;
  497. struct jffs2_raw_xref rr;
  498. uint32_t length;
  499. int ret;
  500. raw = jffs2_alloc_raw_node_ref();
  501. if (!raw)
  502. return -ENOMEM;
  503. raw->flash_offset = phys_ofs;
  504. rr.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
  505. rr.nodetype = cpu_to_je16(JFFS2_NODETYPE_XREF);
  506. rr.totlen = cpu_to_je32(PAD(sizeof(rr)));
  507. rr.hdr_crc = cpu_to_je32(crc32(0, &rr, sizeof(struct jffs2_unknown_node) - 4));
  508. rr.ino = cpu_to_je32(ref->ic->ino);
  509. rr.xid = cpu_to_je32(ref->xd->xid);
  510. rr.node_crc = cpu_to_je32(crc32(0, &rr, sizeof(rr) - 4));
  511. ret = jffs2_flash_write(c, phys_ofs, sizeof(rr), &length, (char *)&rr);
  512. if (ret || sizeof(rr) != length) {
  513. JFFS2_WARNING("jffs2_flash_write() returned %d, request=%u, retlen=%u, at %#08x\n",
  514. ret, sizeof(rr), length, phys_ofs);
  515. ret = ret ? ret : -EIO;
  516. if (length) {
  517. raw->flash_offset |= REF_OBSOLETE;
  518. jffs2_add_physical_node_ref(c, raw, PAD(sizeof(rr)), NULL);
  519. jffs2_mark_node_obsolete(c, raw);
  520. } else {
  521. jffs2_free_raw_node_ref(raw);
  522. }
  523. return ret;
  524. }
  525. raw->flash_offset |= REF_PRISTINE;
  526. jffs2_add_physical_node_ref(c, raw, PAD(sizeof(rr)), NULL);
  527. /* FIXME */ raw->next_in_ino = (void *)ref;
  528. if (ref->node)
  529. delete_xattr_ref_node(c, ref);
  530. ref->node = raw;
  531. dbg_xattr("success on saving xref (ino=%u, xid=%u)\n", ref->ic->ino, ref->xd->xid);
  532. return 0;
  533. }
  534. static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic,
  535. struct jffs2_xattr_datum *xd, uint32_t phys_ofs)
  536. {
  537. /* must be called under down_write(xattr_sem) */
  538. struct jffs2_xattr_ref *ref;
  539. int ret;
  540. ref = jffs2_alloc_xattr_ref();
  541. if (!ref)
  542. return ERR_PTR(-ENOMEM);
  543. ref->ic = ic;
  544. ref->xd = xd;
  545. ret = save_xattr_ref(c, ref, phys_ofs);
  546. if (ret) {
  547. jffs2_free_xattr_ref(ref);
  548. return ERR_PTR(ret);
  549. }
  550. /* Chain to inode */
  551. ref->next = ic->xref;
  552. ic->xref = ref;
  553. return ref; /* success */
  554. }
  555. void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
  556. {
  557. /* It's called from jffs2_clear_inode() on inode removing.
  558. When an inode with XATTR is removed, those XATTRs must be removed. */
  559. struct jffs2_xattr_ref *ref, *_ref;
  560. if (!ic || ic->nlink > 0)
  561. return;
  562. down_write(&c->xattr_sem);
  563. for (ref = ic->xref; ref; ref = _ref) {
  564. _ref = ref->next;
  565. delete_xattr_ref(c, ref);
  566. }
  567. ic->xref = NULL;
  568. up_write(&c->xattr_sem);
  569. }
  570. void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
  571. {
  572. /* It's called from jffs2_free_ino_caches() until unmounting FS. */
  573. struct jffs2_xattr_datum *xd;
  574. struct jffs2_xattr_ref *ref, *_ref;
  575. down_write(&c->xattr_sem);
  576. for (ref = ic->xref; ref; ref = _ref) {
  577. _ref = ref->next;
  578. xd = ref->xd;
  579. xd->refcnt--;
  580. if (!xd->refcnt) {
  581. unload_xattr_datum(c, xd);
  582. jffs2_free_xattr_datum(xd);
  583. }
  584. jffs2_free_xattr_ref(ref);
  585. }
  586. ic->xref = NULL;
  587. up_write(&c->xattr_sem);
  588. }
  589. static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
  590. {
  591. /* success of check_xattr_ref_inode() means taht inode (ic) dose not have
  592. * duplicate name/value pairs. If duplicate name/value pair would be found,
  593. * one will be removed.
  594. */
  595. struct jffs2_xattr_ref *ref, *cmp, **pref;
  596. int rc = 0;
  597. if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED))
  598. return 0;
  599. down_write(&c->xattr_sem);
  600. retry:
  601. rc = 0;
  602. for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
  603. if (!ref->xd->xname) {
  604. rc = load_xattr_datum(c, ref->xd);
  605. if (unlikely(rc > 0)) {
  606. *pref = ref->next;
  607. delete_xattr_ref(c, ref);
  608. goto retry;
  609. } else if (unlikely(rc < 0))
  610. goto out;
  611. }
  612. for (cmp=ref->next, pref=&ref->next; cmp; pref=&cmp->next, cmp=cmp->next) {
  613. if (!cmp->xd->xname) {
  614. ref->xd->flags |= JFFS2_XFLAGS_BIND;
  615. rc = load_xattr_datum(c, cmp->xd);
  616. ref->xd->flags &= ~JFFS2_XFLAGS_BIND;
  617. if (unlikely(rc > 0)) {
  618. *pref = cmp->next;
  619. delete_xattr_ref(c, cmp);
  620. goto retry;
  621. } else if (unlikely(rc < 0))
  622. goto out;
  623. }
  624. if (ref->xd->xprefix == cmp->xd->xprefix
  625. && !strcmp(ref->xd->xname, cmp->xd->xname)) {
  626. *pref = cmp->next;
  627. delete_xattr_ref(c, cmp);
  628. goto retry;
  629. }
  630. }
  631. }
  632. ic->flags |= INO_FLAGS_XATTR_CHECKED;
  633. out:
  634. up_write(&c->xattr_sem);
  635. return rc;
  636. }
  637. /* -------- xattr subsystem functions ---------------
  638. * jffs2_init_xattr_subsystem(c)
  639. * is used to initialize semaphore and list_head, and some variables.
  640. * jffs2_find_xattr_datum(c, xid)
  641. * is used to lookup xdatum while scanning process.
  642. * jffs2_clear_xattr_subsystem(c)
  643. * is used to release any xattr related objects.
  644. * jffs2_build_xattr_subsystem(c)
  645. * is used to associate xdatum and xref while super block building process.
  646. * jffs2_setup_xattr_datum(c, xid, version)
  647. * is used to insert xdatum while scanning process.
  648. * -------------------------------------------------- */
  649. void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c)
  650. {
  651. int i;
  652. for (i=0; i < XATTRINDEX_HASHSIZE; i++)
  653. INIT_LIST_HEAD(&c->xattrindex[i]);
  654. INIT_LIST_HEAD(&c->xattr_unchecked);
  655. c->xref_temp = NULL;
  656. init_rwsem(&c->xattr_sem);
  657. c->xdatum_mem_usage = 0;
  658. c->xdatum_mem_threshold = 32 * 1024; /* Default 32KB */
  659. }
  660. static struct jffs2_xattr_datum *jffs2_find_xattr_datum(struct jffs2_sb_info *c, uint32_t xid)
  661. {
  662. struct jffs2_xattr_datum *xd;
  663. int i = xid % XATTRINDEX_HASHSIZE;
  664. /* It's only used in scanning/building process. */
  665. BUG_ON(!(c->flags & (JFFS2_SB_FLAG_SCANNING|JFFS2_SB_FLAG_BUILDING)));
  666. list_for_each_entry(xd, &c->xattrindex[i], xindex) {
  667. if (xd->xid==xid)
  668. return xd;
  669. }
  670. return NULL;
  671. }
  672. void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
  673. {
  674. struct jffs2_xattr_datum *xd, *_xd;
  675. struct jffs2_xattr_ref *ref, *_ref;
  676. int i;
  677. for (ref=c->xref_temp; ref; ref = _ref) {
  678. _ref = ref->next;
  679. jffs2_free_xattr_ref(ref);
  680. }
  681. c->xref_temp = NULL;
  682. for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
  683. list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
  684. list_del(&xd->xindex);
  685. if (xd->xname)
  686. kfree(xd->xname);
  687. jffs2_free_xattr_datum(xd);
  688. }
  689. }
  690. }
  691. void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
  692. {
  693. struct jffs2_xattr_ref *ref, *_ref;
  694. struct jffs2_xattr_datum *xd, *_xd;
  695. struct jffs2_inode_cache *ic;
  696. int i, xdatum_count =0, xdatum_unchecked_count = 0, xref_count = 0;
  697. BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));
  698. /* Phase.1 */
  699. for (ref=c->xref_temp; ref; ref=_ref) {
  700. _ref = ref->next;
  701. /* checking REF_UNCHECKED nodes */
  702. if (ref_flags(ref->node) != REF_PRISTINE) {
  703. if (verify_xattr_ref(c, ref)) {
  704. delete_xattr_ref_node(c, ref);
  705. jffs2_free_xattr_ref(ref);
  706. continue;
  707. }
  708. }
  709. /* At this point, ref->xid and ref->ino contain XID and inode number.
  710. ref->xd and ref->ic are not valid yet. */
  711. xd = jffs2_find_xattr_datum(c, ref->xid);
  712. ic = jffs2_get_ino_cache(c, ref->ino);
  713. if (!xd || !ic) {
  714. if (ref_flags(ref->node) != REF_UNCHECKED)
  715. JFFS2_WARNING("xref(ino=%u, xid=%u) is orphan. \n",
  716. ref->ino, ref->xid);
  717. delete_xattr_ref_node(c, ref);
  718. jffs2_free_xattr_ref(ref);
  719. continue;
  720. }
  721. ref->xd = xd;
  722. ref->ic = ic;
  723. xd->refcnt++;
  724. ref->next = ic->xref;
  725. ic->xref = ref;
  726. xref_count++;
  727. }
  728. c->xref_temp = NULL;
  729. /* After this, ref->xid/ino are NEVER used. */
  730. /* Phase.2 */
  731. for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
  732. list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
  733. list_del_init(&xd->xindex);
  734. if (!xd->refcnt) {
  735. if (ref_flags(xd->node) != REF_UNCHECKED)
  736. JFFS2_WARNING("orphan xdatum(xid=%u, version=%u) at %#08x\n",
  737. xd->xid, xd->version, ref_offset(xd->node));
  738. delete_xattr_datum(c, xd);
  739. continue;
  740. }
  741. if (ref_flags(xd->node) != REF_PRISTINE) {
  742. dbg_xattr("unchecked xdatum(xid=%u) at %#08x\n",
  743. xd->xid, ref_offset(xd->node));
  744. list_add(&xd->xindex, &c->xattr_unchecked);
  745. xdatum_unchecked_count++;
  746. }
  747. xdatum_count++;
  748. }
  749. }
  750. /* build complete */
  751. JFFS2_NOTICE("complete building xattr subsystem, %u of xdatum (%u unchecked) and "
  752. "%u of xref found.\n", xdatum_count, xdatum_unchecked_count, xref_count);
  753. }
  754. struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
  755. uint32_t xid, uint32_t version)
  756. {
  757. struct jffs2_xattr_datum *xd, *_xd;
  758. _xd = jffs2_find_xattr_datum(c, xid);
  759. if (_xd) {
  760. dbg_xattr("duplicate xdatum (xid=%u, version=%u/%u) at %#08x\n",
  761. xid, version, _xd->version, ref_offset(_xd->node));
  762. if (version < _xd->version)
  763. return ERR_PTR(-EEXIST);
  764. }
  765. xd = jffs2_alloc_xattr_datum();
  766. if (!xd)
  767. return ERR_PTR(-ENOMEM);
  768. xd->xid = xid;
  769. xd->version = version;
  770. if (xd->xid > c->highest_xid)
  771. c->highest_xid = xd->xid;
  772. list_add_tail(&xd->xindex, &c->xattrindex[xid % XATTRINDEX_HASHSIZE]);
  773. if (_xd) {
  774. list_del_init(&_xd->xindex);
  775. delete_xattr_datum_node(c, _xd);
  776. jffs2_free_xattr_datum(_xd);
  777. }
  778. return xd;
  779. }
  780. /* -------- xattr subsystem functions ---------------
  781. * xprefix_to_handler(xprefix)
  782. * is used to translate xprefix into xattr_handler.
  783. * jffs2_listxattr(dentry, buffer, size)
  784. * is an implementation of listxattr handler on jffs2.
  785. * do_jffs2_getxattr(inode, xprefix, xname, buffer, size)
  786. * is an implementation of getxattr handler on jffs2.
  787. * do_jffs2_setxattr(inode, xprefix, xname, buffer, size, flags)
  788. * is an implementation of setxattr handler on jffs2.
  789. * -------------------------------------------------- */
  790. struct xattr_handler *jffs2_xattr_handlers[] = {
  791. &jffs2_user_xattr_handler,
  792. #ifdef CONFIG_JFFS2_FS_SECURITY
  793. &jffs2_security_xattr_handler,
  794. #endif
  795. #ifdef CONFIG_JFFS2_FS_POSIX_ACL
  796. &jffs2_acl_access_xattr_handler,
  797. &jffs2_acl_default_xattr_handler,
  798. #endif
  799. &jffs2_trusted_xattr_handler,
  800. NULL
  801. };
  802. static struct xattr_handler *xprefix_to_handler(int xprefix) {
  803. struct xattr_handler *ret;
  804. switch (xprefix) {
  805. case JFFS2_XPREFIX_USER:
  806. ret = &jffs2_user_xattr_handler;
  807. break;
  808. #ifdef CONFIG_JFFS2_FS_SECURITY
  809. case JFFS2_XPREFIX_SECURITY:
  810. ret = &jffs2_security_xattr_handler;
  811. break;
  812. #endif
  813. #ifdef CONFIG_JFFS2_FS_POSIX_ACL
  814. case JFFS2_XPREFIX_ACL_ACCESS:
  815. ret = &jffs2_acl_access_xattr_handler;
  816. break;
  817. case JFFS2_XPREFIX_ACL_DEFAULT:
  818. ret = &jffs2_acl_default_xattr_handler;
  819. break;
  820. #endif
  821. case JFFS2_XPREFIX_TRUSTED:
  822. ret = &jffs2_trusted_xattr_handler;
  823. break;
  824. default:
  825. ret = NULL;
  826. break;
  827. }
  828. return ret;
  829. }
  830. ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
  831. {
  832. struct inode *inode = dentry->d_inode;
  833. struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
  834. struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
  835. struct jffs2_inode_cache *ic = f->inocache;
  836. struct jffs2_xattr_ref *ref, **pref;
  837. struct jffs2_xattr_datum *xd;
  838. struct xattr_handler *xhandle;
  839. ssize_t len, rc;
  840. int retry = 0;
  841. rc = check_xattr_ref_inode(c, ic);
  842. if (unlikely(rc))
  843. return rc;
  844. down_read(&c->xattr_sem);
  845. retry:
  846. len = 0;
  847. for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
  848. BUG_ON(ref->ic != ic);
  849. xd = ref->xd;
  850. if (!xd->xname) {
  851. /* xdatum is unchached */
  852. if (!retry) {
  853. retry = 1;
  854. up_read(&c->xattr_sem);
  855. down_write(&c->xattr_sem);
  856. goto retry;
  857. } else {
  858. rc = load_xattr_datum(c, xd);
  859. if (unlikely(rc > 0)) {
  860. *pref = ref->next;
  861. delete_xattr_ref(c, ref);
  862. goto retry;
  863. } else if (unlikely(rc < 0))
  864. goto out;
  865. }
  866. }
  867. xhandle = xprefix_to_handler(xd->xprefix);
  868. if (!xhandle)
  869. continue;
  870. if (buffer) {
  871. rc = xhandle->list(inode, buffer+len, size-len, xd->xname, xd->name_len);
  872. } else {
  873. rc = xhandle->list(inode, NULL, 0, xd->xname, xd->name_len);
  874. }
  875. if (rc < 0)
  876. goto out;
  877. len += rc;
  878. }
  879. rc = len;
  880. out:
  881. if (!retry) {
  882. up_read(&c->xattr_sem);
  883. } else {
  884. up_write(&c->xattr_sem);
  885. }
  886. return rc;
  887. }
  888. int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
  889. char *buffer, size_t size)
  890. {
  891. struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
  892. struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
  893. struct jffs2_inode_cache *ic = f->inocache;
  894. struct jffs2_xattr_datum *xd;
  895. struct jffs2_xattr_ref *ref, **pref;
  896. int rc, retry = 0;
  897. rc = check_xattr_ref_inode(c, ic);
  898. if (unlikely(rc))
  899. return rc;
  900. down_read(&c->xattr_sem);
  901. retry:
  902. for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
  903. BUG_ON(ref->ic!=ic);
  904. xd = ref->xd;
  905. if (xd->xprefix != xprefix)
  906. continue;
  907. if (!xd->xname) {
  908. /* xdatum is unchached */
  909. if (!retry) {
  910. retry = 1;
  911. up_read(&c->xattr_sem);
  912. down_write(&c->xattr_sem);
  913. goto retry;
  914. } else {
  915. rc = load_xattr_datum(c, xd);
  916. if (unlikely(rc > 0)) {
  917. *pref = ref->next;
  918. delete_xattr_ref(c, ref);
  919. goto retry;
  920. } else if (unlikely(rc < 0)) {
  921. goto out;
  922. }
  923. }
  924. }
  925. if (!strcmp(xname, xd->xname)) {
  926. rc = xd->value_len;
  927. if (buffer) {
  928. if (size < rc) {
  929. rc = -ERANGE;
  930. } else {
  931. memcpy(buffer, xd->xvalue, rc);
  932. }
  933. }
  934. goto out;
  935. }
  936. }
  937. rc = -ENODATA;
  938. out:
  939. if (!retry) {
  940. up_read(&c->xattr_sem);
  941. } else {
  942. up_write(&c->xattr_sem);
  943. }
  944. return rc;
  945. }
  946. int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
  947. const char *buffer, size_t size, int flags)
  948. {
  949. struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
  950. struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
  951. struct jffs2_inode_cache *ic = f->inocache;
  952. struct jffs2_xattr_datum *xd;
  953. struct jffs2_xattr_ref *ref, *newref, **pref;
  954. uint32_t phys_ofs, length, request;
  955. int rc;
  956. rc = check_xattr_ref_inode(c, ic);
  957. if (unlikely(rc))
  958. return rc;
  959. request = PAD(sizeof(struct jffs2_raw_xattr) + strlen(xname) + 1 + size);
  960. rc = jffs2_reserve_space(c, request, &phys_ofs, &length,
  961. ALLOC_NORMAL, JFFS2_SUMMARY_XATTR_SIZE);
  962. if (rc) {
  963. JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
  964. return rc;
  965. }
  966. /* Find existing xattr */
  967. down_write(&c->xattr_sem);
  968. retry:
  969. for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
  970. xd = ref->xd;
  971. if (xd->xprefix != xprefix)
  972. continue;
  973. if (!xd->xname) {
  974. rc = load_xattr_datum(c, xd);
  975. if (unlikely(rc > 0)) {
  976. *pref = ref->next;
  977. delete_xattr_ref(c, ref);
  978. goto retry;
  979. } else if (unlikely(rc < 0))
  980. goto out;
  981. }
  982. if (!strcmp(xd->xname, xname)) {
  983. if (flags & XATTR_CREATE) {
  984. rc = -EEXIST;
  985. goto out;
  986. }
  987. if (!buffer) {
  988. *pref = ref->next;
  989. delete_xattr_ref(c, ref);
  990. rc = 0;
  991. goto out;
  992. }
  993. goto found;
  994. }
  995. }
  996. /* not found */
  997. if (flags & XATTR_REPLACE) {
  998. rc = -ENODATA;
  999. goto out;
  1000. }
  1001. if (!buffer) {
  1002. rc = -EINVAL;
  1003. goto out;
  1004. }
  1005. found:
  1006. xd = create_xattr_datum(c, xprefix, xname, buffer, size, phys_ofs);
  1007. if (IS_ERR(xd)) {
  1008. rc = PTR_ERR(xd);
  1009. goto out;
  1010. }
  1011. up_write(&c->xattr_sem);
  1012. jffs2_complete_reservation(c);
  1013. /* create xattr_ref */
  1014. request = PAD(sizeof(struct jffs2_raw_xref));
  1015. rc = jffs2_reserve_space(c, request, &phys_ofs, &length,
  1016. ALLOC_NORMAL, JFFS2_SUMMARY_XREF_SIZE);
  1017. if (rc) {
  1018. JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
  1019. down_write(&c->xattr_sem);
  1020. xd->refcnt--;
  1021. if (!xd->refcnt)
  1022. delete_xattr_datum(c, xd);
  1023. up_write(&c->xattr_sem);
  1024. return rc;
  1025. }
  1026. down_write(&c->xattr_sem);
  1027. if (ref)
  1028. *pref = ref->next;
  1029. newref = create_xattr_ref(c, ic, xd, phys_ofs);
  1030. if (IS_ERR(newref)) {
  1031. if (ref) {
  1032. ref->next = ic->xref;
  1033. ic->xref = ref;
  1034. }
  1035. rc = PTR_ERR(newref);
  1036. xd->refcnt--;
  1037. if (!xd->refcnt)
  1038. delete_xattr_datum(c, xd);
  1039. } else if (ref) {
  1040. delete_xattr_ref(c, ref);
  1041. }
  1042. out:
  1043. up_write(&c->xattr_sem);
  1044. jffs2_complete_reservation(c);
  1045. return rc;
  1046. }
  1047. /* -------- garbage collector functions -------------
  1048. * jffs2_garbage_collect_xattr_datum(c, xd)
  1049. * is used to move xdatum into new node.
  1050. * jffs2_garbage_collect_xattr_ref(c, ref)
  1051. * is used to move xref into new node.
  1052. * jffs2_verify_xattr(c)
  1053. * is used to call do_verify_xattr_datum() before garbage collecting.
  1054. * -------------------------------------------------- */
  1055. int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
  1056. {
  1057. uint32_t phys_ofs, totlen, length, old_ofs;
  1058. int rc = -EINVAL;
  1059. down_write(&c->xattr_sem);
  1060. BUG_ON(!xd->node);
  1061. old_ofs = ref_offset(xd->node);
  1062. totlen = ref_totlen(c, c->gcblock, xd->node);
  1063. if (totlen < sizeof(struct jffs2_raw_xattr))
  1064. goto out;
  1065. if (!xd->xname) {
  1066. rc = load_xattr_datum(c, xd);
  1067. if (unlikely(rc > 0)) {
  1068. delete_xattr_datum_node(c, xd);
  1069. rc = 0;
  1070. goto out;
  1071. } else if (unlikely(rc < 0))
  1072. goto out;
  1073. }
  1074. rc = jffs2_reserve_space_gc(c, totlen, &phys_ofs, &length, JFFS2_SUMMARY_XATTR_SIZE);
  1075. if (rc || length < totlen) {
  1076. JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, totlen);
  1077. rc = rc ? rc : -EBADFD;
  1078. goto out;
  1079. }
  1080. rc = save_xattr_datum(c, xd, phys_ofs);
  1081. if (!rc)
  1082. dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n",
  1083. xd->xid, xd->version, old_ofs, ref_offset(xd->node));
  1084. out:
  1085. up_write(&c->xattr_sem);
  1086. return rc;
  1087. }
  1088. int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
  1089. {
  1090. uint32_t phys_ofs, totlen, length, old_ofs;
  1091. int rc = -EINVAL;
  1092. down_write(&c->xattr_sem);
  1093. BUG_ON(!ref->node);
  1094. old_ofs = ref_offset(ref->node);
  1095. totlen = ref_totlen(c, c->gcblock, ref->node);
  1096. if (totlen != sizeof(struct jffs2_raw_xref))
  1097. goto out;
  1098. rc = jffs2_reserve_space_gc(c, totlen, &phys_ofs, &length, JFFS2_SUMMARY_XREF_SIZE);
  1099. if (rc || length < totlen) {
  1100. JFFS2_WARNING("%s: jffs2_reserve_space() = %d, request = %u\n",
  1101. __FUNCTION__, rc, totlen);
  1102. rc = rc ? rc : -EBADFD;
  1103. goto out;
  1104. }
  1105. rc = save_xattr_ref(c, ref, phys_ofs);
  1106. if (!rc)
  1107. dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n",
  1108. ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node));
  1109. out:
  1110. up_write(&c->xattr_sem);
  1111. return rc;
  1112. }
  1113. int jffs2_verify_xattr(struct jffs2_sb_info *c)
  1114. {
  1115. struct jffs2_xattr_datum *xd, *_xd;
  1116. int rc;
  1117. down_write(&c->xattr_sem);
  1118. list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) {
  1119. rc = do_verify_xattr_datum(c, xd);
  1120. if (rc == 0) {
  1121. list_del_init(&xd->xindex);
  1122. break;
  1123. } else if (rc > 0) {
  1124. list_del_init(&xd->xindex);
  1125. delete_xattr_datum_node(c, xd);
  1126. }
  1127. }
  1128. up_write(&c->xattr_sem);
  1129. return list_empty(&c->xattr_unchecked) ? 1 : 0;
  1130. }