207
207
link_t link; /**< Link to list of all instances */
208
208
service_id_t service_id; /**< Service ID of block device */
209
209
cdfs_enc_t enc; /**< Filesystem string encoding */
210
char *vol_ident; /**< Volume identifier */
521
/** Decode volume identifier.
523
* @param data Volume identifier buffer
524
* @param dsize Volume identifier buffer size
525
* @param enc Encoding
526
* @return Decoded volume identifier (allocated string)
528
static char *cdfs_decode_vol_ident(void *data, size_t dsize, cdfs_enc_t enc)
533
ident = cdfs_decode_str(data, dsize, enc);
537
/* Trim trailing spaces */
539
while (i > 0 && ident[i - 1] == ' ')
519
546
static bool cdfs_readdir(cdfs_t *fs, fs_node_t *fs_node)
521
548
cdfs_node_t *node = CDFS_NODE(fs_node);
840
867
* @param altroot First filesystem block
841
868
* @param rlba Place to store LBA of root dir
842
869
* @param rsize Place to store size of root dir
870
* @param vol_ident Place to store pointer to volume identifier
843
871
* @return EOK if found, ENOENT if not
845
873
static int cdfs_find_joliet_svd(service_id_t sid, cdfs_lba_t altroot,
846
uint32_t *rlba, uint32_t *rsize)
874
uint32_t *rlba, uint32_t *rsize, char **vol_ident)
908
static bool iso_readfs(cdfs_t *fs, fs_node_t *rfn,
940
/** Read the volume descriptors. */
941
static bool iso_read_vol_desc(service_id_t sid, cdfs_lba_t altroot,
942
uint32_t *rlba, uint32_t *rsize, cdfs_enc_t *enc, char **vol_ident)
911
944
/* First 16 blocks of isofs are empty */
913
int rc = block_get(&block, fs->service_id, altroot + 16, BLOCK_FLAGS_NONE);
946
int rc = block_get(&block, sid, altroot + 16, BLOCK_FLAGS_NONE);
956
989
// TODO: implement path table support
958
cdfs_node_t *node = CDFS_NODE(rfn);
960
991
/* Search for Joliet SVD */
965
rc = cdfs_find_joliet_svd(fs->service_id, altroot, &jrlba, &jrsize);
996
rc = cdfs_find_joliet_svd(sid, altroot, &jrlba, &jrsize, vol_ident);
972
node->lba = uint32_lb(vol_desc->data.prisec.root_dir.lba);
973
node->size = uint32_lb(vol_desc->data.prisec.root_dir.size);
977
if (!cdfs_readdir(fs, rfn)) {
1003
*rlba = uint32_lb(vol_desc->data.prisec.root_dir.lba);
1004
*rsize = uint32_lb(vol_desc->data.prisec.root_dir.size);
1006
*vol_ident = cdfs_decode_vol_ident(vol_desc->data.prisec.ident,
982
1010
block_put(block);
1014
static bool iso_readfs(cdfs_t *fs, fs_node_t *rfn,
1017
cdfs_node_t *node = CDFS_NODE(rfn);
1019
if (!iso_read_vol_desc(fs->service_id, altroot, &node->lba,
1020
&node->size, &fs->enc, &fs->vol_ident))
1023
return cdfs_readdir(fs, rfn);
986
1026
/* Mount a session with session start offset
1063
static int cdfs_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info)
1067
/* Initialize the block layer */
1068
int rc = block_init(service_id, BLOCK_SIZE);
1072
cdfs_lba_t altroot = 0;
1075
* Read TOC multisession information and get the start address
1076
* of the first track in the last session
1078
scsi_toc_multisess_data_t toc;
1080
rc = block_read_toc(service_id, 1, &toc, sizeof(toc));
1081
if (rc == EOK && (uint16_t_be2host(toc.toc_len) == 10))
1082
altroot = uint32_t_be2host(toc.ftrack_lsess.start_addr);
1084
/* Initialize the block cache */
1085
rc = block_cache_init(service_id, BLOCK_SIZE, 0, CACHE_MODE_WT);
1087
block_fini(service_id);
1091
/* Check if this device is not already mounted */
1093
rc = cdfs_root_get(&rootfn, service_id);
1094
if ((rc == EOK) && (rootfn)) {
1095
cdfs_node_put(rootfn);
1096
block_cache_fini(service_id);
1097
block_fini(service_id);
1101
/* Read volume descriptors */
1105
if (!iso_read_vol_desc(service_id, altroot, &rlba, &rsize, &enc,
1107
block_cache_fini(service_id);
1108
block_fini(service_id);
1112
str_cpy(info->label, FS_LABEL_MAXLEN + 1, vol_ident);
1115
block_cache_fini(service_id);
1116
block_fini(service_id);
1023
1120
static int cdfs_mounted(service_id_t service_id, const char *opts,
1024
fs_index_t *index, aoff64_t *size, unsigned int *lnkcnt)
1121
fs_index_t *index, aoff64_t *size)
1026
1123
/* Initialize the block layer */
1027
1124
int rc = block_init(service_id, BLOCK_SIZE);