From 7018d7178e366146881d693e0159e13307e888ee Mon Sep 17 00:00:00 2001 From: Anand Avati Date: Wed, 18 Jul 2012 15:50:35 -0700 Subject: fuse-bridge: expose negative entry caching of FUSE Fuse kernel module supports caching negative entries, enabled by specifying a timeout while returning ENOENT to lookup. This patch enables the functionality to be enabled with the command line. Also fixed a typo bug in mount.glusterfs.in. Change-Id: I47eab2834cca9a05887266358afbf504bbb4c489 BUG: 841417 Signed-off-by: Anand Avati Reviewed-on: http://review.gluster.com/3696 Tested-by: Gluster Build System Reviewed-by: Brian Foster --- glusterfsd/src/glusterfsd.c | 25 +++++++++++++++++++++++++ glusterfsd/src/glusterfsd.h | 1 + libglusterfs/src/glusterfs.h | 2 ++ xlators/mount/fuse/src/fuse-bridge.c | 18 +++++++++++++++++- xlators/mount/fuse/src/fuse-bridge.h | 1 + xlators/mount/fuse/utils/mount.glusterfs.in | 7 ++++++- 6 files changed, 52 insertions(+), 2 deletions(-) diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c index 2b6ee54523b..5d5586625f8 100644 --- a/glusterfsd/src/glusterfsd.c +++ b/glusterfsd/src/glusterfsd.c @@ -178,6 +178,8 @@ static struct argp_option gf_options[] = { "\"on\" for fds not opened with O_RDONLY]"}, {"entry-timeout", ARGP_ENTRY_TIMEOUT_KEY, "SECONDS", 0, "Set entry timeout to SECONDS in fuse kernel module [default: 1]"}, + {"negative-timeout", ARGP_NEGATIVE_TIMEOUT_KEY, "SECONDS", 0, + "Set negative timeout to SECONDS in fuse kernel module [default: 0]"}, {"attribute-timeout", ARGP_ATTRIBUTE_TIMEOUT_KEY, "SECONDS", 0, "Set attribute timeout to SECONDS for inodes in fuse kernel module " "[default: 1]"}, @@ -302,6 +304,17 @@ create_fuse_mount (glusterfs_ctx_t *ctx) } } + if (cmd_args->fuse_negative_timeout >= 0) { + ret = dict_set_double (master->options, ZR_NEGATIVE_TIMEOUT_OPT, + cmd_args->fuse_negative_timeout); + if (ret < 0) { + gf_log ("glusterfsd", GF_LOG_ERROR, + "failed to set dict value for key %s", + ZR_NEGATIVE_TIMEOUT_OPT); + goto err; + } + } + if (cmd_args->client_pid_set) { ret = dict_set_int32 (master->options, "client-pid", cmd_args->client_pid); @@ -746,6 +759,18 @@ parse_opts (int key, char *arg, struct argp_state *state) argp_failure (state, -1, 0, "unknown entry timeout %s", arg); break; + case ARGP_NEGATIVE_TIMEOUT_KEY: + d = 0.0; + + gf_string2double (arg, &d); + if (!(d < 0.0)) { + cmd_args->fuse_negative_timeout = d; + break; + } + + argp_failure (state, -1, 0, "unknown negative timeout %s", arg); + break; + case ARGP_ATTRIBUTE_TIMEOUT_KEY: d = 0.0; diff --git a/glusterfsd/src/glusterfsd.h b/glusterfsd/src/glusterfsd.h index 75edff6a633..4f08cd31a60 100644 --- a/glusterfsd/src/glusterfsd.h +++ b/glusterfsd/src/glusterfsd.h @@ -63,6 +63,7 @@ enum argp_option_keys { ARGP_NO_DAEMON_KEY = 'N', ARGP_RUN_ID_KEY = 'r', ARGP_DEBUG_KEY = 133, + ARGP_NEGATIVE_TIMEOUT_KEY = 134, ARGP_ENTRY_TIMEOUT_KEY = 135, ARGP_ATTRIBUTE_TIMEOUT_KEY = 136, ARGP_VOLUME_NAME_KEY = 137, diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index d14666fb63d..5bd5d5437fe 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -66,6 +66,7 @@ #define ZR_MOUNTPOINT_OPT "mountpoint" #define ZR_ATTR_TIMEOUT_OPT "attribute-timeout" #define ZR_ENTRY_TIMEOUT_OPT "entry-timeout" +#define ZR_NEGATIVE_TIMEOUT_OPT "negative-timeout" #define ZR_DIRECT_IO_OPT "direct-io-mode" #define ZR_STRICT_VOLFILE_CHECK "strict-volfile-check" #define ZR_DUMP_FUSE "dump-fuse" @@ -293,6 +294,7 @@ struct _cmd_args { int fuse_direct_io_mode; int volfile_check; double fuse_entry_timeout; + double fuse_negative_timeout; double fuse_attribute_timeout; char *volume_name; int fuse_nodev; diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index b96d6017331..d4ca1d1f617 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -359,7 +359,15 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this, "%"PRIu64": %s() %s => -1 (%s)", frame->root->unique, gf_fop_list[frame->root->op], state->loc.path, strerror (op_errno)); - send_fuse_err (this, state->finh, op_errno); + if (op_errno == ENOENT) { + feo.entry_valid = + calc_timeout_sec (priv->negative_timeout); + feo.entry_valid_nsec = + calc_timeout_nsec (priv->negative_timeout); + send_fuse_obj (this, finh, &feo); + } else { + send_fuse_err (this, state->finh, op_errno); + } } free_fuse_state (state); @@ -4547,6 +4555,11 @@ init (xlator_t *this_xl) if (ret != 0) priv->entry_timeout = 1.0; /* default */ + ret = dict_get_double (options, "negative-timeout", + &priv->negative_timeout); + if (ret != 0) + priv->negative_timeout = 0.0; /* default */ + ret = dict_get_int32 (options, "client-pid", &priv->client_pid); if (ret == 0) @@ -4777,6 +4790,9 @@ struct volume_options options[] = { { .key = {ZR_ENTRY_TIMEOUT_OPT}, .type = GF_OPTION_TYPE_DOUBLE }, + { .key = {ZR_NEGATIVE_TIMEOUT_OPT}, + .type = GF_OPTION_TYPE_DOUBLE + }, { .key = {ZR_STRICT_VOLFILE_CHECK}, .type = GF_OPTION_TYPE_BOOL }, diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h index 5ffb285a28b..cb5eb600147 100644 --- a/xlators/mount/fuse/src/fuse-bridge.h +++ b/xlators/mount/fuse/src/fuse-bridge.h @@ -86,6 +86,7 @@ struct fuse_private { size_t *msg0_len_p; double entry_timeout; + double negative_timeout; double attribute_timeout; pthread_cond_t sync_cond; diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in index e585ba3b7fd..a0a31660ab3 100755 --- a/xlators/mount/fuse/utils/mount.glusterfs.in +++ b/xlators/mount/fuse/utils/mount.glusterfs.in @@ -125,13 +125,17 @@ start_glusterfs () fi if [ -n "$attribute_timeout" ]; then - cmd_line=$(echo "$cmd_line --attribute-time=$attribute_timeout"); + cmd_line=$(echo "$cmd_line --attribute-timeout=$attribute_timeout"); fi if [ -n "$entry_timeout" ]; then cmd_line=$(echo "$cmd_line --entry-timeout=$entry_timeout"); fi + if [ -n "$negative_timeout" ]; then + cmd_line=$(echo "$cmd_line --negative-timeout=$negative_timeout"); + fi + if [ -n "$gid_timeout" ]; then cmd_line=$(echo "$cmd_line --gid-timeout=$gid_timeout"); fi @@ -329,6 +333,7 @@ main () "attribute-timeout") attribute_timeout=$value ;; "entry-timeout") entry_timeout=$value ;; + "negative-timeout") negative_timeout=$value ;; "gid-timeout") gid_timeout=$value ;; *) echo "unknown option $key (ignored)" ;; esac -- cgit