Ephemeral fguid crash in zfs_log_create() question

Dave Baukus daveb at spectralogic.com
Tue Oct 3 23:03:04 UTC 2017


Small formatting correction included below:

On 10/03/2017 04:40 PM, Dave Baukus wrote:
> I have a FreeBSD (stable 11) ZFS system crashing in zfs_log_create() because
> the zfs_fuid_info_t *fuidp passed in from zfs_create():
>
> zfs_log_create(zilog, tx, txtype, dzp, zp, name,
>           vsecp, acl_ids.z_fuidp, vap);
> 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
>


More information about the freebsd-fs mailing list