diff options
| author | Brian Foster <bfoster@redhat.com> | 2012-07-16 13:51:09 -0400 |
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2012-12-12 00:12:01 -0500 |
| commit | f62a8026be3875afd38fb1899e1fa235c8f1a6fb (patch) | |
| tree | 979e00e416f3bdcabce611f7d65d7a695651df5a | |
| parent | 19a8495a01702b94343c8e252396a13f6d70d09d (diff) | |
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 <bfoster@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/1853
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Tested-by: Vijay Bellur <vbellur@redhat.com>
| -rw-r--r-- | glusterfsd/src/glusterfsd.c | 22 | ||||
| -rw-r--r-- | glusterfsd/src/glusterfsd.h | 1 | ||||
| -rw-r--r-- | libglusterfs/src/Makefile.am | 5 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 13 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.h | 3 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-helpers.c | 42 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-mem-types.h | 1 | ||||
| -rwxr-xr-x | xlators/mount/fuse/utils/mount.glusterfs.in | 5 |
8 files changed, 88 insertions, 4 deletions
diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c index 90f12e9f77b..9e21204929f 100644 --- a/glusterfsd/src/glusterfsd.c +++ b/glusterfsd/src/glusterfsd.c @@ -182,6 +182,9 @@ static struct argp_option gf_options[] = { {"attribute-timeout", ARGP_ATTRIBUTE_TIMEOUT_KEY, "SECONDS", 0, "Set attribute timeout to SECONDS for inodes in fuse kernel module " "[default: 1]"}, + {"gid-timeout", ARGP_GID_TIMEOUT_KEY, "SECONDS", 0, + "Set auxilary group list timeout to SECONDS for fuse translator " + "[default: 0]"}, {"client-pid", ARGP_CLIENT_PID_KEY, "PID", OPTION_HIDDEN, "client will authenticate itself with process id PID to server"}, {"user-map-root", ARGP_USER_MAP_ROOT_KEY, "USER", OPTION_HIDDEN, @@ -382,6 +385,16 @@ create_fuse_mount (glusterfs_ctx_t *ctx) } } + if (cmd_args->gid_timeout) { + ret = dict_set_int32(master->options, "gid-timeout", + cmd_args->gid_timeout); + if (ret < 0) { + gf_log("glusterfsd", GF_LOG_ERROR, "failed to set dict " + "value for key gid-timeout"); + goto err; + } + } + switch (cmd_args->fuse_direct_io_mode) { case GF_OPTION_DISABLE: /* disable */ ret = dict_set_static_ptr (master->options, ZR_DIRECT_IO_OPT, @@ -828,7 +841,14 @@ parse_opts (int key, char *arg, struct argp_state *state) ctx = glusterfs_ctx_get (); ctx->mem_accounting = 1; break; - } + + case ARGP_GID_TIMEOUT_KEY: + if (!gf_string2int(arg, &cmd_args->gid_timeout)) + break; + + argp_failure(state, -1, 0, "unknown group list timeout %s", arg); + break; + } return 0; } diff --git a/glusterfsd/src/glusterfsd.h b/glusterfsd/src/glusterfsd.h index e832b87a21a..03585cf22ee 100644 --- a/glusterfsd/src/glusterfsd.h +++ b/glusterfsd/src/glusterfsd.h @@ -89,6 +89,7 @@ enum argp_option_keys { ARGP_SELINUX_KEY = 158, /* glusterfs upstream includes options 159-162, but we dont */ ARGP_INODE32_KEY = 159, /* 163 upstream */ + ARGP_GID_TIMEOUT_KEY = 160, }; struct _gfd_vol_top_priv_t { diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am index dd07aaa4ea7..798b309093a 100644 --- a/libglusterfs/src/Makefile.am +++ b/libglusterfs/src/Makefile.am @@ -23,7 +23,8 @@ libglusterfs_la_SOURCES = dict.c xlator.c logging.c \ $(CONTRIBDIR)/uuid/uuid_time.c $(CONTRIBDIR)/uuid/compare.c \ $(CONTRIBDIR)/uuid/isnull.c $(CONTRIBDIR)/uuid/unpack.c syncop.c \ $(CONTRIBDIR)/stdlib/gf_mkostemp.c \ - graph-print.c trie.c run.c options.c fd-lk.c circ-buff.c event-history.c + graph-print.c trie.c run.c options.c fd-lk.c circ-buff.c \ + event-history.c gidcache.c nodist_libglusterfs_la_SOURCES = y.tab.c graph.lex.c @@ -37,7 +38,7 @@ noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h \ rbthash.h iatt.h latency.h mem-types.h $(CONTRIBDIR)/uuid/uuidd.h \ $(CONTRIBDIR)/uuid/uuid.h $(CONTRIBDIR)/uuid/uuidP.h \ $(CONTRIB_BUILDDIR)/uuid/uuid_types.h syncop.h graph-utils.h trie.h run.h \ - options.h lkowner.h fd-lk.h circ-buff.h event-history.h + options.h lkowner.h fd-lk.h circ-buff.h event-history.h gidcache.h EXTRA_DIST = graph.l graph.y 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 |
