Пример #1
0
static int udf_unmounted(service_id_t service_id)
{
	fs_node_t *fn;
	int rc = udf_root_get(&fn, service_id);
	if (rc != EOK)
		return rc;
	
	udf_node_t *nodep = UDF_NODE(fn);
	udf_instance_t *instance = nodep->instance;
	
	/*
	 * We expect exactly two references on the root node.
	 * One for the udf_root_get() above and one created in
	 * udf_mounted().
	 */
	if (nodep->ref_cnt != 2) {
		udf_node_put(fn);
		return EBUSY;
	}
	
	/*
	 * Put the root node twice.
	 */
	udf_node_put(fn);
	udf_node_put(fn);
	
	fs_instance_destroy(service_id);
	free(instance);
	block_cache_fini(service_id);
	block_fini(service_id);
	
	return EOK;
}
Пример #2
0
int main(int argc, char **argv)
{

	int rc;
	char *dev_path;
	size_t block_size;
	char *endptr;
	aoff64_t block_offset = 0;
	aoff64_t block_count = 1;
	aoff64_t dev_nblocks;
	bool toc = false;
	
	if (argc < 2) {
		printf(NAME ": Error, argument missing.\n");
		syntax_print();
		return 1;
	}

	--argc; ++argv;

	if (str_cmp(*argv, "--toc") == 0) {
		--argc; ++argv;
		toc = true;
		goto devname;
	}

	if (str_cmp(*argv, "--relative") == 0) {
		--argc; ++argv;
		relative = true;
	}
	
	if (str_cmp(*argv, "--offset") == 0) {
		--argc; ++argv;
		if (*argv == NULL) {
			printf(NAME ": Error, argument missing (offset).\n");
			syntax_print();
			return 1;
		}

		block_offset = strtol(*argv, &endptr, 10);
		if (*endptr != '\0') {
			printf(NAME ": Error, invalid argument (offset).\n");
			syntax_print();
			return 1;
		}

		--argc; ++argv;
	}
	
	if (str_cmp(*argv, "--count") == 0) {
		--argc; ++argv;
		if (*argv == NULL) {
			printf(NAME ": Error, argument missing (count).\n");
			syntax_print();
			return 1;
		}

		block_count = strtol(*argv, &endptr, 10);
		if (*endptr != '\0') {
			printf(NAME ": Error, invalid argument (count).\n");
			syntax_print();
			return 1;
		}

		--argc; ++argv;
	}

devname:
	if (argc != 1) {
		printf(NAME ": Error, unexpected argument.\n");
		syntax_print();
		return 1;
	}

	dev_path = *argv;

	rc = loc_service_get_id(dev_path, &service_id, 0);
	if (rc != EOK) {
		printf(NAME ": Error resolving device `%s'.\n", dev_path);
		return 2;
	}

	rc = block_init(service_id, 2048);
	if (rc != EOK)  {
		printf(NAME ": Error initializing libblock.\n");
		return 2;
	}

	rc = block_get_bsize(service_id, &block_size);
	if (rc != EOK) {
		printf(NAME ": Error determining device block size.\n");
		return 2;
	}

	rc = block_get_nblocks(service_id, &dev_nblocks);
	if (rc != EOK) {
		printf(NAME ": Warning, failed to obtain block device size.\n");
	}

	printf("Device %s has %" PRIuOFF64 " blocks, %" PRIuOFF64 " bytes each\n", dev_path, dev_nblocks, (aoff64_t) block_size);

	if (toc)
		rc = print_toc();
	else
		rc = print_blocks(block_offset, block_count, block_size);

	block_fini(service_id);

	return rc;
}
Пример #3
0
int main(int argc, char **argv)
{
	struct fat_cfg cfg;

	int rc;
	char *dev_path;
	service_id_t service_id;
	char *endptr;
	aoff64_t dev_nblocks;

	cfg.sector_size = default_sector_size;
	cfg.sectors_per_cluster = default_sectors_per_cluster;
	cfg.fat_count = default_fat_count;
	cfg.total_sectors = 0;
	cfg.addt_res_sectors = 0;
	cfg.root_ent_max = 128;
	cfg.fat_type = FAT16;

	if (argc < 2) {
		printf(NAME ": Error, argument missing.\n");
		syntax_print();
		return 1;
	}

	--argc; ++argv;
	if (str_cmp(*argv, "--size") == 0) {
		--argc; ++argv;
		if (*argv == NULL) {
			printf(NAME ": Error, argument missing.\n");
			syntax_print();
			return 1;
		}

		cfg.total_sectors = strtol(*argv, &endptr, 10);
		if (*endptr != '\0') {
			printf(NAME ": Error, invalid argument.\n");
			syntax_print();
			return 1;
		}

		--argc; ++argv;
	}

	if (str_cmp(*argv, "--type") == 0) {
		--argc; ++argv;
		if (*argv == NULL) {
			printf(NAME ": Error, argument missing.\n");
			syntax_print();
			return 1;
		}

		cfg.fat_type = strtol(*argv, &endptr, 10);
		if (*endptr != '\0') {
			printf(NAME ": Error, invalid argument.\n");
			syntax_print();
			return 1;
		}

		--argc; ++argv;
	}

	if (argc != 1) {
		printf(NAME ": Error, unexpected argument.\n");
		syntax_print();
		return 1;
	}

	dev_path = *argv;
	printf("Device: %s\n", dev_path);

	rc = loc_service_get_id(dev_path, &service_id, 0);
	if (rc != EOK) {
		printf(NAME ": Error resolving device `%s'.\n", dev_path);
		return 2;
	}

	rc = block_init(EXCHANGE_SERIALIZE, service_id, 2048);
	if (rc != EOK)  {
		printf(NAME ": Error initializing libblock.\n");
		return 2;
	}

	rc = block_get_bsize(service_id, &cfg.sector_size);
	if (rc != EOK) {
		printf(NAME ": Error determining device block size.\n");
		return 2;
	}

	rc = block_get_nblocks(service_id, &dev_nblocks);
	if (rc != EOK) {
		printf(NAME ": Warning, failed to obtain block device size.\n");
	} else {
		printf(NAME ": Block device has %" PRIuOFF64 " blocks.\n",
		    dev_nblocks);
		if (!cfg.total_sectors || dev_nblocks < cfg.total_sectors)
			cfg.total_sectors = dev_nblocks;
	}

	if (cfg.total_sectors == 0) {
		printf(NAME ": Error. You must specify filesystem size.\n");
		return 1;
	}

	if (cfg.fat_type != FAT12 && cfg.fat_type != FAT16 && cfg.fat_type != FAT32) {
		printf(NAME ": Error. Unknown FAT type.\n");
		return 2;
	}

	printf(NAME ": Creating FAT%d filesystem on device %s.\n", cfg.fat_type, dev_path);

	rc = fat_params_compute(&cfg);
	if (rc != EOK) {
		printf(NAME ": Invalid file-system parameters.\n");
		return 2;
	}

	rc = fat_blocks_write(&cfg, service_id);
	if (rc != EOK) {
		printf(NAME ": Error writing device.\n");
		return 2;
	}

	block_fini(service_id);
	printf("Success.\n");

	return 0;
}
Пример #4
0
static int udf_mounted(service_id_t service_id, const char *opts,
    fs_index_t *index, aoff64_t *size, unsigned *linkcnt)
{
	enum cache_mode cmode;
	
	/* Check for option enabling write through. */
	if (str_cmp(opts, "wtcache") == 0)
		cmode = CACHE_MODE_WT;
	else
		cmode = CACHE_MODE_WB;
	
	udf_instance_t *instance = malloc(sizeof(udf_instance_t));
	if (!instance)
		return ENOMEM;
	
	instance->sector_size = 0;
	
	/* Check for block size. Will be enhanced later */
	if (str_cmp(opts, "bs=512") == 0)
		instance->sector_size = 512;
	else if (str_cmp(opts, "bs=1024") == 0)
		instance->sector_size = 1024;
	else if (str_cmp(opts, "bs=2048") == 0)
		instance->sector_size = 2048;
	
	/* initialize block cache */
	int rc = block_init(service_id, MAX_SIZE);
	if (rc != EOK)
		return rc;
	
	rc = fs_instance_create(service_id, instance);
	if (rc != EOK) {
		free(instance);
		block_fini(service_id);
		return rc;
	}
	
	instance->service_id = service_id;
	instance->open_nodes_count = 0;
	
	/* Check Volume Recognition Sequence */
	rc = udf_volume_recongnition(service_id);
	if (rc != EOK) {
		log_msg(LOG_DEFAULT, LVL_NOTE, "VRS failed");
		fs_instance_destroy(service_id);
		free(instance);
		block_fini(service_id);
		return rc;
	}
	
	/* Search for Anchor Volume Descriptor */
	udf_anchor_volume_descriptor_t avd;
	rc = udf_get_anchor_volume_descriptor(service_id, &avd);
	if (rc != EOK) {
		log_msg(LOG_DEFAULT, LVL_NOTE, "Anchor read failed");
		fs_instance_destroy(service_id);
		free(instance);
		block_fini(service_id);
		return rc;
	}
	
	log_msg(LOG_DEFAULT, LVL_DEBUG,
	    "Volume: Anchor volume descriptor found. Sector size=%" PRIu32,
	    instance->sector_size);
	log_msg(LOG_DEFAULT, LVL_DEBUG,
	    "Anchor: main sequence [length=%" PRIu32 " (bytes), start=%"
	    PRIu32 " (sector)]", avd.main_extent.length,
	    avd.main_extent.location);
	log_msg(LOG_DEFAULT, LVL_DEBUG,
	    "Anchor: reserve sequence [length=%" PRIu32 " (bytes), start=%"
	    PRIu32 " (sector)]", avd.reserve_extent.length,
	    avd.reserve_extent.location);
	
	/* Initialize the block cache */
	rc = block_cache_init(service_id, instance->sector_size, 0, cmode);
	if (rc != EOK) {
		fs_instance_destroy(service_id);
		free(instance);
		block_fini(service_id);
		return rc;
	}
	
	/* Read Volume Descriptor Sequence */
	rc = udf_read_volume_descriptor_sequence(service_id, avd.main_extent);
	if (rc != EOK) {
		log_msg(LOG_DEFAULT, LVL_NOTE, "Volume Descriptor Sequence read failed");
		fs_instance_destroy(service_id);
		free(instance);
		block_cache_fini(service_id);
		block_fini(service_id);
		return rc;
	}
	
	fs_node_t *rfn;
	rc = udf_node_get(&rfn, service_id, instance->volumes[DEFAULT_VOL].root_dir);
	if (rc != EOK) {
		log_msg(LOG_DEFAULT, LVL_NOTE, "Can't create root node");
		fs_instance_destroy(service_id);
		free(instance);
		block_cache_fini(service_id);
		block_fini(service_id);
		return rc;
	}
	
	udf_node_t *node = UDF_NODE(rfn);
	*index = instance->volumes[DEFAULT_VOL].root_dir;
	*size = node->data_size;
	*linkcnt = node->link_cnt;
	
	return EOK;
}
Пример #5
0
int main (int argc, char **argv)
{
	int rc, c, opt_ind;
	char *device_name;
	size_t devblock_size;

	struct mfs_sb_info sb;

	/* Default is MinixFS V3 */
	sb.magic = MFS_MAGIC_V3;
	sb.fs_version = 3;

	/* Default block size is 4Kb */
	sb.block_size = MFS_MAX_BLOCKSIZE;
	sb.dirsize = MFS3_DIRSIZE;
	sb.n_inodes = 0;
	sb.longnames = false;
	sb.ino_per_block = V3_INODES_PER_BLOCK(MFS_MAX_BLOCKSIZE);

	if (argc == 1) {
		help_cmd_mkmfs(HELP_SHORT);
		printf("Incorrect number of arguments, try `mkmfs --help'\n");
		exit(0);
	}

	for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
		c = getopt_long(argc, argv, "lh12b:i:",
		    long_options, &opt_ind);
		switch (c) {
		case 'h':
			help_cmd_mkmfs(HELP_LONG);
			exit(0);
		case '1':
			sb.magic = MFS_MAGIC_V1;
			sb.block_size = MFS_BLOCKSIZE;
			sb.fs_version = 1;
			sb.ino_per_block = V1_INODES_PER_BLOCK;
			sb.dirsize = MFS_DIRSIZE;
			break;
		case '2':
			sb.magic = MFS_MAGIC_V2;
			sb.block_size = MFS_BLOCKSIZE;
			sb.fs_version = 2;
			sb.ino_per_block = V2_INODES_PER_BLOCK;
			sb.dirsize = MFS_DIRSIZE;
			break;
		case 'b':
			sb.block_size = (uint32_t) strtol(optarg, NULL, 10);
			break;
		case 'i':
			sb.n_inodes = (uint64_t) strtol(optarg, NULL, 10);
			break;
		case 'l':
			sb.longnames = true;
			sb.dirsize = MFSL_DIRSIZE;
			break;
		}
	}

	if (sb.block_size < MFS_MIN_BLOCKSIZE || 
	    sb.block_size > MFS_MAX_BLOCKSIZE) {
		printf(NAME ":Error! Invalid block size.\n");
		exit(0);
	} else if (!is_power_of_two(sb.block_size)) {
		/* Block size must be a power of 2. */
		printf(NAME ":Error! Invalid block size.\n");
		exit(0);
	} else if (sb.block_size > MFS_BLOCKSIZE && 
	    sb.fs_version != 3) {
		printf(NAME ":Error! Block size > 1024 is "
		    "supported by V3 filesystem only.\n");
		exit(0);
	} else if (sb.fs_version == 3 && sb.longnames) {
		printf(NAME ":Error! Long filenames are supported "
		    "by V1/V2 filesystem only.\n");
		exit(0);
	}

	if (sb.block_size == MFS_MIN_BLOCKSIZE)
		shift = 1;
	else if (sb.block_size == MFS_MAX_BLOCKSIZE)
		shift = 3;
	else
		shift = 2;

	argv += optind;

	device_name = argv[0];

	if (!device_name) {
		help_cmd_mkmfs(HELP_LONG);
		exit(0);
	}

	rc = loc_service_get_id(device_name, &service_id, 0);
	if (rc != EOK) {
		printf(NAME ": Error resolving device `%s'.\n", device_name);
		return 2;
	}

	rc = block_init(EXCHANGE_SERIALIZE, service_id, 2048);
	if (rc != EOK)  {
		printf(NAME ": Error initializing libblock.\n");
		return 2;
	}

	rc = block_get_bsize(service_id, &devblock_size);
	if (rc != EOK) {
		printf(NAME ": Error determining device block size.\n");
		return 2;
	}

	rc = block_get_nblocks(service_id, &sb.dev_nblocks);
	if (rc != EOK) {
		printf(NAME ": Warning, failed to obtain "
		    "block device size.\n");
	} else {
		printf(NAME ": Block device has %" PRIuOFF64 " blocks.\n",
		    sb.dev_nblocks);
	}

	if (devblock_size != 512) {
		printf(NAME ": Error. Device block size is not 512 bytes.\n");
		return 2;
	}

	/* Minimum block size is 1 Kb */
	sb.dev_nblocks /= 2;

	printf(NAME ": Creating Minix file system on device\n");
	printf(NAME ": Writing superblock\n");

	/* Initialize superblock */
	if (init_superblock(&sb) != EOK) {
		printf(NAME ": Error. Superblock initialization failed\n");
		return 2;
	}

	printf(NAME ": Initializing bitmaps\n");

	/* Initialize bitmaps */
	if (init_bitmaps(&sb) != EOK) {
		printf(NAME ": Error. Bitmaps initialization failed\n");
		return 2;
	}

	printf(NAME ": Initializing the inode table\n");

	/* Init inode table */
	if (init_inode_table(&sb) != EOK) {
		printf(NAME ": Error. Inode table initialization failed\n");
		return 2;
	}

	printf(NAME ": Creating the root directory inode\n");

	/* Make the root inode */
	if (sb.fs_version == 1)
		rc = make_root_ino(&sb);
	else
		rc = make_root_ino2(&sb);

	if (rc != EOK) {
		printf(NAME ": Error. Root inode initialization failed\n");
		return 2;
	}

	/* Insert directory entries . and .. */
	if (insert_dentries(&sb) != EOK) {
		printf(NAME ": Error. Root directory initialization failed\n");
		return 2;
	}

	block_fini(service_id);

	return 0;
}