2 * Copyright (c) 2020 iXsystems, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <sys/types.h>
29 #include <sys/param.h>
31 #include <sys/kernel.h>
33 #include <sys/malloc.h>
34 #include <sys/mutex.h>
35 #include <sys/errno.h>
36 #include <sys/cmn_err.h>
37 #include <sys/zfs_ioctl_compat.h>
39 #ifdef ZFS_LEGACY_SUPPORT
41 ZFS_IOC_LEGACY_NONE
= -1,
42 ZFS_IOC_LEGACY_FIRST
= 0,
43 ZFS_LEGACY_IOC
= ZFS_IOC_LEGACY_FIRST
,
44 ZFS_IOC_LEGACY_POOL_CREATE
= ZFS_IOC_LEGACY_FIRST
,
45 ZFS_IOC_LEGACY_POOL_DESTROY
,
46 ZFS_IOC_LEGACY_POOL_IMPORT
,
47 ZFS_IOC_LEGACY_POOL_EXPORT
,
48 ZFS_IOC_LEGACY_POOL_CONFIGS
,
49 ZFS_IOC_LEGACY_POOL_STATS
,
50 ZFS_IOC_LEGACY_POOL_TRYIMPORT
,
51 ZFS_IOC_LEGACY_POOL_SCAN
,
52 ZFS_IOC_LEGACY_POOL_FREEZE
,
53 ZFS_IOC_LEGACY_POOL_UPGRADE
,
54 ZFS_IOC_LEGACY_POOL_GET_HISTORY
,
55 ZFS_IOC_LEGACY_VDEV_ADD
,
56 ZFS_IOC_LEGACY_VDEV_REMOVE
,
57 ZFS_IOC_LEGACY_VDEV_SET_STATE
,
58 ZFS_IOC_LEGACY_VDEV_ATTACH
,
59 ZFS_IOC_LEGACY_VDEV_DETACH
,
60 ZFS_IOC_LEGACY_VDEV_SETPATH
,
61 ZFS_IOC_LEGACY_VDEV_SETFRU
,
62 ZFS_IOC_LEGACY_OBJSET_STATS
,
63 ZFS_IOC_LEGACY_OBJSET_ZPLPROPS
,
64 ZFS_IOC_LEGACY_DATASET_LIST_NEXT
,
65 ZFS_IOC_LEGACY_SNAPSHOT_LIST_NEXT
,
66 ZFS_IOC_LEGACY_SET_PROP
,
67 ZFS_IOC_LEGACY_CREATE
,
68 ZFS_IOC_LEGACY_DESTROY
,
69 ZFS_IOC_LEGACY_ROLLBACK
,
70 ZFS_IOC_LEGACY_RENAME
,
73 ZFS_IOC_LEGACY_INJECT_FAULT
,
74 ZFS_IOC_LEGACY_CLEAR_FAULT
,
75 ZFS_IOC_LEGACY_INJECT_LIST_NEXT
,
76 ZFS_IOC_LEGACY_ERROR_LOG
,
78 ZFS_IOC_LEGACY_PROMOTE
,
79 ZFS_IOC_LEGACY_DESTROY_SNAPS
,
80 ZFS_IOC_LEGACY_SNAPSHOT
,
81 ZFS_IOC_LEGACY_DSOBJ_TO_DSNAME
,
82 ZFS_IOC_LEGACY_OBJ_TO_PATH
,
83 ZFS_IOC_LEGACY_POOL_SET_PROPS
,
84 ZFS_IOC_LEGACY_POOL_GET_PROPS
,
85 ZFS_IOC_LEGACY_SET_FSACL
,
86 ZFS_IOC_LEGACY_GET_FSACL
,
88 ZFS_IOC_LEGACY_INHERIT_PROP
,
89 ZFS_IOC_LEGACY_SMB_ACL
,
90 ZFS_IOC_LEGACY_USERSPACE_ONE
,
91 ZFS_IOC_LEGACY_USERSPACE_MANY
,
92 ZFS_IOC_LEGACY_USERSPACE_UPGRADE
,
94 ZFS_IOC_LEGACY_RELEASE
,
95 ZFS_IOC_LEGACY_GET_HOLDS
,
96 ZFS_IOC_LEGACY_OBJSET_RECVD_PROPS
,
97 ZFS_IOC_LEGACY_VDEV_SPLIT
,
98 ZFS_IOC_LEGACY_NEXT_OBJ
,
100 ZFS_IOC_LEGACY_TMP_SNAPSHOT
,
101 ZFS_IOC_LEGACY_OBJ_TO_STATS
,
103 ZFS_IOC_LEGACY_UNJAIL
,
104 ZFS_IOC_LEGACY_POOL_REGUID
,
105 ZFS_IOC_LEGACY_SPACE_WRITTEN
,
106 ZFS_IOC_LEGACY_SPACE_SNAPS
,
107 ZFS_IOC_LEGACY_SEND_PROGRESS
,
108 ZFS_IOC_LEGACY_POOL_REOPEN
,
109 ZFS_IOC_LEGACY_LOG_HISTORY
,
110 ZFS_IOC_LEGACY_SEND_NEW
,
111 ZFS_IOC_LEGACY_SEND_SPACE
,
112 ZFS_IOC_LEGACY_CLONE
,
113 ZFS_IOC_LEGACY_BOOKMARK
,
114 ZFS_IOC_LEGACY_GET_BOOKMARKS
,
115 ZFS_IOC_LEGACY_DESTROY_BOOKMARKS
,
116 ZFS_IOC_LEGACY_NEXTBOOT
,
117 ZFS_IOC_LEGACY_CHANNEL_PROGRAM
,
118 ZFS_IOC_LEGACY_REMAP
,
119 ZFS_IOC_LEGACY_POOL_CHECKPOINT
,
120 ZFS_IOC_LEGACY_POOL_DISCARD_CHECKPOINT
,
121 ZFS_IOC_LEGACY_POOL_INITIALIZE
,
122 ZFS_IOC_LEGACY_POOL_SYNC
,
126 static unsigned long zfs_ioctl_legacy_to_ozfs_
[] = {
127 ZFS_IOC_POOL_CREATE
, /* 0x00 */
128 ZFS_IOC_POOL_DESTROY
, /* 0x01 */
129 ZFS_IOC_POOL_IMPORT
, /* 0x02 */
130 ZFS_IOC_POOL_EXPORT
, /* 0x03 */
131 ZFS_IOC_POOL_CONFIGS
, /* 0x04 */
132 ZFS_IOC_POOL_STATS
, /* 0x05 */
133 ZFS_IOC_POOL_TRYIMPORT
, /* 0x06 */
134 ZFS_IOC_POOL_SCAN
, /* 0x07 */
135 ZFS_IOC_POOL_FREEZE
, /* 0x08 */
136 ZFS_IOC_POOL_UPGRADE
, /* 0x09 */
137 ZFS_IOC_POOL_GET_HISTORY
, /* 0x0a */
138 ZFS_IOC_VDEV_ADD
, /* 0x0b */
139 ZFS_IOC_VDEV_REMOVE
, /* 0x0c */
140 ZFS_IOC_VDEV_SET_STATE
, /* 0x0d */
141 ZFS_IOC_VDEV_ATTACH
, /* 0x0e */
142 ZFS_IOC_VDEV_DETACH
, /* 0x0f */
143 ZFS_IOC_VDEV_SETPATH
, /* 0x10 */
144 ZFS_IOC_VDEV_SETFRU
, /* 0x11 */
145 ZFS_IOC_OBJSET_STATS
, /* 0x12 */
146 ZFS_IOC_OBJSET_ZPLPROPS
, /* 0x13 */
147 ZFS_IOC_DATASET_LIST_NEXT
, /* 0x14 */
148 ZFS_IOC_SNAPSHOT_LIST_NEXT
, /* 0x15 */
149 ZFS_IOC_SET_PROP
, /* 0x16 */
150 ZFS_IOC_CREATE
, /* 0x17 */
151 ZFS_IOC_DESTROY
, /* 0x18 */
152 ZFS_IOC_ROLLBACK
, /* 0x19 */
153 ZFS_IOC_RENAME
, /* 0x1a */
154 ZFS_IOC_RECV
, /* 0x1b */
155 ZFS_IOC_SEND
, /* 0x1c */
156 ZFS_IOC_INJECT_FAULT
, /* 0x1d */
157 ZFS_IOC_CLEAR_FAULT
, /* 0x1e */
158 ZFS_IOC_INJECT_LIST_NEXT
, /* 0x1f */
159 ZFS_IOC_ERROR_LOG
, /* 0x20 */
160 ZFS_IOC_CLEAR
, /* 0x21 */
161 ZFS_IOC_PROMOTE
, /* 0x22 */
162 /* start of mismatch */
164 ZFS_IOC_DESTROY_SNAPS
, /* 0x23:0x3b */
165 ZFS_IOC_SNAPSHOT
, /* 0x24:0x23 */
166 ZFS_IOC_DSOBJ_TO_DSNAME
, /* 0x25:0x24 */
167 ZFS_IOC_OBJ_TO_PATH
, /* 0x26:0x25 */
168 ZFS_IOC_POOL_SET_PROPS
, /* 0x27:0x26 */
169 ZFS_IOC_POOL_GET_PROPS
, /* 0x28:0x27 */
170 ZFS_IOC_SET_FSACL
, /* 0x29:0x28 */
171 ZFS_IOC_GET_FSACL
, /* 0x30:0x29 */
172 ZFS_IOC_SHARE
, /* 0x2b:0x2a */
173 ZFS_IOC_INHERIT_PROP
, /* 0x2c:0x2b */
174 ZFS_IOC_SMB_ACL
, /* 0x2d:0x2c */
175 ZFS_IOC_USERSPACE_ONE
, /* 0x2e:0x2d */
176 ZFS_IOC_USERSPACE_MANY
, /* 0x2f:0x2e */
177 ZFS_IOC_USERSPACE_UPGRADE
, /* 0x30:0x2f */
178 ZFS_IOC_HOLD
, /* 0x31:0x30 */
179 ZFS_IOC_RELEASE
, /* 0x32:0x31 */
180 ZFS_IOC_GET_HOLDS
, /* 0x33:0x32 */
181 ZFS_IOC_OBJSET_RECVD_PROPS
, /* 0x34:0x33 */
182 ZFS_IOC_VDEV_SPLIT
, /* 0x35:0x34 */
183 ZFS_IOC_NEXT_OBJ
, /* 0x36:0x35 */
184 ZFS_IOC_DIFF
, /* 0x37:0x36 */
185 ZFS_IOC_TMP_SNAPSHOT
, /* 0x38:0x37 */
186 ZFS_IOC_OBJ_TO_STATS
, /* 0x39:0x38 */
187 ZFS_IOC_JAIL
, /* 0x3a:0xc2 */
188 ZFS_IOC_UNJAIL
, /* 0x3b:0xc3 */
189 ZFS_IOC_POOL_REGUID
, /* 0x3c:0x3c */
190 ZFS_IOC_SPACE_WRITTEN
, /* 0x3d:0x39 */
191 ZFS_IOC_SPACE_SNAPS
, /* 0x3e:0x3a */
192 ZFS_IOC_SEND_PROGRESS
, /* 0x3f:0x3e */
193 ZFS_IOC_POOL_REOPEN
, /* 0x40:0x3d */
194 ZFS_IOC_LOG_HISTORY
, /* 0x41:0x3f */
195 ZFS_IOC_SEND_NEW
, /* 0x42:0x40 */
196 ZFS_IOC_SEND_SPACE
, /* 0x43:0x41 */
197 ZFS_IOC_CLONE
, /* 0x44:0x42 */
198 ZFS_IOC_BOOKMARK
, /* 0x45:0x43 */
199 ZFS_IOC_GET_BOOKMARKS
, /* 0x46:0x44 */
200 ZFS_IOC_DESTROY_BOOKMARKS
, /* 0x47:0x45 */
201 ZFS_IOC_NEXTBOOT
, /* 0x48:0xc1 */
202 ZFS_IOC_CHANNEL_PROGRAM
, /* 0x49:0x48 */
203 ZFS_IOC_REMAP
, /* 0x4a:0x4c */
204 ZFS_IOC_POOL_CHECKPOINT
, /* 0x4b:0x4d */
205 ZFS_IOC_POOL_DISCARD_CHECKPOINT
, /* 0x4c:0x4e */
206 ZFS_IOC_POOL_INITIALIZE
, /* 0x4d:0x4f */
209 static unsigned long zfs_ioctl_ozfs_to_legacy_common_
[] = {
210 ZFS_IOC_POOL_CREATE
, /* 0x00 */
211 ZFS_IOC_POOL_DESTROY
, /* 0x01 */
212 ZFS_IOC_POOL_IMPORT
, /* 0x02 */
213 ZFS_IOC_POOL_EXPORT
, /* 0x03 */
214 ZFS_IOC_POOL_CONFIGS
, /* 0x04 */
215 ZFS_IOC_POOL_STATS
, /* 0x05 */
216 ZFS_IOC_POOL_TRYIMPORT
, /* 0x06 */
217 ZFS_IOC_POOL_SCAN
, /* 0x07 */
218 ZFS_IOC_POOL_FREEZE
, /* 0x08 */
219 ZFS_IOC_POOL_UPGRADE
, /* 0x09 */
220 ZFS_IOC_POOL_GET_HISTORY
, /* 0x0a */
221 ZFS_IOC_VDEV_ADD
, /* 0x0b */
222 ZFS_IOC_VDEV_REMOVE
, /* 0x0c */
223 ZFS_IOC_VDEV_SET_STATE
, /* 0x0d */
224 ZFS_IOC_VDEV_ATTACH
, /* 0x0e */
225 ZFS_IOC_VDEV_DETACH
, /* 0x0f */
226 ZFS_IOC_VDEV_SETPATH
, /* 0x10 */
227 ZFS_IOC_VDEV_SETFRU
, /* 0x11 */
228 ZFS_IOC_OBJSET_STATS
, /* 0x12 */
229 ZFS_IOC_OBJSET_ZPLPROPS
, /* 0x13 */
230 ZFS_IOC_DATASET_LIST_NEXT
, /* 0x14 */
231 ZFS_IOC_SNAPSHOT_LIST_NEXT
, /* 0x15 */
232 ZFS_IOC_SET_PROP
, /* 0x16 */
233 ZFS_IOC_CREATE
, /* 0x17 */
234 ZFS_IOC_DESTROY
, /* 0x18 */
235 ZFS_IOC_ROLLBACK
, /* 0x19 */
236 ZFS_IOC_RENAME
, /* 0x1a */
237 ZFS_IOC_RECV
, /* 0x1b */
238 ZFS_IOC_SEND
, /* 0x1c */
239 ZFS_IOC_INJECT_FAULT
, /* 0x1d */
240 ZFS_IOC_CLEAR_FAULT
, /* 0x1e */
241 ZFS_IOC_INJECT_LIST_NEXT
, /* 0x1f */
242 ZFS_IOC_ERROR_LOG
, /* 0x20 */
243 ZFS_IOC_CLEAR
, /* 0x21 */
244 ZFS_IOC_PROMOTE
, /* 0x22 */
245 /* start of mismatch */
246 ZFS_IOC_LEGACY_SNAPSHOT
, /* 0x23 */
247 ZFS_IOC_LEGACY_DSOBJ_TO_DSNAME
, /* 0x24 */
248 ZFS_IOC_LEGACY_OBJ_TO_PATH
, /* 0x25 */
249 ZFS_IOC_LEGACY_POOL_SET_PROPS
, /* 0x26 */
250 ZFS_IOC_LEGACY_POOL_GET_PROPS
, /* 0x27 */
251 ZFS_IOC_LEGACY_SET_FSACL
, /* 0x28 */
252 ZFS_IOC_LEGACY_GET_FSACL
, /* 0x29 */
253 ZFS_IOC_LEGACY_SHARE
, /* 0x2a */
254 ZFS_IOC_LEGACY_INHERIT_PROP
, /* 0x2b */
255 ZFS_IOC_LEGACY_SMB_ACL
, /* 0x2c */
256 ZFS_IOC_LEGACY_USERSPACE_ONE
, /* 0x2d */
257 ZFS_IOC_LEGACY_USERSPACE_MANY
, /* 0x2e */
258 ZFS_IOC_LEGACY_USERSPACE_UPGRADE
, /* 0x2f */
259 ZFS_IOC_LEGACY_HOLD
, /* 0x30 */
260 ZFS_IOC_LEGACY_RELEASE
, /* 0x31 */
261 ZFS_IOC_LEGACY_GET_HOLDS
, /* 0x32 */
262 ZFS_IOC_LEGACY_OBJSET_RECVD_PROPS
, /* 0x33 */
263 ZFS_IOC_LEGACY_VDEV_SPLIT
, /* 0x34 */
264 ZFS_IOC_LEGACY_NEXT_OBJ
, /* 0x35 */
265 ZFS_IOC_LEGACY_DIFF
, /* 0x36 */
266 ZFS_IOC_LEGACY_TMP_SNAPSHOT
, /* 0x37 */
267 ZFS_IOC_LEGACY_OBJ_TO_STATS
, /* 0x38 */
268 ZFS_IOC_LEGACY_SPACE_WRITTEN
, /* 0x39 */
269 ZFS_IOC_LEGACY_SPACE_SNAPS
, /* 0x3a */
270 ZFS_IOC_LEGACY_DESTROY_SNAPS
, /* 0x3b */
271 ZFS_IOC_LEGACY_POOL_REGUID
, /* 0x3c */
272 ZFS_IOC_LEGACY_POOL_REOPEN
, /* 0x3d */
273 ZFS_IOC_LEGACY_SEND_PROGRESS
, /* 0x3e */
274 ZFS_IOC_LEGACY_LOG_HISTORY
, /* 0x3f */
275 ZFS_IOC_LEGACY_SEND_NEW
, /* 0x40 */
276 ZFS_IOC_LEGACY_SEND_SPACE
, /* 0x41 */
277 ZFS_IOC_LEGACY_CLONE
, /* 0x42 */
278 ZFS_IOC_LEGACY_BOOKMARK
, /* 0x43 */
279 ZFS_IOC_LEGACY_GET_BOOKMARKS
, /* 0x44 */
280 ZFS_IOC_LEGACY_DESTROY_BOOKMARKS
, /* 0x45 */
281 ZFS_IOC_LEGACY_NONE
, /* ZFS_IOC_RECV_NEW */
282 ZFS_IOC_LEGACY_POOL_SYNC
, /* 0x47 */
283 ZFS_IOC_LEGACY_CHANNEL_PROGRAM
, /* 0x48 */
284 ZFS_IOC_LEGACY_NONE
, /* ZFS_IOC_LOAD_KEY */
285 ZFS_IOC_LEGACY_NONE
, /* ZFS_IOC_UNLOAD_KEY */
286 ZFS_IOC_LEGACY_NONE
, /* ZFS_IOC_CHANGE_KEY */
287 ZFS_IOC_LEGACY_REMAP
, /* 0x4c */
288 ZFS_IOC_LEGACY_POOL_CHECKPOINT
, /* 0x4d */
289 ZFS_IOC_LEGACY_POOL_DISCARD_CHECKPOINT
, /* 0x4e */
290 ZFS_IOC_LEGACY_POOL_INITIALIZE
, /* 0x4f */
291 ZFS_IOC_LEGACY_NONE
, /* ZFS_IOC_POOL_TRIM */
292 ZFS_IOC_LEGACY_NONE
, /* ZFS_IOC_REDACT */
293 ZFS_IOC_LEGACY_NONE
, /* ZFS_IOC_GET_BOOKMARK_PROPS */
294 ZFS_IOC_LEGACY_NONE
, /* ZFS_IOC_WAIT */
295 ZFS_IOC_LEGACY_NONE
, /* ZFS_IOC_WAIT_FS */
298 static unsigned long zfs_ioctl_ozfs_to_legacy_platform_
[] = {
299 ZFS_IOC_LEGACY_NONE
, /* ZFS_IOC_EVENTS_NEXT */
300 ZFS_IOC_LEGACY_NONE
, /* ZFS_IOC_EVENTS_CLEAR */
301 ZFS_IOC_LEGACY_NONE
, /* ZFS_IOC_EVENTS_SEEK */
302 ZFS_IOC_LEGACY_NEXTBOOT
,
304 ZFS_IOC_LEGACY_UNJAIL
,
305 ZFS_IOC_LEGACY_NONE
, /* ZFS_IOC_SET_BOOTENV */
306 ZFS_IOC_LEGACY_NONE
, /* ZFS_IOC_GET_BOOTENV */
310 zfs_ioctl_legacy_to_ozfs(int request
)
312 if (request
>= sizeof (zfs_ioctl_legacy_to_ozfs_
)/sizeof (long))
314 return (zfs_ioctl_legacy_to_ozfs_
[request
]);
318 zfs_ioctl_ozfs_to_legacy(int request
)
320 if (request
>= ZFS_IOC_LAST
)
323 if (request
> ZFS_IOC_PLATFORM
) {
324 request
-= ZFS_IOC_PLATFORM
+ 1;
325 return (zfs_ioctl_ozfs_to_legacy_platform_
[request
]);
327 if (request
>= sizeof (zfs_ioctl_ozfs_to_legacy_common_
)/sizeof (long))
329 return (zfs_ioctl_ozfs_to_legacy_common_
[request
]);
333 zfs_cmd_legacy_to_ozfs(zfs_cmd_legacy_t
*src
, zfs_cmd_t
*dst
)
335 memcpy(dst
, src
, offsetof(zfs_cmd_t
, zc_objset_stats
));
336 *&dst
->zc_objset_stats
= *&src
->zc_objset_stats
;
337 memcpy(&dst
->zc_begin_record
, &src
->zc_begin_record
,
338 offsetof(zfs_cmd_t
, zc_sendobj
) -
339 offsetof(zfs_cmd_t
, zc_begin_record
));
340 memcpy(&dst
->zc_sendobj
, &src
->zc_sendobj
,
341 sizeof (zfs_cmd_t
) - 8 - offsetof(zfs_cmd_t
, zc_sendobj
));
342 dst
->zc_zoneid
= src
->zc_jailid
;
346 zfs_cmd_ozfs_to_legacy(zfs_cmd_t
*src
, zfs_cmd_legacy_t
*dst
)
348 memcpy(dst
, src
, offsetof(zfs_cmd_t
, zc_objset_stats
));
349 *&dst
->zc_objset_stats
= *&src
->zc_objset_stats
;
350 *&dst
->zc_begin_record
.drr_u
.drr_begin
= *&src
->zc_begin_record
;
351 dst
->zc_begin_record
.drr_payloadlen
= 0;
352 dst
->zc_begin_record
.drr_type
= 0;
354 memcpy(&dst
->zc_inject_record
, &src
->zc_inject_record
,
355 offsetof(zfs_cmd_t
, zc_sendobj
) -
356 offsetof(zfs_cmd_t
, zc_inject_record
));
357 dst
->zc_resumable
= B_FALSE
;
358 memcpy(&dst
->zc_sendobj
, &src
->zc_sendobj
,
359 sizeof (zfs_cmd_t
) - 8 - offsetof(zfs_cmd_t
, zc_sendobj
));
360 dst
->zc_jailid
= src
->zc_zoneid
;
362 #endif /* ZFS_LEGACY_SUPPORT */