.. | .. |
---|
10 | 10 | |
---|
11 | 11 | #include <linux/init.h> |
---|
12 | 12 | #include <linux/module.h> |
---|
| 13 | +#include <linux/fs_context.h> |
---|
13 | 14 | |
---|
14 | 15 | #define FUSE_CTL_SUPER_MAGIC 0x65735543 |
---|
15 | 16 | |
---|
.. | .. |
---|
35 | 36 | { |
---|
36 | 37 | struct fuse_conn *fc = fuse_ctl_file_conn_get(file); |
---|
37 | 38 | if (fc) { |
---|
38 | | - fuse_abort_conn(fc, true); |
---|
| 39 | + if (fc->abort_err) |
---|
| 40 | + fc->aborted = true; |
---|
| 41 | + fuse_abort_conn(fc); |
---|
39 | 42 | fuse_conn_put(fc); |
---|
40 | 43 | } |
---|
41 | 44 | return count; |
---|
.. | .. |
---|
117 | 120 | const char __user *buf, |
---|
118 | 121 | size_t count, loff_t *ppos) |
---|
119 | 122 | { |
---|
120 | | - unsigned uninitialized_var(val); |
---|
| 123 | + unsigned val; |
---|
121 | 124 | ssize_t ret; |
---|
122 | 125 | |
---|
123 | 126 | ret = fuse_conn_limit_write(file, buf, count, ppos, &val, |
---|
.. | .. |
---|
125 | 128 | if (ret > 0) { |
---|
126 | 129 | struct fuse_conn *fc = fuse_ctl_file_conn_get(file); |
---|
127 | 130 | if (fc) { |
---|
| 131 | + spin_lock(&fc->bg_lock); |
---|
128 | 132 | fc->max_background = val; |
---|
| 133 | + fc->blocked = fc->num_background >= fc->max_background; |
---|
| 134 | + if (!fc->blocked) |
---|
| 135 | + wake_up(&fc->blocked_waitq); |
---|
| 136 | + spin_unlock(&fc->bg_lock); |
---|
129 | 137 | fuse_conn_put(fc); |
---|
130 | 138 | } |
---|
131 | 139 | } |
---|
.. | .. |
---|
154 | 162 | const char __user *buf, |
---|
155 | 163 | size_t count, loff_t *ppos) |
---|
156 | 164 | { |
---|
157 | | - unsigned uninitialized_var(val); |
---|
| 165 | + unsigned val; |
---|
| 166 | + struct fuse_conn *fc; |
---|
| 167 | + struct fuse_mount *fm; |
---|
158 | 168 | ssize_t ret; |
---|
159 | 169 | |
---|
160 | 170 | ret = fuse_conn_limit_write(file, buf, count, ppos, &val, |
---|
161 | 171 | max_user_congthresh); |
---|
162 | | - if (ret > 0) { |
---|
163 | | - struct fuse_conn *fc = fuse_ctl_file_conn_get(file); |
---|
164 | | - if (fc) { |
---|
165 | | - fc->congestion_threshold = val; |
---|
166 | | - fuse_conn_put(fc); |
---|
| 172 | + if (ret <= 0) |
---|
| 173 | + goto out; |
---|
| 174 | + fc = fuse_ctl_file_conn_get(file); |
---|
| 175 | + if (!fc) |
---|
| 176 | + goto out; |
---|
| 177 | + |
---|
| 178 | + down_read(&fc->killsb); |
---|
| 179 | + spin_lock(&fc->bg_lock); |
---|
| 180 | + fc->congestion_threshold = val; |
---|
| 181 | + |
---|
| 182 | + /* |
---|
| 183 | + * Get any fuse_mount belonging to this fuse_conn; s_bdi is |
---|
| 184 | + * shared between all of them |
---|
| 185 | + */ |
---|
| 186 | + |
---|
| 187 | + if (!list_empty(&fc->mounts)) { |
---|
| 188 | + fm = list_first_entry(&fc->mounts, struct fuse_mount, fc_entry); |
---|
| 189 | + if (fc->num_background < fc->congestion_threshold) { |
---|
| 190 | + clear_bdi_congested(fm->sb->s_bdi, BLK_RW_SYNC); |
---|
| 191 | + clear_bdi_congested(fm->sb->s_bdi, BLK_RW_ASYNC); |
---|
| 192 | + } else { |
---|
| 193 | + set_bdi_congested(fm->sb->s_bdi, BLK_RW_SYNC); |
---|
| 194 | + set_bdi_congested(fm->sb->s_bdi, BLK_RW_ASYNC); |
---|
167 | 195 | } |
---|
168 | 196 | } |
---|
169 | | - |
---|
| 197 | + spin_unlock(&fc->bg_lock); |
---|
| 198 | + up_read(&fc->killsb); |
---|
| 199 | + fuse_conn_put(fc); |
---|
| 200 | +out: |
---|
170 | 201 | return ret; |
---|
171 | 202 | } |
---|
172 | 203 | |
---|
.. | .. |
---|
244 | 275 | struct dentry *parent; |
---|
245 | 276 | char name[32]; |
---|
246 | 277 | |
---|
247 | | - if (!fuse_control_sb) |
---|
| 278 | + if (!fuse_control_sb || fc->no_control) |
---|
248 | 279 | return 0; |
---|
249 | 280 | |
---|
250 | 281 | parent = fuse_control_sb->s_root; |
---|
.. | .. |
---|
282 | 313 | { |
---|
283 | 314 | int i; |
---|
284 | 315 | |
---|
285 | | - if (!fuse_control_sb) |
---|
| 316 | + if (!fuse_control_sb || fc->no_control) |
---|
286 | 317 | return; |
---|
287 | 318 | |
---|
288 | 319 | for (i = fc->ctl_ndents - 1; i >= 0; i--) { |
---|
.. | .. |
---|
297 | 328 | drop_nlink(d_inode(fuse_control_sb->s_root)); |
---|
298 | 329 | } |
---|
299 | 330 | |
---|
300 | | -static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent) |
---|
| 331 | +static int fuse_ctl_fill_super(struct super_block *sb, struct fs_context *fctx) |
---|
301 | 332 | { |
---|
302 | 333 | static const struct tree_descr empty_descr = {""}; |
---|
303 | 334 | struct fuse_conn *fc; |
---|
.. | .. |
---|
323 | 354 | return 0; |
---|
324 | 355 | } |
---|
325 | 356 | |
---|
326 | | -static struct dentry *fuse_ctl_mount(struct file_system_type *fs_type, |
---|
327 | | - int flags, const char *dev_name, void *raw_data) |
---|
| 357 | +static int fuse_ctl_get_tree(struct fs_context *fc) |
---|
328 | 358 | { |
---|
329 | | - return mount_single(fs_type, flags, raw_data, fuse_ctl_fill_super); |
---|
| 359 | + return get_tree_single(fc, fuse_ctl_fill_super); |
---|
| 360 | +} |
---|
| 361 | + |
---|
| 362 | +static const struct fs_context_operations fuse_ctl_context_ops = { |
---|
| 363 | + .get_tree = fuse_ctl_get_tree, |
---|
| 364 | +}; |
---|
| 365 | + |
---|
| 366 | +static int fuse_ctl_init_fs_context(struct fs_context *fc) |
---|
| 367 | +{ |
---|
| 368 | + fc->ops = &fuse_ctl_context_ops; |
---|
| 369 | + return 0; |
---|
330 | 370 | } |
---|
331 | 371 | |
---|
332 | 372 | static void fuse_ctl_kill_sb(struct super_block *sb) |
---|
.. | .. |
---|
345 | 385 | static struct file_system_type fuse_ctl_fs_type = { |
---|
346 | 386 | .owner = THIS_MODULE, |
---|
347 | 387 | .name = "fusectl", |
---|
348 | | - .mount = fuse_ctl_mount, |
---|
| 388 | + .init_fs_context = fuse_ctl_init_fs_context, |
---|
349 | 389 | .kill_sb = fuse_ctl_kill_sb, |
---|
350 | 390 | }; |
---|
351 | 391 | MODULE_ALIAS_FS("fusectl"); |
---|