Deleted Added
full compact
zfs_fuid.c (185029) zfs_fuid.c (209962)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 5 unchanged lines hidden (view full) ---

14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 5 unchanged lines hidden (view full) ---

14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#include <sys/zfs_context.h>
27#include <sys/sunddi.h>
28#include <sys/dmu.h>
29#include <sys/avl.h>
30#include <sys/zap.h>

--- 11 unchanged lines hidden (view full) ---

42 * FUID Domain table(s).
43 *
44 * The FUID table is stored as a packed nvlist of an array
45 * of nvlists which contain an index, domain string and offset
46 *
47 * During file system initialization the nvlist(s) are read and
48 * two AVL trees are created. One tree is keyed by the index number
49 * and the other by the domain string. Nodes are never removed from
23 * Use is subject to license terms.
24 */
25
26#include <sys/zfs_context.h>
27#include <sys/sunddi.h>
28#include <sys/dmu.h>
29#include <sys/avl.h>
30#include <sys/zap.h>

--- 11 unchanged lines hidden (view full) ---

42 * FUID Domain table(s).
43 *
44 * The FUID table is stored as a packed nvlist of an array
45 * of nvlists which contain an index, domain string and offset
46 *
47 * During file system initialization the nvlist(s) are read and
48 * two AVL trees are created. One tree is keyed by the index number
49 * and the other by the domain string. Nodes are never removed from
50 * trees, but new entries may be added. If a new entry is added then the
51 * on-disk packed nvlist will also be updated.
50 * trees, but new entries may be added. If a new entry is added then
51 * the zfsvfs->z_fuid_dirty flag is set to true and the caller will then
52 * be responsible for calling zfs_fuid_sync() to sync the changes to disk.
53 *
52 */
53
54#define FUID_IDX "fuid_idx"
55#define FUID_DOMAIN "fuid_domain"
56#define FUID_OFFSET "fuid_offset"
57#define FUID_NVP_ARRAY "fuid_nvlist"
58
59typedef struct fuid_domain {

--- 32 unchanged lines hidden (view full) ---

92 int val;
93
94 val = strcmp(node1->f_ksid->kd_name, node2->f_ksid->kd_name);
95 if (val == 0)
96 return (0);
97 return (val > 0 ? 1 : -1);
98}
99
54 */
55
56#define FUID_IDX "fuid_idx"
57#define FUID_DOMAIN "fuid_domain"
58#define FUID_OFFSET "fuid_offset"
59#define FUID_NVP_ARRAY "fuid_nvlist"
60
61typedef struct fuid_domain {

--- 32 unchanged lines hidden (view full) ---

94 int val;
95
96 val = strcmp(node1->f_ksid->kd_name, node2->f_ksid->kd_name);
97 if (val == 0)
98 return (0);
99 return (val > 0 ? 1 : -1);
100}
101
102void
103zfs_fuid_avl_tree_create(avl_tree_t *idx_tree, avl_tree_t *domain_tree)
104{
105 avl_create(idx_tree, idx_compare,
106 sizeof (fuid_domain_t), offsetof(fuid_domain_t, f_idxnode));
107 avl_create(domain_tree, domain_compare,
108 sizeof (fuid_domain_t), offsetof(fuid_domain_t, f_domnode));
109}
110
100/*
101 * load initial fuid domain and idx trees. This function is used by
102 * both the kernel and zdb.
103 */
104uint64_t
105zfs_fuid_table_load(objset_t *os, uint64_t fuid_obj, avl_tree_t *idx_tree,
106 avl_tree_t *domain_tree)
107{
108 dmu_buf_t *db;
109 uint64_t fuid_size;
110
111/*
112 * load initial fuid domain and idx trees. This function is used by
113 * both the kernel and zdb.
114 */
115uint64_t
116zfs_fuid_table_load(objset_t *os, uint64_t fuid_obj, avl_tree_t *idx_tree,
117 avl_tree_t *domain_tree)
118{
119 dmu_buf_t *db;
120 uint64_t fuid_size;
121
111 avl_create(idx_tree, idx_compare,
112 sizeof (fuid_domain_t), offsetof(fuid_domain_t, f_idxnode));
113 avl_create(domain_tree, domain_compare,
114 sizeof (fuid_domain_t), offsetof(fuid_domain_t, f_domnode));
115
116 VERIFY(0 == dmu_bonus_hold(os, fuid_obj, FTAG, &db));
122 ASSERT(fuid_obj != 0);
123 VERIFY(0 == dmu_bonus_hold(os, fuid_obj,
124 FTAG, &db));
117 fuid_size = *(uint64_t *)db->db_data;
118 dmu_buf_rele(db, FTAG);
119
120 if (fuid_size) {
121 nvlist_t **fuidnvp;
122 nvlist_t *nvp = NULL;
123 uint_t count;
124 char *packed;
125 int i;
126
127 packed = kmem_alloc(fuid_size, KM_SLEEP);
125 fuid_size = *(uint64_t *)db->db_data;
126 dmu_buf_rele(db, FTAG);
127
128 if (fuid_size) {
129 nvlist_t **fuidnvp;
130 nvlist_t *nvp = NULL;
131 uint_t count;
132 char *packed;
133 int i;
134
135 packed = kmem_alloc(fuid_size, KM_SLEEP);
128 VERIFY(dmu_read(os, fuid_obj, 0, fuid_size, packed) == 0);
136 VERIFY(dmu_read(os, fuid_obj, 0,
137 fuid_size, packed, DMU_READ_PREFETCH) == 0);
129 VERIFY(nvlist_unpack(packed, fuid_size,
130 &nvp, 0) == 0);
131 VERIFY(nvlist_lookup_nvlist_array(nvp, FUID_NVP_ARRAY,
132 &fuidnvp, &count) == 0);
133
134 for (i = 0; i != count; i++) {
135 fuid_domain_t *domnode;
136 char *domain;

--- 47 unchanged lines hidden (view full) ---

184 return (findnode ? findnode->f_ksid->kd_name : nulldomain);
185}
186
187#ifdef _KERNEL
188/*
189 * Load the fuid table(s) into memory.
190 */
191static void
138 VERIFY(nvlist_unpack(packed, fuid_size,
139 &nvp, 0) == 0);
140 VERIFY(nvlist_lookup_nvlist_array(nvp, FUID_NVP_ARRAY,
141 &fuidnvp, &count) == 0);
142
143 for (i = 0; i != count; i++) {
144 fuid_domain_t *domnode;
145 char *domain;

--- 47 unchanged lines hidden (view full) ---

193 return (findnode ? findnode->f_ksid->kd_name : nulldomain);
194}
195
196#ifdef _KERNEL
197/*
198 * Load the fuid table(s) into memory.
199 */
200static void
192zfs_fuid_init(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
201zfs_fuid_init(zfsvfs_t *zfsvfs)
193{
202{
194 int error = 0;
195
196 rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER);
197
198 if (zfsvfs->z_fuid_loaded) {
199 rw_exit(&zfsvfs->z_fuid_lock);
200 return;
201 }
202
203 rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER);
204
205 if (zfsvfs->z_fuid_loaded) {
206 rw_exit(&zfsvfs->z_fuid_lock);
207 return;
208 }
209
203 if (zfsvfs->z_fuid_obj == 0) {
210 zfs_fuid_avl_tree_create(&zfsvfs->z_fuid_idx, &zfsvfs->z_fuid_domain);
204
211
205 /* first make sure we need to allocate object */
206
207 error = zap_lookup(zfsvfs->z_os, MASTER_NODE_OBJ,
208 ZFS_FUID_TABLES, 8, 1, &zfsvfs->z_fuid_obj);
209 if (error == ENOENT && tx != NULL) {
210 zfsvfs->z_fuid_obj = dmu_object_alloc(zfsvfs->z_os,
211 DMU_OT_FUID, 1 << 14, DMU_OT_FUID_SIZE,
212 sizeof (uint64_t), tx);
213 VERIFY(zap_add(zfsvfs->z_os, MASTER_NODE_OBJ,
214 ZFS_FUID_TABLES, sizeof (uint64_t), 1,
215 &zfsvfs->z_fuid_obj, tx) == 0);
216 }
217 }
218
212 (void) zap_lookup(zfsvfs->z_os, MASTER_NODE_OBJ,
213 ZFS_FUID_TABLES, 8, 1, &zfsvfs->z_fuid_obj);
219 if (zfsvfs->z_fuid_obj != 0) {
220 zfsvfs->z_fuid_size = zfs_fuid_table_load(zfsvfs->z_os,
221 zfsvfs->z_fuid_obj, &zfsvfs->z_fuid_idx,
222 &zfsvfs->z_fuid_domain);
214 if (zfsvfs->z_fuid_obj != 0) {
215 zfsvfs->z_fuid_size = zfs_fuid_table_load(zfsvfs->z_os,
216 zfsvfs->z_fuid_obj, &zfsvfs->z_fuid_idx,
217 &zfsvfs->z_fuid_domain);
223 zfsvfs->z_fuid_loaded = B_TRUE;
224 }
225
218 }
219
220 zfsvfs->z_fuid_loaded = B_TRUE;
226 rw_exit(&zfsvfs->z_fuid_lock);
227}
228
229/*
221 rw_exit(&zfsvfs->z_fuid_lock);
222}
223
224/*
225 * sync out AVL trees to persistent storage.
226 */
227void
228zfs_fuid_sync(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
229{
230 nvlist_t *nvp;
231 nvlist_t **fuids;
232 size_t nvsize = 0;
233 char *packed;
234 dmu_buf_t *db;
235 fuid_domain_t *domnode;
236 int numnodes;
237 int i;
238
239 if (!zfsvfs->z_fuid_dirty) {
240 return;
241 }
242
243 rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER);
244
245 /*
246 * First see if table needs to be created?
247 */
248 if (zfsvfs->z_fuid_obj == 0) {
249 zfsvfs->z_fuid_obj = dmu_object_alloc(zfsvfs->z_os,
250 DMU_OT_FUID, 1 << 14, DMU_OT_FUID_SIZE,
251 sizeof (uint64_t), tx);
252 VERIFY(zap_add(zfsvfs->z_os, MASTER_NODE_OBJ,
253 ZFS_FUID_TABLES, sizeof (uint64_t), 1,
254 &zfsvfs->z_fuid_obj, tx) == 0);
255 }
256
257 VERIFY(nvlist_alloc(&nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
258
259 numnodes = avl_numnodes(&zfsvfs->z_fuid_idx);
260 fuids = kmem_alloc(numnodes * sizeof (void *), KM_SLEEP);
261 for (i = 0, domnode = avl_first(&zfsvfs->z_fuid_domain); domnode; i++,
262 domnode = AVL_NEXT(&zfsvfs->z_fuid_domain, domnode)) {
263 VERIFY(nvlist_alloc(&fuids[i], NV_UNIQUE_NAME, KM_SLEEP) == 0);
264 VERIFY(nvlist_add_uint64(fuids[i], FUID_IDX,
265 domnode->f_idx) == 0);
266 VERIFY(nvlist_add_uint64(fuids[i], FUID_OFFSET, 0) == 0);
267 VERIFY(nvlist_add_string(fuids[i], FUID_DOMAIN,
268 domnode->f_ksid->kd_name) == 0);
269 }
270 VERIFY(nvlist_add_nvlist_array(nvp, FUID_NVP_ARRAY,
271 fuids, numnodes) == 0);
272 for (i = 0; i != numnodes; i++)
273 nvlist_free(fuids[i]);
274 kmem_free(fuids, numnodes * sizeof (void *));
275 VERIFY(nvlist_size(nvp, &nvsize, NV_ENCODE_XDR) == 0);
276 packed = kmem_alloc(nvsize, KM_SLEEP);
277 VERIFY(nvlist_pack(nvp, &packed, &nvsize,
278 NV_ENCODE_XDR, KM_SLEEP) == 0);
279 nvlist_free(nvp);
280 zfsvfs->z_fuid_size = nvsize;
281 dmu_write(zfsvfs->z_os, zfsvfs->z_fuid_obj, 0,
282 zfsvfs->z_fuid_size, packed, tx);
283 kmem_free(packed, zfsvfs->z_fuid_size);
284 VERIFY(0 == dmu_bonus_hold(zfsvfs->z_os, zfsvfs->z_fuid_obj,
285 FTAG, &db));
286 dmu_buf_will_dirty(db, tx);
287 *(uint64_t *)db->db_data = zfsvfs->z_fuid_size;
288 dmu_buf_rele(db, FTAG);
289
290 zfsvfs->z_fuid_dirty = B_FALSE;
291 rw_exit(&zfsvfs->z_fuid_lock);
292}
293
294/*
230 * Query domain table for a given domain.
231 *
295 * Query domain table for a given domain.
296 *
232 * If domain isn't found it is added to AVL trees and
233 * the results are pushed out to disk.
297 * If domain isn't found and addok is set, it is added to AVL trees and
298 * the zfsvfs->z_fuid_dirty flag will be set to TRUE. It will then be
299 * necessary for the caller or another thread to detect the dirty table
300 * and sync out the changes.
234 */
235int
301 */
302int
236zfs_fuid_find_by_domain(zfsvfs_t *zfsvfs, const char *domain, char **retdomain,
237 dmu_tx_t *tx)
303zfs_fuid_find_by_domain(zfsvfs_t *zfsvfs, const char *domain,
304 char **retdomain, boolean_t addok)
238{
239 fuid_domain_t searchnode, *findnode;
240 avl_index_t loc;
241 krw_t rw = RW_READER;
242
243 /*
244 * If the dummy "nobody" domain then return an index of 0
245 * to cause the created FUID to be a standard POSIX id
246 * for the user nobody.
247 */
248 if (domain[0] == '\0') {
305{
306 fuid_domain_t searchnode, *findnode;
307 avl_index_t loc;
308 krw_t rw = RW_READER;
309
310 /*
311 * If the dummy "nobody" domain then return an index of 0
312 * to cause the created FUID to be a standard POSIX id
313 * for the user nobody.
314 */
315 if (domain[0] == '\0') {
249 *retdomain = nulldomain;
316 if (retdomain)
317 *retdomain = nulldomain;
250 return (0);
251 }
252
253 searchnode.f_ksid = ksid_lookupdomain(domain);
318 return (0);
319 }
320
321 searchnode.f_ksid = ksid_lookupdomain(domain);
254 if (retdomain) {
322 if (retdomain)
255 *retdomain = searchnode.f_ksid->kd_name;
323 *retdomain = searchnode.f_ksid->kd_name;
256 }
257 if (!zfsvfs->z_fuid_loaded)
324 if (!zfsvfs->z_fuid_loaded)
258 zfs_fuid_init(zfsvfs, tx);
325 zfs_fuid_init(zfsvfs);
259
260retry:
261 rw_enter(&zfsvfs->z_fuid_lock, rw);
262 findnode = avl_find(&zfsvfs->z_fuid_domain, &searchnode, &loc);
263
264 if (findnode) {
265 rw_exit(&zfsvfs->z_fuid_lock);
266 ksiddomain_rele(searchnode.f_ksid);
267 return (findnode->f_idx);
326
327retry:
328 rw_enter(&zfsvfs->z_fuid_lock, rw);
329 findnode = avl_find(&zfsvfs->z_fuid_domain, &searchnode, &loc);
330
331 if (findnode) {
332 rw_exit(&zfsvfs->z_fuid_lock);
333 ksiddomain_rele(searchnode.f_ksid);
334 return (findnode->f_idx);
268 } else {
335 } else if (addok) {
269 fuid_domain_t *domnode;
336 fuid_domain_t *domnode;
270 nvlist_t *nvp;
271 nvlist_t **fuids;
272 uint64_t retidx;
337 uint64_t retidx;
273 size_t nvsize = 0;
274 char *packed;
275 dmu_buf_t *db;
276 int i = 0;
277
278 if (rw == RW_READER && !rw_tryupgrade(&zfsvfs->z_fuid_lock)) {
279 rw_exit(&zfsvfs->z_fuid_lock);
280 rw = RW_WRITER;
281 goto retry;
282 }
283
284 domnode = kmem_alloc(sizeof (fuid_domain_t), KM_SLEEP);
285 domnode->f_ksid = searchnode.f_ksid;
286
287 retidx = domnode->f_idx = avl_numnodes(&zfsvfs->z_fuid_idx) + 1;
288
289 avl_add(&zfsvfs->z_fuid_domain, domnode);
290 avl_add(&zfsvfs->z_fuid_idx, domnode);
338
339 if (rw == RW_READER && !rw_tryupgrade(&zfsvfs->z_fuid_lock)) {
340 rw_exit(&zfsvfs->z_fuid_lock);
341 rw = RW_WRITER;
342 goto retry;
343 }
344
345 domnode = kmem_alloc(sizeof (fuid_domain_t), KM_SLEEP);
346 domnode->f_ksid = searchnode.f_ksid;
347
348 retidx = domnode->f_idx = avl_numnodes(&zfsvfs->z_fuid_idx) + 1;
349
350 avl_add(&zfsvfs->z_fuid_domain, domnode);
351 avl_add(&zfsvfs->z_fuid_idx, domnode);
291 /*
292 * Now resync the on-disk nvlist.
293 */
294 VERIFY(nvlist_alloc(&nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
295
296 domnode = avl_first(&zfsvfs->z_fuid_domain);
297 fuids = kmem_alloc(retidx * sizeof (void *), KM_SLEEP);
298 while (domnode) {
299 VERIFY(nvlist_alloc(&fuids[i],
300 NV_UNIQUE_NAME, KM_SLEEP) == 0);
301 VERIFY(nvlist_add_uint64(fuids[i], FUID_IDX,
302 domnode->f_idx) == 0);
303 VERIFY(nvlist_add_uint64(fuids[i],
304 FUID_OFFSET, 0) == 0);
305 VERIFY(nvlist_add_string(fuids[i++], FUID_DOMAIN,
306 domnode->f_ksid->kd_name) == 0);
307 domnode = AVL_NEXT(&zfsvfs->z_fuid_domain, domnode);
308 }
309 VERIFY(nvlist_add_nvlist_array(nvp, FUID_NVP_ARRAY,
310 fuids, retidx) == 0);
311 for (i = 0; i != retidx; i++)
312 nvlist_free(fuids[i]);
313 kmem_free(fuids, retidx * sizeof (void *));
314 VERIFY(nvlist_size(nvp, &nvsize, NV_ENCODE_XDR) == 0);
315 packed = kmem_alloc(nvsize, KM_SLEEP);
316 VERIFY(nvlist_pack(nvp, &packed, &nvsize,
317 NV_ENCODE_XDR, KM_SLEEP) == 0);
318 nvlist_free(nvp);
319 zfsvfs->z_fuid_size = nvsize;
320 dmu_write(zfsvfs->z_os, zfsvfs->z_fuid_obj, 0,
321 zfsvfs->z_fuid_size, packed, tx);
322 kmem_free(packed, zfsvfs->z_fuid_size);
323 VERIFY(0 == dmu_bonus_hold(zfsvfs->z_os, zfsvfs->z_fuid_obj,
324 FTAG, &db));
325 dmu_buf_will_dirty(db, tx);
326 *(uint64_t *)db->db_data = zfsvfs->z_fuid_size;
327 dmu_buf_rele(db, FTAG);
328
352 zfsvfs->z_fuid_dirty = B_TRUE;
329 rw_exit(&zfsvfs->z_fuid_lock);
330 return (retidx);
353 rw_exit(&zfsvfs->z_fuid_lock);
354 return (retidx);
355 } else {
356 rw_exit(&zfsvfs->z_fuid_lock);
357 return (-1);
331 }
332}
333
334/*
335 * Query domain table by index, returning domain string
336 *
337 * Returns a pointer from an avl node of the domain string.
338 *
339 */
358 }
359}
360
361/*
362 * Query domain table by index, returning domain string
363 *
364 * Returns a pointer from an avl node of the domain string.
365 *
366 */
340static char *
367const char *
341zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx)
342{
343 char *domain;
344
345 if (idx == 0 || !zfsvfs->z_use_fuids)
346 return (NULL);
347
348 if (!zfsvfs->z_fuid_loaded)
368zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx)
369{
370 char *domain;
371
372 if (idx == 0 || !zfsvfs->z_use_fuids)
373 return (NULL);
374
375 if (!zfsvfs->z_fuid_loaded)
349 zfs_fuid_init(zfsvfs, NULL);
376 zfs_fuid_init(zfsvfs);
350
351 rw_enter(&zfsvfs->z_fuid_lock, RW_READER);
352
353 if (zfsvfs->z_fuid_obj)
354 domain = zfs_fuid_idx_domain(&zfsvfs->z_fuid_idx, idx);
355 else
356 domain = nulldomain;
357 rw_exit(&zfsvfs->z_fuid_lock);

--- 11 unchanged lines hidden (view full) ---

369 cr, ZFS_GROUP);
370}
371
372uid_t
373zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
374 cred_t *cr, zfs_fuid_type_t type)
375{
376 uint32_t index = FUID_INDEX(fuid);
377
378 rw_enter(&zfsvfs->z_fuid_lock, RW_READER);
379
380 if (zfsvfs->z_fuid_obj)
381 domain = zfs_fuid_idx_domain(&zfsvfs->z_fuid_idx, idx);
382 else
383 domain = nulldomain;
384 rw_exit(&zfsvfs->z_fuid_lock);

--- 11 unchanged lines hidden (view full) ---

396 cr, ZFS_GROUP);
397}
398
399uid_t
400zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
401 cred_t *cr, zfs_fuid_type_t type)
402{
403 uint32_t index = FUID_INDEX(fuid);
377 char *domain;
404 const char *domain;
378 uid_t id;
379
380 if (index == 0)
381 return (fuid);
382
383 domain = zfs_fuid_find_by_idx(zfsvfs, index);
384 ASSERT(domain != NULL);
385

--- 52 unchanged lines hidden (view full) ---

438 fuid_domain->z_domain = domain;
439 fuid_domain->z_domidx = idx;
440 list_insert_tail(&fuidp->z_domains, fuid_domain);
441 fuidp->z_domain_str_sz += strlen(domain) + 1;
442 fuidp->z_domain_cnt++;
443 }
444
445 if (type == ZFS_ACE_USER || type == ZFS_ACE_GROUP) {
405 uid_t id;
406
407 if (index == 0)
408 return (fuid);
409
410 domain = zfs_fuid_find_by_idx(zfsvfs, index);
411 ASSERT(domain != NULL);
412

--- 52 unchanged lines hidden (view full) ---

465 fuid_domain->z_domain = domain;
466 fuid_domain->z_domidx = idx;
467 list_insert_tail(&fuidp->z_domains, fuid_domain);
468 fuidp->z_domain_str_sz += strlen(domain) + 1;
469 fuidp->z_domain_cnt++;
470 }
471
472 if (type == ZFS_ACE_USER || type == ZFS_ACE_GROUP) {
473
446 /*
447 * Now allocate fuid entry and add it on the end of the list
448 */
449
450 fuid = kmem_alloc(sizeof (zfs_fuid_t), KM_SLEEP);
451 fuid->z_id = id;
452 fuid->z_domidx = idx;
453 fuid->z_logfuid = FUID_ENCODE(fuididx, rid);

--- 8 unchanged lines hidden (view full) ---

462 }
463}
464
465/*
466 * Create a file system FUID, based on information in the users cred
467 */
468uint64_t
469zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type,
474 /*
475 * Now allocate fuid entry and add it on the end of the list
476 */
477
478 fuid = kmem_alloc(sizeof (zfs_fuid_t), KM_SLEEP);
479 fuid->z_id = id;
480 fuid->z_domidx = idx;
481 fuid->z_logfuid = FUID_ENCODE(fuididx, rid);

--- 8 unchanged lines hidden (view full) ---

490 }
491}
492
493/*
494 * Create a file system FUID, based on information in the users cred
495 */
496uint64_t
497zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type,
470 dmu_tx_t *tx, cred_t *cr, zfs_fuid_info_t **fuidp)
498 cred_t *cr, zfs_fuid_info_t **fuidp)
471{
472 uint64_t idx;
473 ksid_t *ksid;
474 uint32_t rid;
475 char *kdomain;
476 const char *domain;
477 uid_t id;
478

--- 9 unchanged lines hidden (view full) ---

488
489#ifdef TODO
490 ksid = crgetsid(cr, (type == ZFS_OWNER) ? KSID_OWNER : KSID_GROUP);
491
492 VERIFY(ksid != NULL);
493 rid = ksid_getrid(ksid);
494 domain = ksid_getdomain(ksid);
495
499{
500 uint64_t idx;
501 ksid_t *ksid;
502 uint32_t rid;
503 char *kdomain;
504 const char *domain;
505 uid_t id;
506

--- 9 unchanged lines hidden (view full) ---

516
517#ifdef TODO
518 ksid = crgetsid(cr, (type == ZFS_OWNER) ? KSID_OWNER : KSID_GROUP);
519
520 VERIFY(ksid != NULL);
521 rid = ksid_getrid(ksid);
522 domain = ksid_getdomain(ksid);
523
496 idx = zfs_fuid_find_by_domain(zfsvfs, domain, &kdomain, tx);
524 idx = zfs_fuid_find_by_domain(zfsvfs, domain, &kdomain, B_TRUE);
497
498 zfs_fuid_node_add(fuidp, kdomain, rid, idx, id, type);
499
500 return (FUID_ENCODE(idx, rid));
501#else
502 panic(__func__);
503#endif
504}

--- 7 unchanged lines hidden (view full) ---

512 * domain and rid.
513 *
514 * During replay operations the domain+rid information is
515 * found in the zfs_fuid_info_t that the replay code has
516 * attached to the zfsvfs of the file system.
517 */
518uint64_t
519zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
525
526 zfs_fuid_node_add(fuidp, kdomain, rid, idx, id, type);
527
528 return (FUID_ENCODE(idx, rid));
529#else
530 panic(__func__);
531#endif
532}

