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
This commit is contained in:
Andriy Gapon 2016-09-24 08:13:15 +00:00
parent b2b4f88476
commit d26312a4e4

View File

@ -3197,6 +3197,11 @@ zfs_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
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, int flags, cred_t *cr,
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, int flags, cred_t *cr,
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);