1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 ^L
68 create_vtoce : procedure (branchp, pvid, vtocx, code);
69
70
71 dcl branchp ptr;
72 dcl pvid bit (36);
73 dcl vtocx fixed bin (17);
74 dcl code fixed bin (35);
75
76
77
78 dcl corout_pvtx fixed bin;
79 dcl a_skip_pvtx fixed bin;
80 dcl skip_pvtx fixed bin;
81 dcl a_nreq fixed bin;
82 dcl a_optimize bit (1) aligned;
83
84 dcl (i, pvtx, msl) fixed bin (17);
85 dcl first_pvtx fixed bin (17);
86 dcl nreq fixed bin (17);
87 dcl (mover, looped, looping, try_cycle, held) bit (1);
88 dcl 1 event_flags aligned like audit_event_flags;
89 dcl force_rpv bit (1);
90 dcl optimizing bit (1);
91 dcl lvid bit (36);
92 dcl queue_length fixed bin;
93 dcl (working_sum, random_number, sum_fract_empty) fixed bin (35, 18);
94 dcl n_pvs fixed bin;
95 dcl pv_found bit (1);
96 dcl pv_alloc_x fixed bin;
97 dcl 1 pv_alloc (MAX_PV_PER_LV) aligned,
98 2 pvtx fixed bin,
99 2 fract_empty fixed bin (35, 18);
100
101 dcl vtoc_buffer (96) fixed bin (71);
102 dcl 1 local_vtoce like vtoce aligned based (addr (vtoc_buffer));
103 dcl based_class_range (2) bit (72) aligned based;
104
105 dcl access_operations_$fs_obj_create bit (36) aligned ext;
106 dcl sys_info$initialization_state fixed bin ext;
107 dcl sst$cycle_pv_allocation fixed bin (35) external;
108 dcl pvt$root_lvid bit (36) aligned external;
109 dcl error_table_$log_vol_full ext fixed bin (35);
110 dcl error_table_$pvid_not_found ext fixed bin (35);
111 dcl error_table_$ai_restricted ext fixed bin (35);
112 dcl sys_info$default_max_length ext fixed bin (19);
113 dcl sys_info$default_dir_max_length ext fixed bin (19);
114 dcl active_hardcore_data$sl1_uid bit (36) aligned external;
115
116 dcl access_audit_check_ep_$self entry (bit (36) aligned, bit (36) aligned, ptr) returns (bit (1));
117 dcl access_audit_$log_entry_ptr entry options (variable);
118 dcl display_access_class_$range entry ((2) bit(72) aligned) returns(char(32) aligned);
119 dcl vtoc_man$alloc_and_put_vtoce entry (bit (36) aligned, fixed bin (17), ptr, fixed bin (35)) returns (fixed bin);
120 dcl logical_volume_manager$lvtep entry (bit (36) aligned, ptr, fixed bin (35));
121 dcl clock_ entry returns (fixed bin (52));
122 dcl level$get entry () returns (fixed bin);
123 dcl read_allowed_ entry (bit(72) aligned, bit(72) aligned) returns(bit(1) aligned);
124 dcl write_allowed_ entry (bit(72) aligned, bit(72) aligned) returns(bit(1) aligned);
125 dcl get_pvtx$hold_pvtx entry (bit (36) aligned, fixed bin, fixed bin (35));
126 dcl get_pvtx$release_pvtx entry (bit (36) aligned, fixed bin);
127 dcl dbm_man$set_incr entry (fixed bin, fixed bin, fixed bin (35));
128 dcl uid_path_util$get entry (ptr, dim (0:15) bit (36) aligned, fixed bin (35));
129 dcl disk_control$queue_length_given_pvtx entry entry (fixed bin, fixed bin);
130
131 dcl (addr, bit, clock, divide, fixed, high9, mod, multiply, null, ptr, rel, string, unspec) builtin;
132
133
134 dcl fm_nullifier char (256*2) aligned based (fmn_ptr);
135 dcl fmn_ptr ptr;
136 dcl uid_path (0:15) bit (36) aligned;
137
138 dcl MAXQ_FOR_PDIR_CYCLE fixed bin int static options (constant) init (7);
139 dcl MAX_PV_PER_LV fixed bin int static options (constant) init (32);
140 dcl MODULUS fixed bin int static options (constant) init (1024);
141
142
143 ^L
144
145
146 mover = "0"b;
147 skip_pvtx = 0;
148 nreq = 0;
149 optimizing = "1"b;
150 join: code = 0;
151 vtocep = addr (local_vtoce);
152 ep = branchp;
153 dp = ptr (ep, 0);
154
155 if entry.dirsw then msl = divide (sys_info$default_dir_max_length, 1024, 17, 0);
156 else msl = divide (sys_info$default_max_length, 1024, 17, 0);
157
158 unspec (local_vtoce) = "0"b;
159 local_vtoce.uid = entry.uid;
160 local_vtoce.msl = bit (fixed (msl, 9));
161 local_vtoce.dirsw = entry.dirsw;
162 local_vtoce.primary_name = addr (entry.primary_name) -> names.name;
163 local_vtoce.time_created = bit (clock_ (), 52);
164 local_vtoce.dtu = local_vtoce.time_created;
165 local_vtoce.dtm = local_vtoce.dtu;
166 local_vtoce.par_pvid = dir.pvid;
167 local_vtoce.par_vtocx = dir.vtocx;
168 local_vtoce.per_process = entry.per_process_sw;
169 local_vtoce.branch_rp = rel (ep);
170 local_vtoce.access_class = entry.access_class;
171 local_vtoce.master_dir = entry.master_dir;
172 if dp -> dir.uid = active_hardcore_data$sl1_uid
173 then local_vtoce.perm_flags.per_bootload = "1"b;
174 if mover then
175 if tq_infop ^= null then
176 do i = 0 to 1;
177 local_vtoce.trp (i) = tq_info.trp (i);
178 local_vtoce.trp_time (i) = tq_info.tup (i);
179 local_vtoce.received (i) = tq_info.received (i);
180 end;
181
182
183
184
185
186
187 fmn_ptr = addr (local_vtoce.fm (0));
188 fm_nullifier = high9(256*2);
189
190
191
192
193
194
195
196 force_rpv = (dir.tree_depth = 0)
197 | dir.force_rpv
198 | sys_info$initialization_state < 3;
199
200
201
202
203 call uid_path_util$get (dp, uid_path, code);
204 if code ^= 0 then return;
205 local_vtoce.uid_path = uid_path;
206
207
208
209
210 try_cycle = ^mover & ^force_rpv
211 & (dir.per_process_sw | sst$cycle_pv_allocation ^= 0);
212
213
214
215 if entry.dirsw = "0"b then lvid = dir.sons_lvid;
216 else lvid = pvt$root_lvid;
217
218
219 restart: call logical_volume_manager$lvtep ((lvid), lvtep, code);
220 if code ^= 0 then return;
221 if ^(read_allowed_ (entry.access_class, lvte.access_class.min) &
222 write_allowed_ (entry.access_class, lvte.access_class.max))
223 then do;
224 pvid = "0"b;
225 vtocx = -1;
226 code = error_table_$ai_restricted;
227 string(event_flags) = ""b;
228 if access_audit_check_ep_$self (string (event_flags), access_operations_$fs_obj_create, ep) then
229 call access_audit_$log_entry_ptr ("create_vtoce", level$get(), string(event_flags),
230 access_operations_$fs_obj_create, ep, code, null(), 0,
231 "entry class range outside LV (^a LVID ^w)",
232 display_access_class_$range (addr(lvte.access_class)->based_class_range), lvte.lvid);
233 return;
234 end;
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252 pvt_arrayp = addr (pvt$array);
253 retry:
254 held = "0"b;
255 if try_cycle then do;
256 try_cycle = "0"b;
257
258 looped, looping = "0"b;
259 pvtx = lvte.cycle_pvtx;
260 if pvtx = 0 then looped = "1"b; note
261 else do;
262 pvtep = addr (pvt_array (pvtx));
263 if pvte.lvid ^= lvid then looped = "1"b; note
264 end;
265 if looped then pvtx, lvte.cycle_pvtx = lvte.pvtex;
266
267
268 do while (^looping);
269 pvtep = addr (pvt_array (pvtx));
270 call disk_control$queue_length_given_pvtx (pvtx, queue_length);
271 if ^pvte.vacating
272 & ^pvte.device_inoperative
273 & pvte.n_free_vtoce > 0
274 & pvte.nleft > 32 then do;
275 if dir.per_process_sw
276 & queue_length>MAXQ_FOR_PDIR_CYCLE
277 then do;
278 if pvte.skip_queue_count=262143
279 then pvte.skip_queue_count = 0;
280 else pvte.skip_queue_count = pvte.skip_queue_count + 1;
281 end;
282 else do;
283 lvte.cycle_pvtx = pvte.brother_pvtx;
284 pvid = pvte.pvid;
285 go to got;
286 end;
287 end;
288 pvtx = pvte.brother_pvtx;
289 if pvtx = 0 then do;
290 if looped then looping = "1"b;
291 else do;
292 looped = "1"b; note
293 pvtx = lvte.pvtex;
294 end;
295 end;
296 end;
297 end;
298
299 n_pvs = 0;
300 sum_fract_empty = 0;
301 pvtx = -1;
302
303 if mover
304 then if corout_pvtx = 0
305 then first_pvtx = lvte.pvtex;
306 else do;
307 first_pvtx = pvt_array (corout_pvtx).brother_pvtx;
308 corout_pvtx = 0;
309 end;
310 else first_pvtx = lvte.pvtex;
311
312 do i = first_pvtx repeat (pvte.brother_pvtx) while (i ^= 0);
313 pvtep = addr (pvt_array (i));
314 if pvte.lvid ^= lvid then go to restart;
315 if (^force_rpv | pvte.rpv)
316 then if pvte.n_free_vtoce > 0 & ^pvte.vacating
317 then if (^mover | (pvte.nleft > nreq) & (i ^= skip_pvtx))
318 & ^pvte.device_inoperative
319 then do;
320 if ^optimizing then do;
321 pvtx = i;
322 goto got;
323 end;
324 else do;
325 n_pvs = n_pvs + 1;
326 pv_alloc (n_pvs).pvtx = i;
327 pv_alloc (n_pvs).fract_empty
328 = divide (pvte.nleft, pvte.totrec, 35, 18);
329 sum_fract_empty = sum_fract_empty
330 + pv_alloc (n_pvs).fract_empty;
331 end;
332 end;
333 end;
334
335
336
337
338
339
340
341
342
343 if n_pvs > 0 then do;
344 random_number = divide (multiply (mod (clock (), MODULUS), sum_fract_empty, 35, 18),
345 MODULUS, 35, 18);
346 working_sum = 0;
347 pv_found = "0"b;
348 do pv_alloc_x = 1 repeat pv_alloc_x + 1
349 while (^pv_found & pv_alloc_x < n_pvs);
350 working_sum = working_sum + pv_alloc (pv_alloc_x).fract_empty;
351 if working_sum >= random_number then do;
352 pv_found = "1"b;
353 pvtx = pv_alloc (pv_alloc_x).pvtx;
354 end;
355 end;
356 if ^pv_found then pvtx = pv_alloc (n_pvs).pvtx;
357 end;
358
359
360
361 if pvtx = -1 then
362 do ;
363 no_room: vtocx = -1;
364 pvid = "0"b;
365 code = error_table_$log_vol_full;
366 return;
367 end;
368
369 got: pvtep = addr (pvt_array (pvtx));
370 if pvte.lvid ^= lvid then go to retry;
371 pvid = pvte.pvid;
372
373
374 call get_pvtx$hold_pvtx ((pvid), pvtx, code);
375 if code ^= 0 then goto not_there;
376 held = "1"b;
377
378 vtocx = vtoc_man$alloc_and_put_vtoce ((pvid), pvtx, addr (local_vtoce), code);
379 if code ^= 0 then do;
380 not_there:
381 vtocx = -1;
382 if held then call get_pvtx$release_pvtx ((pvid), pvtx);
383 pvid = "0"b;
384 return;
385 end;
386 if vtocx = -1 then do;
387
388 if held then call get_pvtx$release_pvtx ((pvid), pvtx);
389 goto retry;
390 end;
391 call dbm_man$set_incr (pvtx, vtocx, code);
392
393 call get_pvtx$release_pvtx ((pvid), pvtx);
394
395 if mover then corout_pvtx = pvtx;
396 return;
397
398
399
400
401
402
403
404
405
406
407
408
409 createv_for_segmove: entry (branchp, pvid, vtocx, code,
410 corout_pvtx,
411 a_skip_pvtx,
412 a_nreq,
413 tq_infop,
414 a_optimize);
415
416
417 skip_pvtx = a_skip_pvtx;
418 nreq = a_nreq;
419 mover = "1"b;
420 optimizing = a_optimize;
421 go to join;
422 %page; %include backup_static_variables;
423 %page; %include dir_entry;
424 %page; %include dir_header;
425 %page; %include dir_name;
426 %page; %include lvt;
427 %page; %include null_addresses;
428 %page; %include pvte;
429 %page; %include tq_info;
430 %page; %include vtoce;
431 %page; %include access_audit_eventflags;
432 %page;
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450 end create_vtoce;