/*
 * Copyright 2010-2011 Red Hat, Inc.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU General Public License v2 or (at your option) any later version.
 */

#ifndef __LEADER_H__
#define __LEADER_H__

/* does not include terminating null byte */
/* NB NAME_ID_SIZE must match SANLK_NAME_LEN */
/* NB NAME_ID_SIZE is part of ondisk format */

#define NAME_ID_SIZE 48

/*
 * paxos version changes:
 * 6.4: add ALIGN leader flags
 * 7.0: add CAW leader flag
 *      breaks compat with older versions, because compare-and-write
 *      only works correctly when all hosts use it to write leader.
 *
 * delta version changes:
 * 3.4: add ALIGN leader flags
 * 4.0: add NO_TIMEOUT and DEAD_EXT leader flags
 *      breaks compat with older versions, because they would take
 *      a NO_TIMEOUT lease after dead timeout when they shouldn't.
 * 5.0: add CAW leader flag
 *      breaks compat with older versions, because compare-and-write
 *      only works correctly when all hosts use it to write leader.
 */

#define PAXOS_DISK_MAGIC 0x06152010
#define PAXOS_DISK_CLEAR 0x11282016
#define PAXOS_DISK_VERSION_MAJOR 0x00070000
#define PAXOS_DISK_VERSION_MINOR 0x00000000

/* 6.4 does not support CAW leader flag. */
# define PAXOS_DISK_VERSION_64 0x00060004

#define DELTA_DISK_MAGIC 0x12212010
#define DELTA_DISK_VERSION_MAJOR 0x00050000
#define DELTA_DISK_VERSION_MINOR 0x00000000

/* 3.4 does not support NO_TIMEOUT leader flag. */
#define DELTA_DISK_VERSION_34 0x00030004

/* 4.0 does not support CAW leader flag. */
#define DELTA_DISK_VERSION_40 0x00040000

/* for all disk structures:
   uint64 aligned on 8 byte boundaries,
   uint32 aligned on 4 byte boundaries, etc */

/* NB. adjust LEADER_COMPARE_LEN and LEADER_CHECKSUM_LEN when changing
   this struct.
   LEADER_CHECKSUM_LEN should end just before the checksum field.
   LEADER_COMPARE_LEN should end just before timestamp.
   The checksum field should follow the timestamp field.

   The leader may be partially through updating the timestamp on
   multiple leader blocks in a lease, but for the purpose of counting
   repetitions of a leader block owned by a single host they should be
   counted together, so COMPARE_LEN should exclude timestamp. */

#define LEADER_COMPARE_LEN 152
#define LEADER_CHECKSUM_LEN 168
#define LEASE_FREE 0

/* leader_record flags */
#define LFL_SHORT_HOLD 0x00000001
#define LFL_NO_TIMEOUT 0x00000002
#define LFL_DEAD_EXT   0x00000004
#define LFL_CAW        0x00000008
/* note: these align flag values match other defines */
#define LFL_ALIGN_1M   0x00000010
#define LFL_ALIGN_2M   0x00000020
#define LFL_ALIGN_4M   0x00000040
#define LFL_ALIGN_8M   0x00000080

struct leader_record {
	uint32_t magic;
	uint32_t version;
	uint32_t flags;
	uint32_t sector_size;
	uint64_t num_hosts;
	uint64_t max_hosts;
	uint64_t owner_id; /* host_id of owner */
	uint64_t owner_generation;
	uint64_t lver;
	char space_name[NAME_ID_SIZE] __attribute__ ((nonstring)); /* lockspace for resource */
	char resource_name[NAME_ID_SIZE] __attribute__ ((nonstring)); /* resource being locked */
	uint64_t timestamp;
	uint64_t unused1;
	uint32_t checksum;
	uint16_t unused2;
	uint16_t io_timeout;
	uint64_t write_id;		/* for extra info, debug */
	uint64_t write_generation;	/* for extra info, debug */
	uint64_t write_timestamp;	/* for extra info, debug */
};

/* leader_record can use first 256 bytes of a sector,
   bitmap uses the last 256 bytes */

#define LEADER_RECORD_MAX 256
#define HOSTID_BITMAP_OFFSET 256
#define HOSTID_BITMAP_SIZE 256

/* the request record is in the sector following the leader record
   for a paxos lease. */

#define REQ_DISK_MAGIC 0x08292011
#define REQ_DISK_VERSION_MAJOR 0x00010000
#define REQ_DISK_VERSION_MINOR 0x00000001

struct request_record {
	uint32_t magic;
	uint32_t version;
	uint64_t lver;
	uint32_t force_mode;
};

#endif
