RE: [Linux-nvdimm] [PATCH v2 18/20] libnd: infrastructure for btt devices

2015-05-14 Thread Elliott, Robert (Server Storage)
> -Original Message-
> From: Linux-nvdimm [mailto:linux-nvdimm-boun...@lists.01.org] On Behalf
> Of Dan Williams
> Sent: Thursday, May 14, 2015 7:42 PM
> To: Kani, Toshimitsu
> Cc: Neil Brown; Greg KH; linux-kernel@vger.kernel.org; linux-
> nvd...@lists.01.org
> Subject: Re: [Linux-nvdimm] [PATCH v2 18/20] libnd: infrastructure for
> btt devices
> 
...
> So we can fix this to be at least as stable as the backing device
> names [1], but as far as I can see we would need to start using the
> backing device name in the btt device name.  A strawman proposal is to
> append 's' to indicated 'sectored'.  So /dev/pmem0s is the btt
> instance fronting /dev/pmem0.  Other examples:
> 
> /dev/pmem0p1s
> /dev/ndblk0.0s
> /dev/ndblk0.0p1s
> ...
> 
> Thoughts?
> 
> [1]: https://lists.01.org/pipermail/linux-nvdimm/2015-April/000636.html

I like that; it also hints to the user that another driver has already
claimed /dev/pmem0, similar to how the presence of /dev/sda1, /dev/sda2,
etc. hints that a program has partitioned /dev/sda.


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Linux-nvdimm] [PATCH v2 18/20] libnd: infrastructure for btt devices

2015-05-14 Thread Dan Williams
On Tue, May 12, 2015 at 9:33 AM, Toshi Kani  wrote:
> On Tue, 2015-04-28 at 14:25 -0400, Dan Williams wrote:
>> Block devices from an nd bus, in addition to accepting "struct bio"
>> based requests, also have the capability to perform byte-aligned
>> accesses.  By default only the bio/block interface is used.  However, if
>> another driver can make effective use of the byte-aligned capability it
>> can claim/disable the block interface and use the byte-aligned "nd_io"
>> interface.
>>
>> The BTT driver is the intended first consumer of this mechanism to allow
>> layering atomic sector update guarantees on top of nd_io capable
>> nd-bus-block-devices.
>  :
>> +static int nd_btt_autodetect(struct nd_bus *nd_bus, struct nd_io *ndio,
>> + struct block_device *bdev)
>> +{
>> + char name[BDEVNAME_SIZE];
>> + struct nd_btt *nd_btt;
>> + struct btt_sb *btt_sb;
>> + u64 offset, checksum;
>> + u32 lbasize;
>> + u8 *uuid;
>> + int rc;
>> +
>> + btt_sb = kzalloc(sizeof(*btt_sb), GFP_KERNEL);
>> + if (!btt_sb)
>> + return -ENODEV;
>> +
>> + offset = nd_partition_offset(bdev);
>> + rc = ndio->rw_bytes(ndio, btt_sb, offset + SZ_4K, sizeof(*btt_sb), 
>> READ);
>> + if (rc)
>> + goto out_free_sb;
>> +
>> + if (get_capacity(bdev->bd_disk) < SZ_16M / 512)
>> + goto out_free_sb;
>> +
>> + if (memcmp(btt_sb->signature, BTT_SIG, BTT_SIG_LEN) != 0)
>> + goto out_free_sb;
>> +
>> + checksum = le64_to_cpu(btt_sb->checksum);
>> + btt_sb->checksum = 0;
>> + if (checksum != nd_btt_sb_checksum(btt_sb))
>> + goto out_free_sb;
>> + btt_sb->checksum = cpu_to_le64(checksum);
>> +
>> + uuid = kmemdup(btt_sb->uuid, 16, GFP_KERNEL);
>> + if (!uuid)
>> + goto out_free_sb;
>> +
>> + lbasize = le32_to_cpu(btt_sb->external_lbasize);
>> + nd_btt = __nd_btt_create(nd_bus, lbasize, uuid);
>
> When BTT is first set up, user binds a seed "btt0" to a block device,
> such as /dev/pmem0.  It then creates /dev/nd0 bound to /dev/pmem0.
>
> After a reboot, nd_btt_autodetect() detects the BTT setup and creates a
> new "btt1" since it is called after a seed "btt0" is created.
> Therefore, it creates /dev/nd1 bound to /dev/pmem0 this time.
>
> Is this how it is intended to work, i.e. "btt0" as the default seed btt?
> While user should not rely on the name of /dev/nd%d, I thought this
> device name change was confusing...

So we can fix this to be at least as stable as the backing device
names [1], but as far as I can see we would need to start using the
backing device name in the btt device name.  A strawman proposal is to
append 's' to indicated 'sectored'.  So /dev/pmem0s is the btt
instance fronting /dev/pmem0.  Other examples:

/dev/pmem0p1s
/dev/ndblk0.0s
/dev/ndblk0.0p1s
...

Thoughts?

[1]: https://lists.01.org/pipermail/linux-nvdimm/2015-April/000636.html
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Linux-nvdimm] [PATCH v2 18/20] libnd: infrastructure for btt devices

