1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 retv_copy: proc (a_dirname, a_ename, a_auth, a_userid, a_level, a_vtocep, a_objectp, a_attributes, a_code);
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 dcl a_attributes bit (36);
37 dcl a_auth bit (72) aligned;
38 dcl a_code fixed bin (35);
39 dcl a_dirname char (*) aligned;
40 dcl a_ename char (*) aligned;
41 dcl a_level fixed bin;
42 dcl a_objectp ptr;
43 dcl a_userid char (*) aligned;
44 dcl a_vtocep ptr;
45
46
47
48 dcl attributes bit (36);
49 dcl code fixed bin (35);
50 dcl del_code fixed bin (35);
51 dcl del_ename char (32);
52 dcl del_pname char (168);
53 dcl dir_pvid bit (36) aligned;
54 dcl dir_uid bit (36) aligned;
55 dcl dir_vtocx fixed bin;
56 dcl dirl bit (1) aligned;
57 dcl dirname char (168);
58 dcl dirsw bit (1);
59 dcl ec fixed bin (35);
60 dcl ename char (32);
61 dcl found bit (1);
62 dcl hold bit (1);
63 dcl i fixed bin;
64 dcl ignore fixed bin (35);
65 dcl inf_received (0:1) fixed bin (18);
66 dcl 1 input_vtoce like vtoce aligned;
67 dcl 1 local_audit_user_info like audit_user_info aligned;
68 dcl 1 local_dir_header like dir aligned;
69 dcl 1 local_makeknown_info like makeknown_info aligned;
70 dcl 1 local_quota_cell like quota_cell aligned;
71 dcl 1 local_vtoce like vtoce aligned;
72 dcl mismatch bit (1);
73 dcl ncd fixed bin;
74 dcl new_ep ptr;
75 dcl new_vtoce bit (1);
76 dcl nid fixed bin;
77 dcl objectp ptr;
78 dcl old_ep ptr;
79 dcl old_uid bit (36) aligned;
80 dcl par_ep ptr;
81 dcl par_pvid bit (36) aligned;
82 dcl par_quota (0:1) fixed bin (18);
83 dcl par_received (0:1) fixed bin (18);
84 dcl par_uid bit (36) aligned;
85 dcl par_vtocx fixed bin;
86 dcl pardirl bit (1) aligned;
87 dcl pvid bit (36) aligned;
88 dcl pvtx fixed bin;
89 dcl quota_type fixed bin;
90 dcl segno fixed bin;
91 dcl segptr ptr;
92 dcl skip_list (1500) bit (36) aligned;
93 dcl skip_list_cnt fixed bin init (0);
94 dcl skip_list_idx fixed bin;
95 dcl target_dirl bit (1);
96 dcl target_dp ptr;
97 dcl 1 temp_quota_cell like quota_cell aligned;
98 dcl uid bit (36) aligned;
99 dcl vtocx fixed bin;
100
101
102
103 dcl dates_set defined attributes position (1) bit (1);
104 dcl dump_info_set defined attributes position (3) bit (1);
105 dcl dump_switches_set defined attributes position (2) bit (1);
106 dcl page (512) bit (72) aligned based;
107 dcl pc_switches_set defined attributes position (4) bit (1);
108 dcl quota_set defined attributes position (5) bit (1);
109
110
111
112 dcl error_table_$action_not_performed ext fixed bin (35);
113 dcl error_table_$argerr ext fixed bin (35);
114 dcl error_table_$fulldir ext fixed bin (35);
115 dcl error_table_$invalidsegno ext fixed bin (35);
116 dcl error_table_$segknown ext fixed bin (35);
117 dcl error_table_$vtoce_connection_fail ext fixed bin (35);
118 dcl sys_info$max_seg_size ext fixed bin;
119
120
121
122 dcl create_vtoce entry (ptr, bit (36) aligned, fixed bin, fixed bin (35));
123 dcl del_dir_tree$retv entry (char (*), char (*), fixed bin (35));
124 dcl delentry$retv entry (char (*), char (*), fixed bin (35));
125 dcl get_kstep entry (fixed bin, ptr, fixed bin (35));
126 dcl get_pvtx entry (bit (36) aligned, fixed bin (35)) returns (fixed bin);
127 dcl get_pvtx$release_pvtx entry (bit (36) aligned, fixed bin);
128 dcl grab_aste entry (ptr, fixed bin, fixed bin (35), ptr);
129 dcl lock$dir_lock_read entry (ptr, fixed bin (35));
130 dcl lock$dir_unlock entry (ptr);
131 dcl makeknown_ entry (ptr, fixed bin, fixed bin, fixed bin (35));
132 dcl makeunknown_ entry (fixed bin, bit (36) aligned, bit (1) aligned, fixed bin (35));
133 dcl mountedp entry (bit (36) aligned) returns (fixed bin (35));
134 dcl setfaults$disconnect entry (fixed bin);
135 dcl setfaults$if_active entry (bit (36) aligned, bit (36) aligned, fixed bin, bit (1));
136 dcl sum$getbranch entry (ptr, bit (36), ptr, fixed bin (35));
137 dcl syserr$error_code entry options (variable);
138 dcl truncate_vtoce$hold entry (ptr, fixed bin, fixed bin (35));
139 dcl vtoc_attributes$get_quota entry (bit (36) aligned, bit (36) aligned, fixed bin, ptr, fixed bin, fixed bin (35));
140 dcl vtoc_attributes$set_dates entry (bit (36) aligned, bit (36) aligned, fixed bin, bit (36), bit (36), fixed bin (35));
141 dcl vtoc_attributes$set_dump_info entry (bit (36) aligned, bit (36) aligned, fixed bin, bit (36), (3) bit (36),
142 fixed bin (35));
143 dcl vtoc_attributes$set_dump_switches entry (bit (36) aligned, bit (36) aligned, fixed bin, fixed bin, fixed bin,
144 fixed bin (35));
145 dcl vtoc_attributes$set_max_lth entry (bit (36) aligned, bit (36) aligned, fixed bin, fixed bin (9), bit (1),
146 fixed bin (35));
147 dcl vtoc_attributes$set_pc_switches entry (bit (36) aligned, bit (36) aligned, fixed bin, bit (36), bit (36),
148 fixed bin (35));
149 dcl vtoc_attributes$set_quota entry (bit (36) aligned, bit (36) aligned, fixed bin, ptr, fixed bin, fixed bin (35));
150 dcl vtoc_man$get_vtoce entry (bit (36) aligned, fixed bin, fixed bin, bit (3), ptr, fixed bin (35));
151
152
153
154 dcl bad_dir_ condition;
155 dcl cleanup condition;
156
157 dcl (addr, baseptr, fixed, null, ptr, rel, rtrim, substr, unspec) builtin;
158 %page;
159 audit_user_info_ptr = addr (local_audit_user_info);
160 unspec (audit_user_info) = "0"b;
161
162
163 dirname = a_dirname;
164 ename = a_ename;
165 objectp = a_objectp;
166 audit_user_info.version = audit_user_info_version_1;
167 audit_user_info.user_id = a_userid;
168 audit_user_info.ring = a_level;
169 audit_user_info.process_id = "0"b;
170 audit_user_info.authorization_range(2),
171 audit_user_info.authorization = a_auth;
172 audit_user_info.audit_flags = (36)"1"b;
173 input_vtoce = a_vtocep -> vtoce;
174
175 target_dirl, dirl, pardirl, hold, new_vtoce = "0"b;
176 attributes = "0"b;
177 code = 0;
178 segno = -1;
179 astep, dp, kstep = null;
180
181 on cleanup begin;
182 code = error_table_$action_not_performed;
183 if kstep ^= null then call revert_kst_access;
184 goto fin;
185 end;
186
187
188
189 if input_vtoce.dirsw then do;
190 unspec (local_dir_header) = "0"b;
191 target_dp = addr (local_dir_header);
192 local_dir_header.uid = input_vtoce.uid;
193 call lock$dir_lock_read (target_dp, code);
194 if code ^= 0 then goto fin;
195 target_dirl = "1"b;
196 end;
197
198
199
200 call grab_aste (objectp, sys_info$max_seg_size, code, astep);
201 if code ^= 0 then goto fin;
202
203 call dc_find$obj_volume_retrieve (dirname, ename, audit_user_info_ptr, ep, code);
204 if code ^= 0 then goto fin;
205 dp = ptr (ep, 0);
206 dirl = "1"b;
207
208 if entry.uid ^= input_vtoce.uid then do;
209 code = error_table_$vtoce_connection_fail;
210 goto fin;
211 end;
212
213 if ^entry.bs then do;
214 code = error_table_$action_not_performed;
215 goto fin;
216 end;
217 if ^entry.dirsw then do;
218 code = mountedp (dir.sons_lvid);
219 if code ^= 0 then goto fin;
220 end;
221
222 if entry.dirsw then do;
223 call sum$getbranch (dp, "0"b, par_ep, code);
224 if code ^= 0 then goto fin;
225 pardirl = "1"b;
226
227 par_uid = par_ep -> entry.uid;
228 par_vtocx = par_ep -> entry.vtocx;
229 par_pvid = par_ep -> entry.pvid;
230 qcp = addr (local_quota_cell);
231 do quota_type = 0 to 1;
232 call vtoc_attributes$get_quota (par_uid, par_pvid, par_vtocx, qcp, quota_type, code);
233 if code ^= 0 then goto fin;
234 par_received (quota_type) = quota_cell.received;
235 par_quota (quota_type) = quota_cell.quota;
236 end;
237
238 call lock$dir_unlock (ptr (par_ep, 0));
239 pardirl = "0"b;
240 end;
241
242
243
244 pvid = entry.pvid;
245 uid = entry.uid;
246 pvtx = get_pvtx (pvid, code);
247 if code ^= 0 then goto fin;
248 vtocx = entry.vtocx;
249 vtocep = addr (local_vtoce);
250 call vtoc_man$get_vtoce (pvid, pvtx, vtocx, "100"b, vtocep, code);
251 if code ^= 0 then goto fin;
252 if entry.uid ^= vtoce.uid then do;
253 call create_vtoce (ep, pvid, vtocx, code);
254 if code ^= 0 then goto fin;
255 entry.vtocx = vtocx;
256 entry.pvid = pvid;
257 pvtx = get_pvtx (pvid, code);
258 if code ^= 0 then goto fin;
259 new_vtoce = "1"b;
260 end;
261
262 makeknown_infop = addr (local_makeknown_info);
263 makeknown_info.uid = uid;
264 makeknown_info.entryp = ep;
265 makeknown_info.activate, makeknown_info.dirsw = entry.dirsw;
266 makeknown_info.rsw = "0"b;
267 makeknown_info.allow_write = "1"b;
268 makeknown_info.priv_init = "1"b;
269 makeknown_info.audit = "0"b;
270 call makeknown_ (makeknown_infop, segno, (0), code);
271 if code ^= 0 then do;
272 if code = error_table_$segknown then code = 0;
273 else goto fin;
274 end;
275
276 call force_kst_access;
277 if code ^= 0 then goto fin;
278 segptr = baseptr (segno);
279
280
281
282
283
284 mismatch = "1"b;
285 if ^new_vtoce & entry.dirsw then
286 do while (mismatch);
287 call reset_new_dir;
288 if code ^= 0 then goto fin;
289 end;
290
291 call truncate_vtoce$hold (ep, 0, code);
292 if code ^= 0 then goto fin;
293 hold = "1"b;
294
295 call vtoc_attributes$set_max_lth (uid, pvid, vtocx, fixed (input_vtoce.msl, 9), "1"b, code);
296 if code ^= 0 then goto fin;
297
298 do i = 0 to fixed (input_vtoce.csl, 9) - 1;
299 if substr (input_vtoce.fm (i), 1, 1) = "0"b then
300 ptr (segptr, i * 1024) -> page = ptr (objectp, i * 1024) -> page;
301 end;
302
303 if entry.dirsw then do;
304 segptr -> dir.pvid = pvid;
305 segptr -> dir.vtocx = vtocx;
306 end;
307
308 call revert_kst_access;
309 call makeunknown_ (segno, "0"b, ("0"b), ignore);
310
311 call vtoc_attributes$set_dates (uid, pvid, vtocx, input_vtoce.dtu, input_vtoce.dtm, ec);
312 dates_set = (ec ^= 0);
313
314 if input_vtoce.nid = "1"b then nid = 1; else nid = -1;
315 if input_vtoce.ncd = "1"b then ncd = 1; else ncd = -1;
316 call vtoc_attributes$set_dump_switches (uid, pvid, vtocx, nid, ncd, ec);
317 dump_switches_set = (ec ^= 0);
318
319 call vtoc_attributes$set_dump_info (uid, pvid, vtocx, input_vtoce.dtd, input_vtoce.volid, ec);
320 dump_info_set = (ec ^= 0);
321
322 call vtoc_attributes$set_pc_switches (uid, pvid, vtocx, input_vtoce.dnzp || input_vtoce.gtpd, "11"b, ec);
323 pc_switches_set = (ec ^= 0);
324
325
326
327
328
329
330
331
332 if entry.dirsw then do;
333 qcp = addr (local_quota_cell);
334 call compute_inf_received;
335 if ec ^= 0 then goto q_done;
336 do quota_type = 0 to 1;
337 call vtoc_attributes$get_quota (uid, pvid, vtocx, qcp, quota_type, ec);
338 if ec ^= 0 then goto q_done;
339 if new_vtoce then do;
340 quota_cell.quota = input_vtoce.quota (quota_type);
341 quota_cell.used = input_vtoce.used (quota_type);
342 quota_cell.received = input_vtoce.received (quota_type);
343 quota_cell.tup = input_vtoce.trp_time (quota_type);
344 quota_cell.trp = input_vtoce.trp (quota_type);
345 quota_cell.pad = 0;
346 end;
347 else do;
348 quota_cell.quota = input_vtoce.quota (quota_type);
349 quota_cell.received = input_vtoce.received (quota_type);
350 end;
351 if inf_received (quota_type) + par_quota (quota_type) + input_vtoce.received (quota_type) <= par_received (quota_type) then
352 call vtoc_attributes$set_quota (uid, pvid, vtocx, qcp, quota_type, ec);
353 else do;
354 quota_set = "1"b;
355 quota_cell.quota = 1;
356 call vtoc_attributes$set_quota (uid, pvid, vtocx, qcp, quota_type, ec);
357 goto q_next;
358 end;
359 q_done: quota_set = quota_set | (ec ^= 0);
360 q_next: end;
361 end;
362
363 fin:
364
365 if hold then call get_pvtx$release_pvtx (pvid, pvtx);
366 if target_dirl then call lock$dir_unlock (target_dp);
367 if dp ^= null then call dc_find$finished (dp, dirl);
368 if pardirl then call lock$dir_unlock (ptr (par_ep, 0));
369 if astep ^= null then aste.ehs = "0"b;
370 a_attributes = attributes;
371 ret: a_code = code;
372 return;
373 %page;
374 force_kst_access: proc;
375
376
377
378
379
380 call get_kstep (segno, kstep, code);
381 if code ^= 0 then return;
382 kste.dtbm = entry.dtem;
383 kste.access = "101"b;
384 call setfaults$if_active (uid, pvid, vtocx, "0"b);
385 return;
386
387 end force_kst_access;
388
389 revert_kst_access: proc;
390
391
392
393 kste.dtbm = (36)"1"b;
394 call setfaults$disconnect (segno);
395 return;
396
397 end revert_kst_access;
398
399 compute_inf_received: proc;
400
401
402
403 dcl nentries fixed bin;
404 dcl ok fixed bin (35);
405 dcl seen fixed bin;
406
407 inf_received (*) = 0;
408 nentries = dir.lcount + dir.seg_count + dir.dir_count;
409 seen = 0;
410 do ep = ptr (dp, dir.entryfrp) repeat (ptr (dp, entry.efrp)) while (rel (ep) ^= "0"b);
411 seen = seen + 1;
412 if seen > nentries then signal bad_dir_;
413 if entry.bs then
414 if entry.owner ^= dir.uid then signal bad_dir_;
415 else ;
416 else if link.owner ^= dir.uid
417 | link.type ^= LINK_TYPE then signal bad_dir_;
418 if entry.dirsw then do;
419 if entry.type ^= DIR_TYPE then signal bad_dir_;
420 dir_vtocx = entry.vtocx;
421 dir_pvid = entry.pvid;
422 dir_uid = entry.uid;
423 qcp = addr (temp_quota_cell);
424 do quota_type = 0 to 1;
425 call vtoc_attributes$get_quota (dir_uid, dir_pvid, dir_vtocx, qcp, quota_type, ok);
426 if ok = 0 then inf_received (quota_type) = inf_received (quota_type) + quota_cell.received;
427 end;
428 end;
429 end;
430 return;
431
432 end compute_inf_received;
433
434 reset_new_dir: proc;
435
436
437
438
439
440
441 dcl nentries1 fixed bin;
442 dcl nentries2 fixed bin;
443 dcl seen1 fixed bin;
444 dcl seen2 fixed bin;
445
446 mismatch = "0"b;
447 reset_loop: seen2 = 0;
448 nentries2 = segptr -> dir.lcount + segptr -> dir.dir_count + segptr -> dir.seg_count;
449 do old_ep = ptr (segptr, segptr -> dir.entryfrp) repeat (ptr (segptr, old_ep -> entry.efrp))
450 while (rel (old_ep) ^= "0"b);
451 seen2 = seen2 + 1;
452 if seen2 > nentries2 then signal bad_dir_;
453 seen1 = 0;
454 nentries1 = objectp -> dir.lcount + objectp -> dir.dir_count + objectp -> dir.seg_count;
455 do new_ep = ptr (objectp, objectp -> dir.entryfrp) repeat (ptr (objectp, new_ep -> entry.efrp))
456 while (rel (new_ep) ^= "0"b & new_ep -> entry.uid ^= old_ep -> entry.uid);
457 seen1 = seen1 + 1;
458 if seen1 > nentries1 then do;
459 code = error_table_$argerr;
460 return;
461 end;
462 end;
463 if rel (new_ep) ^= "0"b then do;
464 new_ep -> entry.pvid = old_ep -> entry.pvid;
465 new_ep -> entry.vtocx = old_ep -> entry.vtocx;
466 end;
467 else if ^on_skip_list () then do;
468 mismatch = "1"b;
469 del_ename = ptr (old_ep, old_ep -> entry.name_frp) -> names.name;
470 if dirname = ">" then del_pname = ">" || ename;
471 else del_pname = rtrim (dirname) || ">" || ename;
472 old_uid = old_ep -> entry.uid;
473 dirsw = old_ep -> entry.dirsw;
474 call lock$dir_unlock (segptr);
475 target_dirl = "0"b;
476 call dc_find$finished (dp, "1"b);
477 dp = null;
478 dirl = "0"b;
479 if dirsw then do;
480 subtree: call del_dir_tree$retv (del_pname, del_ename, del_code);
481 if del_code ^= 0 then goto delerr;
482 end;
483 call delentry$retv (del_pname, del_ename, del_code);
484 if del_code = error_table_$fulldir then goto subtree;
485 if del_code ^= 0 then do;
486 delerr: call syserr$error_code (4, del_code, "retv_copy: deleting ^a>^a without recovering resources",
487 del_pname, del_ename);
488 call add_to_skip_list;
489 end;
490 call lock$dir_lock_read (segptr, code);
491 if code ^= 0 then return;
492 target_dirl = "1"b;
493 call dc_find$obj_volume_retrieve (dirname, ename, audit_user_info_ptr, ep, code);
494 if code ^= 0 then return;
495 dirl = "1"b;
496 if ep -> entry.uid ^= uid then do;
497 code = error_table_$invalidsegno;
498 return;
499 end;
500 dp = ptr (ep, 0);
501 goto reset_loop;
502 end;
503 end;
504 return;
505
506 end reset_new_dir;
507
508 on_skip_list: proc returns (bit (1));
509 found = "0"b;
510 do skip_list_idx = 1 to skip_list_cnt while (skip_list (skip_list_idx) ^= old_uid);
511 end;
512 if skip_list_idx <= skip_list_cnt then found = "1"b;
513 return (found);
514
515 end on_skip_list;
516
517 add_to_skip_list: proc;
518 skip_list_cnt = skip_list_cnt + 1;
519 skip_list (skip_list_cnt) = old_uid;
520 return;
521
522 end add_to_skip_list;
523 %page; %include access_audit_user_info;
524 %page; %include aste;
525 %page; %include dc_find_dcls;
526 %page; %include dir_entry;
527 %page; %include dir_header;
528 %page; %include dir_link;
529 %page; %include dir_name;
530 %page; %include fs_types;
531 %page; %include kst;
532 %page; %include makeknown_info;
533 %page; %include quota_cell;
534 %page; %include sdw;
535 %page; %include vtoce;
536 %page;
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554 Note
555
556
557
558 end retv_copy;