mirror of
				https://git.proxmox.com/git/mirror_zfs
				synced 2025-11-04 08:52:47 +00:00 
			
		
		
		
	FreeBSD: damage control racing .. lookups in face of mkdir/rmdir
External-issue: https://reviews.freebsd.org/D29769 Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Ryan Moeller <ryan@iXsystems.com> Signed-off-by: Mateusz Guzik <mjguzik@gmail.com> Closes #11926
This commit is contained in:
		
							parent
							
								
									0375465536
								
							
						
					
					
						commit
						f172f759b9
					
				@ -781,6 +781,9 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
 | 
			
		||||
	znode_t *zdp = VTOZ(dvp);
 | 
			
		||||
	znode_t *zp;
 | 
			
		||||
	zfsvfs_t *zfsvfs = zdp->z_zfsvfs;
 | 
			
		||||
#if	__FreeBSD_version > 1300124
 | 
			
		||||
	seqc_t dvp_seqc;
 | 
			
		||||
#endif
 | 
			
		||||
	int	error = 0;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
@ -806,6 +809,10 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
 | 
			
		||||
	ZFS_ENTER(zfsvfs);
 | 
			
		||||
	ZFS_VERIFY_ZP(zdp);
 | 
			
		||||
 | 
			
		||||
#if	__FreeBSD_version > 1300124
 | 
			
		||||
	dvp_seqc = vn_seqc_read_notmodify(dvp);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	*vpp = NULL;
 | 
			
		||||
 | 
			
		||||
	if (flags & LOOKUP_XATTR) {
 | 
			
		||||
@ -975,6 +982,26 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#if	__FreeBSD_version > 1300124
 | 
			
		||||
	if ((cnp->cn_flags & ISDOTDOT) != 0) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * FIXME: zfs_lookup_lock relocks vnodes and does nothing to
 | 
			
		||||
		 * handle races. In particular different callers may end up
 | 
			
		||||
		 * with different vnodes and will try to add conflicting
 | 
			
		||||
		 * entries to the namecache.
 | 
			
		||||
		 *
 | 
			
		||||
		 * While finding different result may be acceptable in face
 | 
			
		||||
		 * of concurrent modification, adding conflicting entries
 | 
			
		||||
		 * trips over an assert in the namecache.
 | 
			
		||||
		 *
 | 
			
		||||
		 * Ultimately let an entry through once everything settles.
 | 
			
		||||
		 */
 | 
			
		||||
		if (!vn_seqc_consistent(dvp, dvp_seqc)) {
 | 
			
		||||
			cnp->cn_flags &= ~MAKEENTRY;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Insert name into cache (as non-existent) if appropriate. */
 | 
			
		||||
	if (zfsvfs->z_use_namecache && !zfsvfs->z_replay &&
 | 
			
		||||
	    error == ENOENT && (cnp->cn_flags & MAKEENTRY) != 0)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user