mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 19:29: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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -155,18 +160,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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue