fs/libfs.c

Source file repositories/reference/linux-study-clean/fs/libfs.c

File Facts

System
Linux kernel
Corpus path
fs/libfs.c
Extension
.c
Size
62674 bytes
Lines
2315
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

const struct file_operations simple_dir_operations = {
	.open		= dcache_dir_open,
	.release	= dcache_dir_close,
	.llseek		= dcache_dir_lseek,
	.read		= generic_read_dir,
	.iterate_shared	= dcache_readdir,
	.fsync		= noop_fsync,
};
EXPORT_SYMBOL(simple_dir_operations);

const struct inode_operations simple_dir_inode_operations = {
	.lookup		= simple_lookup,
};
EXPORT_SYMBOL(simple_dir_inode_operations);

/* simple_offset_add() never assigns these to a dentry */
enum {
	DIR_OFFSET_FIRST	= 2,		/* Find first real entry */
	DIR_OFFSET_EOD		= S32_MAX,
};

/* simple_offset_add() allocation range */
enum {
	DIR_OFFSET_MIN		= DIR_OFFSET_FIRST + 1,
	DIR_OFFSET_MAX		= DIR_OFFSET_EOD - 1,
};

static void offset_set(struct dentry *dentry, long offset)
{
	dentry->d_fsdata = (void *)offset;
}

static long dentry2offset(struct dentry *dentry)
{
	return (long)dentry->d_fsdata;
}

static struct lock_class_key simple_offset_lock_class;

/**
 * simple_offset_init - initialize an offset_ctx
 * @octx: directory offset map to be initialized
 *
 */
void simple_offset_init(struct offset_ctx *octx)
{
	mt_init_flags(&octx->mt, MT_FLAGS_ALLOC_RANGE);
	lockdep_set_class(&octx->mt.ma_lock, &simple_offset_lock_class);
	octx->next_offset = DIR_OFFSET_MIN;
}

/**
 * simple_offset_add - Add an entry to a directory's offset map
 * @octx: directory offset ctx to be updated
 * @dentry: new dentry being added
 *
 * Returns zero on success. @octx and the dentry's offset are updated.
 * Otherwise, a negative errno value is returned.
 */
int simple_offset_add(struct offset_ctx *octx, struct dentry *dentry)
{
	unsigned long offset;
	int ret;

	if (dentry2offset(dentry) != 0)
		return -EBUSY;

	ret = mtree_alloc_cyclic(&octx->mt, &offset, dentry, DIR_OFFSET_MIN,
				 DIR_OFFSET_MAX, &octx->next_offset,
				 GFP_KERNEL);
	if (unlikely(ret < 0))
		return ret == -EBUSY ? -ENOSPC : ret;

	offset_set(dentry, offset);
	return 0;
}

static int simple_offset_replace(struct offset_ctx *octx, struct dentry *dentry,
				 long offset)
{
	int ret;

	ret = mtree_store(&octx->mt, offset, dentry, GFP_KERNEL);
	if (ret)
		return ret;
	offset_set(dentry, offset);
	return 0;
}

/**

Annotation

Implementation Notes