示例#1
0
/*
 * Reads on sysfs are handled through seq_file, which takes care of hairy
 * details like buffering and seeking.  The following function pipes
 * sysfs_ops->show() result through seq_file.
 */
static int sysfs_seq_show(struct seq_file *sf, void *v)
{
	struct sysfs_open_file *of = sf->private;
	struct kobject *kobj = of->sd->s_parent->s_dir.kobj;
	const struct sysfs_ops *ops;
	char *buf;
	ssize_t count;

	/* acquire buffer and ensure that it's >= PAGE_SIZE */
	count = seq_get_buf(sf, &buf);
	if (count < PAGE_SIZE) {
		seq_commit(sf, -1);
		return 0;
	}

	/*
	 * Need @of->sd for attr and ops, its parent for kobj.  @of->mutex
	 * nests outside active ref and is just to ensure that the ops
	 * aren't called concurrently for the same open file.
	 */
	mutex_lock(&of->mutex);
	if (!sysfs_get_active(of->sd)) {
		mutex_unlock(&of->mutex);
		return -ENODEV;
	}

	of->event = atomic_read(&of->sd->s_attr.open->event);

	/*
	 * Lookup @ops and invoke show().  Control may reach here via seq
	 * file lseek even if @ops->show() isn't implemented.
	 */
	ops = sysfs_file_ops(of->sd);
	if (ops->show)
		count = ops->show(kobj, of->sd->s_attr.attr, buf);
	else
		count = 0;

	sysfs_put_active(of->sd);
	mutex_unlock(&of->mutex);

	if (count < 0)
		return count;

	/*
	 * The code works fine with PAGE_SIZE return but it's likely to
	 * indicate truncated result or overflow in normal use cases.
	 */
	if (count >= (ssize_t)PAGE_SIZE) {
		print_symbol("fill_read_buffer: %s returned bad count\n",
			(unsigned long)ops->show);
		/* Try to struggle along */
		count = PAGE_SIZE - 1;
	}
	seq_commit(sf, count);
	return 0;
}
示例#2
0
文件: file.c 项目: 383530895/linux
/*
 * Reads on sysfs are handled through seq_file, which takes care of hairy
 * details like buffering and seeking.  The following function pipes
 * sysfs_ops->show() result through seq_file.
 */
static int sysfs_kf_seq_show(struct seq_file *sf, void *v)
{
	struct kernfs_open_file *of = sf->private;
	struct kobject *kobj = of->kn->parent->priv;
	const struct sysfs_ops *ops = sysfs_file_ops(of->kn);
	ssize_t count;
	char *buf;

	/* acquire buffer and ensure that it's >= PAGE_SIZE and clear */
	count = seq_get_buf(sf, &buf);
	if (count < PAGE_SIZE) {
		seq_commit(sf, -1);
		return 0;
	}
	memset(buf, 0, PAGE_SIZE);

	/*
	 * Invoke show().  Control may reach here via seq file lseek even
	 * if @ops->show() isn't implemented.
	 */
	if (ops->show) {
		count = ops->show(kobj, of->kn->priv, buf);
		if (count < 0)
			return count;
	}

	/*
	 * The code works fine with PAGE_SIZE return but it's likely to
	 * indicate truncated result or overflow in normal use cases.
	 */
	if (count >= (ssize_t)PAGE_SIZE) {
		print_symbol("fill_read_buffer: %s returned bad count\n",
			(unsigned long)ops->show);
		/* Try to struggle along */
		count = PAGE_SIZE - 1;
	}
	seq_commit(sf, count);
	return 0;
}
示例#3
0
文件: array.c 项目: 020gzh/linux
static inline void task_name(struct seq_file *m, struct task_struct *p)
{
	char *buf;
	size_t size;
	char tcomm[sizeof(p->comm)];
	int ret;

	get_task_comm(tcomm, p);

	seq_puts(m, "Name:\t");

	size = seq_get_buf(m, &buf);
	ret = string_escape_str(tcomm, buf, size, ESCAPE_SPACE | ESCAPE_SPECIAL, "\n\\");
	seq_commit(m, ret < size ? ret : -1);

	seq_putc(m, '\n');
}
static int mali_seq_internal_state_show(struct seq_file *seq_file, void *v)
{
	u32 len = 0;
	u32 size;
	char *buf;

	size = seq_get_buf(seq_file, &buf);

	if (!size) {
		return -ENOMEM;
	}

	/* Create the internal state dump. */
	len  = snprintf(buf + len, size - len, "Mali device driver %s\n", SVN_REV_STRING);
	len += snprintf(buf + len, size - len, "License: %s\n\n", MALI_KERNEL_LINUX_LICENSE);

	len += _mali_kernel_core_dump_state(buf + len, size - len);

	seq_commit(seq_file, len);

	return 0;
}
示例#5
0
文件: array.c 项目: Lyude/linux
void proc_task_name(struct seq_file *m, struct task_struct *p, bool escape)
{
	char *buf;
	size_t size;
	char tcomm[64];
	int ret;

	if (p->flags & PF_WQ_WORKER)
		wq_worker_comm(tcomm, sizeof(tcomm), p);
	else
		__get_task_comm(tcomm, sizeof(tcomm), p);

	size = seq_get_buf(m, &buf);
	if (escape) {
		ret = string_escape_str(tcomm, buf, size,
					ESCAPE_SPACE | ESCAPE_SPECIAL, "\n\\");
		if (ret >= size)
			ret = -1;
	} else {
		ret = strscpy(buf, tcomm, size);
	}

	seq_commit(m, ret);
}