|
@@ -98,8 +98,11 @@ struct nfs_direct_req {
|
|
|
struct pnfs_ds_commit_info ds_cinfo; /* Storage for cinfo */
|
|
|
struct work_struct work;
|
|
|
int flags;
|
|
|
+ /* for write */
|
|
|
#define NFS_ODIRECT_DO_COMMIT (1) /* an unstable reply was received */
|
|
|
#define NFS_ODIRECT_RESCHED_WRITES (2) /* write verification failed */
|
|
|
+ /* for read */
|
|
|
+#define NFS_ODIRECT_SHOULD_DIRTY (3) /* dirty user-space page after read */
|
|
|
struct nfs_writeverf verf; /* unstable write verifier */
|
|
|
};
|
|
|
|
|
@@ -412,7 +415,8 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
|
|
|
struct nfs_page *req = nfs_list_entry(hdr->pages.next);
|
|
|
struct page *page = req->wb_page;
|
|
|
|
|
|
- if (!PageCompound(page) && bytes < hdr->good_bytes)
|
|
|
+ if (!PageCompound(page) && bytes < hdr->good_bytes &&
|
|
|
+ (dreq->flags == NFS_ODIRECT_SHOULD_DIRTY))
|
|
|
set_page_dirty(page);
|
|
|
bytes += req->wb_bytes;
|
|
|
nfs_list_remove_request(req);
|
|
@@ -587,6 +591,9 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter)
|
|
|
if (!is_sync_kiocb(iocb))
|
|
|
dreq->iocb = iocb;
|
|
|
|
|
|
+ if (iter_is_iovec(iter))
|
|
|
+ dreq->flags = NFS_ODIRECT_SHOULD_DIRTY;
|
|
|
+
|
|
|
nfs_start_io_direct(inode);
|
|
|
|
|
|
NFS_I(inode)->read_io += count;
|