1 /* 2 FUSE: Filesystem in Userspace 3 Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 4 5 This program can be distributed under the terms of the GNU GPL. 6 See the file COPYING. 7 */ 8 9 #include "fuse_i.h" 10 11 #include <linux/init.h> 12 #include <linux/module.h> 13 14 #define FUSE_CTL_SUPER_MAGIC 0x65735543 15 16 /* 17 * This is non-NULL when the single instance of the control filesystem 18 * exists. Protected by fuse_mutex 19 */ 20 static struct super_block *fuse_control_sb; 21 22 static struct fuse_conn *fuse_ctl_file_conn_get(struct file *file) 23 { 24 struct fuse_conn *fc; 25 mutex_lock(&fuse_mutex); 26 fc = file_inode(file)->i_private; 27 if (fc) 28 fc = fuse_conn_get(fc); 29 mutex_unlock(&fuse_mutex); 30 return fc; 31 } 32 33 static ssize_t fuse_conn_abort_write(struct file *file, const char __user *buf, 34 size_t count, loff_t *ppos) 35 { 36 struct fuse_conn *fc = fuse_ctl_file_conn_get(file); 37 if (fc) { 38 if (fc->abort_err) 39 fc->aborted = true; 40 fuse_abort_conn(fc); 41 fuse_conn_put(fc); 42 } 43 return count; 44 } 45 46 static ssize_t fuse_conn_waiting_read(struct file *file, char __user *buf, 47 size_t len, loff_t *ppos) 48 { 49 char tmp[32]; 50 size_t size; 51 52 if (!*ppos) { 53 long value; 54 struct fuse_conn *fc = fuse_ctl_file_conn_get(file); 55 if (!fc) 56 return 0; 57 58 value = atomic_read(&fc->num_waiting); 59 file->private_data = (void *)value; 60 fuse_conn_put(fc); 61 } 62 size = sprintf(tmp, "%ld\n", (long)file->private_data); 63 return simple_read_from_buffer(buf, len, ppos, tmp, size); 64 } 65 66 static ssize_t fuse_conn_limit_read(struct file *file, char __user *buf, 67 size_t len, loff_t *ppos, unsigned val) 68 { 69 char tmp[32]; 70 size_t size = sprintf(tmp, "%u\n", val); 71 72 return simple_read_from_buffer(buf, len, ppos, tmp, size); 73 } 74 75 static ssize_t fuse_conn_limit_write(struct file *file, const char __user *buf, 76 size_t count, loff_t *ppos, unsigned *val, 77 unsigned global_limit) 78 { 79 unsigned long t; 80 unsigned limit = (1 << 16) - 1; 81 int err; 82 83 if (*ppos) 84 return -EINVAL; 85 86 err = kstrtoul_from_user(buf, count, 0, &t); 87 if (err) 88 return err; 89 90 if (!capable(CAP_SYS_ADMIN)) 91 limit = min(limit, global_limit); 92 93 if (t > limit) 94 return -EINVAL; 95 96 *val = t; 97 98 return count; 99 } 100 101 static ssize_t fuse_conn_max_background_read(struct file *file, 102 char __user *buf, size_t len, 103 loff_t *ppos) 104 { 105 struct fuse_conn *fc; 106 unsigned val; 107 108 fc = fuse_ctl_file_conn_get(file); 109 if (!fc) 110 return 0; 111 112 val = READ_ONCE(fc->max_background); 113 fuse_conn_put(fc); 114 115 return fuse_conn_limit_read(file, buf, len, ppos, val); 116 } 117 118 static ssize_t fuse_conn_max_background_write(struct file *file, 119 const char __user *buf, 120 size_t count, loff_t *ppos) 121 { 122 unsigned uninitialized_var(val); 123 ssize_t ret; 124 125 ret = fuse_conn_limit_write(file, buf, count, ppos, &val, 126 max_user_bgreq); 127 if (ret > 0) { 128 struct fuse_conn *fc = fuse_ctl_file_conn_get(file); 129 if (fc) { 130 spin_lock(&fc->bg_lock); 131 fc->max_background = val; 132 fc->blocked = fc->num_background >= fc->max_background; 133 if (!fc->blocked) 134 wake_up(&fc->blocked_waitq); 135 spin_unlock(&fc->bg_lock); 136 fuse_conn_put(fc); 137 } 138 } 139 140 return ret; 141 } 142 143 static ssize_t fuse_conn_congestion_threshold_read(struct file *file, 144 char __user *buf, size_t len, 145 loff_t *ppos) 146 { 147 struct fuse_conn *fc; 148 unsigned val; 149 150 fc = fuse_ctl_file_conn_get(file); 151 if (!fc) 152 return 0; 153 154 val = READ_ONCE(fc->congestion_threshold); 155 fuse_conn_put(fc); 156 157 return fuse_conn_limit_read(file, buf, len, ppos, val); 158 } 159 160 static ssize_t fuse_conn_congestion_threshold_write(struct file *file, 161 const char __user *buf, 162 size_t count, loff_t *ppos) 163 { 164 unsigned uninitialized_var(val); 165 struct fuse_conn *fc; 166 ssize_t ret; 167 168 ret = fuse_conn_limit_write(file, buf, count, ppos, &val, 169 max_user_congthresh); 170 if (ret <= 0) 171 goto out; 172 fc = fuse_ctl_file_conn_get(file); 173 if (!fc) 174 goto out; 175 176 spin_lock(&fc->bg_lock); 177 fc->congestion_threshold = val; 178 if (fc->sb) { 179 if (fc->num_background < fc->congestion_threshold) { 180 clear_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC); 181 clear_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC); 182 } else { 183 set_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC); 184 set_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC); 185 } 186 } 187 spin_unlock(&fc->bg_lock); 188 fuse_conn_put(fc); 189 out: 190 return ret; 191 } 192 193 static const struct file_operations fuse_ctl_abort_ops = { 194 .open = nonseekable_open, 195 .write = fuse_conn_abort_write, 196 .llseek = no_llseek, 197 }; 198 199 static const struct file_operations fuse_ctl_waiting_ops = { 200 .open = nonseekable_open, 201 .read = fuse_conn_waiting_read, 202 .llseek = no_llseek, 203 }; 204 205 static const struct file_operations fuse_conn_max_background_ops = { 206 .open = nonseekable_open, 207 .read = fuse_conn_max_background_read, 208 .write = fuse_conn_max_background_write, 209 .llseek = no_llseek, 210 }; 211 212 static const struct file_operations fuse_conn_congestion_threshold_ops = { 213 .open = nonseekable_open, 214 .read = fuse_conn_congestion_threshold_read, 215 .write = fuse_conn_congestion_threshold_write, 216 .llseek = no_llseek, 217 }; 218 219 static struct dentry *fuse_ctl_add_dentry(struct dentry *parent, 220 struct fuse_conn *fc, 221 const char *name, 222 int mode, int nlink, 223 const struct inode_operations *iop, 224 const struct file_operations *fop) 225 { 226 struct dentry *dentry; 227 struct inode *inode; 228 229 BUG_ON(fc->ctl_ndents >= FUSE_CTL_NUM_DENTRIES); 230 dentry = d_alloc_name(parent, name); 231 if (!dentry) 232 return NULL; 233 234 inode = new_inode(fuse_control_sb); 235 if (!inode) { 236 dput(dentry); 237 return NULL; 238 } 239 240 inode->i_ino = get_next_ino(); 241 inode->i_mode = mode; 242 inode->i_uid = fc->user_id; 243 inode->i_gid = fc->group_id; 244 inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); 245 /* setting ->i_op to NULL is not allowed */ 246 if (iop) 247 inode->i_op = iop; 248 inode->i_fop = fop; 249 set_nlink(inode, nlink); 250 inode->i_private = fc; 251 d_add(dentry, inode); 252 253 fc->ctl_dentry[fc->ctl_ndents++] = dentry; 254 255 return dentry; 256 } 257 258 /* 259 * Add a connection to the control filesystem (if it exists). Caller 260 * must hold fuse_mutex 261 */ 262 int fuse_ctl_add_conn(struct fuse_conn *fc) 263 { 264 struct dentry *parent; 265 char name[32]; 266 267 if (!fuse_control_sb) 268 return 0; 269 270 parent = fuse_control_sb->s_root; 271 inc_nlink(d_inode(parent)); 272 sprintf(name, "%u", fc->dev); 273 parent = fuse_ctl_add_dentry(parent, fc, name, S_IFDIR | 0500, 2, 274 &simple_dir_inode_operations, 275 &simple_dir_operations); 276 if (!parent) 277 goto err; 278 279 if (!fuse_ctl_add_dentry(parent, fc, "waiting", S_IFREG | 0400, 1, 280 NULL, &fuse_ctl_waiting_ops) || 281 !fuse_ctl_add_dentry(parent, fc, "abort", S_IFREG | 0200, 1, 282 NULL, &fuse_ctl_abort_ops) || 283 !fuse_ctl_add_dentry(parent, fc, "max_background", S_IFREG | 0600, 284 1, NULL, &fuse_conn_max_background_ops) || 285 !fuse_ctl_add_dentry(parent, fc, "congestion_threshold", 286 S_IFREG | 0600, 1, NULL, 287 &fuse_conn_congestion_threshold_ops)) 288 goto err; 289 290 return 0; 291 292 err: 293 fuse_ctl_remove_conn(fc); 294 return -ENOMEM; 295 } 296 297 /* 298 * Remove a connection from the control filesystem (if it exists). 299 * Caller must hold fuse_mutex 300 */ 301 void fuse_ctl_remove_conn(struct fuse_conn *fc) 302 { 303 int i; 304 305 if (!fuse_control_sb) 306 return; 307 308 for (i = fc->ctl_ndents - 1; i >= 0; i--) { 309 struct dentry *dentry = fc->ctl_dentry[i]; 310 d_inode(dentry)->i_private = NULL; 311 if (!i) { 312 /* Get rid of submounts: */ 313 d_invalidate(dentry); 314 } 315 dput(dentry); 316 } 317 drop_nlink(d_inode(fuse_control_sb->s_root)); 318 } 319 320 static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent) 321 { 322 static const struct tree_descr empty_descr = {""}; 323 struct fuse_conn *fc; 324 int err; 325 326 err = simple_fill_super(sb, FUSE_CTL_SUPER_MAGIC, &empty_descr); 327 if (err) 328 return err; 329 330 mutex_lock(&fuse_mutex); 331 BUG_ON(fuse_control_sb); 332 fuse_control_sb = sb; 333 list_for_each_entry(fc, &fuse_conn_list, entry) { 334 err = fuse_ctl_add_conn(fc); 335 if (err) { 336 fuse_control_sb = NULL; 337 mutex_unlock(&fuse_mutex); 338 return err; 339 } 340 } 341 mutex_unlock(&fuse_mutex); 342 343 return 0; 344 } 345 346 static struct dentry *fuse_ctl_mount(struct file_system_type *fs_type, 347 int flags, const char *dev_name, void *raw_data) 348 { 349 return mount_single(fs_type, flags, raw_data, fuse_ctl_fill_super); 350 } 351 352 static void fuse_ctl_kill_sb(struct super_block *sb) 353 { 354 struct fuse_conn *fc; 355 356 mutex_lock(&fuse_mutex); 357 fuse_control_sb = NULL; 358 list_for_each_entry(fc, &fuse_conn_list, entry) 359 fc->ctl_ndents = 0; 360 mutex_unlock(&fuse_mutex); 361 362 kill_litter_super(sb); 363 } 364 365 static struct file_system_type fuse_ctl_fs_type = { 366 .owner = THIS_MODULE, 367 .name = "fusectl", 368 .mount = fuse_ctl_mount, 369 .kill_sb = fuse_ctl_kill_sb, 370 }; 371 MODULE_ALIAS_FS("fusectl"); 372 373 int __init fuse_ctl_init(void) 374 { 375 return register_filesystem(&fuse_ctl_fs_type); 376 } 377 378 void __exit fuse_ctl_cleanup(void) 379 { 380 unregister_filesystem(&fuse_ctl_fs_type); 381 } 382