1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 truncate_vtoce: proc (branchp, first_page, code);
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 %page;
65
66 dcl branchp ptr;
67 dcl code fixed bin (35);
68 dcl first_page fixed bin (17);
69
70 dcl csl fixed bin;
71 dcl deleting bit (1) init ("0"b);
72 dcl 1 deposit aligned,
73 2 list (256) bit (22) aligned;
74 dcl dir_must_be_unlocked bit (1);
75 dcl event_count fixed bin;
76 dcl first fixed bin;
77 dcl hold bit (1) init ("0"b);
78 dcl i fixed bin;
79 dcl 1 local_vtoce like vtoce aligned;
80 dcl multi_class bit (1) aligned;
81 dcl n fixed bin;
82 dcl normal bit (1) aligned;
83 dcl page_count fixed bin;
84 dcl pageno_list (256) fixed bin aligned;
85 dcl par_astep ptr;
86 dcl par_dp ptr;
87 dcl par_ep ptr;
88 dcl par_pvid bit (36) aligned;
89 dcl par_uid bit (36) aligned;
90 dcl par_vtocx fixed bin;
91 dcl pvid bit (36) aligned;
92 dcl pvtx fixed bin;
93 dcl uid bit (36) aligned;
94 dcl vtocx fixed bin;
95
96 dcl error_table_$mylock fixed bin (35) external;
97 dcl error_table_$vtoce_connection_fail fixed bin (35) external;
98 dcl pds$throttle_segment_state_changes bit (1) aligned external;
99 dcl sst$checksum_filemap fixed bin (35) external;
100
101 dcl activate entry (ptr, fixed bin (35)) returns (ptr);
102 dcl dbm_man$set_incr entry (fixed bin, fixed bin, fixed bin (35));
103 dcl filemap_checksum_ entry (ptr, fixed bin, bit (36) aligned);
104 dcl get_pvtx entry (bit (36) aligned, fixed bin (35)) returns (fixed bin);
105 dcl get_pvtx$hold_pvtx entry (bit (36) aligned, fixed bin, fixed bin (35));
106 dcl get_pvtx$release_pvtx entry (bit (36) aligned, fixed bin);
107 dcl limit_covert_channel entry (fixed bin);
108 dcl lock$dir_unlock entry (ptr);
109 dcl lock$lock_ast entry;
110 dcl lock$unlock_ast entry;
111 dcl pc$deposit_list entry (fixed bin, fixed bin, ptr, fixed bin, ptr);
112 dcl pc$truncate entry (ptr, fixed bin);
113 dcl pc$updates entry (ptr);
114 dcl quotaw$cu entry (ptr, fixed bin, bit (1), fixed bin, fixed bin (35));
115 dcl search_ast$check entry (bit (36) aligned, bit (36) aligned, fixed bin, fixed bin (35)) returns (ptr);
116 dcl sum$getbranch_root_my entry (ptr, bit (1), ptr, fixed bin (35));
117 dcl syserr entry options (variable);
118 dcl vtoc_man$await_vtoce entry (bit (36) aligned, fixed bin, fixed bin, fixed bin (35));
119 dcl vtoc_man$get_vtoce entry (bit (36) aligned, fixed bin, fixed bin, bit (3), ptr, fixed bin (35));
120 dcl vtoc_man$put_vtoce entry (bit (36) aligned, fixed bin, fixed bin, bit (3), ptr, fixed bin (35));
121
122 dcl (addr, bit, clock, fixed, min, null, ptr, substr) builtin;
123
124 %page;
125 first = first_page;
126 go to join;
127 hold: entry (branchp, first_page, code);
128 first = first_page;
129 hold = "1"b;
130 goto join;
131 truncate_vtoce_delete: entry (branchp, code);
132 deleting = "1"b;
133 first = 0;
134 join:
135
136
137
138 normal = ^(deleting | hold);
139 ep = branchp;
140 code = 0;
141
142 uid = entry.uid;
143 pvid = entry.pvid;
144 pvtx = get_pvtx (pvid, code); if code ^= 0 then return;
145 vtocx = entry.vtocx;
146 multi_class = entry.multiple_class;
147 event_count = 0;
148
149
150
151 call lock$lock_ast;
152
153 astep = search_ast$check (uid, pvid, vtocx, (0));
154
155 if astep ^= null then do;
156 if aste.hc_sdw then call syserr (CRASH, "truncate_vtoce: attempt to destroy hc_sdw seg astep ^p", astep);
157 csl = fixed (aste.csl);
158 call pc$truncate (astep, first);
159 if first = 0 then do;
160 if aste.damaged then aste.fmchanged = "1"b;
161 aste.damaged = "0"b;
162 aste.fm_damaged = "0"b;
163 end;
164 call lock$unlock_ast;
165 if ^deleting & hold then call get_pvtx$hold_pvtx (pvid, pvtx, code);
166 go to covert_test;
167 end;
168
169 call lock$unlock_ast;
170
171
172
173 NOTE
174
175 vtocep = addr (local_vtoce);
176
177 call vtoc_man$get_vtoce (pvid, pvtx, vtocx, "111"b, vtocep, code);
178 if code ^= 0 then return;
179
180 if uid ^= vtoce.uid then do;
181 code = error_table_$vtoce_connection_fail;
182 return;
183 end;
184
185 csl = fixed (vtoce.csl);
186
187 if ^deleting then call get_pvtx$hold_pvtx (pvid, pvtx, code);
188 if code ^= 0 then return;
189
190
191
192
193
194 n = 0;
195 do i = first to csl - 1;
196 if substr (vtoce.fm (i), 1, 1) = "0"b then do;
197 n = n + 1;
198 deposit.list (n) = vtoce.fm (i);
199 pageno_list (n) = i;
200 vtoce.fm (i) = truncate_vtoce_null_addr;
201 end;
202 end;
203
204 if vtoce.fm_damaged & (sst$checksum_filemap ^= 0)
205 then n = 0;
206
207 vtoce.csl = bit (fixed (min (first, csl), 9), 9);
208 if first = 0 then do;
209 vtoce.records = "0"b;
210 vtoce.damaged = "0"b;
211 vtoce.fm_damaged = "0"b;
212 end;
213 else vtoce.records = bit (fixed (fixed (vtoce.records, 9) - n, 9), 9);
214
215 if sst$checksum_filemap = 0 then do;
216 vtoce.fm_damaged = "0"b;
217 vtoce.fm_checksum_valid = "0"b;
218 vtoce.fm_checksum = ""b;
219 end;
220 else do;
221 vtoce.fm_checksum_valid = "1"b;
222 call filemap_checksum_ (addr (vtoce.fm), fixed (vtoce.csl, 9), vtoce.fm_checksum);
223 end;
224
225 if vtoce.dirsw then
226 if ^vtoce.deciduous then
227 vtoce.used (1) = vtoce.used (1) - n;
228
229
230
231
232
233
234
235 if normal then do;
236 vtoce.dtm, vtoce.dtu = bit (fixed (clock (), 52), 52);
237 if multi_class then event_count = 2;
238 else event_count = 1;
239 end;
240
241 call vtoc_man$put_vtoce ("0"b, pvtx, vtocx, "111"b, vtocep, code);
242 if code ^= 0 then go to release;
243
244 if deleting | (^deleting & ^vtoce.per_process & ^vtoce.deciduous) then
245 call dbm_man$set_incr (pvtx, vtocx, code);
246
247
248
249
250
251 if n = 0 then go to release;
252
253 if ^vtoce.deciduous then do;
254 call vtoc_man$await_vtoce ("0"b, pvtx, vtocx, code);
255 if code ^= 0 then go to release;
256 call pc$deposit_list (pvtx, (n), addr (deposit.list), vtocx, addr (pageno_list));
257 end;
258
259 release:
260 if normal then call get_pvtx$release_pvtx (pvid, pvtx);
261
262
263 if entry.owner = "111111111111111111111111111111111000"b then return;
264
265
266 dp = ptr (ep, 0);
267 par_uid = dir.uid;
268 par_pvid = dir.pvid;
269 par_vtocx = dir.vtocx;
270 dir_must_be_unlocked = "0"b;
271
272 call lock$lock_ast;
273
274 par_astep = search_ast$check (par_uid, par_pvid, par_vtocx, code);
275 if code ^= 0 then do;
276 call lock$unlock_ast;
277 return;
278 end;
279
280 if par_astep = null then do;
281 call lock$unlock_ast;
282
283 call sum$getbranch_root_my (dp, "0"b, par_ep, code);
284
285 if code = 0 then dir_must_be_unlocked = "1"b;
286 else if code = error_table_$mylock then code = 0; else return;
287
288 par_dp = ptr (par_ep, 0);
289 par_astep = activate (par_ep, code);
290
291 if code ^= 0 then do;
292 if dir_must_be_unlocked then call lock$dir_unlock (par_dp);
293 return;
294 end;
295 end;
296
297 if ^vtoce.deciduous then do;
298 if vtoce.dirsw then
299 if vtoce.received (1) = 0 then
300 call quotaw$cu (par_astep, (-n), "1"b, 0, code);
301 else ;
302 else call quotaw$cu (par_astep, (-n), "0"b, 0, code);
303 if normal then call pc$updates (par_astep);
304 end;
305 call lock$unlock_ast;
306
307 if dir_must_be_unlocked then call lock$dir_unlock (par_dp);
308 %page;
309 covert_test:
310 if ^normal then return;
311
312
313
314 if ^pds$throttle_segment_state_changes then return;
315 if multi_class then do;
316
317
318
319
320 csl = csl - first;
321 if csl > 0 then do;
322 page_count = 1;
323 do event_count = event_count repeat event_count + 1 while (page_count <= csl);
324 page_count = page_count * 2;
325 end;
326 end;
327 end;
328
329 if event_count > 0 then call limit_covert_channel (event_count);
330 return;
331
332
333
334 %page; %include aste;
335 %page; %include dir_entry;
336 %page; %include dir_header;
337 %page; %include null_addresses;
338 %page; %include syserr_constants;
339 %page; %include vtoce;
340 %page;
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361 end truncate_vtoce;