"Fossies" - the Fresh Open Source Software archive

Member "evms-2.5.5/plugins/bbr/bbr.h" of archive evms-2.5.5.tar.gz:


/*
 *
 *   (C) Copyright IBM Corp. 2001, 2003
 *
 *   This program is free software;  you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 *   the GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program;  if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 *   Module: bbr.h
 *
 */

#ifndef BAD_BLOCK_RELOCATION_HEADER
#define BAD_BLOCK_RELOCATION_HEADER

#define EVMS_BBR_VERSION_MAJOR            1
#define EVMS_BBR_VERSION_MINOR            0
#define EVMS_BBR_VERSION_PATCHLEVEL       0

#define EVMS_BBR_SIGNATURE        0x42627246   /* BbrF */

/* The following defines establish the minimum and maximum number of
 * replacement sectors which can be allocated for Bad Block Relocation.
 * Otherwise, 1 replacement sector per MB of disk space is allocated. */
#define EVMS_BBR_ENTRIES_PER_SECT    31 /* Assume sector size is 512 bytes*/
#define EVMS_BBR_LIMIT  4096

#define EVMS_BBR_TABLE_SIGNATURE         0x42627254 /* BbrT */

typedef struct evms_bbr_table_entry {
    u_int64_t bad_sect;
    u_int64_t replacement_sect;
} evms_bbr_table_entry_t;

typedef struct evms_bbr_table {
    u_int32_t signature;                /* Signature for a sector of the bbr table (EVMS_BBR_TABLE_SIGNATURE) */
    u_int32_t crc;                      /* CRC for this sector of the BBR Table. */
    u_int32_t sequence_number;          /* Used to resolve conflicts when the primary and secondary tables do not match. */
    u_int32_t in_use_cnt;               /* number of in-use entries */
    evms_bbr_table_entry_t entries[EVMS_BBR_ENTRIES_PER_SECT];   /* BBR table entries available for this sector of the BBR table */
} evms_bbr_table_t;

/* description of on disk meta data sector for bbr feature */
typedef struct evms_bbr_metadata {
/* 0*/        u_int32_t signature;                /* EVMS_BBR_SIGNATURE */
/* 4*/        u_int32_t crc;
/* 8*/        u_int32_t block_size;               /* block size in bytes */
/*12*/        u_int32_t flags;                    /* Global flag used by BBR */
/*16*/        u_int64_t sequence_number;
/*24*/        u_int64_t start_sect_bbr_table;     /* start 64-bit LBA of the BBR table */
/*32*/        u_int64_t nr_sects_bbr_table;       /* number of sectors to hold the BBR table */
/*40*/        u_int64_t start_replacement_sect;   /* start 64-bit LBA of the replacement sectors */
/*48*/        u_int64_t nr_replacement_blks;      /* number of replacement blocks. */
/*56*/        char      pads[456];                /* padding for 512-byte sector alignment */
} evms_bbr_metadata_t;


// BBR direct ioctl commands.
#define BBR_GET_INFO_CMD	1	// Return the total number of sectors
					// that are currently remapped for the
					// bbr object.
#define BBR_STOP_REMAP_CMD	2	// Stop ... do not remap any new sectors
					// or even honor any existing remaps for
					// the bbr object until after the next
					// rediscover command is received.
//#define BBR_SECTOR_IO_CMD	3	// Process an I/O from the engine directly
//					// through the bbr object.

#define SECTOR_IO_READ	0
#define SECTOR_IO_WRITE	1

typedef struct evms_notify_bbr {
	char		object_name[EVMS_VOLUME_NAME_SIZE+1];	// Input  - Name of bbr object from feature header
	uint64_t	count;		// Output - Count of remapped sectors
	uint64_t	start_sect;	// Input - Starting sector for sector_io
	uint64_t	nr_sect;	// Input - Number of sectors for sector_io
	uint8_t *	buffer;		// Input - Pointer to buffer for sector_io
	int32_t		rw;		// Input - READ or WRITE for sector_io
} evms_notify_bbr_t;


extern plugin_record_t             *my_plugin_record;
extern struct engine_functions_s   *EngFncs;


