示例#1
0
/**
 * flush_write_buffer - push buffer to kobject
 * @of: open file
 * @buf: data buffer for file
 * @off: file offset to write to
 * @count: number of bytes
 *
 * Get the correct pointers for the kobject and the attribute we're dealing
 * with, then call the store() method for it with @buf.
 */
static int flush_write_buffer(struct sysfs_open_file *of, char *buf, loff_t off,
			      size_t count)
{
	struct kobject *kobj = of->sd->s_parent->s_dir.kobj;
	int rc = 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;
	}

	if (sysfs_is_bin(of->sd)) {
		struct bin_attribute *battr = of->sd->s_attr.bin_attr;

		rc = -EIO;
		if (battr->write)
			rc = battr->write(of->file, kobj, battr, buf, off,
					  count);
	} else {
		const struct sysfs_ops *ops = sysfs_file_ops(of->sd);

		rc = ops->store(kobj, of->sd->s_attr.attr, buf, count);
	}

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

	return rc;
}
示例#2
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;
}
示例#3
0
文件: file.c 项目: 383530895/linux
/* kernfs write callback for regular sysfs files */
static ssize_t sysfs_kf_write(struct kernfs_open_file *of, char *buf,
			      size_t count, loff_t pos)
{
	const struct sysfs_ops *ops = sysfs_file_ops(of->kn);
	struct kobject *kobj = of->kn->parent->priv;

	if (!count)
		return 0;

	return ops->store(kobj, of->kn->priv, buf, count);
}
示例#4
0
文件: file.c 项目: 383530895/linux
/* kernfs read callback for regular sysfs files with pre-alloc */
static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf,
			     size_t count, loff_t pos)
{
	const struct sysfs_ops *ops = sysfs_file_ops(of->kn);
	struct kobject *kobj = of->kn->parent->priv;

	/*
	 * If buf != of->prealloc_buf, we don't know how
	 * large it is, so cannot safely pass it to ->show
	 */
	if (pos || WARN_ON_ONCE(buf != of->prealloc_buf))
		return 0;
	return ops->show(kobj, of->kn->priv, buf);
}
示例#5
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;
}