fs/jffs2/readinode.c
Source file repositories/reference/linux-study-clean/fs/jffs2/readinode.c
File Facts
- System
- Linux kernel
- Corpus path
fs/jffs2/readinode.c- Extension
.c- Size
- 44273 bytes
- Lines
- 1448
- 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/sched.hlinux/slab.hlinux/fs.hlinux/crc32.hlinux/pagemap.hlinux/mtd/mtd.hlinux/compiler.hnodelist.h
Detected Declarations
function check_node_datafunction jffs2_add_older_frag_to_fragtreefunction jffs2_kill_tnfunction handledfunction childfunction treefunction jffs2_build_inode_fragtreefunction jffs2_free_tmp_dnode_info_listfunction rbtree_postorder_for_each_entry_safefunction jffs2_free_full_dirent_listfunction read_direntryfunction read_dnodefunction read_unknownfunction read_morefunction jffs2_get_inode_nodesfunction jffs2_do_read_inode_internalfunction jffs2_do_read_inodefunction jffs2_do_crccheck_inodefunction jffs2_do_clear_inode
Annotated Snippet
if (adj >= tn->csize) {
dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n",
ref_offset(ref), tn->csize, ofs);
goto adj_acc;
}
ofs += adj;
len -= adj;
}
dbg_readinode("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes.\n",
ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len);
#ifndef __ECOS
/* TODO: instead, incapsulate point() stuff to jffs2_flash_read(),
* adding and jffs2_flash_read_end() interface. */
err = mtd_point(c->mtd, ofs, len, &retlen, (void **)&buffer, NULL);
if (!err && retlen < len) {
JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize);
mtd_unpoint(c->mtd, ofs, retlen);
} else if (err) {
if (err != -EOPNOTSUPP)
JFFS2_WARNING("MTD point failed: error code %d.\n", err);
} else
pointed = 1; /* successfully pointed to device */
#endif
if (!pointed) {
buffer = kmalloc(len, GFP_KERNEL);
if (unlikely(!buffer))
return -ENOMEM;
/* TODO: this is very frequent pattern, make it a separate
* routine */
err = jffs2_flash_read(c, ofs, len, &retlen, buffer);
if (err) {
JFFS2_ERROR("can not read %d bytes from 0x%08x, error code: %d.\n", len, ofs, err);
goto free_out;
}
if (retlen != len) {
JFFS2_ERROR("short read at %#08x: %zd instead of %d.\n", ofs, retlen, len);
err = -EIO;
goto free_out;
}
}
/* Continue calculating CRC */
crc = crc32(tn->partial_crc, buffer, len);
if(!pointed)
kfree(buffer);
#ifndef __ECOS
else
mtd_unpoint(c->mtd, ofs, len);
#endif
if (crc != tn->data_crc) {
JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n",
ref_offset(ref), tn->data_crc, crc);
return 1;
}
adj_acc:
jeb = &c->blocks[ref->flash_offset / c->sector_size];
len = ref_totlen(c, jeb, ref);
/* If it should be REF_NORMAL, it'll get marked as such when
we build the fragtree, shortly. No need to worry about GC
moving it while it's marked REF_PRISTINE -- GC won't happen
till we've finished checking every inode anyway. */
ref->flash_offset |= REF_PRISTINE;
/*
* Mark the node as having been checked and fix the
* accounting accordingly.
*/
spin_lock(&c->erase_completion_lock);
jeb->used_size += len;
jeb->unchecked_size -= len;
c->used_size += len;
c->unchecked_size -= len;
jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
spin_unlock(&c->erase_completion_lock);
return 0;
free_out:
if(!pointed)
kfree(buffer);
#ifndef __ECOS
else
mtd_unpoint(c->mtd, ofs, len);
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/sched.h`, `linux/slab.h`, `linux/fs.h`, `linux/crc32.h`, `linux/pagemap.h`, `linux/mtd/mtd.h`, `linux/compiler.h`.
- Detected declarations: `function check_node_data`, `function jffs2_add_older_frag_to_fragtree`, `function jffs2_kill_tn`, `function handled`, `function child`, `function tree`, `function jffs2_build_inode_fragtree`, `function jffs2_free_tmp_dnode_info_list`, `function rbtree_postorder_for_each_entry_safe`, `function jffs2_free_full_dirent_list`.
- 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.