mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
Update pin_user_pages() calls for Direct I/O
Originally #16856 updated Linux Direct I/O requests to use the new pin_user_pages API. However, it was an oversight that this PR only handled iov_iter's of type ITER_IOVEC and ITER_UBUF. Other iov_iter types may try and use the pin_user_pages API if it is available. This can lead to panics as the iov_iter is not being iterated over correctly in zfs_uio_pin_user_pages(). Unfortunately, generic iov_iter API's that call pin_user_page_fast() are protected as GPL only. Rather than update zfs_uio_pin_user_pages() to account for all iov_iter types, we can simply just call zfs_uio_get_dio_page_iov_iter() if the iov_iter type is not ITER_IOVEC or ITER_UBUF. zfs_uio_get_dio_page_iov_iter() calls the iov_iter_get_pages() calls that can handle any iov_iter type. In the future it might be worth using the exposed iov_iter iterator functions that are included in the header iov_iter.h since v6.7. These functions allow for any iov_iter type to be iterated over and advanced while applying a step function during iteration. This could possibly be leveraged in zfs_uio_pin_user_pages(). A new ZFS test case was added to test that a ITER_BVEC is handled correctly using this new code path. This test case was provided though issue #16956. Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Ameer Hamza <ahamza@ixsystems.com> Signed-off-by: Brian Atkinson <batkinson@lanl.gov> Closes #16956 Closes #17006
This commit is contained in:
committed by
Ameer Hamza
parent
6e9911212e
commit
0e21e473a7
@@ -63,6 +63,7 @@ typedef enum zfs_uio_seg {
|
||||
typedef struct {
|
||||
struct page **pages; /* Mapped pages */
|
||||
long npages; /* Number of mapped pages */
|
||||
boolean_t pinned; /* Whether FOLL_PIN was used */
|
||||
} zfs_uio_dio_t;
|
||||
|
||||
typedef struct zfs_uio {
|
||||
@@ -199,4 +200,13 @@ zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset,
|
||||
#define zfs_uio_iov_iter_type(iter) (iter)->type
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ITER_IS_UBUF)
|
||||
#define zfs_user_backed_iov_iter(iter) \
|
||||
(iter_is_ubuf((iter)) || \
|
||||
(zfs_uio_iov_iter_type((iter)) == ITER_IOVEC))
|
||||
#else
|
||||
#define zfs_user_backed_iov_iter(iter) \
|
||||
(zfs_uio_iov_iter_type((iter)) == ITER_IOVEC)
|
||||
#endif
|
||||
|
||||
#endif /* SPL_UIO_H */
|
||||
|
||||
Reference in New Issue
Block a user