1
2
3
4
5
6
7
8
9
10
11
12
13
14 sum:
15 procedure;
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 dcl a_code fixed bin (35);
48 dcl a_dp ptr;
49 dcl a_ep ptr;
50 dcl a_segptr ptr;
51 dcl a_type_lock bit (36) aligned;
52
53
54
55 dcl code fixed bin (35);
56 dcl dtm_changed bit (1) aligned;
57 dcl lsw bit (1) aligned;
58 dcl my_lock_entry bit (1) aligned init ("0"b);
59 dcl old_dtm bit (36) aligned;
60 dcl segptr ptr;
61 dcl target_dp ptr;
62 dcl type_lock bit (36) aligned;
63
64
65
66 dcl error_table_$mylock fixed bin (35) ext;
67 dcl error_table_$root fixed bin (35) ext;
68 dcl error_table_$seg_deleted
69 fixed bin (35) external static;
70 dcl pds$throttle_segment_state_changes
71 bit (1) aligned external static;
72 dcl 1 pds$transparent external aligned,
73 ( 2 m bit (1),
74 2 u bit (1)
75 ) unaligned;
76
77
78
79 dcl activate ext entry (ptr, fixed bin (35)) returns (ptr);
80 dcl get_kstep ext entry (fixed bin (17), ptr, fixed bin (35));
81 dcl limit_covert_channel entry (fixed bin);
82 dcl lock$dir_unlock external entry (ptr);
83 dcl lock$dir_wait external entry (ptr, bit (36) aligned, fixed bin (35));
84 dcl lock$lock_ast entry;
85 dcl lock$unlock_ast entry;
86 dcl pc$updates external entry (ptr);
87 dcl syserr external entry options (variable);
88
89
90
91 dcl (addr, baseno, fixed, null, pointer, ptr)
92 builtin;
93
94 dcl (bad_dir_, fixedoverflow)
95 condition;
96 %page;
97 getbranch_root_my:
98 entry (a_segptr, a_type_lock, a_ep, a_code);
99
100
101
102 my_lock_entry = "1"b;
103
104 getbranch:
105 entry (a_segptr, a_type_lock, a_ep, a_code);
106
107
108
109 segptr = a_segptr;
110 type_lock = a_type_lock;
111 a_code = 0;
112 a_ep = null ();
113 call get_kstep (fixed (baseno (segptr), 17), kstep, code);
114 if code ^= 0
115 then call abort (code);
116
117 if kstep -> kste.uid = (36)"1"b
118 then call abort (error_table_$root);
119
120 dp = ptr (kste.entryp, 0);
121 lsw = "1"b;
122 call lock$dir_wait (dp, type_lock, code);
123 if code ^= 0
124 then if code ^= error_table_$mylock
125 then call abort (code);
126 else if my_lock_entry
127 then do;
128 lsw = "0"b;
129 a_code = code;
130 end;
131 else call syserr (CRASH, "sum: mylock error on ^p", dp);
132
133 ep = validate_entryp (kstep, code);
134 if ep = null ()
135 then do;
136 call unlock ();
137 call abort (code);
138 end;
139 a_ep = ep;
140 return;
141 %page;
142 dirmod:
143 entry (a_dp);
144
145
146
147 if pds$transparent.m = "1"b
148 then return;
149 target_dp = a_dp;
150 on fixedoverflow
151 begin;
152 target_dp -> dir.change_pclock = 0;
153 go to clocked;
154 end;
155
156 (fixedoverflow):
157 target_dp -> dir.change_pclock = target_dp -> dir.change_pclock + 1;
158
159 clocked:
160 call get_kstep (fixed (baseno (target_dp), 17), kstep, code);
161 if code ^= 0
162 then return;
163 if kstep -> kste.uid = (36)"1"b
164 then do;
165 call lock$lock_ast;
166 astep = addr (sst_seg$) -> sst.root_astep;
167
168 end;
169 else do;
170 ep = validate_entryp (kstep, (0));
171 if ep = null
172 then return;
173 astep = activate (ep, code);
174
175 if astep = null
176 then call syserr (CRASH, "sum: dirmod failed to activate ^p", ep);
177 end;
178 aste.gtms = "0"b;
179 old_dtm = aste.dtm;
180 call pc$updates (astep);
181 dtm_changed = (old_dtm ^= aste.dtm);
182 aste.gtms = "1"b;
183 call lock$unlock_ast;
184 if pds$throttle_segment_state_changes
185 then if dtm_changed
186 then call limit_covert_channel (1);
187 return;
188 %page;
189 unlock:
190 proc ();
191 if lsw
192 then call lock$dir_unlock (dp);
193 end unlock;
194
195 abort:
196 proc (code);
197 dcl code fixed bin (35);
198 a_code = code;
199 go to non_local_return;
200 end abort;
201
202 non_local_return:
203 return;
204 %page;
205 validate_entryp:
206 procedure (a_kstep, a_code) returns (pointer);
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238 dcl a_code fixed bin (35) parameter;
239 dcl a_kstep pointer parameter;
240
241
242
243 dcl dp pointer;
244 dcl entries_in_dir fixed bin;
245 dcl entries_seen fixed bin;
246 dcl ep pointer;
247 dcl kstep pointer;
248 dcl np pointer;
249 dcl rep bit (18) aligned;
250 dcl uid bit (36) aligned;
251 %page;
252 kstep = a_kstep;
253 uid = kstep -> kste.uid;
254 ep = kstep -> kste.entryp;
255 dp = pointer (ep, 0);
256 np = addr (ep -> entry.primary_name);
257
258
259
260
261 if uid = ep -> entry.uid
262 then if (ep -> entry.type = SEG_TYPE) | (ep -> entry.type = DIR_TYPE)
263 then if ep -> entry.bs = "1"b
264 then if np -> names.owner = uid
265 then do;
266 a_code = 0;
267 return (ep);
268 end;
269
270
271
272
273 entries_in_dir = dp -> dir.seg_count + dp -> dir.dir_count + dp -> dir.lcount;
274 entries_seen = 0;
275
276 do rep = dp -> dir.entryfrp repeat (ep -> entry.efrp) while (rep ^= "0"b);
277 ep = pointer (dp, rep);
278 entries_seen = entries_seen + 1;
279
280 if entries_seen > entries_in_dir
281 then signal condition (bad_dir_);
282
283 if ep -> entry.bs
284 then if (ep -> entry.owner ^= dp -> dir.uid)
285 | (ep -> entry.type ^= SEG_TYPE & ep -> entry.type ^= DIR_TYPE)
286 then signal condition (bad_dir_);
287
288 if ep -> entry.uid = uid
289 then do;
290 kstep -> kste.entryp = ep;
291 a_code = 0;
292 return (ep);
293 end;
294 end;
295
296
297
298
299
300 a_code = error_table_$seg_deleted;
301 return (null ());
302 end validate_entryp;
303 %page;
304 %include aste;
305 %page;
306 %include dir_entry;
307 %page;
308 %include dir_header;
309 %page;
310 %include dir_name;
311 %page;
312 %include fs_types;
313 %page;
314 %include kst;
315 %page;
316 %include sst;
317 %page;
318 %include syserr_constants;
319 %page;
320
321
322
323 XXX
324
325
326
327
328
329
330
331
332
333
334
335
336 XXX
337
338
339
340
341
342
343
344
345
346
347
348
349
350 end sum;