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 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 24c2f99d7cSDavid van Moolenbroek static int create_vol_pri_desc(struct iso9660_vol_pri_desc *vol_pri, char *buf, 25c2f99d7cSDavid van Moolenbroek size_t __unused address) 26c2f99d7cSDavid van Moolenbroek { 27c2f99d7cSDavid van Moolenbroek /* 28c2f99d7cSDavid van Moolenbroek * This function fullfill the super block data structure using the 29c2f99d7cSDavid van Moolenbroek * information contained in the buffer. 30c2f99d7cSDavid van Moolenbroek */ 31c2f99d7cSDavid van Moolenbroek struct iso9660_dir_record *root_record; 32c2f99d7cSDavid van Moolenbroek struct inode *root; 33c2f99d7cSDavid van Moolenbroek struct dir_extent *extent; 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", 42c2f99d7cSDavid van Moolenbroek ISO9660_SIZE_STANDARD_ID) != 0) || 43c2f99d7cSDavid van Moolenbroek (vol_pri->vd_version != 1) || 44c2f99d7cSDavid van Moolenbroek (vol_pri->logical_block_size_l < 2048) || 45c2f99d7cSDavid van Moolenbroek (vol_pri->file_struct_ver != 1)) 46c2f99d7cSDavid van Moolenbroek return EINVAL; 47c2f99d7cSDavid van Moolenbroek 480314acfbSDavid van Moolenbroek lmfs_set_blocksize(vol_pri->logical_block_size_l); 49*1311233cSDavid van Moolenbroek lmfs_set_blockusage(vol_pri->volume_space_size_l, 50*1311233cSDavid van Moolenbroek vol_pri->volume_space_size_l); 51c2f99d7cSDavid van Moolenbroek 52c2f99d7cSDavid van Moolenbroek /* Read root directory record. */ 53c2f99d7cSDavid van Moolenbroek root_record = (struct iso9660_dir_record *)vol_pri->root_directory; 54c2f99d7cSDavid van Moolenbroek root = alloc_inode(); 55c2f99d7cSDavid van Moolenbroek extent = alloc_extent(); 56c2f99d7cSDavid van Moolenbroek 57c2f99d7cSDavid van Moolenbroek extent->location = 58c2f99d7cSDavid van Moolenbroek root_record->loc_extent_l + root_record->ext_attr_rec_length; 59c2f99d7cSDavid van Moolenbroek extent->length = 60c2f99d7cSDavid van Moolenbroek root_record->data_length_l / vol_pri->logical_block_size_l; 61c2f99d7cSDavid van Moolenbroek if (root_record->data_length_l % vol_pri->logical_block_size_l) 62c2f99d7cSDavid van Moolenbroek extent->length++; 63c2f99d7cSDavid van Moolenbroek 64c2f99d7cSDavid van Moolenbroek if (read_inode(root, extent, 0, NULL) != OK) { 65c2f99d7cSDavid van Moolenbroek free_extent(extent); 66c2f99d7cSDavid van Moolenbroek put_inode(root); 67c2f99d7cSDavid van Moolenbroek return EINVAL; 68c2f99d7cSDavid van Moolenbroek } 69c2f99d7cSDavid van Moolenbroek 70c2f99d7cSDavid van Moolenbroek free_extent(extent); 71c2f99d7cSDavid van Moolenbroek vol_pri->inode_root = root; 72c2f99d7cSDavid van Moolenbroek vol_pri->i_count = 1; 73c2f99d7cSDavid van Moolenbroek 74c2f99d7cSDavid van Moolenbroek return OK; 75c2f99d7cSDavid van Moolenbroek } 76c2f99d7cSDavid van Moolenbroek 77c2f99d7cSDavid van Moolenbroek int read_vds(struct iso9660_vol_pri_desc *vol_pri, dev_t dev) 78c2f99d7cSDavid van Moolenbroek { 79c2f99d7cSDavid van Moolenbroek /* 80c2f99d7cSDavid van Moolenbroek * This function reads from a ISO9660 filesystem (in the device dev) 81c2f99d7cSDavid van Moolenbroek * the super block and saves it in vol_pri. 82c2f99d7cSDavid van Moolenbroek */ 83c2f99d7cSDavid van Moolenbroek size_t offset; 84c2f99d7cSDavid van Moolenbroek int vol_ok = FALSE, vol_pri_flag = FALSE; 85c2f99d7cSDavid van Moolenbroek int r; 86c2f99d7cSDavid van Moolenbroek static char sbbuf[ISO9660_MIN_BLOCK_SIZE]; 87c2f99d7cSDavid van Moolenbroek int i = 0; 88c2f99d7cSDavid van Moolenbroek 89c2f99d7cSDavid van Moolenbroek for(offset = ISO9660_SUPER_BLOCK_POSITION; 90c2f99d7cSDavid van Moolenbroek !vol_ok && i++ < MAX_ATTEMPTS; 91c2f99d7cSDavid van Moolenbroek offset += ISO9660_MIN_BLOCK_SIZE) { 92c2f99d7cSDavid van Moolenbroek /* Read the sector of the super block. */ 93c2f99d7cSDavid van Moolenbroek r = bdev_read(dev, offset, sbbuf, ISO9660_MIN_BLOCK_SIZE, 94c2f99d7cSDavid van Moolenbroek BDEV_NOFLAGS); 95c2f99d7cSDavid van Moolenbroek 96c2f99d7cSDavid van Moolenbroek if (r != ISO9660_MIN_BLOCK_SIZE) { 97c2f99d7cSDavid van Moolenbroek /* Damaged sector or what? */ 98c2f99d7cSDavid van Moolenbroek return EINVAL; 99c2f99d7cSDavid van Moolenbroek } 100c2f99d7cSDavid van Moolenbroek 101c2f99d7cSDavid van Moolenbroek if ((sbbuf[0] & BYTE) == VD_PRIMARY) { 102c2f99d7cSDavid van Moolenbroek /* Copy the buffer in the data structure. */ 103c2f99d7cSDavid van Moolenbroek if (create_vol_pri_desc(vol_pri, sbbuf, offset) == OK) { 104c2f99d7cSDavid van Moolenbroek vol_pri_flag = TRUE; 105c2f99d7cSDavid van Moolenbroek } 106c2f99d7cSDavid van Moolenbroek } 107c2f99d7cSDavid van Moolenbroek 108c2f99d7cSDavid van Moolenbroek if ((sbbuf[0] & BYTE) == VD_SET_TERM) { 109c2f99d7cSDavid van Moolenbroek /* I dont need to save anything about it */ 110c2f99d7cSDavid van Moolenbroek vol_ok = TRUE; 111c2f99d7cSDavid van Moolenbroek } 112c2f99d7cSDavid van Moolenbroek } 113c2f99d7cSDavid van Moolenbroek 114c2f99d7cSDavid van Moolenbroek if (vol_ok == FALSE || vol_pri_flag == FALSE) 115c2f99d7cSDavid van Moolenbroek return EINVAL; /* If no superblock was found... */ 116c2f99d7cSDavid van Moolenbroek else 117c2f99d7cSDavid van Moolenbroek return OK; /* otherwise. */ 118c2f99d7cSDavid van Moolenbroek } 119