mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 00:28:52 +02:00 
			
		
		
		
	fsdax,xfs: port unshare to fsdax
Implement unshare in fsdax mode: copy data from srcmap to iomap. Link: https://lkml.kernel.org/r/1669908753-169-1-git-send-email-ruansy.fnst@fujitsu.com Signed-off-by: Shiyang Ruan <ruansy.fnst@fujitsu.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Cc: Alistair Popple <apopple@nvidia.com> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Dave Chinner <david@fromorbit.com> Cc: Jason Gunthorpe <jgg@nvidia.com> Cc: John Hubbard <jhubbard@nvidia.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									64e6edc185
								
							
						
					
					
						commit
						d984648e42
					
				
					 3 changed files with 60 additions and 2 deletions
				
			
		
							
								
								
									
										52
									
								
								fs/dax.c
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								fs/dax.c
									
									
									
									
									
								
							|  | @ -1245,6 +1245,58 @@ static vm_fault_t dax_pmd_load_hole(struct xa_state *xas, struct vm_fault *vmf, | |||
| } | ||||
| #endif /* CONFIG_FS_DAX_PMD */ | ||||
| 
 | ||||
| static s64 dax_unshare_iter(struct iomap_iter *iter) | ||||
| { | ||||
| 	struct iomap *iomap = &iter->iomap; | ||||
| 	const struct iomap *srcmap = iomap_iter_srcmap(iter); | ||||
| 	loff_t pos = iter->pos; | ||||
| 	loff_t length = iomap_length(iter); | ||||
| 	int id = 0; | ||||
| 	s64 ret = 0; | ||||
| 	void *daddr = NULL, *saddr = NULL; | ||||
| 
 | ||||
| 	/* don't bother with blocks that are not shared to start with */ | ||||
| 	if (!(iomap->flags & IOMAP_F_SHARED)) | ||||
| 		return length; | ||||
| 	/* don't bother with holes or unwritten extents */ | ||||
| 	if (srcmap->type == IOMAP_HOLE || srcmap->type == IOMAP_UNWRITTEN) | ||||
| 		return length; | ||||
| 
 | ||||
| 	id = dax_read_lock(); | ||||
| 	ret = dax_iomap_direct_access(iomap, pos, length, &daddr, NULL); | ||||
| 	if (ret < 0) | ||||
| 		goto out_unlock; | ||||
| 
 | ||||
| 	ret = dax_iomap_direct_access(srcmap, pos, length, &saddr, NULL); | ||||
| 	if (ret < 0) | ||||
| 		goto out_unlock; | ||||
| 
 | ||||
| 	ret = copy_mc_to_kernel(daddr, saddr, length); | ||||
| 	if (ret) | ||||
| 		ret = -EIO; | ||||
| 
 | ||||
| out_unlock: | ||||
| 	dax_read_unlock(id); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| int dax_file_unshare(struct inode *inode, loff_t pos, loff_t len, | ||||
| 		const struct iomap_ops *ops) | ||||
| { | ||||
| 	struct iomap_iter iter = { | ||||
| 		.inode		= inode, | ||||
| 		.pos		= pos, | ||||
| 		.len		= len, | ||||
| 		.flags		= IOMAP_WRITE | IOMAP_UNSHARE | IOMAP_DAX, | ||||
| 	}; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	while ((ret = iomap_iter(&iter, ops)) > 0) | ||||
| 		iter.processed = dax_unshare_iter(&iter); | ||||
| 	return ret; | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(dax_file_unshare); | ||||
| 
 | ||||
| static int dax_memzero(struct iomap_iter *iter, loff_t pos, size_t size) | ||||
| { | ||||
| 	const struct iomap *iomap = &iter->iomap; | ||||
|  |  | |||
|  | @ -1693,8 +1693,12 @@ xfs_reflink_unshare( | |||
| 
 | ||||
| 	inode_dio_wait(inode); | ||||
| 
 | ||||
| 	error = iomap_file_unshare(inode, offset, len, | ||||
| 			&xfs_buffered_write_iomap_ops); | ||||
| 	if (IS_DAX(inode)) | ||||
| 		error = dax_file_unshare(inode, offset, len, | ||||
| 				&xfs_dax_write_iomap_ops); | ||||
| 	else | ||||
| 		error = iomap_file_unshare(inode, offset, len, | ||||
| 				&xfs_buffered_write_iomap_ops); | ||||
| 	if (error) | ||||
| 		goto out; | ||||
| 
 | ||||
|  |  | |||
|  | @ -205,6 +205,8 @@ static inline void dax_unlock_mapping_entry(struct address_space *mapping, | |||
| } | ||||
| #endif | ||||
| 
 | ||||
| int dax_file_unshare(struct inode *inode, loff_t pos, loff_t len, | ||||
| 		const struct iomap_ops *ops); | ||||
| int dax_zero_range(struct inode *inode, loff_t pos, loff_t len, bool *did_zero, | ||||
| 		const struct iomap_ops *ops); | ||||
| int dax_truncate_page(struct inode *inode, loff_t pos, bool *did_zero, | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Shiyang Ruan
						Shiyang Ruan