|
Packit Service |
d40955 |
/*
|
|
Packit Service |
d40955 |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
d40955 |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
d40955 |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
d40955 |
* of the License, or (at your option) any later version.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
d40955 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
d40955 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
d40955 |
* GNU General Public License for more details.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
d40955 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
d40955 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
d40955 |
* 02110-1301, USA.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/poolSysfs.c#1 $
|
|
Packit Service |
d40955 |
*/
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#include "poolSysfs.h"
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#include "memoryAlloc.h"
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#include "vdo.h"
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#include "dedupeIndex.h"
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
typedef struct poolAttribute {
|
|
Packit Service |
d40955 |
struct attribute attr;
|
|
Packit Service |
d40955 |
ssize_t (*show)(KernelLayer *layer, char *buf);
|
|
Packit Service |
d40955 |
ssize_t (*store)(KernelLayer *layer, const char *value, size_t count);
|
|
Packit Service |
d40955 |
} PoolAttribute;
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static ssize_t vdoPoolAttrShow(struct kobject *kobj,
|
|
Packit Service |
d40955 |
struct attribute *attr,
|
|
Packit Service |
d40955 |
char *buf)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
PoolAttribute *poolAttr = container_of(attr, PoolAttribute, attr);
|
|
Packit Service |
d40955 |
if (poolAttr->show == NULL) {
|
|
Packit Service |
d40955 |
return -EINVAL;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
KernelLayer *layer = container_of(kobj, KernelLayer, kobj);
|
|
Packit Service |
d40955 |
return poolAttr->show(layer, buf);
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static ssize_t vdoPoolAttrStore(struct kobject *kobj,
|
|
Packit Service |
d40955 |
struct attribute *attr,
|
|
Packit Service |
d40955 |
const char *buf,
|
|
Packit Service |
d40955 |
size_t length)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
PoolAttribute *poolAttr = container_of(attr, PoolAttribute, attr);
|
|
Packit Service |
d40955 |
if (poolAttr->store == NULL) {
|
|
Packit Service |
d40955 |
return -EINVAL;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
KernelLayer *layer = container_of(kobj, KernelLayer, kobj);
|
|
Packit Service |
d40955 |
return poolAttr->store(layer, buf, length);
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
static struct sysfs_ops vdoPoolSysfsOps = {
|
|
Packit Service |
d40955 |
.show = vdoPoolAttrShow,
|
|
Packit Service |
d40955 |
.store = vdoPoolAttrStore,
|
|
Packit Service |
d40955 |
};
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static ssize_t poolCompressingShow(KernelLayer *layer, char *buf)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
return sprintf(buf, "%s\n", (getKVDOCompressing(&layer->kvdo) ? "1" : "0"));
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static ssize_t poolDiscardsActiveShow(KernelLayer *layer, char *buf)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
return sprintf(buf, "%" PRIu32 "\n", layer->discardLimiter.active);
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static ssize_t poolDiscardsLimitShow(KernelLayer *layer, char *buf)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
return sprintf(buf, "%" PRIu32 "\n", layer->discardLimiter.limit);
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static ssize_t poolDiscardsLimitStore(KernelLayer *layer,
|
|
Packit Service |
d40955 |
const char *buf,
|
|
Packit Service |
d40955 |
size_t length)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
unsigned int value;
|
|
Packit Service |
d40955 |
if ((length > 12) || (sscanf(buf, "%u", &value) != 1) || (value < 1)) {
|
|
Packit Service |
d40955 |
return -EINVAL;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
layer->discardLimiter.limit = value;
|
|
Packit Service |
d40955 |
return length;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static ssize_t poolDiscardsMaximumShow(KernelLayer *layer, char *buf)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
return sprintf(buf, "%" PRIu32 "\n", layer->discardLimiter.maximum);
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static ssize_t poolInstanceShow(KernelLayer *layer, char *buf)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
return sprintf(buf, "%u\n", layer->instance);
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static ssize_t poolRequestsActiveShow(KernelLayer *layer, char *buf)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
return sprintf(buf, "%" PRIu32 "\n", layer->requestLimiter.active);
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static ssize_t poolRequestsLimitShow(KernelLayer *layer, char *buf)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
return sprintf(buf, "%" PRIu32 "\n", layer->requestLimiter.limit);
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static ssize_t poolRequestsMaximumShow(KernelLayer *layer, char *buf)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
return sprintf(buf, "%" PRIu32 "\n", layer->requestLimiter.maximum);
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static void vdoPoolRelease(struct kobject *kobj)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
KernelLayer *layer = container_of(kobj, KernelLayer, kobj);
|
|
Packit Service |
d40955 |
freeVDO(&layer->kvdo.vdo);
|
|
Packit Service |
d40955 |
FREE(layer);
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
static PoolAttribute vdoPoolCompressingAttr = {
|
|
Packit Service |
d40955 |
.attr = { .name = "compressing", .mode = 0444, },
|
|
Packit Service |
d40955 |
.show = poolCompressingShow,
|
|
Packit Service |
d40955 |
};
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
static PoolAttribute vdoPoolDiscardsActiveAttr = {
|
|
Packit Service |
d40955 |
.attr = { .name = "discards_active", .mode = 0444, },
|
|
Packit Service |
d40955 |
.show = poolDiscardsActiveShow,
|
|
Packit Service |
d40955 |
};
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
static PoolAttribute vdoPoolDiscardsLimitAttr = {
|
|
Packit Service |
d40955 |
.attr = { .name = "discards_limit", .mode = 0644, },
|
|
Packit Service |
d40955 |
.show = poolDiscardsLimitShow,
|
|
Packit Service |
d40955 |
.store = poolDiscardsLimitStore,
|
|
Packit Service |
d40955 |
};
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
static PoolAttribute vdoPoolDiscardsMaximumAttr = {
|
|
Packit Service |
d40955 |
.attr = { .name = "discards_maximum", .mode = 0444, },
|
|
Packit Service |
d40955 |
.show = poolDiscardsMaximumShow,
|
|
Packit Service |
d40955 |
};
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
static PoolAttribute vdoPoolInstanceAttr = {
|
|
Packit Service |
d40955 |
.attr = { .name = "instance", .mode = 0444, },
|
|
Packit Service |
d40955 |
.show = poolInstanceShow,
|
|
Packit Service |
d40955 |
};
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
static PoolAttribute vdoPoolRequestsActiveAttr = {
|
|
Packit Service |
d40955 |
.attr = { .name = "requests_active", .mode = 0444, },
|
|
Packit Service |
d40955 |
.show = poolRequestsActiveShow,
|
|
Packit Service |
d40955 |
};
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
static PoolAttribute vdoPoolRequestsLimitAttr = {
|
|
Packit Service |
d40955 |
.attr = { .name = "requests_limit", .mode = 0444, },
|
|
Packit Service |
d40955 |
.show = poolRequestsLimitShow,
|
|
Packit Service |
d40955 |
};
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
static PoolAttribute vdoPoolRequestsMaximumAttr = {
|
|
Packit Service |
d40955 |
.attr = { .name = "requests_maximum", .mode = 0444, },
|
|
Packit Service |
d40955 |
.show = poolRequestsMaximumShow,
|
|
Packit Service |
d40955 |
};
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
static struct attribute *poolAttrs[] = {
|
|
Packit Service |
d40955 |
&vdoPoolCompressingAttr.attr,
|
|
Packit Service |
d40955 |
&vdoPoolDiscardsActiveAttr.attr,
|
|
Packit Service |
d40955 |
&vdoPoolDiscardsLimitAttr.attr,
|
|
Packit Service |
d40955 |
&vdoPoolDiscardsMaximumAttr.attr,
|
|
Packit Service |
d40955 |
&vdoPoolInstanceAttr.attr,
|
|
Packit Service |
d40955 |
&vdoPoolRequestsActiveAttr.attr,
|
|
Packit Service |
d40955 |
&vdoPoolRequestsLimitAttr.attr,
|
|
Packit Service |
d40955 |
&vdoPoolRequestsMaximumAttr.attr,
|
|
Packit Service |
d40955 |
NULL,
|
|
Packit Service |
d40955 |
};
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
struct kobj_type kernelLayerKobjType = {
|
|
Packit Service |
d40955 |
.release = vdoPoolRelease,
|
|
Packit Service |
d40955 |
.sysfs_ops = &vdoPoolSysfsOps,
|
|
Packit Service |
d40955 |
.default_attrs = poolAttrs,
|
|
Packit Service |
d40955 |
};
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static void workQueueDirectoryRelease(struct kobject *kobj)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
/*
|
|
Packit Service |
d40955 |
* The workQueueDirectory holds an implicit reference to its parent,
|
|
Packit Service |
d40955 |
* the kernelLayer object (->kobj), so even if there are some
|
|
Packit Service |
d40955 |
* external references held to the workQueueDirectory when work
|
|
Packit Service |
d40955 |
* queue shutdown calls kobject_put on the kernelLayer object, the
|
|
Packit Service |
d40955 |
* kernelLayer object won't actually be released and won't free the
|
|
Packit Service |
d40955 |
* KernelLayer storage until the workQueueDirectory object is
|
|
Packit Service |
d40955 |
* released first.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* So, we don't need to do any additional explicit management here.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* (But we aren't allowed to use a NULL function pointer to indicate
|
|
Packit Service |
d40955 |
* a no-op.)
|
|
Packit Service |
d40955 |
*/
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static struct attribute *noAttrs[] = {
|
|
Packit Service |
d40955 |
NULL,
|
|
Packit Service |
d40955 |
};
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
static struct sysfs_ops noSysfsOps = {
|
|
Packit Service |
d40955 |
// These should never be reachable since there are no attributes.
|
|
Packit Service |
d40955 |
.show = NULL,
|
|
Packit Service |
d40955 |
.store = NULL,
|
|
Packit Service |
d40955 |
};
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
struct kobj_type workQueueDirectoryKobjType = {
|
|
Packit Service |
d40955 |
.release = workQueueDirectoryRelease,
|
|
Packit Service |
d40955 |
.sysfs_ops = &noSysfsOps,
|
|
Packit Service |
d40955 |
.default_attrs = noAttrs,
|
|
Packit Service |
d40955 |
};
|