2015-05-14 Thread Dan Williams
On Tue, May 12, 2015 at 9:33 AM, Toshi Kani toshi.k...@hp.com wrote:
 On Tue, 2015-04-28 at 14:25 -0400, Dan Williams wrote:
 Block devices from an nd bus, in addition to accepting struct bio
 based requests, also have the capability to perform byte-aligned
 accesses.  By default only the bio/block interface is used.  However, if
 another driver can make effective use of the byte-aligned capability it
 can claim/disable the block interface and use the byte-aligned nd_io
 interface.

 The BTT driver is the intended first consumer of this mechanism to allow
 layering atomic sector update guarantees on top of nd_io capable
 nd-bus-block-devices.
  :
 +static int nd_btt_autodetect(struct nd_bus *nd_bus, struct nd_io *ndio,
 + struct block_device *bdev)
 +{
 + char name[BDEVNAME_SIZE];
 + struct nd_btt *nd_btt;
 + struct btt_sb *btt_sb;
 + u64 offset, checksum;
 + u32 lbasize;
 + u8 *uuid;
 + int rc;
 +
 + btt_sb = kzalloc(sizeof(*btt_sb), GFP_KERNEL);
 + if (!btt_sb)
 + return -ENODEV;
 +
 + offset = nd_partition_offset(bdev);
 + rc = ndio-rw_bytes(ndio, btt_sb, offset + SZ_4K, sizeof(*btt_sb), 
 READ);
 + if (rc)
 + goto out_free_sb;
 +
 + if (get_capacity(bdev-bd_disk)  SZ_16M / 512)
 + goto out_free_sb;
 +
 + if (memcmp(btt_sb-signature, BTT_SIG, BTT_SIG_LEN) != 0)
 + goto out_free_sb;
 +
 + checksum = le64_to_cpu(btt_sb-checksum);
 + btt_sb-checksum = 0;
 + if (checksum != nd_btt_sb_checksum(btt_sb))
 + goto out_free_sb;
 + btt_sb-checksum = cpu_to_le64(checksum);
 +
 + uuid = kmemdup(btt_sb-uuid, 16, GFP_KERNEL);
 + if (!uuid)
 + goto out_free_sb;
 +
 + lbasize = le32_to_cpu(btt_sb-external_lbasize);
 + nd_btt = __nd_btt_create(nd_bus, lbasize, uuid);

 When BTT is first set up, user binds a seed btt0 to a block device,
 such as /dev/pmem0.  It then creates /dev/nd0 bound to /dev/pmem0.

 After a reboot, nd_btt_autodetect() detects the BTT setup and creates a
 new btt1 since it is called after a seed btt0 is created.
 Therefore, it creates /dev/nd1 bound to /dev/pmem0 this time.

 Is this how it is intended to work, i.e. btt0 as the default seed btt?
 While user should not rely on the name of /dev/nd%d, I thought this
 device name change was confusing...

So we can fix this to be at least as stable as the backing device
names [1], but as far as I can see we would need to start using the
backing device name in the btt device name.  A strawman proposal is to
append 's' to indicated 'sectored'.  So /dev/pmem0s is the btt
instance fronting /dev/pmem0.  Other examples:

/dev/pmem0p1s
/dev/ndblk0.0s
/dev/ndblk0.0p1s
...

Thoughts?

[1]: https://lists.01.org/pipermail/linux-nvdimm/2015-April/000636.html
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


RE: [Linux-nvdimm] [PATCH v2 18/20] libnd: infrastructure for btt devices

2015-05-14 Thread Elliott, Robert (Server Storage)
 -Original Message-
 From: Linux-nvdimm [mailto:linux-nvdimm-boun...@lists.01.org] On Behalf
 Of Dan Williams
 Sent: Thursday, May 14, 2015 7:42 PM
 To: Kani, Toshimitsu
 Cc: Neil Brown; Greg KH; linux-kernel@vger.kernel.org; linux-
 nvd...@lists.01.org
 Subject: Re: [Linux-nvdimm] [PATCH v2 18/20] libnd: infrastructure for
 btt devices
 
...
 So we can fix this to be at least as stable as the backing device
 names [1], but as far as I can see we would need to start using the
 backing device name in the btt device name.  A strawman proposal is to
 append 's' to indicated 'sectored'.  So /dev/pmem0s is the btt
 instance fronting /dev/pmem0.  Other examples:
 
 /dev/pmem0p1s
 /dev/ndblk0.0s
 /dev/ndblk0.0p1s
 ...
 
 Thoughts?
 
 [1]: https://lists.01.org/pipermail/linux-nvdimm/2015-April/000636.html

I like that; it also hints to the user that another driver has already
claimed /dev/pmem0, similar to how the presence of /dev/sda1, /dev/sda2,
etc. hints that a program has partitioned /dev/sda.


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Linux-nvdimm] [PATCH v2 18/20] libnd: infrastructure for btt devices

