mount/fuse: Provide option to use/not use kernel-readdirp

By default fuse kernel readdirp usage in fuse xlator is off.
When mount option use-readdirp=yes is provided it starts using
fuse-kernel's readdirp.

Change-Id: Id37edc53b1adc1638186d956c2f74c1e4e48aa59
BUG: 983477
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Reviewed-on: http://review.gluster.org/5322
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
This commit is contained in:
Pranith Kumar K 2013-07-11 12:52:11 +05:30 committed by Vijay Bellur
parent 07833f13d4
commit 61b09562b9
7 changed files with 98 additions and 2 deletions
glusterfsd/src
libglusterfs/src
tests/bugs
xlators/mount/fuse

@ -198,6 +198,9 @@ static struct argp_option gf_options[] = {
"Enable internal memory accounting"},
{"fuse-mountopts", ARGP_FUSE_MOUNTOPTS_KEY, "OPTIONS", OPTION_HIDDEN,
"Extra mount options to pass to FUSE"},
{"use-readdirp", ARGP_FUSE_USE_READDIRP_KEY, "BOOL", OPTION_ARG_OPTIONAL,
"Use readdirp mode in fuse kernel module"
" [default: \"off\"]"},
{0, 0, 0, 0, "Miscellaneous Options:"},
{0, }
};
@ -440,6 +443,16 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
goto err;
}
}
if (cmd_args->use_readdirp) {
ret = dict_set_str (options, "use-readdirp",
cmd_args->use_readdirp);
if (ret < 0) {
gf_log ("glusterfsd", GF_LOG_ERROR, "failed to set dict"
" value for key use-readdirp");
goto err;
}
}
ret = 0;
err:
return ret;
@ -949,6 +962,25 @@ parse_opts (int key, char *arg, struct argp_state *state)
case ARGP_FUSE_MOUNTOPTS_KEY:
cmd_args->fuse_mountopts = gf_strdup (arg);
break;
case ARGP_FUSE_USE_READDIRP_KEY:
if (!arg)
arg = "no";
if (gf_string2boolean (arg, &b) == 0) {
if (b) {
cmd_args->use_readdirp = "yes";
} else {
cmd_args->use_readdirp = "no";
}
break;
}
argp_failure (state, -1, 0,
"unknown use-readdirp setting \"%s\"", arg);
break;
}
return 0;

@ -84,6 +84,7 @@ enum argp_option_keys {
ARGP_FUSE_CONGESTION_THRESHOLD_KEY = 162,
ARGP_INODE32_KEY = 163,
ARGP_FUSE_MOUNTOPTS_KEY = 164,
ARGP_FUSE_USE_READDIRP_KEY = 165,
};
struct _gfd_vol_top_priv_t {

@ -321,6 +321,7 @@ struct _cmd_args {
/* fuse options */
int fuse_direct_io_mode;
char *use_readdirp;
int volfile_check;
double fuse_entry_timeout;
double fuse_negative_timeout;

45
tests/bugs/bug-983477.t Executable file

@ -0,0 +1,45 @@
#!/bin/bash
. $(dirname $0)/../include.rc
. $(dirname $0)/../volume.rc
#This script checks if use-readdirp option works as accepted in mount options
function get_use_readdirp_value {
local vol=$1
local statedump=$(generate_mount_statedump $vol)
local val=$(grep "use_readdirp=" $statedump | cut -f2 -d'=' | tail -1)
rm -f $statedump
echo $val
}
cleanup;
TEST glusterd
TEST pidof glusterd
TEST $CLI volume create $V0 $H0:$B0/${V0}
TEST $CLI volume start $V0
#If readdirp is enabled statedump should reflect it
TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0 --use-readdirp=yes
TEST cd $M0
EXPECT_WITHIN 20 "1" get_use_readdirp_value $V0
TEST cd -
TEST umount $M0
#If readdirp is enabled statedump should reflect it
TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0 --use-readdirp=no
TEST cd $M0
EXPECT_WITHIN 20 "0" get_use_readdirp_value $V0
TEST cd -
TEST umount $M0
#By default it is disabled.
TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0
TEST cd $M0
EXPECT_WITHIN 20 "0" get_use_readdirp_value $V0
TEST cd -
TEST umount $M0
#Invalid values for use-readdirp should not be accepted
TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0 --use-readdirp=please-fail
cleanup

@ -3752,8 +3752,10 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)
if (fini->minor < 9)
*priv->msg0_len_p = sizeof(*finh) + FUSE_COMPAT_WRITE_IN_SIZE;
#endif
if (fini->flags & FUSE_DO_READDIRPLUS)
fino.flags |= FUSE_DO_READDIRPLUS;
if (priv->use_readdirp) {
if (fini->flags & FUSE_DO_READDIRPLUS)
fino.flags |= FUSE_DO_READDIRPLUS;
}
if (fini->flags & FUSE_ASYNC_DIO)
fino.flags |= FUSE_ASYNC_DIO;
@ -4728,6 +4730,7 @@ fuse_priv_dump (xlator_t *this)
(int)private->strict_volfile_check);
gf_proc_dump_write("reverse_thread_started", "%d",
(int)private->reverse_fuse_thread_started);
gf_proc_dump_write("use_readdirp", "%d", private->use_readdirp);
return 0;
}
@ -5115,6 +5118,8 @@ init (xlator_t *this_xl)
GF_OPTION_INIT ("enable-ino32", priv->enable_ino32, bool, cleanup_exit);
GF_OPTION_INIT ("use-readdirp", priv->use_readdirp, bool, cleanup_exit);
priv->fuse_dump_fd = -1;
ret = dict_get_str (options, "dump-fuse", &value_string);
if (ret == 0) {
@ -5394,5 +5399,9 @@ struct volume_options options[] = {
{ .key = {"fuse-mountopts"},
.type = GF_OPTION_TYPE_STR
},
{ .key = {"use-readdirp"},
.type = GF_OPTION_TYPE_BOOL,
.default_value = "no"
},
{ .key = {NULL} },
};

@ -119,6 +119,9 @@ struct fuse_private {
/* for fuse queue length and congestion threshold */
int background_qlen;
int congestion_threshold;
/* for using fuse-kernel readdirp*/
gf_boolean_t use_readdirp;
};
typedef struct fuse_private fuse_private_t;

@ -135,6 +135,10 @@ start_glusterfs ()
cmd_line=$(echo "$cmd_line --direct-io-mode=$direct_io_mode");
fi
if [ -n "$use_readdirp" ]; then
cmd_line=$(echo "$cmd_line --use-readdirp=$use_readdirp");
fi
if [ -n "$volume_name" ]; then
cmd_line=$(echo "$cmd_line --volume-name=$volume_name");
fi
@ -376,6 +380,7 @@ main ()
"congestion-threshold") cong_threshold=$value ;;
"xlator-option") xlator_option=$xlator_option" "$pair ;;
"fuse-mountopts") fuse_mountopts=$value ;;
"use-readdirp") use_readdirp=$value ;;
*)
# Passthru
[ -z "$fuse_mountopts" ] || fuse_mountopts="$fuse_mountopts,"