aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2010-05-23 11:00:55 -0400
committerChris Mason <chris.mason@oracle.com>2010-05-25 10:34:55 -0400
commitfacd07b07d2a7988f5ce849558838cc953847637 (patch)
tree269200329390f450d2bc7f0858a8ed114a418374 /include
parent66f998f611897319b555364cefd5d6e88a205866 (diff)
direct-io: add a hook for the fs to provide its own submit_bio function
Because BTRFS can do RAID and such, we need our own submit hook so we can setup the bio's in the correct fashion, and handle checksum errors properly. So there are a few changes here 1) The submit_io hook. This is straightforward, just call this instead of submit_bio. 2) Allow the fs to return -ENOTBLK for reads. Usually this has only worked for writes, since writes can fallback onto buffered IO. But BTRFS needs the option of falling back on buffered IO if it encounters a compressed extent, since we need to read the entire extent in and decompress it. So if we get -ENOTBLK back from get_block we'll return back and fallback on buffered just like the write case. I've tested these changes with fsx and everything seems to work. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/fs.h11
1 files changed, 8 insertions, 3 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 44f35aea2f1f..10704f0086c8 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2250,10 +2250,15 @@ static inline int xip_truncate_page(struct address_space *mapping, loff_t from)
2250#endif 2250#endif
2251 2251
2252#ifdef CONFIG_BLOCK 2252#ifdef CONFIG_BLOCK
2253struct bio;
2254typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode,
2255 loff_t file_offset);
2256void dio_end_io(struct bio *bio, int error);
2257
2253ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, 2258ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
2254 struct block_device *bdev, const struct iovec *iov, loff_t offset, 2259 struct block_device *bdev, const struct iovec *iov, loff_t offset,
2255 unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io, 2260 unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
2256 int lock_type); 2261 dio_submit_t submit_io, int lock_type);
2257 2262
2258enum { 2263enum {
2259 /* need locking between buffered and direct access */ 2264 /* need locking between buffered and direct access */
@@ -2269,7 +2274,7 @@ static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb,
2269 dio_iodone_t end_io) 2274 dio_iodone_t end_io)
2270{ 2275{
2271 return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset, 2276 return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
2272 nr_segs, get_block, end_io, 2277 nr_segs, get_block, end_io, NULL,
2273 DIO_LOCKING | DIO_SKIP_HOLES); 2278 DIO_LOCKING | DIO_SKIP_HOLES);
2274} 2279}
2275 2280
@@ -2279,7 +2284,7 @@ static inline ssize_t blockdev_direct_IO_no_locking(int rw, struct kiocb *iocb,
2279 dio_iodone_t end_io) 2284 dio_iodone_t end_io)
2280{ 2285{
2281 return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset, 2286 return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
2282 nr_segs, get_block, end_io, 0); 2287 nr_segs, get_block, end_io, NULL, 0);
2283} 2288}
2284#endif 2289#endif
2285 2290