From 6e25f9317b5ad4846971cf7c148d6c22f080c74e Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Tue, 5 May 2020 00:17:47 -0400 Subject: [PATCH] ceph-fuse: add connection args parsing support for libfuse > 3.0 Since 3.0 some options are moved to connection part. The following options are recognized and should be parsed and applied to the connection: -o max_write=N sets conn->max_write -o max_readahead=N sets conn->max_readahead -o max_background=N sets conn->max_background -o congestion_threshold=N sets conn->congestion_threshold -o async_read sets FUSE_CAP_ASYNC_READ in conn->want -o sync_read unsets FUSE_CAP_ASYNC_READ in conn->want -o atomic_o_trunc sets FUSE_CAP_ATOMIC_O_TRUNC in conn->want -o no_remote_lock Equivalent to -o no_remote_flock,no_remote_posix_lock -o no_remote_flock Unsets FUSE_CAP_FLOCK_LOCKS in conn->want -o no_remote_posix_lock Unsets FUSE_CAP_POSIX_LOCKS in conn->want -o [no_]splice_write (un-)sets FUSE_CAP_SPLICE_WRITE in conn->want -o [no_]splice_move (un-)sets FUSE_CAP_SPLICE_MOVE in conn->want -o [no_]splice_read (un-)sets FUSE_CAP_SPLICE_READ in conn->want -o [no_]auto_inval_data (un-)sets FUSE_CAP_AUTO_INVAL_DATA in conn->want -o readdirplus=no unsets FUSE_CAP_READDIRPLUS in conn->want -o readdirplus=yes sets FUSE_CAP_READDIRPLUS and unsets FUSE_CAP_READDIRPLUS_AUTO in conn->want -o readdirplus=auto sets FUSE_CAP_READDIRPLUS and FUSE_CAP_READDIRPLUS_AUTO in conn->want -o [no_]async_dio (un-)sets FUSE_CAP_ASYNC_DIO in conn->want -o [no_]writeback_cache (un-)sets FUSE_CAP_WRITEBACK_CACHE in conn->want -o time_gran=N sets conn->time_gran Fixes: https://tracker.ceph.com/issues/45267 Signed-off-by: Xiubo Li --- src/client/fuse_ll.cc | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/client/fuse_ll.cc b/src/client/fuse_ll.cc index 16f4d12abd0d5..7cec8d70b9be2 100644 --- a/src/client/fuse_ll.cc +++ b/src/client/fuse_ll.cc @@ -88,6 +88,7 @@ public: struct fuse_session *se; #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0) struct fuse_cmdline_opts opts; + struct fuse_conn_info_opts *conn_opts; #else struct fuse_chan *ch; char *mountpoint; @@ -989,6 +990,10 @@ static void do_init(void *data, fuse_conn_info *conn) CephFuse::Handle *cfuse = (CephFuse::Handle *)data; Client *client = cfuse->client; +#if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0) + fuse_apply_conn_info_opts(cfuse->conn_opts, conn); +#endif + #if !defined(__APPLE__) if (!client->fuse_default_permissions && client->ll_handle_umask()) { // apply umask in userspace if posix acl is enabled @@ -1105,6 +1110,8 @@ void CephFuse::Handle::finalize() fuse_session_unmount(se); fuse_session_destroy(se); } + if (conn_opts) + free(conn_opts); if (opts.mountpoint) free(opts.mountpoint); #else @@ -1132,7 +1139,7 @@ int CephFuse::Handle::init(int argc, const char *argv[]) // set up fuse argc/argv int newargc = 0; - const char **newargv = (const char **) malloc((argc + 10) * sizeof(char *)); + const char **newargv = (const char **) malloc((argc + 11) * sizeof(char *)); if(!newargv) return ENOMEM; @@ -1146,11 +1153,11 @@ int CephFuse::Handle::init(int argc, const char *argv[]) #if FUSE_VERSION < FUSE_MAKE_VERSION(3, 0) auto fuse_big_writes = client->cct->_conf.get_val( "fuse_big_writes"); +#endif auto fuse_max_write = client->cct->_conf.get_val( "fuse_max_write"); auto fuse_atomic_o_trunc = client->cct->_conf.get_val( "fuse_atomic_o_trunc"); -#endif auto fuse_debug = client->cct->_conf.get_val( "fuse_debug"); @@ -1168,6 +1175,7 @@ int CephFuse::Handle::init(int argc, const char *argv[]) newargv[newargc++] = "-o"; newargv[newargc++] = "big_writes"; } +#endif if (fuse_max_write > 0) { char strsplice[65]; newargv[newargc++] = "-o"; @@ -1178,7 +1186,6 @@ int CephFuse::Handle::init(int argc, const char *argv[]) newargv[newargc++] = "-o"; newargv[newargc++] = "atomic_o_trunc"; } -#endif #endif if (fuse_debug) newargv[newargc++] = "-d"; @@ -1201,6 +1208,17 @@ int CephFuse::Handle::init(int argc, const char *argv[]) return EINVAL; } +#if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0) + derr << "init, args.argv = " << args.argv << " args.argc=" << args.argc << dendl; + conn_opts = fuse_parse_conn_info_opts(&args); + if (!conn_opts) { + derr << "fuse_parse_conn_info_opts failed" << dendl; + fuse_opt_free_args(&args); + free(newargv); + return EINVAL; + } +#endif + ceph_assert(args.allocated); // Checking fuse has realloc'd args so we can free newargv free(newargv); return 0; @@ -1210,6 +1228,10 @@ int CephFuse::Handle::start() { #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0) se = fuse_session_new(&args, &fuse_ll_oper, sizeof(fuse_ll_oper), this); + if (!se) { + derr << "fuse_session_new failed" << dendl; + return EDOM; + } #else ch = fuse_mount(mountpoint, &args); if (!ch) { @@ -1218,11 +1240,11 @@ int CephFuse::Handle::start() } se = fuse_lowlevel_new(&args, &fuse_ll_oper, sizeof(fuse_ll_oper), this); -#endif if (!se) { derr << "fuse_lowlevel_new failed" << dendl; return EDOM; } +#endif signal(SIGTERM, SIG_DFL); signal(SIGINT, SIG_DFL); -- 2.39.5