Date: Tue, 3 Oct 2017 22:40:38 +0000 From: Dave Baukus <daveb@spectralogic.com> To: "freebsd-fs@freebsd.org" <freebsd-fs@freebsd.org>, "zfs@lists.illumos.org" <zfs@lists.illumos.org> Subject: Ephemeral fguid crash in zfs_log_create() question Message-ID: <e8d67f33-6922-bbbe-ab9f-b5f4a6470a35@spectralogic.com>
next in thread | raw e-mail | index | archive | help
I have a FreeBSD (stable 11) ZFS system crashing in zfs_log_create() because
the zfs_fuid_info_t *fuidp passed in from:
zfs_log_create(zilog, tx, txtype, dzp, zp, name,
vsecp, acl_ids.z_fuidp, vap);zfs_create()
is NULL.
The zfs_acl_ids_t built via zfs_acl_ids_create() for zfs_create() is
as follows:
p/x *$acl_ids
$74 = {
z_fuid = 0x2126d1,
z_fgid = 0x300000201,
z_mode = 0x81b4,
z_aclp = 0xfffff80886901b00,
z_fuidp = 0x0
}
The issue, as I've been able to piece together, could be this snippet of
code in zfs_acl_ids_create():
} else {
acl_ids->z_fgid = zfs_fuid_create_cred(zfsvfs,
ZFS_GROUP, cr, &acl_ids->z_fuidp);
#ifdef __FreeBSD_kernel__
gid = acl_ids->z_fgid = dzp->z_gid;
#else
gid = crgetgid(cr);
#endif
}
zfs_fuid_create_cred() would have returned a non-EPHEMERAL z_fgid from the cred:
p/x $cred->cr_groups[0]
$70 = 0x1e8681
But then the FreeBSD_kernel code set it to an EPHEMERAL z_gid from the parent znode:
p/x $dzp->z_gid
$73 = 0x300000201
Now the problem for zfs_log_create() is that we have an EPHEMERAL z_gid but we do not have
a fuidp and we crash here:
if (!IS_EPHEMERAL(zp->z_gid)) {
lr->lr_gid = (uint64_t)zp->z_gid;
} else {
lr->lr_gid = fuidp->z_fuid_group;
}
Finally to a question:
Why doesn't the snippet of code (above) from zfs_acl_ids_create(), also include
the functionality to add a fuid node for ephemeral GIDs (i.e. the same code that
is in the if (dzp->z_mode & S_ISGID) block) ?
That is why not something like:
if (dzp->z_mode & S_ISGID) {
....
} else {
acl_ids->z_fgid = zfs_fuid_create_cred(zfsvfs,
ZFS_GROUP, cr, &acl_ids->z_fuidp);
#ifdef __FreeBSD_kernel__
gid = acl_ids->z_fgid = dzp->z_gid;
if (zfsvfs->z_use_fuids &&
IS_EPHEMERAL(acl_ids->z_fgid)) {
domain = zfs_fuid_idx_domain(
&zfsvfs->z_fuid_idx,
FUID_INDEX(acl_ids->z_fgid));
rid = FUID_RID(acl_ids->z_fgid);
zfs_fuid_node_add(&acl_ids->z_fuidp,
domain, rid,
FUID_INDEX(acl_ids->z_fgid),
acl_ids->z_fgid, ZFS_GROUP);
}
#endif
Thanks for any insights
--
Dave Baukus
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?e8d67f33-6922-bbbe-ab9f-b5f4a6470a35>
