1
2
3
4
5
6
7
8
9
10
11 fs_modes: proc (a_segptr, a_mode, a_ex_mode, a_rings, a_code);
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 dcl a_code fixed bin (35) parameter;
33 dcl a_ex_mode bit (36) aligned parameter;
34 dcl a_mode bit (36) aligned parameter;
35 dcl a_rings (3) fixed bin (3) parameter;
36 dcl a_segptr ptr parameter;
37
38
39
40 dcl read_lock bit (36) aligned static options (constant) init ("0"b);
41
42
43
44 dcl code fixed bin (35);
45 dcl dirsw bit (1) aligned;
46 dcl dp ptr;
47 dcl ex_mode bit (36) aligned;
48 dcl have_ep bit (1) aligned;
49 dcl lock_sw bit (1) aligned;
50 dcl mode bit (36) aligned;
51 dcl rb (3) fixed bin (3);
52 dcl ring fixed bin;
53 dcl segno fixed bin (17);
54 dcl segptr ptr;
55
56
57
58 dcl dseg$ (0:1) fixed bin (71) external;
59 dcl error_table_$mylock fixed bin (35) external;
60
61
62
63 dcl get_kstep entry (fixed bin, ptr, fixed bin (35));
64 dcl level$get entry returns (fixed bin);
65 dcl lock$dir_unlock entry (ptr);
66 dcl sum$getbranch_root_my entry (ptr, bit (36) aligned, ptr, fixed bin (35));
67 dcl update_kste_access entry (ptr, ptr, bit (36) aligned);
68
69
70
71 dcl (addr, baseno, binary, fixed, null, ptr) builtin;
72 %page;
73 have_ep = "0"b;
74 go to join;
75
76 locked: entry (a_segptr, a_mode, a_ex_mode, a_rings, a_code);
77
78 have_ep = "1"b;
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95 join: segptr = a_segptr;
96
97 call get_kstep (fixed (baseno (segptr), 17), kstep, code);
98 if code ^= 0 then go to RETURN;
99
100 if have_ep then ep = kste.entryp;
101 else ep = null;
102
103 dirsw = kstep -> kste.dirsw;
104
105 if kstep -> kste.uid = (36)"1"b then do;
106 lock_sw = "0"b;
107 dp = null;
108 if kstep -> kste.dtbm = (36)"1"b then call update_kste_access (kstep, ep, mode);
109 mode = RW_ACCESS;
110 ex_mode = kstep -> kste.extended_access;
111 rb (1), rb (2), rb (3) = 7;
112 end;
113
114 else do;
115 if dirsw = "0"b then do;
116 dp = null;
117 lock_sw = "0"b;
118 segno = fixed (baseno (segptr), 17);
119 sdwp = addr (dseg$ (segno));
120 if sdwp -> sdw.df = "1"b then call get_sdw_access;
121 else do;
122 call lock_dir;
123
124 if kstep -> kste.dtbm ^= ep -> entry.dtem then
125 call update_kste_access (kstep, ep, mode);
126 else mode = kstep -> kste.access;
127 rb (*) = binary (ep -> entry.ring_brackets (*), 3);
128 end;
129 ex_mode = kstep -> kste.extended_access;
130 end;
131 else do;
132 call lock_dir;
133 if kstep -> kste.dtbm ^= ep -> entry.dtem then call update_kste_access (kstep, ep, mode);
134 mode = RW_ACCESS;
135 ex_mode = kstep -> kste.extended_access;
136 rb (*) = binary (kstep -> kste.ex_rb (*), 3);
137 end;
138 end;
139
140 call compute_effective_mode;
141 if dirsw then call compute_effective_dir_mode;
142
143 if lock_sw then call lock$dir_unlock (dp);
144
145 a_rings = rb;
146 a_mode = mode;
147 a_ex_mode = ex_mode;
148
149 RETURN: a_code = code;
150 return;
151 %page;
152 get_sdw_access: proc;
153 mode = kstep -> kste.access;
154 rb (1) = fixed (sdwp -> sdw.r1, 3);
155 rb (2) = fixed (sdwp -> sdw.r2, 3);
156 rb (3) = fixed (sdwp -> sdw.r3, 3);
157 end get_sdw_access;
158
159 lock_dir: proc;
160
161 lock_sw = "0"b;
162 if ^have_ep then do;
163 call sum$getbranch_root_my (segptr, (read_lock), ep, code);
164 if code ^= 0 then
165 if code ^= error_table_$mylock then go to RETURN;
166 else code = 0;
167 else lock_sw = "1"b;
168 end;
169 dp = ptr (ep, 0);
170
171 end lock_dir;
172
173 compute_effective_mode: proc;
174
175 ring = level$get ();
176 if ring = rb (1) then ;
177 else if ring < rb (1) then mode = mode & "101"b;
178 else if ring <= rb (2) then mode = mode & "110"b;
179 else if ring <= rb (3) then mode = mode & "010"b;
180 else mode = "0"b;
181
182 end compute_effective_mode;
183
184 compute_effective_dir_mode: proc;
185
186 ring = level$get ();
187 if ring <= rb (1) then ;
188 else if ring <= rb (2) then ex_mode = ex_mode & "100"b;
189 else ex_mode = "0"b;
190
191 end compute_effective_dir_mode;
192 %page; %include access_mode_values;
193 %page; %include dir_entry;
194 %page; %include fs_types;
195 %page; %include kst;
196 %page; %include sdw;
197 end fs_modes;