Server IP : 103.169.32.36 / Your IP : 216.73.217.13 Web Server : Apache System : Linux web.dpmptsp 3.10.0-1160.119.1.el7.x86_64 #1 SMP Tue Jun 4 14:43:51 UTC 2024 x86_64 User : apache ( 48) PHP Version : 5.6.40 Disable Function : NONE MySQL : ON | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /var/opt/eset/efs/eventd/eset_rtp/ |
Upload File : |
| Current File : /var/opt/eset/efs/eventd/eset_rtp/ertp_cache_container.c |
/*
* eset_rtp (ESET Real-time file system protection module)
* Copyright (C) 1992-2023 ESET, spol. s r.o.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* In case of any questions, you can contact us at ESET, spol. s r.o., Einsteinova 24, 851 01 Bratislava, Slovakia.
*/
#include "ertp_cache_container.h"
#include "ertp_logs.h"
#include <linux/slab.h>
static struct kmem_cache *ertp_cache_allocator = NULL;
int ertp_cache_item_allocator_init(void) {
ertp_cache_allocator = kmem_cache_create(
"ertp_cache_allocator", sizeof(struct ertp_cache_item),
__alignof__(struct ertp_cache_item), SLAB_RECLAIM_ACCOUNT, NULL);
if (!ertp_cache_allocator) {
return -ENOMEM;
}
return 0;
}
void ertp_cache_item_allocator_deinit(void) {
kmem_cache_destroy(ertp_cache_allocator);
}
static struct ertp_cache_item *ertp_cache_item_new(struct ertp_cache_key key,
ertp_timespec_t ctime,
unsigned type) {
struct ertp_cache_item *item =
kmem_cache_zalloc(ertp_cache_allocator, GFP_KERNEL);
if (!item) {
return ERR_PTR(-ENOMEM);
}
INIT_LIST_HEAD(&item->time_list);
item->key = key;
item->ctime = ctime;
item->event_type = type;
return item;
}
static void ertp_cache_item_free(struct ertp_cache_item *item) {
kmem_cache_free(ertp_cache_allocator, item);
}
static inline int ertp_cache_key_cmp(const struct ertp_cache_key *key1,
const struct ertp_cache_key *key2) {
if (key1->ino < key2->ino) {
return -1;
}
if (key1->ino > key2->ino) {
return 1;
}
if (key1->dev < key2->dev) {
return -1;
}
if (key1->dev > key2->dev) {
return 1;
}
return 0;
}
struct ertp_cache_item *ertp_cache_container_find(
struct rb_root *root, const struct ertp_cache_key *key,
struct rb_node **parent) {
struct rb_node *p = NULL;
struct rb_node *node = root->rb_node;
struct ertp_cache_item *result = NULL;
while (node) {
struct rb_node *child;
struct ertp_cache_item *entry =
rb_entry(node, struct ertp_cache_item, node);
int cmp = ertp_cache_key_cmp(key, &entry->key);
if (cmp < 0) {
child = node->rb_left;
} else if (cmp > 0) {
child = node->rb_right;
} else {
result = entry;
break;
}
p = node;
node = child;
}
if (parent) {
*parent = p;
}
return result;
}
static void ertp_cache_container_insert(struct rb_root *root,
struct ertp_cache_item *item,
struct rb_node *parent) {
struct rb_node **link;
if (RB_EMPTY_ROOT(root)) {
link = &root->rb_node;
} else {
struct ertp_cache_item *parent_entry;
int cmp;
if (unlikely(parent == NULL)) {
BUG();
}
parent_entry = rb_entry(parent, struct ertp_cache_item, node);
cmp = ertp_cache_key_cmp(&item->key, &parent_entry->key);
if (cmp < 0) {
link = &parent->rb_left;
} else if (cmp > 0) {
link = &parent->rb_right;
} else {
BUG();
}
}
rb_link_node(&item->node, parent, link);
rb_insert_color(&item->node, root);
}
struct ertp_cache_item *ertp_cache_container_add(
struct rb_root *root, const struct ertp_cache_key *key,
ertp_timespec_t ctime, unsigned type) {
struct rb_node *parent = NULL;
struct ertp_cache_item *item = ertp_cache_container_find(root, key, &parent);
if (item) {
if (ertp_timespec_equal(item->ctime, ctime)) {
item->event_type |= type;
} else {
item->ctime = ctime;
item->event_type = type;
}
} else {
item = ertp_cache_item_new(*key, ctime, type);
if (unlikely(IS_ERR(item))) {
return NULL;
}
ertp_cache_container_insert(root, item, parent);
}
return item;
}
void ertp_cache_container_erase(struct rb_root *root,
struct ertp_cache_item *item) {
rb_erase(&item->node, root);
ertp_cache_item_free(item);
}
void ertp_cache_container_clear(struct rb_root *root) {
struct ertp_cache_item *item;
struct ertp_cache_item *tmp;
rbtree_postorder_for_each_entry_safe(item, tmp, root, node) {
ertp_pr_log(ERTP_LOG_CACHE,
"deleting item from cache with ino %lld and dev %lld",
item->key.ino, item->key.dev);
ertp_cache_item_free(item);
}
}