/*
 * tools/lib/lv_check_consistency.c
 *
 * Copyright (C) 1997 - 2000  Heinz Mauelshagen, Sistina Software
 *
 * March 1997
 * December 1998
 * July 1999
 * January 2000
 *
 *
 * This LVM library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This LVM library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this LVM library; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA
 *
 */

/*
 * Changelog
 *
 *   20/12/1998 - checked for correct LV number lv lv_check_consistency_all_lv()
 *   30/07/1999 - added snapshot logical volume support
 *   31/01/2000 - use debug_enter()/debug_leave()
 *
 */

#include <liblvm.h>

int lv_check_consistency ( lv_t *lv) {
   int ret = 0;

   debug_enter ( "lv_check_consistency -- CALLED\n");

   /* Don't barf on broken LVM1.1 created metadata */
   if (lv->lv_status > 2) lv->lv_status = 1;

   if ( lv == NULL)                                   ret = -LVM_EPARAM;
   else if ( lv_check_name ( lv->lv_name) != 0)       ret = -LVM_ELV_LVNAME;
   else if ( vg_check_name ( lv->vg_name) != 0)       ret = -LVM_ELV_VGNAME;
   else if ( lv->lv_access != LV_READ &&
             lv->lv_access != ( LV_READ | LV_WRITE) &&
             lv->lv_access != ( LV_READ | LV_SNAPSHOT) &&
             lv->lv_access != ( LV_READ | LV_WRITE | LV_SNAPSHOT) &&
             lv->lv_access != ( LV_READ | LV_SNAPSHOT_ORG) &&
             lv->lv_access != ( LV_READ | LV_WRITE | LV_SNAPSHOT_ORG))
                                                      ret = -LVM_ELV_ACCESS;
   else if ( lv->lv_status != LV_ACTIVE &&
             lv->lv_status != 0)                      ret = -LVM_ELV_STATUS;
   else if ( lv->lv_open > MAX_LV)                    ret = -LVM_ELV_OPEN;
   else if ( lv->lv_mirror_copies > LVM_MAX_MIRRORS)  ret = -LVM_ELV_MIRROR_COPIES;
   else if ( lv->lv_recovery != 0 &&
             lv->lv_recovery != LV_BADBLOCK_ON)       ret = -LVM_ELV_RECOVERY;

   else if ( lv->lv_schedule != 0)                    ret = -LVM_ELV_SCHEDULE;
/*
   else if ( lv->lv_size > LVM_MAX_SIZE)              ret = -LVM_ELV_SIZE;
   else if ( lv->lv_current_le > LVM_MAX_SIZE / LVM_MIN_PE_SIZE)
                                                      ret = -LVM_ELV_CURRENT_LE;
*/
   else if ( lv->lv_allocated_le > lv->lv_current_le) ret = -LVM_ELV_ALLOCATED_LE;
   else if ( lv->lv_stripes > MAX_PV)                 ret = -LVM_ELV_STRIPES;
   else if ( lv->lv_stripesize != 0 && 
             lv->lv_stripesize < LVM_MIN_STRIPE_SIZE &&
             lv->lv_stripesize > LVM_MAX_STRIPE_SIZE) ret = -LVM_ELV_STRIPESIZE;
   else if ( lv->lv_badblock != 0 && lv->lv_badblock != LV_BADBLOCK_ON)
                                                      ret = -LVM_ELV_BADBLOCK;
   else if ( lv->lv_allocation != 0 &&
             lv->lv_allocation != LV_STRICT &&
             lv->lv_allocation != LV_CONTIGUOUS &&
             lv->lv_allocation != ( LV_STRICT | LV_CONTIGUOUS))
                                                      ret = -LVM_ELV_ALLOCATION;
   else if ( lv->lv_io_timeout > LVM_MAX_LV_IO_TIMEOUT)
                                                      ret = -LVM_ELV_TIMEOUT;

   debug_leave ( "lv_check_consistency -- LEAVING with ret: %d\n", ret);
   return ret;
}


int lv_check_consistency_all_lv ( vg_t *vg) {
   int l = 0;
   int ret = 0;

   debug_enter ( "lv_check_consistency_all_lv -- CALLED vg->lv_max: %lu\n",
           vg->lv_max);

   if ( vg == NULL) ret = -LVM_EPARAM;
   else {
      for ( l = 0; l < vg->lv_max; l++) {
         debug ( "lv_check_consistency_all_lv -- vg->lv[%d]: %X  name: %s\n",
                  l, ( uint) vg->lv[l], vg->lv[l]->lv_name);
         if ( vg->lv[l] != NULL) {
            if ( ( ret = lv_check_consistency ( vg->lv[l])) < 0) break;
            if ( vg->lv[l]->lv_number != l) {
               ret = -LVM_ELV_NUMBER;
               break;
            }
         }
      }
   }

   debug_leave ( "lv_check_consistency_all_lv -- LEAVING with ret: %d\n", ret);
   return ret;
}
