opt
/
kaspersky
/
kav4fs
/
src
/
kernel
/
redirfs
➕ New
📤 Upload
✎ Editing:
rfs_flt.c
← Back
/* * RedirFS: Redirecting File System * Written by Frantisek Hrbata <frantisek.hrbata@redirfs.org> * * Copyright 2008 - 2010 Frantisek Hrbata * All rights reserved. * * This file is part of RedirFS. * * RedirFS 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. * * RedirFS 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 RedirFS. If not, see <http://www.gnu.org/licenses/>. */ #include "rfs.h" static LIST_HEAD(rfs_flt_list); static RFS_DEFINE_MUTEX(rfs_flt_list_mutex); static struct rfs_flt* rfs_flt_alloc(struct redirfs_filter_info* flt_info) { struct rfs_flt* rflt; char* name; int len; len = strlen(flt_info->name); name = kzalloc(len + 1, GFP_KERNEL); if (!name) return ERR_PTR(-ENOMEM); strncpy(name, flt_info->name, len); rflt = kzalloc(sizeof(struct rfs_flt), GFP_KERNEL); if (!rflt) { kfree(name); return ERR_PTR(-ENOMEM); } INIT_LIST_HEAD(&rflt->list); rflt->name = name; rflt->priority = flt_info->priority; rflt->owner = flt_info->owner; rflt->ops = flt_info->ops; spin_lock_init(&rflt->lock); atomic_set(&rflt->count, 1); try_module_get(rflt->owner); return rflt; } struct rfs_flt* rfs_flt_get(struct rfs_flt* rflt) { if (!rflt || IS_ERR(rflt)) return NULL; spin_lock(&rflt->lock); BUG_ON(atomic_read(&rflt->count) < 1); atomic_inc(&rflt->count); spin_unlock(&rflt->lock); return rflt; } void rfs_flt_put(struct rfs_flt* rflt) { if (!rflt || IS_ERR(rflt)) return; spin_lock(&rflt->lock); BUG_ON(atomic_read(&rflt->count) <= 1); atomic_dec(&rflt->count); spin_unlock(&rflt->lock); return; } static int rfs_flt_exist(const char* name, int priority) { struct rfs_flt* rflt; list_for_each_entry(rflt, &rfs_flt_list, list) { if (rflt->priority == priority) return 1; if (!strcmp(rflt->name, name)) return 1; } return 0; } redirfs_filter redirfs_register_filter(struct redirfs_filter_info* info) { struct rfs_flt* rflt; might_sleep(); if (!info) return ERR_PTR(-EINVAL); rfs_mutex_lock(&rfs_flt_list_mutex); if (rfs_flt_exist(info->name, info->priority)) { rfs_mutex_unlock(&rfs_flt_list_mutex); return ERR_PTR(-EEXIST); } rflt = rfs_flt_alloc(info); if (IS_ERR(rflt)) { rfs_mutex_unlock(&rfs_flt_list_mutex); return (redirfs_filter)rflt; } list_add_tail(&rflt->list, &rfs_flt_list); rfs_mutex_unlock(&rfs_flt_list_mutex); return (redirfs_filter)rflt; } int redirfs_unregister_filter(redirfs_filter filter) { struct rfs_flt* rflt = (struct rfs_flt*)filter; might_sleep(); if (!rflt || IS_ERR(rflt)) return -EINVAL; if (rflt->paths_nr) return -EBUSY; for (;;) { switch (atomic_cmpxchg(&rflt->count, 1, 0)) { case 1: rfs_mutex_lock(&rfs_flt_list_mutex); list_del_init(&rflt->list); rfs_mutex_unlock(&rfs_flt_list_mutex); module_put(rflt->owner); kfree(rflt->name); kfree(rflt); case 0: return 0; default: msleep(1); } } return -EBUSY; } static int rfs_flt_set_ops(struct rfs_flt* rflt) { struct rfs_root* rroot; struct rfs_info* rinfo; int rv; list_for_each_entry(rroot, &rfs_root_list, list) { if (rfs_chain_find(rroot->rinfo->rchain, rflt) == -1) continue; rinfo = rfs_info_alloc(rroot, rroot->rinfo->rchain); if (IS_ERR(rinfo)) return PTR_ERR(rinfo); rv = rfs_info_reset(rroot->dentry, rinfo); if (rv) { rfs_info_put(rinfo); return rv; } rfs_info_put(rroot->rinfo); rroot->rinfo = rinfo; } return 0; } int redirfs_set_operations(redirfs_filter filter, struct redirfs_op_info ops[]) { struct rfs_flt* rflt = (struct rfs_flt*)filter; int i = 0; int rv = 0; might_sleep(); if (!rflt || IS_ERR(rflt)) return -EINVAL; while (ops[i].op_id != REDIRFS_OP_END) { rflt->cbs[ops[i].op_id].pre_cb = ops[i].pre_cb; rflt->cbs[ops[i].op_id].post_cb = ops[i].post_cb; i++; } rfs_mutex_lock(&rfs_path_mutex); rv = rfs_flt_set_ops(rflt); rfs_mutex_unlock(&rfs_path_mutex); return rv; } EXPORT_SYMBOL(redirfs_register_filter); EXPORT_SYMBOL(redirfs_unregister_filter); EXPORT_SYMBOL(redirfs_set_operations);
💾 Save Changes
Cancel
📤 Upload File
×
Select File
Upload
Cancel
➕ Create New
×
Type
📄 File
📁 Folder
Name
Create
Cancel
✎ Rename Item
×
Current Name
New Name
Rename
Cancel
🔐 Change Permissions
×
Target File
Permission (e.g., 0755, 0644)
0755
0644
0777
Apply
Cancel