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 segment_mover:
32 proc (a_refaddr, a_astep, a_ep, a_segno, a_code);
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93 dcl a_astep ptr;
94 dcl a_code fixed bin (35);
95 dcl a_ep ptr;
96 dcl a_refaddr fixed bin (18);
97 dcl a_segno fixed bin;
98
99 dcl aste_uid bit (36) aligned;
100 dcl aste_tqsw (0:1) bit (1) aligned;
101 dcl cleanup_must_zero_sdw bit (1) aligned;
102 dcl code fixed bin (35);
103 dcl corout_pvtx fixed bin;
104
105 dcl demand_segmove bit (1);
106 dcl depolist (0:255) bit (36) aligned;
107
108 dcl dlp ptr;
109 dcl move_astep ptr;
110 dcl held_pvtx bit (1);
111 dcl ignore fixed bin (35);
112 dcl mod_status bit (1);
113 dcl n_nulled_pages fixed bin;
114 dcl new_pts fixed bin;
115 dcl new_ptsi fixed bin;
116 dcl new_pvid bit (36) aligned;
117 dcl new_pvtx fixed bin;
118 dcl new_vtocx fixed bin;
119 dcl old_nqsw bit (1);
120 dcl old_pts fixed bin;
121 dcl old_ptsi fixed bin;
122 dcl old_pvid bit (36) aligned;
123 dcl old_pvtx fixed bin;
124 dcl old_vtocx fixed bin;
125 dcl optimizing bit (1) aligned;
126 dcl pageno_list (256) fixed bin;
127 dcl pvid bit (36);
128 dcl pw1 fixed bin;
129 dcl pw2 fixed bin;
130 dcl qtype fixed bin;
131 dcl recs_needed fixed bin;
132 dcl ref_addr fixed bin (18);
133 dcl refpage fixed bin;
134 dcl same_pvtx bit (1);
135 dcl segno fixed bin;
136 dcl size_needed fixed bin;
137 dcl skip_pvtx fixed bin;
138 dcl temp_ename char (32);
139 dcl time1 fixed bin (71);
140 dcl time2 fixed bin (71);
141 dcl tsdw fixed bin (71) aligned;
142
143
144 dcl 1 aq_cell like quota_cell aligned;
145
146 dcl 1 atq_info like tq_info aligned;
147
148
149 dcl MAGIC_NPAGES fixed bin static init (10);
150
151
152 dcl create_vtoce$createv_for_segmove
153 entry (ptr, bit (36), fixed bin, fixed bin (35), fixed bin, fixed bin, fixed bin,
154 ptr, bit (1) aligned);
155 dcl dbm_man$set_incr entry (fixed bin, fixed bin, fixed bin (35));
156 dcl get_aste entry (fixed bin) returns (ptr);
157 dcl get_ptrs_$given_astep entry (ptr) returns (fixed bin (71) aligned);
158 dcl get_pvtx$hold_pvtx entry (bit (36) aligned, fixed bin, fixed bin (35));
159 dcl get_pvtx$release_pvtx entry (bit (36) aligned, fixed bin);
160 dcl lock$lock_ast ext entry;
161 dcl lock$unlock_ast ext entry;
162 dcl logical_volume_manager$lvtep
163 entry (bit (36) aligned, ptr, fixed bin (35));
164 dcl pc$deposit_list entry (fixed bin, fixed bin, ptr, fixed bin, ptr);
165 dcl pc$list_deposited_add entry (ptr, fixed bin, fixed bin, fixed bin, ptr, ptr);
166 dcl pc$segmove entry (ptr, ptr, ptr, fixed bin, fixed bin, fixed bin, ptr, ptr, fixed bin (35));
167 dcl pds$process_group_id ext char (32) aligned;
168 dcl pmut$swap_sdw entry (ptr, ptr);
169 dcl put_aste entry (ptr);
170 dcl setfaults entry (ptr, bit (1) aligned);
171 dcl sum$dirmod entry (pointer);
172
173 dcl syserr entry options (variable);
174 dcl syserr$error_code entry options (variable);
175 dcl (
176 search_ast$hash_in,
177 search_ast$hash_out
178 ) entry (pointer);
179 dcl thread$cin entry (ptr, bit (18));
180 dcl thread$out entry (ptr, bit (18));
181 dcl usage_values entry (fixed bin (17), fixed bin (71));
182 dcl vtoc_attributes$get_quota
183 entry (bit (36) aligned, bit (36) aligned, fixed bin, ptr, fixed bin,
184 fixed bin (35));
185 dcl vtoc_man$await_vtoce entry (bit (36) aligned, fixed bin, fixed bin, fixed bin (35));
186 dcl vtoc_man$free_vtoce entry (bit (36) aligned, fixed bin, fixed bin, fixed bin (35));
187
188 dcl sys_info$page_size fixed bin external static;
189 dcl error_table_$log_vol_full
190 fixed bin (35) ext static;
191 dcl error_table_$illegal_deactivation
192 fixed bin (35) external;
193
194
195 dcl (addr, baseptr, divide, fixed, null, setwordno, unspec, wordno)
196 builtin;
197
198 %page;
199
200
201
202
203
204
205
206
207 demand_segmove = "0"b;
208 ref_addr = a_refaddr;
209 goto COMMON;
210
211 demand_segmove:
212 entry (a_astep, a_ep, a_segno, a_code);
213
214 demand_segmove = "1"b;
215 ref_addr = -1;
216
217 COMMON:
218 call usage_values (pw1, time1);
219 code = 0;
220 segno = a_segno;
221 ep = a_ep;
222 astep = null ();
223 move_astep = a_astep;
224
225 dlp = addr (depolist);
226 pvt_arrayp = addr (pvt$array);
227 sstp = addr (sst_seg$);
228
229 if move_astep -> aste.hc_sdw | move_astep -> aste.hc | move_astep -> aste.par_astep = "0"b
230 then do;
231 a_code = error_table_$illegal_deactivation;
232
233 if ^demand_segmove
234 then
235 call syserr (LOG, "segment_mover: critical segment out of disk on ^a, segno/astep = ^o ^o",
236 diskname ((move_astep -> aste.pvtx)), segno, wordno (move_astep));
237 call lock$unlock_ast;
238 return;
239 end;
240
241
242
243
244
245
246 call logical_volume_manager$lvtep ((pvt_array (move_astep -> aste.pvtx).lvid), lvtep, code);
247 if code = 0 & ^demand_segmove
248 then if move_astep -> aste.pvtx = lvte.pvtex & pvt_array (move_astep -> aste.pvtx).brother_pvtx = 0
249 then do;
250 call lock$unlock_ast;
251 a_code = error_table_$log_vol_full;
252 return;
253 end;
254
255
256
257
258
259
260
261
262 if move_astep -> aste.synchronized
263 then do;
264 call setfaults (move_astep, "0"b);
265 tsdw = get_ptrs_$given_astep (move_astep);
266
267 call pmut$swap_sdw (baseptr (segno), addr (tsdw));
268
269 cleanup_must_zero_sdw = "1"b;
270 end;
271 else cleanup_must_zero_sdw = "0"b;
272
273
274
275
276
277
278
279
280 call thread$out (move_astep, sst.ausedp (fixed (move_astep -> aste.ptsi, 2)));
281 call search_ast$hash_out (move_astep);
282
283
284
285 old_ptsi = fixed (move_astep -> aste.ptsi, 9);
286 old_pts = sst.pts (old_ptsi);
287 old_vtocx = move_astep -> aste.vtocx;
288 old_pvtx = move_astep -> aste.pvtx;
289 old_pvid = pvt_array (old_pvtx).pvid;
290
291 call get_pvtx$hold_pvtx (old_pvid, old_pvtx, code);
292 if code ^= 0
293 then call syserr (CRASH, "segment_mover: get_pvtx(^o) fails under ast lock", old_pvtx);
294 held_pvtx = "0"b;
295
296 mod_status = move_astep -> aste.fms;
297
298 n_nulled_pages = 0;
299 if ^move_astep -> aste.ddnp & ^(move_astep -> aste.fm_damaged & (sst.checksum_filemap ^= 0))
300 then do;
301 call pc$list_deposited_add (move_astep, 0, old_pts - 1, n_nulled_pages, dlp, addr (pageno_list));
302
303 if n_nulled_pages > 0 & ^demand_segmove
304 then do;
305 call vtoc_man$await_vtoce (old_pvid, old_pvtx, old_vtocx, code);
306
307 if code ^= 0
308 then go to retake_fault;
309 call pc$deposit_list (fixed (move_astep -> aste.pvtx, 17), n_nulled_pages, dlp, old_vtocx,
310 addr (pageno_list));
311 if n_nulled_pages > MAGIC_NPAGES & ^demand_segmove
312 then do;
313 retake_fault:
314 call thread$cin (move_astep, sst.ausedp (fixed (move_astep -> aste.ptsi, 2)));
315 call search_ast$hash_in (move_astep);
316 call cleanup_dseg_and_meter;
317 if move_astep -> aste.uid = aste_uid
318 then move_astep -> aste.pack_ovfl = "0"b;
319 call release_pvtxs;
320 call lock$unlock_ast;
321 a_code = code;
322 return;
323 end;
324 end;
325 end;
326
327 recs_needed = n_nulled_pages + fixed (move_astep -> aste.records, 9);
328
329 refpage = divide (ref_addr, sys_info$page_size, 18, 0);
330 size_needed = old_pts;
331 aste_uid = move_astep -> aste.uid;
332 aste_tqsw (*) = move_astep -> aste.tqsw (*);
333 old_nqsw = move_astep -> aste.nqsw;
334
335
336 move_astep -> aste.nqsw = "1"b;
337
338 new_ptsi, new_pts = -1;
339
340
341 call lock$unlock_ast;
342
343 if aste_tqsw (0) | aste_tqsw (1)
344 then do;
345 unspec (atq_info) = "0"b;
346 tq_infop = addr (atq_info);
347 qcp = addr (aq_cell);
348 do qtype = 0 to 1;
349 if aste_tqsw (qtype)
350 then do;
351 call vtoc_attributes$get_quota (aste_uid, old_pvid, old_vtocx, qcp, qtype, code);
352 if code ^= 0
353 then
354 call syserr$error_code (LOG, code,
355 "segment_mover: Moving ^[segment^;directory^] quota account from pvtx ^o, vtocx ^o^/",
356 qtype + 1, old_pvtx, old_vtocx);
357 else do;
358 tq_info.trp (qtype) = quota_cell.trp;
359
360 tq_info.tup (qtype) = quota_cell.tup;
361 tq_info.received (qtype) = quota_cell.received;
362 end;
363 end;
364 end;
365 end;
366 else tq_infop = null;
367
368 temp_ename = addr (ep -> entry.primary_name) -> names.name;
369 corout_pvtx = 0;
370 optimizing = demand_segmove;
371 if demand_segmove
372 then skip_pvtx = 0;
373 else skip_pvtx = old_pvtx;
374
375 next_pv:
376
377
378
379 same_pvtx, held_pvtx = "0"b;
380 call create_vtoce$createv_for_segmove (ep, pvid, new_vtocx, code, corout_pvtx, skip_pvtx, recs_needed, tq_infop,
381 optimizing);
382
383 Debug
384
385
386
387
388 if code ^= 0
389 then go to move_fails;
390 new_pvtx = corout_pvtx;
391 if optimizing
392 then do;
393 optimizing = "0"b;
394 corout_pvtx = 0;
395 end;
396 new_pvid = pvid;
397 if new_pvtx = old_pvtx
398 then same_pvtx = "1"b;
399 else do;
400 call get_pvtx$hold_pvtx (new_pvid, new_pvtx, code);
401 if code = 0
402 then held_pvtx = "1"b;
403 else go to next_pv;
404 end;
405
406
407 call MOVE_THE_SEGMENT;
408
409 sstp -> sst.good_sgms = sstp -> sst.good_sgms + 1;
410 if ^demand_segmove
411 then
412 call syserr (LOG, "segment_mover: Moved ^w(^a) from ^a to ^a for ^a", move_astep -> aste.uid, temp_ename,
413 diskname (old_pvtx), diskname (new_pvtx), pds$process_group_id);
414 move_astep = null ();
415 call release_pvtxs;
416 call cleanup_dseg_and_meter;
417 a_code = 0;
418 return;
419
420 move_fails:
421 sstp -> sst.bad_sgms = sstp -> sst.bad_sgms + 1;
422 if ^demand_segmove
423 then call syserr$error_code (LOG, code, "segment_mover: Failed to seg move ^w(^a) from ^a for ^a",
424 move_astep -> aste.uid, temp_ename, diskname (old_pvtx), pds$process_group_id);
425 call lock$lock_ast;
426 call thread$cin (move_astep, sst.ausedp (fixed (move_astep -> aste.ptsi, 2)));
427
428 move_astep -> aste.pack_ovfl = "0"b;
429 move_astep -> aste.nqsw = old_nqsw;
430 call search_ast$hash_in (move_astep);
431 call release_pvtxs;
432 call lock$unlock_ast;
433 call cleanup_dseg_and_meter;
434 a_code = code;
435 %page;
436
437
438 MOVE_THE_SEGMENT:
439 procedure;
440 dcl astes (2) pointer;
441 dcl px fixed bin;
442
443 code = 0;
444 call lock$lock_ast;
445
446 do px = 1, 2;
447 astep, astes (px) = get_aste (size_needed);
448 if astes (px) = null ()
449 then do;
450 code = error_table_$log_vol_full;
451 go to retake_fault;
452 end;
453
454 call thread$out (astep, sst.ausedp (fixed (astep -> aste.ptsi, 2)));
455
456 end;
457 astep = null ();
458
459 call lock$unlock_ast;
460
461 astes (1) -> aste.nqsw, astes (1) -> aste.gtms, astes (1) -> aste.gtus = "1"b;
462 astes (2) -> aste.nqsw, astes (2) -> aste.gtms, astes (2) -> aste.gtus = "1"b;
463 astes (2) -> aste.pvtx = new_pvtx;
464
465
466
467
468 n_nulled_pages = 0;
469 depolist = ""b;
470 pageno_list = 0;
471 code = 0;
472
473 call pc$segmove (move_astep, astes (1), astes (2), new_pvtx, new_vtocx, n_nulled_pages, dlp, addr (pageno_list),
474 code);
475
476 Debug
477
478
479
480 call lock$lock_ast;
481 if code ^= 0
482 then do;
483 call put_aste (astes (1));
484 astes (1) = null;
485 call put_aste (astes (2));
486 astes (2) = null ();
487 call lock$unlock_ast;
488 if code = error_table_$log_vol_full
489 then do;
490 call release_pvtxs;
491 go to next_pv;
492 end;
493 else go to move_fails;
494 end;
495
496 call thread$cin (move_astep, sst.ausedp (fixed (move_astep -> aste.ptsi, 2)));
497
498
499 move_astep -> aste.pack_ovfl = "0"b;
500 move_astep -> aste.nqsw = old_nqsw;
501 call search_ast$hash_in (move_astep);
502
503 do astep = astes (1), astes (2);
504 call put_aste (astep);
505 end;
506
507 astep, astes (1), astes (2) = null;
508
509 call lock$unlock_ast;
510 ep -> entry.pvid = pvid;
511 ep -> entry.vtocx = new_vtocx;
512 if ep -> entry.dirsw
513 then do;
514 dp = baseptr (segno);
515 dp -> dir.vtocx = new_vtocx;
516 dp -> dir.pvid = pvid;
517 call sum$dirmod (dp);
518 end;
519 else call sum$dirmod (setwordno (ep, 0));
520 call release_old_vtoce;
521
522 end MOVE_THE_SEGMENT;
523 %page;
524
525 cleanup_dseg_and_meter:
526 procedure;
527
528 if cleanup_must_zero_sdw
529 then do;
530 tsdw = 0;
531 call pmut$swap_sdw (baseptr (segno), addr (tsdw));
532
533 end;
534 call usage_values (pw2, time2);
535 sstp -> sst.sgm_time = sstp -> sst.sgm_time + time2 - time1;
536 sstp -> sst.sgm_pf = sstp -> sst.sgm_pf + pw2 - pw1;
537
538 end cleanup_dseg_and_meter;
539
540
541 diskname:
542 proc (pvtx1) returns (char (9));
543 dcl pic99 pic "99";
544 dcl pvtx1 fixed bin;
545
546 pvtep = addr (pvt_array (pvtx1));
547 pic99 = pvte.logical_area_number;
548 if ^pvte.is_sv
549 then return (pvte.devname || "_" || pic99);
550 else return (pvte.devname || "_" || pic99 || pvte.sv_name);
551
552 end diskname;
553
554
555 release_old_vtoce:
556 procedure;
557 call dbm_man$set_incr (old_pvtx, old_vtocx, ignore);
558 call vtoc_man$free_vtoce (old_pvid, old_pvtx, old_vtocx, code);
559 if code = 0
560 then call truncator (old_pvid, old_pvtx, old_vtocx);
561 else do;
562 call syserr$error_code (0, code, "segment_mover: freeing vtocx ^o on old pvtx ^o", old_vtocx,
563 old_pvtx);
564 pvt_array (old_pvtx).vol_trouble_count = pvt_array (old_pvtx).vol_trouble_count + 1;
565 end;
566
567 end release_old_vtoce;
568
569
570 release_pvtxs:
571 proc;
572 call get_pvtx$release_pvtx (old_pvid, old_pvtx);
573 if held_pvtx
574 then call get_pvtx$release_pvtx (new_pvid, new_pvtx);
575
576 end release_pvtxs;
577
578
579
580
581 truncator:
582 procedure (a_pvid, a_pvtx, a_vtocx);
583
584 dcl (a_pvtx, a_vtocx) fixed bin;
585 dcl a_pvid bit (36) aligned;
586
587 call vtoc_man$await_vtoce (a_pvid, a_pvtx, a_vtocx, code);
588
589 if code = 0
590 then call pc$deposit_list (a_pvtx, n_nulled_pages, dlp, a_vtocx, addr (pageno_list));
591 else do;
592 call syserr$error_code (0, code, "segment_mover: finishing truncation of pvtx ^o vtocx ^o.", a_pvtx,
593 a_vtocx);
594 pvt_array (a_pvtx).vol_trouble_count = pvt_array (a_pvtx).vol_trouble_count + 1;
595 end;
596
597 end truncator;
598
599
600
601
602 %page; %include aste;
603 %page; %include add_type;
604 %page; %include dir_entry;
605 %include dir_header;
606
607 %include dir_name;
608 %page; %include pvte;
609 %page; %include lvt;
610 %page; %include sst;
611 %page; %include tq_info;
612 %page; %include quota_cell;
613 %page; %include syserr_constants;
614 %page;
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772 end segment_mover;