Merging upstream version 4.3+20241108.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
1e24552bfc
commit
60ccb5b596
64 changed files with 2015 additions and 1768 deletions
121
monitor.c
121
monitor.c
|
@ -35,11 +35,6 @@ enum bb_action {
|
|||
COMPARE_BB,
|
||||
};
|
||||
|
||||
static int write_attr(char *attr, int fd)
|
||||
{
|
||||
return write(fd, attr, strlen(attr));
|
||||
}
|
||||
|
||||
static void add_fd(fd_set *fds, int *maxfd, int fd)
|
||||
{
|
||||
struct stat st;
|
||||
|
@ -155,6 +150,8 @@ int read_dev_state(int fd)
|
|||
rv |= DS_SPARE;
|
||||
if (sysfs_attr_match(cp, "blocked"))
|
||||
rv |= DS_BLOCKED;
|
||||
if (sysfs_attr_match(cp, "external_bbl"))
|
||||
rv |= DS_EXTERNAL_BB;
|
||||
cp = strchr(cp, ',');
|
||||
if (cp)
|
||||
cp++;
|
||||
|
@ -173,7 +170,7 @@ int process_ubb(struct active_array *a, struct mdinfo *mdi, const unsigned long
|
|||
* via sysfs file
|
||||
*/
|
||||
if ((ss->record_bad_block(a, mdi->disk.raid_disk, sector, length)) &&
|
||||
(write(mdi->bb_fd, buf, buf_len) == buf_len))
|
||||
(sysfs_write_descriptor(mdi->bb_fd, buf, buf_len, NULL) == MDADM_STATUS_SUCCESS))
|
||||
return 1;
|
||||
|
||||
/*
|
||||
|
@ -311,9 +308,6 @@ static int check_for_cleared_bb(struct active_array *a, struct mdinfo *mdi)
|
|||
struct md_bb *bb;
|
||||
int i;
|
||||
|
||||
if (!ss->get_bad_blocks)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Get a list of bad blocks for an array, then read list of
|
||||
* acknowledged bad blocks from kernel and compare it against metadata
|
||||
|
@ -402,11 +396,12 @@ static void signal_manager(void)
|
|||
|
||||
#define ARRAY_DIRTY 1
|
||||
#define ARRAY_BUSY 2
|
||||
static int read_and_act(struct active_array *a, fd_set *fds)
|
||||
static int read_and_act(struct active_array *a)
|
||||
{
|
||||
unsigned long long sync_completed;
|
||||
int check_degraded = 0;
|
||||
int check_reshape = 0;
|
||||
bool disks_to_remove = false;
|
||||
bool check_degraded = false;
|
||||
bool check_reshape = false;
|
||||
int deactivate = 0;
|
||||
struct mdinfo *mdi;
|
||||
int ret = 0;
|
||||
|
@ -430,23 +425,32 @@ static int read_and_act(struct active_array *a, fd_set *fds)
|
|||
for (mdi = a->info.devs; mdi ; mdi = mdi->next) {
|
||||
mdi->next_state = 0;
|
||||
mdi->curr_state = 0;
|
||||
if (mdi->state_fd >= 0) {
|
||||
read_resync_start(mdi->recovery_fd,
|
||||
&mdi->recovery_start);
|
||||
mdi->curr_state = read_dev_state(mdi->state_fd);
|
||||
}
|
||||
/*
|
||||
* If array is blocked and metadata handler is able to handle
|
||||
* BB, check if you can acknowledge them to md driver. If
|
||||
* successful, clear faulty state and unblock the array.
|
||||
*/
|
||||
if ((mdi->curr_state & DS_BLOCKED) &&
|
||||
a->container->ss->record_bad_block &&
|
||||
(process_dev_ubb(a, mdi) > 0)) {
|
||||
|
||||
if (mdi->man_disk_to_remove)
|
||||
/* We are removing this device, skip it then */
|
||||
continue;
|
||||
|
||||
read_resync_start(mdi->recovery_fd, &mdi->recovery_start);
|
||||
mdi->curr_state = read_dev_state(mdi->state_fd);
|
||||
|
||||
if (!(mdi->curr_state & DS_EXTERNAL_BB))
|
||||
/*
|
||||
* It assumes that superswitch badblock functions are set if disk
|
||||
* has external badblocks support configured.
|
||||
*/
|
||||
continue;
|
||||
|
||||
if ((mdi->curr_state & DS_BLOCKED) && process_dev_ubb(a, mdi) > 0)
|
||||
/*
|
||||
* Blocked has two meanings: we need to acknowledge failure or badblocks
|
||||
* (if supported). Here, badblocks are handled.
|
||||
*
|
||||
* If successful, unblock the array. This is not perfect but
|
||||
* process_dev_ubb() may disable badblock support in case of failure.
|
||||
*/
|
||||
mdi->next_state |= DS_UNBLOCK;
|
||||
}
|
||||
if (FD_ISSET(mdi->bb_fd, fds))
|
||||
check_for_cleared_bb(a, mdi);
|
||||
|
||||
check_for_cleared_bb(a, mdi);
|
||||
}
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
@ -621,24 +625,12 @@ static int read_and_act(struct active_array *a, fd_set *fds)
|
|||
write_attr("-blocked", mdi->state_fd);
|
||||
}
|
||||
|
||||
if ((mdi->next_state & DS_REMOVE) && mdi->state_fd >= 0) {
|
||||
int remove_result;
|
||||
|
||||
/* The kernel may not be able to immediately remove the
|
||||
* disk. In that case we wait a little while and
|
||||
* try again.
|
||||
*/
|
||||
remove_result = write_attr("remove", mdi->state_fd);
|
||||
if (remove_result > 0) {
|
||||
dprintf_cont(" %d:removed", mdi->disk.raid_disk);
|
||||
close(mdi->state_fd);
|
||||
close(mdi->recovery_fd);
|
||||
close(mdi->bb_fd);
|
||||
close(mdi->ubb_fd);
|
||||
mdi->state_fd = -1;
|
||||
} else
|
||||
ret |= ARRAY_BUSY;
|
||||
if ((mdi->next_state & DS_REMOVE) && !mdi->man_disk_to_remove) {
|
||||
dprintf_cont(" %d:disk_to_remove", mdi->disk.raid_disk);
|
||||
mdi->man_disk_to_remove = true;
|
||||
disks_to_remove = true;
|
||||
}
|
||||
|
||||
if (mdi->next_state & DS_INSYNC) {
|
||||
write_attr("+in_sync", mdi->state_fd);
|
||||
dprintf_cont(" %d:+in_sync", mdi->disk.raid_disk);
|
||||
|
@ -651,17 +643,14 @@ static int read_and_act(struct active_array *a, fd_set *fds)
|
|||
|
||||
a->prev_action = a->curr_action;
|
||||
|
||||
for (mdi = a->info.devs; mdi ; mdi = mdi->next) {
|
||||
for (mdi = a->info.devs; mdi ; mdi = mdi->next)
|
||||
mdi->prev_state = mdi->curr_state;
|
||||
mdi->next_state = 0;
|
||||
}
|
||||
|
||||
if (check_degraded || check_reshape) {
|
||||
/* manager will do the actual check */
|
||||
if (check_degraded)
|
||||
a->check_degraded = 1;
|
||||
if (check_reshape)
|
||||
a->check_reshape = 1;
|
||||
if (check_degraded || check_reshape || disks_to_remove) {
|
||||
|
||||
a->check_member_remove |= disks_to_remove;
|
||||
a->check_degraded |= check_degraded;
|
||||
a->check_reshape |= check_reshape;
|
||||
signal_manager();
|
||||
}
|
||||
|
||||
|
@ -734,13 +723,11 @@ int monitor_loop_cnt;
|
|||
|
||||
static int wait_and_act(struct supertype *container, int nowait)
|
||||
{
|
||||
fd_set rfds;
|
||||
int maxfd = 0;
|
||||
struct active_array **aap = &container->arrays;
|
||||
struct active_array *a, **ap;
|
||||
int rv;
|
||||
struct mdinfo *mdi;
|
||||
struct active_array *a, **ap, **aap = &container->arrays;
|
||||
static unsigned int dirty_arrays = ~0; /* start at some non-zero value */
|
||||
struct mdinfo *mdi;
|
||||
int rv, maxfd = 0;
|
||||
fd_set rfds;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
|
||||
|
@ -764,7 +751,18 @@ static int wait_and_act(struct supertype *container, int nowait)
|
|||
add_fd(&rfds, &maxfd, a->info.state_fd);
|
||||
add_fd(&rfds, &maxfd, a->action_fd);
|
||||
add_fd(&rfds, &maxfd, a->sync_completed_fd);
|
||||
|
||||
for (mdi = a->info.devs ; mdi ; mdi = mdi->next) {
|
||||
if (mdi->man_disk_to_remove) {
|
||||
mdi->mon_descriptors_not_used = true;
|
||||
|
||||
/* Managemon could be blocked on suspend in kernel.
|
||||
* Monitor must respond if any badblock is recorded in this time.
|
||||
*/
|
||||
container->retry_soon = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
add_fd(&rfds, &maxfd, mdi->state_fd);
|
||||
add_fd(&rfds, &maxfd, mdi->bb_fd);
|
||||
add_fd(&rfds, &maxfd, mdi->ubb_fd);
|
||||
|
@ -863,7 +861,8 @@ static int wait_and_act(struct supertype *container, int nowait)
|
|||
signal_manager();
|
||||
}
|
||||
if (a->container && !a->to_remove) {
|
||||
int ret = read_and_act(a, &rfds);
|
||||
int ret = read_and_act(a);
|
||||
|
||||
rv |= 1;
|
||||
dirty_arrays += !!(ret & ARRAY_DIRTY);
|
||||
/* when terminating stop manipulating the array after it
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue