Skip to content

Commit f00a344

Browse files
ukernelgregkh
authored andcommitted
ceph: only dirty ITER_IOVEC pages for direct read
commit 85784f9 upstream. If a page is already locked, attempting to dirty it leads to a deadlock in lock_page(). This is what currently happens to ITER_BVEC pages when a dio-enabled loop device is backed by ceph: $ losetup --direct-io /dev/loop0 /mnt/cephfs/img $ xfs_io -c 'pread 0 4k' /dev/loop0 Follow other file systems and only dirty ITER_IOVEC pages. Cc: [email protected] Signed-off-by: "Yan, Zheng" <[email protected]> Reviewed-by: Ilya Dryomov <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ca04476 commit f00a344

File tree

1 file changed

+6
-3
lines changed

1 file changed

+6
-3
lines changed

fs/ceph/file.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,8 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *to,
635635
struct ceph_aio_request {
636636
struct kiocb *iocb;
637637
size_t total_len;
638-
int write;
638+
bool write;
639+
bool should_dirty;
639640
int error;
640641
struct list_head osd_reqs;
641642
unsigned num_reqs;
@@ -745,7 +746,7 @@ static void ceph_aio_complete_req(struct ceph_osd_request *req)
745746
}
746747
}
747748

748-
ceph_put_page_vector(osd_data->pages, num_pages, !aio_req->write);
749+
ceph_put_page_vector(osd_data->pages, num_pages, aio_req->should_dirty);
749750
ceph_osdc_put_request(req);
750751

751752
if (rc < 0)
@@ -842,6 +843,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
842843
size_t count = iov_iter_count(iter);
843844
loff_t pos = iocb->ki_pos;
844845
bool write = iov_iter_rw(iter) == WRITE;
846+
bool should_dirty = !write && iter_is_iovec(iter);
845847

846848
if (write && ceph_snap(file_inode(file)) != CEPH_NOSNAP)
847849
return -EROFS;
@@ -909,6 +911,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
909911
if (aio_req) {
910912
aio_req->iocb = iocb;
911913
aio_req->write = write;
914+
aio_req->should_dirty = should_dirty;
912915
INIT_LIST_HEAD(&aio_req->osd_reqs);
913916
if (write) {
914917
aio_req->mtime = mtime;
@@ -966,7 +969,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
966969
len = ret;
967970
}
968971

969-
ceph_put_page_vector(pages, num_pages, !write);
972+
ceph_put_page_vector(pages, num_pages, should_dirty);
970973

971974
ceph_osdc_put_request(req);
972975
if (ret < 0)

0 commit comments

Comments
 (0)