diff options
author | Csaba Henk <csaba@redhat.com> | 2019-04-03 14:23:06 +0200 |
---|---|---|
committer | Amar Tumballi <amarts@redhat.com> | 2019-08-08 06:10:29 +0000 |
commit | 40f476f40b37cc8fcc83618094d357ee643442d8 (patch) | |
tree | 574d891bf6d7f46356e8a807e5fe01715ece2dda /xlators/mount | |
parent | 8ca15e3c9c72511bbe8a548a1471f8d6a5bfd709 (diff) |
fuse: rate limit reading from fuse device upon receiving EPERM
Fixes: bz#1644322
Change-Id: I53e8fa362cd8c7d04fb1c4abb606a9abb642c592
Signed-off-by: Csaba Henk <csaba@redhat.com>
Diffstat (limited to 'xlators/mount')
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 22 | ||||
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.h | 2 | ||||
-rwxr-xr-x | xlators/mount/fuse/utils/mount.glusterfs.in | 7 |
3 files changed, 31 insertions, 0 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index c1ce008eace..3a779625a08 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -5976,6 +5976,16 @@ fuse_thread_proc(void *data) "glusterfs-fuse: read from " "/dev/fuse returned -1 (%s)", strerror(errno)); + if (errno == EPERM) { + /* + * sleep a while to avoid busy looping + * on EPERM condition + */ + nanosleep( + &(struct timespec){0, + priv->fuse_dev_eperm_ratelimit_ns}, + NULL); + } } goto cont_err; @@ -6692,6 +6702,9 @@ init(xlator_t *this_xl) GF_OPTION_INIT("flush-handle-interrupt", priv->flush_handle_interrupt, bool, cleanup_exit); + GF_OPTION_INIT("fuse-dev-eperm-ratelimit-ns", + priv->fuse_dev_eperm_ratelimit_ns, uint32, cleanup_exit); + /* user has set only background-qlen, not congestion-threshold, use the fuse kernel driver formula to set congestion. ie, 75% */ if (dict_get(this_xl->options, "background-qlen") && @@ -7023,6 +7036,15 @@ struct volume_options options[] = { "if same files/directories are not accessed across " "two different mounts concurrently", }, + { + .key = {"fuse-dev-eperm-ratelimit-ns"}, + .type = GF_OPTION_TYPE_INT, + .default_value = "10000000", /* 0.01 sec */ + .min = 0, + .max = 1000000000, + .description = "Rate limit reading from fuse device upon EPERM " + "failure.", + }, {.key = {NULL}}, }; diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h index 697bd8848e1..8d25bed0481 100644 --- a/xlators/mount/fuse/src/fuse-bridge.h +++ b/xlators/mount/fuse/src/fuse-bridge.h @@ -191,6 +191,8 @@ struct fuse_private { /* LRU Limit, if not set, default is 128k for now */ uint32_t lru_limit; + + uint32_t fuse_dev_eperm_ratelimit_ns; }; typedef struct fuse_private fuse_private_t; diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in index 29906316266..21cc018eaa5 100755 --- a/xlators/mount/fuse/utils/mount.glusterfs.in +++ b/xlators/mount/fuse/utils/mount.glusterfs.in @@ -362,6 +362,10 @@ start_glusterfs () cmd_line=$(echo "$cmd_line --subdir-mount=/$subdir_mount"); fi + if [ -n "$fuse_dev_eperm_ratelimit_ns" ]; then + cmd_line=$(echo "$cmd_line --fuse-dev-eperm-ratelimit-ns=$fuse_dev_eperm_ratelimit_ns"); + fi + cmd_line=$(echo "$cmd_line $mount_point"); $cmd_line; if [ $? -ne 0 ]; then @@ -571,6 +575,9 @@ with_options() "fuse-flush-handle-interrupt") fuse_flush_handle_interrupt=$value ;; + "fuse-dev-eperm-ratelimit-ns") + fuse_dev_eperm_ratelimit_ns=$value + ;; "context"|"fscontext"|"defcontext"|"rootcontext") # standard SElinux mount options to pass to the kernel [ -z "$fuse_mountopts" ] || fuse_mountopts="$fuse_mountopts," |