Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (C) 2008 Red Hat, Inc. All rights reserved.
0003  *
0004  * This file is released under the GPL.
0005  */
0006 
0007 #include <linux/sysfs.h>
0008 #include <linux/dm-ioctl.h>
0009 #include "dm-core.h"
0010 #include "dm-rq.h"
0011 
0012 struct dm_sysfs_attr {
0013     struct attribute attr;
0014     ssize_t (*show)(struct mapped_device *, char *);
0015     ssize_t (*store)(struct mapped_device *, const char *, size_t count);
0016 };
0017 
0018 #define DM_ATTR_RO(_name) \
0019 struct dm_sysfs_attr dm_attr_##_name = \
0020     __ATTR(_name, S_IRUGO, dm_attr_##_name##_show, NULL)
0021 
0022 static ssize_t dm_attr_show(struct kobject *kobj, struct attribute *attr,
0023                 char *page)
0024 {
0025     struct dm_sysfs_attr *dm_attr;
0026     struct mapped_device *md;
0027     ssize_t ret;
0028 
0029     dm_attr = container_of(attr, struct dm_sysfs_attr, attr);
0030     if (!dm_attr->show)
0031         return -EIO;
0032 
0033     md = dm_get_from_kobject(kobj);
0034     if (!md)
0035         return -EINVAL;
0036 
0037     ret = dm_attr->show(md, page);
0038     dm_put(md);
0039 
0040     return ret;
0041 }
0042 
0043 #define DM_ATTR_RW(_name) \
0044 struct dm_sysfs_attr dm_attr_##_name = \
0045     __ATTR(_name, S_IRUGO | S_IWUSR, dm_attr_##_name##_show, dm_attr_##_name##_store)
0046 
0047 static ssize_t dm_attr_store(struct kobject *kobj, struct attribute *attr,
0048                  const char *page, size_t count)
0049 {
0050     struct dm_sysfs_attr *dm_attr;
0051     struct mapped_device *md;
0052     ssize_t ret;
0053 
0054     dm_attr = container_of(attr, struct dm_sysfs_attr, attr);
0055     if (!dm_attr->store)
0056         return -EIO;
0057 
0058     md = dm_get_from_kobject(kobj);
0059     if (!md)
0060         return -EINVAL;
0061 
0062     ret = dm_attr->store(md, page, count);
0063     dm_put(md);
0064 
0065     return ret;
0066 }
0067 
0068 static ssize_t dm_attr_name_show(struct mapped_device *md, char *buf)
0069 {
0070     if (dm_copy_name_and_uuid(md, buf, NULL))
0071         return -EIO;
0072 
0073     strcat(buf, "\n");
0074     return strlen(buf);
0075 }
0076 
0077 static ssize_t dm_attr_uuid_show(struct mapped_device *md, char *buf)
0078 {
0079     if (dm_copy_name_and_uuid(md, NULL, buf))
0080         return -EIO;
0081 
0082     strcat(buf, "\n");
0083     return strlen(buf);
0084 }
0085 
0086 static ssize_t dm_attr_suspended_show(struct mapped_device *md, char *buf)
0087 {
0088     sprintf(buf, "%d\n", dm_suspended_md(md));
0089 
0090     return strlen(buf);
0091 }
0092 
0093 static ssize_t dm_attr_use_blk_mq_show(struct mapped_device *md, char *buf)
0094 {
0095     /* Purely for userspace compatibility */
0096     sprintf(buf, "%d\n", true);
0097 
0098     return strlen(buf);
0099 }
0100 
0101 static DM_ATTR_RO(name);
0102 static DM_ATTR_RO(uuid);
0103 static DM_ATTR_RO(suspended);
0104 static DM_ATTR_RO(use_blk_mq);
0105 static DM_ATTR_RW(rq_based_seq_io_merge_deadline);
0106 
0107 static struct attribute *dm_attrs[] = {
0108     &dm_attr_name.attr,
0109     &dm_attr_uuid.attr,
0110     &dm_attr_suspended.attr,
0111     &dm_attr_use_blk_mq.attr,
0112     &dm_attr_rq_based_seq_io_merge_deadline.attr,
0113     NULL,
0114 };
0115 ATTRIBUTE_GROUPS(dm);
0116 
0117 static const struct sysfs_ops dm_sysfs_ops = {
0118     .show   = dm_attr_show,
0119     .store  = dm_attr_store,
0120 };
0121 
0122 static struct kobj_type dm_ktype = {
0123     .sysfs_ops  = &dm_sysfs_ops,
0124     .default_groups = dm_groups,
0125     .release    = dm_kobject_release,
0126 };
0127 
0128 /*
0129  * Initialize kobj
0130  * because nobody using md yet, no need to call explicit dm_get/put
0131  */
0132 int dm_sysfs_init(struct mapped_device *md)
0133 {
0134     return kobject_init_and_add(dm_kobject(md), &dm_ktype,
0135                     &disk_to_dev(dm_disk(md))->kobj,
0136                     "%s", "dm");
0137 }
0138 
0139 /*
0140  * Remove kobj, called after all references removed
0141  */
0142 void dm_sysfs_exit(struct mapped_device *md)
0143 {
0144     struct kobject *kobj = dm_kobject(md);
0145     kobject_put(kobj);
0146     wait_for_completion(dm_get_completion_from_kobject(kobj));
0147 }