Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2b30a533 authored by Kirill Tkhai's avatar Kirill Tkhai Committed by Miklos Szeredi
Browse files

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: default avatarKirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent 2a23f2b8
Loading
Loading
Loading
Loading
+24 −6
Original line number Diff line number Diff line
@@ -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) {
	if (ret <= 0)
		goto out;
	fc = fuse_ctl_file_conn_get(file);
	if (!fc)
		goto out;

	spin_lock(&fc->lock);
	fc->congestion_threshold = val;
			fuse_conn_put(fc);
	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;
}