Blame source/uds/volumeStore.c

Packit Service 310c69
/*
Packit Service 310c69
 * Copyright (c) 2020 Red Hat, Inc.
Packit Service 310c69
 *
Packit Service 310c69
 * This program is free software; you can redistribute it and/or
Packit Service 310c69
 * modify it under the terms of the GNU General Public License
Packit Service 310c69
 * as published by the Free Software Foundation; either version 2
Packit Service 310c69
 * of the License, or (at your option) any later version.
Packit Service 310c69
 * 
Packit Service 310c69
 * This program is distributed in the hope that it will be useful,
Packit Service 310c69
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 310c69
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 310c69
 * GNU General Public License for more details.
Packit Service 310c69
 * 
Packit Service 310c69
 * You should have received a copy of the GNU General Public License
Packit Service 310c69
 * along with this program; if not, write to the Free Software
Packit Service 310c69
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 310c69
 * 02110-1301, USA. 
Packit Service 310c69
 *
Packit Service 310c69
 * $Id: //eng/uds-releases/jasper/src/uds/volumeStore.c#2 $
Packit Service 310c69
 */
Packit Service 310c69
Packit Service 310c69
#include "geometry.h"
Packit Service 310c69
#include "indexLayout.h"
Packit Service 310c69
#include "logger.h"
Packit Service 310c69
#include "uds-error.h"
Packit Service 310c69
#include "volumeStore.h"
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
void closeVolumeStore(struct volume_store *volumeStore)
Packit Service 310c69
{
Packit Service 310c69
#ifdef __KERNEL__
Packit Service 310c69
  if (volumeStore->vs_client != NULL) {
Packit Service 310c69
    dm_bufio_client_destroy(volumeStore->vs_client);
Packit Service 310c69
    volumeStore->vs_client = NULL;
Packit Service 310c69
  }
Packit Service 310c69
#else
Packit Service 310c69
  if (volumeStore->vs_region != NULL) {
Packit Service 310c69
    putIORegion(volumeStore->vs_region);
Packit Service 310c69
    volumeStore->vs_region = NULL;
Packit Service 310c69
  }
Packit Service 310c69
#endif
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
void destroyVolumePage(struct volume_page *volumePage)
Packit Service 310c69
{
Packit Service 310c69
#ifdef __KERNEL__
Packit Service 310c69
  releaseVolumePage(volumePage);
Packit Service 310c69
#else
Packit Service 310c69
  FREE(volumePage->vp_data);
Packit Service 310c69
  volumePage->vp_data = NULL;
Packit Service 310c69
#endif
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
int initializeVolumePage(const struct geometry *geometry,
Packit Service 310c69
                         struct volume_page    *volumePage)
Packit Service 310c69
{
Packit Service 310c69
#ifdef __KERNEL__
Packit Service 310c69
  volumePage->vp_buffer = NULL;
Packit Service 310c69
  return UDS_SUCCESS;
Packit Service 310c69
#else
Packit Service 310c69
  return ALLOCATE_IO_ALIGNED(geometry->bytesPerPage, byte, __func__,
Packit Service 310c69
                             &volumePage->vp_data);
Packit Service 310c69
#endif
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
int openVolumeStore(struct volume_store *volumeStore,
Packit Service 310c69
                    IndexLayout  *layout,
Packit Service 310c69
                    unsigned int  reservedBuffers __attribute__((unused)),
Packit Service 310c69
                    size_t        bytesPerPage)
Packit Service 310c69
{
Packit Service 310c69
#ifdef __KERNEL__
Packit Service 310c69
  return openVolumeBufio(layout, bytesPerPage, reservedBuffers,
Packit Service 310c69
                         &volumeStore->vs_client);
Packit Service 310c69
#else
Packit Service 310c69
  volumeStore->vs_bytesPerPage = bytesPerPage;
Packit Service 310c69
  return openVolumeRegion(layout, &volumeStore->vs_region);
Packit Service 310c69
#endif
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
void prefetchVolumePages(const struct volume_store *vs __attribute__((unused)),
Packit Service 310c69
                         unsigned int physicalPage __attribute__((unused)),
Packit Service 310c69
                         unsigned int pageCount __attribute__((unused)))
Packit Service 310c69
{
Packit Service 310c69
#ifdef __KERNEL__
Packit Service 310c69
  dm_bufio_prefetch(vs->vs_client, physicalPage, pageCount);
Packit Service 310c69
#else
Packit Service 310c69
  // Nothing to do in user mode
Packit Service 310c69
#endif
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
int prepareToWriteVolumePage(const struct volume_store *volumeStore
Packit Service 310c69
                             __attribute__((unused)),
Packit Service 310c69
                             unsigned int         physicalPage
Packit Service 310c69
                             __attribute__((unused)),
Packit Service 310c69
                             struct volume_page  *volumePage
Packit Service 310c69
                             __attribute__((unused)))
Packit Service 310c69
{
Packit Service 310c69
#ifdef __KERNEL__
Packit Service 310c69
  releaseVolumePage(volumePage);
Packit Service 310c69
  struct dm_buffer *buffer = NULL;
Packit Service 310c69
  byte *data = dm_bufio_new(volumeStore->vs_client, physicalPage, &buffer);
Packit Service 310c69
  if (IS_ERR(data)) {
Packit Service 310c69
    return -PTR_ERR(data);
Packit Service 310c69
  }
Packit Service 310c69
  volumePage->vp_buffer = buffer;
Packit Service 310c69
#else
Packit Service 310c69
  // Nothing to do in user mode
Packit Service 310c69
#endif
Packit Service 310c69
  return UDS_SUCCESS;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
int readVolumePage(const struct volume_store *volumeStore,
Packit Service 310c69
                   unsigned int               physicalPage,
Packit Service 310c69
                   struct volume_page        *volumePage)
Packit Service 310c69
{
Packit Service 310c69
#ifdef __KERNEL__
Packit Service 310c69
  releaseVolumePage(volumePage);
Packit Service 310c69
  byte *data = dm_bufio_read(volumeStore->vs_client, physicalPage,
Packit Service 310c69
                             &volumePage->vp_buffer);
Packit Service 310c69
  if (IS_ERR(data)) {
Packit Service 310c69
    return logWarningWithStringError(-PTR_ERR(data),
Packit Service 310c69
                                     "error reading physical page %u",
Packit Service 310c69
                                     physicalPage);
Packit Service 310c69
  }
Packit Service 310c69
#else
Packit Service 310c69
  off_t offset = (off_t) physicalPage * volumeStore->vs_bytesPerPage;
Packit Service 310c69
  int result = readFromRegion(volumeStore->vs_region, offset,
Packit Service 310c69
                              getPageData(volumePage),
Packit Service 310c69
                              volumeStore->vs_bytesPerPage, NULL);
Packit Service 310c69
  if (result != UDS_SUCCESS) {
Packit Service 310c69
    return logWarningWithStringError(result,
Packit Service 310c69
                                     "error reading physical page %u",
Packit Service 310c69
                                     physicalPage);
Packit Service 310c69
  }
Packit Service 310c69
#endif
Packit Service 310c69
  return UDS_SUCCESS;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
void releaseVolumePage(struct volume_page *volumePage __attribute__((unused)))
Packit Service 310c69
{
Packit Service 310c69
#ifdef __KERNEL__
Packit Service 310c69
  if (volumePage->vp_buffer != NULL) {
Packit Service 310c69
    dm_bufio_release(volumePage->vp_buffer);
Packit Service 310c69
    volumePage->vp_buffer = NULL;
Packit Service 310c69
  }
Packit Service 310c69
#else
Packit Service 310c69
  // Nothing to do in user mode
Packit Service 310c69
#endif
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
void swapVolumePages(struct volume_page *volumePage1,
Packit Service 310c69
                     struct volume_page *volumePage2)
Packit Service 310c69
{
Packit Service 310c69
  struct volume_page temp = *volumePage1;
Packit Service 310c69
  *volumePage1 = *volumePage2;
Packit Service 310c69
  *volumePage2 = temp;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
int syncVolumeStore(const struct volume_store *volumeStore)
Packit Service 310c69
{
Packit Service 310c69
#ifdef __KERNEL__
Packit Service 310c69
  int result = -dm_bufio_write_dirty_buffers(volumeStore->vs_client);
Packit Service 310c69
#else
Packit Service 310c69
  int result = syncRegionContents(volumeStore->vs_region);
Packit Service 310c69
#endif
Packit Service 310c69
  if (result != UDS_SUCCESS) {
Packit Service 310c69
    return logErrorWithStringError(result, "cannot sync chapter to volume");
Packit Service 310c69
  }
Packit Service 310c69
  return UDS_SUCCESS;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
int writeVolumePage(const struct volume_store *volumeStore,
Packit Service 310c69
                    unsigned int               physicalPage,
Packit Service 310c69
                    struct volume_page        *volumePage)
Packit Service 310c69
{
Packit Service 310c69
#ifdef __KERNEL__
Packit Service 310c69
  dm_bufio_mark_buffer_dirty(volumePage->vp_buffer);
Packit Service 310c69
  return UDS_SUCCESS;
Packit Service 310c69
#else
Packit Service 310c69
  off_t offset = (off_t) physicalPage * volumeStore->vs_bytesPerPage;
Packit Service 310c69
  return writeToRegion(volumeStore->vs_region, offset, getPageData(volumePage),
Packit Service 310c69
                       volumeStore->vs_bytesPerPage,
Packit Service 310c69
                       volumeStore->vs_bytesPerPage);
Packit Service 310c69
#endif
Packit Service 310c69
}