diff options
| author | Andrew Morton <akpm@digeo.com> | 2002-10-28 16:22:23 -0800 |
|---|---|---|
| committer | Jens Axboe <axboe@suse.de> | 2002-10-28 16:22:23 -0800 |
| commit | 4a4c6811f4fb8aa7f59fbb04c678e48d080e1071 (patch) | |
| tree | dba6ecf5bd85ac2c0100be691b45de6ce5490c8a /include/linux/fs.h | |
| parent | a9577554546f46b9c53773e7dbfb295a2e968799 (diff) | |
[PATCH] permit direct IO with finer-than-fs-blocksize alignments
Mainly from Badari Pulavarty
Traditionally we have only supported O_DIRECT I/O at an alignment and
granularity which matches the underlying filesystem. That typically
means that all IO must be 4k-aligned and a multiple of 4k in size.
Here, we relax that so that direct I/O happens with (typically)
512-byte alignment and multiple-of-512-byte size.
The tricky part is when a write starts and/or ends partway through a
filesystem block which has just been added. We need to zero out the
parts of that block which lie outside the written region.
We handle that by putting appropriately-sized parts of the ZERO_PAGE
into sepatate BIOs.
The generic_direct_IO() function has been changed so that the
filesystem must pass in the address of the block_device against which
the IO is to be performed. I'd have preferred to not do this, but we
do need that info at that time so that alignment checks can be
performed.
If the filesystem passes in a NULL block_device pointer then we fall
back to the old behaviour - must align with the fs blocksize.
There is no trivial way for userspace to know what the minimum
alignment is - it depends on what bdev_hardsect_size() says about the
device. It is _usually_ 512 bytes, but not always. This introduces
the risk that someone will develop and test applications which work
fine on their hardware, but will fail on someone else's hardware.
It is possible to query the hardsect size using the BLKSSZGET ioctl
against the backing block device. This can be performed at runtime or
at application installation time.
Diffstat (limited to 'include/linux/fs.h')
| -rw-r--r-- | include/linux/fs.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h index d6d1e30c01dd..862d767fe310 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1252,8 +1252,8 @@ extern void do_generic_mapping_read(struct address_space *, struct file_ra_state loff_t *, read_descriptor_t *, read_actor_t); extern ssize_t generic_file_direct_IO(int rw, struct file *file, const struct iovec *iov, loff_t offset, unsigned long nr_segs); -extern int generic_direct_IO(int rw, struct inode *inode, const struct iovec - *iov, loff_t offset, unsigned long nr_segs, get_blocks_t *get_blocks); +extern int generic_direct_IO(int rw, struct inode *inode, struct block_device *bdev, + const struct iovec *iov, loff_t offset, unsigned long nr_segs, get_blocks_t *get_blocks); extern ssize_t generic_file_readv(struct file *filp, const struct iovec *iov, unsigned long nr_segs, loff_t *ppos); ssize_t generic_file_writev(struct file *filp, const struct iovec *iov, |
