[PATCH] fuse: make fuse connection a kobject

Kobjectify fuse_conn, and make it visible under /sys/fs/fuse/connections.

Lacking any natural naming, connections are numbered.

This patch doesn't add any attributes, just the infrastructure.

Signed-off-by: Miklos Szeredi <miklos@szeredi.hu>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Miklos Szeredi and committed by
Linus Torvalds
f543f253 9ba7cbba

+164 -43
+3 -1
fs/fuse/dev.c
··· 852 852 fc->connected = 0; 853 853 end_requests(fc, &fc->pending); 854 854 end_requests(fc, &fc->processing); 855 - fuse_release_conn(fc); 856 855 } 857 856 spin_unlock(&fuse_lock); 857 + if (fc) 858 + kobject_put(&fc->kobj); 859 + 858 860 return 0; 859 861 } 860 862
+8 -9
fs/fuse/fuse_i.h
··· 196 196 * unmounted. 197 197 */ 198 198 struct fuse_conn { 199 - /** Reference count */ 200 - int count; 201 - 202 199 /** The user id for this mount */ 203 200 uid_t user_id; 204 201 ··· 285 288 286 289 /** Backing dev info */ 287 290 struct backing_dev_info bdi; 291 + 292 + /** kobject */ 293 + struct kobject kobj; 288 294 }; 289 295 290 296 static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) ··· 298 298 static inline struct fuse_conn *get_fuse_conn(struct inode *inode) 299 299 { 300 300 return get_fuse_conn_super(inode->i_sb); 301 + } 302 + 303 + static inline struct fuse_conn *get_fuse_conn_kobj(struct kobject *obj) 304 + { 305 + return container_of(obj, struct fuse_conn, kobj); 301 306 } 302 307 303 308 static inline struct fuse_inode *get_fuse_inode(struct inode *inode) ··· 403 398 * Change attributes of an inode 404 399 */ 405 400 void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr); 406 - 407 - /** 408 - * Check if the connection can be released, and if yes, then free the 409 - * connection structure 410 - */ 411 - void fuse_release_conn(struct fuse_conn *fc); 412 401 413 402 /** 414 403 * Initialize the client device
+153 -33
fs/fuse/inode.c
··· 24 24 25 25 spinlock_t fuse_lock; 26 26 static kmem_cache_t *fuse_inode_cachep; 27 + static struct subsystem connections_subsys; 28 + 29 + struct fuse_conn_attr { 30 + struct attribute attr; 31 + ssize_t (*show)(struct fuse_conn *, char *); 32 + ssize_t (*store)(struct fuse_conn *, const char *, size_t); 33 + }; 27 34 28 35 #define FUSE_SUPER_MAGIC 0x65735546 29 36 ··· 208 201 spin_lock(&fuse_lock); 209 202 fc->mounted = 0; 210 203 fc->connected = 0; 204 + spin_unlock(&fuse_lock); 205 + up_write(&fc->sbput_sem); 211 206 /* Flush all readers on this fs */ 212 207 wake_up_all(&fc->waitq); 213 - up_write(&fc->sbput_sem); 214 - fuse_release_conn(fc); 215 - spin_unlock(&fuse_lock); 208 + kobject_del(&fc->kobj); 209 + kobject_put(&fc->kobj); 216 210 } 217 211 218 212 static void convert_fuse_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr) ··· 362 354 return 0; 363 355 } 364 356 365 - static void free_conn(struct fuse_conn *fc) 357 + static void fuse_conn_release(struct kobject *kobj) 366 358 { 359 + struct fuse_conn *fc = get_fuse_conn_kobj(kobj); 360 + 367 361 while (!list_empty(&fc->unused_list)) { 368 362 struct fuse_req *req; 369 363 req = list_entry(fc->unused_list.next, struct fuse_req, list); ··· 375 365 kfree(fc); 376 366 } 377 367 378 - /* Must be called with the fuse lock held */ 379 - void fuse_release_conn(struct fuse_conn *fc) 380 - { 381 - fc->count--; 382 - if (!fc->count) 383 - free_conn(fc); 384 - } 385 - 386 368 static struct fuse_conn *new_conn(void) 387 369 { 388 370 struct fuse_conn *fc; 389 371 390 372 fc = kzalloc(sizeof(*fc), GFP_KERNEL); 391 - if (fc != NULL) { 373 + if (fc) { 392 374 int i; 393 375 init_waitqueue_head(&fc->waitq); 394 376 INIT_LIST_HEAD(&fc->pending); ··· 390 388 INIT_LIST_HEAD(&fc->background); 391 389 sema_init(&fc->outstanding_sem, 1); /* One for INIT */ 392 390 init_rwsem(&fc->sbput_sem); 391 + kobj_set_kset_s(fc, connections_subsys); 392 + kobject_init(&fc->kobj); 393 393 for (i = 0; i < FUSE_MAX_OUTSTANDING; i++) { 394 394 struct fuse_req *req = fuse_request_alloc(); 395 395 if (!req) { 396 - free_conn(fc); 396 + kobject_put(&fc->kobj); 397 397 return NULL; 398 398 } 399 399 list_add(&req->list, &fc->unused_list); ··· 410 406 static struct fuse_conn *get_conn(struct file *file, struct super_block *sb) 411 407 { 412 408 struct fuse_conn *fc; 409 + int err; 413 410 411 + err = -EINVAL; 414 412 if (file->f_op != &fuse_dev_operations) 415 - return ERR_PTR(-EINVAL); 413 + goto out_err; 414 + 415 + err = -ENOMEM; 416 416 fc = new_conn(); 417 - if (fc == NULL) 418 - return ERR_PTR(-ENOMEM); 417 + if (!fc) 418 + goto out_err; 419 + 419 420 spin_lock(&fuse_lock); 420 - if (file->private_data) { 421 - free_conn(fc); 422 - fc = ERR_PTR(-EINVAL); 423 - } else { 424 - file->private_data = fc; 425 - sb->s_fs_info = fc; 426 - fc->mounted = 1; 427 - fc->connected = 1; 428 - fc->count = 2; 429 - } 421 + err = -EINVAL; 422 + if (file->private_data) 423 + goto out_unlock; 424 + 425 + kobject_get(&fc->kobj); 426 + file->private_data = fc; 430 427 spin_unlock(&fuse_lock); 431 428 return fc; 429 + 430 + out_unlock: 431 + spin_unlock(&fuse_lock); 432 + kobject_put(&fc->kobj); 433 + out_err: 434 + return ERR_PTR(err); 432 435 } 433 436 434 437 static struct inode *get_root_inode(struct super_block *sb, unsigned mode) ··· 458 447 .show_options = fuse_show_options, 459 448 }; 460 449 450 + static unsigned long long conn_id(void) 451 + { 452 + static unsigned long long ctr = 1; 453 + unsigned long long val; 454 + spin_lock(&fuse_lock); 455 + val = ctr++; 456 + spin_unlock(&fuse_lock); 457 + return val; 458 + } 459 + 461 460 static int fuse_fill_super(struct super_block *sb, void *data, int silent) 462 461 { 463 462 struct fuse_conn *fc; 464 463 struct inode *root; 465 464 struct fuse_mount_data d; 466 465 struct file *file; 466 + struct dentry *root_dentry; 467 467 int err; 468 468 469 469 if (!parse_fuse_opt((char *) data, &d)) ··· 502 480 if (fc->max_read / PAGE_CACHE_SIZE < fc->bdi.ra_pages) 503 481 fc->bdi.ra_pages = fc->max_read / PAGE_CACHE_SIZE; 504 482 483 + /* Used by get_root_inode() */ 484 + sb->s_fs_info = fc; 485 + 505 486 err = -ENOMEM; 506 487 root = get_root_inode(sb, d.rootmode); 507 - if (root == NULL) 488 + if (!root) 508 489 goto err; 509 490 510 - sb->s_root = d_alloc_root(root); 511 - if (!sb->s_root) { 491 + root_dentry = d_alloc_root(root); 492 + if (!root_dentry) { 512 493 iput(root); 513 494 goto err; 514 495 } 496 + 497 + err = kobject_set_name(&fc->kobj, "%llu", conn_id()); 498 + if (err) 499 + goto err_put_root; 500 + 501 + err = kobject_add(&fc->kobj); 502 + if (err) 503 + goto err_put_root; 504 + 505 + sb->s_root = root_dentry; 506 + spin_lock(&fuse_lock); 507 + fc->mounted = 1; 508 + fc->connected = 1; 509 + spin_unlock(&fuse_lock); 510 + 515 511 fuse_send_init(fc); 512 + 516 513 return 0; 517 514 515 + err_put_root: 516 + dput(root_dentry); 518 517 err: 519 - spin_lock(&fuse_lock); 520 - fuse_release_conn(fc); 521 - spin_unlock(&fuse_lock); 518 + kobject_put(&fc->kobj); 522 519 return err; 523 520 } 524 521 ··· 554 513 .get_sb = fuse_get_sb, 555 514 .kill_sb = kill_anon_super, 556 515 }; 516 + 517 + static struct attribute *fuse_conn_attrs[] = { 518 + NULL, 519 + }; 520 + 521 + static ssize_t fuse_conn_attr_show(struct kobject *kobj, 522 + struct attribute *attr, 523 + char *page) 524 + { 525 + struct fuse_conn_attr *fca = 526 + container_of(attr, struct fuse_conn_attr, attr); 527 + 528 + if (fca->show) 529 + return fca->show(get_fuse_conn_kobj(kobj), page); 530 + else 531 + return -EACCES; 532 + } 533 + 534 + static ssize_t fuse_conn_attr_store(struct kobject *kobj, 535 + struct attribute *attr, 536 + const char *page, size_t count) 537 + { 538 + struct fuse_conn_attr *fca = 539 + container_of(attr, struct fuse_conn_attr, attr); 540 + 541 + if (fca->store) 542 + return fca->store(get_fuse_conn_kobj(kobj), page, count); 543 + else 544 + return -EACCES; 545 + } 546 + 547 + static struct sysfs_ops fuse_conn_sysfs_ops = { 548 + .show = &fuse_conn_attr_show, 549 + .store = &fuse_conn_attr_store, 550 + }; 551 + 552 + static struct kobj_type ktype_fuse_conn = { 553 + .release = fuse_conn_release, 554 + .sysfs_ops = &fuse_conn_sysfs_ops, 555 + .default_attrs = fuse_conn_attrs, 556 + }; 557 + 558 + static decl_subsys(fuse, NULL, NULL); 559 + static decl_subsys(connections, &ktype_fuse_conn, NULL); 557 560 558 561 static void fuse_inode_init_once(void *foo, kmem_cache_t *cachep, 559 562 unsigned long flags) ··· 636 551 kmem_cache_destroy(fuse_inode_cachep); 637 552 } 638 553 554 + static int fuse_sysfs_init(void) 555 + { 556 + int err; 557 + 558 + kset_set_kset_s(&fuse_subsys, fs_subsys); 559 + err = subsystem_register(&fuse_subsys); 560 + if (err) 561 + goto out_err; 562 + 563 + kset_set_kset_s(&connections_subsys, fuse_subsys); 564 + err = subsystem_register(&connections_subsys); 565 + if (err) 566 + goto out_fuse_unregister; 567 + 568 + return 0; 569 + 570 + out_fuse_unregister: 571 + subsystem_unregister(&fuse_subsys); 572 + out_err: 573 + return err; 574 + } 575 + 576 + static void fuse_sysfs_cleanup(void) 577 + { 578 + subsystem_unregister(&connections_subsys); 579 + subsystem_unregister(&fuse_subsys); 580 + } 581 + 639 582 static int __init fuse_init(void) 640 583 { 641 584 int res; ··· 680 567 if (res) 681 568 goto err_fs_cleanup; 682 569 570 + res = fuse_sysfs_init(); 571 + if (res) 572 + goto err_dev_cleanup; 573 + 683 574 return 0; 684 575 576 + err_dev_cleanup: 577 + fuse_dev_cleanup(); 685 578 err_fs_cleanup: 686 579 fuse_fs_cleanup(); 687 580 err: ··· 698 579 { 699 580 printk(KERN_DEBUG "fuse exit\n"); 700 581 582 + fuse_sysfs_cleanup(); 701 583 fuse_fs_cleanup(); 702 584 fuse_dev_cleanup(); 703 585 }