// SPDX-License-Identifier: GPL-2.0
/*
* Bad block management
*
* - Heavily based on MD badblocks code from Neil Brown
*
* Copyright (c) 2015, Intel Corporation.
*/
#include <linux/badblocks.h>
#include <linux/seqlock.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/stddef.h>
#include <linux/types.h>
#include <linux/slab.h>
/*
* The purpose of badblocks set/clear is to manage bad blocks ranges which are
* identified by LBA addresses.
*
* When the caller of badblocks_set() wants to set a range of bad blocks, the
* setting range can be acked or unacked. And the setting range may merge,
* overwrite, skip the overlapped already set range, depends on who they are
* overlapped or adjacent, and the acknowledgment type of the ranges. It can be
* more complicated when the setting range covers multiple already set bad block
* ranges, with restrictions of maximum length of each bad range and the bad
* table space limitation.
*
* It is difficult and unnecessary to take care of all the possible situations,
* for setting a large range of bad blocks, we can handle it by dividing the
* large range into smaller ones when encounter overlap, max range length or
* bad table full conditions. Every time only a smaller piece of the bad range
* is handled with a limited number of conditions how it is interacted with
* possible overlapped or adjacent already set bad block ranges. Then the hard
* complicated problem can be much simpler to handle in proper way.