xattr.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258
  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. raw->next_in_ino = (void *)xd;
  292. /* Setup raw-xattr */
  293. rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
  294. rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR);
  295. rx.totlen = cpu_to_je32(PAD(totlen));
  296. rx.hdr_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_unknown_node) - 4));
  297. rx.xid = cpu_to_je32(xd->xid);
  298. rx.version = cpu_to_je32(++xd->version);
  299. rx.xprefix = xd->xprefix;
  300. rx.name_len = xd->name_len;
  301. rx.value_len = cpu_to_je16(xd->value_len);
  302. rx.data_crc = cpu_to_je32(crc32(0, vecs[1].iov_base, vecs[1].iov_len));
  303. rx.node_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_raw_xattr) - 4));
  304. rc = jffs2_flash_writev(c, vecs, 2, phys_ofs, &length, 0);
  305. if (rc || totlen != length) {
  306. JFFS2_WARNING("jffs2_flash_writev()=%d, req=%u, wrote=%u, at %#08x\n",
  307. rc, totlen, length, phys_ofs);
  308. rc = rc ? rc : -EIO;
  309. if (length) {
  310. raw->flash_offset |= REF_OBSOLETE;
  311. raw->next_in_ino = NULL;
  312. jffs2_add_physical_node_ref(c, raw, PAD(totlen));
  313. jffs2_mark_node_obsolete(c, raw);
  314. } else {
  315. jffs2_free_raw_node_ref(raw);
  316. }
  317. return rc;
  318. }
  319. /* success */
  320. raw->flash_offset |= REF_PRISTINE;
  321. jffs2_add_physical_node_ref(c, raw, PAD(totlen));
  322. if (xd->node)
  323. delete_xattr_datum_node(c, xd);
  324. xd->node = raw;
  325. dbg_xattr("success on saving xdatum (xid=%u, version=%u, xprefix=%u, xname='%s')\n",
  326. xd->xid, xd->version, xd->xprefix, xd->xname);
  327. return 0;
  328. }
  329. static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
  330. int xprefix, const char *xname,
  331. const char *xvalue, int xsize,
  332. uint32_t phys_ofs)
  333. {
  334. /* must be called under down_write(xattr_sem) */
  335. struct jffs2_xattr_datum *xd;
  336. uint32_t hashkey, name_len;
  337. char *data;
  338. int i, rc;
  339. /* Search xattr_datum has same xname/xvalue by index */
  340. hashkey = xattr_datum_hashkey(xprefix, xname, xvalue, xsize);
  341. i = hashkey % XATTRINDEX_HASHSIZE;
  342. list_for_each_entry(xd, &c->xattrindex[i], xindex) {
  343. if (xd->hashkey==hashkey
  344. && xd->xprefix==xprefix
  345. && xd->value_len==xsize
  346. && !strcmp(xd->xname, xname)
  347. && !memcmp(xd->xvalue, xvalue, xsize)) {
  348. xd->refcnt++;
  349. return xd;
  350. }
  351. }
  352. /* Not found, Create NEW XATTR-Cache */
  353. name_len = strlen(xname);
  354. xd = jffs2_alloc_xattr_datum();
  355. if (!xd)
  356. return ERR_PTR(-ENOMEM);
  357. data = kmalloc(name_len + 1 + xsize, GFP_KERNEL);
  358. if (!data) {
  359. jffs2_free_xattr_datum(xd);
  360. return ERR_PTR(-ENOMEM);
  361. }
  362. strcpy(data, xname);
  363. memcpy(data + name_len + 1, xvalue, xsize);
  364. xd->refcnt = 1;
  365. xd->xid = ++c->highest_xid;
  366. xd->flags |= JFFS2_XFLAGS_HOT;
  367. xd->xprefix = xprefix;
  368. xd->hashkey = hashkey;
  369. xd->xname = data;
  370. xd->xvalue = data + name_len + 1;
  371. xd->name_len = name_len;
  372. xd->value_len = xsize;
  373. xd->data_crc = crc32(0, data, xd->name_len + 1 + xd->value_len);
  374. rc = save_xattr_datum(c, xd, phys_ofs);
  375. if (rc) {
  376. kfree(xd->xname);
  377. jffs2_free_xattr_datum(xd);
  378. return ERR_PTR(rc);
  379. }
  380. /* Insert Hash Index */
  381. i = hashkey % XATTRINDEX_HASHSIZE;
  382. list_add(&xd->xindex, &c->xattrindex[i]);
  383. c->xdatum_mem_usage += (xd->name_len + 1 + xd->value_len);
  384. reclaim_xattr_datum(c);
  385. return xd;
  386. }
  387. /* -------- xref related functions ------------------
  388. * verify_xattr_ref(c, ref)
  389. * is used to load xref information from medium. Because summary data does not
  390. * contain xid/ino, it's necessary to verify once while mounting process.
  391. * delete_xattr_ref_node(c, ref)
  392. * is used to delete a jffs2 node is dominated by xref. When EBS is enabled,
  393. * it overwrites the obsolete node by myself.
  394. * delete_xattr_ref(c, ref)
  395. * is used to delete jffs2_xattr_ref object. If the reference counter of xdatum
  396. * is refered by this xref become 0, delete_xattr_datum() is called later.
  397. * save_xattr_ref(c, ref, phys_ofs)
  398. * is used to write xref to medium.
  399. * create_xattr_ref(c, ic, xd, phys_ofs)
  400. * is used to create a new xref and write to medium.
  401. * jffs2_xattr_delete_inode(c, ic)
  402. * is called to remove xrefs related to obsolete inode when inode is unlinked.
  403. * jffs2_xattr_free_inode(c, ic)
  404. * is called to release xattr related objects when unmounting.
  405. * check_xattr_ref_inode(c, ic)
  406. * is used to confirm inode does not have duplicate xattr name/value pair.
  407. * -------------------------------------------------- */
  408. static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
  409. {
  410. struct jffs2_eraseblock *jeb;
  411. struct jffs2_raw_xref rr;
  412. size_t readlen;
  413. uint32_t crc, totlen;
  414. int rc;
  415. BUG_ON(ref_flags(ref->node) != REF_UNCHECKED);
  416. rc = jffs2_flash_read(c, ref_offset(ref->node), sizeof(rr), &readlen, (char *)&rr);
  417. if (rc || sizeof(rr) != readlen) {
  418. JFFS2_WARNING("jffs2_flash_read()=%d, req=%u, read=%u, at %#08x\n",
  419. rc, sizeof(rr), readlen, ref_offset(ref->node));
  420. return rc ? rc : -EIO;
  421. }
  422. /* obsolete node */
  423. crc = crc32(0, &rr, sizeof(rr) - 4);
  424. if (crc != je32_to_cpu(rr.node_crc)) {
  425. if (je32_to_cpu(rr.node_crc) != 0xffffffff)
  426. JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
  427. ref_offset(ref->node), je32_to_cpu(rr.node_crc), crc);
  428. return EIO;
  429. }
  430. if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK
  431. || je16_to_cpu(rr.nodetype) != JFFS2_NODETYPE_XREF
  432. || je32_to_cpu(rr.totlen) != PAD(sizeof(rr))) {
  433. JFFS2_ERROR("inconsistent xref at %#08x, magic=%#04x/%#04x, "
  434. "nodetype=%#04x/%#04x, totlen=%u/%u\n",
  435. ref_offset(ref->node), je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK,
  436. je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF,
  437. je32_to_cpu(rr.totlen), PAD(sizeof(rr)));
  438. return EIO;
  439. }
  440. ref->ino = je32_to_cpu(rr.ino);
  441. ref->xid = je32_to_cpu(rr.xid);
  442. /* fixup superblock/eraseblock info */
  443. jeb = &c->blocks[ref_offset(ref->node) / c->sector_size];
  444. totlen = PAD(sizeof(rr));
  445. spin_lock(&c->erase_completion_lock);
  446. c->unchecked_size -= totlen; c->used_size += totlen;
  447. jeb->unchecked_size -= totlen; jeb->used_size += totlen;
  448. ref->node->flash_offset = ref_offset(ref->node) | REF_PRISTINE;
  449. spin_unlock(&c->erase_completion_lock);
  450. dbg_xattr("success on verifying xref (ino=%u, xid=%u) at %#08x\n",
  451. ref->ino, ref->xid, ref_offset(ref->node));
  452. return 0;
  453. }
  454. static void delete_xattr_ref_node(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
  455. {
  456. struct jffs2_raw_xref rr;
  457. uint32_t length;
  458. int rc;
  459. if (jffs2_sum_active()) {
  460. memset(&rr, 0xff, sizeof(rr));
  461. rc = jffs2_flash_read(c, ref_offset(ref->node),
  462. sizeof(struct jffs2_unknown_node),
  463. &length, (char *)&rr);
  464. if (rc || length != sizeof(struct jffs2_unknown_node)) {
  465. JFFS2_ERROR("jffs2_flash_read()=%d, req=%u, read=%u at %#08x\n",
  466. rc, sizeof(struct jffs2_unknown_node),
  467. length, ref_offset(ref->node));
  468. }
  469. rc = jffs2_flash_write(c, ref_offset(ref->node), sizeof(rr),
  470. &length, (char *)&rr);
  471. if (rc || length != sizeof(struct jffs2_raw_xref)) {
  472. JFFS2_ERROR("jffs2_flash_write()=%d, req=%u, wrote=%u at %#08x\n",
  473. rc, sizeof(rr), length, ref_offset(ref->node));
  474. }
  475. }
  476. spin_lock(&c->erase_completion_lock);
  477. ref->node->next_in_ino = NULL;
  478. spin_unlock(&c->erase_completion_lock);
  479. jffs2_mark_node_obsolete(c, ref->node);
  480. ref->node = NULL;
  481. }
  482. static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
  483. {
  484. /* must be called under down_write(xattr_sem) */
  485. struct jffs2_xattr_datum *xd;
  486. BUG_ON(!ref->node);
  487. delete_xattr_ref_node(c, ref);
  488. xd = ref->xd;
  489. xd->refcnt--;
  490. if (!xd->refcnt)
  491. delete_xattr_datum(c, xd);
  492. jffs2_free_xattr_ref(ref);
  493. }
  494. static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref, uint32_t phys_ofs)
  495. {
  496. /* must be called under down_write(xattr_sem) */
  497. struct jffs2_raw_node_ref *raw;
  498. struct jffs2_raw_xref rr;
  499. uint32_t length;
  500. int ret;
  501. raw = jffs2_alloc_raw_node_ref();
  502. if (!raw)
  503. return -ENOMEM;
  504. raw->flash_offset = phys_ofs;
  505. raw->next_in_ino = (void *)ref;
  506. rr.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
  507. rr.nodetype = cpu_to_je16(JFFS2_NODETYPE_XREF);
  508. rr.totlen = cpu_to_je32(PAD(sizeof(rr)));
  509. rr.hdr_crc = cpu_to_je32(crc32(0, &rr, sizeof(struct jffs2_unknown_node) - 4));
  510. rr.ino = cpu_to_je32(ref->ic->ino);
  511. rr.xid = cpu_to_je32(ref->xd->xid);
  512. rr.node_crc = cpu_to_je32(crc32(0, &rr, sizeof(rr) - 4));
  513. ret = jffs2_flash_write(c, phys_ofs, sizeof(rr), &length, (char *)&rr);
  514. if (ret || sizeof(rr) != length) {
  515. JFFS2_WARNING("jffs2_flash_write() returned %d, request=%u, retlen=%u, at %#08x\n",
  516. ret, sizeof(rr), length, phys_ofs);
  517. ret = ret ? ret : -EIO;
  518. if (length) {
  519. raw->flash_offset |= REF_OBSOLETE;
  520. raw->next_in_ino = NULL;
  521. jffs2_add_physical_node_ref(c, raw, PAD(sizeof(rr)));
  522. jffs2_mark_node_obsolete(c, raw);
  523. } else {
  524. jffs2_free_raw_node_ref(raw);
  525. }
  526. return ret;
  527. }
  528. raw->flash_offset |= REF_PRISTINE;
  529. jffs2_add_physical_node_ref(c, raw, PAD(sizeof(rr)));
  530. if (ref->node)
  531. delete_xattr_ref_node(c, ref);
  532. ref->node = raw;
  533. dbg_xattr("success on saving xref (ino=%u, xid=%u)\n", ref->ic->ino, ref->xd->xid);
  534. return 0;
  535. }
  536. static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic,
  537. struct jffs2_xattr_datum *xd, uint32_t phys_ofs)
  538. {
  539. /* must be called under down_write(xattr_sem) */
  540. struct jffs2_xattr_ref *ref;
  541. int ret;
  542. ref = jffs2_alloc_xattr_ref();
  543. if (!ref)
  544. return ERR_PTR(-ENOMEM);
  545. ref->ic = ic;
  546. ref->xd = xd;
  547. ret = save_xattr_ref(c, ref, phys_ofs);
  548. if (ret) {
  549. jffs2_free_xattr_ref(ref);
  550. return ERR_PTR(ret);
  551. }
  552. /* Chain to inode */
  553. ref->next = ic->xref;
  554. ic->xref = ref;
  555. return ref; /* success */
  556. }
  557. void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
  558. {
  559. /* It's called from jffs2_clear_inode() on inode removing.
  560. When an inode with XATTR is removed, those XATTRs must be removed. */
  561. struct jffs2_xattr_ref *ref, *_ref;
  562. if (!ic || ic->nlink > 0)
  563. return;
  564. down_write(&c->xattr_sem);
  565. for (ref = ic->xref; ref; ref = _ref) {
  566. _ref = ref->next;
  567. delete_xattr_ref(c, ref);
  568. }
  569. ic->xref = NULL;
  570. up_write(&c->xattr_sem);
  571. }
  572. void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
  573. {
  574. /* It's called from jffs2_free_ino_caches() until unmounting FS. */
  575. struct jffs2_xattr_datum *xd;
  576. struct jffs2_xattr_ref *ref, *_ref;
  577. down_write(&c->xattr_sem);
  578. for (ref = ic->xref; ref; ref = _ref) {
  579. _ref = ref->next;
  580. xd = ref->xd;
  581. xd->refcnt--;
  582. if (!xd->refcnt) {
  583. unload_xattr_datum(c, xd);
  584. jffs2_free_xattr_datum(xd);
  585. }
  586. jffs2_free_xattr_ref(ref);
  587. }
  588. ic->xref = NULL;
  589. up_write(&c->xattr_sem);
  590. }
  591. static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
  592. {
  593. /* success of check_xattr_ref_inode() means taht inode (ic) dose not have
  594. * duplicate name/value pairs. If duplicate name/value pair would be found,
  595. * one will be removed.
  596. */
  597. struct jffs2_xattr_ref *ref, *cmp, **pref;
  598. int rc = 0;
  599. if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED))
  600. return 0;
  601. down_write(&c->xattr_sem);
  602. retry:
  603. rc = 0;
  604. for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
  605. if (!ref->xd->xname) {
  606. rc = load_xattr_datum(c, ref->xd);
  607. if (unlikely(rc > 0)) {
  608. *pref = ref->next;
  609. delete_xattr_ref(c, ref);
  610. goto retry;
  611. } else if (unlikely(rc < 0))
  612. goto out;
  613. }
  614. for (cmp=ref->next, pref=&ref->next; cmp; pref=&cmp->next, cmp=cmp->next) {
  615. if (!cmp->xd->xname) {
  616. ref->xd->flags |= JFFS2_XFLAGS_BIND;
  617. rc = load_xattr_datum(c, cmp->xd);
  618. ref->xd->flags &= ~JFFS2_XFLAGS_BIND;
  619. if (unlikely(rc > 0)) {
  620. *pref = cmp->next;
  621. delete_xattr_ref(c, cmp);
  622. goto retry;
  623. } else if (unlikely(rc < 0))
  624. goto out;
  625. }
  626. if (ref->xd->xprefix == cmp->xd->xprefix
  627. && !strcmp(ref->xd->xname, cmp->xd->xname)) {
  628. *pref = cmp->next;
  629. delete_xattr_ref(c, cmp);
  630. goto retry;
  631. }
  632. }
  633. }
  634. ic->flags |= INO_FLAGS_XATTR_CHECKED;
  635. out:
  636. up_write(&c->xattr_sem);
  637. return rc;
  638. }
  639. /* -------- xattr subsystem functions ---------------
  640. * jffs2_init_xattr_subsystem(c)
  641. * is used to initialize semaphore and list_head, and some variables.
  642. * jffs2_find_xattr_datum(c, xid)
  643. * is used to lookup xdatum while scanning process.
  644. * jffs2_clear_xattr_subsystem(c)
  645. * is used to release any xattr related objects.
  646. * jffs2_build_xattr_subsystem(c)
  647. * is used to associate xdatum and xref while super block building process.
  648. * jffs2_setup_xattr_datum(c, xid, version)
  649. * is used to insert xdatum while scanning process.
  650. * -------------------------------------------------- */
  651. void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c)
  652. {
  653. int i;
  654. for (i=0; i < XATTRINDEX_HASHSIZE; i++)
  655. INIT_LIST_HEAD(&c->xattrindex[i]);
  656. INIT_LIST_HEAD(&c->xattr_unchecked);
  657. c->xref_temp = NULL;
  658. init_rwsem(&c->xattr_sem);
  659. c->xdatum_mem_usage = 0;
  660. c->xdatum_mem_threshold = 32 * 1024; /* Default 32KB */
  661. }
  662. static struct jffs2_xattr_datum *jffs2_find_xattr_datum(struct jffs2_sb_info *c, uint32_t xid)
  663. {
  664. struct jffs2_xattr_datum *xd;
  665. int i = xid % XATTRINDEX_HASHSIZE;
  666. /* It's only used in scanning/building process. */
  667. BUG_ON(!(c->flags & (JFFS2_SB_FLAG_SCANNING|JFFS2_SB_FLAG_BUILDING)));
  668. list_for_each_entry(xd, &c->xattrindex[i], xindex) {
  669. if (xd->xid==xid)
  670. return xd;
  671. }
  672. return NULL;
  673. }
  674. void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
  675. {
  676. struct jffs2_xattr_datum *xd, *_xd;
  677. struct jffs2_xattr_ref *ref, *_ref;
  678. int i;
  679. for (ref=c->xref_temp; ref; ref = _ref) {
  680. _ref = ref->next;
  681. jffs2_free_xattr_ref(ref);
  682. }
  683. c->xref_temp = NULL;
  684. for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
  685. list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
  686. list_del(&xd->xindex);
  687. if (xd->xname)
  688. kfree(xd->xname);
  689. jffs2_free_xattr_datum(xd);
  690. }
  691. }
  692. }
  693. void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
  694. {
  695. struct jffs2_xattr_ref *ref, *_ref;
  696. struct jffs2_xattr_datum *xd, *_xd;
  697. struct jffs2_inode_cache *ic;
  698. int i, xdatum_count =0, xdatum_unchecked_count = 0, xref_count = 0;
  699. BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));
  700. /* Phase.1 */
  701. for (ref=c->xref_temp; ref; ref=_ref) {
  702. _ref = ref->next;
  703. /* checking REF_UNCHECKED nodes */
  704. if (ref_flags(ref->node) != REF_PRISTINE) {
  705. if (verify_xattr_ref(c, ref)) {
  706. delete_xattr_ref_node(c, ref);
  707. jffs2_free_xattr_ref(ref);
  708. continue;
  709. }
  710. }
  711. /* At this point, ref->xid and ref->ino contain XID and inode number.
  712. ref->xd and ref->ic are not valid yet. */
  713. xd = jffs2_find_xattr_datum(c, ref->xid);
  714. ic = jffs2_get_ino_cache(c, ref->ino);
  715. if (!xd || !ic) {
  716. if (ref_flags(ref->node) != REF_UNCHECKED)
  717. JFFS2_WARNING("xref(ino=%u, xid=%u) is orphan. \n",
  718. ref->ino, ref->xid);
  719. delete_xattr_ref_node(c, ref);
  720. jffs2_free_xattr_ref(ref);
  721. continue;
  722. }
  723. ref->xd = xd;
  724. ref->ic = ic;
  725. xd->refcnt++;
  726. ref->next = ic->xref;
  727. ic->xref = ref;
  728. xref_count++;
  729. }
  730. c->xref_temp = NULL;
  731. /* After this, ref->xid/ino are NEVER used. */
  732. /* Phase.2 */
  733. for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
  734. list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
  735. list_del_init(&xd->xindex);
  736. if (!xd->refcnt) {
  737. if (ref_flags(xd->node) != REF_UNCHECKED)
  738. JFFS2_WARNING("orphan xdatum(xid=%u, version=%u) at %#08x\n",
  739. xd->xid, xd->version, ref_offset(xd->node));
  740. delete_xattr_datum(c, xd);
  741. continue;
  742. }
  743. if (ref_flags(xd->node) != REF_PRISTINE) {
  744. dbg_xattr("unchecked xdatum(xid=%u) at %#08x\n",
  745. xd->xid, ref_offset(xd->node));
  746. list_add(&xd->xindex, &c->xattr_unchecked);
  747. xdatum_unchecked_count++;
  748. }
  749. xdatum_count++;
  750. }
  751. }
  752. /* build complete */
  753. JFFS2_NOTICE("complete building xattr subsystem, %u of xdatum (%u unchecked) and "
  754. "%u of xref found.\n", xdatum_count, xdatum_unchecked_count, xref_count);
  755. }
  756. struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
  757. uint32_t xid, uint32_t version)
  758. {
  759. struct jffs2_xattr_datum *xd, *_xd;
  760. _xd = jffs2_find_xattr_datum(c, xid);
  761. if (_xd) {
  762. dbg_xattr("duplicate xdatum (xid=%u, version=%u/%u) at %#08x\n",
  763. xid, version, _xd->version, ref_offset(_xd->node));
  764. if (version < _xd->version)
  765. return ERR_PTR(-EEXIST);
  766. }
  767. xd = jffs2_alloc_xattr_datum();
  768. if (!xd)
  769. return ERR_PTR(-ENOMEM);
  770. xd->xid = xid;
  771. xd->version = version;
  772. if (xd->xid > c->highest_xid)
  773. c->highest_xid = xd->xid;
  774. list_add_tail(&xd->xindex, &c->xattrindex[xid % XATTRINDEX_HASHSIZE]);
  775. if (_xd) {
  776. list_del_init(&_xd->xindex);
  777. delete_xattr_datum_node(c, _xd);
  778. jffs2_free_xattr_datum(_xd);
  779. }
  780. return xd;
  781. }
  782. /* -------- xattr subsystem functions ---------------
  783. * xprefix_to_handler(xprefix)
  784. * is used to translate xprefix into xattr_handler.
  785. * jffs2_listxattr(dentry, buffer, size)
  786. * is an implementation of listxattr handler on jffs2.
  787. * do_jffs2_getxattr(inode, xprefix, xname, buffer, size)
  788. * is an implementation of getxattr handler on jffs2.
  789. * do_jffs2_setxattr(inode, xprefix, xname, buffer, size, flags)
  790. * is an implementation of setxattr handler on jffs2.
  791. * -------------------------------------------------- */
  792. struct xattr_handler *jffs2_xattr_handlers[] = {
  793. &jffs2_user_xattr_handler,
  794. #ifdef CONFIG_JFFS2_FS_SECURITY
  795. &jffs2_security_xattr_handler,
  796. #endif
  797. #ifdef CONFIG_JFFS2_FS_POSIX_ACL
  798. &jffs2_acl_access_xattr_handler,
  799. &jffs2_acl_default_xattr_handler,
  800. #endif
  801. &jffs2_trusted_xattr_handler,
  802. NULL
  803. };
  804. static struct xattr_handler *xprefix_to_handler(int xprefix) {
  805. struct xattr_handler *ret;
  806. switch (xprefix) {
  807. case JFFS2_XPREFIX_USER:
  808. ret = &jffs2_user_xattr_handler;
  809. break;
  810. #ifdef CONFIG_JFFS2_FS_SECURITY
  811. case JFFS2_XPREFIX_SECURITY:
  812. ret = &jffs2_security_xattr_handler;
  813. break;
  814. #endif
  815. #ifdef CONFIG_JFFS2_FS_POSIX_ACL
  816. case JFFS2_XPREFIX_ACL_ACCESS:
  817. ret = &jffs2_acl_access_xattr_handler;
  818. break;
  819. case JFFS2_XPREFIX_ACL_DEFAULT:
  820. ret = &jffs2_acl_default_xattr_handler;
  821. break;
  822. #endif
  823. case JFFS2_XPREFIX_TRUSTED:
  824. ret = &jffs2_trusted_xattr_handler;
  825. break;
  826. default:
  827. ret = NULL;
  828. break;
  829. }
  830. return ret;
  831. }
  832. ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
  833. {
  834. struct inode *inode = dentry->d_inode;
  835. struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
  836. struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
  837. struct jffs2_inode_cache *ic = f->inocache;
  838. struct jffs2_xattr_ref *ref, **pref;
  839. struct jffs2_xattr_datum *xd;
  840. struct xattr_handler *xhandle;
  841. ssize_t len, rc;
  842. int retry = 0;
  843. rc = check_xattr_ref_inode(c, ic);
  844. if (unlikely(rc))
  845. return rc;
  846. down_read(&c->xattr_sem);
  847. retry:
  848. len = 0;
  849. for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
  850. BUG_ON(ref->ic != ic);
  851. xd = ref->xd;
  852. if (!xd->xname) {
  853. /* xdatum is unchached */
  854. if (!retry) {
  855. retry = 1;
  856. up_read(&c->xattr_sem);
  857. down_write(&c->xattr_sem);
  858. goto retry;
  859. } else {
  860. rc = load_xattr_datum(c, xd);
  861. if (unlikely(rc > 0)) {
  862. *pref = ref->next;
  863. delete_xattr_ref(c, ref);
  864. goto retry;
  865. } else if (unlikely(rc < 0))
  866. goto out;
  867. }
  868. }
  869. xhandle = xprefix_to_handler(xd->xprefix);
  870. if (!xhandle)
  871. continue;
  872. if (buffer) {
  873. rc = xhandle->list(inode, buffer+len, size-len, xd->xname, xd->name_len);
  874. } else {
  875. rc = xhandle->list(inode, NULL, 0, xd->xname, xd->name_len);
  876. }
  877. if (rc < 0)
  878. goto out;
  879. len += rc;
  880. }
  881. rc = len;
  882. out:
  883. if (!retry) {
  884. up_read(&c->xattr_sem);
  885. } else {
  886. up_write(&c->xattr_sem);
  887. }
  888. return rc;
  889. }
  890. int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
  891. char *buffer, size_t size)
  892. {
  893. struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
  894. struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
  895. struct jffs2_inode_cache *ic = f->inocache;
  896. struct jffs2_xattr_datum *xd;
  897. struct jffs2_xattr_ref *ref, **pref;
  898. int rc, retry = 0;
  899. rc = check_xattr_ref_inode(c, ic);
  900. if (unlikely(rc))
  901. return rc;
  902. down_read(&c->xattr_sem);
  903. retry:
  904. for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
  905. BUG_ON(ref->ic!=ic);
  906. xd = ref->xd;
  907. if (xd->xprefix != xprefix)
  908. continue;
  909. if (!xd->xname) {
  910. /* xdatum is unchached */
  911. if (!retry) {
  912. retry = 1;
  913. up_read(&c->xattr_sem);
  914. down_write(&c->xattr_sem);
  915. goto retry;
  916. } else {
  917. rc = load_xattr_datum(c, xd);
  918. if (unlikely(rc > 0)) {
  919. *pref = ref->next;
  920. delete_xattr_ref(c, ref);
  921. goto retry;
  922. } else if (unlikely(rc < 0)) {
  923. goto out;
  924. }
  925. }
  926. }
  927. if (!strcmp(xname, xd->xname)) {
  928. rc = xd->value_len;
  929. if (buffer) {
  930. if (size < rc) {
  931. rc = -ERANGE;
  932. } else {
  933. memcpy(buffer, xd->xvalue, rc);
  934. }
  935. }
  936. goto out;
  937. }
  938. }
  939. rc = -ENODATA;
  940. out:
  941. if (!retry) {
  942. up_read(&c->xattr_sem);
  943. } else {
  944. up_write(&c->xattr_sem);
  945. }
  946. return rc;
  947. }
  948. int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
  949. const char *buffer, size_t size, int flags)
  950. {
  951. struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
  952. struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
  953. struct jffs2_inode_cache *ic = f->inocache;
  954. struct jffs2_xattr_datum *xd;
  955. struct jffs2_xattr_ref *ref, *newref, **pref;
  956. uint32_t phys_ofs, length, request;
  957. int rc;
  958. rc = check_xattr_ref_inode(c, ic);
  959. if (unlikely(rc))
  960. return rc;
  961. request = PAD(sizeof(struct jffs2_raw_xattr) + strlen(xname) + 1 + size);
  962. rc = jffs2_reserve_space(c, request, &phys_ofs, &length,
  963. ALLOC_NORMAL, JFFS2_SUMMARY_XATTR_SIZE);
  964. if (rc) {
  965. JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
  966. return rc;
  967. }
  968. /* Find existing xattr */
  969. down_write(&c->xattr_sem);
  970. retry:
  971. for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
  972. xd = ref->xd;
  973. if (xd->xprefix != xprefix)
  974. continue;
  975. if (!xd->xname) {
  976. rc = load_xattr_datum(c, xd);
  977. if (unlikely(rc > 0)) {
  978. *pref = ref->next;
  979. delete_xattr_ref(c, ref);
  980. goto retry;
  981. } else if (unlikely(rc < 0))
  982. goto out;
  983. }
  984. if (!strcmp(xd->xname, xname)) {
  985. if (flags & XATTR_CREATE) {
  986. rc = -EEXIST;
  987. goto out;
  988. }
  989. if (!buffer) {
  990. *pref = ref->next;
  991. delete_xattr_ref(c, ref);
  992. rc = 0;
  993. goto out;
  994. }
  995. goto found;
  996. }
  997. }
  998. /* not found */
  999. if (flags & XATTR_REPLACE) {
  1000. rc = -ENODATA;
  1001. goto out;
  1002. }
  1003. if (!buffer) {
  1004. rc = -EINVAL;
  1005. goto out;
  1006. }
  1007. found:
  1008. xd = create_xattr_datum(c, xprefix, xname, buffer, size, phys_ofs);
  1009. if (IS_ERR(xd)) {
  1010. rc = PTR_ERR(xd);
  1011. goto out;
  1012. }
  1013. up_write(&c->xattr_sem);
  1014. jffs2_complete_reservation(c);
  1015. /* create xattr_ref */
  1016. request = PAD(sizeof(struct jffs2_raw_xref));
  1017. rc = jffs2_reserve_space(c, request, &phys_ofs, &length,
  1018. ALLOC_NORMAL, JFFS2_SUMMARY_XREF_SIZE);
  1019. if (rc) {
  1020. JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
  1021. down_write(&c->xattr_sem);
  1022. xd->refcnt--;
  1023. if (!xd->refcnt)
  1024. delete_xattr_datum(c, xd);
  1025. up_write(&c->xattr_sem);
  1026. return rc;
  1027. }
  1028. down_write(&c->xattr_sem);
  1029. if (ref)
  1030. *pref = ref->next;
  1031. newref = create_xattr_ref(c, ic, xd, phys_ofs);
  1032. if (IS_ERR(newref)) {
  1033. if (ref) {
  1034. ref->next = ic->xref;
  1035. ic->xref = ref;
  1036. }
  1037. rc = PTR_ERR(newref);
  1038. xd->refcnt--;
  1039. if (!xd->refcnt)
  1040. delete_xattr_datum(c, xd);
  1041. } else if (ref) {
  1042. delete_xattr_ref(c, ref);
  1043. }
  1044. out:
  1045. up_write(&c->xattr_sem);
  1046. jffs2_complete_reservation(c);
  1047. return rc;
  1048. }
  1049. /* -------- garbage collector functions -------------
  1050. * jffs2_garbage_collect_xattr_datum(c, xd)
  1051. * is used to move xdatum into new node.
  1052. * jffs2_garbage_collect_xattr_ref(c, ref)
  1053. * is used to move xref into new node.
  1054. * jffs2_verify_xattr(c)
  1055. * is used to call do_verify_xattr_datum() before garbage collecting.
  1056. * -------------------------------------------------- */
  1057. int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
  1058. {
  1059. uint32_t phys_ofs, totlen, length, old_ofs;
  1060. int rc = -EINVAL;
  1061. down_write(&c->xattr_sem);
  1062. BUG_ON(!xd->node);
  1063. old_ofs = ref_offset(xd->node);
  1064. totlen = ref_totlen(c, c->gcblock, xd->node);
  1065. if (totlen < sizeof(struct jffs2_raw_xattr))
  1066. goto out;
  1067. if (!xd->xname) {
  1068. rc = load_xattr_datum(c, xd);
  1069. if (unlikely(rc > 0)) {
  1070. delete_xattr_datum_node(c, xd);
  1071. rc = 0;
  1072. goto out;
  1073. } else if (unlikely(rc < 0))
  1074. goto out;
  1075. }
  1076. rc = jffs2_reserve_space_gc(c, totlen, &phys_ofs, &length, JFFS2_SUMMARY_XATTR_SIZE);
  1077. if (rc || length < totlen) {
  1078. JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, totlen);
  1079. rc = rc ? rc : -EBADFD;
  1080. goto out;
  1081. }
  1082. rc = save_xattr_datum(c, xd, phys_ofs);
  1083. if (!rc)
  1084. dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n",
  1085. xd->xid, xd->version, old_ofs, ref_offset(xd->node));
  1086. out:
  1087. up_write(&c->xattr_sem);
  1088. return rc;
  1089. }
  1090. int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
  1091. {
  1092. uint32_t phys_ofs, totlen, length, old_ofs;
  1093. int rc = -EINVAL;
  1094. down_write(&c->xattr_sem);
  1095. BUG_ON(!ref->node);
  1096. old_ofs = ref_offset(ref->node);
  1097. totlen = ref_totlen(c, c->gcblock, ref->node);
  1098. if (totlen != sizeof(struct jffs2_raw_xref))
  1099. goto out;
  1100. rc = jffs2_reserve_space_gc(c, totlen, &phys_ofs, &length, JFFS2_SUMMARY_XREF_SIZE);
  1101. if (rc || length < totlen) {
  1102. JFFS2_WARNING("%s: jffs2_reserve_space() = %d, request = %u\n",
  1103. __FUNCTION__, rc, totlen);
  1104. rc = rc ? rc : -EBADFD;
  1105. goto out;
  1106. }
  1107. rc = save_xattr_ref(c, ref, phys_ofs);
  1108. if (!rc)
  1109. dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n",
  1110. ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node));
  1111. out:
  1112. up_write(&c->xattr_sem);
  1113. return rc;
  1114. }
  1115. int jffs2_verify_xattr(struct jffs2_sb_info *c)
  1116. {
  1117. struct jffs2_xattr_datum *xd, *_xd;
  1118. int rc;
  1119. down_write(&c->xattr_sem);
  1120. list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) {
  1121. rc = do_verify_xattr_datum(c, xd);
  1122. if (rc == 0) {
  1123. list_del_init(&xd->xindex);
  1124. break;
  1125. } else if (rc > 0) {
  1126. list_del_init(&xd->xindex);
  1127. delete_xattr_datum_node(c, xd);
  1128. }
  1129. }
  1130. up_write(&c->xattr_sem);
  1131. return list_empty(&c->xattr_unchecked) ? 1 : 0;
  1132. }