|
Packit |
2ba279 |
/*
|
|
Packit |
2ba279 |
* Copyright (C) 2018 Red Hat, Inc.
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
2ba279 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
2ba279 |
* License as published by the Free Software Foundation; either
|
|
Packit |
2ba279 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
2ba279 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
2ba279 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
2ba279 |
* Lesser General Public License for more details.
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
2ba279 |
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Author: Vojtech Trefny <vtrefny@redhat.com>
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
#include <glib.h>
|
|
Packit |
2ba279 |
#include <blockdev/utils.h>
|
|
Packit |
2ba279 |
#include <ndctl/libndctl.h>
|
|
Packit |
2ba279 |
#include <uuid.h>
|
|
Packit |
2ba279 |
#include <string.h>
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
#include "nvdimm.h"
|
|
Packit |
2ba279 |
#include "check_deps.h"
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/**
|
|
Packit |
2ba279 |
* SECTION: nvdimm
|
|
Packit |
2ba279 |
* @short_description: plugin for operations with nvdimm space
|
|
Packit |
2ba279 |
* @title: NVDIMM
|
|
Packit |
2ba279 |
* @include: nvdimm.h
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* A plugin for operations with NVDIMM devices.
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/**
|
|
Packit |
2ba279 |
* bd_nvdimm_error_quark: (skip)
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
GQuark bd_nvdimm_error_quark (void) {
|
|
Packit |
2ba279 |
return g_quark_from_static_string ("g-bd-nvdimm-error-quark");
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
void bd_nvdimm_namespace_info_free (BDNVDIMMNamespaceInfo *info) {
|
|
Packit |
2ba279 |
if (info == NULL)
|
|
Packit |
2ba279 |
return;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
g_free (info->dev);
|
|
Packit |
2ba279 |
g_free (info->uuid);
|
|
Packit |
2ba279 |
g_free (info->blockdev);
|
|
Packit |
2ba279 |
g_free (info);
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
BDNVDIMMNamespaceInfo* bd_nvdimm_namespace_info_copy (BDNVDIMMNamespaceInfo *info) {
|
|
Packit |
2ba279 |
if (info == NULL)
|
|
Packit |
2ba279 |
return NULL;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
BDNVDIMMNamespaceInfo *new_info = g_new0 (BDNVDIMMNamespaceInfo, 1);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
new_info->dev = g_strdup (info->dev);
|
|
Packit |
2ba279 |
new_info->mode = info->mode;
|
|
Packit |
2ba279 |
new_info->size = info->size;
|
|
Packit |
2ba279 |
new_info->uuid = g_strdup (info->uuid);
|
|
Packit |
2ba279 |
new_info->sector_size = info->sector_size;
|
|
Packit |
2ba279 |
new_info->blockdev = g_strdup (info->blockdev);
|
|
Packit |
2ba279 |
new_info->enabled = info->enabled;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
return new_info;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
static const gchar * const mode_str[BD_NVDIMM_NAMESPACE_MODE_UNKNOWN+1] = {"raw", "sector", "memory", "dax", "fsdax", "devdax", "unknown"};
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
static volatile guint avail_deps = 0;
|
|
Packit |
2ba279 |
static GMutex deps_check_lock;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
#define DEPS_NDCTL 0
|
|
Packit |
2ba279 |
#define DEPS_NDCTL_MASK (1 << DEPS_NDCTL)
|
|
Packit |
2ba279 |
#define DEPS_LAST 1
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
static const UtilDep deps[DEPS_LAST] = {
|
|
Packit |
2ba279 |
{"ndctl", NULL, NULL, NULL},
|
|
Packit |
2ba279 |
};
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/**
|
|
Packit |
2ba279 |
* bd_nvdimm_check_deps:
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Returns: whether the plugin's runtime dependencies are satisfied or not
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Function checking plugin's runtime dependencies.
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
gboolean bd_nvdimm_check_deps (void) {
|
|
Packit |
2ba279 |
GError *error = NULL;
|
|
Packit |
2ba279 |
guint i = 0;
|
|
Packit |
2ba279 |
gboolean status = FALSE;
|
|
Packit |
2ba279 |
gboolean ret = TRUE;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
for (i=0; i < DEPS_LAST; i++) {
|
|
Packit |
2ba279 |
status = bd_utils_check_util_version (deps[i].name, deps[i].version,
|
|
Packit |
2ba279 |
deps[i].ver_arg, deps[i].ver_regexp, &error);
|
|
Packit |
2ba279 |
if (!status)
|
|
Packit |
2ba279 |
g_warning ("%s", error->message);
|
|
Packit |
2ba279 |
else
|
|
Packit |
2ba279 |
g_atomic_int_or (&avail_deps, 1 << i);
|
|
Packit |
2ba279 |
g_clear_error (&error);
|
|
Packit |
2ba279 |
ret = ret && status;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
if (!ret)
|
|
Packit |
2ba279 |
g_warning("Cannot load the NVDIMM plugin");
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
return ret;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/**
|
|
Packit |
2ba279 |
* bd_nvdimm_init:
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Initializes the plugin. **This function is called automatically by the
|
|
Packit |
2ba279 |
* library's initialization functions.**
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
gboolean bd_nvdimm_init (void) {
|
|
Packit |
2ba279 |
/* nothing to do here */
|
|
Packit |
2ba279 |
return TRUE;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/**
|
|
Packit |
2ba279 |
* bd_nvdimm_close:
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Cleans up after the plugin. **This function is called automatically by the
|
|
Packit |
2ba279 |
* library's functions that unload it.**
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
void bd_nvdimm_close (void) {
|
|
Packit |
2ba279 |
/* nothing to do here */
|
|
Packit |
2ba279 |
return;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
#define UNUSED __attribute__((unused))
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/**
|
|
Packit |
2ba279 |
* bd_nvdimm_is_tech_avail:
|
|
Packit |
2ba279 |
* @tech: the queried tech
|
|
Packit |
2ba279 |
* @mode: a bit mask of queried modes of operation (#BDNVDIMMTechMode) for @tech
|
|
Packit |
2ba279 |
* @error: (out): place to store error (details about why the @tech-@mode combination is not available)
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Returns: whether the @tech-@mode combination is available -- supported by the
|
|
Packit |
2ba279 |
* plugin implementation and having all the runtime dependencies available
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
gboolean bd_nvdimm_is_tech_avail (BDNVDIMMTech tech, guint64 mode, GError **error) {
|
|
Packit |
2ba279 |
/* all tech-mode combinations are supported by this implementation of the
|
|
Packit |
2ba279 |
plugin, namespace reconfigure requires the 'ndctl' utility */
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
if (tech == BD_NVDIMM_TECH_NAMESPACE) {
|
|
Packit |
2ba279 |
if (mode & BD_NVDIMM_TECH_MODE_RECONFIGURE)
|
|
Packit |
2ba279 |
return check_deps (&avail_deps, DEPS_NDCTL_MASK, deps, DEPS_LAST, &deps_check_lock, error);
|
|
Packit |
2ba279 |
else
|
|
Packit |
2ba279 |
return TRUE;
|
|
Packit |
2ba279 |
} else {
|
|
Packit |
2ba279 |
g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_TECH_UNAVAIL, "Unknown technology");
|
|
Packit |
2ba279 |
return FALSE;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
return TRUE;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/**
|
|
Packit |
2ba279 |
* bd_nvdimm_namespace_get_mode_from_str:
|
|
Packit |
2ba279 |
* @mode_str: string representation of mode
|
|
Packit |
2ba279 |
* @error: (out): place to store error (if any)
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Returns: mode matching the @mode_str given or %BD_NVDIMM_NAMESPACE_MODE_UNKNOWN in case of no match
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Tech category: always available
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
BDNVDIMMNamespaceMode bd_nvdimm_namespace_get_mode_from_str (const gchar *mode_str, GError **error) {
|
|
Packit |
2ba279 |
if (g_strcmp0 (mode_str, "raw") == 0)
|
|
Packit |
2ba279 |
return BD_NVDIMM_NAMESPACE_MODE_RAW;
|
|
Packit |
2ba279 |
else if (g_strcmp0 (mode_str, "sector") == 0)
|
|
Packit |
2ba279 |
return BD_NVDIMM_NAMESPACE_MODE_SECTOR;
|
|
Packit |
2ba279 |
else if (g_strcmp0 (mode_str, "memory") == 0)
|
|
Packit |
2ba279 |
return BD_NVDIMM_NAMESPACE_MODE_MEMORY;
|
|
Packit |
2ba279 |
else if (g_strcmp0 (mode_str, "dax") == 0)
|
|
Packit |
2ba279 |
return BD_NVDIMM_NAMESPACE_MODE_DAX;
|
|
Packit |
2ba279 |
else if (g_strcmp0 (mode_str, "fsdax") == 0)
|
|
Packit |
2ba279 |
return BD_NVDIMM_NAMESPACE_MODE_FSDAX;
|
|
Packit |
2ba279 |
else if (g_strcmp0 (mode_str, "devdax") == 0)
|
|
Packit |
2ba279 |
return BD_NVDIMM_NAMESPACE_MODE_DEVDAX;
|
|
Packit |
2ba279 |
else {
|
|
Packit |
2ba279 |
g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_MODE_INVAL,
|
|
Packit |
2ba279 |
"Invalid mode given: '%s'", mode_str);
|
|
Packit |
2ba279 |
return BD_NVDIMM_NAMESPACE_MODE_UNKNOWN;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/**
|
|
Packit |
2ba279 |
* bd_nvdimm_namespace_get_mode_str:
|
|
Packit |
2ba279 |
* @mode: mode to get string representation of
|
|
Packit |
2ba279 |
* @error: (out): place to store error (if any)
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Returns: (transfer none): string representation of @mode or %NULL in case of error
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Tech category: always available
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
const gchar* bd_nvdimm_namespace_get_mode_str (BDNVDIMMNamespaceMode mode, GError **error) {
|
|
Packit |
2ba279 |
if (mode <= BD_NVDIMM_NAMESPACE_MODE_UNKNOWN)
|
|
Packit |
2ba279 |
return mode_str[mode];
|
|
Packit |
2ba279 |
else {
|
|
Packit |
2ba279 |
g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_MODE_INVAL,
|
|
Packit |
2ba279 |
"Invalid mode given: %d", mode);
|
|
Packit |
2ba279 |
return NULL;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
static struct ndctl_namespace* get_namespace_by_name (const gchar *namespace, struct ndctl_ctx *ctx) {
|
|
Packit |
2ba279 |
struct ndctl_namespace *ndns = NULL;
|
|
Packit |
2ba279 |
struct ndctl_region *region = NULL;
|
|
Packit |
2ba279 |
struct ndctl_bus *bus = NULL;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ndctl_bus_foreach (ctx, bus) {
|
|
Packit |
2ba279 |
ndctl_region_foreach (bus, region) {
|
|
Packit |
2ba279 |
ndctl_namespace_foreach (region, ndns) {
|
|
Packit |
2ba279 |
if (g_strcmp0 (namespace, ndctl_namespace_get_devname (ndns)) == 0)
|
|
Packit |
2ba279 |
return ndns;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
return NULL;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/**
|
|
Packit |
2ba279 |
* bd_nvdimm_namespace_get_devname:
|
|
Packit |
2ba279 |
* @device: name or path of a block device (e.g. "/dev/pmem0")
|
|
Packit |
2ba279 |
* @error: (out): place to store error (if any)
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Returns: (transfer full): namespace device name (e.g. "namespaceX.Y") for @device
|
|
Packit |
2ba279 |
* or %NULL if @device is not a NVDIMM namespace
|
|
Packit |
2ba279 |
* (@error may be set to indicate error)
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_QUERY
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
gchar* bd_nvdimm_namespace_get_devname (const gchar *device, GError **error) {
|
|
Packit |
2ba279 |
struct ndctl_ctx *ctx = NULL;
|
|
Packit |
2ba279 |
struct ndctl_namespace *ndns = NULL;
|
|
Packit |
2ba279 |
struct ndctl_region *region = NULL;
|
|
Packit |
2ba279 |
struct ndctl_bus *bus = NULL;
|
|
Packit |
2ba279 |
gint success = 0;
|
|
Packit |
2ba279 |
gchar *ret = NULL;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/* get rid of the "/dev/" prefix (if any) */
|
|
Packit |
2ba279 |
if (g_str_has_prefix (device, "/dev/"))
|
|
Packit |
2ba279 |
device = device + 5;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
success = ndctl_new (&ctx;;
|
|
Packit |
2ba279 |
if (success != 0) {
|
|
Packit |
2ba279 |
g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL,
|
|
Packit |
2ba279 |
"Failed to create ndctl context");
|
|
Packit |
2ba279 |
return FALSE;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ndctl_bus_foreach (ctx, bus) {
|
|
Packit |
2ba279 |
ndctl_region_foreach (bus, region) {
|
|
Packit |
2ba279 |
ndctl_namespace_foreach (region, ndns) {
|
|
Packit |
2ba279 |
if (!ndctl_namespace_is_active (ndns))
|
|
Packit |
2ba279 |
continue;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
struct ndctl_btt *btt = ndctl_namespace_get_btt (ndns);
|
|
Packit |
2ba279 |
struct ndctl_dax *dax = ndctl_namespace_get_dax (ndns);
|
|
Packit |
2ba279 |
struct ndctl_pfn *pfn = ndctl_namespace_get_pfn (ndns);
|
|
Packit |
2ba279 |
const gchar *blockdev = NULL;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
if (dax)
|
|
Packit |
2ba279 |
continue;
|
|
Packit |
2ba279 |
else if (btt)
|
|
Packit |
2ba279 |
blockdev = ndctl_btt_get_block_device (btt);
|
|
Packit |
2ba279 |
else if (pfn)
|
|
Packit |
2ba279 |
blockdev = ndctl_pfn_get_block_device (pfn);
|
|
Packit |
2ba279 |
else
|
|
Packit |
2ba279 |
blockdev = ndctl_namespace_get_block_device (ndns);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
if (g_strcmp0 (blockdev, device) == 0) {
|
|
Packit |
2ba279 |
ret = g_strdup (ndctl_namespace_get_devname (ndns));
|
|
Packit |
2ba279 |
ndctl_unref (ctx);
|
|
Packit |
2ba279 |
return ret;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ndctl_unref (ctx);
|
|
Packit |
2ba279 |
return NULL;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/**
|
|
Packit |
2ba279 |
* bd_nvdimm_namespace_enable:
|
|
Packit |
2ba279 |
* @namespace: name of the namespace to enable
|
|
Packit |
2ba279 |
* @extra: (allow-none) (array zero-terminated=1): extra options (currently unused)
|
|
Packit |
2ba279 |
* @error: (out): place to store error (if any)
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Returns: whether the @namespace was successfully enabled or not
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_ACTIVATE_DEACTIVATE
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
gboolean bd_nvdimm_namespace_enable (const gchar *namespace, const BDExtraArg **extra UNUSED, GError **error) {
|
|
Packit |
2ba279 |
struct ndctl_ctx *ctx = NULL;
|
|
Packit |
2ba279 |
struct ndctl_namespace *ndns = NULL;
|
|
Packit |
2ba279 |
gint ret = 0;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ret = ndctl_new (&ctx;;
|
|
Packit |
2ba279 |
if (ret != 0) {
|
|
Packit |
2ba279 |
g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL,
|
|
Packit |
2ba279 |
"Failed to create ndctl context");
|
|
Packit |
2ba279 |
return FALSE;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ndns = get_namespace_by_name (namespace, ctx);
|
|
Packit |
2ba279 |
if (!ndns) {
|
|
Packit |
2ba279 |
g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_NOEXIST,
|
|
Packit |
2ba279 |
"Failed to enable namespace: namespace '%s' not found.", namespace);
|
|
Packit |
2ba279 |
return FALSE;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ret = ndctl_namespace_enable (ndns);
|
|
Packit |
2ba279 |
if (ret < 0) {
|
|
Packit |
2ba279 |
g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL,
|
|
Packit |
2ba279 |
"Failed to enable namespace: %s", strerror (-ret));
|
|
Packit |
2ba279 |
ndctl_unref (ctx);
|
|
Packit |
2ba279 |
return FALSE;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ndctl_unref (ctx);
|
|
Packit |
2ba279 |
return TRUE;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/**
|
|
Packit |
2ba279 |
* bd_nvdimm_namespace_disable:
|
|
Packit |
2ba279 |
* @namespace: name of the namespace to disable
|
|
Packit |
2ba279 |
* @extra: (allow-none) (array zero-terminated=1): extra options (currently unused)
|
|
Packit |
2ba279 |
* @error: (out): place to store error (if any)
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Returns: whether the @namespace was successfully disabled or not
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_ACTIVATE_DEACTIVATE
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
gboolean bd_nvdimm_namespace_disable (const gchar *namespace, const BDExtraArg **extra UNUSED, GError **error) {
|
|
Packit |
2ba279 |
struct ndctl_ctx *ctx = NULL;
|
|
Packit |
2ba279 |
struct ndctl_namespace *ndns = NULL;
|
|
Packit |
2ba279 |
gint ret = 0;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ret = ndctl_new (&ctx;;
|
|
Packit |
2ba279 |
if (ret != 0) {
|
|
Packit |
2ba279 |
g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL,
|
|
Packit |
2ba279 |
"Failed to create ndctl context");
|
|
Packit |
2ba279 |
return FALSE;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ndns = get_namespace_by_name (namespace, ctx);
|
|
Packit |
2ba279 |
if (!ndns) {
|
|
Packit |
2ba279 |
g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_NOEXIST,
|
|
Packit |
2ba279 |
"Failed to disable namespace: namespace '%s' not found.", namespace);
|
|
Packit |
2ba279 |
return FALSE;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ret = ndctl_namespace_disable_safe (ndns);
|
|
Packit |
2ba279 |
if (ret != 0) {
|
|
Packit |
2ba279 |
g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL,
|
|
Packit |
2ba279 |
"Failed to disable namespace: %s", strerror (-ret));
|
|
Packit |
2ba279 |
ndctl_unref (ctx);
|
|
Packit |
2ba279 |
return FALSE;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ndctl_unref (ctx);
|
|
Packit |
2ba279 |
return TRUE;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
static BDNVDIMMNamespaceInfo* get_nvdimm_namespace_info (struct ndctl_namespace *ndns, GError **error) {
|
|
Packit |
2ba279 |
struct ndctl_btt *btt;
|
|
Packit |
2ba279 |
struct ndctl_pfn *pfn;
|
|
Packit |
2ba279 |
struct ndctl_dax *dax;
|
|
Packit |
2ba279 |
enum ndctl_namespace_mode mode;
|
|
Packit |
2ba279 |
gchar uuid_buf[37] = {0};
|
|
Packit |
2ba279 |
uuid_t uuid;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
btt = ndctl_namespace_get_btt (ndns);
|
|
Packit |
2ba279 |
dax = ndctl_namespace_get_dax (ndns);
|
|
Packit |
2ba279 |
pfn = ndctl_namespace_get_pfn (ndns);
|
|
Packit |
2ba279 |
mode = ndctl_namespace_get_mode (ndns);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
BDNVDIMMNamespaceInfo *info = g_new0 (BDNVDIMMNamespaceInfo, 1);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
info->dev = g_strdup (ndctl_namespace_get_devname (ndns));
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
switch (mode) {
|
|
Packit |
2ba279 |
case NDCTL_NS_MODE_MEMORY:
|
|
Packit |
2ba279 |
if (pfn)
|
|
Packit |
2ba279 |
info->size = ndctl_pfn_get_size (pfn);
|
|
Packit |
2ba279 |
else
|
|
Packit |
2ba279 |
info->size = ndctl_namespace_get_size (ndns);
|
|
Packit |
2ba279 |
#ifndef LIBNDCTL_NEW_MODES
|
|
Packit |
2ba279 |
info->mode = BD_NVDIMM_NAMESPACE_MODE_MEMORY;
|
|
Packit |
2ba279 |
#else
|
|
Packit |
2ba279 |
info->mode = BD_NVDIMM_NAMESPACE_MODE_FSDAX;
|
|
Packit |
2ba279 |
#endif
|
|
Packit |
2ba279 |
break;
|
|
Packit |
2ba279 |
case NDCTL_NS_MODE_DAX:
|
|
Packit |
2ba279 |
if (!dax) {
|
|
Packit |
2ba279 |
g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL,
|
|
Packit |
2ba279 |
"Failed to get information about namespaces: DAX mode "
|
|
Packit |
2ba279 |
"detected but no DAX device found.");
|
|
Packit |
2ba279 |
bd_nvdimm_namespace_info_free (info);
|
|
Packit |
2ba279 |
return NULL;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
info->size = ndctl_dax_get_size (dax);
|
|
Packit |
2ba279 |
#ifndef LIBNDCTL_NEW_MODES
|
|
Packit |
2ba279 |
info->mode = BD_NVDIMM_NAMESPACE_MODE_DAX;
|
|
Packit |
2ba279 |
#else
|
|
Packit |
2ba279 |
info->mode = BD_NVDIMM_NAMESPACE_MODE_DEVDAX;
|
|
Packit |
2ba279 |
#endif
|
|
Packit |
2ba279 |
break;
|
|
Packit |
2ba279 |
case NDCTL_NS_MODE_SAFE:
|
|
Packit |
2ba279 |
if (!btt) {
|
|
Packit |
2ba279 |
g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL,
|
|
Packit |
2ba279 |
"Failed to get information about namespaces: Sector mode "
|
|
Packit |
2ba279 |
"detected but no BTT device found.");
|
|
Packit |
2ba279 |
bd_nvdimm_namespace_info_free (info);
|
|
Packit |
2ba279 |
return NULL;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
info->size = ndctl_btt_get_size (btt);
|
|
Packit |
2ba279 |
info->mode = BD_NVDIMM_NAMESPACE_MODE_SECTOR;
|
|
Packit |
2ba279 |
break;
|
|
Packit |
2ba279 |
case NDCTL_NS_MODE_RAW:
|
|
Packit |
2ba279 |
info->size = ndctl_namespace_get_size (ndns);
|
|
Packit |
2ba279 |
info->mode = BD_NVDIMM_NAMESPACE_MODE_RAW;
|
|
Packit |
2ba279 |
break;
|
|
Packit |
2ba279 |
default:
|
|
Packit |
2ba279 |
g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL,
|
|
Packit |
2ba279 |
"Failed to get information about namespaces: Unknow mode.");
|
|
Packit |
2ba279 |
bd_nvdimm_namespace_info_free (info);
|
|
Packit |
2ba279 |
return NULL;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
if (btt) {
|
|
Packit |
2ba279 |
ndctl_btt_get_uuid (btt, uuid);
|
|
Packit |
2ba279 |
uuid_unparse (uuid, uuid_buf);
|
|
Packit |
2ba279 |
info->uuid = g_strdup (uuid_buf);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
info->blockdev = g_strdup (ndctl_btt_get_block_device (btt));
|
|
Packit |
2ba279 |
} else if (pfn) {
|
|
Packit |
2ba279 |
ndctl_pfn_get_uuid (pfn, uuid);
|
|
Packit |
2ba279 |
uuid_unparse (uuid, uuid_buf);
|
|
Packit |
2ba279 |
info->uuid = g_strdup (uuid_buf);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
info->blockdev = g_strdup (ndctl_pfn_get_block_device (pfn));
|
|
Packit |
2ba279 |
} else if (dax) {
|
|
Packit |
2ba279 |
ndctl_dax_get_uuid (dax, uuid);
|
|
Packit |
2ba279 |
uuid_unparse (uuid, uuid_buf);
|
|
Packit |
2ba279 |
info->uuid = g_strdup (uuid_buf);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/* no blockdev for dax mode */
|
|
Packit |
2ba279 |
info->blockdev = NULL;
|
|
Packit |
2ba279 |
} else {
|
|
Packit |
2ba279 |
ndctl_namespace_get_uuid (ndns, uuid);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
if (uuid_is_null (uuid))
|
|
Packit |
2ba279 |
info->uuid = NULL;
|
|
Packit |
2ba279 |
else {
|
|
Packit |
2ba279 |
uuid_unparse (uuid, uuid_buf);
|
|
Packit |
2ba279 |
info->uuid = g_strdup (uuid_buf);
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
info->blockdev = g_strdup (ndctl_namespace_get_block_device (ndns));
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
if (btt)
|
|
Packit |
2ba279 |
info->sector_size = ndctl_btt_get_sector_size (btt);
|
|
Packit |
2ba279 |
else if (dax)
|
|
Packit |
2ba279 |
/* no sector size for dax mode */
|
|
Packit |
2ba279 |
info->sector_size = 0;
|
|
Packit |
2ba279 |
else {
|
|
Packit |
2ba279 |
info->sector_size = ndctl_namespace_get_sector_size (ndns);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/* apparently the default value for sector size is 512
|
|
Packit |
2ba279 |
on non DAX namespaces even if libndctl says it's 0
|
|
Packit |
2ba279 |
https://github.com/pmem/ndctl/commit/a7320456f1bca5edf15352ce977e757fdf78ed58
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
if (info->sector_size == 0)
|
|
Packit |
2ba279 |
info->sector_size = 512;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
info->enabled = ndctl_namespace_is_active (ndns);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
return info;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/**
|
|
Packit |
2ba279 |
* bd_nvdimm_namespace_info:
|
|
Packit |
2ba279 |
* @namespace: namespace to get information about
|
|
Packit |
2ba279 |
* @extra: (allow-none) (array zero-terminated=1): extra options (currently unused)
|
|
Packit |
2ba279 |
* @error: (out): place to store error (if any)
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Returns: (transfer full): information about given namespace or %NULL if no such
|
|
Packit |
2ba279 |
* namespace was found (@error may be set to indicate error)
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_QUERY
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
BDNVDIMMNamespaceInfo* bd_nvdimm_namespace_info (const gchar *namespace, const BDExtraArg **extra UNUSED, GError **error) {
|
|
Packit |
2ba279 |
struct ndctl_ctx *ctx = NULL;
|
|
Packit |
2ba279 |
struct ndctl_namespace *ndns = NULL;
|
|
Packit |
2ba279 |
BDNVDIMMNamespaceInfo *info = NULL;
|
|
Packit |
2ba279 |
gint ret = 0;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ret = ndctl_new (&ctx;;
|
|
Packit |
2ba279 |
if (ret != 0) {
|
|
Packit |
2ba279 |
g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL,
|
|
Packit |
2ba279 |
"Failed to create ndctl context");
|
|
Packit |
2ba279 |
return NULL;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ndns = get_namespace_by_name (namespace, ctx);
|
|
Packit |
2ba279 |
if (ndns) {
|
|
Packit |
2ba279 |
info = get_nvdimm_namespace_info (ndns, error);
|
|
Packit |
2ba279 |
ndctl_unref (ctx);
|
|
Packit |
2ba279 |
return info;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ndctl_unref (ctx);
|
|
Packit |
2ba279 |
return NULL;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/**
|
|
Packit |
2ba279 |
* bd_nvdimm_list_namespaces:
|
|
Packit |
2ba279 |
* @bus_name: (allow-none): return only namespaces on given bus (specified by name),
|
|
Packit |
2ba279 |
* %NULL may be specified to return namespaces from all buses
|
|
Packit |
2ba279 |
* @region_name: (allow-none): return only namespaces on given region (specified by 'regionX' name),
|
|
Packit |
2ba279 |
* %NULL may be specified to return namespaces from all regions
|
|
Packit |
2ba279 |
* @idle: whether to list idle (not enabled) namespaces too
|
|
Packit |
2ba279 |
* @extra: (allow-none) (array zero-terminated=1): extra options (currently unused)
|
|
Packit |
2ba279 |
* @error: (out): place to store error (if any)
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Returns: (array zero-terminated=1): information about the namespaces on @bus and @region or
|
|
Packit |
2ba279 |
* %NULL if no namespaces were found (@error may be set to indicate error)
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_QUERY
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
BDNVDIMMNamespaceInfo** bd_nvdimm_list_namespaces (const gchar *bus_name, const gchar *region_name, gboolean idle, const BDExtraArg **extra UNUSED, GError **error) {
|
|
Packit |
2ba279 |
struct ndctl_ctx *ctx = NULL;
|
|
Packit |
2ba279 |
struct ndctl_namespace *ndns = NULL;
|
|
Packit |
2ba279 |
struct ndctl_region *region = NULL;
|
|
Packit |
2ba279 |
struct ndctl_bus *bus = NULL;
|
|
Packit |
2ba279 |
gint ret = 0;
|
|
Packit |
2ba279 |
BDNVDIMMNamespaceInfo **info = NULL;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
GPtrArray *namespaces = g_ptr_array_new ();
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ret = ndctl_new (&ctx;;
|
|
Packit |
2ba279 |
if (ret != 0) {
|
|
Packit |
2ba279 |
g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL,
|
|
Packit |
2ba279 |
"Failed to create ndctl context");
|
|
Packit |
2ba279 |
return NULL;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ndctl_bus_foreach (ctx, bus) {
|
|
Packit |
2ba279 |
if (bus_name && g_strcmp0 (bus_name, ndctl_bus_get_devname (bus)) != 0)
|
|
Packit |
2ba279 |
continue;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ndctl_region_foreach (bus, region) {
|
|
Packit |
2ba279 |
if (region_name && g_strcmp0 (bus_name, ndctl_region_get_devname (region)) != 0)
|
|
Packit |
2ba279 |
continue;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ndctl_namespace_foreach (region, ndns) {
|
|
Packit |
2ba279 |
if (!idle && !ndctl_namespace_is_active (ndns))
|
|
Packit |
2ba279 |
continue;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
BDNVDIMMNamespaceInfo *info = get_nvdimm_namespace_info (ndns, error);
|
|
Packit |
2ba279 |
if (!info) {
|
|
Packit |
2ba279 |
g_ptr_array_foreach (namespaces, (GFunc) (void *) bd_nvdimm_namespace_info_free, NULL);
|
|
Packit |
2ba279 |
g_ptr_array_free (namespaces, FALSE);
|
|
Packit |
2ba279 |
ndctl_unref (ctx);
|
|
Packit |
2ba279 |
return NULL;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
g_ptr_array_add (namespaces, info);
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
if (namespaces->len == 0) {
|
|
Packit |
2ba279 |
ndctl_unref (ctx);
|
|
Packit |
2ba279 |
return NULL;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
g_ptr_array_add (namespaces, NULL);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
info = (BDNVDIMMNamespaceInfo **) g_ptr_array_free (namespaces, FALSE);
|
|
Packit |
2ba279 |
ndctl_unref (ctx);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
return info;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/**
|
|
Packit |
2ba279 |
* bd_nvdimm_namespace_reconfigure:
|
|
Packit |
2ba279 |
* @namespace: name of the namespace to recofigure
|
|
Packit |
2ba279 |
* @mode: mode type to set
|
|
Packit |
2ba279 |
* @error: (out): place to store error if any
|
|
Packit |
2ba279 |
* @extra: (allow-none) (array zero-terminated=1): extra options for the creation (right now
|
|
Packit |
2ba279 |
* passed to the 'ndctl' utility)
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Returns: whether @namespace was successfully reconfigured or not
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_RECONFIGURE
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
gboolean bd_nvdimm_namespace_reconfigure (const gchar* namespace, BDNVDIMMNamespaceMode mode, gboolean force, const BDExtraArg **extra, GError** error) {
|
|
Packit |
2ba279 |
const gchar *args[8] = {"ndctl", "create-namespace", "-e", namespace, "-m", NULL, NULL, NULL};
|
|
Packit |
2ba279 |
gboolean ret = FALSE;
|
|
Packit |
2ba279 |
const gchar *mode_str = NULL;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
if (!check_deps (&avail_deps, DEPS_NDCTL_MASK, deps, DEPS_LAST, &deps_check_lock, error))
|
|
Packit |
2ba279 |
return FALSE;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
mode_str = bd_nvdimm_namespace_get_mode_str (mode, error);
|
|
Packit |
2ba279 |
if (!mode_str)
|
|
Packit |
2ba279 |
/* error is already populated */
|
|
Packit |
2ba279 |
return FALSE;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
args[5] = g_strdup (mode_str);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
if (force)
|
|
Packit |
2ba279 |
args[6] = "-f";
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ret = bd_utils_exec_and_report_error (args, extra, error);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
g_free ((gchar *) args[5]);
|
|
Packit |
2ba279 |
return ret;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
static guint64 blk_sector_sizes[] = { 512, 520, 528, 4096, 4104, 4160, 4224, 0 };
|
|
Packit |
2ba279 |
static guint64 pmem_sector_sizes[] = { 512, 4096, 0 };
|
|
Packit |
2ba279 |
static guint64 io_sector_sizes[] = { 0 };
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/**
|
|
Packit |
2ba279 |
* bd_nvdimm_namepace_get_supported_sector_sizes:
|
|
Packit |
2ba279 |
* @mode: namespace mode
|
|
Packit |
2ba279 |
* @error: (out): place to store error if any
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Returns: (transfer none) (array zero-terminated=1): list of supported sector sizes for @mode
|
|
Packit |
2ba279 |
*
|
|
Packit |
2ba279 |
* Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_QUERY
|
|
Packit |
2ba279 |
*/
|
|
Packit |
2ba279 |
const guint64 *bd_nvdimm_namepace_get_supported_sector_sizes (BDNVDIMMNamespaceMode mode, GError **error) {
|
|
Packit |
2ba279 |
switch (mode) {
|
|
Packit |
2ba279 |
case BD_NVDIMM_NAMESPACE_MODE_RAW:
|
|
Packit |
2ba279 |
case BD_NVDIMM_NAMESPACE_MODE_MEMORY:
|
|
Packit |
2ba279 |
case BD_NVDIMM_NAMESPACE_MODE_FSDAX:
|
|
Packit |
2ba279 |
return pmem_sector_sizes;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
case BD_NVDIMM_NAMESPACE_MODE_DAX:
|
|
Packit |
2ba279 |
case BD_NVDIMM_NAMESPACE_MODE_DEVDAX:
|
|
Packit |
2ba279 |
return io_sector_sizes;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
case BD_NVDIMM_NAMESPACE_MODE_SECTOR:
|
|
Packit |
2ba279 |
return blk_sector_sizes;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
default:
|
|
Packit |
2ba279 |
g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_MODE_INVAL,
|
|
Packit |
2ba279 |
"Invalid/unknown mode specified.");
|
|
Packit |
2ba279 |
return NULL;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
}
|