linux/drivers/md/md-cluster.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2015, SUSE
 */


#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/dlm.h>
#include <linux/sched.h>
#include <linux/raid/md_p.h>
#include "md.h"
#include "md-bitmap.h"
#include "md-cluster.h"

#define LVB_SIZE
#define NEW_DEV_TIMEOUT
#define WAIT_DLM_LOCK_TIMEOUT

struct dlm_lock_resource {};

struct resync_info {};

/* md_cluster_info flags */
#define MD_CLUSTER_WAITING_FOR_NEWDISK
#define MD_CLUSTER_SUSPEND_READ_BALANCING
#define MD_CLUSTER_BEGIN_JOIN_CLUSTER

/* Lock the send communication. This is done through
 * bit manipulation as opposed to a mutex in order to
 * accommodate lock and hold. See next comment.
 */
#define MD_CLUSTER_SEND_LOCK
/* If cluster operations (such as adding a disk) must lock the
 * communication channel, so as to perform extra operations
 * (update metadata) and no other operation is allowed on the
 * MD. Token needs to be locked and held until the operation
 * completes witha md_update_sb(), which would eventually release
 * the lock.
 */
#define MD_CLUSTER_SEND_LOCKED_ALREADY
/* We should receive message after node joined cluster and
 * set up all the related infos such as bitmap and personality */
#define MD_CLUSTER_ALREADY_IN_CLUSTER
#define MD_CLUSTER_PENDING_RECV_EVENT
#define MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD
#define MD_CLUSTER_WAITING_FOR_SYNC

struct md_cluster_info {};

/* For compatibility, add the new msg_type at the end. */
enum msg_type {};

struct cluster_msg {};

static void sync_ast(void *arg)
{}

static int dlm_lock_sync(struct dlm_lock_resource *res, int mode)
{}

static int dlm_unlock_sync(struct dlm_lock_resource *res)
{}

/*
 * An variation of dlm_lock_sync, which make lock request could
 * be interrupted
 */
static int dlm_lock_sync_interruptible(struct dlm_lock_resource *res, int mode,
				       struct mddev *mddev)
{}

static struct dlm_lock_resource *lockres_init(struct mddev *mddev,
		char *name, void (*bastfn)(void *arg, int mode), int with_lvb)
{}

static void lockres_free(struct dlm_lock_resource *res)
{}

static void add_resync_info(struct dlm_lock_resource *lockres,
			    sector_t lo, sector_t hi)
{}

static int read_resync_info(struct mddev *mddev,
			    struct dlm_lock_resource *lockres)
{}

static void recover_bitmaps(struct md_thread *thread)
{}

static void recover_prep(void *arg)
{}

static void __recover_slot(struct mddev *mddev, int slot)
{}

static void recover_slot(void *arg, struct dlm_slot *slot)
{}

static void recover_done(void *arg, struct dlm_slot *slots,
		int num_slots, int our_slot,
		uint32_t generation)
{}

/* the ops is called when node join the cluster, and do lock recovery
 * if node failure occurs */
static const struct dlm_lockspace_ops md_ls_ops =;

/*
 * The BAST function for the ack lock resource
 * This function wakes up the receive thread in
 * order to receive and process the message.
 */
static void ack_bast(void *arg, int mode)
{}

static void remove_suspend_info(struct mddev *mddev, int slot)
{}

static void process_suspend_info(struct mddev *mddev,
		int slot, sector_t lo, sector_t hi)
{}

static int process_add_new_disk(struct mddev *mddev, struct cluster_msg *cmsg)
{}


static void process_metadata_update(struct mddev *mddev, struct cluster_msg *msg)
{}

static void process_remove_disk(struct mddev *mddev, struct cluster_msg *msg)
{}

static void process_readd_disk(struct mddev *mddev, struct cluster_msg *msg)
{}

static int process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg)
{}

/*
 * thread for receiving message
 */
static void recv_daemon(struct md_thread *thread)
{}

/* lock_token()
 * Takes the lock on the TOKEN lock resource so no other
 * node can communicate while the operation is underway.
 */
static int lock_token(struct md_cluster_info *cinfo)
{}

