Changeset bdad846 in mainline


Ignore:
Timestamp:
2021-09-08T13:31:58Z (3 years ago)
Author:
Erik Kučák <riko98@…>
Children:
d5309df7
Parents:
2f7dfc2e
Message:

Fixed bugs from the review

Location:
uspace/srv/bd/qcow_bd
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/bd/qcow_bd/qcow_bd.c

    r2f7dfc2e rbdad846  
    152152}
    153153
    154 static errno_t compute_table_sizes()
     154static void initialize_state()
    155155{
    156156        /* Computing sizes in bytes */
     
    173173                state.num_blocks = (header.size / state.block_size);
    174174
    175         return EOK;
    176 }
    177 
    178 static errno_t read_l1_table()
    179 {
    180         /* Allocating memory for l1_table */
    181175        state.l1_table_offset = header.l1_table_offset;
    182         state.l2_references = (uint64_t*)malloc(state.l1_size);
    183 
    184         /* Reading all L2 table references from L1 table */
    185         clearerr(img);
    186         printf("READING 2,5\n");
    187         if (fseek(img, state.l1_table_offset, SEEK_SET) < 0)
    188                 return EIO;
    189 
    190         size_t n_rd = fread(state.l2_references, state.l1_size, 1, img);
    191 
    192         if (n_rd < 1)
    193                 return EINVAL;
    194 
    195         /* Clearing last bit in all references which tells us whether cluster is compressed */
    196         for (uint64_t i = 0; i < state.l1_size / sizeof(uint64_t); i++) {
    197                 state.l2_references[i] = __builtin_bswap64(state.l2_references[i]);
    198                 if (state.l2_references[i] & QCOW_OFLAG_COMPRESSED) {
    199                         fprintf(stderr, "Compression is not supported!\n");
    200                         return ENOTSUP;
    201                 }
    202         }
    203 
    204         if (ferror(img))
    205                 return EIO;     /* Read error */
    206         return EOK;
    207176}
    208177
     
    222191        /* Try to open file */
    223192        img = fopen(fname, "rb+");
    224         if (img == NULL)
     193        if (img == NULL) {
     194                fprintf(stderr, "File opening failed!\n");
    225195                return EINVAL;
     196        }
    226197
    227198        if (fseek(img, 0, SEEK_END) != 0) {
     199                fprintf(stderr, "Seeking end of file failed!\n");
    228200                fclose(img);
    229201                return EIO;
    230202        }
    231203
    232         if (fseek(img, 0, SEEK_SET) < 0)
     204        if (fseek(img, 0, SEEK_SET) < 0) {
     205                fprintf(stderr, "Seeking file header failed!\n");
     206                fclose(img);
    233207                return EIO;
     208        }
    234209
    235210        /* Read the file header */
    236211        size_t n_rd = fread(&header, sizeof(header), 1, img);
    237212
    238         if (n_rd < 1)
     213        if (n_rd < 1) {
     214                fprintf(stderr, "Reading file header failed!\n");
     215                fclose(img);
    239216                return EINVAL;
     217        }
     218
    240219
    241220        /* Swap values to big-endian */
     
    249228        header.l1_table_offset = __builtin_bswap64(header.l1_table_offset);
    250229
     230        if (ferror(img)) {
     231                fclose(img);
     232                return EIO;
     233        }
     234
    251235        /* Verify all values from file header */
    252         if (ferror(img))
    253                 return EIO;
    254 
    255         if (header.magic == QCOW_MAGIC) {
    256                 errno_t error = compute_table_sizes();
    257                 if (error != EOK) {
    258                         return error;
    259                 }
    260                 error = read_l1_table();
    261                 if (error != EOK) {
    262                         return error;
    263                 }
    264         }
     236        if (header.magic == QCOW_MAGIC)
     237                initialize_state();
    265238
    266239        if (header.version != QCOW_VERSION) {
    267                 fprintf(stderr, "Version: %d is not supported!\n", header.version);
     240                fprintf(stderr, "Version QCOW%d is not supported!\n", header.version);
     241                fclose(img);
    268242                return ENOTSUP;
    269243        }
     
    271245        if (header.crypt_method != QCOW_CRYPT_NONE) {
    272246                fprintf(stderr, "Encryption is not supported!\n");
     247                fclose(img);
    273248                return ENOTSUP;
    274249        }
     
    294269static errno_t qcow_bd_close(bd_srv_t *bd)
    295270{
    296         free(state.l2_references);
    297271        fclose(img);
    298272        return EOK;
     
    300274
    301275/** From the offset of the given block compute its offset which is relative from the start of qcow file. */
    302 static uint64_t get_block_offset(uint64_t offset, errno_t *error)
     276static errno_t get_block_offset(uint64_t *offset)
    303277{
    304278        /* Compute l1 table index from the offset  */
    305279        uint64_t l1_table_index_bit_shift =  header.cluster_bits + header.l2_bits;
    306         uint64_t l1_table_index = (offset & 0x7fffffffffffffffULL) >> l1_table_index_bit_shift;
     280        uint64_t l1_table_index = (*offset & 0x7fffffffffffffffULL) >> l1_table_index_bit_shift;
    307281
    308282        /* Reading l2 reference from the l1 table */
    309         uint64_t l2_table_reference = state.l2_references[l1_table_index];
    310 
    311         if (l2_table_reference == QCOW_UNALLOCATED_REFERENCE)
    312                 return QCOW_UNALLOCATED_REFERENCE;
     283        if (fseek(img, state.l1_table_offset + l1_table_index * sizeof(uint64_t), SEEK_SET) < 0) {
     284                fprintf(stderr, "Seeking l2 reference in l1 table failed!\n");
     285                return EIO;
     286        }
     287
     288
     289        uint64_t l2_table_reference;
     290        size_t n_rd = fread(&l2_table_reference, sizeof(uint64_t), 1, img);
     291
     292        if (n_rd < 1) {
     293                fprintf(stderr, "Reading l2 reference from l1 table failed!\n");
     294                return EINVAL;
     295        }
     296
     297        l2_table_reference = __builtin_bswap64(l2_table_reference);
     298
     299        if (l2_table_reference & QCOW_OFLAG_COMPRESSED) {
     300                fprintf(stderr, "Compression is not supported!\n");
     301                return ENOTSUP;
     302        }
     303
     304        if (l2_table_reference == QCOW_UNALLOCATED_REFERENCE) {
     305                *offset = QCOW_UNALLOCATED_REFERENCE;
     306                return EOK;
     307        }
     308
    313309
    314310        /* Compute l2 table index from the offset  */
    315         uint64_t l2_table_index = (offset >> header.cluster_bits) & (state.l2_size - 1);
     311        uint64_t l2_table_index = (*offset >> header.cluster_bits) & (state.l2_size - 1);
    316312
    317313        /* Reading cluster reference from the l2 table */
    318         if (fseek(img, l2_table_reference + l2_table_index * sizeof(uint64_t), SEEK_SET) < 0){
    319                 *error = EIO;
     314        if (fseek(img, l2_table_reference + l2_table_index * sizeof(uint64_t), SEEK_SET) < 0) {
     315                fprintf(stderr, "Seeking cluster reference in l2 table failed!\n");
    320316                return EIO;
    321317        }
    322318
    323319        uint64_t cluster_reference;
    324         size_t n_rd = fread(&cluster_reference, sizeof(uint64_t), 1, img);
     320        n_rd = fread(&cluster_reference, sizeof(uint64_t), 1, img);
    325321
    326322        if (n_rd < 1) {
    327                 *error = EINVAL;
     323                fprintf(stderr, "Reading cluster reference from l2 table failed!\n");
    328324                return EINVAL;
    329325        }
     
    333329        if (cluster_reference & QCOW_OFLAG_COMPRESSED) {
    334330                fprintf(stderr, "Compression is not supported!\n");
    335                 *error = ENOTSUP;
    336331                return ENOTSUP;
    337332        }
    338333
    339         if (cluster_reference == QCOW_UNALLOCATED_REFERENCE)
    340                 return QCOW_UNALLOCATED_REFERENCE;
     334        if (cluster_reference == QCOW_UNALLOCATED_REFERENCE) {
     335                *offset = QCOW_UNALLOCATED_REFERENCE;
     336                return EOK;
     337        }
    341338
    342339        /* Compute cluster block offset from the offset  */
    343340        uint64_t cluster_block_bit_mask = ~(0xffffffffffffffffULL <<  header.cluster_bits);
    344         uint64_t cluster_block_offset = offset & cluster_block_bit_mask;
    345 
    346         return cluster_reference + cluster_block_offset;
     341        uint64_t cluster_block_offset = *offset & cluster_block_bit_mask;
     342
     343        *offset = cluster_reference + cluster_block_offset;
     344        return EOK;
    347345}
    348346
     
    351349    size_t size)
    352350{
    353         if (size < cnt * state.block_size)
     351        if (size < cnt * state.block_size){
     352                fprintf(stderr, "Error: trying to read block behind the file");
    354353                return EINVAL;
     354        }
     355
    355356
    356357        /* Check whether access is within device address bounds. */
     
    366367        for (uint64_t i = 0; i < cnt; i++) {
    367368                /* Compute block offset which is relative from the start of qcow file */
    368                 errno_t error = EOK;
    369                 uint64_t block_offset = get_block_offset((ba + i) * state.block_size, &error);
    370                 if (error != EOK)
     369                uint64_t block_offset = (ba + i) * state.block_size;
     370                errno_t error = get_block_offset(&block_offset);
     371                if (error != EOK) {
     372                        fibril_mutex_unlock(&dev_lock);
    371373                        return error;
     374                }
     375
    372376
    373377                /* If there is empty reference then continue */
  • uspace/srv/bd/qcow_bd/qcow_bd.h

    r2f7dfc2e rbdad846  
    8383    uint64_t l1_size;
    8484    uint64_t l1_table_offset;
    85     uint64_t *l2_references;
    8685} QcowState;
    8786
Note: See TracChangeset for help on using the changeset viewer.