fs/gfs2/dir.c
Source file repositories/reference/linux-study-clean/fs/gfs2/dir.c
File Facts
- System
- Linux kernel
- Corpus path
fs/gfs2/dir.c- Extension
.c- Size
- 53638 bytes
- Lines
- 2188
- 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/slab.hlinux/spinlock.hlinux/buffer_head.hlinux/sort.hlinux/gfs2_ondisk.hlinux/crc32.hlinux/vmalloc.hlinux/bio.hlinux/log2.hgfs2.hincore.hdir.hglock.hinode.hmeta_io.hquota.hrgrp.htrans.hbmap.hutil.h
Detected Declarations
struct dirent_gatherfunction gfs2_dir_get_new_bufferfunction gfs2_dir_get_existing_bufferfunction gfs2_dir_write_stuffedfunction gfs2_dir_write_datafunction gfs2_dir_read_stuffedfunction gfs2_dir_read_datafunction gfs2_dir_hash_invalfunction gfs2_dirent_sentinelfunction __gfs2_dirent_findfunction gfs2_dirent_findfunction gfs2_dirent_prevfunction gfs2_dirent_lastfunction gfs2_dirent_find_offsetfunction gfs2_dirent_find_spacefunction gfs2_dirent_gatherfunction gfs2_check_direntfunction gfs2_dirent_offsetfunction dirent_check_reclenfunction dirent_nextfunction dirent_delfunction get_leaffunction get_leaf_nrfunction get_first_leaffunction dir_make_exhashfunction dir_split_leaffunction dir_double_exhashfunction compare_dentsfunction do_filldir_mainfunction gfs2_set_cookiesfunction gfs2_dir_read_leaffunction gfs2_dir_readaheadfunction dir_e_readfunction gfs2_dir_readfunction gfs2_dir_checkfunction zerofunction gfs2_inode_ra_lenfunction gfs2_dir_addfunction gfs2_dir_delfunction gfs2_dir_mvinofunction leaf_deallocfunction gfs2_dir_exhash_deallocfunction gfs2_diradd_alloc_required
Annotated Snippet
struct dirent_gather {
const struct gfs2_dirent **pdent;
unsigned offset;
};
static int gfs2_dirent_gather(const struct gfs2_dirent *dent,
const struct qstr *name,
void *opaque)
{
struct dirent_gather *g = opaque;
if (!gfs2_dirent_sentinel(dent)) {
g->pdent[g->offset++] = dent;
}
return 0;
}
/*
* Other possible things to check:
* - Inode located within filesystem size (and on valid block)
* - Valid directory entry type
* Not sure how heavy-weight we want to make this... could also check
* hash is correct for example, but that would take a lot of extra time.
* For now the most important thing is to check that the various sizes
* are correct.
*/
static int gfs2_check_dirent(struct gfs2_sbd *sdp,
struct gfs2_dirent *dent, unsigned int offset,
unsigned int size, unsigned int len, int first)
{
const char *msg = "gfs2_dirent too small";
if (unlikely(size < sizeof(struct gfs2_dirent)))
goto error;
msg = "gfs2_dirent misaligned";
if (unlikely(offset & 0x7))
goto error;
msg = "gfs2_dirent points beyond end of block";
if (unlikely(offset + size > len))
goto error;
msg = "zero inode number";
if (unlikely(!first && gfs2_dirent_sentinel(dent)))
goto error;
msg = "name length is greater than space in dirent";
if (!gfs2_dirent_sentinel(dent) &&
unlikely(sizeof(struct gfs2_dirent)+be16_to_cpu(dent->de_name_len) >
size))
goto error;
return 0;
error:
fs_warn(sdp, "%s: %s (%s)\n",
__func__, msg, first ? "first in block" : "not first in block");
return -EIO;
}
static int gfs2_dirent_offset(struct gfs2_sbd *sdp, const void *buf)
{
const struct gfs2_meta_header *h = buf;
int offset;
BUG_ON(buf == NULL);
switch(be32_to_cpu(h->mh_type)) {
case GFS2_METATYPE_LF:
offset = sizeof(struct gfs2_leaf);
break;
case GFS2_METATYPE_DI:
offset = sizeof(struct gfs2_dinode);
break;
default:
goto wrong_type;
}
return offset;
wrong_type:
fs_warn(sdp, "%s: wrong block type %u\n", __func__,
be32_to_cpu(h->mh_type));
return -1;
}
static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf,
unsigned int len, gfs2_dscan_t scan,
const struct qstr *name,
void *opaque)
{
struct gfs2_dirent *dent, *prev;
unsigned offset;
unsigned size;
int ret = 0;
ret = gfs2_dirent_offset(GFS2_SB(inode), buf);
if (ret < 0) {
gfs2_consist_inode(GFS2_I(inode));
Annotation
- Immediate include surface: `linux/slab.h`, `linux/spinlock.h`, `linux/buffer_head.h`, `linux/sort.h`, `linux/gfs2_ondisk.h`, `linux/crc32.h`, `linux/vmalloc.h`, `linux/bio.h`.
- Detected declarations: `struct dirent_gather`, `function gfs2_dir_get_new_buffer`, `function gfs2_dir_get_existing_buffer`, `function gfs2_dir_write_stuffed`, `function gfs2_dir_write_data`, `function gfs2_dir_read_stuffed`, `function gfs2_dir_read_data`, `function gfs2_dir_hash_inval`, `function gfs2_dirent_sentinel`, `function __gfs2_dirent_find`.
- 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.