diff options
Diffstat (limited to 'fs/fuse/inode.c')
-rw-r--r-- | fs/fuse/inode.c | 86 |
1 files changed, 71 insertions, 15 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 082ac1c97f39..ac81f48ab2f4 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -362,8 +362,8 @@ static void fuse_send_destroy(struct fuse_conn *fc) | |||
362 | if (req && fc->conn_init) { | 362 | if (req && fc->conn_init) { |
363 | fc->destroy_req = NULL; | 363 | fc->destroy_req = NULL; |
364 | req->in.h.opcode = FUSE_DESTROY; | 364 | req->in.h.opcode = FUSE_DESTROY; |
365 | req->force = 1; | 365 | __set_bit(FR_FORCE, &req->flags); |
366 | req->background = 0; | 366 | __clear_bit(FR_BACKGROUND, &req->flags); |
367 | fuse_request_send(fc, req); | 367 | fuse_request_send(fc, req); |
368 | fuse_put_request(fc, req); | 368 | fuse_put_request(fc, req); |
369 | } | 369 | } |
@@ -567,30 +567,46 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root) | |||
567 | return 0; | 567 | return 0; |
568 | } | 568 | } |
569 | 569 | ||
570 | static void fuse_iqueue_init(struct fuse_iqueue *fiq) | ||
571 | { | ||
572 | memset(fiq, 0, sizeof(struct fuse_iqueue)); | ||
573 | init_waitqueue_head(&fiq->waitq); | ||
574 | INIT_LIST_HEAD(&fiq->pending); | ||
575 | INIT_LIST_HEAD(&fiq->interrupts); | ||
576 | fiq->forget_list_tail = &fiq->forget_list_head; | ||
577 | fiq->connected = 1; | ||
578 | } | ||
579 | |||
580 | static void fuse_pqueue_init(struct fuse_pqueue *fpq) | ||
581 | { | ||
582 | memset(fpq, 0, sizeof(struct fuse_pqueue)); | ||
583 | spin_lock_init(&fpq->lock); | ||
584 | INIT_LIST_HEAD(&fpq->processing); | ||
585 | INIT_LIST_HEAD(&fpq->io); | ||
586 | fpq->connected = 1; | ||
587 | } | ||
588 | |||
570 | void fuse_conn_init(struct fuse_conn *fc) | 589 | void fuse_conn_init(struct fuse_conn *fc) |
571 | { | 590 | { |
572 | memset(fc, 0, sizeof(*fc)); | 591 | memset(fc, 0, sizeof(*fc)); |
573 | spin_lock_init(&fc->lock); | 592 | spin_lock_init(&fc->lock); |
574 | init_rwsem(&fc->killsb); | 593 | init_rwsem(&fc->killsb); |
575 | atomic_set(&fc->count, 1); | 594 | atomic_set(&fc->count, 1); |
576 | init_waitqueue_head(&fc->waitq); | 595 | atomic_set(&fc->dev_count, 1); |
577 | init_waitqueue_head(&fc->blocked_waitq); | 596 | init_waitqueue_head(&fc->blocked_waitq); |
578 | init_waitqueue_head(&fc->reserved_req_waitq); | 597 | init_waitqueue_head(&fc->reserved_req_waitq); |
579 | INIT_LIST_HEAD(&fc->pending); | 598 | fuse_iqueue_init(&fc->iq); |
580 | INIT_LIST_HEAD(&fc->processing); | ||
581 | INIT_LIST_HEAD(&fc->io); | ||
582 | INIT_LIST_HEAD(&fc->interrupts); | ||
583 | INIT_LIST_HEAD(&fc->bg_queue); | 599 | INIT_LIST_HEAD(&fc->bg_queue); |
584 | INIT_LIST_HEAD(&fc->entry); | 600 | INIT_LIST_HEAD(&fc->entry); |
585 | fc->forget_list_tail = &fc->forget_list_head; | 601 | INIT_LIST_HEAD(&fc->devices); |
586 | atomic_set(&fc->num_waiting, 0); | 602 | atomic_set(&fc->num_waiting, 0); |
587 | fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND; | 603 | fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND; |
588 | fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD; | 604 | fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD; |
589 | fc->khctr = 0; | 605 | fc->khctr = 0; |
590 | fc->polled_files = RB_ROOT; | 606 | fc->polled_files = RB_ROOT; |
591 | fc->reqctr = 0; | ||
592 | fc->blocked = 0; | 607 | fc->blocked = 0; |
593 | fc->initialized = 0; | 608 | fc->initialized = 0; |
609 | fc->connected = 1; | ||
594 | fc->attr_version = 1; | 610 | fc->attr_version = 1; |
595 | get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); | 611 | get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); |
596 | } | 612 | } |
@@ -930,6 +946,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) | |||
930 | 946 | ||
931 | static void fuse_free_conn(struct fuse_conn *fc) | 947 | static void fuse_free_conn(struct fuse_conn *fc) |
932 | { | 948 | { |
949 | WARN_ON(!list_empty(&fc->devices)); | ||
933 | kfree_rcu(fc, rcu); | 950 | kfree_rcu(fc, rcu); |
934 | } | 951 | } |
935 | 952 | ||
@@ -975,8 +992,42 @@ static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb) | |||
975 | return 0; | 992 | return 0; |
976 | } | 993 | } |
977 | 994 | ||
995 | struct fuse_dev *fuse_dev_alloc(struct fuse_conn *fc) | ||
996 | { | ||
997 | struct fuse_dev *fud; | ||
998 | |||
999 | fud = kzalloc(sizeof(struct fuse_dev), GFP_KERNEL); | ||
1000 | if (fud) { | ||
1001 | fud->fc = fuse_conn_get(fc); | ||
1002 | fuse_pqueue_init(&fud->pq); | ||
1003 | |||
1004 | spin_lock(&fc->lock); | ||
1005 | list_add_tail(&fud->entry, &fc->devices); | ||
1006 | spin_unlock(&fc->lock); | ||
1007 | } | ||
1008 | |||
1009 | return fud; | ||
1010 | } | ||
1011 | EXPORT_SYMBOL_GPL(fuse_dev_alloc); | ||
1012 | |||
1013 | void fuse_dev_free(struct fuse_dev *fud) | ||
1014 | { | ||
1015 | struct fuse_conn *fc = fud->fc; | ||
1016 | |||
1017 | if (fc) { | ||
1018 | spin_lock(&fc->lock); | ||
1019 | list_del(&fud->entry); | ||
1020 | spin_unlock(&fc->lock); | ||
1021 | |||
1022 | fuse_conn_put(fc); | ||
1023 | } | ||
1024 | kfree(fud); | ||
1025 | } | ||
1026 | EXPORT_SYMBOL_GPL(fuse_dev_free); | ||
1027 | |||
978 | static int fuse_fill_super(struct super_block *sb, void *data, int silent) | 1028 | static int fuse_fill_super(struct super_block *sb, void *data, int silent) |
979 | { | 1029 | { |
1030 | struct fuse_dev *fud; | ||
980 | struct fuse_conn *fc; | 1031 | struct fuse_conn *fc; |
981 | struct inode *root; | 1032 | struct inode *root; |
982 | struct fuse_mount_data d; | 1033 | struct fuse_mount_data d; |
@@ -1026,12 +1077,17 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
1026 | goto err_fput; | 1077 | goto err_fput; |
1027 | 1078 | ||
1028 | fuse_conn_init(fc); | 1079 | fuse_conn_init(fc); |
1080 | fc->release = fuse_free_conn; | ||
1081 | |||
1082 | fud = fuse_dev_alloc(fc); | ||
1083 | if (!fud) | ||
1084 | goto err_put_conn; | ||
1029 | 1085 | ||
1030 | fc->dev = sb->s_dev; | 1086 | fc->dev = sb->s_dev; |
1031 | fc->sb = sb; | 1087 | fc->sb = sb; |
1032 | err = fuse_bdi_init(fc, sb); | 1088 | err = fuse_bdi_init(fc, sb); |
1033 | if (err) | 1089 | if (err) |
1034 | goto err_put_conn; | 1090 | goto err_dev_free; |
1035 | 1091 | ||
1036 | sb->s_bdi = &fc->bdi; | 1092 | sb->s_bdi = &fc->bdi; |
1037 | 1093 | ||
@@ -1040,7 +1096,6 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
1040 | fc->dont_mask = 1; | 1096 | fc->dont_mask = 1; |
1041 | sb->s_flags |= MS_POSIXACL; | 1097 | sb->s_flags |= MS_POSIXACL; |
1042 | 1098 | ||
1043 | fc->release = fuse_free_conn; | ||
1044 | fc->flags = d.flags; | 1099 | fc->flags = d.flags; |
1045 | fc->user_id = d.user_id; | 1100 | fc->user_id = d.user_id; |
1046 | fc->group_id = d.group_id; | 1101 | fc->group_id = d.group_id; |
@@ -1053,14 +1108,14 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
1053 | root = fuse_get_root_inode(sb, d.rootmode); | 1108 | root = fuse_get_root_inode(sb, d.rootmode); |
1054 | root_dentry = d_make_root(root); | 1109 | root_dentry = d_make_root(root); |
1055 | if (!root_dentry) | 1110 | if (!root_dentry) |
1056 | goto err_put_conn; | 1111 | goto err_dev_free; |
1057 | /* only now - we want root dentry with NULL ->d_op */ | 1112 | /* only now - we want root dentry with NULL ->d_op */ |
1058 | sb->s_d_op = &fuse_dentry_operations; | 1113 | sb->s_d_op = &fuse_dentry_operations; |
1059 | 1114 | ||
1060 | init_req = fuse_request_alloc(0); | 1115 | init_req = fuse_request_alloc(0); |
1061 | if (!init_req) | 1116 | if (!init_req) |
1062 | goto err_put_root; | 1117 | goto err_put_root; |
1063 | init_req->background = 1; | 1118 | __set_bit(FR_BACKGROUND, &init_req->flags); |
1064 | 1119 | ||
1065 | if (is_bdev) { | 1120 | if (is_bdev) { |
1066 | fc->destroy_req = fuse_request_alloc(0); | 1121 | fc->destroy_req = fuse_request_alloc(0); |
@@ -1079,8 +1134,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
1079 | 1134 | ||
1080 | list_add_tail(&fc->entry, &fuse_conn_list); | 1135 | list_add_tail(&fc->entry, &fuse_conn_list); |
1081 | sb->s_root = root_dentry; | 1136 | sb->s_root = root_dentry; |
1082 | fc->connected = 1; | 1137 | file->private_data = fud; |
1083 | file->private_data = fuse_conn_get(fc); | ||
1084 | mutex_unlock(&fuse_mutex); | 1138 | mutex_unlock(&fuse_mutex); |
1085 | /* | 1139 | /* |
1086 | * atomic_dec_and_test() in fput() provides the necessary | 1140 | * atomic_dec_and_test() in fput() provides the necessary |
@@ -1099,6 +1153,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
1099 | fuse_request_free(init_req); | 1153 | fuse_request_free(init_req); |
1100 | err_put_root: | 1154 | err_put_root: |
1101 | dput(root_dentry); | 1155 | dput(root_dentry); |
1156 | err_dev_free: | ||
1157 | fuse_dev_free(fud); | ||
1102 | err_put_conn: | 1158 | err_put_conn: |
1103 | fuse_bdi_destroy(fc); | 1159 | fuse_bdi_destroy(fc); |
1104 | fuse_conn_put(fc); | 1160 | fuse_conn_put(fc); |