version 1.5, 2006/03/01 12:38:21 |
version 1.5.2.4, 2006/09/03 15:25:13 |
Line 63 __RCSID("$NetBSD$"); |
|
Line 63 __RCSID("$NetBSD$"); |
|
#include <sys/dirent.h> |
#include <sys/dirent.h> |
#include <sys/stat.h> |
#include <sys/stat.h> |
#include <sys/conf.h> |
#include <sys/conf.h> |
|
#include <sys/kauth.h> |
|
|
#include <fs/udf/ecma167-udf.h> |
#include <fs/udf/ecma167-udf.h> |
#include <fs/udf/udf_mount.h> |
#include <fs/udf/udf_mount.h> |
Line 96 __RCSID("$NetBSD$"); |
|
Line 97 __RCSID("$NetBSD$"); |
|
printf("%02x ", blob[i+j]); |
printf("%02x ", blob[i+j]); |
} else { |
} else { |
printf(" "); |
printf(" "); |
}; |
} |
}; |
} |
for (j = 0; j < 16; j++) { |
for (j = 0; j < 16; j++) { |
if (i+j < dlen) { |
if (i+j < dlen) { |
if (blob[i+j]>32 && blob[i+j]! = 127) { |
if (blob[i+j]>32 && blob[i+j]! = 127) { |
printf("%c", blob[i+j]); |
printf("%c", blob[i+j]); |
} else { |
} else { |
printf("."); |
printf("."); |
}; |
} |
}; |
} |
}; |
} |
printf("\n"); |
printf("\n"); |
}; |
} |
printf("\n"); |
printf("\n"); |
}; |
} |
Debugger(); |
Debugger(); |
#endif |
#endif |
|
|
Line 187 udf_check_tag_payload(void *blob, uint32 |
|
Line 188 udf_check_tag_payload(void *blob, uint32 |
|
if (crc != udf_rw16(tag->desc_crc)) { |
if (crc != udf_rw16(tag->desc_crc)) { |
/* bad payload CRC; this is a broken tag */ |
/* bad payload CRC; this is a broken tag */ |
return EINVAL; |
return EINVAL; |
}; |
} |
|
|
return 0; |
return 0; |
} |
} |
Line 207 udf_validate_tag_sum(void *blob) |
|
Line 208 udf_validate_tag_sum(void *blob) |
|
for(cnt = 0; cnt < 16; cnt++) { |
for(cnt = 0; cnt < 16; cnt++) { |
if (cnt != 4) sum += *pos; |
if (cnt != 4) sum += *pos; |
pos++; |
pos++; |
}; |
} |
tag->cksum = sum; /* 8 bit */ |
tag->cksum = sum; /* 8 bit */ |
|
|
return 0; |
return 0; |
Line 215 udf_validate_tag_sum(void *blob) |
|
Line 216 udf_validate_tag_sum(void *blob) |
|
|
|
/* --------------------------------------------------------------------- */ |
/* --------------------------------------------------------------------- */ |
|
|
/* assumes sector number of descriptor to be saved allready present */ |
/* assumes sector number of descriptor to be saved already present */ |
|
|
int |
int |
udf_validate_tag_and_crc_sums(void *blob) |
udf_validate_tag_and_crc_sums(void *blob) |
Line 230 udf_validate_tag_and_crc_sums(void *blob |
|
Line 231 udf_validate_tag_and_crc_sums(void *blob |
|
if (crc_len > 0) { |
if (crc_len > 0) { |
crc = udf_cksum(btag + UDF_DESC_TAG_LENGTH, crc_len); |
crc = udf_cksum(btag + UDF_DESC_TAG_LENGTH, crc_len); |
tag->desc_crc = udf_rw16(crc); |
tag->desc_crc = udf_rw16(crc); |
}; |
} |
|
|
/* calculate TAG header checksum */ |
/* calculate TAG header checksum */ |
return udf_validate_tag_sum(blob); |
return udf_validate_tag_sum(blob); |
Line 292 udf_tagsize(union dscrptr *dscr, uint32_ |
|
Line 293 udf_tagsize(union dscrptr *dscr, uint32_ |
|
default : |
default : |
size = sizeof(union dscrptr); |
size = sizeof(union dscrptr); |
break; |
break; |
}; |
} |
|
|
if ((size == 0) || (udf_sector_size == 0)) return 0; |
if ((size == 0) || (udf_sector_size == 0)) return 0; |
|
|
Line 353 udf_read_descriptor(struct udf_mount *um |
|
Line 354 udf_read_descriptor(struct udf_mount *um |
|
pos = bp->b_data; |
pos = bp->b_data; |
for (i = 0; i < sector_size; i++, pos++) { |
for (i = 0; i < sector_size; i++, pos++) { |
if (*pos) break; |
if (*pos) break; |
}; |
} |
if (i == sector_size) { |
if (i == sector_size) { |
/* return no error but with no dscrptr */ |
/* return no error but with no dscrptr */ |
/* dispose first block */ |
/* dispose first block */ |
brelse(bp); |
brelse(bp); |
return 0; |
return 0; |
}; |
} |
}; |
} |
}; |
} |
DPRINTFIF(DESCRIPTOR, error, ("bad tag checksum\n")); |
DPRINTFIF(DESCRIPTOR, error, ("bad tag checksum\n")); |
if (!error) { |
if (!error) { |
src = (union dscrptr *) bp->b_data; |
src = (union dscrptr *) bp->b_data; |
dscrlen = udf_tagsize(src, sector_size); |
dscrlen = udf_tagsize(src, sector_size); |
dst = malloc(dscrlen, mtype, M_WAITOK); |
dst = malloc(dscrlen, mtype, M_WAITOK); |
memcpy(dst, src, dscrlen); |
memcpy(dst, src, dscrlen); |
}; |
} |
/* dispose first block */ |
/* dispose first block */ |
bp->b_flags |= B_AGE; |
bp->b_flags |= B_AGE; |
brelse(bp); |
brelse(bp); |
Line 386 udf_read_descriptor(struct udf_mount *um |
|
Line 387 udf_read_descriptor(struct udf_mount *um |
|
if (error) { |
if (error) { |
brelse(bp); |
brelse(bp); |
break; |
break; |
}; |
} |
pos = (uint8_t *) dst + blk*sector_size; |
pos = (uint8_t *) dst + blk*sector_size; |
memcpy(pos, bp->b_data, sector_size); |
memcpy(pos, bp->b_data, sector_size); |
|
|
/* dispose block */ |
/* dispose block */ |
bp->b_flags |= B_AGE; |
bp->b_flags |= B_AGE; |
brelse(bp); |
brelse(bp); |
}; |
} |
DPRINTFIF(DESCRIPTOR, error, ("read error on multi (%d)\n", |
DPRINTFIF(DESCRIPTOR, error, ("read error on multi (%d)\n", |
error)); |
error)); |
}; |
} |
if (!error) { |
if (!error) { |
error = udf_check_tag_payload(dst, dscrlen); |
error = udf_check_tag_payload(dst, dscrlen); |
DPRINTFIF(DESCRIPTOR, error, ("bad payload check sum\n")); |
DPRINTFIF(DESCRIPTOR, error, ("bad payload check sum\n")); |
}; |
} |
if (error && dst) { |
if (error && dst) { |
free(dst, mtype); |
free(dst, mtype); |
dst = NULL; |
dst = NULL; |
}; |
} |
*dstp = dst; |
*dstp = dst; |
|
|
return error; |
return error; |
Line 468 udf_update_discinfo(struct udf_mount *um |
|
Line 469 udf_update_discinfo(struct udf_mount *um |
|
if (error == 0) { |
if (error == 0) { |
udf_dump_discinfo(ump); |
udf_dump_discinfo(ump); |
return 0; |
return 0; |
}; |
} |
|
|
/* disc partition support */ |
/* disc partition support */ |
error = VOP_IOCTL(devvp, DIOCGPART, &dpart, FREAD, NOCRED, NULL); |
error = VOP_IOCTL(devvp, DIOCGPART, &dpart, FREAD, NOCRED, NULL); |
Line 520 udf_update_trackinfo(struct udf_mount *u |
|
Line 521 udf_update_trackinfo(struct udf_mount *u |
|
error = VOP_IOCTL(devvp, MMCGETTRACKINFO, ti, FKIOCTL, |
error = VOP_IOCTL(devvp, MMCGETTRACKINFO, ti, FKIOCTL, |
NOCRED, NULL); |
NOCRED, NULL); |
return error; |
return error; |
}; |
} |
|
|
/* disc partition support */ |
/* disc partition support */ |
if (ti->tracknr != 1) |
if (ti->tracknr != 1) |
Line 563 udf_search_tracks(struct udf_mount *ump, |
|
Line 564 udf_search_tracks(struct udf_mount *ump, |
|
/* sanity */ |
/* sanity */ |
if (args->sessionnr < 0) |
if (args->sessionnr < 0) |
args->sessionnr = 0; |
args->sessionnr = 0; |
}; |
} |
|
|
/* sanity */ |
/* sanity */ |
if (args->sessionnr > ump->discinfo.num_sessions) |
if (args->sessionnr > ump->discinfo.num_sessions) |
Line 575 udf_search_tracks(struct udf_mount *ump, |
|
Line 576 udf_search_tracks(struct udf_mount *ump, |
|
if (ump->discinfo.last_session_state == MMC_STATE_EMPTY) { |
if (ump->discinfo.last_session_state == MMC_STATE_EMPTY) { |
args->sessionnr--; |
args->sessionnr--; |
} |
} |
}; |
} |
|
|
/* search the first and last track of the specified session */ |
/* search the first and last track of the specified session */ |
num_tracks = ump->discinfo.num_tracks; |
num_tracks = ump->discinfo.num_tracks; |
Line 602 udf_search_tracks(struct udf_mount *ump, |
|
Line 603 udf_search_tracks(struct udf_mount *ump, |
|
if (error || (trackinfo.sessionnr != args->sessionnr)) { |
if (error || (trackinfo.sessionnr != args->sessionnr)) { |
tracknr--; |
tracknr--; |
break; |
break; |
}; |
} |
}; |
} |
if (tracknr > num_tracks) |
if (tracknr > num_tracks) |
tracknr--; |
tracknr--; |
|
|
Line 631 udf_read_anchor(struct udf_mount *ump, u |
|
Line 632 udf_read_anchor(struct udf_mount *ump, u |
|
free(*dst, M_UDFVOLD); |
free(*dst, M_UDFVOLD); |
*dst = NULL; |
*dst = NULL; |
DPRINTF(VOLUMES, ("Not an anchor\n")); |
DPRINTF(VOLUMES, ("Not an anchor\n")); |
}; |
} |
}; |
} |
|
|
return error; |
return error; |
} |
} |
Line 655 udf_read_anchors(struct udf_mount *ump, |
|
Line 656 udf_read_anchors(struct udf_mount *ump, |
|
if (!error) { |
if (!error) { |
first_track.tracknr = first_tracknr; |
first_track.tracknr = first_tracknr; |
error = udf_update_trackinfo(ump, &first_track); |
error = udf_update_trackinfo(ump, &first_track); |
}; |
} |
if (!error) { |
if (!error) { |
last_track.tracknr = last_tracknr; |
last_track.tracknr = last_tracknr; |
error = udf_update_trackinfo(ump, &last_track); |
error = udf_update_trackinfo(ump, &last_track); |
}; |
} |
if (error) { |
if (error) { |
printf("UDF mount: reading disc geometry failed\n"); |
printf("UDF mount: reading disc geometry failed\n"); |
return 0; |
return 0; |
}; |
} |
|
|
track_start = first_track.track_start; |
track_start = first_track.track_start; |
|
|
Line 678 udf_read_anchors(struct udf_mount *ump, |
|
Line 679 udf_read_anchors(struct udf_mount *ump, |
|
else if (last_track.flags & MMC_TRACKINFO_NWA_VALID) |
else if (last_track.flags & MMC_TRACKINFO_NWA_VALID) |
track_end = last_track.next_writable |
track_end = last_track.next_writable |
- ump->discinfo.link_block_penalty; |
- ump->discinfo.link_block_penalty; |
}; |
} |
/* VATs are only recorded on sequential media, but initialise */ |
|
ump->possible_vat_location = track_end; |
|
|
|
/* its no use reading a blank track */ |
/* its no use reading a blank track */ |
first_anchor = 0; |
first_anchor = 0; |
Line 703 udf_read_anchors(struct udf_mount *ump, |
|
Line 702 udf_read_anchors(struct udf_mount *ump, |
|
if (!error) { |
if (!error) { |
anchorsp++; |
anchorsp++; |
ok++; |
ok++; |
}; |
} |
}; |
} |
|
|
|
/* VATs are only recorded on sequential media, but initialise */ |
|
ump->first_possible_vat_location = track_start + 256 + 1; |
|
ump->last_possible_vat_location = track_end |
|
+ ump->discinfo.blockingnr; |
|
|
return ok; |
return ok; |
} |
} |
Line 743 udf_process_vds_descriptor(struct udf_mo |
|
Line 747 udf_process_vds_descriptor(struct udf_mo |
|
if ((udf_rw16(dscr->pd.flags) & UDF_PART_FLAG_ALLOCATED) == 0) { |
if ((udf_rw16(dscr->pd.flags) & UDF_PART_FLAG_ALLOCATED) == 0) { |
free(dscr, M_UDFVOLD); |
free(dscr, M_UDFVOLD); |
break; |
break; |
}; |
} |
|
|
/* check partnr boundaries */ |
/* check partnr boundaries */ |
partnr = udf_rw16(dscr->pd.part_num); |
partnr = udf_rw16(dscr->pd.part_num); |
Line 760 udf_process_vds_descriptor(struct udf_mo |
|
Line 764 udf_process_vds_descriptor(struct udf_mo |
|
DPRINTF(VOLUMES, ("Unhandled VDS type %d\n", |
DPRINTF(VOLUMES, ("Unhandled VDS type %d\n", |
udf_rw16(dscr->tag.id))); |
udf_rw16(dscr->tag.id))); |
free(dscr, M_UDFVOLD); |
free(dscr, M_UDFVOLD); |
}; |
} |
|
|
return 0; |
return 0; |
} |
} |
Line 798 udf_read_vds_extent(struct udf_mount *um |
|
Line 802 udf_read_vds_extent(struct udf_mount *um |
|
if (error) { |
if (error) { |
free(dscr, M_UDFVOLD); |
free(dscr, M_UDFVOLD); |
break; |
break; |
}; |
} |
assert((dscr_size % sector_size) == 0); |
assert((dscr_size % sector_size) == 0); |
|
|
len -= dscr_size; |
len -= dscr_size; |
loc += dscr_size / sector_size; |
loc += dscr_size / sector_size; |
}; |
} |
|
|
return error; |
return error; |
} |
} |
Line 836 udf_read_vds_space(struct udf_mount *ump |
|
Line 840 udf_read_vds_space(struct udf_mount *ump |
|
if (memcmp(&anchor->main_vds_ex, &anchor2->main_vds_ex, size)) |
if (memcmp(&anchor->main_vds_ex, &anchor2->main_vds_ex, size)) |
anchor = anchor2; |
anchor = anchor2; |
/* reserve is specified to be a literal copy of main */ |
/* reserve is specified to be a literal copy of main */ |
}; |
} |
|
|
main_loc = udf_rw32(anchor->main_vds_ex.loc); |
main_loc = udf_rw32(anchor->main_vds_ex.loc); |
main_len = udf_rw32(anchor->main_vds_ex.len); |
main_len = udf_rw32(anchor->main_vds_ex.len); |
Line 848 udf_read_vds_space(struct udf_mount *ump |
|
Line 852 udf_read_vds_space(struct udf_mount *ump |
|
if (error) { |
if (error) { |
printf("UDF mount: reading in reserve VDS extent\n"); |
printf("UDF mount: reading in reserve VDS extent\n"); |
error = udf_read_vds_extent(ump, reserve_loc, reserve_len); |
error = udf_read_vds_extent(ump, reserve_loc, reserve_len); |
}; |
} |
|
|
return error; |
return error; |
} |
} |
Line 889 udf_retrieve_lvint(struct udf_mount *ump |
|
Line 893 udf_retrieve_lvint(struct udf_mount *ump |
|
dscr_type = udf_rw16(dscr->tag.id); |
dscr_type = udf_rw16(dscr->tag.id); |
if (dscr_type == TAGID_TERM) { |
if (dscr_type == TAGID_TERM) { |
break; /* clean terminator */ |
break; /* clean terminator */ |
}; |
} |
if (dscr_type != TAGID_LOGVOL_INTEGRITY) { |
if (dscr_type != TAGID_LOGVOL_INTEGRITY) { |
/* fatal... corrupt disc */ |
/* fatal... corrupt disc */ |
error = ENOENT; |
error = ENOENT; |
break; |
break; |
}; |
} |
if (lvint) |
if (lvint) |
free(lvint, M_UDFVOLD); |
free(lvint, M_UDFVOLD); |
lvint = &dscr->lvid; |
lvint = &dscr->lvid; |
dscr = NULL; |
dscr = NULL; |
}; /* else hope for the best... maybe the next is ok */ |
} /* else hope for the best... maybe the next is ok */ |
|
|
DPRINTFIF(VOLUMES, lvint, ("logvol integrity read, state %s\n", |
DPRINTFIF(VOLUMES, lvint, ("logvol integrity read, state %s\n", |
udf_rw32(lvint->integrity_type) ? "CLOSED" : "OPEN")); |
udf_rw32(lvint->integrity_type) ? "CLOSED" : "OPEN")); |
Line 912 udf_retrieve_lvint(struct udf_mount *ump |
|
Line 916 udf_retrieve_lvint(struct udf_mount *ump |
|
if (lvint->next_extent.len) { |
if (lvint->next_extent.len) { |
len = udf_rw32(lvint->next_extent.len); |
len = udf_rw32(lvint->next_extent.len); |
sector = udf_rw32(lvint->next_extent.loc); |
sector = udf_rw32(lvint->next_extent.loc); |
}; |
} |
}; |
} |
|
|
/* clean up the mess, esp. when there is an error */ |
/* clean up the mess, esp. when there is an error */ |
if (dscr) |
if (dscr) |
Line 922 udf_retrieve_lvint(struct udf_mount *ump |
|
Line 926 udf_retrieve_lvint(struct udf_mount *ump |
|
if (error && lvint) { |
if (error && lvint) { |
free(lvint, M_UDFVOLD); |
free(lvint, M_UDFVOLD); |
lvint = NULL; |
lvint = NULL; |
}; |
} |
|
|
if (!lvint) |
if (!lvint) |
error = ENOENT; |
error = ENOENT; |
Line 970 udf_process_vds(struct udf_mount *ump, s |
|
Line 974 udf_process_vds(struct udf_mount *ump, s |
|
if (udf_rw32(ump->logical_vol->lb_size) != ump->discinfo.sector_size) { |
if (udf_rw32(ump->logical_vol->lb_size) != ump->discinfo.sector_size) { |
printf("UDF mount: format violation, lb_size != sector size\n"); |
printf("UDF mount: format violation, lb_size != sector size\n"); |
return EINVAL; |
return EINVAL; |
}; |
} |
|
|
domain_name = ump->logical_vol->domain_id.id; |
domain_name = ump->logical_vol->domain_id.id; |
if (strncmp(domain_name, "*OSTA UDF Compliant", 20)) { |
if (strncmp(domain_name, "*OSTA UDF Compliant", 20)) { |
printf("mount_udf: disc not OSTA UDF Compliant, aborting\n"); |
printf("mount_udf: disc not OSTA UDF Compliant, aborting\n"); |
return EINVAL; |
return EINVAL; |
}; |
} |
|
|
/* retrieve logical volume integrity sequence */ |
/* retrieve logical volume integrity sequence */ |
error = udf_retrieve_lvint(ump, &ump->logvol_integrity); |
error = udf_retrieve_lvint(ump, &ump->logvol_integrity); |
Line 1010 udf_process_vds(struct udf_mount *ump, s |
|
Line 1014 udf_process_vds(struct udf_mount *ump, s |
|
if (n_pm > UDF_PMAPS) { |
if (n_pm > UDF_PMAPS) { |
printf("UDF mount: too many mappings\n"); |
printf("UDF mount: too many mappings\n"); |
return EINVAL; |
return EINVAL; |
}; |
} |
|
|
n_phys = n_virt = n_spar = n_meta = 0; |
n_phys = n_virt = n_spar = n_meta = 0; |
for (log_part = 0; log_part < n_pm; log_part++) { |
for (log_part = 0; log_part < n_pm; log_part++) { |
Line 1036 udf_process_vds(struct udf_mount *ump, s |
|
Line 1040 udf_process_vds(struct udf_mount *ump, s |
|
pmap_type = UDF_VTOP_TYPE_VIRT; |
pmap_type = UDF_VTOP_TYPE_VIRT; |
n_virt++; |
n_virt++; |
break; |
break; |
}; |
} |
check_name = "*UDF Sparable Partition"; |
check_name = "*UDF Sparable Partition"; |
if (strncmp(map_name, check_name, len) == 0) { |
if (strncmp(map_name, check_name, len) == 0) { |
pmap_type = UDF_VTOP_TYPE_SPARABLE; |
pmap_type = UDF_VTOP_TYPE_SPARABLE; |
n_spar++; |
n_spar++; |
break; |
break; |
}; |
} |
check_name = "*UDF Metadata Partition"; |
check_name = "*UDF Metadata Partition"; |
if (strncmp(map_name, check_name, len) == 0) { |
if (strncmp(map_name, check_name, len) == 0) { |
pmap_type = UDF_VTOP_TYPE_META; |
pmap_type = UDF_VTOP_TYPE_META; |
n_meta++; |
n_meta++; |
break; |
break; |
}; |
} |
break; |
break; |
default: |
default: |
return EINVAL; |
return EINVAL; |
}; |
} |
|
|
DPRINTF(VOLUMES, ("\t%d -> %d type %d\n", log_part, phys_part, |
DPRINTF(VOLUMES, ("\t%d -> %d type %d\n", log_part, phys_part, |
pmap_type)); |
pmap_type)); |
Line 1063 udf_process_vds(struct udf_mount *ump, s |
|
Line 1067 udf_process_vds(struct udf_mount *ump, s |
|
ump->vtop_tp[log_part] = pmap_type; |
ump->vtop_tp[log_part] = pmap_type; |
|
|
pmap_pos += pmap_size; |
pmap_pos += pmap_size; |
}; |
} |
/* not winning the beauty contest */ |
/* not winning the beauty contest */ |
ump->vtop_tp[UDF_VTOP_RAWPART] = UDF_VTOP_TYPE_RAW; |
ump->vtop_tp[UDF_VTOP_RAWPART] = UDF_VTOP_TYPE_RAW; |
|
|
Line 1074 udf_process_vds(struct udf_mount *ump, s |
|
Line 1078 udf_process_vds(struct udf_mount *ump, s |
|
if (n_virt) { |
if (n_virt) { |
if ((n_phys == 0) || n_spar || n_meta) |
if ((n_phys == 0) || n_spar || n_meta) |
return EINVAL; |
return EINVAL; |
}; |
} |
if (n_spar + n_phys == 0) |
if (n_spar + n_phys == 0) |
return EINVAL; |
return EINVAL; |
|
|
Line 1096 udf_process_vds(struct udf_mount *ump, s |
|
Line 1100 udf_process_vds(struct udf_mount *ump, s |
|
ump->meta_alloc = UDF_ALLOC_METASEQUENTIAL; |
ump->meta_alloc = UDF_ALLOC_METASEQUENTIAL; |
} else { |
} else { |
ump->meta_alloc = UDF_ALLOC_RELAXEDSEQUENTIAL; |
ump->meta_alloc = UDF_ALLOC_RELAXEDSEQUENTIAL; |
}; |
} |
}; |
} |
|
|
DPRINTF(VOLUMES, ("\tdata alloc scheme %d, meta alloc scheme %d\n", |
DPRINTF(VOLUMES, ("\tdata alloc scheme %d, meta alloc scheme %d\n", |
ump->data_alloc, ump->meta_alloc)); |
ump->data_alloc, ump->meta_alloc)); |
Line 1153 udf_check_for_vat(struct udf_node *vat_n |
|
Line 1157 udf_check_for_vat(struct udf_node *vat_n |
|
vat_length = udf_rw64(vat_node->efe->inf_len); |
vat_length = udf_rw64(vat_node->efe->inf_len); |
icbtag = &vat_node->efe->icbtag; |
icbtag = &vat_node->efe->icbtag; |
mtime = &vat_node->efe->mtime; |
mtime = &vat_node->efe->mtime; |
}; |
} |
|
|
/* Check icb filetype! it has to be 0 or UDF_ICB_FILETYPE_VAT */ |
/* Check icb filetype! it has to be 0 or UDF_ICB_FILETYPE_VAT */ |
filetype = icbtag->file_type; |
filetype = icbtag->file_type; |
Line 1188 udf_check_for_vat(struct udf_node *vat_n |
|
Line 1192 udf_check_for_vat(struct udf_node *vat_n |
|
free(ump->vat_table, M_UDFMNT); |
free(ump->vat_table, M_UDFMNT); |
ump->vat_table = NULL; |
ump->vat_table = NULL; |
return error; |
return error; |
}; |
} |
DPRINTF(VOLUMES, ("VAT read in fine!\n")); |
DPRINTF(VOLUMES, ("VAT read in fine!\n")); |
|
|
/* |
/* |
Line 1213 udf_check_for_vat(struct udf_node *vat_n |
|
Line 1217 udf_check_for_vat(struct udf_node *vat_n |
|
free(ump->vat_table, M_UDFMNT); |
free(ump->vat_table, M_UDFMNT); |
ump->vat_table = NULL; |
ump->vat_table = NULL; |
return ENOENT; |
return ENOENT; |
}; |
} |
/* TODO update LVID from "*UDF VAT LVExtension" ext. attr. */ |
/* TODO update LVID from "*UDF VAT LVExtension" ext. attr. */ |
} else { |
} else { |
vat = (struct udf_vat *) raw_vat; |
vat = (struct udf_vat *) raw_vat; |
Line 1228 udf_check_for_vat(struct udf_node *vat_n |
|
Line 1232 udf_check_for_vat(struct udf_node *vat_n |
|
lvinfo->min_udf_readver = vat->min_udf_readver; |
lvinfo->min_udf_readver = vat->min_udf_readver; |
lvinfo->min_udf_writever = vat->min_udf_writever; |
lvinfo->min_udf_writever = vat->min_udf_writever; |
lvinfo->max_udf_writever = vat->max_udf_writever; |
lvinfo->max_udf_writever = vat->max_udf_writever; |
}; |
} |
|
|
ump->vat_offset = vat_offset; |
ump->vat_offset = vat_offset; |
ump->vat_entries = vat_entries; |
ump->vat_entries = vat_entries; |
Line 1253 udf_search_vat(struct udf_mount *ump, un |
|
Line 1257 udf_search_vat(struct udf_mount *ump, un |
|
/* mapping info not needed */ |
/* mapping info not needed */ |
mapping = mapping; |
mapping = mapping; |
|
|
vat_loc = ump->possible_vat_location; |
vat_loc = ump->last_possible_vat_location; |
early_vat_loc = vat_loc - 20; |
early_vat_loc = vat_loc - 2 * ump->discinfo.blockingnr; |
|
early_vat_loc = MAX(early_vat_loc, ump->first_possible_vat_location); |
late_vat_loc = vat_loc + 1024; |
late_vat_loc = vat_loc + 1024; |
|
|
/* TODO first search last sector? */ |
/* TODO first search last sector? */ |
Line 1269 udf_search_vat(struct udf_mount *ump, un |
|
Line 1274 udf_search_vat(struct udf_mount *ump, un |
|
if (vat_node) { |
if (vat_node) { |
vput(vat_node->vnode); |
vput(vat_node->vnode); |
udf_dispose_node(vat_node); |
udf_dispose_node(vat_node); |
}; |
} |
vat_loc--; /* walk backwards */ |
vat_loc--; /* walk backwards */ |
} while (vat_loc >= early_vat_loc); |
} while (vat_loc >= early_vat_loc); |
|
|
Line 1277 udf_search_vat(struct udf_mount *ump, un |
|
Line 1282 udf_search_vat(struct udf_mount *ump, un |
|
if (vat_node) { |
if (vat_node) { |
vput(vat_node->vnode); |
vput(vat_node->vnode); |
udf_dispose_node(vat_node); |
udf_dispose_node(vat_node); |
}; |
} |
|
|
return error; |
return error; |
} |
} |
Line 1314 udf_read_sparables(struct udf_mount *ump |
|
Line 1319 udf_read_sparables(struct udf_mount *ump |
|
("Sparing table accepted (%d entries)\n", |
("Sparing table accepted (%d entries)\n", |
udf_rw16(ump->sparing_table->rt_l))); |
udf_rw16(ump->sparing_table->rt_l))); |
break; /* we're done */ |
break; /* we're done */ |
}; |
} |
}; |
} |
if (dscr) |
if (dscr) |
free(dscr, M_UDFVOLD); |
free(dscr, M_UDFVOLD); |
}; |
} |
|
|
if (ump->sparing_table) |
if (ump->sparing_table) |
return 0; |
return 0; |
Line 1364 udf_read_vds_tables(struct udf_mount *um |
|
Line 1369 udf_read_vds_tables(struct udf_mount *um |
|
break; |
break; |
default: |
default: |
break; |
break; |
}; |
} |
pmap_size = pmap_pos[1]; |
pmap_size = pmap_pos[1]; |
pmap_pos += pmap_size; |
pmap_pos += pmap_size; |
}; |
} |
|
|
return 0; |
return 0; |
} |
} |
Line 1411 udf_read_rootdirs(struct udf_mount *ump, |
|
Line 1416 udf_read_rootdirs(struct udf_mount *ump, |
|
if (dscr_type != TAGID_FSD) { |
if (dscr_type != TAGID_FSD) { |
free(dscr, M_UDFVOLD); |
free(dscr, M_UDFVOLD); |
return ENOENT; |
return ENOENT; |
}; |
} |
|
|
/* |
/* |
* TODO check for multiple fileset descriptors; its only |
* TODO check for multiple fileset descriptors; its only |
Line 1422 udf_read_rootdirs(struct udf_mount *ump, |
|
Line 1427 udf_read_rootdirs(struct udf_mount *ump, |
|
/* update */ |
/* update */ |
if (ump->fileset_desc) { |
if (ump->fileset_desc) { |
free(ump->fileset_desc, M_UDFVOLD); |
free(ump->fileset_desc, M_UDFVOLD); |
}; |
} |
ump->fileset_desc = &dscr->fsd; |
ump->fileset_desc = &dscr->fsd; |
dscr = NULL; |
dscr = NULL; |
|
|
Line 1435 udf_read_rootdirs(struct udf_mount *ump, |
|
Line 1440 udf_read_rootdirs(struct udf_mount *ump, |
|
DPRINTF(VOLUMES, ("follow up FSD extent\n")); |
DPRINTF(VOLUMES, ("follow up FSD extent\n")); |
fsd_loc = ump->fileset_desc->next_ex; |
fsd_loc = ump->fileset_desc->next_ex; |
fsd_len = udf_rw32(ump->fileset_desc->next_ex.len); |
fsd_len = udf_rw32(ump->fileset_desc->next_ex.len); |
}; |
} |
}; |
} |
if (dscr) |
if (dscr) |
free(dscr, M_UDFVOLD); |
free(dscr, M_UDFVOLD); |
|
|
Line 1478 udf_read_rootdirs(struct udf_mount *ump, |
|
Line 1483 udf_read_rootdirs(struct udf_mount *ump, |
|
* TODO process streamdir `baddies' i.e. files we dont |
* TODO process streamdir `baddies' i.e. files we dont |
* want if R/W |
* want if R/W |
*/ |
*/ |
}; |
} |
}; |
} |
|
|
DPRINTF(VOLUMES, ("Rootdir(s) read in fine\n")); |
DPRINTF(VOLUMES, ("Rootdir(s) read in fine\n")); |
|
|
/* release the vnodes again; they'll be auto-recycled later */ |
/* release the vnodes again; they'll be auto-recycled later */ |
if (streamdir_node) { |
if (streamdir_node) { |
vput(streamdir_node->vnode); |
vput(streamdir_node->vnode); |
}; |
} |
if (rootdir_node) { |
if (rootdir_node) { |
vput(rootdir_node->vnode); |
vput(rootdir_node->vnode); |
}; |
} |
|
|
return 0; |
return 0; |
} |
} |
Line 1561 udf_translate_vtop(struct udf_mount *ump |
|
Line 1566 udf_translate_vtop(struct udf_mount *ump |
|
*lb_numres = udf_rw32(sme->map) + lb_rel; |
*lb_numres = udf_rw32(sme->map) + lb_rel; |
*extres = ump->sparable_packet_len - lb_rel; |
*extres = ump->sparable_packet_len - lb_rel; |
return 0; |
return 0; |
}; |
} |
}; |
} |
|
|
/* transform into its disc logical block */ |
/* transform into its disc logical block */ |
part = ump->vtop[vpart]; |
part = ump->vtop[vpart]; |
Line 1578 udf_translate_vtop(struct udf_mount *ump |
|
Line 1583 udf_translate_vtop(struct udf_mount *ump |
|
default: |
default: |
printf("UDF vtop translation scheme %d unimplemented yet\n", |
printf("UDF vtop translation scheme %d unimplemented yet\n", |
ump->vtop_tp[vpart]); |
ump->vtop_tp[vpart]); |
}; |
} |
|
|
return EINVAL; |
return EINVAL; |
} |
} |
|
|
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK)) |
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK)) |
goto loop; |
goto loop; |
return unp; |
return unp; |
}; |
} |
}; |
} |
simple_unlock(&ump->ihash_slock); |
simple_unlock(&ump->ihash_slock); |
|
|
return NULL; |
return NULL; |
}; |
} |
|
|
/* --------------------------------------------------------------------- */ |
/* --------------------------------------------------------------------- */ |
|
|
Line 1680 udf_dispose_node(struct udf_node *node) |
|
Line 1685 udf_dispose_node(struct udf_node *node) |
|
if (!node) { |
if (!node) { |
DPRINTF(NODE, ("UDF: Dispose node on node NULL, ignoring\n")); |
DPRINTF(NODE, ("UDF: Dispose node on node NULL, ignoring\n")); |
return 0; |
return 0; |
}; |
} |
|
|
vp = node->vnode; |
vp = node->vnode; |
|
|
Line 1694 udf_dispose_node(struct udf_node *node) |
|
Line 1699 udf_dispose_node(struct udf_node *node) |
|
|
|
/* free associated memory and the node itself */ |
/* free associated memory and the node itself */ |
if (node->fe) |
if (node->fe) |
pool_put(&node->ump->desc_pool, node->fe); |
pool_put(node->ump->desc_pool, node->fe); |
if (node->efe) |
if (node->efe) |
pool_put(&node->ump->desc_pool, node->efe); |
pool_put(node->ump->desc_pool, node->efe); |
pool_put(&udf_node_pool, node); |
pool_put(&udf_node_pool, node); |
|
|
return 0; |
return 0; |
Line 1716 udf_dispose_node(struct udf_node *node) |
|
Line 1721 udf_dispose_node(struct udf_node *node) |
|
* putpages interface code |
* putpages interface code |
* .gop_markupdate = udf_gop_markupdate, |
* .gop_markupdate = udf_gop_markupdate, |
* set update/modify flags etc. |
* set update/modify flags etc. |
* }; |
* } |
*/ |
*/ |
|
|
/* |
/* |
Line 1727 udf_dispose_node(struct udf_node *node) |
|
Line 1732 udf_dispose_node(struct udf_node *node) |
|
|
|
static int |
static int |
udf_gop_alloc(struct vnode *vp, off_t off, off_t len, int flags, |
udf_gop_alloc(struct vnode *vp, off_t off, off_t len, int flags, |
struct ucred *cred) |
kauth_cred_t cred) |
{ |
{ |
return 0; |
return 0; |
} |
} |
Line 1808 udf_get_node(struct udf_mount *ump, stru |
|
Line 1813 udf_get_node(struct udf_mount *ump, stru |
|
*noderes = node; |
*noderes = node; |
lockmgr(&ump->get_node_lock, LK_RELEASE, NULL); |
lockmgr(&ump->get_node_lock, LK_RELEASE, NULL); |
return 0; |
return 0; |
}; |
} |
|
|
/* garbage check: translate node_icb_loc to sectornr */ |
/* garbage check: translate node_icb_loc to sectornr */ |
error = udf_translate_vtop(ump, node_icb_loc, §or, &dummy); |
error = udf_translate_vtop(ump, node_icb_loc, §or, &dummy); |
Line 1816 udf_get_node(struct udf_mount *ump, stru |
|
Line 1821 udf_get_node(struct udf_mount *ump, stru |
|
/* no use, this will fail anyway */ |
/* no use, this will fail anyway */ |
lockmgr(&ump->get_node_lock, LK_RELEASE, NULL); |
lockmgr(&ump->get_node_lock, LK_RELEASE, NULL); |
return EINVAL; |
return EINVAL; |
}; |
} |
|
|
/* build node (do initialise!) */ |
/* build node (do initialise!) */ |
node = pool_get(&udf_node_pool, PR_WAITOK); |
node = pool_get(&udf_node_pool, PR_WAITOK); |
Line 1829 udf_get_node(struct udf_mount *ump, stru |
|
Line 1834 udf_get_node(struct udf_mount *ump, stru |
|
pool_put(&udf_node_pool, node); |
pool_put(&udf_node_pool, node); |
lockmgr(&ump->get_node_lock, LK_RELEASE, NULL); |
lockmgr(&ump->get_node_lock, LK_RELEASE, NULL); |
return error; |
return error; |
}; |
} |
|
|
/* allways return locked vnode */ |
/* allways return locked vnode */ |
if ((error = vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY))) { |
if ((error = vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY))) { |
Line 1837 udf_get_node(struct udf_mount *ump, stru |
|
Line 1842 udf_get_node(struct udf_mount *ump, stru |
|
ungetnewvnode(nvp); |
ungetnewvnode(nvp); |
lockmgr(&ump->get_node_lock, LK_RELEASE, NULL); |
lockmgr(&ump->get_node_lock, LK_RELEASE, NULL); |
return error; |
return error; |
}; |
} |
|
|
/* initialise crosslinks, note location of fe/efe for hashing */ |
/* initialise crosslinks, note location of fe/efe for hashing */ |
node->ump = ump; |
node->ump = ump; |
Line 1884 udf_get_node(struct udf_mount *ump, stru |
|
Line 1889 udf_get_node(struct udf_mount *ump, stru |
|
icb_loc = tmpdscr->inde.indirect_icb; |
icb_loc = tmpdscr->inde.indirect_icb; |
free(tmpdscr, M_UDFTEMP); |
free(tmpdscr, M_UDFTEMP); |
continue; |
continue; |
}; |
} |
|
|
/* only file entries and extended file entries allowed here */ |
/* only file entries and extended file entries allowed here */ |
if ((dscr_type != TAGID_FENTRY) && |
if ((dscr_type != TAGID_FENTRY) && |
Line 1892 udf_get_node(struct udf_mount *ump, stru |
|
Line 1897 udf_get_node(struct udf_mount *ump, stru |
|
free(tmpdscr, M_UDFTEMP); |
free(tmpdscr, M_UDFTEMP); |
error = ENOENT; |
error = ENOENT; |
break; |
break; |
}; |
} |
|
|
/* get descriptor space from our pool */ |
/* get descriptor space from our pool */ |
KASSERT(udf_tagsize(tmpdscr, lb_size) == lb_size); |
KASSERT(udf_tagsize(tmpdscr, lb_size) == lb_size); |
|
|
dscr = pool_get(&ump->desc_pool, PR_WAITOK); |
dscr = pool_get(ump->desc_pool, PR_WAITOK); |
memcpy(dscr, tmpdscr, lb_size); |
memcpy(dscr, tmpdscr, lb_size); |
free(tmpdscr, M_UDFTEMP); |
free(tmpdscr, M_UDFTEMP); |
|
|
/* record and process/update (ext)fentry */ |
/* record and process/update (ext)fentry */ |
if (dscr_type == TAGID_FENTRY) { |
if (dscr_type == TAGID_FENTRY) { |
if (node->fe) |
if (node->fe) |
pool_put(&ump->desc_pool, node->fe); |
pool_put(ump->desc_pool, node->fe); |
node->fe = &dscr->fe; |
node->fe = &dscr->fe; |
strat = udf_rw16(node->fe->icbtag.strat_type); |
strat = udf_rw16(node->fe->icbtag.strat_type); |
udf_file_type = node->fe->icbtag.file_type; |
udf_file_type = node->fe->icbtag.file_type; |
file_size = udf_rw64(node->fe->inf_len); |
file_size = udf_rw64(node->fe->inf_len); |
} else { |
} else { |
if (node->efe) |
if (node->efe) |
pool_put(&ump->desc_pool, node->efe); |
pool_put(ump->desc_pool, node->efe); |
node->efe = &dscr->efe; |
node->efe = &dscr->efe; |
strat = udf_rw16(node->efe->icbtag.strat_type); |
strat = udf_rw16(node->efe->icbtag.strat_type); |
udf_file_type = node->efe->icbtag.file_type; |
udf_file_type = node->efe->icbtag.file_type; |
file_size = udf_rw64(node->efe->inf_len); |
file_size = udf_rw64(node->efe->inf_len); |
}; |
} |
|
|
/* check recording strategy (structure) */ |
/* check recording strategy (structure) */ |
|
|
Line 1931 udf_get_node(struct udf_mount *ump, stru |
|
Line 1936 udf_get_node(struct udf_mount *ump, stru |
|
needs_indirect = 1; |
needs_indirect = 1; |
|
|
icb_loc.loc.lb_num = udf_rw32(icb_loc.loc.lb_num) + 1; |
icb_loc.loc.lb_num = udf_rw32(icb_loc.loc.lb_num) + 1; |
}; |
} |
|
|
/* |
/* |
* Strategy 4 is the normal strategy and terminates, but if |
* Strategy 4 is the normal strategy and terminates, but if |
Line 1942 udf_get_node(struct udf_mount *ump, stru |
|
Line 1947 udf_get_node(struct udf_mount *ump, stru |
|
if (strat4096) { |
if (strat4096) { |
error = EINVAL; |
error = EINVAL; |
break; |
break; |
}; |
} |
break; /* done */ |
break; /* done */ |
}; |
} |
} while (!error); |
} while (!error); |
|
|
if (error) { |
if (error) { |
Line 1956 udf_get_node(struct udf_mount *ump, stru |
|
Line 1961 udf_get_node(struct udf_mount *ump, stru |
|
ungetnewvnode(nvp); |
ungetnewvnode(nvp); |
|
|
return EINVAL; /* error code ok? */ |
return EINVAL; /* error code ok? */ |
}; |
} |
|
|
/* post process and initialise node */ |
/* post process and initialise node */ |
|
|
Line 2009 udf_get_node(struct udf_mount *ump, stru |
|
Line 2014 udf_get_node(struct udf_mount *ump, stru |
|
default: |
default: |
/* YIKES, either a block/char device, fifo or something else */ |
/* YIKES, either a block/char device, fifo or something else */ |
nvp->v_type = VNON; |
nvp->v_type = VNON; |
}; |
} |
|
|
/* initialise genfs */ |
/* initialise genfs */ |
genfs_node_init(nvp, &udf_genfsops); |
genfs_node_init(nvp, &udf_genfsops); |
Line 2082 udf_icb_to_unix_filetype(uint32_t icbfty |
|
Line 2087 udf_icb_to_unix_filetype(uint32_t icbfty |
|
return S_IFLNK; |
return S_IFLNK; |
case UDF_ICB_FILETYPE_SOCKET : |
case UDF_ICB_FILETYPE_SOCKET : |
return S_IFSOCK; |
return S_IFSOCK; |
}; |
} |
/* no idea what this is */ |
/* no idea what this is */ |
return 0; |
return 0; |
} |
} |
Line 2094 udf_icb_to_unix_filetype(uint32_t icbfty |
|
Line 2099 udf_icb_to_unix_filetype(uint32_t icbfty |
|
void |
void |
udf_to_unix_name(char *result, char *id, int len, struct charspec *chsp) |
udf_to_unix_name(char *result, char *id, int len, struct charspec *chsp) |
{ |
{ |
uint16_t raw_name[1024], unix_name[1024]; |
uint16_t *raw_name, *unix_name; |
uint16_t *inchp, ch; |
uint16_t *inchp, ch; |
uint8_t *outchp; |
uint8_t *outchp; |
int ucode_chars, nice_uchars; |
int ucode_chars, nice_uchars; |
|
|
|
raw_name = malloc(2048 * sizeof(uint16_t), M_UDFTEMP, M_WAITOK); |
|
unix_name = raw_name + 1024; /* split space in half */ |
assert(sizeof(char) == sizeof(uint8_t)); |
assert(sizeof(char) == sizeof(uint8_t)); |
outchp = (uint8_t *) result; |
outchp = (uint8_t *) result; |
if ((chsp->type == 0) && (strcmp((char*) chsp->inf, "OSTA Compressed Unicode") == 0)) { |
if ((chsp->type == 0) && (strcmp((char*) chsp->inf, "OSTA Compressed Unicode") == 0)) { |
Line 2111 udf_to_unix_name(char *result, char *id, |
|
Line 2118 udf_to_unix_name(char *result, char *id, |
|
/* XXX sloppy unicode -> latin */ |
/* XXX sloppy unicode -> latin */ |
*outchp++ = ch & 255; |
*outchp++ = ch & 255; |
if (!ch) break; |
if (!ch) break; |
}; |
} |
*outchp++ = 0; |
*outchp++ = 0; |
} else { |
} else { |
/* assume 8bit char length byte latin-1 */ |
/* assume 8bit char length byte latin-1 */ |
assert(*id == 8); |
assert(*id == 8); |
strncpy((char *) result, (char *) (id+1), strlen((char *) (id+1))); |
strncpy((char *) result, (char *) (id+1), strlen((char *) (id+1))); |
}; |
} |
|
free(raw_name, M_UDFTEMP); |
} |
} |
|
|
/* --------------------------------------------------------------------- */ |
/* --------------------------------------------------------------------- */ |
|
|
unix_to_udf_name(char *result, char *name, |
unix_to_udf_name(char *result, char *name, |
uint8_t *result_len, struct charspec *chsp) |
uint8_t *result_len, struct charspec *chsp) |
{ |
{ |
uint16_t raw_name[1024]; |
uint16_t *raw_name; |
int udf_chars, name_len; |
int udf_chars, name_len; |
char *inchp; |
char *inchp; |
uint16_t *outchp; |
uint16_t *outchp; |
|
|
|
raw_name = malloc(1024, M_UDFTEMP, M_WAITOK); |
/* convert latin-1 or whatever to unicode-16 */ |
/* convert latin-1 or whatever to unicode-16 */ |
*raw_name = 0; |
*raw_name = 0; |
name_len = 0; |
name_len = 0; |
Line 2141 unix_to_udf_name(char *result, char *nam |
|
Line 2150 unix_to_udf_name(char *result, char *nam |
|
while (*inchp) { |
while (*inchp) { |
*outchp++ = (uint16_t) (*inchp++); |
*outchp++ = (uint16_t) (*inchp++); |
name_len++; |
name_len++; |
}; |
} |
|
|
if ((chsp->type == 0) && (strcmp((char *) chsp->inf, "OSTA Compressed Unicode") == 0)) { |
if ((chsp->type == 0) && (strcmp((char *) chsp->inf, "OSTA Compressed Unicode") == 0)) { |
udf_chars = udf_CompressUnicode(name_len, 8, (unicode_t *) raw_name, (byte *) result); |
udf_chars = udf_CompressUnicode(name_len, 8, (unicode_t *) raw_name, (byte *) result); |
Line 2150 unix_to_udf_name(char *result, char *nam |
|
Line 2159 unix_to_udf_name(char *result, char *nam |
|
*result++ = 8; udf_chars = 1; |
*result++ = 8; udf_chars = 1; |
strncpy(result, name + 1, strlen(name+1)); |
strncpy(result, name + 1, strlen(name+1)); |
udf_chars += strlen(name); |
udf_chars += strlen(name); |
}; |
} |
*result_len = udf_chars; |
*result_len = udf_chars; |
|
free(raw_name, M_UDFTEMP); |
} |
} |
|
|
/* --------------------------------------------------------------------- */ |
/* --------------------------------------------------------------------- */ |
Line 2242 udf_timestamp_to_timespec(struct udf_mou |
|
Line 2252 udf_timestamp_to_timespec(struct udf_mou |
|
secs -= (int16_t) tz * 60; |
secs -= (int16_t) tz * 60; |
} else { |
} else { |
secs -= ump->mount_args.gmtoff; |
secs -= ump->mount_args.gmtoff; |
}; |
} |
|
|
timespec->tv_sec = secs; |
timespec->tv_sec = secs; |
timespec->tv_nsec = nsecs; |
timespec->tv_nsec = nsecs; |
Line 2274 udf_getaccessmode(struct udf_node *udf_n |
|
Line 2284 udf_getaccessmode(struct udf_node *udf_n |
|
udf_perm = udf_rw32(efe->perm); |
udf_perm = udf_rw32(efe->perm); |
icbftype = efe->icbtag.file_type; |
icbftype = efe->icbtag.file_type; |
icbflags = udf_rw16(efe->icbtag.flags); |
icbflags = udf_rw16(efe->icbtag.flags); |
}; |
} |
|
|
mode = udf_perm_to_unix_mode(udf_perm); |
mode = udf_perm_to_unix_mode(udf_perm); |
ftype = udf_icb_to_unix_filetype(icbftype); |
ftype = udf_icb_to_unix_filetype(icbftype); |
Line 2317 udf_lookup_name_in_dir(struct vnode *vp, |
|
Line 2327 udf_lookup_name_in_dir(struct vnode *vp, |
|
assert(dir_node->efe); |
assert(dir_node->efe); |
efe = dir_node->efe; |
efe = dir_node->efe; |
file_size = udf_rw64(efe->inf_len); |
file_size = udf_rw64(efe->inf_len); |
}; |
} |
|
|
/* allocate temporary space for fid */ |
/* allocate temporary space for fid */ |
lb_size = udf_rw32(dir_node->ump->logical_vol->lb_size); |
lb_size = udf_rw32(dir_node->ump->logical_vol->lb_size); |
Line 2339 udf_lookup_name_in_dir(struct vnode *vp, |
|
Line 2349 udf_lookup_name_in_dir(struct vnode *vp, |
|
(strncmp(dirent.d_name, name, namelen) == 0)) { |
(strncmp(dirent.d_name, name, namelen) == 0)) { |
found = 1; |
found = 1; |
*icb_loc = fid->icb; |
*icb_loc = fid->icb; |
}; |
} |
}; |
} |
free(fid, M_TEMP); |
free(fid, M_TEMP); |
|
|
return found; |
return found; |
Line 2383 udf_read_fid_stream(struct vnode *vp, ui |
|
Line 2393 udf_read_fid_stream(struct vnode *vp, ui |
|
assert(dir_node->efe); |
assert(dir_node->efe); |
efe = dir_node->efe; |
efe = dir_node->efe; |
file_size = udf_rw64(efe->inf_len); |
file_size = udf_rw64(efe->inf_len); |
}; |
} |
if (*offset >= file_size) |
if (*offset >= file_size) |
return EINVAL; |
return EINVAL; |
|
|
Line 2423 udf_read_fid_stream(struct vnode *vp, ui |
|
Line 2433 udf_read_fid_stream(struct vnode *vp, ui |
|
if (!enough) { |
if (!enough) { |
/* short dir ... */ |
/* short dir ... */ |
return EIO; |
return EIO; |
}; |
} |
|
|
/* check if our FID header is OK */ |
/* check if our FID header is OK */ |
error = udf_check_tag(fid); |
error = udf_check_tag(fid); |
Line 2431 udf_read_fid_stream(struct vnode *vp, ui |
|
Line 2441 udf_read_fid_stream(struct vnode *vp, ui |
|
if (!error) { |
if (!error) { |
if (udf_rw16(fid->tag.id) != TAGID_FID) |
if (udf_rw16(fid->tag.id) != TAGID_FID) |
error = ENOENT; |
error = ENOENT; |
}; |
} |
DPRINTFIF(FIDS, !error, ("\ttag checked ok: got TAGID_FID\n")); |
DPRINTFIF(FIDS, !error, ("\ttag checked ok: got TAGID_FID\n")); |
|
|
/* check for length */ |
/* check for length */ |
if (!error) { |
if (!error) { |
entry_length = udf_fidsize(fid, lb_size); |
entry_length = udf_fidsize(fid, lb_size); |
enough = (dir_uio.uio_offset - (*offset) >= entry_length); |
enough = (dir_uio.uio_offset - (*offset) >= entry_length); |
}; |
} |
DPRINTFIF(FIDS, !error, ("\tentry_length = %d, enough = %s\n", |
DPRINTFIF(FIDS, !error, ("\tentry_length = %d, enough = %s\n", |
entry_length, enough?"yes":"no")); |
entry_length, enough?"yes":"no")); |
|
|
if (!enough) { |
if (!enough) { |
/* short dir ... bomb out */ |
/* short dir ... bomb out */ |
return EIO; |
return EIO; |
}; |
} |
|
|
/* check FID contents */ |
/* check FID contents */ |
if (!error) { |
if (!error) { |
error = udf_check_tag_payload((union dscrptr *) fid, lb_size); |
error = udf_check_tag_payload((union dscrptr *) fid, lb_size); |
DPRINTF(FIDS, ("\tpayload checked ok\n")); |
DPRINTF(FIDS, ("\tpayload checked ok\n")); |
}; |
} |
if (error) { |
if (error) { |
/* note that is sometimes a bit quick to report */ |
/* note that is sometimes a bit quick to report */ |
printf("BROKEN DIRECTORY ENTRY\n"); |
printf("BROKEN DIRECTORY ENTRY\n"); |
/* RESYNC? */ |
/* RESYNC? */ |
/* TODO: use udf_resync_fid_stream */ |
/* TODO: use udf_resync_fid_stream */ |
return EIO; |
return EIO; |
}; |
} |
DPRINTF(FIDS, ("\tinterpret FID\n")); |
DPRINTF(FIDS, ("\tinterpret FID\n")); |
|
|
/* we got a whole and valid descriptor! */ |
/* we got a whole and valid descriptor! */ |
Line 2523 udf_read_internal(struct udf_node *node, |
|
Line 2533 udf_read_internal(struct udf_node *node, |
|
inflen = udf_rw64(fe->inf_len); |
inflen = udf_rw64(fe->inf_len); |
pos = &fe->data[0] + udf_rw32(fe->l_ea); |
pos = &fe->data[0] + udf_rw32(fe->l_ea); |
icbflags = udf_rw16(fe->icbtag.flags); |
icbflags = udf_rw16(fe->icbtag.flags); |
}; |
} |
if (efe) { |
if (efe) { |
inflen = udf_rw64(efe->inf_len); |
inflen = udf_rw64(efe->inf_len); |
pos = &efe->data[0] + udf_rw32(efe->l_ea); |
pos = &efe->data[0] + udf_rw32(efe->l_ea); |
icbflags = udf_rw16(efe->icbtag.flags); |
icbflags = udf_rw16(efe->icbtag.flags); |
}; |
} |
addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK; |
addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK; |
|
|
assert(addr_type == UDF_ICB_INTERN_ALLOC); |
assert(addr_type == UDF_ICB_INTERN_ALLOC); |
Line 2587 udf_read_file_extent(struct udf_node *no |
|
Line 2597 udf_read_file_extent(struct udf_node *no |
|
*/ |
*/ |
|
|
|
|
/* mininum of 128 translations (!) (64 kb in 512 byte sectors) */ |
/* maximum of 128 translations (!) (64 kb in 512 byte sectors) */ |
#define FILEBUFSECT 128 |
#define FILEBUFSECT 128 |
|
|
void |
void |
udf_read_filebuf(struct udf_node *node, struct buf *buf) |
udf_read_filebuf(struct udf_node *node, struct buf *buf) |
{ |
{ |
struct buf *nestbuf; |
struct buf *nestbuf; |
uint64_t mapping[FILEBUFSECT]; |
uint64_t *mapping; |
uint64_t run_start; |
uint64_t run_start; |
uint32_t sector_size; |
uint32_t sector_size; |
uint32_t buf_offset, sector, rbuflen, rblk; |
uint32_t buf_offset, sector, rbuflen, rblk; |
Line 2619 udf_read_filebuf(struct udf_node *node, |
|
Line 2629 udf_read_filebuf(struct udf_node *node, |
|
buf->b_flags |= B_ERROR; |
buf->b_flags |= B_ERROR; |
biodone(buf); |
biodone(buf); |
return; |
return; |
}; |
} |
|
|
|
mapping = malloc(sizeof(*mapping) * FILEBUFSECT, M_TEMP, M_WAITOK); |
|
|
error = 0; |
error = 0; |
DPRINTF(READ, ("\ttranslate %d-%d\n", from, sectors)); |
DPRINTF(READ, ("\ttranslate %d-%d\n", from, sectors)); |
Line 2628 udf_read_filebuf(struct udf_node *node, |
|
Line 2640 udf_read_filebuf(struct udf_node *node, |
|
buf->b_error = error; |
buf->b_error = error; |
buf->b_flags |= B_ERROR; |
buf->b_flags |= B_ERROR; |
biodone(buf); |
biodone(buf); |
return; |
goto out; |
}; |
} |
DPRINTF(READ, ("\ttranslate extent went OK\n")); |
DPRINTF(READ, ("\ttranslate extent went OK\n")); |
|
|
/* pre-check if internal or parts are zero */ |
/* pre-check if internal or parts are zero */ |
Line 2638 udf_read_filebuf(struct udf_node *node, |
|
Line 2650 udf_read_filebuf(struct udf_node *node, |
|
if (error) { |
if (error) { |
buf->b_error = error; |
buf->b_error = error; |
buf->b_flags |= B_ERROR; |
buf->b_flags |= B_ERROR; |
}; |
} |
biodone(buf); |
biodone(buf); |
return; |
goto out; |
}; |
} |
DPRINTF(READ, ("\tnot intern\n")); |
DPRINTF(READ, ("\tnot intern\n")); |
|
|
/* request read-in of data from disc sheduler */ |
/* request read-in of data from disc sheduler */ |
Line 2670 udf_read_filebuf(struct udf_node *node, |
|
Line 2682 udf_read_filebuf(struct udf_node *node, |
|
break; |
break; |
run_length++; |
run_length++; |
sector++; |
sector++; |
}; |
} |
|
|
/* |
/* |
* nest an iobuf and mark it for async reading. Since |
* nest an iobuf and mark it for async reading. Since |
Line 2690 udf_read_filebuf(struct udf_node *node, |
|
Line 2702 udf_read_filebuf(struct udf_node *node, |
|
nestbuf->b_cylinder = 0; |
nestbuf->b_cylinder = 0; |
nestbuf->b_rawblkno = rblk; |
nestbuf->b_rawblkno = rblk; |
VOP_STRATEGY(node->ump->devvp, nestbuf); |
VOP_STRATEGY(node->ump->devvp, nestbuf); |
}; |
} |
}; |
} |
|
out: |
DPRINTF(READ, ("\tend of read_filebuf\n")); |
DPRINTF(READ, ("\tend of read_filebuf\n")); |
|
free(mapping, M_TEMP); |
|
return; |
} |
} |
#undef FILEBUFSECT |
#undef FILEBUFSECT |
|
|
Line 2737 udf_translate_file_extent(struct udf_nod |
|
Line 2752 udf_translate_file_extent(struct udf_nod |
|
alloclen = udf_rw32(fe->l_ad); |
alloclen = udf_rw32(fe->l_ad); |
pos = &fe->data[0] + udf_rw32(fe->l_ea); |
pos = &fe->data[0] + udf_rw32(fe->l_ea); |
icbflags = udf_rw16(fe->icbtag.flags); |
icbflags = udf_rw16(fe->icbtag.flags); |
}; |
} |
if (efe) { |
if (efe) { |
alloclen = udf_rw32(efe->l_ad); |
alloclen = udf_rw32(efe->l_ad); |
pos = &efe->data[0] + udf_rw32(efe->l_ea); |
pos = &efe->data[0] + udf_rw32(efe->l_ea); |
icbflags = udf_rw16(efe->icbtag.flags); |
icbflags = udf_rw16(efe->icbtag.flags); |
}; |
} |
addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK; |
addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK; |
|
|
DPRINTF(TRANSLATE, ("udf trans: alloc_len = %d, addr_type %d, " |
DPRINTF(TRANSLATE, ("udf trans: alloc_len = %d, addr_type %d, " |
Line 2777 udf_translate_file_extent(struct udf_nod |
|
Line 2792 udf_translate_file_extent(struct udf_nod |
|
default: |
default: |
/* can't be here */ |
/* can't be here */ |
return EINVAL; /* for sure */ |
return EINVAL; /* for sure */ |
}; |
} |
|
|
/* process extent */ |
/* process extent */ |
flags = UDF_EXT_FLAGS(len); |
flags = UDF_EXT_FLAGS(len); |
Line 2792 udf_translate_file_extent(struct udf_nod |
|
Line 2807 udf_translate_file_extent(struct udf_nod |
|
lb_num += from; /* advance in extent */ |
lb_num += from; /* advance in extent */ |
overlap -= from; |
overlap -= from; |
from = 0; |
from = 0; |
}; |
} |
}; |
} |
|
|
overlap = MIN(overlap, pages); |
overlap = MIN(overlap, pages); |
while (overlap) { |
while (overlap) { |
Line 2809 udf_translate_file_extent(struct udf_nod |
|
Line 2824 udf_translate_file_extent(struct udf_nod |
|
while (overlap && pages && translen) { |
while (overlap && pages && translen) { |
*map++ = transsec; |
*map++ = transsec; |
overlap--; pages--; translen--; |
overlap--; pages--; translen--; |
}; |
} |
break; |
break; |
case UDF_EXT_ALLOCATED : |
case UDF_EXT_ALLOCATED : |
t_ad.loc.lb_num = udf_rw32(lb_num); |
t_ad.loc.lb_num = udf_rw32(lb_num); |
Line 2823 udf_translate_file_extent(struct udf_nod |
|
Line 2838 udf_translate_file_extent(struct udf_nod |
|
*map++ = transsec; |
*map++ = transsec; |
transsec++; |
transsec++; |
overlap--; pages--; translen--; |
overlap--; pages--; translen--; |
}; |
} |
break; |
break; |
}; |
} |
}; |
} |
pos += icblen; |
pos += icblen; |
alloclen -= icblen; |
alloclen -= icblen; |
}; |
} |
return 0; |
return 0; |
} |
} |
|
|