1c2f99d7cSDavid van Moolenbroek /*
2c2f99d7cSDavid van Moolenbroek * Functions to manage the superblock of the filesystem. These functions are
3c2f99d7cSDavid van Moolenbroek * are called at the beginning and at the end of the server.
4c2f99d7cSDavid van Moolenbroek */
5c2f99d7cSDavid van Moolenbroek
6c2f99d7cSDavid van Moolenbroek #include "inc.h"
7c2f99d7cSDavid van Moolenbroek #include <string.h>
8c2f99d7cSDavid van Moolenbroek #include <minix/com.h>
9c2f99d7cSDavid van Moolenbroek #include <minix/u64.h>
10c2f99d7cSDavid van Moolenbroek #include <minix/bdev.h>
11c2f99d7cSDavid van Moolenbroek
release_vol_pri_desc(struct iso9660_vol_pri_desc * vol_pri)12c2f99d7cSDavid van Moolenbroek int release_vol_pri_desc(struct iso9660_vol_pri_desc *vol_pri)
13c2f99d7cSDavid van Moolenbroek {
14c2f99d7cSDavid van Moolenbroek /* Release the root dir root. */
15c2f99d7cSDavid van Moolenbroek if (vol_pri->i_count > 0) {
16c2f99d7cSDavid van Moolenbroek put_inode(vol_pri->inode_root);
17c2f99d7cSDavid van Moolenbroek vol_pri->inode_root = NULL;
18c2f99d7cSDavid van Moolenbroek vol_pri->i_count = 0;
19c2f99d7cSDavid van Moolenbroek }
20c2f99d7cSDavid van Moolenbroek
21c2f99d7cSDavid van Moolenbroek return OK;
22c2f99d7cSDavid van Moolenbroek }
23c2f99d7cSDavid van Moolenbroek
create_vol_pri_desc(struct iso9660_vol_pri_desc * vol_pri,char * buf)24*b1d06847SJean-Baptiste Boric static int create_vol_pri_desc(struct iso9660_vol_pri_desc *vol_pri, char *buf)
25c2f99d7cSDavid van Moolenbroek {
26c2f99d7cSDavid van Moolenbroek /*
27c2f99d7cSDavid van Moolenbroek * This function fullfill the super block data structure using the
28c2f99d7cSDavid van Moolenbroek * information contained in the buffer.
29c2f99d7cSDavid van Moolenbroek */
30c2f99d7cSDavid van Moolenbroek struct iso9660_dir_record *root_record;
31*b1d06847SJean-Baptiste Boric struct inode_dir_entry dir_entry;
32*b1d06847SJean-Baptiste Boric struct dir_extent extent;
33*b1d06847SJean-Baptiste Boric size_t dummy_offset = 0;
34c2f99d7cSDavid van Moolenbroek
35c2f99d7cSDavid van Moolenbroek if (vol_pri->i_count > 0)
36c2f99d7cSDavid van Moolenbroek release_vol_pri_desc(vol_pri);
37c2f99d7cSDavid van Moolenbroek
38c2f99d7cSDavid van Moolenbroek memcpy(vol_pri, buf, 2048);
39c2f99d7cSDavid van Moolenbroek
40c2f99d7cSDavid van Moolenbroek /* Check various fields for consistency. */
41c2f99d7cSDavid van Moolenbroek if ((memcmp(vol_pri->standard_id, "CD001",
42*b1d06847SJean-Baptiste Boric ISO9660_SIZE_STANDARD_ID) != 0)
43*b1d06847SJean-Baptiste Boric || (vol_pri->vd_version != 1)
44*b1d06847SJean-Baptiste Boric || (vol_pri->logical_block_size_l < 2048))
45c2f99d7cSDavid van Moolenbroek return EINVAL;
46c2f99d7cSDavid van Moolenbroek
470314acfbSDavid van Moolenbroek lmfs_set_blocksize(vol_pri->logical_block_size_l);
481311233cSDavid van Moolenbroek lmfs_set_blockusage(vol_pri->volume_space_size_l,
491311233cSDavid van Moolenbroek vol_pri->volume_space_size_l);
50c2f99d7cSDavid van Moolenbroek
51c2f99d7cSDavid van Moolenbroek /* Read root directory record. */
52c2f99d7cSDavid van Moolenbroek root_record = (struct iso9660_dir_record *)vol_pri->root_directory;
53c2f99d7cSDavid van Moolenbroek
54*b1d06847SJean-Baptiste Boric extent.location =
55c2f99d7cSDavid van Moolenbroek root_record->loc_extent_l + root_record->ext_attr_rec_length;
56*b1d06847SJean-Baptiste Boric extent.length =
57c2f99d7cSDavid van Moolenbroek root_record->data_length_l / vol_pri->logical_block_size_l;
58*b1d06847SJean-Baptiste Boric extent.next = NULL;
59c2f99d7cSDavid van Moolenbroek
60*b1d06847SJean-Baptiste Boric if (root_record->data_length_l % vol_pri->logical_block_size_l)
61*b1d06847SJean-Baptiste Boric extent.length++;
62*b1d06847SJean-Baptiste Boric
63*b1d06847SJean-Baptiste Boric if (read_inode(&dir_entry, &extent, &dummy_offset) != OK) {
64c2f99d7cSDavid van Moolenbroek return EINVAL;
65c2f99d7cSDavid van Moolenbroek }
66c2f99d7cSDavid van Moolenbroek
67*b1d06847SJean-Baptiste Boric dir_entry.i_node->i_count = 1;
68*b1d06847SJean-Baptiste Boric
69*b1d06847SJean-Baptiste Boric vol_pri->inode_root = dir_entry.i_node;
70c2f99d7cSDavid van Moolenbroek vol_pri->i_count = 1;
71c2f99d7cSDavid van Moolenbroek
72c2f99d7cSDavid van Moolenbroek return OK;
73c2f99d7cSDavid van Moolenbroek }
74c2f99d7cSDavid van Moolenbroek
read_vds(struct iso9660_vol_pri_desc * vol_pri,dev_t dev)75c2f99d7cSDavid van Moolenbroek int read_vds(struct iso9660_vol_pri_desc *vol_pri, dev_t dev)
76c2f99d7cSDavid van Moolenbroek {
77c2f99d7cSDavid van Moolenbroek /*
78c2f99d7cSDavid van Moolenbroek * This function reads from a ISO9660 filesystem (in the device dev)
79c2f99d7cSDavid van Moolenbroek * the super block and saves it in vol_pri.
80c2f99d7cSDavid van Moolenbroek */
81c2f99d7cSDavid van Moolenbroek size_t offset;
82c2f99d7cSDavid van Moolenbroek int vol_ok = FALSE, vol_pri_flag = FALSE;
83c2f99d7cSDavid van Moolenbroek int r;
84c2f99d7cSDavid van Moolenbroek static char sbbuf[ISO9660_MIN_BLOCK_SIZE];
85c2f99d7cSDavid van Moolenbroek int i = 0;
86c2f99d7cSDavid van Moolenbroek
87c2f99d7cSDavid van Moolenbroek for(offset = ISO9660_SUPER_BLOCK_POSITION;
88c2f99d7cSDavid van Moolenbroek !vol_ok && i++ < MAX_ATTEMPTS;
89c2f99d7cSDavid van Moolenbroek offset += ISO9660_MIN_BLOCK_SIZE) {
90c2f99d7cSDavid van Moolenbroek /* Read the sector of the super block. */
91c2f99d7cSDavid van Moolenbroek r = bdev_read(dev, offset, sbbuf, ISO9660_MIN_BLOCK_SIZE,
92c2f99d7cSDavid van Moolenbroek BDEV_NOFLAGS);
93c2f99d7cSDavid van Moolenbroek
94c2f99d7cSDavid van Moolenbroek if (r != ISO9660_MIN_BLOCK_SIZE) {
95c2f99d7cSDavid van Moolenbroek /* Damaged sector or what? */
96c2f99d7cSDavid van Moolenbroek return EINVAL;
97c2f99d7cSDavid van Moolenbroek }
98c2f99d7cSDavid van Moolenbroek
99c2f99d7cSDavid van Moolenbroek if ((sbbuf[0] & BYTE) == VD_PRIMARY) {
100*b1d06847SJean-Baptiste Boric /* Free already parsed descriptor, if any. */
101*b1d06847SJean-Baptiste Boric if (vol_pri_flag == TRUE) {
102*b1d06847SJean-Baptiste Boric release_vol_pri_desc(vol_pri);
103*b1d06847SJean-Baptiste Boric vol_pri_flag = FALSE;
104*b1d06847SJean-Baptiste Boric }
105c2f99d7cSDavid van Moolenbroek /* Copy the buffer in the data structure. */
106*b1d06847SJean-Baptiste Boric if (create_vol_pri_desc(vol_pri, sbbuf) == OK) {
107c2f99d7cSDavid van Moolenbroek vol_pri_flag = TRUE;
108c2f99d7cSDavid van Moolenbroek }
109c2f99d7cSDavid van Moolenbroek }
110c2f99d7cSDavid van Moolenbroek
111c2f99d7cSDavid van Moolenbroek if ((sbbuf[0] & BYTE) == VD_SET_TERM) {
112c2f99d7cSDavid van Moolenbroek /* I dont need to save anything about it */
113c2f99d7cSDavid van Moolenbroek vol_ok = TRUE;
114c2f99d7cSDavid van Moolenbroek }
115c2f99d7cSDavid van Moolenbroek }
116c2f99d7cSDavid van Moolenbroek
117c2f99d7cSDavid van Moolenbroek if (vol_ok == FALSE || vol_pri_flag == FALSE)
118c2f99d7cSDavid van Moolenbroek return EINVAL; /* If no superblock was found... */
119c2f99d7cSDavid van Moolenbroek else
120c2f99d7cSDavid van Moolenbroek return OK; /* otherwise. */
121c2f99d7cSDavid van Moolenbroek }
122