fs/jffs2/xattr.c
Source file repositories/reference/linux-study-clean/fs/jffs2/xattr.c
File Facts
- System
- Linux kernel
- Corpus path
fs/jffs2/xattr.c- Extension
.c- Size
- 39232 bytes
- Lines
- 1354
- Domain
- Core OS
- Bucket
- VFS And Filesystem Core
- Inferred role
- Core OS: implementation source
- Status
- source implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/slab.hlinux/fs.hlinux/time.hlinux/pagemap.hlinux/highmem.hlinux/crc32.hlinux/jffs2.hlinux/xattr.hlinux/posix_acl_xattr.hlinux/mtd/mtd.hnodelist.h
Detected Declarations
function xattr_datum_hashkeyfunction is_xattr_datum_uncheckedfunction unload_xattr_datumfunction reclaim_xattr_datumfunction list_for_each_entry_safefunction do_verify_xattr_datumfunction do_load_xattr_datumfunction load_xattr_datumfunction save_xattr_datumfunction unrefer_xattr_datumfunction verify_xattr_reffunction save_xattr_reffunction delete_xattr_reffunction jffs2_xattr_delete_inodefunction jffs2_xattr_free_inodefunction check_xattr_ref_inodefunction jffs2_xattr_do_crccheck_inodefunction jffs2_init_xattr_subsystemfunction list_for_each_entryfunction jffs2_clear_xattr_subsystemfunction list_for_each_entry_safefunction list_for_each_entry_safefunction jffs2_build_xattr_subsystemfunction list_for_each_entry_safefunction jffs2_listxattrfunction do_jffs2_getxattrfunction do_jffs2_setxattrfunction jffs2_garbage_collect_xattr_datumfunction jffs2_garbage_collect_xattr_reffunction jffs2_verify_xattrfunction jffs2_release_xattr_datumfunction jffs2_release_xattr_ref
Annotated Snippet
if (ref_flags(raw) == REF_UNCHECKED) {
rc = 1;
break;
}
}
spin_unlock(&c->erase_completion_lock);
return rc;
}
static void unload_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
{
/* must be called under down_write(xattr_sem) */
D1(dbg_xattr("%s: xid=%u, version=%u\n", __func__, xd->xid, xd->version));
if (xd->xname) {
c->xdatum_mem_usage -= (xd->name_len + 1 + xd->value_len);
kfree(xd->xname);
}
list_del_init(&xd->xindex);
xd->hashkey = 0;
xd->xname = NULL;
xd->xvalue = NULL;
}
static void reclaim_xattr_datum(struct jffs2_sb_info *c)
{
/* must be called under down_write(xattr_sem) */
struct jffs2_xattr_datum *xd, *_xd;
uint32_t target, before;
static int index = 0;
int count;
if (c->xdatum_mem_threshold > c->xdatum_mem_usage)
return;
before = c->xdatum_mem_usage;
target = c->xdatum_mem_usage * 4 / 5; /* 20% reduction */
for (count = 0; count < XATTRINDEX_HASHSIZE; count++) {
list_for_each_entry_safe(xd, _xd, &c->xattrindex[index], xindex) {
if (xd->flags & JFFS2_XFLAGS_HOT) {
xd->flags &= ~JFFS2_XFLAGS_HOT;
} else if (!(xd->flags & JFFS2_XFLAGS_BIND)) {
unload_xattr_datum(c, xd);
}
if (c->xdatum_mem_usage <= target)
goto out;
}
index = (index+1) % XATTRINDEX_HASHSIZE;
}
out:
JFFS2_NOTICE("xdatum_mem_usage from %u byte to %u byte (%u byte reclaimed)\n",
before, c->xdatum_mem_usage, before - c->xdatum_mem_usage);
}
static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
{
/* must be called under down_write(xattr_sem) */
struct jffs2_eraseblock *jeb;
struct jffs2_raw_node_ref *raw;
struct jffs2_raw_xattr rx;
size_t readlen;
uint32_t crc, offset, totlen;
int rc;
spin_lock(&c->erase_completion_lock);
offset = ref_offset(xd->node);
if (ref_flags(xd->node) == REF_PRISTINE)
goto complete;
spin_unlock(&c->erase_completion_lock);
rc = jffs2_flash_read(c, offset, sizeof(rx), &readlen, (char *)&rx);
if (rc || readlen != sizeof(rx)) {
JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n",
rc, sizeof(rx), readlen, offset);
return rc ? rc : -EIO;
}
crc = crc32(0, &rx, sizeof(rx) - 4);
if (crc != je32_to_cpu(rx.node_crc)) {
JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
offset, je32_to_cpu(rx.hdr_crc), crc);
xd->flags |= JFFS2_XFLAGS_INVALID;
return JFFS2_XATTR_IS_CORRUPTED;
}
totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len));
if (je16_to_cpu(rx.magic) != JFFS2_MAGIC_BITMASK
|| je16_to_cpu(rx.nodetype) != JFFS2_NODETYPE_XATTR
|| je32_to_cpu(rx.totlen) != totlen
|| je32_to_cpu(rx.xid) != xd->xid
|| je32_to_cpu(rx.version) != xd->version) {
JFFS2_ERROR("inconsistent xdatum at %#08x, magic=%#04x/%#04x, "
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/slab.h`, `linux/fs.h`, `linux/time.h`, `linux/pagemap.h`, `linux/highmem.h`, `linux/crc32.h`, `linux/jffs2.h`.
- Detected declarations: `function xattr_datum_hashkey`, `function is_xattr_datum_unchecked`, `function unload_xattr_datum`, `function reclaim_xattr_datum`, `function list_for_each_entry_safe`, `function do_verify_xattr_datum`, `function do_load_xattr_datum`, `function load_xattr_datum`, `function save_xattr_datum`, `function unrefer_xattr_datum`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.