|
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 |
}
|