1 /****^  ***********************************************************
  2         *                                                         *
  3         * Copyright, (C) Honeywell Bull Inc., 1987                *
  4         *                                                         *
  5         * Copyright, (C) Honeywell Information Systems Inc., 1982 *
  6         *                                                         *
  7         * Copyright (c) 1972 by Massachusetts Institute of        *
  8         * Technology and Honeywell Information Systems, Inc.      *
  9         *                                                         *
 10         *********************************************************** */
 11 
 12 
 13 
 14 /* format: style3 */
 15 vtoc_attributes$set_dates:
 16      proc (Uid, Pvid, Vtocx, Dtu, Dtm, Code);
 17 
 18 /* VTOC_ATTRIBUTES - segment control interface for directory control.
 19    When DC wishes to set or get items from the VTOC it calls here.
 20 
 21    Entry points are:
 22 
 23    set_dates
 24    set_max_lth
 25    get_info
 26    get_quota
 27    set_quota
 28    reloading
 29    set_pc_switches
 30    set_dump_switches
 31    set_dump_info
 32    correct_qused
 33    salv_update
 34    get_dump_info
 35 
 36 
 37    THVV 4/75
 38 
 39    $reloading added by RE Mullen Autumn 1975
 40    Modified by D. Vinograd 7/76 to update volume dumper bit map so that modified vtoces are dumped.
 41    unlock AST before vtoc read for $get_info:  RE Mullen, Winter 1976
 42    Modified by D. Vinograd 8/76 to add entry to set the volume dumper control switches
 43    $correct_qused - BSG 2/18/77
 44    Modified 7/77 by S.E. Barr to add salv_update entry.
 45    Modified 10/79 by Mike Grady to fix dormat seg time update bug
 46    Modified 11/80 by E. N. Kittlitz to fix race in set_dates (active). Use clock builtin.
 47    Modified 11/80 by E.N. Kittlitz for dtu/dtm change.
 48    Modified 3/82 BIM for expanded sc_info.
 49    Modified 3/82 by J. Bongiovanni to remove vtoce.infqcnt
 50    Modified 8/82 by J. Bongiovanni for new vtoc_man
 51    Modified 9/82 by J. Bongiovanni to do less work under AST lock, fix races
 52    Modified 8/83 by E. N. Kittlitz for search_ast$check
 53    Modified 83-12-01 BIM to not setfault on set_max_length unless necessary.
 54 */
 55 
 56 /*  Parameter  */
 57 
 58 dcl       Code                fixed bin (35) parameter;     /* Return Code */
 59 dcl       Dtd                 bit (36) aligned parameter;   /* File System Date-Time-Dumped */
 60 dcl       Dtm                 bit (36) aligned parameter;   /* File System Date-Time Modified */
 61 dcl       Dtu                 bit (36) aligned parameter;   /* File System Date-Time Used */
 62 dcl       Dudelta             fixed bin (34);               /* Change in directory quota used */
 63 dcl       Msk                 bit (36) aligned;             /* Mask of which PC switches to diddle */
 64 dcl       Mxl                 fixed bin (9) parameter;      /* Maximum Length */
 65 dcl       Ncd                 fixed bin parameter;          /* No-Complete-Dump switch */
 66 dcl       Nid                 fixed bin parameter;          /* No-Incremental-Dump switch */
 67 dcl       Priv_Sw             bit (1) aligned parameter;    /* ON => privileged call */
 68 dcl       Pvid                bit (36) aligned parameter;   /* Physical Volume Unique ID */
 69 dcl       Qcp                 ptr parameter;                /* -> quota info structure */
 70 dcl       Qtype               fixed bin parameter;          /* Type of Quota */
 71 dcl       Salv_Updatep        ptr parameter;                /* -> salvager info structure */
 72 dcl       Scip                ptr parameter;                /* -> status info structure */
 73 dcl       Sudelta             fixed bin (34);               /* Change in segment quota used */
 74 dcl       Sws                 bit (36) aligned;             /* PC switch values */
 75 dcl       Uid                 bit (36) aligned parameter;   /* Segment Unique ID */
 76 dcl       Volid               (3) bit (36) aligned parameter;
 77                                                             /* Dump Volume IDs */
 78 dcl       Vtocx               fixed bin parameter;          /* VTOCE index on volume */
 79 
 80 /*  Automatic  */
 81 
 82 dcl       active              bit (1) aligned;              /* ON => target segment is active */
 83 dcl       add_to_dumper       bit (1) aligned;              /* ON => add to dumper bit map when done */
 84 dcl       ast_is_locked       bit (1) aligned;              /* ON => AST lock held */
 85 dcl       code                fixed bin (35);               /* Error Code */
 86 dcl       code1               fixed bin (35);               /* Another Error Code */
 87 dcl       curtime             fixed bin (71);               /* Used for dtu, dtm computations */
 88 dcl       dtd                 bit (36) aligned;             /* File System Date-Time-Dumped */
 89 dcl       dtm                 bit (36) aligned;             /* File System Date-Time-Modified */
 90 dcl       dtu                 bit (36) aligned;             /* File System Date-Time-Used */
 91 dcl       dudelta             fixed bin (34);               /* Change in directory quota used */
 92 dcl       1 local_aste        aligned like aste;            /* Pseudo-ASTE */
 93 dcl       1 local_quota_cell  aligned like quota_cell;      /* Copy of quota structure */
 94 dcl       1 local_salv_update_info
 95                               aligned like salv_update_info;/* Copy of salvager infor structure */
 96 dcl       1 local_sc_info     aligned like sc_info;         /* Copy of status info structure */
 97 dcl       1 local_vtoce       aligned like vtoce;           /* Copy of VTOCE */
 98 dcl       1 msk               aligned like vtoce_pc_sws;    /* Mask of PC switches to diddle */
 99 dcl       mxl                 fixed bin (9);                /* Maximum length */
