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