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