xref: /minix3/minix/fs/isofs/super.c (revision 3e2c6c96745db64738bad809b90b163a66e7b201)
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