// need an object that is exactly 1 sector in size;
typedef struct vsector_s {
    char  one_sector[EVMS_VSECTOR_SIZE];
} vsector_t;


// macro to pull the BBR child object ptr from the BBR private data area
#define GET_BBR_CHILD( bbrobject ) ((BBR_Private_Data *)bbrobject->private_data)->child

// minimum number of replacement blocks to use for a partition (roughly 2 tracks)
#define BBR_MIN_REPLACEMENT_BLOCKS  128  // but rounded up to an 8k multiple for systems with a
                                         // variable hard sector size

// maximum number of replacement blocks to use for a partition (roughly 2 cylinders)
#define BBR_MAX_REPLACEMENT_BLOCKS  2048  // rounded up to an 8k multiple


// BBR storage object private data area
typedef struct _bbr_pdata {

    // private data can be verified by this signature
    u_int32_t                   signature;

    // child object that we consumed
    storage_object_t           *child;

    // Feature Header information
    u_int64_t                   feature_header_data1_size;
    u_int64_t                   feature_header_data2_size;
    u_int64_t                   feature_header_data1_start_lsn;
    u_int64_t                   feature_header_data2_start_lsn;
    char                        feature_header_object_name[EVMS_VOLUME_NAME_SIZE];

    // Replacement Blocks information
    u_int64_t                   replacement_blocks_lsn;
    u_int64_t                   replacement_blocks_needed;
    u_int64_t                   replacement_blocks_size_in_sectors;

    // BBR Table information
    u_int64_t                   bbr_table_lsn1;
    u_int64_t                   bbr_table_lsn2;
    u_int64_t                   bbr_table_size_in_sectors;
    evms_bbr_table_t           *bbr_table;

    // feature data information
    u_int64_t                   sequence_number;

    // Block size
    u_int32_t                   block_size;

    // for expand, move, shrink ... previous metadata info
    u_int64_t                   active_replacement_blocks_lsn;
    u_int64_t                   active_replacement_blocks_needed;
    u_int64_t                   active_bbr_table_lsn1;
    u_int64_t                   active_bbr_table_lsn2;
    u_int64_t                   active_bbr_table_size_in_sectors;
    evms_bbr_table_t           *active_bbr_table;

    // flag to tell commit code to move replacement blocks
    boolean                     repl_blocks_moved;

} BBR_Private_Data;


/*
 *  Returns the specified LSN rounded up to a device sector boundary
 */
static inline lsn_t  roundup_to_hardsect_boundary( storage_object_t *obj, lsn_t lsn )
{
        int vsects_per_hardsect;
        lsn_t hardsector_alligned_lsn = lsn;

        if (obj) {

                vsects_per_hardsect = obj->geometry.bytes_per_sector >> EVMS_VSECTOR_SIZE_SHIFT;

                if ((lsn+obj->start) % vsects_per_hardsect) {
                        hardsector_alligned_lsn = lsn -
                                                  ((lsn+obj->start) % vsects_per_hardsect) +
                                                  vsects_per_hardsect;
                }

        }

        return  hardsector_alligned_lsn;
}


/*
 *  Returns the specified LSN rounded down to a device sector boundary
 */
static inline lsn_t  rounddown_to_hardsect_boundary( storage_object_t *obj, lsn_t lsn )
{
        int vsects_per_hardsect;
        lsn_t hardsector_alligned_lsn = lsn;

        if (obj) {

                vsects_per_hardsect = obj->geometry.bytes_per_sector >> EVMS_VSECTOR_SIZE_SHIFT;

                if ((lsn+obj->start) % vsects_per_hardsect) {
                        hardsector_alligned_lsn -= (lsn+obj->start) % vsects_per_hardsect;
                }

        }

        return  hardsector_alligned_lsn;
}


// EVMS functions exported by the BBR shared object
int             get_bbr_disk_info( storage_object_t *child, geometry_t *geometry );
int             PluginInit( plugin_record_t *pPlugRec );
void            PluginCleanup( plugin_record_t *pPlugRec);



#endif