arch/powerpc/platforms/cell/spufs/inode.c

Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/cell/spufs/inode.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/platforms/cell/spufs/inode.c
Extension
.c
Size
17801 bytes
Lines
816
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

const struct file_operations *fops, umode_t mode,
		size_t size, struct spu_context *ctx)
{
	static const struct inode_operations spufs_file_iops = {
		.setattr = spufs_setattr,
	};
	struct inode *inode;
	int ret;

	ret = -ENOSPC;
	inode = spufs_new_inode(sb, S_IFREG | mode);
	if (!inode)
		goto out;

	ret = 0;
	inode->i_op = &spufs_file_iops;
	inode->i_fop = fops;
	inode->i_size = size;
	inode->i_private = SPUFS_I(inode)->i_ctx = get_spu_context(ctx);
	d_make_persistent(dentry, inode);
out:
	return ret;
}

static void
spufs_evict_inode(struct inode *inode)
{
	struct spufs_inode_info *ei = SPUFS_I(inode);
	clear_inode(inode);
	if (ei->i_ctx)
		put_spu_context(ei->i_ctx);
	if (ei->i_gang)
		put_spu_gang(ei->i_gang);
}

/* Caller must hold parent->i_mutex */
static void spufs_rmdir(struct inode *parent, struct dentry *dir)
{
	struct spu_context *ctx = SPUFS_I(d_inode(dir))->i_ctx;

	locked_recursive_removal(dir, NULL);
	spu_forget(ctx);
}

static int spufs_fill_dir(struct dentry *dir,
		const struct spufs_tree_descr *files, umode_t mode,
		struct spu_context *ctx)
{
	while (files->name && files->name[0]) {
		int ret;
		struct dentry *dentry = d_alloc_name(dir, files->name);
		if (!dentry)
			return -ENOMEM;
		ret = spufs_new_file(dir->d_sb, dentry, files->ops,
					files->mode & mode, files->size, ctx);
		dput(dentry);
		if (ret)
			return ret;
		files++;
	}
	return 0;
}

static void unuse_gang(struct dentry *dir)
{
	struct inode *inode = dir->d_inode;
	struct spu_gang *gang = SPUFS_I(inode)->i_gang;

	if (gang) {
		bool dead;

		inode_lock(inode); // exclusion with spufs_create_context()
		dead = !--gang->alive;
		inode_unlock(inode);

		if (dead)
			simple_recursive_removal(dir, NULL);
	}
}

static int spufs_dir_close(struct inode *inode, struct file *file)
{
	struct inode *parent;
	struct dentry *dir;

	dir = file->f_path.dentry;
	parent = d_inode(dir->d_parent);

	inode_lock_nested(parent, I_MUTEX_PARENT);
	spufs_rmdir(parent, dir);

Annotation

Implementation Notes