4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 * libfstyp module for udfs
38 #include <sys/param.h>
41 #include <sys/types.h>
43 #include <libnvpair.h>
44 #include <libfstyp_module.h>
45 #include <sys/fs/udf_volume.h>
49 typedef struct fstyp_udfs
{
55 static int is_udfs(fstyp_udfs_t
*h
);
56 static int print_vds(fstyp_udfs_t
*h
, struct vds
*,
57 FILE *fout
, FILE *ferr
);
58 static int get_attr(fstyp_udfs_t
*h
);
60 int fstyp_mod_init(int fd
, off_t offset
, fstyp_mod_handle_t
*handle
);
61 void fstyp_mod_fini(fstyp_mod_handle_t handle
);
62 int fstyp_mod_ident(fstyp_mod_handle_t handle
);
63 int fstyp_mod_get_attr(fstyp_mod_handle_t handle
, nvlist_t
**attrp
);
64 int fstyp_mod_dump(fstyp_mod_handle_t handle
, FILE *fout
, FILE *ferr
);
68 fstyp_mod_init(int fd
, off_t offset
, fstyp_mod_handle_t
*handle
)
70 fstyp_udfs_t
*h
= (fstyp_udfs_t
*)handle
;
73 return (FSTYP_ERR_OFFSET
);
76 if ((h
= calloc(1, sizeof (fstyp_udfs_t
))) == NULL
) {
77 return (FSTYP_ERR_NOMEM
);
81 if (ud_init(h
->fd
, &h
->udh
) != 0) {
83 return (FSTYP_ERR_NOMEM
);
86 *handle
= (fstyp_mod_handle_t
)h
;
91 fstyp_mod_fini(fstyp_mod_handle_t handle
)
93 fstyp_udfs_t
*h
= (fstyp_udfs_t
*)handle
;
95 if (h
->attr
== NULL
) {
104 fstyp_mod_ident(fstyp_mod_handle_t handle
)
106 fstyp_udfs_t
*h
= (fstyp_udfs_t
*)handle
;
112 fstyp_mod_get_attr(fstyp_mod_handle_t handle
, nvlist_t
**attrp
)
114 fstyp_udfs_t
*h
= (fstyp_udfs_t
*)handle
;
117 if (h
->attr
== NULL
) {
118 if (nvlist_alloc(&h
->attr
, NV_UNIQUE_NAME_TYPE
, 0)) {
119 return (FSTYP_ERR_NOMEM
);
121 if ((error
= get_attr(h
)) != 0) {
122 nvlist_free(h
->attr
);
133 fstyp_mod_dump(fstyp_mod_handle_t handle
, FILE *fout
, FILE *ferr
)
135 fstyp_udfs_t
*h
= (fstyp_udfs_t
*)handle
;
136 struct udf
*udfs
= &h
->udh
->udfs
;
140 "Standard Identifier %5s\n", udfs
->ecma_id
);
142 if (udfs
->flags
& VALID_MVDS
) {
143 ret
= print_vds(h
, &udfs
->mvds
, fout
, ferr
);
145 ret
= print_vds(h
, &udfs
->rvds
, fout
, ferr
);
153 * Assumption is that we will confirm to level-1
156 is_udfs(fstyp_udfs_t
*h
)
158 struct udf
*udfs
= &h
->udh
->udfs
;
161 if ((ret
= ud_fill_udfs_info(h
->udh
)) != 0) {
165 if ((udfs
->flags
& VALID_UDFS
) == 0) {
166 return (FSTYP_ERR_NO_MATCH
);
173 * For now, only return generic attributes.
174 * Will open an RFE to add native attributes.
177 get_attr(fstyp_udfs_t
*h
)
179 struct udf
*udfs
= &h
->udh
->udfs
;
181 struct pri_vol_desc
*pvd
;
188 v
= (udfs
->flags
& VALID_MVDS
) ? &udfs
->mvds
: &udfs
->rvds
;
190 /* allocate buffer */
192 if (v
->pvd_len
> len
) {
195 if ((buf
= (uint8_t *)malloc(len
)) == NULL
) {
196 return (FSTYP_ERR_NOMEM
);
199 (void) nvlist_add_boolean_value(h
->attr
, "gen_clean", B_TRUE
);
201 /* Primary Volume Descriptor */
202 if (v
->pvd_len
!= 0) {
203 off
= v
->pvd_loc
* udfs
->lbsize
;
204 if (ud_read_dev(h
->udh
, off
, buf
, v
->pvd_len
) != 0) {
209 pvd
= (struct pri_vol_desc
*)(uint32_t *)buf
;
211 ud_convert2local(pvd
->pvd_vol_id
, str
, 32);
213 (void) nvlist_add_string(h
->attr
, "gen_volume_label", str
);
225 print_vds(fstyp_udfs_t
*h
, struct vds
*v
, FILE *fout
, FILE *ferr
)
227 struct udf
*udfs
= &h
->udh
->udfs
;
235 * All descriptors are 512 bytes
236 * except lvd, usd and lvid
237 * findout the largest and allocate space
240 if (v
->lvd_len
> len
) {
243 if (v
->usd_len
> len
) {
246 if (udfs
->lvid_len
> len
) {
247 len
= udfs
->lvid_len
;
250 if ((buf
= (uint8_t *)malloc(len
)) == NULL
) {
251 return (FSTYP_ERR_NOMEM
);
255 * Anchor Volume Descriptor
257 if (udfs
->avdp_len
!= 0) {
258 off
= udfs
->avdp_loc
* udfs
->lbsize
;
259 if (ud_read_dev(h
->udh
, off
, buf
, udfs
->avdp_len
) != 0) {
265 print_avd(fout
, (struct anch_vol_desc_ptr
*)buf
);
269 * Primary Volume Descriptor
271 if (v
->pvd_len
!= 0) {
272 off
= v
->pvd_loc
* udfs
->lbsize
;
273 if (ud_read_dev(h
->udh
, off
, buf
, v
->pvd_len
) != 0) {
279 print_pvd(fout
, (struct pri_vol_desc
*)buf
);
283 * Implementation Use descriptor
285 if (v
->iud_len
!= 0) {
286 off
= v
->iud_loc
* udfs
->lbsize
;
287 if (ud_read_dev(h
->udh
, off
, buf
, v
->iud_len
) != 0) {
293 print_iuvd(fout
, (struct iuvd_desc
*)buf
);
299 for (i
= 0; i
< h
->udh
->n_parts
; i
++) {
300 if (v
->part_len
[i
] != 0) {
301 off
= v
->part_loc
[i
] * udfs
->lbsize
;
302 if (ud_read_dev(h
->udh
, off
, buf
,
303 v
->part_len
[i
]) != 0) {
309 print_part(fout
, (struct part_desc
*)buf
);
314 * Logical Volume Descriptor
316 if (v
->lvd_len
!= 0) {
317 off
= v
->lvd_loc
* udfs
->lbsize
;
318 if (ud_read_dev(h
->udh
, off
, buf
, v
->lvd_len
) != 0) {
324 print_lvd(fout
, (struct log_vol_desc
*)buf
);
328 * Unallocated Space Descriptor
330 if (v
->usd_len
!= 0) {
331 off
= v
->usd_loc
* udfs
->lbsize
;
332 if (ud_read_dev(h
->udh
, off
, buf
, v
->usd_len
) != 0) {
338 print_usd(fout
, (struct unall_spc_desc
*)buf
);
342 * Logical Volume Integrity Descriptor
344 if (udfs
->lvid_len
!= 0) {
345 off
= udfs
->lvid_loc
* udfs
->lbsize
;
346 if (ud_read_dev(h
->udh
, off
, buf
, udfs
->lvid_len
) != 0) {
352 print_lvid(fout
, (struct log_vol_int_desc
*)buf
);
356 * File Set Descriptor
358 if (udfs
->fsd_len
!= 0) {
359 off
= udfs
->fsd_loc
* udfs
->lbsize
;
360 if (ud_read_dev(h
->udh
, off
, buf
, udfs
->fsd_len
) != 0) {
366 print_fsd(fout
, h
->udh
, (struct file_set_desc
*)buf
);