Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 199003
b: refs/heads/master
c: facd07b
h: refs/heads/master
i:
  199001: 6fb57d8
  198999: 08f7b31
v: v3
  • Loading branch information
Josef Bacik authored and Chris Mason committed May 25, 2010
1 parent 06118a1 commit 8c4cb38
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 9 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: 66f998f611897319b555364cefd5d6e88a205866
refs/heads/master: facd07b07d2a7988f5ce849558838cc953847637
42 changes: 37 additions & 5 deletions trunk/fs/direct-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ struct dio {
int reap_counter; /* rate limit reaping */
get_block_t *get_block; /* block mapping function */
dio_iodone_t *end_io; /* IO completion function */
dio_submit_t *submit_io; /* IO submition function */
loff_t logical_offset_in_bio; /* current first logical block in bio */
sector_t final_block_in_bio; /* current final block in bio + 1 */
sector_t next_block_for_io; /* next block to be put under IO,
in dio_blocks units */
Expand All @@ -96,6 +98,7 @@ struct dio {
unsigned cur_page_offset; /* Offset into it, in bytes */
unsigned cur_page_len; /* Nr of bytes at cur_page_offset */
sector_t cur_page_block; /* Where it starts */
loff_t cur_page_fs_offset; /* Offset in file */

/* BIO completion state */
spinlock_t bio_lock; /* protects BIO fields below */
Expand Down Expand Up @@ -300,6 +303,26 @@ static void dio_bio_end_io(struct bio *bio, int error)
spin_unlock_irqrestore(&dio->bio_lock, flags);
}

/**
* dio_end_io - handle the end io action for the given bio
* @bio: The direct io bio thats being completed
* @error: Error if there was one
*
* This is meant to be called by any filesystem that uses their own dio_submit_t
* so that the DIO specific endio actions are dealt with after the filesystem
* has done it's completion work.
*/
void dio_end_io(struct bio *bio, int error)
{
struct dio *dio = bio->bi_private;

if (dio->is_async)
dio_bio_end_aio(bio, error);
else
dio_bio_end_io(bio, error);
}
EXPORT_SYMBOL_GPL(dio_end_io);

static int
dio_bio_alloc(struct dio *dio, struct block_device *bdev,
sector_t first_sector, int nr_vecs)
Expand All @@ -316,6 +339,7 @@ dio_bio_alloc(struct dio *dio, struct block_device *bdev,
bio->bi_end_io = dio_bio_end_io;

dio->bio = bio;
dio->logical_offset_in_bio = dio->cur_page_fs_offset;
return 0;
}

Expand All @@ -340,10 +364,15 @@ static void dio_bio_submit(struct dio *dio)
if (dio->is_async && dio->rw == READ)
bio_set_pages_dirty(bio);

submit_bio(dio->rw, bio);
if (dio->submit_io)
dio->submit_io(dio->rw, bio, dio->inode,
dio->logical_offset_in_bio);
else
submit_bio(dio->rw, bio);

dio->bio = NULL;
dio->boundary = 0;
dio->logical_offset_in_bio = 0;
}

/*
Expand Down Expand Up @@ -701,6 +730,7 @@ submit_page_section(struct dio *dio, struct page *page,
dio->cur_page_offset = offset;
dio->cur_page_len = len;
dio->cur_page_block = blocknr;
dio->cur_page_fs_offset = dio->block_in_file << dio->blkbits;
out:
return ret;
}
Expand Down Expand Up @@ -935,7 +965,7 @@ static ssize_t
direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
const struct iovec *iov, loff_t offset, unsigned long nr_segs,
unsigned blkbits, get_block_t get_block, dio_iodone_t end_io,
struct dio *dio)
dio_submit_t submit_io, struct dio *dio)
{
unsigned long user_addr;
unsigned long flags;
Expand All @@ -952,6 +982,7 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,

dio->get_block = get_block;
dio->end_io = end_io;
dio->submit_io = submit_io;
dio->final_block_in_bio = -1;
dio->next_block_for_io = -1;

Expand Down Expand Up @@ -1008,7 +1039,7 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
}
} /* end iovec loop */

if (ret == -ENOTBLK && (rw & WRITE)) {
if (ret == -ENOTBLK) {
/*
* The remaining part of the request will be
* be handled by buffered I/O when we return
Expand Down Expand Up @@ -1110,7 +1141,7 @@ ssize_t
__blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
struct block_device *bdev, const struct iovec *iov, loff_t offset,
unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
int flags)
dio_submit_t submit_io, int flags)
{
int seg;
size_t size;
Expand Down Expand Up @@ -1197,7 +1228,8 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
(end > i_size_read(inode)));

retval = direct_io_worker(rw, iocb, inode, iov, offset,
nr_segs, blkbits, get_block, end_io, dio);
nr_segs, blkbits, get_block, end_io,
submit_io, dio);

/*
* In case of error extending write may have instantiated a few
Expand Down
11 changes: 8 additions & 3 deletions trunk/include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2250,10 +2250,15 @@ static inline int xip_truncate_page(struct address_space *mapping, loff_t from)
#endif

#ifdef CONFIG_BLOCK
struct bio;
typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode,
loff_t file_offset);
void dio_end_io(struct bio *bio, int error);

ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
struct block_device *bdev, const struct iovec *iov, loff_t offset,
unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
int lock_type);
dio_submit_t submit_io, int lock_type);

enum {
/* need locking between buffered and direct access */
Expand All @@ -2269,7 +2274,7 @@ static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb,
dio_iodone_t end_io)
{
return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
nr_segs, get_block, end_io,
nr_segs, get_block, end_io, NULL,
DIO_LOCKING | DIO_SKIP_HOLES);
}

Expand All @@ -2279,7 +2284,7 @@ static inline ssize_t blockdev_direct_IO_no_locking(int rw, struct kiocb *iocb,
dio_iodone_t end_io)
{
return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
nr_segs, get_block, end_io, 0);
nr_segs, get_block, end_io, NULL, 0);
}
#endif

Expand Down

0 comments on commit 8c4cb38

Please sign in to comment.