Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 61623
b: refs/heads/master
c: fe71b5f
h: refs/heads/master
i:
  61621: 56f1010
  61619: 1139d10
  61615: b7bdd25
v: v3
  • Loading branch information
Jan Harkes authored and Linus Torvalds committed Jul 19, 2007
1 parent bd4bd5d commit b30450e
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 64 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: 87065519633af79e0577e32a58dcd9cf3c45a8a0
refs/heads/master: fe71b5f3871af2c281a08acd4bedd2da25e46bc3
121 changes: 58 additions & 63 deletions trunk/fs/coda/upcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -687,41 +687,41 @@ static inline void coda_waitfor_upcall(struct upc_req *vmp)
* are all mapped to -EINTR, while showing a nice warning message. (jh)
*
*/
static int coda_upcall(struct coda_sb_info *sbi,
int inSize, int *outSize,
union inputArgs *buffer)
static int coda_upcall(struct coda_sb_info *sbi,
int inSize, int *outSize,
union inputArgs *buffer)
{
struct venus_comm *vcommp;
union outputArgs *out;
struct upc_req *req;
union inputArgs *sig_inputArgs;
struct upc_req *req, *sig_req;
int error = 0;

vcommp = sbi->sbi_vcomm;
if ( !vcommp->vc_inuse ) {
printk("No pseudo device in upcall comms at %p\n", vcommp);
return -ENXIO;
if (!vcommp->vc_inuse) {
printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n");
return -ENXIO;
}

/* Format the request message. */
req = upc_alloc();
if (!req) {
printk("Failed to allocate upc_req structure\n");
if (!req)
return -ENOMEM;
}

req->uc_data = (void *)buffer;
req->uc_flags = 0;
req->uc_inSize = inSize;
req->uc_outSize = *outSize ? *outSize : inSize;
req->uc_opcode = ((union inputArgs *)buffer)->ih.opcode;
req->uc_unique = ++vcommp->vc_seq;
init_waitqueue_head(&req->uc_sleep);

/* Fill in the common input args. */
((union inputArgs *)buffer)->ih.unique = req->uc_unique;

/* Append msg to pending queue and poke Venus. */
list_add_tail(&(req->uc_chain), &vcommp->vc_pending);
list_add_tail(&req->uc_chain, &vcommp->vc_pending);

wake_up_interruptible(&vcommp->vc_waitq);
/* We can be interrupted while we wait for Venus to process
* our request. If the interrupt occurs before Venus has read
Expand All @@ -735,64 +735,59 @@ static int coda_upcall(struct coda_sb_info *sbi,
/* Go to sleep. Wake up on signals only after the timeout. */
coda_waitfor_upcall(req);

if (vcommp->vc_inuse) { /* i.e. Venus is still alive */
/* Op went through, interrupt or not... */
if (req->uc_flags & REQ_WRITE) {
/* Op went through, interrupt or not... */
if (req->uc_flags & REQ_WRITE) {
out = (union outputArgs *)req->uc_data;
/* here we map positive Venus errors to kernel errors */
error = -out->oh.result;
*outSize = req->uc_outSize;
goto exit;
}
if ( !(req->uc_flags & REQ_READ) && signal_pending(current)) {
/* Interrupted before venus read it. */
list_del(&(req->uc_chain));
/* perhaps the best way to convince the app to
give up? */
error = -EINTR;
}

error = -EINTR;
if ((req->uc_flags & REQ_ABORT) || !signal_pending(current)) {
printk(KERN_WARNING "coda: Unexpected interruption.\n");
goto exit;
}
if ( (req->uc_flags & REQ_READ) && signal_pending(current) ) {
/* interrupted after Venus did its read, send signal */
union inputArgs *sig_inputArgs;
struct upc_req *sig_req;

list_del(&(req->uc_chain));
error = -ENOMEM;
sig_req = upc_alloc();
if (!sig_req) goto exit;

CODA_ALLOC((sig_req->uc_data), char *, sizeof(struct coda_in_hdr));
if (!sig_req->uc_data) {
upc_free(sig_req);
goto exit;
}

error = -EINTR;
sig_inputArgs = (union inputArgs *)sig_req->uc_data;
sig_inputArgs->ih.opcode = CODA_SIGNAL;
sig_inputArgs->ih.unique = req->uc_unique;

sig_req->uc_flags = REQ_ASYNC;
sig_req->uc_opcode = sig_inputArgs->ih.opcode;
sig_req->uc_unique = sig_inputArgs->ih.unique;
sig_req->uc_inSize = sizeof(struct coda_in_hdr);
sig_req->uc_outSize = sizeof(struct coda_in_hdr);

/* insert at head of queue! */
list_add(&(sig_req->uc_chain), &vcommp->vc_pending);
wake_up_interruptible(&vcommp->vc_waitq);
} else {
printk("Coda: Strange interruption..\n");
error = -EINTR;
}
} else { /* If venus died i.e. !VC_OPEN(vcommp) */
printk("coda_upcall: Venus dead on (op,un) (%d.%d) flags %d\n",
req->uc_opcode, req->uc_unique, req->uc_flags);
error = -ENODEV;
}

exit:
list_del(&(req->uc_chain));

/* Interrupted before venus read it. */
if (!(req->uc_flags & REQ_READ))
goto exit;

/* Venus saw the upcall, make sure we can send interrupt signal */
if (!vcommp->vc_inuse) {
printk(KERN_INFO "coda: Venus dead, not sending signal.\n");
goto exit;
}

error = -ENOMEM;
sig_req = upc_alloc();
if (!sig_req) goto exit;

CODA_ALLOC((sig_req->uc_data), char *, sizeof(struct coda_in_hdr));
if (!sig_req->uc_data) {
upc_free(sig_req);
goto exit;
}

error = -EINTR;
sig_inputArgs = (union inputArgs *)sig_req->uc_data;
sig_inputArgs->ih.opcode = CODA_SIGNAL;
sig_inputArgs->ih.unique = req->uc_unique;

sig_req->uc_flags = REQ_ASYNC;
sig_req->uc_opcode = sig_inputArgs->ih.opcode;
sig_req->uc_unique = sig_inputArgs->ih.unique;
sig_req->uc_inSize = sizeof(struct coda_in_hdr);
sig_req->uc_outSize = sizeof(struct coda_in_hdr);

/* insert at head of queue! */
list_add(&(sig_req->uc_chain), &vcommp->vc_pending);
wake_up_interruptible(&vcommp->vc_waitq);

exit:
upc_free(req);
return error;
}
Expand Down

0 comments on commit b30450e

Please sign in to comment.