mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 08:38:45 +02:00 
			
		
		
		
	fsdax: unshare: zero destination if srcmap is HOLE or UNWRITTEN
unshare copies data from source to destination.  But if the source is
HOLE or UNWRITTEN extents, we should zero the destination, otherwise
the HOLE or UNWRITTEN part will be user-visible old data of the new
allocated extent.
Found by running generic/649 while mounting with -o dax=always on pmem.
Link: https://lkml.kernel.org/r/1679483469-2-1-git-send-email-ruansy.fnst@fujitsu.com
Fixes: d984648e42 ("fsdax,xfs: port unshare to fsdax")
Signed-off-by: Shiyang Ruan <ruansy.fnst@fujitsu.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Darrick J. Wong <djwong@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: Jason Gunthorpe <jgg@nvidia.com>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
			
			
This commit is contained in:
		
							parent
							
								
									f478b9987c
								
							
						
					
					
						commit
						13dd4e0462
					
				
					 1 changed files with 8 additions and 3 deletions
				
			
		
							
								
								
									
										11
									
								
								fs/dax.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								fs/dax.c
									
									
									
									
									
								
							|  | @ -1258,15 +1258,20 @@ static s64 dax_unshare_iter(struct iomap_iter *iter) | ||||||
| 	/* don't bother with blocks that are not shared to start with */ | 	/* don't bother with blocks that are not shared to start with */ | ||||||
| 	if (!(iomap->flags & IOMAP_F_SHARED)) | 	if (!(iomap->flags & IOMAP_F_SHARED)) | ||||||
| 		return length; | 		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(); | 	id = dax_read_lock(); | ||||||
| 	ret = dax_iomap_direct_access(iomap, pos, length, &daddr, NULL); | 	ret = dax_iomap_direct_access(iomap, pos, length, &daddr, NULL); | ||||||
| 	if (ret < 0) | 	if (ret < 0) | ||||||
| 		goto out_unlock; | 		goto out_unlock; | ||||||
| 
 | 
 | ||||||
|  | 	/* zero the distance if srcmap is HOLE or UNWRITTEN */ | ||||||
|  | 	if (srcmap->flags & IOMAP_F_SHARED || srcmap->type == IOMAP_UNWRITTEN) { | ||||||
|  | 		memset(daddr, 0, length); | ||||||
|  | 		dax_flush(iomap->dax_dev, daddr, length); | ||||||
|  | 		ret = length; | ||||||
|  | 		goto out_unlock; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	ret = dax_iomap_direct_access(srcmap, pos, length, &saddr, NULL); | 	ret = dax_iomap_direct_access(srcmap, pos, length, &saddr, NULL); | ||||||
| 	if (ret < 0) | 	if (ret < 0) | ||||||
| 		goto out_unlock; | 		goto out_unlock; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Shiyang Ruan
						Shiyang Ruan