From: "Jun'ichi Nomura" <j-nomura@ce.jp.nec.com>
To: Neil Brown <neilb@suse.de>, Alasdair Kergon <agk@redhat.com>,
Lars Marowsky-Bree <lmb@suse.de>, Greg KH <gregkh@suse.de>
Cc: device-mapper development <dm-devel@redhat.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH 1/3] sysfs representation of stacked devices (common) (rev.2)
Date: Wed, 22 Feb 2006 11:13:00 -0500 [thread overview]
Message-ID: <43FC8D8C.1060904@ce.jp.nec.com> (raw)
In-Reply-To: <43FC8C00.5020600@ce.jp.nec.com>
[-- Attachment #1: Type: text/plain, Size: 186 bytes --]
This patch adds bd_claim_by_kobject and bd_release_from_kobject
which create/remove symlinks between the claimed bdev and
the holder.
--
Jun'ichi Nomura, NEC Solutions (America), Inc.
[-- Attachment #2: common.patch --]
[-- Type: text/x-patch, Size: 8189 bytes --]
Adding bd_claim_by_kobject/bd_release_from_kobject for use by
stacked device drivers (dm and md)
Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
--- linux-2.6.15/include/linux/fs.h 2006-01-02 22:21:10.000000000 -0500
+++ linux-2.6.15/include/linux/fs.h 2006-02-21 19:04:46.000000000 -0500
@@ -373,6 +373,8 @@ struct block_device {
struct list_head bd_inodes;
void * bd_holder;
int bd_holders;
+ struct kobject bd_holder_dir;
+ struct list_head bd_holder_list;
struct block_device * bd_contains;
unsigned bd_block_size;
struct hd_struct * bd_part;
@@ -1351,6 +1353,8 @@ extern int blkdev_get(struct block_devic
extern int blkdev_put(struct block_device *);
extern int bd_claim(struct block_device *, void *);
extern void bd_release(struct block_device *);
+extern int bd_claim_by_kobject(struct block_device *, void *, struct kobject *);
+extern void bd_release_from_kobject(struct block_device *, struct kobject *);
/* fs/char_dev.c */
extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);
--- linux-2.6.15/include/linux/genhd.h 2006-01-02 22:21:10.000000000 -0500
+++ linux-2.6.15/include/linux/genhd.h 2006-02-21 11:38:01.000000000 -0500
@@ -114,6 +114,7 @@ struct gendisk {
int number; /* more of the same */
struct device *driverfs_dev;
struct kobject kobj;
+ struct kobject slave_dir;
struct timer_rand_state *random;
int policy;
--- linux-2.6.15/fs/block_dev.c 2006-01-02 22:21:10.000000000 -0500
+++ linux-2.6.15/fs/block_dev.c 2006-02-22 09:48:37.000000000 -0500
@@ -443,7 +443,159 @@ void bd_forget(struct inode *inode)
spin_unlock(&bdev_lock);
}
-int bd_claim(struct block_device *bdev, void *holder)
+/*
+ * Functions for bd_claim_by_kobject / bd_release_from_kobject
+ *
+ * If a kobject is passed to bd_claim_by_kobject()
+ * and the kobject has a parent directory,
+ * following symlinks are created:
+ * o from the kobject to the claimed bdev
+ * o from "holders" directory of the bdev to the parent of the kobject
+ * bd_release_from_kobject() removes these symlinks.
+ *
+ * Example:
+ * If /dev/dm-0 maps to /dev/sda, kobject corresponding to
+ * /sys/block/dm-0/slaves is passed to bd_claim_by_kobject(), then:
+ * /sys/block/dm-0/slaves/sda --> /sys/block/sda
+ * /sys/block/sda/holders/dm-0 --> /sys/block/dm-0
+ */
+
+static inline struct kobject * bdev_get_kobj(struct block_device *bdev)
+{
+ if (!bdev)
+ return NULL;
+ else if (bdev->bd_contains != bdev)
+ return kobject_get(&bdev->bd_part->kobj);
+ else
+ return kobject_get(&bdev->bd_disk->kobj);
+}
+
+static inline void add_symlink(struct kobject *from, struct kobject *to)
+{
+ if (!from || !to)
+ return;
+ sysfs_create_link(from, to, kobject_name(to));
+}
+
+static inline void del_symlink(struct kobject *from, struct kobject *to)
+{
+ if (!from || !to)
+ return;
+ sysfs_remove_link(from, kobject_name(to));
+}
+
+static void link_bd_holder(struct block_device *bdev, struct kobject *holder)
+{
+ struct kobject *kobj;
+
+ if (!holder->parent)
+ return;
+
+ kobj = bdev_get_kobj(bdev);
+ add_symlink(holder, kobj);
+ add_symlink(&bdev->bd_holder_dir, holder->parent);
+ kobject_put(kobj);
+}
+
+static void unlink_bd_holder(struct block_device *bdev, struct kobject *holder)
+{
+ struct kobject *kobj;
+
+ if (!holder->parent)
+ return;
+
+ kobj = bdev_get_kobj(bdev);
+ del_symlink(holder, kobj);
+ del_symlink(&bdev->bd_holder_dir, holder->parent);
+ kobject_put(kobj);
+}
+
+/* This is a mere directory in sysfs. No methods are needed. */
+static struct kobj_type bd_holder_ktype = {
+ .release = NULL,
+ .sysfs_ops = NULL,
+ .default_attrs = NULL,
+};
+
+static inline void add_holder_dir(struct block_device *bdev)
+{
+ struct kobject *kobj = &bdev->bd_holder_dir;
+
+ kobj->ktype = &bd_holder_ktype;
+ kobject_set_name(kobj, "holders");
+ kobj->parent = bdev_get_kobj(bdev);
+ kobject_init(kobj);
+ kobject_add(kobj);
+ kobject_put(kobj->parent);
+}
+
+static inline void del_holder_dir(struct block_device *bdev)
+{
+ /*
+ * Don't kobject_unregister to avoid memory allocation
+ * in kobject_hotplug.
+ */
+ kobject_del(&bdev->bd_holder_dir);
+ kobject_put(&bdev->bd_holder_dir);
+}
+
+/* bd_holder_list is protected by bdev_lock */
+struct bd_holder {
+ struct list_head list; /* chain of holders of the bdev */
+ int count; /* references from the holder */
+ struct kobject *kobj; /* holder kobject */
+};
+
+static int add_bd_holder(struct block_device *bdev, struct kobject *kobj)
+{
+ struct bd_holder *bo;
+
+ list_for_each_entry(bo, &bdev->bd_holder_list, list) {
+ if (bo->kobj == kobj) {
+ bo->count++;
+ return 0;
+ }
+ }
+
+ if (list_empty(&bdev->bd_holder_list))
+ add_holder_dir(bdev);
+
+ bo = kmalloc(sizeof(*bo), GFP_KERNEL);
+ if (!bo)
+ return -ENOMEM;
+
+ bo->count = 1;
+ bo->kobj = kobj;
+ list_add_tail(&bo->list, &bdev->bd_holder_list);
+ link_bd_holder(bdev, kobj);
+
+ return 0;
+}
+
+static int del_bd_holder(struct block_device *bdev, struct kobject *kobj)
+{
+ struct bd_holder *bo;
+
+ list_for_each_entry(bo, &bdev->bd_holder_list, list) {
+ if (bo->kobj == kobj) {
+ bo->count--;
+ BUG_ON(bo->count < 0);
+ if (!bo->count) {
+ unlink_bd_holder(bdev, kobj);
+ list_del(&bo->list);
+ kfree(bo);
+ }
+ break;
+ }
+ }
+
+ if (list_empty(&bdev->bd_holder_list))
+ del_holder_dir(bdev);
+
+ return 0;
+}
+
+int bd_claim_by_kobject(struct block_device *bdev, void *holder, struct kobject *kobj)
{
int res;
spin_lock(&bdev_lock);
@@ -464,6 +616,9 @@ int bd_claim(struct block_device *bdev,
res = 0; /* is a partition of an un-held device */
/* now impose change */
+ if (res == 0 && kobj)
+ res = add_bd_holder(bdev, kobj);
+
if (res==0) {
/* note that for a whole device bd_holders
* will be incremented twice, and bd_holder will
@@ -478,11 +633,20 @@ int bd_claim(struct block_device *bdev,
return res;
}
+EXPORT_SYMBOL(bd_claim_by_kobject);
+
+int bd_claim(struct block_device *bdev, void *holder)
+{
+ return bd_claim_by_kobject(bdev, holder, NULL);
+}
+
EXPORT_SYMBOL(bd_claim);
-void bd_release(struct block_device *bdev)
+void bd_release_from_kobject(struct block_device *bdev, struct kobject *kobj)
{
spin_lock(&bdev_lock);
+ if (kobj)
+ del_bd_holder(bdev, kobj);
if (!--bdev->bd_contains->bd_holders)
bdev->bd_contains->bd_holder = NULL;
if (!--bdev->bd_holders)
@@ -490,6 +654,13 @@ void bd_release(struct block_device *bde
spin_unlock(&bdev_lock);
}
+EXPORT_SYMBOL(bd_release_from_kobject);
+
+void bd_release(struct block_device *bdev)
+{
+ bd_release_from_kobject(bdev, NULL);
+}
+
EXPORT_SYMBOL(bd_release);
/*
@@ -578,6 +749,7 @@ static int do_open(struct block_device *
if (!bdev->bd_openers) {
bdev->bd_disk = disk;
bdev->bd_contains = bdev;
+ INIT_LIST_HEAD(&bdev->bd_holder_list);
if (!part) {
struct backing_dev_info *bdi;
if (disk->fops->open) {
--- linux-2.6.15/fs/partitions/check.c 2006-01-02 22:21:10.000000000 -0500
+++ linux-2.6.15/fs/partitions/check.c 2006-02-21 14:30:23.000000000 -0500
@@ -293,6 +293,13 @@ struct kobj_type ktype_part = {
.sysfs_ops = &part_sysfs_ops,
};
+/* This is a mere directory in sysfs. No methods are needed. */
+static struct kobj_type slave_ktype = {
+ .release = NULL,
+ .sysfs_ops = NULL,
+ .default_attrs = NULL,
+};
+
void delete_partition(struct gendisk *disk, int part)
{
struct hd_struct *p = disk->part[part-1];
@@ -343,6 +350,12 @@ static void disk_sysfs_symlinks(struct g
sysfs_create_link(&disk->kobj,&target->kobj,"device");
sysfs_create_link(&target->kobj,&disk->kobj,"block");
}
+
+ /* create subdirectory for symlinks to underlying device */
+ disk->slave_dir.ktype = &slave_ktype;
+ kobject_set_name(&disk->slave_dir, "slaves");
+ disk->slave_dir.parent = &disk->kobj;
+ kobject_register(&disk->slave_dir);
}
/* Not exported, helper to add_disk(). */
@@ -460,6 +473,7 @@ void del_gendisk(struct gendisk *disk)
devfs_remove_disk(disk);
+ kobject_unregister(&disk->slave_dir);
if (disk->driverfs_dev) {
sysfs_remove_link(&disk->kobj, "device");
sysfs_remove_link(&disk->driverfs_dev->kobj, "block");
[-- Attachment #3: Type: text/plain, Size: 0 bytes --]
WARNING: multiple messages have this Message-ID (diff)
From: "Jun'ichi Nomura" <j-nomura@ce.jp.nec.com>
To: Neil Brown <neilb@suse.de>, Alasdair Kergon <agk@redhat.com>,
Lars Marowsky-Bree <lmb@suse.de>, Greg KH <gregkh@suse.de>
Cc: linux-kernel@vger.kernel.org,
device-mapper development <dm-devel@redhat.com>
Subject: [PATCH 1/3] sysfs representation of stacked devices (common) (rev.2)
Date: Wed, 22 Feb 2006 11:13:00 -0500 [thread overview]
Message-ID: <43FC8D8C.1060904@ce.jp.nec.com> (raw)
In-Reply-To: <43FC8C00.5020600@ce.jp.nec.com>
[-- Attachment #1: Type: text/plain, Size: 186 bytes --]
This patch adds bd_claim_by_kobject and bd_release_from_kobject
which create/remove symlinks between the claimed bdev and
the holder.
--
Jun'ichi Nomura, NEC Solutions (America), Inc.
[-- Attachment #2: common.patch --]
[-- Type: text/x-patch, Size: 8189 bytes --]
Adding bd_claim_by_kobject/bd_release_from_kobject for use by
stacked device drivers (dm and md)
Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
--- linux-2.6.15/include/linux/fs.h 2006-01-02 22:21:10.000000000 -0500
+++ linux-2.6.15/include/linux/fs.h 2006-02-21 19:04:46.000000000 -0500
@@ -373,6 +373,8 @@ struct block_device {
struct list_head bd_inodes;
void * bd_holder;
int bd_holders;
+ struct kobject bd_holder_dir;
+ struct list_head bd_holder_list;
struct block_device * bd_contains;
unsigned bd_block_size;
struct hd_struct * bd_part;
@@ -1351,6 +1353,8 @@ extern int blkdev_get(struct block_devic
extern int blkdev_put(struct block_device *);
extern int bd_claim(struct block_device *, void *);
extern void bd_release(struct block_device *);
+extern int bd_claim_by_kobject(struct block_device *, void *, struct kobject *);
+extern void bd_release_from_kobject(struct block_device *, struct kobject *);
/* fs/char_dev.c */
extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);
--- linux-2.6.15/include/linux/genhd.h 2006-01-02 22:21:10.000000000 -0500
+++ linux-2.6.15/include/linux/genhd.h 2006-02-21 11:38:01.000000000 -0500
@@ -114,6 +114,7 @@ struct gendisk {
int number; /* more of the same */
struct device *driverfs_dev;
struct kobject kobj;
+ struct kobject slave_dir;
struct timer_rand_state *random;
int policy;
--- linux-2.6.15/fs/block_dev.c 2006-01-02 22:21:10.000000000 -0500
+++ linux-2.6.15/fs/block_dev.c 2006-02-22 09:48:37.000000000 -0500
@@ -443,7 +443,159 @@ void bd_forget(struct inode *inode)
spin_unlock(&bdev_lock);
}
-int bd_claim(struct block_device *bdev, void *holder)
+/*
+ * Functions for bd_claim_by_kobject / bd_release_from_kobject
+ *
+ * If a kobject is passed to bd_claim_by_kobject()
+ * and the kobject has a parent directory,
+ * following symlinks are created:
+ * o from the kobject to the claimed bdev
+ * o from "holders" directory of the bdev to the parent of the kobject
+ * bd_release_from_kobject() removes these symlinks.
+ *
+ * Example:
+ * If /dev/dm-0 maps to /dev/sda, kobject corresponding to
+ * /sys/block/dm-0/slaves is passed to bd_claim_by_kobject(), then:
+ * /sys/block/dm-0/slaves/sda --> /sys/block/sda
+ * /sys/block/sda/holders/dm-0 --> /sys/block/dm-0
+ */
+
+static inline struct kobject * bdev_get_kobj(struct block_device *bdev)
+{
+ if (!bdev)
+ return NULL;
+ else if (bdev->bd_contains != bdev)
+ return kobject_get(&bdev->bd_part->kobj);
+ else
+ return kobject_get(&bdev->bd_disk->kobj);
+}
+
+static inline void add_symlink(struct kobject *from, struct kobject *to)
+{
+ if (!from || !to)
+ return;
+ sysfs_create_link(from, to, kobject_name(to));
+}
+
+static inline void del_symlink(struct kobject *from, struct kobject *to)
+{
+ if (!from || !to)
+ return;
+ sysfs_remove_link(from, kobject_name(to));
+}
+
+static void link_bd_holder(struct block_device *bdev, struct kobject *holder)
+{
+ struct kobject *kobj;
+
+ if (!holder->parent)
+ return;
+
+ kobj = bdev_get_kobj(bdev);
+ add_symlink(holder, kobj);
+ add_symlink(&bdev->bd_holder_dir, holder->parent);
+ kobject_put(kobj);
+}
+
+static void unlink_bd_holder(struct block_device *bdev, struct kobject *holder)
+{
+ struct kobject *kobj;
+
+ if (!holder->parent)
+ return;
+
+ kobj = bdev_get_kobj(bdev);
+ del_symlink(holder, kobj);
+ del_symlink(&bdev->bd_holder_dir, holder->parent);
+ kobject_put(kobj);
+}
+
+/* This is a mere directory in sysfs. No methods are needed. */
+static struct kobj_type bd_holder_ktype = {
+ .release = NULL,
+ .sysfs_ops = NULL,
+ .default_attrs = NULL,
+};
+
+static inline void add_holder_dir(struct block_device *bdev)
+{
+ struct kobject *kobj = &bdev->bd_holder_dir;
+
+ kobj->ktype = &bd_holder_ktype;
+ kobject_set_name(kobj, "holders");
+ kobj->parent = bdev_get_kobj(bdev);
+ kobject_init(kobj);
+ kobject_add(kobj);
+ kobject_put(kobj->parent);
+}
+
+static inline void del_holder_dir(struct block_device *bdev)
+{
+ /*
+ * Don't kobject_unregister to avoid memory allocation
+ * in kobject_hotplug.
+ */
+ kobject_del(&bdev->bd_holder_dir);
+ kobject_put(&bdev->bd_holder_dir);
+}
+
+/* bd_holder_list is protected by bdev_lock */
+struct bd_holder {
+ struct list_head list; /* chain of holders of the bdev */
+ int count; /* references from the holder */
+ struct kobject *kobj; /* holder kobject */
+};
+
+static int add_bd_holder(struct block_device *bdev, struct kobject *kobj)
+{
+ struct bd_holder *bo;
+
+ list_for_each_entry(bo, &bdev->bd_holder_list, list) {
+ if (bo->kobj == kobj) {
+ bo->count++;
+ return 0;
+ }
+ }
+
+ if (list_empty(&bdev->bd_holder_list))
+ add_holder_dir(bdev);
+
+ bo = kmalloc(sizeof(*bo), GFP_KERNEL);
+ if (!bo)
+ return -ENOMEM;
+
+ bo->count = 1;
+ bo->kobj = kobj;
+ list_add_tail(&bo->list, &bdev->bd_holder_list);
+ link_bd_holder(bdev, kobj);
+
+ return 0;
+}
+
+static int del_bd_holder(struct block_device *bdev, struct kobject *kobj)
+{
+ struct bd_holder *bo;
+
+ list_for_each_entry(bo, &bdev->bd_holder_list, list) {
+ if (bo->kobj == kobj) {
+ bo->count--;
+ BUG_ON(bo->count < 0);
+ if (!bo->count) {
+ unlink_bd_holder(bdev, kobj);
+ list_del(&bo->list);
+ kfree(bo);
+ }
+ break;
+ }
+ }
+
+ if (list_empty(&bdev->bd_holder_list))
+ del_holder_dir(bdev);
+
+ return 0;
+}
+
+int bd_claim_by_kobject(struct block_device *bdev, void *holder, struct kobject *kobj)
{
int res;
spin_lock(&bdev_lock);
@@ -464,6 +616,9 @@ int bd_claim(struct block_device *bdev,
res = 0; /* is a partition of an un-held device */
/* now impose change */
+ if (res == 0 && kobj)
+ res = add_bd_holder(bdev, kobj);
+
if (res==0) {
/* note that for a whole device bd_holders
* will be incremented twice, and bd_holder will
@@ -478,11 +633,20 @@ int bd_claim(struct block_device *bdev,
return res;
}
+EXPORT_SYMBOL(bd_claim_by_kobject);
+
+int bd_claim(struct block_device *bdev, void *holder)
+{
+ return bd_claim_by_kobject(bdev, holder, NULL);
+}
+
EXPORT_SYMBOL(bd_claim);
-void bd_release(struct block_device *bdev)
+void bd_release_from_kobject(struct block_device *bdev, struct kobject *kobj)
{
spin_lock(&bdev_lock);
+ if (kobj)
+ del_bd_holder(bdev, kobj);
if (!--bdev->bd_contains->bd_holders)
bdev->bd_contains->bd_holder = NULL;
if (!--bdev->bd_holders)
@@ -490,6 +654,13 @@ void bd_release(struct block_device *bde
spin_unlock(&bdev_lock);
}
+EXPORT_SYMBOL(bd_release_from_kobject);
+
+void bd_release(struct block_device *bdev)
+{
+ bd_release_from_kobject(bdev, NULL);
+}
+
EXPORT_SYMBOL(bd_release);
/*
@@ -578,6 +749,7 @@ static int do_open(struct block_device *
if (!bdev->bd_openers) {
bdev->bd_disk = disk;
bdev->bd_contains = bdev;
+ INIT_LIST_HEAD(&bdev->bd_holder_list);
if (!part) {
struct backing_dev_info *bdi;
if (disk->fops->open) {
--- linux-2.6.15/fs/partitions/check.c 2006-01-02 22:21:10.000000000 -0500
+++ linux-2.6.15/fs/partitions/check.c 2006-02-21 14:30:23.000000000 -0500
@@ -293,6 +293,13 @@ struct kobj_type ktype_part = {
.sysfs_ops = &part_sysfs_ops,
};
+/* This is a mere directory in sysfs. No methods are needed. */
+static struct kobj_type slave_ktype = {
+ .release = NULL,
+ .sysfs_ops = NULL,
+ .default_attrs = NULL,
+};
+
void delete_partition(struct gendisk *disk, int part)
{
struct hd_struct *p = disk->part[part-1];
@@ -343,6 +350,12 @@ static void disk_sysfs_symlinks(struct g
sysfs_create_link(&disk->kobj,&target->kobj,"device");
sysfs_create_link(&target->kobj,&disk->kobj,"block");
}
+
+ /* create subdirectory for symlinks to underlying device */
+ disk->slave_dir.ktype = &slave_ktype;
+ kobject_set_name(&disk->slave_dir, "slaves");
+ disk->slave_dir.parent = &disk->kobj;
+ kobject_register(&disk->slave_dir);
}
/* Not exported, helper to add_disk(). */
@@ -460,6 +473,7 @@ void del_gendisk(struct gendisk *disk)
devfs_remove_disk(disk);
+ kobject_unregister(&disk->slave_dir);
if (disk->driverfs_dev) {
sysfs_remove_link(&disk->kobj, "device");
sysfs_remove_link(&disk->driverfs_dev->kobj, "block");
next prev parent reply other threads:[~2006-02-22 16:13 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-02-22 16:06 [PATCH 0/3] sysfs representation of stacked devices (dm/md) (rev.2) Jun'ichi Nomura
2006-02-22 16:06 ` Jun'ichi Nomura
2006-02-22 16:13 ` Jun'ichi Nomura [this message]
2006-02-22 16:13 ` [PATCH 1/3] sysfs representation of stacked devices (common) (rev.2) Jun'ichi Nomura
2006-02-22 18:48 ` Greg KH
2006-02-22 18:48 ` Greg KH
2006-02-22 22:22 ` Jun'ichi Nomura
2006-02-22 22:22 ` Jun'ichi Nomura
2006-02-22 22:28 ` Greg KH
2006-02-22 22:28 ` Greg KH
2006-02-23 19:15 ` Jun'ichi Nomura
2006-02-23 19:15 ` Jun'ichi Nomura
2006-02-24 3:40 ` Greg KH
2006-02-24 3:40 ` Greg KH
2006-02-27 16:09 ` Jun'ichi Nomura
2006-02-22 16:13 ` [PATCH 2/3] sysfs representation of stacked devices (dm) (rev.2) Jun'ichi Nomura
2006-02-22 16:13 ` Jun'ichi Nomura
2006-02-22 16:34 ` Alasdair G Kergon
2006-02-22 16:34 ` Alasdair G Kergon
2006-02-22 17:13 ` Jun'ichi Nomura
2006-02-22 17:13 ` Jun'ichi Nomura
2006-02-22 18:13 ` Alasdair G Kergon
2006-02-22 18:13 ` Alasdair G Kergon
2006-02-22 19:32 ` Jun'ichi Nomura
2006-02-22 19:32 ` Jun'ichi Nomura
2006-02-22 16:13 ` [PATCH 3/3] sysfs representation of stacked devices (md) (rev.2) Jun'ichi Nomura
2006-02-22 16:13 ` Jun'ichi Nomura
2006-02-22 18:47 ` [PATCH 0/3] sysfs representation of stacked devices (dm/md) (rev.2) Greg KH
2006-02-22 18:47 ` Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=43FC8D8C.1060904@ce.jp.nec.com \
--to=j-nomura@ce.jp.nec.com \
--cc=agk@redhat.com \
--cc=dm-devel@redhat.com \
--cc=gregkh@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=lmb@suse.de \
--cc=neilb@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.