Merge tag 'libnvdimm-for-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull libnvdimm updates from Dan Williams: "The bulk of this has appeared in -next and independently received a build success notification from the kbuild robot. The 'for-4.5/block- dax' topic branch was rebased over the weekend to drop the "block device end-of-life" rework that Al would like to see re-implemented with a notifier, and to address bug reports against the badblocks integration. There is pending feedback against "libnvdimm: Add a poison list and export badblocks" received last week. Linda identified some localized fixups that we will handle incrementally. Summary: - Media error handling: The 'badblocks' implementation that originated in md-raid is up-levelled to a generic capability of a block device. This initial implementation is limited to being consulted in the pmem block-i/o path. Later, 'badblocks' will be consulted when creating dax mappings. - Raw block device dax: For virtualization and other cases that want large contiguous mappings of persistent memory, add the capability to dax-mmap a block device directly. - Increased /dev/mem restrictions: Add an option to treat all io-memory as IORESOURCE_EXCLUSIVE, i.e. disable /dev/mem access while a driver is actively using an address range. This behavior is controlled via the new CONFIG_IO_STRICT_DEVMEM option and can be overridden by the existing "iomem=relaxed" kernel command line option. - Miscellaneous fixes include a 'pfn'-device huge page alignment fix, block device shutdown crash fix, and other small libnvdimm fixes" * tag 'libnvdimm-for-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: (32 commits) block: kill disk_{check|set|clear|alloc}_badblocks libnvdimm, pmem: nvdimm_read_bytes() badblocks support pmem, dax: disable dax in the presence of bad blocks pmem: fail io-requests to known bad blocks libnvdimm: convert to statically allocated badblocks libnvdimm: don't fail init for full badblocks list block, badblocks: introduce devm_init_badblocks block: clarify badblocks lifetime badblocks: rename badblocks_free to badblocks_exit libnvdimm, pmem: move definition of nvdimm_namespace_add_poison to nd.h libnvdimm: Add a poison list and export badblocks nfit_test: Enable DSMs for all test NFITs md: convert to use the generic badblocks code block: Add badblock management for gendisks badblocks: Add core badblock management code block: fix del_gendisk() vs blkdev_ioctl crash block: enable dax for raw block devices block: introduce bdev_file_inode() restrict /dev/mem to idle io memory ranges arch: consolidate CONFIG_STRICT_DEVM in lib/Kconfig.debug ...
This commit is contained in:
65
include/linux/badblocks.h
Normal file
65
include/linux/badblocks.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef _LINUX_BADBLOCKS_H
|
||||
#define _LINUX_BADBLOCKS_H
|
||||
|
||||
#include <linux/seqlock.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define BB_LEN_MASK (0x00000000000001FFULL)
|
||||
#define BB_OFFSET_MASK (0x7FFFFFFFFFFFFE00ULL)
|
||||
#define BB_ACK_MASK (0x8000000000000000ULL)
|
||||
#define BB_MAX_LEN 512
|
||||
#define BB_OFFSET(x) (((x) & BB_OFFSET_MASK) >> 9)
|
||||
#define BB_LEN(x) (((x) & BB_LEN_MASK) + 1)
|
||||
#define BB_ACK(x) (!!((x) & BB_ACK_MASK))
|
||||
#define BB_MAKE(a, l, ack) (((a)<<9) | ((l)-1) | ((u64)(!!(ack)) << 63))
|
||||
|
||||
/* Bad block numbers are stored sorted in a single page.
|
||||
* 64bits is used for each block or extent.
|
||||
* 54 bits are sector number, 9 bits are extent size,
|
||||
* 1 bit is an 'acknowledged' flag.
|
||||
*/
|
||||
#define MAX_BADBLOCKS (PAGE_SIZE/8)
|
||||
|
||||
struct badblocks {
|
||||
struct device *dev; /* set by devm_init_badblocks */
|
||||
int count; /* count of bad blocks */
|
||||
int unacked_exist; /* there probably are unacknowledged
|
||||
* bad blocks. This is only cleared
|
||||
* when a read discovers none
|
||||
*/
|
||||
int shift; /* shift from sectors to block size
|
||||
* a -ve shift means badblocks are
|
||||
* disabled.*/
|
||||
u64 *page; /* badblock list */
|
||||
int changed;
|
||||
seqlock_t lock;
|
||||
sector_t sector;
|
||||
sector_t size; /* in sectors */
|
||||
};
|
||||
|
||||
int badblocks_check(struct badblocks *bb, sector_t s, int sectors,
|
||||
sector_t *first_bad, int *bad_sectors);
|
||||
int badblocks_set(struct badblocks *bb, sector_t s, int sectors,
|
||||
int acknowledged);
|
||||
int badblocks_clear(struct badblocks *bb, sector_t s, int sectors);
|
||||
void ack_all_badblocks(struct badblocks *bb);
|
||||
ssize_t badblocks_show(struct badblocks *bb, char *page, int unack);
|
||||
ssize_t badblocks_store(struct badblocks *bb, const char *page, size_t len,
|
||||
int unack);
|
||||
int badblocks_init(struct badblocks *bb, int enable);
|
||||
void badblocks_exit(struct badblocks *bb);
|
||||
struct device;
|
||||
int devm_init_badblocks(struct device *dev, struct badblocks *bb);
|
||||
static inline void devm_exit_badblocks(struct device *dev, struct badblocks *bb)
|
||||
{
|
||||
if (bb->dev != dev) {
|
||||
dev_WARN_ONCE(dev, 1, "%s: badblocks instance not associated\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
badblocks_exit(bb);
|
||||
}
|
||||
#endif
|
@@ -483,6 +483,9 @@ struct block_device {
|
||||
int bd_fsfreeze_count;
|
||||
/* Mutex for freeze */
|
||||
struct mutex bd_fsfreeze_mutex;
|
||||
#ifdef CONFIG_FS_DAX
|
||||
int bd_map_count;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -2280,6 +2283,14 @@ extern struct super_block *freeze_bdev(struct block_device *);
|
||||
extern void emergency_thaw_all(void);
|
||||
extern int thaw_bdev(struct block_device *bdev, struct super_block *sb);
|
||||
extern int fsync_bdev(struct block_device *);
|
||||
#ifdef CONFIG_FS_DAX
|
||||
extern bool blkdev_dax_capable(struct block_device *bdev);
|
||||
#else
|
||||
static inline bool blkdev_dax_capable(struct block_device *bdev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern struct super_block *blockdev_superblock;
|
||||
|
||||
|
@@ -162,6 +162,7 @@ struct disk_part_tbl {
|
||||
};
|
||||
|
||||
struct disk_events;
|
||||
struct badblocks;
|
||||
|
||||
#if defined(CONFIG_BLK_DEV_INTEGRITY)
|
||||
|
||||
@@ -213,6 +214,7 @@ struct gendisk {
|
||||
struct kobject integrity_kobj;
|
||||
#endif /* CONFIG_BLK_DEV_INTEGRITY */
|
||||
int node_id;
|
||||
struct badblocks *bb;
|
||||
};
|
||||
|
||||
static inline struct gendisk *part_to_disk(struct hd_struct *part)
|
||||
|
@@ -116,6 +116,7 @@ static inline struct nd_blk_region_desc *to_blk_region_desc(
|
||||
|
||||
}
|
||||
|
||||
int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length);
|
||||
struct nvdimm_bus *__nvdimm_bus_register(struct device *parent,
|
||||
struct nvdimm_bus_descriptor *nfit_desc, struct module *module);
|
||||
#define nvdimm_bus_register(parent, desc) \
|
||||
|
Reference in New Issue
Block a user