--- 7 unchanged lines hidden (view full) ---

540 * domain and rid.
541 *
542 * During replay operations the domain+rid information is
543 * found in the zfs_fuid_info_t that the replay code has
544 * attached to the zfsvfs of the file system.
545 */
546uint64_t
547zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
520 zfs_fuid_type_t type, dmu_tx_t *tx, zfs_fuid_info_t **fuidpp)
548 zfs_fuid_type_t type, zfs_fuid_info_t **fuidpp)
521{
522 const char *domain;
523 char *kdomain;
524 uint32_t fuid_idx = FUID_INDEX(id);
525 uint32_t rid;
526 idmap_stat status;
527 uint64_t idx;
549{
550 const char *domain;
551 char *kdomain;
552 uint32_t fuid_idx = FUID_INDEX(id);
553 uint32_t rid;
554 idmap_stat status;
555 uint64_t idx;
528 boolean_t is_replay = (zfsvfs->z_assign >= TXG_INITIAL);
529 zfs_fuid_t *zfuid = NULL;
530 zfs_fuid_info_t *fuidp;
531
532 /*
533 * If POSIX ID, or entry is already a FUID then
534 * just return the id
535 *
536 * We may also be handed an already FUID'ized id via
537 * chmod.
538 */
539
540 if (!zfsvfs->z_use_fuids || !IS_EPHEMERAL(id) || fuid_idx != 0)
541 return (id);
542
556 zfs_fuid_t *zfuid = NULL;
557 zfs_fuid_info_t *fuidp;
558
559 /*
560 * If POSIX ID, or entry is already a FUID then
561 * just return the id
562 *
563 * We may also be handed an already FUID'ized id via
564 * chmod.
565 */
566
567 if (!zfsvfs->z_use_fuids || !IS_EPHEMERAL(id) || fuid_idx != 0)
568 return (id);
569
543 if (is_replay) {
570 if (zfsvfs->z_replay) {
544 fuidp = zfsvfs->z_fuid_replay;
545
546 /*
547 * If we are passed an ephemeral id, but no
548 * fuid_info was logged then return NOBODY.
549 * This is most likely a result of idmap service
550 * not being available.
551 */

--- 35 unchanged lines hidden (view full) ---

587 rid = UID_NOBODY;
588 domain = nulldomain;
589 }
590#else
591 panic(__func__);
592#endif
593 }
594
571 fuidp = zfsvfs->z_fuid_replay;
572
573 /*
574 * If we are passed an ephemeral id, but no
575 * fuid_info was logged then return NOBODY.
576 * This is most likely a result of idmap service
577 * not being available.
578 */

--- 35 unchanged lines hidden (view full) ---

614 rid = UID_NOBODY;
615 domain = nulldomain;
616 }
617#else
618 panic(__func__);
619#endif
620 }
621
595 idx = zfs_fuid_find_by_domain(zfsvfs, domain, &kdomain, tx);
622 idx = zfs_fuid_find_by_domain(zfsvfs, domain, &kdomain, B_TRUE);
596
623
597 if (!is_replay)
598 zfs_fuid_node_add(fuidpp, kdomain, rid, idx, id, type);
624 if (!zfsvfs->z_replay)
625 zfs_fuid_node_add(fuidpp, kdomain,
626 rid, idx, id, type);
599 else if (zfuid != NULL) {
600 list_remove(&fuidp->z_fuids, zfuid);
601 kmem_free(zfuid, sizeof (zfs_fuid_t));
602 }
603 return (FUID_ENCODE(idx, rid));
604}
605
606void

