Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 61624
b: refs/heads/master
c: d9664c9
h: refs/heads/master
v: v3
  • Loading branch information
Jan Harkes authored and Linus Torvalds committed Jul 19, 2007
1 parent b30450e commit 3a24ae5
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 23 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: fe71b5f3871af2c281a08acd4bedd2da25e46bc3
refs/heads/master: d9664c95afe5baa92ea56eff6a1c18e7b7a2cbe7
81 changes: 60 additions & 21 deletions trunk/fs/coda/upcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,42 +638,83 @@ int venus_statfs(struct dentry *dentry, struct kstatfs *sfs)

/*
* coda_upcall and coda_downcall routines.
*
*/
static void block_signals(sigset_t *old)
{
spin_lock_irq(&current->sighand->siglock);
*old = current->blocked;

sigfillset(&current->blocked);
sigdelset(&current->blocked, SIGKILL);
sigdelset(&current->blocked, SIGSTOP);
sigdelset(&current->blocked, SIGINT);

recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
}

static void unblock_signals(sigset_t *old)
{
spin_lock_irq(&current->sighand->siglock);
current->blocked = *old;
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
}

/* Don't allow signals to interrupt the following upcalls before venus
* has seen them,
* - CODA_CLOSE or CODA_RELEASE upcall (to avoid reference count problems)
* - CODA_STORE (to avoid data loss)
*/
#define CODA_INTERRUPTIBLE(r) (!coda_hard && \
(((r)->uc_opcode != CODA_CLOSE && \
(r)->uc_opcode != CODA_STORE && \
(r)->uc_opcode != CODA_RELEASE) || \
(r)->uc_flags & REQ_READ))

static inline void coda_waitfor_upcall(struct upc_req *vmp)
static inline void coda_waitfor_upcall(struct upc_req *req)
{
DECLARE_WAITQUEUE(wait, current);
unsigned long timeout = jiffies + coda_timeout * HZ;
sigset_t old;
int blocked;

vmp->uc_posttime = jiffies;
block_signals(&old);
blocked = 1;

add_wait_queue(&vmp->uc_sleep, &wait);
add_wait_queue(&req->uc_sleep, &wait);
for (;;) {
if ( !coda_hard && vmp->uc_opcode != CODA_CLOSE )
if (CODA_INTERRUPTIBLE(req))
set_current_state(TASK_INTERRUPTIBLE);
else
set_current_state(TASK_UNINTERRUPTIBLE);

/* got a reply */
if ( vmp->uc_flags & ( REQ_WRITE | REQ_ABORT ) )
if (req->uc_flags & (REQ_WRITE | REQ_ABORT))
break;

if ( !coda_hard && vmp->uc_opcode != CODA_CLOSE && signal_pending(current) ) {
/* if this process really wants to die, let it go */
if ( sigismember(&(current->pending.signal), SIGKILL) ||
sigismember(&(current->pending.signal), SIGINT) )
break;
/* signal is present: after timeout always return
really smart idea, probably useless ... */
if ( jiffies - vmp->uc_posttime > coda_timeout * HZ )
break;
if (blocked && time_after(jiffies, timeout) &&
CODA_INTERRUPTIBLE(req))
{
unblock_signals(&old);
blocked = 0;
}
schedule();

if (signal_pending(current)) {
list_del(&req->uc_chain);
break;
}

if (blocked)
schedule_timeout(HZ);
else
schedule();
}
remove_wait_queue(&vmp->uc_sleep, &wait);
set_current_state(TASK_RUNNING);
if (blocked)
unblock_signals(&old);

return;
remove_wait_queue(&req->uc_sleep, &wait);
set_current_state(TASK_RUNNING);
}


Expand Down Expand Up @@ -750,8 +791,6 @@ static int coda_upcall(struct coda_sb_info *sbi,
goto exit;
}

list_del(&(req->uc_chain));

/* Interrupted before venus read it. */
if (!(req->uc_flags & REQ_READ))
goto exit;
Expand Down
1 change: 0 additions & 1 deletion trunk/include/linux/coda_psdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ struct upc_req {
u_short uc_opcode; /* copied from data to save lookup */
int uc_unique;
wait_queue_head_t uc_sleep; /* process' wait queue */
unsigned long uc_posttime;
};

#define REQ_ASYNC 0x1
Expand Down

0 comments on commit 3a24ae5

Please sign in to comment.