==== //depot/user/pjd/zfs/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c#8 - /home/lulf/dev/freebsd/p4/pjd_zfs/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c ==== @@ -4092,8 +4092,48 @@ struct thread *a_td; } */ *ap; { + vattr_t *vap = ap->a_vap; + xvattr_t xvap; + u_long flags = vap->va_flags; + int error; + + xva_init(&xvap); + xvap.xva_vattr = *vap; + + /* Convert chflags into ZFS-type flags. */ + if (flags != VNOVAL) { + /* XXX: what about SF_SETTABLE?. */ + if (flags & SF_ARCHIVED) + XVA_SET_REQ(&xvap, XAT_ARCHIVE); + if (flags & SF_IMMUTABLE) + XVA_SET_REQ(&xvap, XAT_IMMUTABLE); + if (flags & SF_APPEND) + XVA_SET_REQ(&xvap, XAT_APPENDONLY); + if (flags & SF_NOUNLINK) + XVA_SET_REQ(&xvap, XAT_NOUNLINK); + } + error = zfs_getattr(ap->a_vp, (vattr_t *)&xvap, 0, ap->a_cred, NULL); + /* Should we wait with this until we've set the chflags? */ + if (error) + return (error); - return (zfs_getattr(ap->a_vp, ap->a_vap, 0, ap->a_cred, NULL)); + flags = 0; + /* Convert ZFS xattr into chflags. */ + if (XVA_ISSET_RTN(&xvap, XAT_ARCHIVE) && + xvap.xva_xoptattrs.xoa_archive != 0) + flags |= SF_ARCHIVED; + if (XVA_ISSET_RTN(&xvap, XAT_IMMUTABLE) && + xvap.xva_xoptattrs.xoa_immutable != 0) + flags |= SF_IMMUTABLE; + if (XVA_ISSET_RTN(&xvap, XAT_APPENDONLY) && + xvap.xva_xoptattrs.xoa_appendonly != 0) + flags |= SF_APPEND; + if (XVA_ISSET_RTN(&xvap, XAT_NOUNLINK) && + xvap.xva_xoptattrs.xoa_nounlink != 0) + flags |= SF_NOUNLINK; + *vap = xvap.xva_vattr; + vap->va_flags |= flags; + return (0); } static int @@ -4106,15 +4146,38 @@ } */ *ap; { vattr_t *vap = ap->a_vap; + xvattr_t xvap; + u_long flags = vap->va_flags; + int error; - /* No support for FreeBSD's chflags(2). */ - if (vap->va_flags != VNOVAL) - return (EOPNOTSUPP); - vattr_init_mask(vap); vap->va_mask &= ~AT_NOSET; - return (zfs_setattr(ap->a_vp, vap, 0, ap->a_cred, NULL)); + xva_init(&xvap); + xvap.xva_vattr = *vap; + /* Convert chflags into ZFS-type flags. */ + if (flags != VNOVAL) { + /* XXX: what about SF_SETTABLE?. */ + if (flags & SF_ARCHIVED) { + XVA_SET_REQ(&xvap, XAT_ARCHIVE); + xvap.xva_xoptattrs.xoa_archive = 0xff; + } + if (flags & SF_IMMUTABLE) { + XVA_SET_REQ(&xvap, XAT_IMMUTABLE); + xvap.xva_xoptattrs.xoa_immutable = 0xff; + } + if (flags & SF_APPEND) { + XVA_SET_REQ(&xvap, XAT_APPENDONLY); + xvap.xva_xoptattrs.xoa_appendonly = 0xff; + } + if (flags & SF_NOUNLINK) { + XVA_SET_REQ(&xvap, XAT_NOUNLINK); + xvap.xva_xoptattrs.xoa_nounlink = 0xff; + } + } + error = zfs_setattr(ap->a_vp, (vattr_t *)&xvap, 0, ap->a_cred, NULL); + *vap = xvap.xva_vattr; /* Since some bits may be set in zfs_setattr. */ + return (error); } static int