Skip to content

Commit db880e1

Browse files
committed
NFS: O_DIRECT writes must check and adjust the file length
jira LE-3497 Rebuild_History Non-Buildable kernel-5.14.0-570.24.1.el9_6 commit-author Trond Myklebust <[email protected]> commit fcf857e While it is uncommon for delegations to be held while O_DIRECT writes are in progress, it is possible. The xfstests generic/647 and generic/729 both end up triggering that state, and end up failing due to the fact that the file size is not adjusted. Reported-by: Chuck Lever <[email protected]> Link: https://bugzilla.kernel.org/show_bug.cgi?id=219738 Cc: [email protected] Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: Anna Schumaker <[email protected]> (cherry picked from commit fcf857e) Signed-off-by: Jonathan Maple <[email protected]>
1 parent 833cb8c commit db880e1

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

fs/nfs/direct.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,20 @@ static void nfs_direct_truncate_request(struct nfs_direct_req *dreq,
130130
dreq->count = req_start;
131131
}
132132

133+
static void nfs_direct_file_adjust_size_locked(struct inode *inode,
134+
loff_t offset, size_t count)
135+
{
136+
loff_t newsize = offset + (loff_t)count;
137+
loff_t oldsize = i_size_read(inode);
138+
139+
if (newsize > oldsize) {
140+
i_size_write(inode, newsize);
141+
NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_SIZE;
142+
trace_nfs_size_grow(inode, newsize);
143+
nfs_inc_stats(inode, NFSIOS_EXTENDWRITE);
144+
}
145+
}
146+
133147
/**
134148
* nfs_swap_rw - NFS address space operation for swap I/O
135149
* @iocb: target I/O control block
@@ -732,6 +746,7 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
732746
struct nfs_direct_req *dreq = hdr->dreq;
733747
struct nfs_commit_info cinfo;
734748
struct nfs_page *req = nfs_list_entry(hdr->pages.next);
749+
struct inode *inode = dreq->inode;
735750
int flags = NFS_ODIRECT_DONE;
736751

737752
trace_nfs_direct_write_completion(dreq);
@@ -753,6 +768,10 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
753768
}
754769
spin_unlock(&dreq->lock);
755770

771+
spin_lock(&inode->i_lock);
772+
nfs_direct_file_adjust_size_locked(inode, dreq->io_start, dreq->count);
773+
spin_unlock(&inode->i_lock);
774+
756775
while (!list_empty(&hdr->pages)) {
757776

758777
req = nfs_list_entry(hdr->pages.next);

0 commit comments

Comments
 (0)