MCPcopy Create free account
hub / github.com/F-Stack/f-stack / dmu_object_alloc_impl

Function dmu_object_alloc_impl

freebsd/contrib/openzfs/module/zfs/dmu_object.c:46–223  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

44int dmu_object_alloc_chunk_shift = 7;
45
46static uint64_t
47dmu_object_alloc_impl(objset_t *os, dmu_object_type_t ot, int blocksize,
48 int indirect_blockshift, dmu_object_type_t bonustype, int bonuslen,
49 int dnodesize, dnode_t **allocated_dnode, void *tag, dmu_tx_t *tx)
50{
51 uint64_t object;
52 uint64_t L1_dnode_count = DNODES_PER_BLOCK <<
53 (DMU_META_DNODE(os)->dn_indblkshift - SPA_BLKPTRSHIFT);
54 dnode_t *dn = NULL;
55 int dn_slots = dnodesize >> DNODE_SHIFT;
56 boolean_t restarted = B_FALSE;
57 uint64_t *cpuobj = NULL;
58 int dnodes_per_chunk = 1 << dmu_object_alloc_chunk_shift;
59 int error;
60
61 cpuobj = &os->os_obj_next_percpu[CPU_SEQID_UNSTABLE %
62 os->os_obj_next_percpu_len];
63
64 if (dn_slots == 0) {
65 dn_slots = DNODE_MIN_SLOTS;
66 } else {
67 ASSERT3S(dn_slots, >=, DNODE_MIN_SLOTS);
68 ASSERT3S(dn_slots, <=, DNODE_MAX_SLOTS);
69 }
70
71 /*
72 * The "chunk" of dnodes that is assigned to a CPU-specific
73 * allocator needs to be at least one block's worth, to avoid
74 * lock contention on the dbuf. It can be at most one L1 block's
75 * worth, so that the "rescan after polishing off a L1's worth"
76 * logic below will be sure to kick in.
77 */
78 if (dnodes_per_chunk < DNODES_PER_BLOCK)
79 dnodes_per_chunk = DNODES_PER_BLOCK;
80 if (dnodes_per_chunk > L1_dnode_count)
81 dnodes_per_chunk = L1_dnode_count;
82
83 /*
84 * The caller requested the dnode be returned as a performance
85 * optimization in order to avoid releasing the hold only to
86 * immediately reacquire it. Since they caller is responsible
87 * for releasing the hold they must provide the tag.
88 */
89 if (allocated_dnode != NULL) {
90 ASSERT3P(tag, !=, NULL);
91 } else {
92 ASSERT3P(tag, ==, NULL);
93 tag = FTAG;
94 }
95
96 object = *cpuobj;
97 for (;;) {
98 /*
99 * If we finished a chunk of dnodes, get a new one from
100 * the global allocator.
101 */
102 if ((P2PHASE(object, dnodes_per_chunk) == 0) ||
103 (P2PHASE(object + dn_slots - 1, dnodes_per_chunk) <

Callers 4

dmu_object_allocFunction · 0.85
dmu_object_alloc_ibsFunction · 0.85
dmu_object_alloc_dnsizeFunction · 0.85
dmu_object_alloc_holdFunction · 0.85

Calls 12

mutex_enterFunction · 0.85
dnode_next_offsetFunction · 0.85
mutex_exitFunction · 0.85
dnode_hold_implFunction · 0.85
rw_enterFunction · 0.85
dnode_allocateFunction · 0.85
rw_exitFunction · 0.85
dmu_tx_add_new_objectFunction · 0.85
dnode_releFunction · 0.85
dmu_object_nextFunction · 0.85
atomic_swap_64Function · 0.50
atomic_add_64_nvFunction · 0.50

Tested by

no test coverage detected