@@ -137,6 +137,7 @@ int nfs42_proc_allocate(struct file *filep, loff_t offset, loff_t len)
137137 .rpc_proc = & nfs4_procedures [NFSPROC4_CLNT_ALLOCATE ],
138138 };
139139 struct inode * inode = file_inode (filep );
140+ loff_t oldsize = i_size_read (inode );
140141 int err ;
141142
142143 if (!nfs_server_capable (inode , NFS_CAP_ALLOCATE ))
@@ -145,7 +146,11 @@ int nfs42_proc_allocate(struct file *filep, loff_t offset, loff_t len)
145146 inode_lock (inode );
146147
147148 err = nfs42_proc_fallocate (& msg , filep , offset , len );
148- if (err == - EOPNOTSUPP )
149+
150+ if (err == 0 )
151+ nfs_truncate_last_folio (inode -> i_mapping , oldsize ,
152+ offset + len );
153+ else if (err == - EOPNOTSUPP )
149154 NFS_SERVER (inode )-> caps &= ~(NFS_CAP_ALLOCATE |
150155 NFS_CAP_ZERO_RANGE );
151156
@@ -183,6 +188,7 @@ int nfs42_proc_zero_range(struct file *filep, loff_t offset, loff_t len)
183188 .rpc_proc = & nfs4_procedures [NFSPROC4_CLNT_ZERO_RANGE ],
184189 };
185190 struct inode * inode = file_inode (filep );
191+ loff_t oldsize = i_size_read (inode );
186192 int err ;
187193
188194 if (!nfs_server_capable (inode , NFS_CAP_ZERO_RANGE ))
@@ -191,9 +197,11 @@ int nfs42_proc_zero_range(struct file *filep, loff_t offset, loff_t len)
191197 inode_lock (inode );
192198
193199 err = nfs42_proc_fallocate (& msg , filep , offset , len );
194- if (err == 0 )
200+ if (err == 0 ) {
201+ nfs_truncate_last_folio (inode -> i_mapping , oldsize ,
202+ offset + len );
195203 truncate_pagecache_range (inode , offset , (offset + len ) - 1 );
196- if (err == - EOPNOTSUPP )
204+ } else if (err == - EOPNOTSUPP )
197205 NFS_SERVER (inode )-> caps &= ~NFS_CAP_ZERO_RANGE ;
198206
199207 inode_unlock (inode );
@@ -354,22 +362,27 @@ static int process_copy_commit(struct file *dst, loff_t pos_dst,
354362
355363/**
356364 * nfs42_copy_dest_done - perform inode cache updates after clone/copy offload
357- * @inode : pointer to destination inode
365+ * @file : pointer to destination file
358366 * @pos: destination offset
359367 * @len: copy length
368+ * @oldsize: length of the file prior to clone/copy
360369 *
361370 * Punch a hole in the inode page cache, so that the NFS client will
362371 * know to retrieve new data.
363372 * Update the file size if necessary, and then mark the inode as having
364373 * invalid cached values for change attribute, ctime, mtime and space used.
365374 */
366- static void nfs42_copy_dest_done (struct inode * inode , loff_t pos , loff_t len )
375+ static void nfs42_copy_dest_done (struct file * file , loff_t pos , loff_t len ,
376+ loff_t oldsize )
367377{
378+ struct inode * inode = file_inode (file );
379+ struct address_space * mapping = file -> f_mapping ;
368380 loff_t newsize = pos + len ;
369381 loff_t end = newsize - 1 ;
370382
371- WARN_ON_ONCE (invalidate_inode_pages2_range (inode -> i_mapping ,
372- pos >> PAGE_SHIFT , end >> PAGE_SHIFT ));
383+ nfs_truncate_last_folio (mapping , oldsize , pos );
384+ WARN_ON_ONCE (invalidate_inode_pages2_range (mapping , pos >> PAGE_SHIFT ,
385+ end >> PAGE_SHIFT ));
373386
374387 spin_lock (& inode -> i_lock );
375388 if (newsize > i_size_read (inode ))
@@ -402,6 +415,7 @@ static ssize_t _nfs42_proc_copy(struct file *src,
402415 struct nfs_server * src_server = NFS_SERVER (src_inode );
403416 loff_t pos_src = args -> src_pos ;
404417 loff_t pos_dst = args -> dst_pos ;
418+ loff_t oldsize_dst = i_size_read (dst_inode );
405419 size_t count = args -> count ;
406420 ssize_t status ;
407421
@@ -475,7 +489,7 @@ static ssize_t _nfs42_proc_copy(struct file *src,
475489 goto out ;
476490 }
477491
478- nfs42_copy_dest_done (dst_inode , pos_dst , res -> write_res .count );
492+ nfs42_copy_dest_done (dst , pos_dst , res -> write_res .count , oldsize_dst );
479493 nfs_invalidate_atime (src_inode );
480494 status = res -> write_res .count ;
481495out :
@@ -1242,6 +1256,7 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,
12421256 struct nfs42_clone_res res = {
12431257 .server = server ,
12441258 };
1259+ loff_t oldsize_dst = i_size_read (dst_inode );
12451260 int status ;
12461261
12471262 msg -> rpc_argp = & args ;
@@ -1276,7 +1291,7 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,
12761291 /* a zero-length count means clone to EOF in src */
12771292 if (count == 0 && res .dst_fattr -> valid & NFS_ATTR_FATTR_SIZE )
12781293 count = nfs_size_to_loff_t (res .dst_fattr -> size ) - dst_offset ;
1279- nfs42_copy_dest_done (dst_inode , dst_offset , count );
1294+ nfs42_copy_dest_done (dst_f , dst_offset , count , oldsize_dst );
12801295 status = nfs_post_op_update_inode (dst_inode , res .dst_fattr );
12811296 }
12821297
0 commit comments