int rtems_rfs_buffer_open (const char* name, rtems_rfs_file_system* fs) { struct stat st; #if RTEMS_RFS_USE_LIBBLOCK int rv; #endif if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_SYNC)) printf ("rtems-rfs: buffer-open: opening: %s\n", name); fs->device = open (name, O_RDWR); if (fs->device < 0) { if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_OPEN)) printf ("rtems-rfs: buffer-open: cannot open file\n"); return ENXIO; } if (fstat (fs->device, &st) < 0) { if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_OPEN)) printf ("rtems-rfs: buffer-open: stat '%s' failed: %s\n", name, strerror (errno)); return ENXIO; } #if RTEMS_RFS_USE_LIBBLOCK /* * Is the device a block device ? */ if (!S_ISBLK (st.st_mode)) { if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_OPEN)) printf ("rtems-rfs: buffer-open: '%s' is not a block device\n", name); return ENXIO; } /* * Check that device is registred as a block device and lock it. */ rv = rtems_disk_fd_get_disk_device (fs->device, &fs->disk); if (rv != 0) { if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_OPEN)) printf ("rtems-rfs: buffer-open: cannot obtain the disk\n"); return ENXIO; } #else fs->media_size = st.st_size; strcat (fs->name, name); #endif if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_SYNC)) printf ("rtems-rfs: buffer-open: blks=%" PRId32 ", blk-size=%" PRId32 "\n", rtems_rfs_fs_media_blocks (fs), rtems_rfs_fs_media_block_size (fs)); return 0; }
/* * Black box test the disk parameters of a sparse disk */ static void test_disk_params( const int file_descriptor, const uint32_t block_size, const uint32_t media_block_size, const rtems_blkdev_bnum block_number ) { int rv; uint32_t value = 0; rtems_disk_device *fd_dd = NULL; rtems_blkdev_bnum block_count = 0; rv = rtems_disk_fd_get_media_block_size( file_descriptor, &value ); rtems_test_assert( 0 == rv ); rtems_test_assert( media_block_size == value ); value = 0; rv = rtems_disk_fd_get_block_size( file_descriptor, &value ); rtems_test_assert( 0 == rv ); rtems_test_assert( block_size == value ); block_count = 0; rv = rtems_disk_fd_get_block_count( file_descriptor, &block_count ); rtems_test_assert( 0 == rv ); rtems_test_assert( block_number == block_count ); rv = rtems_disk_fd_get_disk_device( file_descriptor, &fd_dd ); rtems_test_assert( 0 == rv ); rtems_test_assert( NULL != fd_dd ); }
static void test_logical_disks(const char *const *rdax, bool exists) { size_t i = 0; for (i = 0; i < PARTITION_COUNT; ++i) { int fd = open(rdax [i], O_RDONLY); if (exists) { rtems_disk_device *dd = NULL; int rv = 0; rtems_test_assert(fd >= 0); rv = rtems_disk_fd_get_disk_device(fd, &dd); rtems_test_assert(rv == 0); rtems_test_assert(dd->start == starts [i]); rtems_test_assert(dd->size == 63); rv = close(fd); rtems_test_assert(rv == 0); } else { rtems_test_assert(fd == -1); } } }
static void test_block_io_control_api(dev_t dev, ramdisk *rd) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_disk_device *dd = NULL; const rtems_disk_device *fd_dd = NULL; int fd = -1; int rv = -1; uint32_t value = 0; rtems_blkdev_bnum block_count = 0; sc = rtems_disk_create_phys(dev, BLOCK_SIZE, BLOCK_COUNT, ramdisk_ioctl, rd, "/dev/rda"); ASSERT_SC(sc); dd = rtems_disk_obtain(dev); rtems_test_assert(dd != NULL); fd = open("/dev/rda", O_RDWR); rtems_test_assert(fd >= 0); value = 0; rv = rtems_disk_fd_get_media_block_size(fd, &value); rtems_test_assert(rv == 0); rtems_test_assert(value == BLOCK_SIZE); value = 0; rv = rtems_disk_fd_get_block_size(fd, &value); rtems_test_assert(rv == 0); rtems_test_assert(value == BLOCK_SIZE); value = 1024; rv = rtems_disk_fd_set_block_size(fd, value); rtems_test_assert(rv == 0); value = 0; rv = rtems_disk_fd_get_block_size(fd, &value); rtems_test_assert(rv == 0); rtems_test_assert(value == 1024); block_count = 0; rv = rtems_disk_fd_get_block_count(fd, &block_count); rtems_test_assert(rv == 0); rtems_test_assert(block_count == BLOCK_COUNT); rv = rtems_disk_fd_get_disk_device(fd, &fd_dd); rtems_test_assert(rv == 0); rtems_test_assert(fd_dd == dd); rv = rtems_disk_fd_sync(fd); rtems_test_assert(rv == 0); rv = close(fd); rtems_test_assert(rv == 0); sc = rtems_disk_release(dd); ASSERT_SC(sc); sc = rtems_disk_delete(dev); ASSERT_SC(sc); }
/* * FIXME: This code should the deviceio interface and not the bdbug interface. */ rtems_status_code rtems_bdpart_get_disk_data( const char *disk_name, int *fd_ptr, rtems_disk_device **dd_ptr, rtems_blkdev_bnum *disk_end ) { rtems_status_code sc = RTEMS_SUCCESSFUL; int rv = 0; int fd = -1; rtems_disk_device *dd = NULL; rtems_blkdev_bnum disk_begin = 0; rtems_blkdev_bnum block_size = 0; /* Open device file */ fd = open( disk_name, O_RDWR); if (fd < 0) { sc = RTEMS_INVALID_NAME; goto error; } /* Get disk handle */ rv = rtems_disk_fd_get_disk_device( fd, &dd); if (rv != 0) { sc = RTEMS_INVALID_NAME; goto error; } /* Get disk begin, end and block size */ disk_begin = dd->start; *disk_end = dd->size; block_size = dd->block_size; /* Check block size */ if (block_size < RTEMS_BDPART_BLOCK_SIZE) { sc = RTEMS_IO_ERROR; goto error; } /* Check that we have do not have a logical disk */ if (disk_begin != 0) { sc = RTEMS_IO_ERROR; goto error; } error: if (sc == RTEMS_SUCCESSFUL && fd_ptr != NULL && dd_ptr != NULL) { *fd_ptr = fd; *dd_ptr = dd; } else { close( fd); } return sc; }
static void test_blkdev_imfs_parameters(void) { rtems_status_code sc; int rv; ramdisk *rd; int fd; rtems_disk_device *dd; struct stat st; rd = ramdisk_allocate(NULL, BLOCK_SIZE, BLOCK_COUNT, false); rtems_test_assert(rd != NULL); ramdisk_enable_free_at_delete_request(rd); sc = rtems_blkdev_create( rda, BLOCK_SIZE, BLOCK_COUNT, ramdisk_ioctl, rd ); ASSERT_SC(sc); sc = rtems_blkdev_create_partition( rda1, rda, 1, BLOCK_COUNT - 1 ); ASSERT_SC(sc); fd = open(rda, O_RDWR); rtems_test_assert(fd >= 0); rv = fstat(fd, &st); rtems_test_assert(rv == 0); rv = rtems_disk_fd_get_disk_device(fd, &dd); rtems_test_assert(rv == 0); rtems_test_assert(rtems_disk_get_driver_data(dd) == rd); rtems_test_assert(rtems_disk_get_device_identifier(dd) == st.st_rdev); rtems_test_assert(rtems_disk_get_media_block_size(dd) == BLOCK_SIZE); rtems_test_assert(rtems_disk_get_block_size(dd) == BLOCK_SIZE); rtems_test_assert(rtems_disk_get_block_begin(dd) == 0); rtems_test_assert(rtems_disk_get_block_count(dd) == BLOCK_COUNT); rv = close(fd); rtems_test_assert(rv == 0); fd = open(rda1, O_RDWR); rtems_test_assert(fd >= 0); rv = fstat(fd, &st); rtems_test_assert(rv == 0); rv = rtems_disk_fd_get_disk_device(fd, &dd); rtems_test_assert(rv == 0); rtems_test_assert(rtems_disk_get_driver_data(dd) == rd); rtems_test_assert(rtems_disk_get_device_identifier(dd) == st.st_rdev); rtems_test_assert(rtems_disk_get_media_block_size(dd) == BLOCK_SIZE); rtems_test_assert(rtems_disk_get_block_size(dd) == BLOCK_SIZE); rtems_test_assert(rtems_disk_get_block_begin(dd) == 1); rtems_test_assert(rtems_disk_get_block_count(dd) == BLOCK_COUNT - 1); rv = close(fd); rtems_test_assert(rv == 0); rv = unlink(rda1); rtems_test_assert(rv == 0); rv = unlink(rda); rtems_test_assert(rv == 0); }
rtems_status_code rtems_blkdev_create_partition( const char *partition, const char *parent_block_device, rtems_blkdev_bnum media_block_begin, rtems_blkdev_bnum media_block_count ) { rtems_status_code sc = RTEMS_SUCCESSFUL; int fd = open(parent_block_device, O_RDWR); if (fd >= 0) { int rv; struct stat st; rv = fstat(fd, &st); if (rv == 0 && S_ISBLK(st.st_mode)) { rtems_disk_device *phys_dd; rv = rtems_disk_fd_get_disk_device(fd, &phys_dd); if (rv == 0) { rtems_blkdev_imfs_context *ctx = malloc(sizeof(*ctx)); if (ctx != NULL) { sc = rtems_disk_init_log( &ctx->dd, phys_dd, media_block_begin, media_block_count ); if (sc == RTEMS_SUCCESSFUL) { ctx->fd = fd; rv = IMFS_make_generic_node( partition, S_IFBLK | S_IRWXU | S_IRWXG | S_IRWXO, &rtems_blkdev_imfs_control, ctx ); if (rv != 0) { free(ctx); sc = RTEMS_UNSATISFIED; } } else { free(ctx); } } else { sc = RTEMS_NO_MEMORY; } } else { sc = RTEMS_NOT_IMPLEMENTED; } } else { sc = RTEMS_INVALID_NODE; } if (sc != RTEMS_SUCCESSFUL) { close(fd); } } else { sc = RTEMS_INVALID_ID; } return sc; }
/* fat_init_volume_info -- * Get inforamtion about volume on which filesystem is mounted on * * PARAMETERS: * mt_entry - mount table entry * * RETURNS: * RC_OK on success, or -1 if error occured * and errno set appropriately */ int fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry) { rtems_status_code sc = RTEMS_SUCCESSFUL; int rc = RC_OK; fat_fs_info_t *fs_info = mt_entry->fs_info; register fat_vol_t *vol = &fs_info->vol; uint32_t data_secs = 0; char boot_rec[FAT_MAX_BPB_SIZE]; char fs_info_sector[FAT_USEFUL_INFO_SIZE]; ssize_t ret = 0; struct stat stat_buf; int i = 0; rtems_bdbuf_buffer *block = NULL; vol->fd = open(mt_entry->dev, O_RDWR); if (vol->fd < 0) { rtems_set_errno_and_return_minus_one(ENXIO); } rc = fstat(vol->fd, &stat_buf); if (rc != 0) { close(vol->fd); rtems_set_errno_and_return_minus_one(ENXIO); } /* Must be a block device. */ if (!S_ISBLK(stat_buf.st_mode)) { close(vol->fd); rtems_set_errno_and_return_minus_one(ENXIO); } /* check that device is registred as block device and lock it */ rc = rtems_disk_fd_get_disk_device(vol->fd, &vol->dd); if (rc != 0) { close(vol->fd); rtems_set_errno_and_return_minus_one(ENXIO); } /* Read boot record */ /* FIXME: Asserts FAT_MAX_BPB_SIZE < bdbuf block size */ sc = rtems_bdbuf_read( vol->dd, 0, &block); if (sc != RTEMS_SUCCESSFUL) { close(vol->fd); rtems_set_errno_and_return_minus_one( EIO); } memcpy( boot_rec, block->buffer, FAT_MAX_BPB_SIZE); sc = rtems_bdbuf_release( block); if (sc != RTEMS_SUCCESSFUL) { close(vol->fd); rtems_set_errno_and_return_minus_one( EIO ); } /* Evaluate boot record */ vol->bps = FAT_GET_BR_BYTES_PER_SECTOR(boot_rec); if ( (vol->bps != 512) && (vol->bps != 1024) && (vol->bps != 2048) && (vol->bps != 4096)) { close(vol->fd); rtems_set_errno_and_return_minus_one( EINVAL ); } for (vol->sec_mul = 0, i = (vol->bps >> FAT_SECTOR512_BITS); (i & 1) == 0; i >>= 1, vol->sec_mul++); for (vol->sec_log2 = 0, i = vol->bps; (i & 1) == 0; i >>= 1, vol->sec_log2++); vol->spc = FAT_GET_BR_SECTORS_PER_CLUSTER(boot_rec); /* * "sectors per cluster" of zero is invalid * (and would hang the following loop) */ if (vol->spc == 0) { close(vol->fd); rtems_set_errno_and_return_minus_one(EINVAL); } for (vol->spc_log2 = 0, i = vol->spc; (i & 1) == 0; i >>= 1, vol->spc_log2++); /* * "bytes per cluster" value greater than 32K is invalid */ if ((vol->bpc = vol->bps << vol->spc_log2) > MS_BYTES_PER_CLUSTER_LIMIT) { close(vol->fd); rtems_set_errno_and_return_minus_one(EINVAL); } for (vol->bpc_log2 = 0, i = vol->bpc; (i & 1) == 0; i >>= 1, vol->bpc_log2++); vol->fats = FAT_GET_BR_FAT_NUM(boot_rec); vol->fat_loc = FAT_GET_BR_RESERVED_SECTORS_NUM(boot_rec); vol->rdir_entrs = FAT_GET_BR_FILES_PER_ROOT_DIR(boot_rec); /* calculate the count of sectors occupied by the root directory */ vol->rdir_secs = ((vol->rdir_entrs * FAT_DIRENTRY_SIZE) + (vol->bps - 1)) / vol->bps; vol->rdir_size = vol->rdir_secs << vol->sec_log2; if ( (FAT_GET_BR_SECTORS_PER_FAT(boot_rec)) != 0) vol->fat_length = FAT_GET_BR_SECTORS_PER_FAT(boot_rec); else vol->fat_length = FAT_GET_BR_SECTORS_PER_FAT32(boot_rec); vol->data_fsec = vol->fat_loc + vol->fats * vol->fat_length + vol->rdir_secs; /* for FAT12/16 root dir starts at(sector) */ vol->rdir_loc = vol->fat_loc + vol->fats * vol->fat_length; if ( (FAT_GET_BR_TOTAL_SECTORS_NUM16(boot_rec)) != 0) vol->tot_secs = FAT_GET_BR_TOTAL_SECTORS_NUM16(boot_rec); else vol->tot_secs = FAT_GET_BR_TOTAL_SECTORS_NUM32(boot_rec); data_secs = vol->tot_secs - vol->data_fsec; vol->data_cls = data_secs / vol->spc; /* determine FAT type at least */ if ( vol->data_cls < FAT_FAT12_MAX_CLN) { vol->type = FAT_FAT12; vol->mask = FAT_FAT12_MASK; vol->eoc_val = FAT_FAT12_EOC; } else { if ( vol->data_cls < FAT_FAT16_MAX_CLN) { vol->type = FAT_FAT16; vol->mask = FAT_FAT16_MASK; vol->eoc_val = FAT_FAT16_EOC; } else { vol->type = FAT_FAT32; vol->mask = FAT_FAT32_MASK; vol->eoc_val = FAT_FAT32_EOC; } } if (vol->type == FAT_FAT32) { vol->rdir_cl = FAT_GET_BR_FAT32_ROOT_CLUSTER(boot_rec); vol->mirror = FAT_GET_BR_EXT_FLAGS(boot_rec) & FAT_BR_EXT_FLAGS_MIRROR; if (vol->mirror) vol->afat = FAT_GET_BR_EXT_FLAGS(boot_rec) & FAT_BR_EXT_FLAGS_FAT_NUM; else vol->afat = 0; vol->info_sec = FAT_GET_BR_FAT32_FS_INFO_SECTOR(boot_rec); if( vol->info_sec == 0 ) { close(vol->fd); rtems_set_errno_and_return_minus_one( EINVAL ); } else { ret = _fat_block_read(mt_entry, vol->info_sec , 0, FAT_FSI_LEADSIG_SIZE, fs_info_sector); if ( ret < 0 ) { close(vol->fd); return -1; } if (FAT_GET_FSINFO_LEAD_SIGNATURE(fs_info_sector) != FAT_FSINFO_LEAD_SIGNATURE_VALUE) { _fat_block_release(mt_entry); close(vol->fd); rtems_set_errno_and_return_minus_one( EINVAL ); } else { ret = _fat_block_read(mt_entry, vol->info_sec , FAT_FSI_INFO, FAT_USEFUL_INFO_SIZE, fs_info_sector); if ( ret < 0 ) { _fat_block_release(mt_entry); close(vol->fd); return -1; } vol->free_cls = FAT_GET_FSINFO_FREE_CLUSTER_COUNT(fs_info_sector); vol->next_cl = FAT_GET_FSINFO_NEXT_FREE_CLUSTER(fs_info_sector); rc = fat_fat32_update_fsinfo_sector(mt_entry, 0xFFFFFFFF, 0xFFFFFFFF); if ( rc != RC_OK ) { _fat_block_release(mt_entry); close(vol->fd); return rc; } } } } else { vol->rdir_cl = 0; vol->mirror = 0; vol->afat = 0; vol->free_cls = 0xFFFFFFFF; vol->next_cl = 0xFFFFFFFF; } _fat_block_release(mt_entry); vol->afat_loc = vol->fat_loc + vol->fat_length * vol->afat; /* set up collection of fat-files fd */ fs_info->vhash = calloc(FAT_HASH_SIZE, sizeof(rtems_chain_control)); if ( fs_info->vhash == NULL ) { close(vol->fd); rtems_set_errno_and_return_minus_one( ENOMEM ); } for (i = 0; i < FAT_HASH_SIZE; i++) rtems_chain_initialize_empty(fs_info->vhash + i); fs_info->rhash = calloc(FAT_HASH_SIZE, sizeof(rtems_chain_control)); if ( fs_info->rhash == NULL ) { close(vol->fd); free(fs_info->vhash); rtems_set_errno_and_return_minus_one( ENOMEM ); } for (i = 0; i < FAT_HASH_SIZE; i++) rtems_chain_initialize_empty(fs_info->rhash + i); fs_info->uino_pool_size = FAT_UINO_POOL_INIT_SIZE; fs_info->uino_base = (vol->tot_secs << vol->sec_mul) << 4; fs_info->index = 0; fs_info->uino = (char *)calloc(fs_info->uino_pool_size, sizeof(char)); if ( fs_info->uino == NULL ) { close(vol->fd); free(fs_info->vhash); free(fs_info->rhash); rtems_set_errno_and_return_minus_one( ENOMEM ); } fs_info->sec_buf = (uint8_t *)calloc(vol->bps, sizeof(uint8_t)); if (fs_info->sec_buf == NULL) { close(vol->fd); free(fs_info->vhash); free(fs_info->rhash); free(fs_info->uino); rtems_set_errno_and_return_minus_one( ENOMEM ); } return RC_OK; }