From 59ff893d11844eb52453ce4f7f098df05fcde174 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: http://review.gluster.com/3676 Tested-by: Gluster Build System Reviewed-by: Jeff Darcy Reviewed-by: Anand Avati --- 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/fuse') diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 360e1443c..3a620ac7e 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -4604,6 +4604,15 @@ init (xlator_t *this_xl) GF_OPTION_INIT("fopen-keep-cache", priv->fopen_keep_cache, bool, cleanup_exit); + 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) { @@ -4768,5 +4777,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 dcd962924..bc35eb061 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) @@ -110,7 +111,9 @@ struct fuse_private { gf_boolean_t selinux; gf_boolean_t read_only; gf_boolean_t fopen_keep_cache; + int32_t gid_cache_timeout; fdtable_t *fdtable; + gid_cache_t gid_cache; /* For fuse-reverse-validation */ int revchan_in; diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c index bcad97fc7..729c8fb2c 100644 --- a/xlators/mount/fuse/src/fuse-helpers.c +++ b/xlators/mount/fuse/src/fuse-helpers.c @@ -245,6 +245,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) { @@ -272,7 +312,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 9c6a1c67a..d1c5e511b 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 b623d3428..e585ba3b7 100755 --- a/xlators/mount/fuse/utils/mount.glusterfs.in +++ b/xlators/mount/fuse/utils/mount.glusterfs.in @@ -132,6 +132,10 @@ start_glusterfs () cmd_line=$(echo "$cmd_line --entry-timeout=$entry_timeout"); fi + if [ -n "$gid_timeout" ]; then + cmd_line=$(echo "$cmd_line --gid-timeout=$gid_timeout"); + fi + if [ -n "$fopen_keep_cache" ]; then cmd_line=$(echo "$cmd_line --fopen-keep-cache"); fi @@ -325,6 +329,7 @@ main () "attribute-timeout") attribute_timeout=$value ;; "entry-timeout") entry_timeout=$value ;; + "gid-timeout") gid_timeout=$value ;; *) echo "unknown option $key (ignored)" ;; esac esac -- cgit