Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 44008
b: refs/heads/master
c: 20258b2
h: refs/heads/master
v: v3
  • Loading branch information
Zach Brown authored and Linus Torvalds committed Dec 10, 2006
1 parent 54aa199 commit 0a45f2b
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 30 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: 0273201e693fd62381f6b1e85b15ffc117d8a46e
refs/heads/master: 20258b2b397031649e4a41922fe803d57017df84
41 changes: 12 additions & 29 deletions trunk/fs/direct-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,6 @@ static int dio_complete(struct dio *dio, loff_t offset, int ret)
*/
static void dio_complete_aio(struct dio *dio)
{
unsigned long flags;
int ret;

ret = dio_complete(dio, dio->iocb->ki_pos, 0);
Expand All @@ -267,14 +266,6 @@ static void dio_complete_aio(struct dio *dio)
((dio->rw == READ) && dio->result)) {
aio_complete(dio->iocb, ret, 0);
kfree(dio);
} else {
/*
* Falling back to buffered
*/
spin_lock_irqsave(&dio->bio_lock, flags);
if (dio->waiter)
wake_up_process(dio->waiter);
spin_unlock_irqrestore(&dio->bio_lock, flags);
}
}

Expand All @@ -285,14 +276,21 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio);
static int dio_bio_end_aio(struct bio *bio, unsigned int bytes_done, int error)
{
struct dio *dio = bio->bi_private;
int waiter_holds_ref = 0;
int remaining;

if (bio->bi_size)
return 1;

/* cleanup the bio */
dio_bio_complete(dio, bio);

if (atomic_dec_and_test(&dio->refcount))
waiter_holds_ref = !!dio->waiter;
remaining = atomic_sub_return(1, (&dio->refcount));
if (remaining == 1 && waiter_holds_ref)
wake_up_process(dio->waiter);

if (remaining == 0)
dio_complete_aio(dio);

return 0;
Expand Down Expand Up @@ -1097,30 +1095,15 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
if (ret == 0)
ret = dio->result;

if (should_wait)
dio_await_completion(dio);

/* this can free the dio */
if (atomic_dec_and_test(&dio->refcount))
dio_complete_aio(dio);

if (should_wait) {
unsigned long flags;
/*
* Wait for already issued I/O to drain out and
* release its references to user-space pages
* before returning to fallback on buffered I/O
*/

spin_lock_irqsave(&dio->bio_lock, flags);
set_current_state(TASK_UNINTERRUPTIBLE);
while (atomic_read(&dio->refcount)) {
spin_unlock_irqrestore(&dio->bio_lock, flags);
io_schedule();
spin_lock_irqsave(&dio->bio_lock, flags);
set_current_state(TASK_UNINTERRUPTIBLE);
}
spin_unlock_irqrestore(&dio->bio_lock, flags);
set_current_state(TASK_RUNNING);
if (should_wait)
kfree(dio);
}
} else {
dio_await_completion(dio);

Expand Down

0 comments on commit 0a45f2b

Please sign in to comment.