fs/bfs/dir.c

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

File Facts

System
Linux kernel
Corpus path
fs/bfs/dir.c
Extension
.c
Size
8935 bytes
Lines
364
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 bfs_dir_operations = {
	.read		= generic_read_dir,
	.iterate_shared	= bfs_readdir,
	.fsync		= bfs_fsync,
	.llseek		= generic_file_llseek,
};

static int bfs_create(struct mnt_idmap *idmap, struct inode *dir,
		      struct dentry *dentry, umode_t mode, bool excl)
{
	int err;
	struct inode *inode;
	struct super_block *s = dir->i_sb;
	struct bfs_sb_info *info = BFS_SB(s);
	unsigned long ino;

	inode = new_inode(s);
	if (!inode)
		return -ENOMEM;
	mutex_lock(&info->bfs_lock);
	ino = find_first_zero_bit(info->si_imap, info->si_lasti + 1);
	if (ino > info->si_lasti) {
		mutex_unlock(&info->bfs_lock);
		iput(inode);
		return -ENOSPC;
	}
	set_bit(ino, info->si_imap);
	info->si_freei--;
	inode_init_owner(&nop_mnt_idmap, inode, dir, mode);
	simple_inode_init_ts(inode);
	inode->i_blocks = 0;
	inode->i_op = &bfs_file_inops;
	inode->i_fop = &bfs_file_operations;
	inode->i_mapping->a_ops = &bfs_aops;
	inode->i_ino = ino;
	BFS_I(inode)->i_dsk_ino = ino;
	BFS_I(inode)->i_sblock = 0;
	BFS_I(inode)->i_eblock = 0;
	insert_inode_hash(inode);
        mark_inode_dirty(inode);
	bfs_dump_imap("create", s);

	err = bfs_add_entry(dir, &dentry->d_name, inode->i_ino);
	if (err) {
		inode_dec_link_count(inode);
		mutex_unlock(&info->bfs_lock);
		iput(inode);
		return err;
	}
	mutex_unlock(&info->bfs_lock);
	d_instantiate(dentry, inode);
	return 0;
}

static struct dentry *bfs_lookup(struct inode *dir, struct dentry *dentry,
						unsigned int flags)
{
	struct inode *inode = NULL;
	struct buffer_head *bh;
	struct bfs_dirent *de;
	struct bfs_sb_info *info = BFS_SB(dir->i_sb);

	if (dentry->d_name.len > BFS_NAMELEN)
		return ERR_PTR(-ENAMETOOLONG);

	mutex_lock(&info->bfs_lock);
	bh = bfs_find_entry(dir, &dentry->d_name, &de);
	if (bh) {
		unsigned long ino = (unsigned long)le16_to_cpu(de->ino);
		brelse(bh);
		inode = bfs_iget(dir->i_sb, ino);
	}
	mutex_unlock(&info->bfs_lock);
	return d_splice_alias(inode, dentry);
}

static int bfs_link(struct dentry *old, struct inode *dir,
						struct dentry *new)
{
	struct inode *inode = d_inode(old);
	struct bfs_sb_info *info = BFS_SB(inode->i_sb);
	int err;

	mutex_lock(&info->bfs_lock);
	err = bfs_add_entry(dir, &new->d_name, inode->i_ino);
	if (err) {
		mutex_unlock(&info->bfs_lock);
		return err;
	}
	inc_nlink(inode);

Annotation

Implementation Notes