2015-05-12 Thread Toshi Kani
On Tue, 2015-04-28 at 14:25 -0400, Dan Williams wrote:
> Block devices from an nd bus, in addition to accepting "struct bio"
> based requests, also have the capability to perform byte-aligned
> accesses.  By default only the bio/block interface is used.  However, if
> another driver can make effective use of the byte-aligned capability it
> can claim/disable the block interface and use the byte-aligned "nd_io"
> interface.
> 
> The BTT driver is the intended first consumer of this mechanism to allow
> layering atomic sector update guarantees on top of nd_io capable
> nd-bus-block-devices.
 :
> +static int nd_btt_autodetect(struct nd_bus *nd_bus, struct nd_io *ndio,
> + struct block_device *bdev)
> +{
> + char name[BDEVNAME_SIZE];
> + struct nd_btt *nd_btt;
> + struct btt_sb *btt_sb;
> + u64 offset, checksum;
> + u32 lbasize;
> + u8 *uuid;
> + int rc;
> +
> + btt_sb = kzalloc(sizeof(*btt_sb), GFP_KERNEL);
> + if (!btt_sb)
> + return -ENODEV;
> +
> + offset = nd_partition_offset(bdev);
> + rc = ndio->rw_bytes(ndio, btt_sb, offset + SZ_4K, sizeof(*btt_sb), 
> READ);
> + if (rc)
> + goto out_free_sb;
> +
> + if (get_capacity(bdev->bd_disk) < SZ_16M / 512)
> + goto out_free_sb;
> +
> + if (memcmp(btt_sb->signature, BTT_SIG, BTT_SIG_LEN) != 0)
> + goto out_free_sb;
> +
> + checksum = le64_to_cpu(btt_sb->checksum);
> + btt_sb->checksum = 0;
> + if (checksum != nd_btt_sb_checksum(btt_sb))
> + goto out_free_sb;
> + btt_sb->checksum = cpu_to_le64(checksum);
> +
> + uuid = kmemdup(btt_sb->uuid, 16, GFP_KERNEL);
> + if (!uuid)
> + goto out_free_sb;
> +
> + lbasize = le32_to_cpu(btt_sb->external_lbasize);
> + nd_btt = __nd_btt_create(nd_bus, lbasize, uuid);

When BTT is first set up, user binds a seed "btt0" to a block device,
such as /dev/pmem0.  It then creates /dev/nd0 bound to /dev/pmem0.

After a reboot, nd_btt_autodetect() detects the BTT setup and creates a
new "btt1" since it is called after a seed "btt0" is created.
Therefore, it creates /dev/nd1 bound to /dev/pmem0 this time.

Is this how it is intended to work, i.e. "btt0" as the default seed btt?
While user should not rely on the name of /dev/nd%d, I thought this
device name change was confusing...

Thanks,
-Toshi


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Linux-nvdimm] [PATCH v2 18/20] libnd: infrastructure for btt devices

