fs/jffs2/nodelist.c
Source file repositories/reference/linux-study-clean/fs/jffs2/nodelist.c
File Facts
- System
- Linux kernel
- Corpus path
fs/jffs2/nodelist.c- Extension
.c- Size
- 21763 bytes
- Lines
- 756
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/sched.hlinux/fs.hlinux/mtd/mtd.hlinux/rbtree.hlinux/crc32.hlinux/pagemap.hnodelist.h
Detected Declarations
function jffs2_add_fd_to_listfunction jffs2_truncate_fragtreefunction jffs2_obsolete_node_fragfunction jffs2_fragtree_insertfunction new_fragmentfunction no_overlapping_nodefunction jffs2_add_frag_to_fragtreefunction frag_nextfunction jffs2_add_full_dnode_to_inodefunction jffs2_set_inocache_statefunction jffs2_add_ino_cachefunction jffs2_del_ino_cachefunction jffs2_free_ino_cachesfunction jffs2_free_raw_node_refsfunction jffs2_kill_fragtreefunction jffs2_scan_dirty_spacefunction __ref_totlenfunction __jffs2_ref_totlen
Annotated Snippet
if ((*prev)->nhash == new->nhash && !strcmp((*prev)->name, new->name)) {
/* Duplicate. Free one */
if (new->version < (*prev)->version) {
dbg_dentlist("Eep! Marking new dirent node obsolete, old is \"%s\", ino #%u\n",
(*prev)->name, (*prev)->ino);
jffs2_mark_node_obsolete(c, new->raw);
jffs2_free_full_dirent(new);
} else {
dbg_dentlist("marking old dirent \"%s\", ino #%u obsolete\n",
(*prev)->name, (*prev)->ino);
new->next = (*prev)->next;
/* It may have been a 'placeholder' deletion dirent,
if jffs2_can_mark_obsolete() (see jffs2_do_unlink()) */
if ((*prev)->raw)
jffs2_mark_node_obsolete(c, ((*prev)->raw));
jffs2_free_full_dirent(*prev);
*prev = new;
}
return;
}
prev = &((*prev)->next);
}
new->next = *prev;
*prev = new;
}
uint32_t jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint32_t size)
{
struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size);
dbg_fragtree("truncating fragtree to 0x%08x bytes\n", size);
/* We know frag->ofs <= size. That's what lookup does for us */
if (frag && frag->ofs != size) {
if (frag->ofs+frag->size > size) {
frag->size = size - frag->ofs;
}
frag = frag_next(frag);
}
while (frag && frag->ofs >= size) {
struct jffs2_node_frag *next = frag_next(frag);
frag_erase(frag, list);
jffs2_obsolete_node_frag(c, frag);
frag = next;
}
if (size == 0)
return 0;
frag = frag_last(list);
/* Sanity check for truncation to longer than we started with... */
if (!frag)
return 0;
if (frag->ofs + frag->size < size)
return frag->ofs + frag->size;
/* If the last fragment starts at the RAM page boundary, it is
* REF_PRISTINE irrespective of its size. */
if (frag->node && (frag->ofs & (PAGE_SIZE - 1)) == 0) {
dbg_fragtree2("marking the last fragment 0x%08x-0x%08x REF_PRISTINE.\n",
frag->ofs, frag->ofs + frag->size);
frag->node->raw->flash_offset = ref_offset(frag->node->raw) | REF_PRISTINE;
}
return size;
}
static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c,
struct jffs2_node_frag *this)
{
if (this->node) {
this->node->frags--;
if (!this->node->frags) {
/* The node has no valid frags left. It's totally obsoleted */
dbg_fragtree2("marking old node @0x%08x (0x%04x-0x%04x) obsolete\n",
ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size);
jffs2_mark_node_obsolete(c, this->node->raw);
jffs2_free_full_dnode(this->node);
} else {
dbg_fragtree2("marking old node @0x%08x (0x%04x-0x%04x) REF_NORMAL. frags is %d\n",
ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size, this->node->frags);
mark_ref_normal(this->node->raw);
}
}
jffs2_free_node_frag(this);
}
static void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_node_frag *base)
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/sched.h`, `linux/fs.h`, `linux/mtd/mtd.h`, `linux/rbtree.h`, `linux/crc32.h`, `linux/pagemap.h`, `nodelist.h`.
- Detected declarations: `function jffs2_add_fd_to_list`, `function jffs2_truncate_fragtree`, `function jffs2_obsolete_node_frag`, `function jffs2_fragtree_insert`, `function new_fragment`, `function no_overlapping_node`, `function jffs2_add_frag_to_fragtree`, `function frag_next`, `function jffs2_add_full_dnode_to_inode`, `function jffs2_set_inocache_state`.
- 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.