mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	Linux: always check or verify return of igrab()
zhold() wraps igrab() on Linux, and igrab() may fail when the inode is in the process of being deleted. This means zhold() must only be called when a reference exists and therefore it cannot be deleted. This is the case for all existing consumers so add a VERIFY and a comment explaining this requirement. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Adam Moss <c@yotes.com> Closes #11704
This commit is contained in:
		
							parent
							
								
									f14b6f2302
								
							
						
					
					
						commit
						ac6f332154
					
				@ -73,7 +73,13 @@ extern "C" {
 | 
			
		||||
#define	zn_has_cached_data(zp)	((zp)->z_is_mapped)
 | 
			
		||||
#define	zn_rlimit_fsize(zp, uio, td)	(0)
 | 
			
		||||
 | 
			
		||||
#define	zhold(zp)	igrab(ZTOI((zp)))
 | 
			
		||||
/*
 | 
			
		||||
 * zhold() wraps igrab() on Linux, and igrab() may fail when the
 | 
			
		||||
 * inode is in the process of being deleted.  As zhold() must only be
 | 
			
		||||
 * called when a ref already exists - so the inode cannot be
 | 
			
		||||
 * mid-deletion - we VERIFY() this.
 | 
			
		||||
 */
 | 
			
		||||
#define	zhold(zp)	VERIFY3P(igrab(ZTOI((zp))), !=, NULL)
 | 
			
		||||
#define	zrele(zp)	iput(ZTOI((zp)))
 | 
			
		||||
 | 
			
		||||
/* Called on entry to each ZFS inode and vfs operation. */
 | 
			
		||||
 | 
			
		||||
@ -590,7 +590,8 @@ struct inode *
 | 
			
		||||
zfsctl_root(znode_t *zp)
 | 
			
		||||
{
 | 
			
		||||
	ASSERT(zfs_has_ctldir(zp));
 | 
			
		||||
	igrab(ZTOZSB(zp)->z_ctldir);
 | 
			
		||||
	/* Must have an existing ref, so igrab() cannot return NULL */
 | 
			
		||||
	VERIFY3P(igrab(ZTOZSB(zp)->z_ctldir), !=, NULL);
 | 
			
		||||
	return (ZTOZSB(zp)->z_ctldir);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1734,7 +1734,11 @@ zfs_vget(struct super_block *sb, struct inode **ipp, fid_t *fidp)
 | 
			
		||||
			VERIFY(zfsctl_root_lookup(*ipp, "snapshot", ipp,
 | 
			
		||||
			    0, kcred, NULL, NULL) == 0);
 | 
			
		||||
		} else {
 | 
			
		||||
			igrab(*ipp);
 | 
			
		||||
			/*
 | 
			
		||||
			 * Must have an existing ref, so igrab()
 | 
			
		||||
			 * cannot return NULL
 | 
			
		||||
			 */
 | 
			
		||||
			VERIFY3P(igrab(*ipp), !=, NULL);
 | 
			
		||||
		}
 | 
			
		||||
		ZFS_EXIT(zfsvfs);
 | 
			
		||||
		return (0);
 | 
			
		||||
 | 
			
		||||
@ -639,7 +639,8 @@ zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
 | 
			
		||||
 | 
			
		||||
	crhold(cr);
 | 
			
		||||
	ip->i_ctime = current_time(ip);
 | 
			
		||||
	igrab(ip); /* Use ihold() if available */
 | 
			
		||||
	/* Must have an existing ref, so igrab() cannot return NULL */
 | 
			
		||||
	VERIFY3P(igrab(ip), !=, NULL);
 | 
			
		||||
 | 
			
		||||
	cookie = spl_fstrans_mark();
 | 
			
		||||
	error = -zfs_link(ITOZ(dir), ITOZ(ip), dname(dentry), cr, 0);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user