diff options
Diffstat (limited to 'module/zfs/zfs_fuid.c')
-rw-r--r-- | module/zfs/zfs_fuid.c | 62 |
1 files changed, 45 insertions, 17 deletions
diff --git a/module/zfs/zfs_fuid.c b/module/zfs/zfs_fuid.c index e704b1ca9..8c0424e84 100644 --- a/module/zfs/zfs_fuid.c +++ b/module/zfs/zfs_fuid.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <sys/zfs_context.h> -#include <sys/sunddi.h> #include <sys/dmu.h> #include <sys/avl.h> #include <sys/zap.h> @@ -377,7 +375,7 @@ zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx) rw_enter(&zfsvfs->z_fuid_lock, RW_READER); - if (zfsvfs->z_fuid_obj) + if (zfsvfs->z_fuid_obj || zfsvfs->z_fuid_dirty) domain = zfs_fuid_idx_domain(&zfsvfs->z_fuid_idx, idx); else domain = nulldomain; @@ -390,10 +388,26 @@ zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx) void zfs_fuid_map_ids(znode_t *zp, cred_t *cr, uid_t *uidp, uid_t *gidp) { - *uidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_phys->zp_uid, - cr, ZFS_OWNER); - *gidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_phys->zp_gid, - cr, ZFS_GROUP); + uint64_t fuid, fgid; + sa_bulk_attr_t bulk[2]; + int count = 0; + + if (IS_EPHEMERAL(zp->z_uid) || IS_EPHEMERAL(zp->z_gid)) { + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zp->z_zfsvfs), + NULL, &fuid, 8); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zp->z_zfsvfs), + NULL, &fgid, 8); + VERIFY(0 == sa_bulk_lookup(zp->z_sa_hdl, bulk, count)); + } + if (IS_EPHEMERAL(zp->z_uid)) + *uidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_uid, cr, ZFS_OWNER); + else + *uidp = zp->z_uid; + if (IS_EPHEMERAL(zp->z_gid)) + *gidp = zfs_fuid_map_id(zp->z_zfsvfs, + zp->z_gid, cr, ZFS_GROUP); + else + *gidp = zp->z_gid; } uid_t @@ -427,7 +441,7 @@ zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid, * If ACL has multiple domains, then keep only one copy of each unique * domain. */ -static void +void zfs_fuid_node_add(zfs_fuid_info_t **fuidpp, const char *domain, uint32_t rid, uint64_t idx, uint64_t id, zfs_fuid_type_t type) { @@ -488,6 +502,11 @@ zfs_fuid_node_add(zfs_fuid_info_t **fuidpp, const char *domain, uint32_t rid, /* * Create a file system FUID, based on information in the users cred + * + * If cred contains KSID_OWNER then it should be used to determine + * the uid otherwise cred's uid will be used. By default cred's gid + * is used unless it's an ephemeral ID in which case KSID_GROUP will + * be used if it exists. */ uint64_t zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type, @@ -503,18 +522,27 @@ zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type, VERIFY(type == ZFS_OWNER || type == ZFS_GROUP); ksid = crgetsid(cr, (type == ZFS_OWNER) ? KSID_OWNER : KSID_GROUP); - if (ksid) { - id = ksid_getid(ksid); - } else { - if (type == ZFS_OWNER) - id = crgetuid(cr); - else - id = crgetgid(cr); + + if (!zfsvfs->z_use_fuids || (ksid == NULL)) { + id = (type == ZFS_OWNER) ? crgetuid(cr) : crgetgid(cr); + + if (IS_EPHEMERAL(id)) + return ((type == ZFS_OWNER) ? UID_NOBODY : GID_NOBODY); + + return ((uint64_t)id); } - if (!zfsvfs->z_use_fuids || (!IS_EPHEMERAL(id))) + /* + * ksid is present and FUID is supported + */ + id = (type == ZFS_OWNER) ? ksid_getid(ksid) : crgetgid(cr); + + if (!IS_EPHEMERAL(id)) return ((uint64_t)id); + if (type == ZFS_GROUP) + id = ksid_getid(ksid); + rid = ksid_getrid(ksid); domain = ksid_getdomain(ksid); |