From f62a8026be3875afd38fb1899e1fa235c8f1a6fb Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Mon, 16 Jul 2012 13:51:09 -0400 Subject: libglusterfs,mount/fuse: implement gidcache mechanism in fuse-bridge This change genericizes the cache mechanism implemented in commit 8efd2845 into libglusterfs/src/gidcache.[ch] and adds fuse-bridge as a client. The cache mechanism is fundamentally equivalent, with some minor changes: - Change cache key from uid_t to uint64_t. - Modify the cache add logic to locate and use an entry with a matching ID, should it already exist. This addresses a bug in the existing mechanism where an expired entry supercedes a newly added entry in lookup, causing repeated adds and flushing of a cache bucket. The fuse group cache is disabled by default. It can be enabled via the 'gid-timeout' fuse-bridge translator option and accompanying mount option (i.e., '-o gid-timeout=1' for a 1s entry timeout). BUG: 800892 Change-Id: I0b34a2263ca48dbb154790a4a44fc70b733e9114 Signed-off-by: Brian Foster Reviewed-on: https://code.engineering.redhat.com/gerrit/1853 Reviewed-by: Vijay Bellur Tested-by: Vijay Bellur --- xlators/mount/fuse/src/fuse-bridge.c | 13 +++++++++ xlators/mount/fuse/src/fuse-bridge.h | 3 +++ xlators/mount/fuse/src/fuse-helpers.c | 42 ++++++++++++++++++++++++++++- xlators/mount/fuse/src/fuse-mem-types.h | 1 + xlators/mount/fuse/utils/mount.glusterfs.in | 5 ++++ 5 files changed, 63 insertions(+), 1 deletion(-) (limited to 'xlators/mount') diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 78f8c0125b0..07859c60a4a 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -4565,6 +4565,15 @@ init (xlator_t *this_xl) GF_ASSERT (ret == 0); } + GF_OPTION_INIT("gid-timeout", priv->gid_cache_timeout, int32, + cleanup_exit); + + if (gid_cache_init(&priv->gid_cache, priv->gid_cache_timeout) < 0) { + gf_log("glusterfs-fuse", GF_LOG_ERROR, "Failed to initialize " + "group cache."); + goto cleanup_exit; + } + cmd_args = &this_xl->ctx->cmd_args; fsname = cmd_args->volfile; if (!fsname && cmd_args->volfile_server) { @@ -4729,5 +4738,9 @@ struct volume_options options[] = { .type = GF_OPTION_TYPE_BOOL, .default_value = "false" }, + { .key = {"gid-timeout"}, + .type = GF_OPTION_TYPE_INT, + .default_value = "0" + }, { .key = {NULL} }, }; diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h index 6b0ba54819f..f9d897c3037 100644 --- a/xlators/mount/fuse/src/fuse-bridge.h +++ b/xlators/mount/fuse/src/fuse-bridge.h @@ -55,6 +55,7 @@ #include "list.h" #include "dict.h" #include "syncop.h" +#include "gidcache.h" #if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__) #define FUSE_OP_HIGH (FUSE_POLL + 1) @@ -109,6 +110,8 @@ struct fuse_private { gf_boolean_t acl; gf_boolean_t selinux; gf_boolean_t read_only; + int32_t gid_cache_timeout; + gid_cache_t gid_cache; gf_boolean_t enable_ino32; fdtable_t *fdtable; diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c index 55b60de1cd8..c582291a1d8 100644 --- a/xlators/mount/fuse/src/fuse-helpers.c +++ b/xlators/mount/fuse/src/fuse-helpers.c @@ -248,6 +248,46 @@ out: #endif /* GF_LINUX_HOST_OS */ } +/* + * Get the groups for the PID associated with this frame. If enabled, + * use the gid cache to reduce group list collection. + */ +static void get_groups(fuse_private_t *priv, call_frame_t *frame) +{ + int i; + const gid_list_t *gl; + gid_list_t agl; + + if (!priv->gid_cache_timeout) { + frame_fill_groups(frame); + return; + } + + gl = gid_cache_lookup(&priv->gid_cache, frame->root->pid); + if (gl) { + frame->root->ngrps = gl->gl_count; + for (i = 0; i < gl->gl_count; i++) + frame->root->groups[i] = gl->gl_list[i]; + gid_cache_release(&priv->gid_cache, gl); + return; + } + + frame_fill_groups (frame); + + agl.gl_id = frame->root->pid; + agl.gl_count = frame->root->ngrps; + agl.gl_list = GF_CALLOC(frame->root->ngrps, sizeof(gid_t), + gf_fuse_mt_gids_t); + if (!agl.gl_list) + return; + + for (i = 0; i < frame->root->ngrps; i++) + agl.gl_list[i] = frame->root->groups[i]; + + if (gid_cache_add(&priv->gid_cache, &agl) != 1) + GF_FREE(agl.gl_list); +} + call_frame_t * get_call_frame_for_req (fuse_state_t *state) { @@ -275,7 +315,7 @@ get_call_frame_for_req (fuse_state_t *state) state->lk_owner); } - frame_fill_groups (frame); + get_groups(priv, frame); if (priv && priv->client_pid_set) frame->root->pid = priv->client_pid; diff --git a/xlators/mount/fuse/src/fuse-mem-types.h b/xlators/mount/fuse/src/fuse-mem-types.h index 9c6a1c67a7a..d1c5e511b0e 100644 --- a/xlators/mount/fuse/src/fuse-mem-types.h +++ b/xlators/mount/fuse/src/fuse-mem-types.h @@ -31,6 +31,7 @@ enum gf_fuse_mem_types_ { gf_fuse_mt_fuse_state_t, gf_fuse_mt_fd_ctx_t, gf_fuse_mt_graph_switch_args_t, + gf_fuse_mt_gids_t, gf_fuse_mt_end }; #endif diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in index e11d79d29b2..f3d3839e8fa 100755 --- a/xlators/mount/fuse/utils/mount.glusterfs.in +++ b/xlators/mount/fuse/utils/mount.glusterfs.in @@ -105,6 +105,10 @@ start_glusterfs () cmd_line=$(echo "$cmd_line --volume-name=$volume_name"); fi + if [ -n "$gid_timeout" ]; then + cmd_line=$(echo "$cmd_line --gid-timeout=$gid_timeout"); + fi + if [ -z "$volfile_loc" ]; then if [ -n "$server_ip" ]; then if [ -n "$server_port" ]; then @@ -279,6 +283,7 @@ main () volfile_max_fetch_attempts=$value ;; "backupvolfile-server") backupvolfile_server=$value ;; + "gid-timeout") gid_timeout=$value ;; *) echo "unknown option $key (ignored)" ;; esac esac -- cgit