Commit 784aae735d9b0bba3f8b9faef4c8b30df3bf0128

Authored by Milan Broz
Committed by Alasdair G Kergon
1 parent d58168763f

dm: add name and uuid to sysfs

Implement simple read-only sysfs entry for device-mapper block device.

This patch adds a simple sysfs directory named "dm" under block device
properties and implements
	- name attribute (string containing mapped device name)
	- uuid attribute (string containing UUID, or empty string if not set)

The kobject is embedded in mapped_device struct, so no additional
memory allocation is needed for initializing sysfs entry.

During the processing of sysfs attribute we need to lock mapped device
which is done by a new function dm_get_from_kobj, which returns the md
associated with kobject and increases the usage count.

Each 'show attribute' function is responsible for its own locking.

Signed-off-by: Milan Broz <mbroz@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>

Showing 4 changed files with 136 additions and 2 deletions Side-by-side Diff

... ... @@ -3,7 +3,7 @@
3 3 #
4 4  
5 5 dm-mod-objs := dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
6   - dm-ioctl.o dm-io.o dm-kcopyd.o
  6 + dm-ioctl.o dm-io.o dm-kcopyd.o dm-sysfs.o
7 7 dm-multipath-objs := dm-path-selector.o dm-mpath.o
8 8 dm-snapshot-objs := dm-snap.o dm-exception-store.o
9 9 dm-mirror-objs := dm-raid1.o
drivers/md/dm-sysfs.c
  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.h"
  10 +
  11 +struct dm_sysfs_attr {
  12 + struct attribute attr;
  13 + ssize_t (*show)(struct mapped_device *, char *);
  14 + ssize_t (*store)(struct mapped_device *, char *);
  15 +};
  16 +
  17 +#define DM_ATTR_RO(_name) \
  18 +struct dm_sysfs_attr dm_attr_##_name = \
  19 + __ATTR(_name, S_IRUGO, dm_attr_##_name##_show, NULL)
  20 +
  21 +static ssize_t dm_attr_show(struct kobject *kobj, struct attribute *attr,
  22 + char *page)
  23 +{
  24 + struct dm_sysfs_attr *dm_attr;
  25 + struct mapped_device *md;
  26 + ssize_t ret;
  27 +
  28 + dm_attr = container_of(attr, struct dm_sysfs_attr, attr);
  29 + if (!dm_attr->show)
  30 + return -EIO;
  31 +
  32 + md = dm_get_from_kobject(kobj);
  33 + if (!md)
  34 + return -EINVAL;
  35 +
  36 + ret = dm_attr->show(md, page);
  37 + dm_put(md);
  38 +
  39 + return ret;
  40 +}
  41 +
  42 +static ssize_t dm_attr_name_show(struct mapped_device *md, char *buf)
  43 +{
  44 + if (dm_copy_name_and_uuid(md, buf, NULL))
  45 + return -EIO;
  46 +
  47 + strcat(buf, "\n");
  48 + return strlen(buf);
  49 +}
  50 +
  51 +static ssize_t dm_attr_uuid_show(struct mapped_device *md, char *buf)
  52 +{
  53 + if (dm_copy_name_and_uuid(md, NULL, buf))
  54 + return -EIO;
  55 +
  56 + strcat(buf, "\n");
  57 + return strlen(buf);
  58 +}
  59 +
  60 +static DM_ATTR_RO(name);
  61 +static DM_ATTR_RO(uuid);
  62 +
  63 +static struct attribute *dm_attrs[] = {
  64 + &dm_attr_name.attr,
  65 + &dm_attr_uuid.attr,
  66 + NULL,
  67 +};
  68 +
  69 +static struct sysfs_ops dm_sysfs_ops = {
  70 + .show = dm_attr_show,
  71 +};
  72 +
  73 +/*
  74 + * dm kobject is embedded in mapped_device structure
  75 + * no need to define release function here
  76 + */
  77 +static struct kobj_type dm_ktype = {
  78 + .sysfs_ops = &dm_sysfs_ops,
  79 + .default_attrs = dm_attrs,
  80 +};
  81 +
  82 +/*
  83 + * Initialize kobj
  84 + * because nobody using md yet, no need to call explicit dm_get/put
  85 + */
  86 +int dm_sysfs_init(struct mapped_device *md)
  87 +{
  88 + return kobject_init_and_add(dm_kobject(md), &dm_ktype,
  89 + &disk_to_dev(dm_disk(md))->kobj,
  90 + "%s", "dm");
  91 +}
  92 +
  93 +/*
  94 + * Remove kobj, called after all references removed
  95 + */
  96 +void dm_sysfs_exit(struct mapped_device *md)
  97 +{
  98 + kobject_put(dm_kobject(md));
  99 +}
1 1 /*
2 2 * Copyright (C) 2001, 2002 Sistina Software (UK) Limited.
3   - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
  3 + * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
4 4 *
5 5 * This file is released under the GPL.
6 6 */
... ... @@ -167,6 +167,9 @@
167 167  
168 168 /* forced geometry settings */
169 169 struct hd_geometry geometry;
  170 +
  171 + /* sysfs handle */
  172 + struct kobject kobj;
170 173 };
171 174  
172 175 #define MIN_IOS 256
... ... @@ -1285,6 +1288,8 @@
1285 1288 if (!md)
1286 1289 return -ENXIO;
1287 1290  
  1291 + dm_sysfs_init(md);
  1292 +
1288 1293 *result = md;
1289 1294 return 0;
1290 1295 }
... ... @@ -1360,6 +1365,7 @@
1360 1365 dm_table_presuspend_targets(map);
1361 1366 dm_table_postsuspend_targets(map);
1362 1367 }
  1368 + dm_sysfs_exit(md);
1363 1369 dm_table_put(map);
1364 1370 __unbind(md);
1365 1371 free_dev(md);
... ... @@ -1697,6 +1703,27 @@
1697 1703 struct gendisk *dm_disk(struct mapped_device *md)
1698 1704 {
1699 1705 return md->disk;
  1706 +}
  1707 +
  1708 +struct kobject *dm_kobject(struct mapped_device *md)
  1709 +{
  1710 + return &md->kobj;
  1711 +}
  1712 +
  1713 +/*
  1714 + * struct mapped_device should not be exported outside of dm.c
  1715 + * so use this check to verify that kobj is part of md structure
  1716 + */
  1717 +struct mapped_device *dm_get_from_kobject(struct kobject *kobj)
  1718 +{
  1719 + struct mapped_device *md;
  1720 +
  1721 + md = container_of(kobj, struct mapped_device, kobj);
  1722 + if (&md->kobj != kobj)
  1723 + return NULL;
  1724 +
  1725 + dm_get(md);
  1726 + return md;
1700 1727 }
1701 1728  
1702 1729 int dm_suspended(struct mapped_device *md)
... ... @@ -74,6 +74,14 @@
74 74 void dm_interface_exit(void);
75 75  
76 76 /*
  77 + * sysfs interface
  78 + */
  79 +int dm_sysfs_init(struct mapped_device *md);
  80 +void dm_sysfs_exit(struct mapped_device *md);
  81 +struct kobject *dm_kobject(struct mapped_device *md);
  82 +struct mapped_device *dm_get_from_kobject(struct kobject *kobj);
  83 +
  84 +/*
77 85 * Targets for linear and striped mappings
78 86 */
79 87 int dm_linear_init(void);