mirror of
https://github.com/trapexit/mergerfs.git
synced 2026-10-26 19:01:56 -04:00
Simplify lowlevel fuse state management and req mem
This commit is contained in:
parent
9a261ca3a0
commit
d5cdd553b5
14 changed files with 376 additions and 307 deletions
|
|
@ -150,7 +150,7 @@ struct fuse_operations
|
|||
int (*fsyncdir)(const fuse_req_ctx_t *,
|
||||
const fuse_file_info_t *,
|
||||
int);
|
||||
void *(*init)(struct fuse_conn_info *conn);
|
||||
void *(*init)(fuse_conn_info_t *conn);
|
||||
void (*destroy)(void);
|
||||
int (*access)(const fuse_req_ctx_t *,
|
||||
const char *,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "extern_c.h"
|
||||
#include "fuse_conn_info.hpp"
|
||||
#include "fuse_opt.h"
|
||||
#include "fuse_timeouts.h"
|
||||
|
||||
|
|
@ -76,7 +77,7 @@ struct fuse_file_info_t
|
|||
};
|
||||
|
||||
/**
|
||||
* Capability bits for 'fuse_conn_info.capable' and 'fuse_conn_info.want'
|
||||
* Capability bits for 'fuse_conn_info_t.capable' and 'fuse_conn_info_t.want'
|
||||
*
|
||||
* FUSE_CAP_ASYNC_READ: filesystem supports asynchronous read requests
|
||||
* FUSE_CAP_POSIX_LOCKS: filesystem supports "remote" locking
|
||||
|
|
@ -128,21 +129,6 @@ struct fuse_file_info_t
|
|||
|
||||
#define FUSE_IOCTL_MAX_IOV 256
|
||||
|
||||
/**
|
||||
* Connection information, passed to the ->init() method
|
||||
*
|
||||
* Some of the elements are read-write, these can be changed to
|
||||
* indicate the value requested by the filesystem. The requested
|
||||
* value must usually be smaller than the indicated value.
|
||||
*/
|
||||
struct fuse_conn_info
|
||||
{
|
||||
unsigned proto_major;
|
||||
unsigned proto_minor;
|
||||
uint64_t capable;
|
||||
uint64_t want;
|
||||
};
|
||||
|
||||
struct fuse_session;
|
||||
struct fuse_chan;
|
||||
struct fuse_pollhandle_t;
|
||||
|
|
|
|||
12
libfuse/include/fuse_conn_info.hpp
Normal file
12
libfuse/include/fuse_conn_info.hpp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "base_types.h"
|
||||
|
||||
typedef struct fuse_conn_info_t fuse_conn_info_t;
|
||||
struct fuse_conn_info_t
|
||||
{
|
||||
u32 proto_major;
|
||||
u32 proto_minor;
|
||||
u64 capable;
|
||||
u64 want;
|
||||
};
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
#include "extern_c.h"
|
||||
#include "fuse_common.h"
|
||||
#include "fuse_kernel.h"
|
||||
#include "fuse_req.h"
|
||||
#include "fuse_req.hpp"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
|
|
@ -119,7 +119,7 @@ struct fuse_lowlevel_ops
|
|||
void (*getattr)(fuse_req_t *req, struct fuse_in_header *hdr);
|
||||
void (*getlk)(fuse_req_t *req, const struct fuse_in_header *hdr);
|
||||
void (*getxattr)(fuse_req_t *req, struct fuse_in_header *hdr);
|
||||
void (*init)(void *userdata, struct fuse_conn_info *conn);
|
||||
void (*init)(void *userdata, fuse_conn_info_t *conn);
|
||||
void (*ioctl)(fuse_req_t *req, const struct fuse_in_header *hdr);
|
||||
void (*link)(fuse_req_t *req, struct fuse_in_header *hdr);
|
||||
void (*listxattr)(fuse_req_t *req, struct fuse_in_header *hdr);
|
||||
|
|
|
|||
|
|
@ -3,12 +3,10 @@
|
|||
#include <stdint.h>
|
||||
|
||||
struct fuse_chan;
|
||||
struct fuse_ll;
|
||||
|
||||
typedef struct fuse_pollhandle_t fuse_pollhandle_t;
|
||||
struct fuse_pollhandle_t
|
||||
{
|
||||
uint64_t kh;
|
||||
struct fuse_chan *ch;
|
||||
struct fuse_ll *f;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,15 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "fuse_req_ctx.h"
|
||||
#include "fuse_conn_info.hpp"
|
||||
|
||||
struct fuse_ll;
|
||||
struct fuse_chan;
|
||||
|
||||
typedef struct fuse_req_t fuse_req_t;
|
||||
struct fuse_req_t
|
||||
{
|
||||
fuse_req_ctx_t ctx;
|
||||
struct fuse_ll *f;
|
||||
struct fuse_chan *ch;
|
||||
fuse_conn_info_t conn;
|
||||
unsigned int ioctl_64bit : 1;
|
||||
};
|
||||
|
||||
fuse_req_t* fuse_req_alloc();
|
||||
void fuse_req_free(fuse_req_t*);
|
||||
136
libfuse/include/objpool.hpp
Normal file
136
libfuse/include/objpool.hpp
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
ISC License
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <new>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
template<typename T>
|
||||
class ObjPool
|
||||
{
|
||||
private:
|
||||
struct alignas(alignof(T)) Node
|
||||
{
|
||||
Node *next;
|
||||
};
|
||||
|
||||
private:
|
||||
static_assert(sizeof(T) >= sizeof(Node), "T must be at least pointer-sized");
|
||||
static_assert(std::is_nothrow_destructible_v<T>, "T must be nothrow destructible");
|
||||
|
||||
private:
|
||||
static
|
||||
Node*
|
||||
to_node(T *obj_)
|
||||
{
|
||||
return reinterpret_cast<Node*>(obj_);
|
||||
}
|
||||
|
||||
private:
|
||||
std::mutex _mtx;
|
||||
Node *_head = nullptr;
|
||||
|
||||
public:
|
||||
ObjPool() = default;
|
||||
ObjPool(const ObjPool&) = delete;
|
||||
ObjPool& operator=(const ObjPool&) = delete;
|
||||
ObjPool(ObjPool&&) = delete;
|
||||
ObjPool& operator=(ObjPool&&) = delete;
|
||||
|
||||
~ObjPool()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
private:
|
||||
Node*
|
||||
_pop_node()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mtx);
|
||||
|
||||
Node *node = _head;
|
||||
if(node)
|
||||
_head = node->next;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void
|
||||
_push_node(Node *node_)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mtx);
|
||||
|
||||
node_->next = _head;
|
||||
_head = node_;
|
||||
}
|
||||
|
||||
public:
|
||||
void
|
||||
clear() noexcept
|
||||
{
|
||||
Node *head;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mtx);
|
||||
head = _head;
|
||||
_head = nullptr;
|
||||
}
|
||||
|
||||
while(head)
|
||||
{
|
||||
Node *next = head->next;
|
||||
::operator delete(head, std::align_val_t{alignof(T)});
|
||||
head = next;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
T*
|
||||
alloc(Args&&... args_)
|
||||
{
|
||||
void *mem;
|
||||
Node *node;
|
||||
|
||||
node = _pop_node();
|
||||
mem = (node ?
|
||||
static_cast<void*>(node) :
|
||||
::operator new(sizeof(T), std::align_val_t{alignof(T)}));
|
||||
|
||||
try
|
||||
{
|
||||
return new(mem) T(std::forward<Args>(args_)...);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
_push_node(static_cast<Node*>(mem));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
free(T *obj_) noexcept
|
||||
{
|
||||
if(not obj_)
|
||||
return;
|
||||
|
||||
obj_->~T();
|
||||
|
||||
_push_node(to_node(obj_));
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue