mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-04 08:08:54 +00:00
iomap: support direct I/O to inline data
Add support for reading from and writing to inline data to iomap_dio_rw. This saves filesystems from having to implement fallback code for this case. The inline data is actually cached in the inode, so the I/O is only direct in the sense that it doesn't go through the page cache. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
parent
09230435df
commit
ec181f6782
1 changed files with 29 additions and 0 deletions
29
fs/iomap.c
29
fs/iomap.c
|
@ -1450,6 +1450,33 @@ iomap_dio_hole_actor(loff_t length, struct iomap_dio *dio)
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static loff_t
|
||||||
|
iomap_dio_inline_actor(struct inode *inode, loff_t pos, loff_t length,
|
||||||
|
struct iomap_dio *dio, struct iomap *iomap)
|
||||||
|
{
|
||||||
|
struct iov_iter *iter = dio->submit.iter;
|
||||||
|
size_t copied;
|
||||||
|
|
||||||
|
BUG_ON(pos + length > PAGE_SIZE - offset_in_page(iomap->inline_data));
|
||||||
|
|
||||||
|
if (dio->flags & IOMAP_DIO_WRITE) {
|
||||||
|
loff_t size = inode->i_size;
|
||||||
|
|
||||||
|
if (pos > size)
|
||||||
|
memset(iomap->inline_data + size, 0, pos - size);
|
||||||
|
copied = copy_from_iter(iomap->inline_data + pos, length, iter);
|
||||||
|
if (copied) {
|
||||||
|
if (pos + copied > size)
|
||||||
|
i_size_write(inode, pos + copied);
|
||||||
|
mark_inode_dirty(inode);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
copied = copy_to_iter(iomap->inline_data + pos, length, iter);
|
||||||
|
}
|
||||||
|
dio->size += copied;
|
||||||
|
return copied;
|
||||||
|
}
|
||||||
|
|
||||||
static loff_t
|
static loff_t
|
||||||
iomap_dio_actor(struct inode *inode, loff_t pos, loff_t length,
|
iomap_dio_actor(struct inode *inode, loff_t pos, loff_t length,
|
||||||
void *data, struct iomap *iomap)
|
void *data, struct iomap *iomap)
|
||||||
|
@ -1467,6 +1494,8 @@ iomap_dio_actor(struct inode *inode, loff_t pos, loff_t length,
|
||||||
return iomap_dio_bio_actor(inode, pos, length, dio, iomap);
|
return iomap_dio_bio_actor(inode, pos, length, dio, iomap);
|
||||||
case IOMAP_MAPPED:
|
case IOMAP_MAPPED:
|
||||||
return iomap_dio_bio_actor(inode, pos, length, dio, iomap);
|
return iomap_dio_bio_actor(inode, pos, length, dio, iomap);
|
||||||
|
case IOMAP_INLINE:
|
||||||
|
return iomap_dio_inline_actor(inode, pos, length, dio, iomap);
|
||||||
default:
|
default:
|
||||||
WARN_ON_ONCE(1);
|
WARN_ON_ONCE(1);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
Loading…
Reference in a new issue