/* lock_comm()
 * Sets the MD_CLUSTER_SEND_LOCK bit to lock the send channel.
 */
static int lock_comm(struct md_cluster_info *cinfo, bool mddev_locked)
{}

static void unlock_comm(struct md_cluster_info *cinfo)
{}

/* __sendmsg()
 * This function performs the actual sending of the message. This function is
 * usually called after performing the encompassing operation
 * The function:
 * 1. Grabs the message lockresource in EX mode
 * 2. Copies the message to the message LVB
 * 3. Downconverts message lockresource to CW
 * 4. Upconverts ack lock resource from CR to EX. This forces the BAST on other nodes
 *    and the other nodes read the message. The thread will wait here until all other
 *    nodes have released ack lock resource.
 * 5. Downconvert ack lockresource to CR
 */
static int __sendmsg(struct md_cluster_info *cinfo, struct cluster_msg *cmsg)
{}

static int sendmsg(struct md_cluster_info *cinfo, struct cluster_msg *cmsg,
		   bool mddev_locked)
{}

static int gather_all_resync_info(struct mddev *mddev, int total_slots)
{}

static int join(struct mddev *mddev, int nodes)
{}

static void load_bitmaps(struct mddev *mddev, int total_slots)
{}

static void resync_bitmap(struct mddev *mddev)
{}

static void unlock_all_bitmaps(struct mddev *mddev);
static int leave(struct mddev *mddev)
{}

/* slot_number(): Returns the MD slot number to use
 * DLM starts the slot numbers from 1, wheras cluster-md
 * wants the number to be from zero, so we deduct one
 */
static int slot_number(struct mddev *mddev)
{}

/*
 * Check if the communication is already locked, else lock the communication
 * channel.
 * If it is already locked, token is in EX mode, and hence lock_token()
 * should not be called.
 */
static int metadata_update_start(struct mddev *mddev)
{}

static int metadata_update_finish(struct mddev *mddev)
{}

static void metadata_update_cancel(struct mddev *mddev)
{}

static int update_bitmap_size(struct mddev *mddev, sector_t size)
{}

static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsize)
{}

/*
 * return 0 if all the bitmaps have the same sync_size
 */
static int cluster_check_sync_size(struct mddev *mddev)
{}

/*
 * Update the size for cluster raid is a little more complex, we perform it
 * by the steps:
 * 1. hold token lock and update superblock in initiator node.
 * 2. send METADATA_UPDATED msg to other nodes.
 * 3. The initiator node continues to check each bitmap's sync_size, if all
 *    bitmaps have the same value of sync_size, then we can set capacity and
 *    let other nodes to perform it. If one node can't update sync_size
 *    accordingly, we need to revert to previous value.
 */
static void update_size(struct mddev *mddev, sector_t old_dev_sectors)
{}

static int resync_start(struct mddev *mddev)
{}

static void resync_info_get(struct mddev *mddev, sector_t *lo, sector_t *hi)
{}

static int resync_status_get(struct mddev *mddev)
{}

static int resync_start_notify(struct mddev *mddev)
{}

static int resync_info_update(struct mddev *mddev, sector_t lo, sector_t hi)
{}

static int resync_finish(struct mddev *mddev)
{}

static int area_resyncing(struct mddev *mddev, int direction,
		sector_t lo, sector_t hi)
{}

/* add_new_disk() - initiates a disk add
 * However, if this fails before writing md_update_sb(),
 * add_new_disk_cancel() must be called to release token lock
 */
static int add_new_disk(struct mddev *mddev, struct md_rdev *rdev)
{}

static void add_new_disk_cancel(struct mddev *mddev)
{}

static int new_disk_ack(struct mddev *mddev, bool ack)
{}

static int remove_disk(struct mddev *mddev, struct md_rdev *rdev)
{}

static int lock_all_bitmaps(struct mddev *mddev)
{}

static void unlock_all_bitmaps(struct mddev *mddev)
{}

static int gather_bitmaps(struct md_rdev *rdev)
{}

static const struct md_cluster_operations cluster_ops =;

static int __init cluster_init(void)
{}

static void cluster_exit(void)
{}

module_init();
module_exit(cluster_exit);
MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_DESCRIPTION();