100 dcl       mxl_bits            bit (9);                      /* Maximum length */
101 dcl       ncd                 fixed bin;                    /* No-complete-dump switch */
102 dcl       need_vtoce          bit (1) aligned;              /* ON => VTOCE must be read, even if segment active */
103 dcl       nid                 fixed bin;                    /* No-incremental-dump switch */
104 dcl       priv_sw             bit (1) aligned;              /* ON => privileged call */
105 dcl       pvid                bit (36) aligned;             /* Physical Volume Unique ID */
106 dcl       pvtx                fixed bin;                    /* PVT Index of Volume */
107 dcl       qt                  fixed bin;                    /* Quota type index */
108 dcl       qtype               fixed bin;                    /* Quota type */
109 dcl       sudelta             fixed bin (34);               /* Change in segment quota used */
110 dcl       1 sws               aligned like vtoce_pc_sws;    /* PC switch values */
111 dcl       uid                 bit (36) aligned;             /* Segment Unique ID */
112 dcl       update              bit (1) aligned;              /* ON => ASTE or VTOCE is being updated */
113 dcl       volid               (3) bit (36) aligned;         /* Dump volume IDs */
114 dcl       vtocx               fixed bin;                    /* VTOCE index on volume */
115 
116 /*  Static  */
117 
118 dcl       ALL_PARTS           bit (3) int static options (constant) init ("111"b);
119 
120 /*  Based  */
121 
122 dcl       1 Quota_Cell        aligned like quota_cell based (Qcp);
123 dcl       1 Salv_Update_Info  aligned like salv_update_info based (Salv_Updatep);
124 dcl       1 Sc_Info           aligned like sc_info based (Scip);
125 
126 /*  External  */
127 
128 dcl       error_table_$dm_not_enabled
129                               fixed bin (35) external;
130 dcl       error_table_$invalid_max_length
131                               fixed bin (35) external;
132 dcl       error_table_$vtoce_connection_fail
133                               fixed bin (35) external;
134 dcl       sst$dm_enabled      bit (1) aligned external;
135 
136 /*  Entry  */
137 
138 dcl       dbm_man$set_incr    entry (fixed bin, fixed bin, fixed bin (35));
139 dcl       deactivate          entry (ptr, fixed bin (35));
140 dcl       get_pvtx            entry (bit (36) aligned, fixed bin (35)) returns (fixed bin);
141 dcl       lock$lock_ast       entry;
142 dcl       lock$unlock_ast     entry;
143 dcl       quotaw$cu           entry (ptr, fixed bin (34), bit (1) aligned, fixed bin (2), fixed bin (35));
144 dcl       pc$update_incore_fms
145                               entry (ptr);
146 dcl       search_ast$check    entry (bit (36) aligned, bit (36) aligned, fixed bin, fixed bin (35)) returns (ptr);
147 dcl       setfaults           entry (ptr, bit (1) aligned);
148 dcl       vtoc_man$get_vtoce  entry (bit (36) aligned, fixed bin, fixed bin, bit (3), ptr, fixed bin (35));
149 dcl       vtoc_man$put_vtoce  entry (bit (36) aligned, fixed bin, fixed bin, bit (3), ptr, fixed bin (35));
150 
151 /*  Builtin  */
152 
153 dcl       addr                builtin;
154 dcl       bit                 builtin;
155 dcl       clock               builtin;
156 dcl       fixed               builtin;
157 dcl       null                builtin;
158 dcl       string              builtin;
159 dcl       unspec              builtin;
160 %page;
161 /* vtoc_attributes$set_dates - called by set$dates, etc., to set the dtu and
162    dtm of a segment. */
163 
164           dtu = Dtu;
165           dtm = Dtm;
166 
167           call SETUP (Code);
168           if Code ^= 0
169           then return;
170 
171           update = "1"b;
172           add_to_dumper = "1"b;
173 
174           call GET_ASTE_VTOCE (code);
175           if code = 0
176           then do;
177                     call UPDATE_ACTIVE_DT;
178                     if dtu ^= ""b
179                     then aste.dtu = dtu;
180                     if dtm ^= ""b
181                     then aste.dtm = dtm;
182                end;
183 
184           call FINISH (code);
185 
186           Code = code;
187 
188           return;
189 %page;
190 /*  vtoc_attributes$set_max_lth - called by set$max_length to set the maximum
191     length of a segment. Unless Priv_Sw is set, the max length cannot be
192     set to less than the current length. */
193 
194 set_max_lth:
195      entry (Uid, Pvid, Vtocx, Mxl, Priv_Sw, Code);
196 
197           mxl = Mxl;
198           mxl_bits = bit (mxl, 9);
199           priv_sw = Priv_Sw;
200 
201           call SETUP (Code);
202           if Code ^= 0
203           then return;
204 
205           call GET_ASTE_VTOCE (code);
206           if code = 0
207           then do;
208                     if ^priv_sw
209                     then if mxl_bits < aste.csl
210                          then code = error_table_$invalid_max_length;
211                end;
212           if code = 0
213           then if aste.msl ^= mxl_bits
214                then do;
215                          update = "1"b;
216                          add_to_dumper = "1"b;
217                          if active & (mxl_bits < aste.msl)
218                          then call setfaults (astep, "0"b);
219                          aste.msl = mxl_bits;
220                     end;
221 
222           call FINISH (code);
223 
224           Code = code;
225 
226           return;
227 %page;
228 /*  vtoc_attributes$get_info - called by status_ to get the dates and lengths
229     from the VTOCE */
230 
231 get_info:
232      entry (Uid, Pvid, Vtocx, Scip, Code);
233 
234           call SETUP (Code);
235           if Code ^= 0
236           then return;
237 
238           unspec (local_sc_info) = ""b;
239 
240           call GET_ASTE_VTOCE (code);
241           if code = 0
242           then do;
243                     call UPDATE_ACTIVE_DT;
244                     local_sc_info.dtu = aste.dtu;
245                     local_sc_info.dtm = aste.dtm;
246                     local_sc_info.records = fixed (aste.records, 9);
247                     local_sc_info.msl = fixed (aste.msl, 9) * 1024;
248                     local_sc_info.csl = fixed (aste.csl, 9) * 1024;
249                     local_sc_info.dnzp = aste.dnzp;
250                     local_sc_info.damaged = aste.damaged;
251                     local_sc_info.synchronized = aste.synchronized;
252                     if aste.dirsw
253                     then local_sc_info.pf_count = 0;
254                     else local_sc_info.pf_count = seg_aste.usage;
255 
256                     local_sc_info.nid = "0"b;
257                     local_sc_info.ncd = "0"b;
258                     local_sc_info.vol_dtd = ""b;
259                     local_sc_info.volid (*) = ""b;
260 
261                     if aste.dirsw
262                     then do qt = 0, 1;
263                               local_sc_info.qcell (qt).quota = aste.quota (qt);
264                               local_sc_info.qcell (qt).used = aste.used (qt);
265                               local_sc_info.qcell (qt).terminal_quota_sw = aste.tqsw (qt);
266                               local_sc_info.qcell (qt).received = 0;
267                               local_sc_info.qcell (qt).tup = ""b;
268                               local_sc_info.qcell (qt).trp = 0;
269                          end;
270                end;
271 
272           call FINISH (code);
273 
274           if code = 0
275           then Sc_Info = local_sc_info;
276           else unspec (Sc_Info) = ""b;
277 
278           Code = code;
279 
280           return;
281 %page;
282 /*  vtoc_attributes$get_quota - called by quota to get the quota account. */
283 
284 get_quota:
285      entry (Uid, Pvid, Vtocx, Qcp, Qtype, Code);
286 
287           qtype = Qtype;
288 
289           call SETUP (Code);
290           if Code ^= 0
291           then return;
292 
293           need_vtoce = "1"b;
294           unspec (local_quota_cell) = ""b;
295 
296           call GET_ASTE_VTOCE (code);
297           if code = 0
298           then do;
299                     local_quota_cell.quota = aste.quota (qtype);
300                     local_quota_cell.used = aste.used (qtype);
301                     local_quota_cell.terminal_quota_sw = aste.tqsw (qtype);
302                     local_quota_cell.received = vtoce.received (qtype);
303                     local_quota_cell.tup = vtoce.trp_time (qtype);
304                     local_quota_cell.trp = vtoce.trp (qtype);
305                end;
306 
307           call FINISH (code);
308 
309           if code = 0
310           then Quota_Cell = local_quota_cell;
311           else unspec (Quota_Cell) = ""b;
312 
313           Code = code;
314 
315           return;
316 %page;
317 /*  vtoc_attributes$set_quota - called by quota to meddle with the quota account.
318     This is a moderate crock, as it must know whether the segment is active.
319     The reason for this is that the quota cells are protected by the PTL
320     and are updated by quota earlier. This just updates the VTOCE.
321 */
322 
323 set_quota:
324      entry (Uid, Pvid, Vtocx, Qcp, Qtype, Code);
325 
326           qtype = Qtype;
327           local_quota_cell = Quota_Cell;
328 
329           call SETUP (Code);
330           if Code ^= 0
331           then return;
332 
333           need_vtoce = "1"b;
334           update = "1"b;
335           add_to_dumper = "1"b;
336 
337           call GET_ASTE_VTOCE (code);
338           if code = 0
339           then do;
340                     if ^active
341                     then do;
342                               aste.quota (qtype) = local_quota_cell.quota;
343                               aste.used (qtype) = local_quota_cell.used;
344                          end;
345                     vtoce.received (qtype) = local_quota_cell.received;
346                     vtoce.trp_time (qtype) = local_quota_cell.tup;
347                     vtoce.trp (qtype) = local_quota_cell.trp;
348                end;
349 
350           call FINISH (code);
351 
352           Code = code;
353 
354           return;
355 %page;
356 /*  vtoc_attributes$reloading - called by set$set_for_reloader */
357 
358 reloading:
359      entry (Uid, Pvid, Vtocx, Dtu, Dtm, Mxl, Code);
360 
361           dtu = Dtu;
362           dtm = Dtm;
363           mxl = Mxl;
364           mxl_bits = bit (mxl, 9);
365 
366           call SETUP (Code);
367           if Code ^= 0
368           then return;
369 
370           update = "1"b;
371           add_to_dumper = "1"b;
372 
373           call GET_ASTE_VTOCE (code);
374           if code = 0
375           then do;
376                     if dtu ^= ""b
377                     then aste.dtu = dtu;
378                     if dtm ^= ""b
379                     then aste.dtm = dtm;
380                     if (mxl >= 0) & (mxl_bits ^= aste.msl)  /* use FB to preserve the sign bit! */
381                     then do;
382                               if active & (mxl_bits < aste.msl)
383                               then call setfaults (astep, "0"b);
384                               aste.msl = mxl_bits;
385                          end;
386                end;
387 
388           call FINISH (code);
389 
390           Code = code;
391 
392           return;
393 %page;
394 /*  vtoc_attributes$set_pc_switches */
395 
396 set_pc_switches:
397      entry (Uid, Pvid, Vtocx, Sws, Msk, Code);
398 
399           string (sws) = Sws;
400           string (msk) = Msk;
401 
402           if msk.synchronized & sws.synchronized
403           then if ^sst$dm_enabled
404                then do;
405                          Code = error_table_$dm_not_enabled;
406                          return;
407                     end;
408 
409           call SETUP (Code);
410           if Code ^= 0
411           then return;
412 
413           update = "1"b;
414           add_to_dumper = "1"b;
415 
416 RETRY_SET:
417           call GET_ASTE_VTOCE (code);
418           if (code = 0) & active
419           then if (msk.synchronized & ^aste.synchronized)
420                then do;
421                          call deactivate (astep, code);
422                          if code = 0
423                          then do;
424                                    call lock$unlock_ast;
425                                    ast_is_locked = "0"b;
426                                    active = "0"b;
427                                    goto RETRY_SET;
428                               end;
429                     end;
430           if code = 0
431           then do;
432                     if msk.dnzp
433                     then aste.dnzp = sws.dnzp;
434                     if msk.damaged
435                     then aste.damaged = sws.damaged;
436                     if msk.synchronized
437                     then aste.synchronized = sws.synchronized;
438                end;
439 
440           call FINISH (code);
441 
442           Code = code;
443 
444           return;
445 %page;
446 /*  vtoc_attributes$set_dump_switches
447      switch values - negative => reset, zero => don't change, positive => set */
448 
449 set_dump_switches:
450      entry (Uid, Pvid, Vtocx, Nid, Ncd, Code);
451 
452           nid = Nid;
453           ncd = Ncd;
454 
455           call SETUP (Code);
456           if Code ^= 0
457           then return;
458 
459           update = "1"b;
460           need_vtoce = "1"b;
461           add_to_dumper = "1"b;
462 
463           call GET_ASTE_VTOCE (code);
464           if code = 0
465           then do;
466                     aste.nid = (aste.nid & (nid = 0)) | (nid > 0);
467                     vtoce.ncd = (vtoce.ncd & (ncd = 0)) | (ncd > 0);
468                end;
469 
470           call FINISH (code);
471 
472           return;
473 %page;
474 /*  vtoc_attributes$set_dump_info */
475 
476 set_dump_info:
477      entry (Uid, Pvid, Vtocx, Dtd, Volid, Code);
478 
479           dtd = Dtd;
480           volid (*) = Volid (*);
481 
482           call SETUP (Code);
483           if Code ^= 0
484           then return;
485 
486           update = "1"b;
487           need_vtoce = "1"b;
488           add_to_dumper = "1"b;
489 
490           call GET_ASTE_VTOCE (code);
491           if code = 0
492           then do;
493                     vtoce.dtd = dtd;
494                     vtoce.volid (*) = volid (*);
495                end;
496 
497           call FINISH (code);
498 
499           Code = code;
500 
501           return;
502 %page;
503 /*  vtoc_attributes$get_dump_info  */
504 
505 get_dump_info:
506      entry (Uid, Pvid, Vtocx, Dtd, Volid, Code);
507 
508           call SETUP (Code);
509           if Code ^= 0
510           then return;
511 
512           need_vtoce = "1"b;
513 
514           call GET_ASTE_VTOCE (code);
515           if code = 0
516           then do;
517                     dtd = vtoce.dtd;
518                     volid (*) = vtoce.volid (*);
519                end;
520 
521           call FINISH (code);
522 
523           if code = 0
524           then do;
525                     Dtd = dtd;
526                     Volid (*) = volid (*);
527                end;
528 
529           Code = code;
530 
531           return;
532 %page;
533 /*  vtoc_attributes$correct_qused - called by adjust_qused to make final correction */
534 
535 correct_qused:
536      entry (Uid, Pvid, Vtocx, Sudelta, Dudelta, Code);
537 
538           sudelta = Sudelta;
539           dudelta = Dudelta;
540           code1 = 0;
541 
542           call SETUP (Code);
543           if Code ^= 0
544           then return;
545 
546           update = "1"b;
547           add_to_dumper = "1"b;
548 
549           call GET_ASTE_VTOCE (code);
550           if code = 0
551           then do;
552                     if active
553                     then do;
554                               if sudelta ^= 0
555                               then call quotaw$cu (astep, sudelta, "0"b, 2, code1);
556                               if dudelta ^= 0
557                               then call quotaw$cu (astep, dudelta, "1"b, 2, code1);
558                          end;
559                     else do;
560                               aste.used (0) = aste.used (0) + sudelta;
561                               aste.used (1) = aste.used (1) + dudelta;
562                          end;
563                end;
564 
565           if code = 0
566           then code = code1;
567 
568           call FINISH (code);
569 
570           Code = code;
571 
572           return;
573 %page;
574 /*  vtoc_attributes$salv_update - called by the directory salvager to update
575     the VTOCE when VTOCE checking. */
576 
577 salv_update:
578      entry (Uid, Pvid, Vtocx, Salv_Updatep, Code);
579 
580           local_salv_update_info = Salv_Update_Info;
581 
582           call SETUP (Code);
583           if Code ^= 0
584           then return;
585 
586           need_vtoce = local_salv_update_info.set_uid_path | local_salv_update_info.set_primary_name;
587           update = "1"b;
588 
589           call GET_ASTE_VTOCE (code);
590           if code = 0
591           then do;
592                     if local_salv_update_info.set_master_dir
593                     then aste.master_dir = local_salv_update_info.master_dir;
594                     if local_salv_update_info.set_primary_name
595                     then vtoce.primary_name = local_salv_update_info.primary_name;
596                     if local_salv_update_info.set_uid_path
597                     then vtoce.uid_path = local_salv_update_info.uid_path;
598                end;
599 
600           call FINISH (code);
601 
602           Code = code;
603 
604           return;
605 %page;
606 /*  vtoc_attributes$get_dump_switches  */
607 
608 get_dump_switches:
609      entry (Uid, Pvid, Vtocx, Nid, Ncd, Code);
610 
611           nid, ncd = 0;
612 
613           call SETUP (Code);
614           if Code ^= 0
615           then return;
616 
617           need_vtoce = "1"b;
618 
619           call GET_ASTE_VTOCE (code);
620           if code = 0
621           then do;
622                     if aste.nid
623                     then nid = 1;
624                     else nid = -1;
625                     if vtoce.ncd
626                     then ncd = 1;
627                     else ncd = -1;
628                end;
629 
630           call FINISH (code);
631 
632           if code = 0
633           then do;
634                     Nid = nid;
635                     Ncd = ncd;
636                end;
637 
638           Code = code;
639 
640           return;
641 
642 
643 %page;
644 /*  Internal Procedure to set automatic variables, translate Physical Volume
645     Unique ID to PVT Index.
646 */
647 
648 SETUP:
649      proc (Code);
650 
651 dcl       Code                fixed bin (35) parameter;
652 
653           Code = 0;
654           ast_is_locked = "0"b;
655           active = "0"b;
656           need_vtoce = "0"b;
657           update = "0"b;
658           add_to_dumper = "0"b;
659           uid = Uid;
660           pvid = Pvid;
661           vtocx = Vtocx;
662           vtocep = addr (local_vtoce);
663           pvtx = get_pvtx (pvid, Code);
664 
665      end SETUP;
666 %page;
667 /*  Internal Procedure to get a pointer to the ASTE and to read the VTOCE
668     if necessary.
669 
670     On return, astep points to the ASTE (if the segment is active), or to
671     a pseudo-ASTE in automatic storage. In the latter case, relevant
672     VTOCE fields have been updated into the pseudo-ASTE so that caller
673     can work with it, and not be concerned about whether the segment
674     is active. Any modifications to the pseudo-ASTE will be reflected into
675     the VTOCE in FINISH.
676 
677     The AST lock protects against activation or deactivation, and ensures
678     that the copy of the VTOCE is the latest one. To avoid doing I/O
679     under the AST lock, the following strategy is used:
680 
681           call vtoc_man$get_vtoce with the AST unlocked
682 
683           lock the AST
684 
685           call vtoc_man$get_vtoce again (this will probably not cause
686               an I/O, due to the way vtoc_man works)
687 
688     This routine uses/sets the following global flags:
689 
690           need_vtoce - will read VTOCE even if segment is active (used)
691 
692           ast_is_locked - what it says (set)
693 
694           active - ON if segment is active (set)
695 
696 */
697 
698 GET_ASTE_VTOCE:
699      proc (Code);
700 
701 dcl       Code                fixed bin (35) parameter;
702 
703 dcl       vtoce_read          bit (1) aligned;              /* ON => we have read the VTOCE */
704 
705 
706           Code = 0;
707           vtoce_read = "0"b;
708           unspec (vtoce) = ""b;
709 
710           if need_vtoce
711           then do;
712                     call vtoc_man$get_vtoce (""b, pvtx, vtocx, ALL_PARTS, vtocep, Code);
713                     if Code ^= 0
714                     then return;
715                     vtoce_read = "1"b;
716                end;
717 
718           call lock$lock_ast;
719           ast_is_locked = "1"b;
720           astep = search_ast$check (uid, pvid, vtocx, Code);
721           if Code ^= 0
722           then do;
723                     call lock$unlock_ast;
724                     ast_is_locked = "0"b;                   /* well, it's true, isn't it? */
725                     return;
726                end;
727 
728 
729           if astep = null () & ^vtoce_read
730           then do;
731                     call lock$unlock_ast;
732                     ast_is_locked = "0"b;
733                     call vtoc_man$get_vtoce (""b, pvtx, vtocx, ALL_PARTS, vtocep, Code);
734                     if Code ^= 0
735                     then return;
736                     vtoce_read = "1"b;
737                     call lock$lock_ast;
738                     ast_is_locked = "1"b;
739                     astep = search_ast$check (uid, pvid, vtocx, Code);
740                     if Code ^= 0
741                     then do;
742                               call lock$unlock_ast;
743                               ast_is_locked = "0"b;
744                               return;
745                          end;
746                end;
747 
748           if (astep = null ()) | need_vtoce
749           then do;
750                     call vtoc_man$get_vtoce (""b, pvtx, vtocx, ALL_PARTS, vtocep, Code);
751                     if Code ^= 0
752                     then do;
753 VTOCE_ERROR:
754                               call lock$unlock_ast;
755                               ast_is_locked = "0"b;
756                               return;
757                          end;
758                     if vtoce.uid ^= uid
759                     then do;
760                               Code = error_table_$vtoce_connection_fail;
761                               goto VTOCE_ERROR;
762                          end;
763                end;
764 
765           if astep ^= null ()
766           then active = "1"b;
767           else do;
768                     astep = addr (local_aste);
769                     call VTOCE_TO_ASTE;
770                end;
771 
772 
773      end GET_ASTE_VTOCE;
774 %page;
775 /*  Internal Procedure to clean up by unlocking and updating whatever
776     is necessary.
777 
778     This routine uses the following global flags:
779 
780          ast_is_locked
781 
782          active
783 
784          update
785 
786          need_vtoce
787 
788 */
789 
790 FINISH:
791      proc (Code);
792 
793 dcl       Code                fixed bin (35) parameter;
794 
795 
796 dcl       code                fixed bin (35);
797 dcl       code1               fixed bin (35);
798 
799 
800           code, code1 = 0;
801 
802           if ^active & update & (astep ^= null ())
803           then call ASTE_TO_VTOCE;
804 
805           if add_to_dumper & (Code = 0)
806           then if ^vtoce.nid & ^vtoce.per_process & ^vtoce.deciduous & ^vtoce.per_bootload
807                then call dbm_man$set_incr (pvtx, vtocx, code);
808 
809           if update & (Code = 0)
810           then if ^active | need_vtoce
811                then call vtoc_man$put_vtoce (""b, pvtx, vtocx, ALL_PARTS, vtocep, code1);
812 
813           if ast_is_locked
814           then call lock$unlock_ast;
815           ast_is_locked = "0"b;
816 
817           if Code = 0
818           then if code ^= 0
819                then Code = code;
820                else Code = code1;
821 
822      end FINISH;
823 %page;
824 /*  Internal Procedure to update a pseudo-ASTE into a VTOCE */
825 
826 ASTE_TO_VTOCE:
827      proc;
828 
829 dcl       i                   fixed bin;
830 
831 
832           vtoce.msl = aste.msl;
833           vtoce.csl = aste.csl;
834           vtoce.dtu = aste.dtu;
835           vtoce.dtm = aste.dtm;
836           vtoce.nqsw = aste.nqsw;
837           vtoce.deciduous = aste.hc_sdw;
838           vtoce.damaged = aste.damaged;
839           vtoce.synchronized = aste.synchronized;
840           vtoce.dnzp = aste.dnzp;
841           vtoce.nid = aste.nid;
842           vtoce.dirsw = aste.dirsw;
843 
844           if aste.dirsw
845           then do;
846                     vtoce.master_dir = aste.master_dir;
847                     do i = 0, 1;
848                          vtoce.used (i) = aste.used (i);
849                          vtoce.quota (i) = aste.quota (i);
850                     end;
851                end;
852 
853      end ASTE_TO_VTOCE;
854 %page;
855 /*  Internal Procedure to fill in the fields of a pseudo-ASTE from a VTOCE */
856 
857 VTOCE_TO_ASTE:
858      proc;
859 
860 dcl       i                   fixed bin;
861 
862 
863           unspec (aste) = ""b;
864 
865           aste.uid = vtoce.uid;
866           aste.msl = vtoce.msl;
867           aste.csl = vtoce.csl;
868           aste.records = vtoce.records;
869           aste.dtu = vtoce.dtu;
870           aste.dtm = vtoce.dtm;
871           aste.nqsw = vtoce.nqsw;
872           aste.hc_sdw = vtoce.deciduous;
873           aste.per_process = vtoce.per_process;
874           aste.damaged = vtoce.damaged;
875           aste.synchronized = vtoce.synchronized;
876           aste.dnzp = vtoce.dnzp;
877           aste.nid = vtoce.nid;
878           aste.dirsw = vtoce.dirsw;
879           aste.pvtx = pvtx;
880           aste.vtocx = vtocx;
881 
882           if aste.dirsw
883           then do;
884                     aste.master_dir = vtoce.master_dir;
885                     do i = 0, 1;
886                          aste.quota (i) = vtoce.quota (i);
887                          aste.used (i) = vtoce.used (i);
888                     end;
889                     aste.tqsw (0) = (vtoce.received (0) ^= 0) | aste.master_dir;
890                     aste.tqsw (1) = (vtoce.received (1) ^= 0);
891                end;
892           else seg_aste.usage = seg_vtoce.usage;
893 
894      end VTOCE_TO_ASTE;
895 %page;
896 /*  Internal Procedure to Update date-time-used and date-time modified. */
897 
898 UPDATE_ACTIVE_DT:
899      proc;
900 
901           curtime = clock ();
902 
903           if (aste.np ^= ""b)
904           then call pc$update_incore_fms (astep);           /* Update modification if noted */
905           if aste.fms
906           then do;
907                     add_to_dumper = "1"b;
908                     aste.fms = "0"b;
909                end;
910           if ^aste.gtus
911           then if ((aste.np ^= ""b) | (aste.infp ^= ""b))   /* pages in, or inferior ASTEs */
912                then aste.dtu = bit (fixed (curtime, 52), 52);
913                                                             /* it's in-use */
914 
915      end UPDATE_ACTIVE_DT;
916 
917 
918 /* format: off */
919 %page; %include aste;
920 %page; %include quota_cell;
921 %page; %include sc_info;
922 %page; %include vtoce;
923 %page; %include vtoce_pc_sws;
924 %page; %include vtoce_salv_update;
925 
926      end vtoc_attributes$set_dates;