Skip to content

Commit 2ebecb4

Browse files
haolianglhlihuiba
authored andcommitted
fuse-adaptor:Add splice api for all loop mode
This patch adds splice I/O support to the fuse request receive process for all three loop modes. Due to some invisible struct definitions in the libfuse code, parts of the libfuse interfaces have to be rewritten, which are all placed in fuse-compat.cpp. For the same reason, we cannot automatically switch between splice(2) and read(2) as libfuse does internally, so currently only the forced splice method and the normal read interface are supported.
1 parent a16a0b9 commit 2ebecb4

5 files changed

Lines changed: 359 additions & 48 deletions

File tree

fs/fuse_adaptor/fuse_adaptor.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,9 @@ int fuser_go_exportfs(IFileSystem *fs_, int argc, char *argv[]) {
8686
return 0;
8787
}
8888

89-
static int fuse_session_loop_mpt(struct fuse_session *se,
90-
uint64_t looptype = FUSE_SESSION_LOOP_EPOLL) {
91-
auto loop = new_session_loop(se, looptype);
92-
loop->run();
93-
delete loop;
94-
return 0;
95-
}
96-
9789
struct user_config {
9890
int threads;
91+
int force_splice_read;
9992
char *looptype;
10093
};
10194

@@ -117,6 +110,7 @@ uint64_t find_looptype(const char *name) {
117110

118111
#define USER_OPT(t, p, v) { t, offsetof(struct user_config, p), v }
119112
struct fuse_opt user_opts[] = { USER_OPT("threads=%d", threads, 0),
113+
USER_OPT("force_splice_read=%d", force_splice_read, 0),
120114
USER_OPT("looptype=%s", looptype, 0),
121115
FUSE_OPT_END };
122116
struct fuse_handle {
@@ -126,6 +120,7 @@ struct fuse_handle {
126120
char *mountpoint = NULL;
127121
int multithreaded = 1;
128122
int threads = 4;
123+
int force_splice_read = 0;
129124
void *userdata = NULL;
130125

131126
int setup(
@@ -136,16 +131,18 @@ struct fuse_handle {
136131
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
137132
DEFER(fuse_opt_free_args(&args));
138133

139-
struct user_config cfg{ .threads = 4, .looptype = NULL};
134+
struct user_config cfg{ .threads = 4, .force_splice_read = 0, .looptype = NULL};
140135
fuse_opt_parse(&args, &cfg, user_opts, NULL);
141136
threads = cfg.threads;
142137
if (cfg.looptype)
143138
looptype = find_looptype(cfg.looptype);
144139
#if FUSE_USE_VERSION < FUSE_MAKE_VERSION(3, 13)
145140
looptype = FUSE_SESSION_LOOP_EPOLL;
146141
#endif
142+
force_splice_read = cfg.force_splice_read;
147143
LOG_INFO("session cfg loop type: `", VALUE(cfg.looptype),
148-
" loop type: `", VALUE(looptype));
144+
" loop type: `", VALUE(looptype),
145+
" splice_read: `", VALUE(cfg.force_splice_read));
149146

150147
#if FUSE_USE_VERSION < FUSE_MAKE_VERSION(3, 0)
151148
if (!ops) {
@@ -238,6 +235,17 @@ struct fuse_handle {
238235
}
239236
};
240237

238+
static int fuse_session_loop_mpt(struct fuse_session *se,
239+
const struct fuse_handle &fh) {
240+
loop_args args;
241+
args.looptype = fh.looptype;
242+
args.force_splice_read = fh.force_splice_read;
243+
auto loop = new_session_loop(se, args);
244+
loop->run();
245+
delete loop;
246+
return 0;
247+
}
248+
241249
static int _run_fuse(int argc, char *argv[],
242250
const struct ::fuse_operations *op,
243251
const struct ::fuse_lowlevel_ops *llops,
@@ -265,13 +273,13 @@ static int _run_fuse(int argc, char *argv[],
265273
ths.emplace_back(std::thread([&]() {
266274
init(INIT_EVENT_EPOLL, INIT_IO_LIBAIO);
267275
DEFER(fini());
268-
if (fuse_session_loop_mpt(se, fh.looptype) != 0) ret = -1;
276+
if (fuse_session_loop_mpt(se, fh) != 0) ret = -1;
269277
}));
270278
}
271279
for (auto& th : ths) th.join();
272280
fuse_session_reset(se);
273281
} else {
274-
ret = fuse_session_loop_mpt(se);
282+
ret = fuse_session_loop_mpt(se, fh);
275283
fuse_session_reset(se);
276284
}
277285

0 commit comments

Comments
 (0)