2015-05-12 Thread Toshi Kani
On Tue, 2015-04-28 at 14:25 -0400, Dan Williams wrote:
 Block devices from an nd bus, in addition to accepting struct bio
 based requests, also have the capability to perform byte-aligned
 accesses.  By default only the bio/block interface is used.  However, if
 another driver can make effective use of the byte-aligned capability it
 can claim/disable the block interface and use the byte-aligned nd_io
 interface.
 
 The BTT driver is the intended first consumer of this mechanism to allow
 layering atomic sector update guarantees on top of nd_io capable
 nd-bus-block-devices.
 :
 +static int nd_btt_autodetect(struct nd_bus *nd_bus, struct nd_io *ndio,
 + struct block_device *bdev)
 +{
 + char name[BDEVNAME_SIZE];
 + struct nd_btt *nd_btt;
 + struct btt_sb *btt_sb;
 + u64 offset, checksum;
 + u32 lbasize;
 + u8 *uuid;
 + int rc;
 +
 + btt_sb = kzalloc(sizeof(*btt_sb), GFP_KERNEL);
 + if (!btt_sb)
 + return -ENODEV;
 +
 + offset = nd_partition_offset(bdev);
 + rc = ndio-rw_bytes(ndio, btt_sb, offset + SZ_4K, sizeof(*btt_sb), 
 READ);
 + if (rc)
 + goto out_free_sb;
 +
 + if (get_capacity(bdev-bd_disk)  SZ_16M / 512)
 + goto out_free_sb;
 +
 + if (memcmp(btt_sb-signature, BTT_SIG, BTT_SIG_LEN) != 0)
 + goto out_free_sb;
 +
 + checksum = le64_to_cpu(btt_sb-checksum);
 + btt_sb-checksum = 0;
 + if (checksum != nd_btt_sb_checksum(btt_sb))
 + goto out_free_sb;
 + btt_sb-checksum = cpu_to_le64(checksum);
 +
 + uuid = kmemdup(btt_sb-uuid, 16, GFP_KERNEL);
 + if (!uuid)
 + goto out_free_sb;
 +
 + lbasize = le32_to_cpu(btt_sb-external_lbasize);
 + nd_btt = __nd_btt_create(nd_bus, lbasize, uuid);

When BTT is first set up, user binds a seed btt0 to a block device,
such as /dev/pmem0.  It then creates /dev/nd0 bound to /dev/pmem0.

After a reboot, nd_btt_autodetect() detects the BTT setup and creates a
new btt1 since it is called after a seed btt0 is created.
Therefore, it creates /dev/nd1 bound to /dev/pmem0 this time.

Is this how it is intended to work, i.e. btt0 as the default seed btt?
While user should not rely on the name of /dev/nd%d, I thought this
device name change was confusing...

Thanks,
-Toshi


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 18/20] libnd: infrastructure for btt devices

2015-04-28 Thread Dan Williams
Block devices from an nd bus, in addition to accepting "struct bio"
based requests, also have the capability to perform byte-aligned
accesses.  By default only the bio/block interface is used.  However, if
another driver can make effective use of the byte-aligned capability it
can claim/disable the block interface and use the byte-aligned "nd_io"
interface.

The BTT driver is the intended first consumer of this mechanism to allow
layering atomic sector update guarantees on top of nd_io capable
nd-bus-block-devices.

Cc: Greg KH 
Cc: Neil Brown 
Signed-off-by: Dan Williams 
---
 drivers/block/nd/Kconfig  |3 
 drivers/block/nd/Makefile |1 
 drivers/block/nd/btt.h|   45 
 drivers/block/nd/btt_devs.c   |  442 +
 drivers/block/nd/bus.c|  128 
 drivers/block/nd/core.c   |   79 +++
 drivers/block/nd/nd-private.h |   28 +++
 drivers/block/nd/nd.h |   94 +
 drivers/block/nd/pmem.c   |   29 +++
 include/uapi/linux/ndctl.h|2 
 10 files changed, 847 insertions(+), 4 deletions(-)
 create mode 100644 drivers/block/nd/btt.h
 create mode 100644 drivers/block/nd/btt_devs.c

diff --git a/drivers/block/nd/Kconfig b/drivers/block/nd/Kconfig
index c5eaf195734d..15896db4de37 100644
--- a/drivers/block/nd/Kconfig
+++ b/drivers/block/nd/Kconfig
@@ -95,4 +95,7 @@ config BLK_DEV_PMEM
 
  Say Y if you want to use a NVDIMM described by NFIT
 
