mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-13 14:14:37 +00:00
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@virtuozzo.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
2a23f2b8ad
commit
2b30a53314
1 changed files with 24 additions and 6 deletions
|
@ -125,7 +125,12 @@ static ssize_t fuse_conn_max_background_write(struct file *file,
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
struct fuse_conn *fc = fuse_ctl_file_conn_get(file);
|
struct fuse_conn *fc = fuse_ctl_file_conn_get(file);
|
||||||
if (fc) {
|
if (fc) {
|
||||||
|
spin_lock(&fc->lock);
|
||||||
fc->max_background = val;
|
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);
|
fuse_conn_put(fc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,18 +160,31 @@ static ssize_t fuse_conn_congestion_threshold_write(struct file *file,
|
||||||
size_t count, loff_t *ppos)
|
size_t count, loff_t *ppos)
|
||||||
{
|
{
|
||||||
unsigned uninitialized_var(val);
|
unsigned uninitialized_var(val);
|
||||||
|
struct fuse_conn *fc;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
ret = fuse_conn_limit_write(file, buf, count, ppos, &val,
|
ret = fuse_conn_limit_write(file, buf, count, ppos, &val,
|
||||||
max_user_congthresh);
|
max_user_congthresh);
|
||||||
if (ret > 0) {
|
if (ret <= 0)
|
||||||
struct fuse_conn *fc = fuse_ctl_file_conn_get(file);
|
goto out;
|
||||||
if (fc) {
|
fc = fuse_ctl_file_conn_get(file);
|
||||||
fc->congestion_threshold = val;
|
if (!fc)
|
||||||
fuse_conn_put(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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue