fuse: duplicate ->connected in iqueue
authorMiklos Szeredi <mszeredi@suse.cz>
Wed, 1 Jul 2015 14:26:01 +0000 (16:26 +0200)
committerMiklos Szeredi <mszeredi@suse.cz>
Wed, 1 Jul 2015 14:26:01 +0000 (16:26 +0200)
This will allow checking ->connected just with the input queue lock.

Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Reviewed-by: Ashish Samant <ashish.samant@oracle.com>
fs/fuse/cuse.c
fs/fuse/dev.c
fs/fuse/fuse_i.h
fs/fuse/inode.c

index e5bbf748b6987a922fa211e3edb083346927f3b6..0993d9a266d3f83711d6f89db1514a70ddc89425 100644 (file)
@@ -502,7 +502,6 @@ static int cuse_channel_open(struct inode *inode, struct file *file)
        INIT_LIST_HEAD(&cc->list);
        cc->fc.release = cuse_fc_release;
 
-       cc->fc.connected = 1;
        cc->fc.initialized = 1;
        rc = cuse_send_init(cc);
        if (rc) {
index 24407e21fb82b32f911c399ee81820f4d53f03dd..a24ead993650579f5d19d0271129155a2a34dce9 100644 (file)
@@ -341,7 +341,7 @@ void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
        forget->forget_one.nlookup = nlookup;
 
        spin_lock(&fc->lock);
-       if (fc->connected) {
+       if (fiq->connected) {
                fiq->forget_list_tail->next = forget;
                fiq->forget_list_tail = forget;
                wake_up(&fiq->waitq);
@@ -471,14 +471,14 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
 
 static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
 {
+       struct fuse_iqueue *fiq = &fc->iq;
+
        BUG_ON(test_bit(FR_BACKGROUND, &req->flags));
        spin_lock(&fc->lock);
-       if (!fc->connected) {
+       if (!fiq->connected) {
                spin_unlock(&fc->lock);
                req->out.h.error = -ENOTCONN;
        } else {
-               struct fuse_iqueue *fiq = &fc->iq;
-
                req->in.h.unique = fuse_get_unique(fiq);
                queue_request(fiq, req);
                /* acquire extra reference, since request is still needed
@@ -619,7 +619,7 @@ static int fuse_request_send_notify_reply(struct fuse_conn *fc,
        __clear_bit(FR_ISREPLY, &req->flags);
        req->in.h.unique = unique;
        spin_lock(&fc->lock);
-       if (fc->connected) {
+       if (fiq->connected) {
                queue_request(fiq, req);
                err = 0;
        }
@@ -1071,7 +1071,7 @@ __acquires(fc->lock)
        DECLARE_WAITQUEUE(wait, current);
 
        add_wait_queue_exclusive(&fiq->waitq, &wait);
-       while (fc->connected && !request_pending(fiq)) {
+       while (fiq->connected && !request_pending(fiq)) {
                set_current_state(TASK_INTERRUPTIBLE);
                if (signal_pending(current))
                        break;
@@ -1261,13 +1261,13 @@ static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file,
  restart:
        spin_lock(&fc->lock);
        err = -EAGAIN;
-       if ((file->f_flags & O_NONBLOCK) && fc->connected &&
+       if ((file->f_flags & O_NONBLOCK) && fiq->connected &&
            !request_pending(fiq))
                goto err_unlock;
 
        request_wait(fc);
        err = -ENODEV;
-       if (!fc->connected)
+       if (!fiq->connected)
                goto err_unlock;
        err = -ERESTARTSYS;
        if (!request_pending(fiq))
@@ -2054,7 +2054,7 @@ static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
        poll_wait(file, &fiq->waitq, wait);
 
        spin_lock(&fc->lock);
-       if (!fc->connected)
+       if (!fiq->connected)
                mask = POLLERR;
        else if (request_pending(fiq))
                mask |= POLLIN | POLLRDNORM;
@@ -2127,6 +2127,7 @@ void fuse_abort_conn(struct fuse_conn *fc)
                LIST_HEAD(to_end2);
 
                fc->connected = 0;
+               fiq->connected = 0;
                fc->blocked = 0;
                fuse_set_initialized(fc);
                list_for_each_entry_safe(req, next, &fc->io, list) {
index 3d075417042a336a07ca9ede3219eaf3c7e44e58..e8be4611fb8ed99a5db66a8e5b1ac70c1d01b15f 100644 (file)
@@ -375,6 +375,9 @@ struct fuse_req {
 };
 
 struct fuse_iqueue {
+       /** Connection established */
+       unsigned connected;
+
        /** Readers of the connection are waiting on this */
        wait_queue_head_t waitq;
 
index 0890428bbad0daab318d734057bd09d3e7d8d687..caf77d5a6e8d6e9327c2d2751e5573b72033aff3 100644 (file)
@@ -574,6 +574,7 @@ static void fuse_iqueue_init(struct fuse_iqueue *fiq)
        INIT_LIST_HEAD(&fiq->pending);
        INIT_LIST_HEAD(&fiq->interrupts);
        fiq->forget_list_tail = &fiq->forget_list_head;
+       fiq->connected = 1;
 }
 
 void fuse_conn_init(struct fuse_conn *fc)
@@ -596,6 +597,7 @@ void fuse_conn_init(struct fuse_conn *fc)
        fc->polled_files = RB_ROOT;
        fc->blocked = 0;
        fc->initialized = 0;
+       fc->connected = 1;
        fc->attr_version = 1;
        get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
 }
@@ -1084,7 +1086,6 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
 
        list_add_tail(&fc->entry, &fuse_conn_list);
        sb->s_root = root_dentry;
-       fc->connected = 1;
        file->private_data = fuse_conn_get(fc);
        mutex_unlock(&fuse_mutex);
        /*