svn commit: r306292 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs

Andriy Gapon avg at FreeBSD.org
Sat Sep 24 08:13:17 UTC 2016


Author: avg
Date: Sat Sep 24 08:13:15 2016
New Revision: 306292
URL: https://svnweb.freebsd.org/changeset/base/306292

Log:
  fix vnode lock assertion for extended attributes directory
  
  Background.  In ZFS a file with extended attributes has a special
  directory associated with it where each extended attribute is a file.
  The attribute's name is a file name and its value is a file content.
  When the ownership of a file with extended attributes is changed, ZFS
  also changes ownership of the special directory.  This is where the bug
  was hit.
  
  The bug was introduced in r209158.
  
  Nota bene.  ZFS vnode locks are typically acquired before
  z_teardown_lock (i.e., before ZFS_ENTER).  But this is not the case for
  the vnodes that represent the extended attribute directory and files.
  Those are always locked after ZFS_ENTER.  This is confusing and fragile.
  
  PR:		212702
  Reported by:	Christian Fuss to FreeNAS
  Tested by:	mav
  MFC after:	1 week

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Sat Sep 24 07:59:54 2016	(r306291)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Sat Sep 24 08:13:15 2016	(r306292)
@@ -3197,6 +3197,11 @@ zfs_setattr(vnode_t *vp, vattr_t *vap, i
 
 		if (err == 0 && xattr_obj) {
 			err = zfs_zget(zp->z_zfsvfs, xattr_obj, &attrzp);
+			if (err == 0) {
+				err = vn_lock(ZTOV(attrzp), LK_EXCLUSIVE);
+				if (err != 0)
+					vrele(ZTOV(attrzp));
+			}
 			if (err)
 				goto out2;
 		}
@@ -3206,7 +3211,7 @@ zfs_setattr(vnode_t *vp, vattr_t *vap, i
 			if (new_uid != zp->z_uid &&
 			    zfs_fuid_overquota(zfsvfs, B_FALSE, new_uid)) {
 				if (attrzp)
-					vrele(ZTOV(attrzp));
+					vput(ZTOV(attrzp));
 				err = SET_ERROR(EDQUOT);
 				goto out2;
 			}
@@ -3218,7 +3223,7 @@ zfs_setattr(vnode_t *vp, vattr_t *vap, i
 			if (new_gid != zp->z_gid &&
 			    zfs_fuid_overquota(zfsvfs, B_TRUE, new_gid)) {
 				if (attrzp)
-					vrele(ZTOV(attrzp));
+					vput(ZTOV(attrzp));
 				err = SET_ERROR(EDQUOT);
 				goto out2;
 			}
@@ -3449,7 +3454,7 @@ out:
 	}
 
 	if (attrzp)
-		vrele(ZTOV(attrzp));
+		vput(ZTOV(attrzp));
 
 	if (aclp)
 		zfs_acl_free(aclp);


More information about the svn-src-all mailing list