[Devel] [PATCH RHEL7 COMMIT] ms/fuse: add locking to max_background and congestion_threshold changes
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Oct 4 12:31:22 MSK 2018
The commit is pushed to "branch-rh7-3.10.0-862.14.4.vz7.72.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.14.4.vz7.72.2
------>
commit f33c7bdcf475e5cbbd9bccc8438d4b7ff10c0d12
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date: Thu Oct 4 12:31:20 2018 +0300
ms/fuse: add locking to max_background and congestion_threshold changes
Functions sequences like request_end()->flush_bg_queue() require that
max_background and congestion_threshold are constant during their
execution. Otherwise, checks like
if (fc->num_background == fc->max_background)
made in different time may behave not like expected.
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
Signed-off-by: Miklos Szeredi <mszeredi at redhat.com>
=====================
Patchset description:
Relax lock contention and ms fixes
https://pmc.acronis.com/browse/VSTOR-9810
Port some ms fixes and begin first round of relaxing fc->lock contention.
Kirill Tkhai (5):
fuse: Fix use-after-free in fuse_dev_do_read()
fuse: Fix use-after-free in fuse_dev_do_write()
fuse: use list_first_entry() in flush_bg_queue()
fuse: use READ_ONCE on congestion_threshold and max_background
fuse: add locking to max_background and congestion_threshold changes
Miklos Szeredi (2):
fuse: set FR_SENT while locked
fuse: fix blocked_waitq wakeup
---
fs/fuse/control.c | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/fs/fuse/control.c b/fs/fuse/control.c
index 9a072ff3c0cd..db733f4318d4 100644
--- a/fs/fuse/control.c
+++ b/fs/fuse/control.c
@@ -126,7 +126,12 @@ static ssize_t fuse_conn_max_background_write(struct file *file,
if (ret > 0) {
struct fuse_conn *fc = fuse_ctl_file_conn_get(file);
if (fc) {
+ spin_lock(&fc->lock);
fc->max_background = val;
+ fc->blocked = fc->num_background >= fc->max_background;
+ if (!fc->blocked)
+ wake_up(&fc->blocked_waitq);
+ spin_unlock(&fc->lock);
fuse_conn_put(fc);
}
}
@@ -156,18 +161,31 @@ static ssize_t fuse_conn_congestion_threshold_write(struct file *file,
size_t count, loff_t *ppos)
{
unsigned uninitialized_var(val);
+ struct fuse_conn *fc;
ssize_t ret;
ret = fuse_conn_limit_write(file, buf, count, ppos, &val,
max_user_congthresh);
- if (ret > 0) {
- struct fuse_conn *fc = fuse_ctl_file_conn_get(file);
- if (fc) {
- fc->congestion_threshold = val;
- fuse_conn_put(fc);
+ if (ret <= 0)
+ goto out;
+ fc = fuse_ctl_file_conn_get(file);
+ if (!fc)
+ goto out;
+
+ spin_lock(&fc->lock);
+ fc->congestion_threshold = val;
+ if (fc->sb) {
+ if (fc->num_background < fc->congestion_threshold) {
+ clear_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC);
+ clear_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC);
+ } else {
+ set_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC);
+ set_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC);
}
}
-
+ spin_unlock(&fc->lock);
+ fuse_conn_put(fc);
+out:
return ret;
}
More information about the Devel
mailing list