fs/coda/inode.c

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

File Facts

System
Linux kernel
Corpus path
fs/coda/inode.c
Extension
.c
Size
8876 bytes
Lines
403
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct coda_fs_context {
	int	idx;
};

enum {
	Opt_fd,
};

static const struct fs_parameter_spec coda_param_specs[] = {
	fsparam_fd	("fd",	Opt_fd),
	{}
};

static int coda_set_idx(struct fs_context *fc, struct file *file)
{
	struct coda_fs_context *ctx = fc->fs_private;
	struct inode *inode;
	int idx;

	inode = file_inode(file);
	if (!S_ISCHR(inode->i_mode) || imajor(inode) != CODA_PSDEV_MAJOR) {
		return invalf(fc, "coda: Not coda psdev");
	}
	idx = iminor(inode);
	if (idx < 0 || idx >= MAX_CODADEVS)
		return invalf(fc, "coda: Bad minor number");
	ctx->idx = idx;
	return 0;
}

static int coda_parse_fd(struct fs_context *fc, struct fs_parameter *param,
			 struct fs_parse_result *result)
{
	struct file *file;
	int err;

	if (param->type == fs_value_is_file) {
		file = param->file;
		param->file = NULL;
	} else {
		file = fget(result->uint_32);
	}
	if (!file)
		return -EBADF;

	err = coda_set_idx(fc, file);
	fput(file);
	return err;
}

static int coda_parse_param(struct fs_context *fc, struct fs_parameter *param)
{
	struct fs_parse_result result;
	int opt;

	opt = fs_parse(fc, coda_param_specs, param, &result);
	if (opt < 0)
		return opt;

	switch (opt) {
	case Opt_fd:
		return coda_parse_fd(fc, param, &result);
	}

	return 0;
}

/*
 * Parse coda's binary mount data form.  We ignore any errors and go with index
 * 0 if we get one for backward compatibility.
 */
static int coda_parse_monolithic(struct fs_context *fc, void *_data)
{
	struct file *file;
	struct coda_mount_data *data = _data;

	if (!data)
		return invalf(fc, "coda: Bad mount data");

	if (data->version != CODA_MOUNT_VERSION)
		return invalf(fc, "coda: Bad mount version");

	file = fget(data->fd);
	if (file) {
		coda_set_idx(fc, file);
		fput(file);
	}
	return 0;
}

Annotation

Implementation Notes