--- 56 unchanged lines hidden (view full) ---

663 * has ksid info then sidlist is checked first
664 * and if still not found then POSIX groups are checked
665 *
666 * Will use a straight FUID compare when possible.
667 */
668boolean_t
669zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
670{
627 else if (zfuid != NULL) {
628 list_remove(&fuidp->z_fuids, zfuid);
629 kmem_free(zfuid, sizeof (zfs_fuid_t));
630 }
631 return (FUID_ENCODE(idx, rid));
632}
633
634void

--- 56 unchanged lines hidden (view full) ---

691 * has ksid info then sidlist is checked first
692 * and if still not found then POSIX groups are checked
693 *
694 * Will use a straight FUID compare when possible.
695 */
696boolean_t
697zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
698{
699#ifdef sun
671 ksid_t *ksid = crgetsid(cr, KSID_GROUP);
700 ksid_t *ksid = crgetsid(cr, KSID_GROUP);
701 ksidlist_t *ksidlist = crgetsidlist(cr);
702#endif /* sun */
672 uid_t gid;
673
703 uid_t gid;
704
674#ifdef TODO
675 if (ksid) {
705#ifdef sun
706 if (ksid && ksidlist) {
676 int i;
677 ksid_t *ksid_groups;
678 ksidlist_t *ksidlist = crgetsidlist(cr);
679 uint32_t idx = FUID_INDEX(id);
680 uint32_t rid = FUID_RID(id);
681
682 ASSERT(ksidlist);
683 ksid_groups = ksidlist->ksl_sids;
684
685 for (i = 0; i != ksidlist->ksl_nsid; i++) {
686 if (idx == 0) {
687 if (id != IDMAP_WK_CREATOR_GROUP_GID &&
688 id == ksid_groups[i].ks_id) {
689 return (B_TRUE);
690 }
691 } else {
707 int i;
708 ksid_t *ksid_groups;
709 ksidlist_t *ksidlist = crgetsidlist(cr);
710 uint32_t idx = FUID_INDEX(id);
711 uint32_t rid = FUID_RID(id);
712
713 ASSERT(ksidlist);
714 ksid_groups = ksidlist->ksl_sids;
715
716 for (i = 0; i != ksidlist->ksl_nsid; i++) {
717 if (idx == 0) {
718 if (id != IDMAP_WK_CREATOR_GROUP_GID &&
719 id == ksid_groups[i].ks_id) {
720 return (B_TRUE);
721 }
722 } else {
692 char *domain;
723 const char *domain;
693
694 domain = zfs_fuid_find_by_idx(zfsvfs, idx);
695 ASSERT(domain != NULL);
696
697 if (strcmp(domain,
698 IDMAP_WK_CREATOR_SID_AUTHORITY) == 0)
699 return (B_FALSE);
700
701 if ((strcmp(domain,
702 ksid_groups[i].ks_domain->kd_name) == 0) &&
703 rid == ksid_groups[i].ks_rid)
704 return (B_TRUE);
705 }
706 }
707 }
724
725 domain = zfs_fuid_find_by_idx(zfsvfs, idx);
726 ASSERT(domain != NULL);
727
728 if (strcmp(domain,
729 IDMAP_WK_CREATOR_SID_AUTHORITY) == 0)
730 return (B_FALSE);
731
732 if ((strcmp(domain,
733 ksid_groups[i].ks_domain->kd_name) == 0) &&
734 rid == ksid_groups[i].ks_rid)
735 return (B_TRUE);
736 }
737 }
738 }
708#endif
739#endif /* sun */
709
710 /*
711 * Not found in ksidlist, check posix groups
712 */
713 gid = zfs_fuid_map_id(zfsvfs, id, cr, ZFS_GROUP);
714 return (groupmember(gid, cr));
715}
740
741 /*
742 * Not found in ksidlist, check posix groups
743 */
744 gid = zfs_fuid_map_id(zfsvfs, id, cr, ZFS_GROUP);
745 return (groupmember(gid, cr));
746}
747
748void
749zfs_fuid_txhold(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
750{
751 if (zfsvfs->z_fuid_obj == 0) {
752 dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
753 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0,
754 FUID_SIZE_ESTIMATE(zfsvfs));
755 dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, FALSE, NULL);
756 } else {
757 dmu_tx_hold_bonus(tx, zfsvfs->z_fuid_obj);
758 dmu_tx_hold_write(tx, zfsvfs->z_fuid_obj, 0,
759 FUID_SIZE_ESTIMATE(zfsvfs));
760 }
761}
716#endif
762#endif