+config ND_BTT_DEVS
+   def_bool y
+
 endif
diff --git a/drivers/block/nd/Makefile b/drivers/block/nd/Makefile
index d588f691163c..0c6d64b7a69d 100644
--- a/drivers/block/nd/Makefile
+++ b/drivers/block/nd/Makefile
@@ -32,3 +32,4 @@ libnd-y += region_devs.o
 libnd-y += region.o
 libnd-y += namespace_devs.o
 libnd-y += label.o
+libnd-$(CONFIG_ND_BTT_DEVS) += btt_devs.o
diff --git a/drivers/block/nd/btt.h b/drivers/block/nd/btt.h
new file mode 100644
index ..e8f6d8e0ddd3
--- /dev/null
+++ b/drivers/block/nd/btt.h
@@ -0,0 +1,45 @@
+/*
+ * Block Translation Table library
+ * Copyright (c) 2014-2015, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _LINUX_BTT_H
+#define _LINUX_BTT_H
+
+#include 
+
+#define BTT_SIG_LEN 16
+#define BTT_SIG "BTT_ARENA_INFO\0"
+
+struct btt_sb {
+   u8 signature[BTT_SIG_LEN];
+   u8 uuid[16];
+   u8 parent_uuid[16];
+   __le32 flags;
+   __le16 version_major;
+   __le16 version_minor;
+   __le32 external_lbasize;
+   __le32 external_nlba;
+   __le32 internal_lbasize;
+   __le32 internal_nlba;
+   __le32 nfree;
+   __le32 infosize;
+   __le64 nextoff;
+   __le64 dataoff;
+   __le64 mapoff;
+   __le64 logoff;
+   __le64 info2off;
+   u8 padding[3968];
+   __le64 checksum;
+};
+
+#endif
diff --git a/drivers/block/nd/btt_devs.c b/drivers/block/nd/btt_devs.c
new file mode 100644
index ..e6f0b8b999d8
--- /dev/null
+++ b/drivers/block/nd/btt_devs.c
@@ -0,0 +1,442 @@
+/*
+ * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "nd-private.h"
+#include "btt.h"
+#include "nd.h"
+
+static DEFINE_IDA(btt_ida);
+
+static void nd_btt_release(struct device *dev)
+{
+   struct nd_btt *nd_btt = to_nd_btt(dev);
+
+   dev_dbg(dev, "%s\n", __func__);
+   WARN_ON(nd_btt->backing_dev);
+   ndio_del_claim(nd_btt->ndio_claim);
+   ida_simple_remove(_ida, nd_btt->id);
+   kfree(nd_btt->uuid);
+   kfree(nd_btt);
+}
+
+static struct device_type nd_btt_device_type = {
+   .name = "nd_btt",
+   .release = nd_btt_release,
+};
+
+bool is_nd_btt(struct device *dev)
+{
+   return dev->type == _btt_device_type;
+}
+
+struct nd_btt *to_nd_btt(struct device *dev)
+{
+   struct nd_btt *nd_btt = container_of(dev, struct nd_btt, dev);
+
+   WARN_ON(!is_nd_btt(dev));
+   return nd_btt;
+}
+EXPORT_SYMBOL(to_nd_btt);
+
+static const unsigned long btt_lbasize_supported[] = { 512, 4096, 0 };
+
+static ssize_t sector_size_show(struct device *dev,
+   

[PATCH v2 18/20] libnd: infrastructure for btt devices

2015-04-28 Thread Dan Williams
Block devices from an nd bus, in addition to accepting struct bio
based requests, also have the capability to perform byte-aligned
accesses.  By default only the bio/block interface is used.  However, if
another driver can make effective use of the byte-aligned capability it
can claim/disable the block interface and use the byte-aligned nd_io
interface.

The BTT driver is the intended first consumer of this mechanism to allow
layering atomic sector update guarantees on top of nd_io capable
nd-bus-block-devices.

Cc: Greg KH gre...@linuxfoundation.org
Cc: Neil Brown ne...@suse.de
Signed-off-by: Dan Williams dan.j.willi...@intel.com
---
 drivers/block/nd/Kconfig  |3 
 drivers/block/nd/Makefile |1 
 drivers/block/nd/btt.h|   45 
 drivers/block/nd/btt_devs.c   |  442 +
 drivers/block/nd/bus.c|  128 
 drivers/block/nd/core.c   |   79 +++
 drivers/block/nd/nd-private.h |   28 +++
 drivers/block/nd/nd.h |   94 +
 drivers/block/nd/pmem.c   |   29 +++
 include/uapi/linux/ndctl.h|2 
 10 files changed, 847 insertions(+), 4 deletions(-)
 create mode 100644 drivers/block/nd/btt.h
 create mode 100644 drivers/block/nd/btt_devs.c

diff --git a/drivers/block/nd/Kconfig b/drivers/block/nd/Kconfig
index c5eaf195734d..15896db4de37 100644
--- a/drivers/block/nd/Kconfig
+++ b/drivers/block/nd/Kconfig
@@ -95,4 +95,7 @@ config BLK_DEV_PMEM
 
  Say Y if you want to use a NVDIMM described by NFIT
 
+config ND_BTT_DEVS
+   def_bool y
+
 endif
diff --git a/drivers/block/nd/Makefile b/drivers/block/nd/Makefile
index d588f691163c..0c6d64b7a69d 100644
--- a/drivers/block/nd/Makefile
+++ b/drivers/block/nd/Makefile
@@ -32,3 +32,4 @@ libnd-y += region_devs.o
 libnd-y += region.o
 libnd-y += namespace_devs.o
 libnd-y += label.o
+libnd-$(CONFIG_ND_BTT_DEVS) += btt_devs.o
diff --git a/drivers/block/nd/btt.h b/drivers/block/nd/btt.h
new file mode 100644
index ..e8f6d8e0ddd3
--- /dev/null
+++ b/drivers/block/nd/btt.h
@@ -0,0 +1,45 @@
+/*
+ * Block Translation Table library
+ * Copyright (c) 2014-2015, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _LINUX_BTT_H
+#define _LINUX_BTT_H
+
+#include linux/types.h
+
+#define BTT_SIG_LEN 16
+#define BTT_SIG BTT_ARENA_INFO\0
+
+struct btt_sb {
+   u8 signature[BTT_SIG_LEN];
+   u8 uuid[16];
+   u8 parent_uuid[16];
+   __le32 flags;
+   __le16 version_major;
+   __le16 version_minor;
+   __le32 external_lbasize;
+   __le32 external_nlba;
+   __le32 internal_lbasize;
+   __le32 internal_nlba;
+   __le32 nfree;
+   __le32 infosize;
+   __le64 nextoff;
+   __le64 dataoff;
+   __le64 mapoff;
+   __le64 logoff;
+   __le64 info2off;
+   u8 padding[3968];
+   __le64 checksum;
+};
+
+#endif
diff --git a/drivers/block/nd/btt_devs.c b/drivers/block/nd/btt_devs.c
new file mode 100644
index ..e6f0b8b999d8
--- /dev/null
+++ b/drivers/block/nd/btt_devs.c
@@ -0,0 +1,442 @@
+/*
+ * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+#include linux/device.h
+#include linux/genhd.h
+#include linux/sizes.h
+#include linux/slab.h
+#include linux/fs.h
+#include linux/mm.h
+#include nd-private.h
+#include btt.h
+#include nd.h
+
+static DEFINE_IDA(btt_ida);
+
+static void nd_btt_release(struct device *dev)
+{
+   struct nd_btt *nd_btt = to_nd_btt(dev);
+
+   dev_dbg(dev, %s\n, __func__);
+   WARN_ON(nd_btt-backing_dev);
+   ndio_del_claim(nd_btt-ndio_claim);
+   ida_simple_remove(btt_ida, nd_btt-id);
+   kfree(nd_btt-uuid);
+   kfree(nd_btt);
+}
+
+static struct device_type nd_btt_device_type = {
+   .name = nd_btt,
+   .release = nd_btt_release,
+};
+
+bool is_nd_btt(struct device *dev)
+{
+   return dev-type == nd_btt_device_type;
+}
+
+struct nd_btt *to_nd_btt(struct device *dev)
+{
+   struct nd_btt *nd_btt = container_of(dev, struct nd_btt, dev);
+
+   WARN_ON(!is_nd_btt(dev));
+   return nd_btt;
+}
+EXPORT_SYMBOL(to_nd_btt);
+
+static