mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	NFSD add vfs_fsync after async copy is done
Currently, the server does all copies as NFS_UNSTABLE. For synchronous copies linux client will append a COMMIT to the COPY compound but for async copies it does not (because COMMIT needs to be done after all bytes are copied and not as a reply to the COPY operation). However, in order to save the client doing a COMMIT as a separate rpc, the server can reply back with NFS_FILE_SYNC copy. This patch proposed to add vfs_fsync() call at the end of the async copy. Signed-off-by: Olga Kornievskaia <kolga@netapp.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
		
							parent
							
								
									eeeadbb9bd
								
							
						
					
					
						commit
						eac0b17a77
					
				
					 2 changed files with 14 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -1375,7 +1375,8 @@ static const struct nfsd4_callback_ops nfsd4_cb_offload_ops = {
 | 
			
		|||
 | 
			
		||||
static void nfsd4_init_copy_res(struct nfsd4_copy *copy, bool sync)
 | 
			
		||||
{
 | 
			
		||||
	copy->cp_res.wr_stable_how = NFS_UNSTABLE;
 | 
			
		||||
	copy->cp_res.wr_stable_how =
 | 
			
		||||
		copy->committed ? NFS_FILE_SYNC : NFS_UNSTABLE;
 | 
			
		||||
	copy->cp_synchronous = sync;
 | 
			
		||||
	gen_boot_verifier(©->cp_res.wr_verifier, copy->cp_clp->net);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1386,6 +1387,7 @@ static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy)
 | 
			
		|||
	u64 bytes_total = copy->cp_count;
 | 
			
		||||
	u64 src_pos = copy->cp_src_pos;
 | 
			
		||||
	u64 dst_pos = copy->cp_dst_pos;
 | 
			
		||||
	__be32 status;
 | 
			
		||||
 | 
			
		||||
	/* See RFC 7862 p.67: */
 | 
			
		||||
	if (bytes_total == 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -1403,6 +1405,16 @@ static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy)
 | 
			
		|||
		src_pos += bytes_copied;
 | 
			
		||||
		dst_pos += bytes_copied;
 | 
			
		||||
	} while (bytes_total > 0 && !copy->cp_synchronous);
 | 
			
		||||
	/* for a non-zero asynchronous copy do a commit of data */
 | 
			
		||||
	if (!copy->cp_synchronous && copy->cp_res.wr_bytes_written > 0) {
 | 
			
		||||
		down_write(©->nf_dst->nf_rwsem);
 | 
			
		||||
		status = vfs_fsync_range(copy->nf_dst->nf_file,
 | 
			
		||||
					 copy->cp_dst_pos,
 | 
			
		||||
					 copy->cp_res.wr_bytes_written, 0);
 | 
			
		||||
		up_write(©->nf_dst->nf_rwsem);
 | 
			
		||||
		if (!status)
 | 
			
		||||
			copy->committed = true;
 | 
			
		||||
	}
 | 
			
		||||
	return bytes_copied;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -567,6 +567,7 @@ struct nfsd4_copy {
 | 
			
		|||
	struct vfsmount		*ss_mnt;
 | 
			
		||||
	struct nfs_fh		c_fh;
 | 
			
		||||
	nfs4_stateid		stateid;
 | 
			
		||||
	bool			committed;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct nfsd4_seek {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue