Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 18657
b: refs/heads/master
c: 64c6d8e
h: refs/heads/master
i:
  18655: 86efbff
v: v3
  • Loading branch information
Miklos Szeredi authored and Linus Torvalds committed Jan 17, 2006
1 parent aeacd82 commit 0524f0f
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 69a53bf267fa58b89aa659d121dfe38436562a30
refs/heads/master: 64c6d8ed4c55f0a99b1b81558851da80c8d58244
42 changes: 28 additions & 14 deletions trunk/fs/fuse/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
fuse_putback_request() */
for (i = 1; i < FUSE_MAX_OUTSTANDING; i++)
up(&fc->outstanding_sem);

fuse_put_request(fc, req);
}

/*
Expand All @@ -180,13 +182,15 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
* occurred during communication with userspace, or the device file
* was closed. In case of a background request the reference to the
* stored objects are released. The requester thread is woken up (if
* still waiting), and finally the reference to the request is
* released
* still waiting), the 'end' callback is called if given, else the
* reference to the request is released
*
* Called with fuse_lock, unlocks it
*/
static void request_end(struct fuse_conn *fc, struct fuse_req *req)
{
void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;
req->end = NULL;
list_del(&req->list);
req->state = FUSE_REQ_FINISHED;
spin_unlock(&fuse_lock);
Expand All @@ -197,16 +201,10 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
up_read(&fc->sbput_sem);
}
wake_up(&req->waitq);
if (req->in.h.opcode == FUSE_INIT)
process_init_reply(fc, req);
else if (req->in.h.opcode == FUSE_RELEASE && req->inode == NULL) {
/* Special case for failed iget in CREATE */
u64 nodeid = req->in.h.nodeid;
fuse_reset_request(req);
fuse_send_forget(fc, req, nodeid, 1);
return;
}
fuse_put_request(fc, req);
if (end)
end(fc, req);
else
fuse_put_request(fc, req);
}

/*
Expand Down Expand Up @@ -387,6 +385,7 @@ void fuse_send_init(struct fuse_conn *fc)
req->out.argvar = 1;
req->out.args[0].size = sizeof(struct fuse_init_out);
req->out.args[0].value = &req->misc.init_out;
req->end = process_init_reply;
request_send_background(fc, req);
}

Expand Down Expand Up @@ -864,17 +863,32 @@ static void end_requests(struct fuse_conn *fc, struct list_head *head)
* The requests are set to interrupted and finished, and the request
* waiter is woken up. This will make request_wait_answer() wait
* until the request is unlocked and then return.
*
* If the request is asynchronous, then the end function needs to be
* called after waiting for the request to be unlocked (if it was
* locked).
*/
static void end_io_requests(struct fuse_conn *fc)
{
while (!list_empty(&fc->io)) {
struct fuse_req *req;
req = list_entry(fc->io.next, struct fuse_req, list);
struct fuse_req *req =
list_entry(fc->io.next, struct fuse_req, list);
void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;

req->interrupted = 1;
req->out.h.error = -ECONNABORTED;
req->state = FUSE_REQ_FINISHED;
list_del_init(&req->list);
wake_up(&req->waitq);
if (end) {
req->end = NULL;
/* The end function will consume this reference */
__fuse_get_request(req);
spin_unlock(&fuse_lock);
wait_event(req->waitq, !req->locked);
end(fc, req);
spin_lock(&fuse_lock);
}
}
}

Expand Down
10 changes: 10 additions & 0 deletions trunk/fs/fuse/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
return err;
}

/* Special case for failed iget in CREATE */
static void fuse_release_end(struct fuse_conn *fc, struct fuse_req *req)
{
u64 nodeid = req->in.h.nodeid;
fuse_reset_request(req);
fuse_send_forget(fc, req, nodeid, 1);
}

void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff,
u64 nodeid, struct inode *inode, int flags, int isdir)
{
Expand All @@ -128,6 +136,8 @@ void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff,
req->in.args[0].size = sizeof(struct fuse_release_in);
req->in.args[0].value = inarg;
request_send_background(fc, req);
if (!inode)
req->end = fuse_release_end;
kfree(ff);
}

Expand Down
5 changes: 5 additions & 0 deletions trunk/fs/fuse/fuse_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ enum fuse_req_state {
FUSE_REQ_FINISHED
};

struct fuse_conn;

/**
* A request to the client
*/
Expand Down Expand Up @@ -186,6 +188,9 @@ struct fuse_req {

/** File used in the request (or NULL) */
struct file *file;

/** Request completion callback */
void (*end)(struct fuse_conn *, struct fuse_req *);
};

/**
Expand Down

0 comments on commit 0524f0f

Please sign in to comment.