Remove SYNC_ATTR check
[zfs.git] / module / zfs / zfs_fuid.c
index 8e481df..a574118 100644 (file)
  * 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>
@@ -170,12 +168,12 @@ zfs_fuid_table_destroy(avl_tree_t *idx_tree, avl_tree_t *domain_tree)
        void *cookie;
 
        cookie = NULL;
-       while (domnode = avl_destroy_nodes(domain_tree, &cookie))
+       while ((domnode = avl_destroy_nodes(domain_tree, &cookie)))
                ksiddomain_rele(domnode->f_ksid);
 
        avl_destroy(domain_tree);
        cookie = NULL;
-       while (domnode = avl_destroy_nodes(idx_tree, &cookie))
+       while ((domnode = avl_destroy_nodes(idx_tree, &cookie)))
                kmem_free(domnode, sizeof (fuid_domain_t));
        avl_destroy(idx_tree);
 }
@@ -353,6 +351,7 @@ retry:
                rw_exit(&zfsvfs->z_fuid_lock);
                return (retidx);
        } else {
+               rw_exit(&zfsvfs->z_fuid_lock);
                return (-1);
        }
 }
@@ -376,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;
@@ -389,16 +388,15 @@ 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);
+       *uidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_uid, cr, ZFS_OWNER);
+       *gidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_gid, cr, ZFS_GROUP);
 }
 
 uid_t
 zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
     cred_t *cr, zfs_fuid_type_t type)
 {
+#ifdef HAVE_KSID
        uint32_t index = FUID_INDEX(fuid);
        const char *domain;
        uid_t id;
@@ -417,6 +415,12 @@ zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
                    FUID_RID(fuid), &id);
        }
        return (id);
+#else
+       if(type == ZFS_OWNER || type == ZFS_ACE_USER)
+               return (crgetuid(cr));
+       else
+               return (crgetgid(cr));
+#endif /* HAVE_KSID */
 }
 
 /*
@@ -426,7 +430,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)
 {
@@ -485,8 +489,14 @@ zfs_fuid_node_add(zfs_fuid_info_t **fuidpp, const char *domain, uint32_t rid,
        }
 }
 
+#ifdef HAVE_KSID
 /*
  * 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,
@@ -502,18 +512,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);
 
@@ -523,6 +542,7 @@ zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type,
 
        return (FUID_ENCODE(idx, rid));
 }
+#endif /* HAVE_KSID */
 
 /*
  * Create a file system FUID for an ACL ace
@@ -540,6 +560,7 @@ uint64_t
 zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
     zfs_fuid_type_t type, zfs_fuid_info_t **fuidpp)
 {
+#ifdef HAVE_KSID
        const char *domain;
        char *kdomain;
        uint32_t fuid_idx = FUID_INDEX(id);
@@ -618,6 +639,12 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
                kmem_free(zfuid, sizeof (zfs_fuid_t));
        }
        return (FUID_ENCODE(idx, rid));
+#else
+       if (type == ZFS_OWNER)
+               return crgetuid(cr);
+       else
+               return crgetgid(cr);
+#endif
 }
 
 void
@@ -685,6 +712,7 @@ zfs_fuid_info_free(zfs_fuid_info_t *fuidp)
 boolean_t
 zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
 {
+#ifdef HAVE_KSID
        ksid_t          *ksid = crgetsid(cr, KSID_GROUP);
        ksidlist_t      *ksidlist = crgetsidlist(cr);
        uid_t           gid;
@@ -726,6 +754,9 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
         */
        gid = zfs_fuid_map_id(zfsvfs, id, cr, ZFS_GROUP);
        return (groupmember(gid, cr));
+#else
+       return (B_TRUE);
+#endif
 }
 
 void