mirror of
				https://git.proxmox.com/git/mirror_zfs
				synced 2025-10-31 04:00:50 +00:00 
			
		
		
		
	linux: zfs: ctldir: set [amc]time to snapshot's creation property
If looking up a snapdir inode failed, hold pool config – hold the 
snapshot – get its creation property – release it – release it, 
then use that as the [amc]time in the allocated inode. If that 
fails then fall back to current time. No performance impact since 
this is only done when allocating a new snapdir inode.
                                                       
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes #15110
Closes #15117
			
			
This commit is contained in:
		
							parent
							
								
									b3c1807d77
								
							
						
					
					
						commit
						bd1eab16eb
					
				| @ -478,17 +478,19 @@ zfsctl_is_snapdir(struct inode *ip) | ||||
|  */ | ||||
| static struct inode * | ||||
| zfsctl_inode_alloc(zfsvfs_t *zfsvfs, uint64_t id, | ||||
|     const struct file_operations *fops, const struct inode_operations *ops) | ||||
|     const struct file_operations *fops, const struct inode_operations *ops, | ||||
|     uint64_t creation) | ||||
| { | ||||
| 	inode_timespec_t now; | ||||
| 	struct inode *ip; | ||||
| 	znode_t *zp; | ||||
| 	inode_timespec_t now = {.tv_sec = creation}; | ||||
| 
 | ||||
| 	ip = new_inode(zfsvfs->z_sb); | ||||
| 	if (ip == NULL) | ||||
| 		return (NULL); | ||||
| 
 | ||||
| 	now = current_time(ip); | ||||
| 	if (!creation) | ||||
| 		now = current_time(ip); | ||||
| 	zp = ITOZ(ip); | ||||
| 	ASSERT3P(zp->z_dirlocks, ==, NULL); | ||||
| 	ASSERT3P(zp->z_acl_cached, ==, NULL); | ||||
| @ -552,14 +554,28 @@ zfsctl_inode_lookup(zfsvfs_t *zfsvfs, uint64_t id, | ||||
|     const struct file_operations *fops, const struct inode_operations *ops) | ||||
| { | ||||
| 	struct inode *ip = NULL; | ||||
| 	uint64_t creation = 0; | ||||
| 	dsl_dataset_t *snap_ds; | ||||
| 	dsl_pool_t *pool; | ||||
| 
 | ||||
| 	while (ip == NULL) { | ||||
| 		ip = ilookup(zfsvfs->z_sb, (unsigned long)id); | ||||
| 		if (ip) | ||||
| 			break; | ||||
| 
 | ||||
| 		if (id <= ZFSCTL_INO_SNAPDIRS && !creation) { | ||||
| 			pool = dmu_objset_pool(zfsvfs->z_os); | ||||
| 			dsl_pool_config_enter(pool, FTAG); | ||||
| 			if (!dsl_dataset_hold_obj(pool, | ||||
| 			    ZFSCTL_INO_SNAPDIRS - id, FTAG, &snap_ds)) { | ||||
| 				creation = dsl_get_creation(snap_ds); | ||||
| 				dsl_dataset_rele(snap_ds, FTAG); | ||||
| 			} | ||||
| 			dsl_pool_config_exit(pool, FTAG); | ||||
| 		} | ||||
| 
 | ||||
| 		/* May fail due to concurrent zfsctl_inode_alloc() */ | ||||
| 		ip = zfsctl_inode_alloc(zfsvfs, id, fops, ops); | ||||
| 		ip = zfsctl_inode_alloc(zfsvfs, id, fops, ops, creation); | ||||
| 	} | ||||
| 
 | ||||
| 	return (ip); | ||||
| @ -581,7 +597,7 @@ zfsctl_create(zfsvfs_t *zfsvfs) | ||||
| 	ASSERT(zfsvfs->z_ctldir == NULL); | ||||
| 
 | ||||
| 	zfsvfs->z_ctldir = zfsctl_inode_alloc(zfsvfs, ZFSCTL_INO_ROOT, | ||||
| 	    &zpl_fops_root, &zpl_ops_root); | ||||
| 	    &zpl_fops_root, &zpl_ops_root, 0); | ||||
| 	if (zfsvfs->z_ctldir == NULL) | ||||
| 		return (SET_ERROR(ENOENT)); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 наб
						наб