cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dm-sysfs.c (3228B)


      1/*
      2 * Copyright (C) 2008 Red Hat, Inc. All rights reserved.
      3 *
      4 * This file is released under the GPL.
      5 */
      6
      7#include <linux/sysfs.h>
      8#include <linux/dm-ioctl.h>
      9#include "dm-core.h"
     10#include "dm-rq.h"
     11
     12struct dm_sysfs_attr {
     13	struct attribute attr;
     14	ssize_t (*show)(struct mapped_device *, char *);
     15	ssize_t (*store)(struct mapped_device *, const char *, size_t count);
     16};
     17
     18#define DM_ATTR_RO(_name) \
     19struct dm_sysfs_attr dm_attr_##_name = \
     20	__ATTR(_name, S_IRUGO, dm_attr_##_name##_show, NULL)
     21
     22static ssize_t dm_attr_show(struct kobject *kobj, struct attribute *attr,
     23			    char *page)
     24{
     25	struct dm_sysfs_attr *dm_attr;
     26	struct mapped_device *md;
     27	ssize_t ret;
     28
     29	dm_attr = container_of(attr, struct dm_sysfs_attr, attr);
     30	if (!dm_attr->show)
     31		return -EIO;
     32
     33	md = dm_get_from_kobject(kobj);
     34	if (!md)
     35		return -EINVAL;
     36
     37	ret = dm_attr->show(md, page);
     38	dm_put(md);
     39
     40	return ret;
     41}
     42
     43#define DM_ATTR_RW(_name) \
     44struct dm_sysfs_attr dm_attr_##_name = \
     45	__ATTR(_name, S_IRUGO | S_IWUSR, dm_attr_##_name##_show, dm_attr_##_name##_store)
     46
     47static ssize_t dm_attr_store(struct kobject *kobj, struct attribute *attr,
     48			     const char *page, size_t count)
     49{
     50	struct dm_sysfs_attr *dm_attr;
     51	struct mapped_device *md;
     52	ssize_t ret;
     53
     54	dm_attr = container_of(attr, struct dm_sysfs_attr, attr);
     55	if (!dm_attr->store)
     56		return -EIO;
     57
     58	md = dm_get_from_kobject(kobj);
     59	if (!md)
     60		return -EINVAL;
     61
     62	ret = dm_attr->store(md, page, count);
     63	dm_put(md);
     64
     65	return ret;
     66}
     67
     68static ssize_t dm_attr_name_show(struct mapped_device *md, char *buf)
     69{
     70	if (dm_copy_name_and_uuid(md, buf, NULL))
     71		return -EIO;
     72
     73	strcat(buf, "\n");
     74	return strlen(buf);
     75}
     76
     77static ssize_t dm_attr_uuid_show(struct mapped_device *md, char *buf)
     78{
     79	if (dm_copy_name_and_uuid(md, NULL, buf))
     80		return -EIO;
     81
     82	strcat(buf, "\n");
     83	return strlen(buf);
     84}
     85
     86static ssize_t dm_attr_suspended_show(struct mapped_device *md, char *buf)
     87{
     88	sprintf(buf, "%d\n", dm_suspended_md(md));
     89
     90	return strlen(buf);
     91}
     92
     93static ssize_t dm_attr_use_blk_mq_show(struct mapped_device *md, char *buf)
     94{
     95	/* Purely for userspace compatibility */
     96	sprintf(buf, "%d\n", true);
     97
     98	return strlen(buf);
     99}
    100
    101static DM_ATTR_RO(name);
    102static DM_ATTR_RO(uuid);
    103static DM_ATTR_RO(suspended);
    104static DM_ATTR_RO(use_blk_mq);
    105static DM_ATTR_RW(rq_based_seq_io_merge_deadline);
    106
    107static struct attribute *dm_attrs[] = {
    108	&dm_attr_name.attr,
    109	&dm_attr_uuid.attr,
    110	&dm_attr_suspended.attr,
    111	&dm_attr_use_blk_mq.attr,
    112	&dm_attr_rq_based_seq_io_merge_deadline.attr,
    113	NULL,
    114};
    115ATTRIBUTE_GROUPS(dm);
    116
    117static const struct sysfs_ops dm_sysfs_ops = {
    118	.show	= dm_attr_show,
    119	.store	= dm_attr_store,
    120};
    121
    122static struct kobj_type dm_ktype = {
    123	.sysfs_ops	= &dm_sysfs_ops,
    124	.default_groups	= dm_groups,
    125	.release	= dm_kobject_release,
    126};
    127
    128/*
    129 * Initialize kobj
    130 * because nobody using md yet, no need to call explicit dm_get/put
    131 */
    132int dm_sysfs_init(struct mapped_device *md)
    133{
    134	return kobject_init_and_add(dm_kobject(md), &dm_ktype,
    135				    &disk_to_dev(dm_disk(md))->kobj,
    136				    "%s", "dm");
    137}
    138
    139/*
    140 * Remove kobj, called after all references removed
    141 */
    142void dm_sysfs_exit(struct mapped_device *md)
    143{
    144	struct kobject *kobj = dm_kobject(md);
    145	kobject_put(kobj);
    146	wait_for_completion(dm_get_completion_from_kobject(kobj));
    147}