mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +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 */ | #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) | static int dax_memzero(struct iomap_iter *iter, loff_t pos, size_t size) | ||||||
| { | { | ||||||
| 	const struct iomap *iomap = &iter->iomap; | 	const struct iomap *iomap = &iter->iomap; | ||||||
|  |  | ||||||
|  | @ -1693,8 +1693,12 @@ xfs_reflink_unshare( | ||||||
| 
 | 
 | ||||||
| 	inode_dio_wait(inode); | 	inode_dio_wait(inode); | ||||||
| 
 | 
 | ||||||
| 	error = iomap_file_unshare(inode, offset, len, | 	if (IS_DAX(inode)) | ||||||
| 			&xfs_buffered_write_iomap_ops); | 		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) | 	if (error) | ||||||
| 		goto out; | 		goto out; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -205,6 +205,8 @@ static inline void dax_unlock_mapping_entry(struct address_space *mapping, | ||||||
| } | } | ||||||
| #endif | #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, | int dax_zero_range(struct inode *inode, loff_t pos, loff_t len, bool *did_zero, | ||||||
| 		const struct iomap_ops *ops); | 		const struct iomap_ops *ops); | ||||||
| int dax_truncate_page(struct inode *inode, loff_t pos, bool *did_zero, | int dax_truncate_page(struct inode *inode, loff_t pos, bool *did_zero, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Shiyang Ruan
						Shiyang Ruan