Beispiel #1
0
/** Get cluster from the first FAT.
 *
 * @param bs		Buffer holding the boot sector for the file system.
 * @param service_id	Service ID for the file system.
 * @param clst		Cluster which to get.
 * @param value		Output argument holding the value of the cluster.
 *
 * @return		EOK or a negative error code.
 */
static int
fat_get_cluster_fat12(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
    fat_cluster_t clst, fat_cluster_t *value)
{
	block_t *b, *b1;
	uint16_t byte1, byte2;
	aoff64_t offset;
	int rc;

	offset = (clst + clst / 2);
	if (offset / BPS(bs) >= SF(bs))
		return ERANGE;

	rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno +
	    offset / BPS(bs), BLOCK_FLAGS_NONE);
	if (rc != EOK)
		return rc;

	byte1 = ((uint8_t *) b->data)[offset % BPS(bs)];
	/* This cluster access spans a sector boundary. Check only for FAT12 */
	if ((offset % BPS(bs)) + 1 == BPS(bs)) {
		/* Is this the last sector of FAT? */
		if (offset / BPS(bs) < SF(bs)) {
			/* No, read the next sector */
			rc = block_get(&b1, service_id, 1 + RSCNT(bs) +
			    SF(bs) * fatno + offset / BPS(bs),
			    BLOCK_FLAGS_NONE);
			if (rc != EOK) {
				block_put(b);
				return rc;
			}
			/*
			* Combining value with last byte of current sector and
			* first byte of next sector
			*/
			byte2 = ((uint8_t*) b1->data)[0];

			rc = block_put(b1);
			if (rc != EOK) {
				block_put(b);
				return rc;
			}
		} else {
			/* Yes. This is the last sector of FAT */
			block_put(b);
			return ERANGE;
		}
	} else
		byte2 = ((uint8_t *) b->data)[(offset % BPS(bs)) + 1];

	*value = uint16_t_le2host(byte1 | (byte2 << 8));
	if (IS_ODD(clst))
		*value = (*value) >> 4;
	else
Beispiel #2
0
void print_inode_data(ext2_filesystem_t *fs, ext2_inode_t *inode, uint32_t data)
{
	int rc;
	uint32_t data_block_index;
	block_t *block;
	
	rc = ext2_filesystem_get_inode_data_block_index(fs, inode, data,
	    &data_block_index);
	
	if (rc != EOK) {
		printf("Failed getting data block #%u\n", data);
		return;
	}
	
	printf("Data for inode contents block #%u is located in filesystem "
	    "block %u\n", data, data_block_index);
	
	printf("Data preview (only printable characters):\n");
	
	rc = block_get(&block, fs->device, data_block_index, 0);
	if (rc != EOK) {
		printf("Failed reading filesystem block %u\n", data_block_index);
		return;
	}
	
	print_data(block->data, block->size);
	printf("\n");	
	
	rc = block_put(block);
	if (rc != EOK) {
		printf("Failed putting filesystem block\n");
	}
	
}
/*
 ****************************************************************
 *	Encerra o uso das entradas da tabela "disktb"		*
 ****************************************************************
 */
int
disktb_close_entry (dev_t dev)
{
	DISKTB		*up;
	int		i;
	BHEAD		*bp;

	/*
	 *	Obtém a partição inicial do dispositivo
	 */
	if ((up = disktb_get_first_entry (dev)) == NODISKTB)
		return (-1);

	/*
	 *	Força a releitura da tabela de partições
	 */
	bp = block_get (up->p_dev, 0, 0);

#ifdef	DEBUG
	printf ("%v: O bloco 0 == %d\n", up->p_dev, EVENTTEST (&bp->b_done));
#endif	DEBUG

	EVENTCLEAR (&bp->b_done); block_put (bp);

	/*
	 *	Encerra as entradas
	 */
	for (i = 0; i < 2; i++, up++)
	{
	   /***	up->p_name = ...; ***/

		up->p_offset = 0;
		up->p_size   = BL4SZ / BLSZ;	/* Provisório, para ler a "parttb" */

	   /***	up->p_dev    = ...; ***/
	   /***	up->p_unit   = ...; ***/
	   /***	up->p_target = ...; ***/

		up->p_type  = 0;
		up->p_flags = 0;

		up->p_head  = 0;
		up->p_sect  = 0;
		up->p_cyl   = 0;

		if (up->p_nopen != 0)
		{
			printf
			(	"%s: p_nopen residual: %d\n",
				up->p_name, up->p_nopen
			);
		}

		up->p_nopen  = 0;
		up->p_lock  = 0;
	}

	return (0);

}	/* end disktb_close_entry */
Beispiel #4
0
static int fat_node_sync(fat_node_t *node)
{
	block_t *b;
	fat_bs_t *bs;
	fat_dentry_t *d;
	int rc;

	assert(node->dirty);

	bs = block_bb_get(node->idx->service_id);

	/* Read the block that contains the dentry of interest. */
	rc = _fat_block_get(&b, bs, node->idx->service_id, node->idx->pfc,
	    NULL, (node->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs),
	    BLOCK_FLAGS_NONE);
	if (rc != EOK)
		return rc;

	d = ((fat_dentry_t *)b->data) + (node->idx->pdi % DPS(bs));

	d->firstc = host2uint16_t_le(node->firstc);
	if (node->type == FAT_FILE) {
		d->size = host2uint32_t_le(node->size);
	} else if (node->type == FAT_DIRECTORY) {
		d->attr = FAT_ATTR_SUBDIR;
	}

	/* TODO: update other fields? (e.g time fields) */

	b->dirty = true;		/* need to sync block */
	rc = block_put(b);
	return rc;
}
static int fat_directory_block_load(fat_directory_t *di)
{
	uint32_t i;
	int rc;

	i = (di->pos * sizeof(fat_dentry_t)) / BPS(di->bs);
	if (i < di->blocks) {
		if (di->b && di->bnum != i) {
			block_put(di->b);
			di->b = NULL;
		}
		if (!di->b) {
			rc = fat_block_get(&di->b, di->bs, di->nodep, i,
			    BLOCK_FLAGS_NONE);
			if (rc != EOK) {
				di->b = NULL;
				return rc;
			}
			di->bnum = i;
		}
		return EOK;
	}

	return ENOENT;
}
/*
 ****************************************************************
 *	Certifica-se de que o sistema de arquivos é V7		*
 ****************************************************************
 */
int
v7_authen (dev_t dev)
{
	BHEAD		*bp;
	int		status = -1;
	DISKTB		*up;

	/*
	 *	Confere a assinatura mágica
	 */
	u.u_error = NOERR;

	bp = bread (dev, V7_SBNO, 0);

	if   (u.u_error)
		/* vazio */;
	elif (ENDIAN_LONG (((V7SB *)bp->b_addr)->s_magic) != V7_SBMAGIC)
		u.u_error = ENOTFS;
	elif (status = 0, (up = disktb_get_entry (dev)) != NODISKTB && up->p_type == 0)
		up->p_type = PAR_TROPIX_V7;

	block_put (bp);

	return (status);

}	/* end v7_authen */
int exfat_bitmap_set_cluster(exfat_bs_t *bs, service_id_t service_id, 
    exfat_cluster_t clst)
{
	fs_node_t *fn;
	block_t *b = NULL;
	exfat_node_t *bitmapp;
	uint8_t *bitmap;
	int rc;

	clst -= EXFAT_CLST_FIRST;
	
	rc = exfat_bitmap_get(&fn, service_id);
	if (rc != EOK)
		return rc;
	bitmapp = EXFAT_NODE(fn);
	
	aoff64_t offset = clst / 8;
	rc = exfat_block_get(&b, bs, bitmapp, offset / BPS(bs), BLOCK_FLAGS_NONE);
	if (rc != EOK) {
		(void) exfat_node_put(fn);
		return rc;
	}
	bitmap = (uint8_t *)b->data;
	bitmap[offset % BPS(bs)] |= (1 << (clst % 8));

	b->dirty = true;
	rc = block_put(b);
	if (rc != EOK) {
		(void) exfat_node_put(fn);
		return rc;
	}
	
	return exfat_node_put(fn);
}
Beispiel #8
0
static ssize_t block_write(struct cdev *cdev, const void *buf, size_t count,
		unsigned long offset, ulong flags)
{
	struct block_device *blk = cdev->priv;
	unsigned long mask = BLOCKSIZE(blk) - 1;
	unsigned long block = offset >> blk->blockbits;
	size_t icount = count;
	int blocks;

	if (offset & mask) {
		size_t now = BLOCKSIZE(blk) - (offset & mask);
		void *iobuf = block_get(blk, block);

		now = min(count, now);

		if (IS_ERR(iobuf))
			return PTR_ERR(iobuf);

		memcpy(iobuf + (offset & mask), buf, now);
		block_put(blk, iobuf, block);
		buf += now;
		count -= now;
		block++;
	}

	blocks = count >> blk->blockbits;

	while (blocks) {
		block_put(blk, buf, block);
		buf += BLOCKSIZE(blk);
		blocks--;
		block++;
		count -= BLOCKSIZE(blk);
	}

	if (count) {
		void *iobuf = block_get(blk, block);

		if (IS_ERR(iobuf))
			return PTR_ERR(iobuf);

		memcpy(iobuf, buf, count);
		block_put(blk, iobuf, block);
	}

	return icount;
}
int fat_directory_close(fat_directory_t *di)
{
	int rc = EOK;
	
	if (di->b)
		rc = block_put(di->b);
	
	return rc;
}
Beispiel #10
0
/** Fill the gap between EOF and a new file position.
 *
 * @param bs		Buffer holding the boot sector for nodep.
 * @param nodep		FAT node with the gap.
 * @param mcl		First cluster in an independent cluster chain that will
 *			be later appended to the end of the node's own cluster
 *			chain. If pos is still in the last allocated cluster,
 *			this argument is ignored.
 * @param pos		Position in the last node block.
 *
 * @return		EOK on success or a negative error code.
 */
int
fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, aoff64_t pos)
{
	block_t *b;
	aoff64_t o, boundary;
	int rc;

	boundary = ROUND_UP(nodep->size, BPS(bs) * SPC(bs));

	/* zero out already allocated space */
	for (o = nodep->size; o < pos && o < boundary;
	    o = ALIGN_DOWN(o + BPS(bs), BPS(bs))) {
	    	int flags = (o % BPS(bs) == 0) ?
		    BLOCK_FLAGS_NOREAD : BLOCK_FLAGS_NONE;
		rc = fat_block_get(&b, bs, nodep, o / BPS(bs), flags);
		if (rc != EOK)
			return rc;
		memset(b->data + o % BPS(bs), 0, BPS(bs) - o % BPS(bs));
		b->dirty = true;		/* need to sync node */
		rc = block_put(b);
		if (rc != EOK)
			return rc;
	}

	if (o >= pos)
		return EOK;

	/* zero out the initial part of the new cluster chain */
	for (o = boundary; o < pos; o += BPS(bs)) {
		rc = _fat_block_get(&b, bs, nodep->idx->service_id, mcl,
		    NULL, (o - boundary) / BPS(bs), BLOCK_FLAGS_NOREAD);
		if (rc != EOK)
			return rc;
		memset(b->data, 0, min(BPS(bs), pos - o));
		b->dirty = true;		/* need to sync node */
		rc = block_put(b);
		if (rc != EOK)
			return rc;
	}

	return EOK;
}
Beispiel #11
0
/* if the added stuff does not fit on current page, write it out
   after page break and change buffer handling mode to pass though */
void buffer_eob(int eot)
{
	block_put();
	if (epsf) {
		if (epsf == 3)
			write_eps();		/* close the image */
		return;
	}
	if (remy + bposy >= 0
	 || multicol_start != 0)
		return;

	// page full
	if (!in_page) {
		if ((cfmt.splittune == 2 && !(nbpages & 1))
		 || (cfmt.splittune == 3 && (nbpages & 1))) { // wrong odd/even page
			if (remy + maxy + bposy < 0) {	// 2nd overflow
				init_page();
				close_page();
				write_buffer();
				return;
			}
			if (eot)
				write_buffer();
			return;
		}
	} else {
		close_page();
	}
	if ((cfmt.splittune == 2 && !(nbpages & 1))
	 || (cfmt.splittune == 3 && (nbpages & 1)))
		use_buffer = 1;			// if wrong odd/even page
	else
		write_buffer();
#if 0
--- old
		if (use_buffer
		 && !eot
		 && ((cfmt.splittune == 2 && !(nbpages & 1))
		   || (cfmt.splittune == 3 && (nbpages & 1)))) {
			init_page();
// 8.7.4
			use_buffer = 1;
		} else {
// 8.7.5 - required to avoid buffer overflow
			write_buffer();
		}
//8.7.0
//		write_buffer();
//8.6.2
//		use_buffer = 0;
#endif
}
Beispiel #12
0
static int udf_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
{
	char *name = malloc(MAX_FILE_NAME_LEN + 1);
	if (name == NULL)
		return ENOMEM;
	
	block_t *block = NULL;
	udf_file_identifier_descriptor_t *fid = NULL;
	size_t pos = 0;
	
	while (udf_get_fid(&fid, &block, UDF_NODE(pfn), pos) == EOK) {
		udf_long_ad_t long_ad = fid->icb;
		
		udf_to_unix_name(name, MAX_FILE_NAME_LEN,
		    (char *) fid->implementation_use + FLE16(fid->lenght_iu),
		    fid->lenght_file_id, &UDF_NODE(pfn)->instance->charset);
		
		if (stricmp(name, component) == 0) {
			int rc = udf_node_get(rfn, udf_service_get(pfn),
			    udf_long_ad_to_pos(UDF_NODE(pfn)->instance, &long_ad));
			
			if (block != NULL)
				block_put(block);
			
			free(name);
			return rc;
		}
		
		if (block != NULL) {
			int rc = block_put(block);
			if (rc != EOK)
				return rc;
		}
		
		pos++;
	}
	
	free(name);
	return ENOENT;
}
Beispiel #13
0
/** Set cluster in FAT.
 *
 * @param bs		Buffer holding the boot sector for the file system.
 * @param service_id	Service ID for the file system.
 * @param clst		Cluster which is to be set.
 * @param value		Value to set the cluster with.
 *
 * @return		EOK on success or a negative error code.
 */
int
exfat_set_cluster(exfat_bs_t *bs, service_id_t service_id,
    exfat_cluster_t clst, exfat_cluster_t value)
{
	block_t *b;
	aoff64_t offset;
	int rc;

	offset = clst * sizeof(exfat_cluster_t);

	rc = block_get(&b, service_id, FAT_FS(bs) + offset / BPS(bs), BLOCK_FLAGS_NONE);
	if (rc != EOK)
		return rc;

	*(uint32_t *)(b->data + offset % BPS(bs)) = host2uint32_t_le(value);

	b->dirty = true;	/* need to sync block */
	rc = block_put(b);
	return rc;
}
Beispiel #14
0
/** Get cluster from the FAT.
 *
 * @param bs		Buffer holding the boot sector for the file system.
 * @param service_id	Service ID for the file system.
 * @param clst		Cluster which to get.
 * @param value		Output argument holding the value of the cluster.
 *
 * @return		EOK or a negative error code.
 */
int
exfat_get_cluster(exfat_bs_t *bs, service_id_t service_id,
    exfat_cluster_t clst, exfat_cluster_t *value)
{
	block_t *b;
	aoff64_t offset;
	int rc;

	offset = clst * sizeof(exfat_cluster_t);

	rc = block_get(&b, service_id, FAT_FS(bs) + offset / BPS(bs), BLOCK_FLAGS_NONE);
	if (rc != EOK)
		return rc;

	*value = uint32_t_le2host(*(uint32_t *)(b->data + offset % BPS(bs)));

	rc = block_put(b);

	return rc;
}
Beispiel #15
0
int
exfat_zero_cluster(exfat_bs_t *bs, service_id_t service_id, exfat_cluster_t c)
{
	size_t i;
	block_t *b;
	int rc;

	for (i = 0; i < SPC(bs); i++) {
		rc = exfat_block_get_by_clst(&b, bs, service_id, false, c, NULL,
		    i, BLOCK_FLAGS_NOREAD);
		if (rc != EOK)
			return rc;
		memset(b->data, 0, BPS(bs));
		b->dirty = true;
		rc = block_put(b);
		if (rc != EOK)
			return rc;
	}

	return EOK;
}
Beispiel #16
0
int
exfat_read_uctable(exfat_bs_t *bs, exfat_node_t *nodep, uint8_t *uctable)
{
	size_t i, blocks, count;
	block_t *b;
	int rc;
	blocks = ROUND_UP(nodep->size, BPS(bs))/BPS(bs);
	count = BPS(bs);
	
	for (i = 0; i < blocks; i++) {
		rc = exfat_block_get(&b, bs, nodep, i, BLOCK_FLAGS_NOREAD);
		if (rc != EOK)
			return rc;
		if (i == blocks - 1)
			count = nodep->size - i * BPS(bs);
		memcpy(uctable, b->data, count);
		uctable += count;
		rc = block_put(b);
		if (rc != EOK)
			return rc;
	}

	return EOK;
}
Beispiel #17
0
static int udf_read(service_id_t service_id, fs_index_t index, aoff64_t pos,
    size_t *rbytes)
{
	udf_instance_t *instance;
	int rc = fs_instance_get(service_id, (void **) &instance);
	if (rc != EOK)
		return rc;
	
	fs_node_t *rfn;
	rc = udf_node_get(&rfn, service_id, index);
	if (rc != EOK)
		return rc;
	
	udf_node_t *node = UDF_NODE(rfn);
	
	ipc_callid_t callid;
	size_t len = 0;
	if (!async_data_read_receive(&callid, &len)) {
		async_answer_0(callid, EINVAL);
		udf_node_put(rfn);
		return EINVAL;
	}
	
	if (node->type == NODE_FILE) {
		if (pos >= node->data_size) {
			*rbytes = 0;
			async_data_read_finalize(callid, NULL, 0);
			udf_node_put(rfn);
			return EOK;
		}
		
		size_t read_len = 0;
		if (node->data == NULL)
			rc = udf_read_file(&read_len, callid, node, pos, len);
		else {
			/* File in allocation descriptors area */
			read_len = (len < node->data_size) ? len : node->data_size;
			async_data_read_finalize(callid, node->data + pos, read_len);
			rc = EOK;
		}
		
		*rbytes = read_len;
		(void) udf_node_put(rfn);
		return rc;
	} else {
		block_t *block = NULL;
		udf_file_identifier_descriptor_t *fid = NULL;
		if (udf_get_fid(&fid, &block, node, pos) == EOK) {
			char *name = malloc(MAX_FILE_NAME_LEN + 1);
			
			// FIXME: Check for NULL return value
			
			udf_to_unix_name(name, MAX_FILE_NAME_LEN,
			    (char *) fid->implementation_use + FLE16(fid->lenght_iu),
			    fid->lenght_file_id, &node->instance->charset);
			
			async_data_read_finalize(callid, name, str_size(name) + 1);
			*rbytes = 1;
			free(name);
			udf_node_put(rfn);
			
			if (block != NULL)
				return block_put(block);
			
			return EOK;
		} else {
			*rbytes = 0;
			udf_node_put(rfn);
			async_answer_0(callid, ENOENT);
			return ENOENT;
		}
	}
}
Beispiel #18
0
			}
		} else {
			/* Yes. This is the last sector of FAT */
			block_put(b);
			return ERANGE;
		}
	} else
		byte2 = ((uint8_t *) b->data)[(offset % BPS(bs)) + 1];

	*value = uint16_t_le2host(byte1 | (byte2 << 8));
	if (IS_ODD(clst))
		*value = (*value) >> 4;
	else
		*value = (*value) & FAT12_MASK;
	
	rc = block_put(b);

	return rc;
}

/** Get cluster from the first FAT.
 *
 * @param bs		Buffer holding the boot sector for the file system.
 * @param service_id	Service ID for the file system.
 * @param clst		Cluster which to get.
 * @param value		Output argument holding the value of the cluster.
 *
 * @return		EOK or a negative error code.
 */
static int
fat_get_cluster_fat16(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
/*
 ****************************************************************
 *	Operação de MOUNT					*
 ****************************************************************
 */
int
v7_mount (SB *sp)
{
	BHEAD		*bp;
	V7SB		*v7sp;

	/*
	 *	Aloca a parte específica do V7SB
	 */
	if ((v7sp = malloc_byte (sizeof (V7SB))) == NOV7SB)
		{ u.u_error = ENOMEM; return (-1); }

	bp = bread (sp->sb_dev, V7_SBNO, 0);

	if (u.u_error)
		{ block_put (bp); goto out_6; }

	memmove (v7sp, bp->b_addr, sizeof (V7SB));

	block_put (bp);

#ifdef	LITTLE_ENDIAN
	/*
	 *	Se for o caso, converte, ...
	 */
	v7_sb_endian_conversion (v7sp);
#endif	LITTLE_ENDIAN

#define	MOUNTCHK
#ifdef	MOUNTCHK
	/*
	 *	Verifica se é realmente um SB de um sistema  de arquivos
	 */
	if (v7sp->s_magic != V7_SBMAGIC)
		{ u.u_error = ENOTFS; goto out_6; }
#endif	MOUNTCHK

	/*
	 *	Verifica a validade das listas livres do SB
	 */
	if ((unsigned)v7sp->s_nfblk > V7_SBFBLK || (unsigned)v7sp->s_nfdino > V7_SBFDINO)
	{
		printf ("%g: Dispositivo \"%v\" com lista livre inválida\n", sp->sb_dev);

		u.u_error = ENOTFS; goto out_6;
	}

	/*
	 *	Atualiza as entradas do SB
	 */
	strcpy (sp->sb_fname, v7sp->s_fname);
	strcpy (sp->sb_fpack, v7sp->s_fpack);

	sp->sb_code	= FS_V7;
	sp->sb_ptr	= v7sp;

	sp->sb_root_ino	= V7_ROOT_INO;

	/*
	 *	Inicializa as variáveis da V7
	 */
	SLEEPCLEAR (&v7sp->s_flock);
	SLEEPCLEAR (&v7sp->s_ilock);

	return (0);

	/*
	 *	Em caso de ERRO
	 */
    out_6:
	free_byte (v7sp);

	return (-1);

}	/* end v7_mount */
Beispiel #20
0
/*
 ****************************************************************
 *	Le as partições do volume e atualiza a "disktb"		*
 ****************************************************************
 */
int
disktb_open_entries (dev_t dev, const SCSI *sp)
{
	DISKTB		*up;
	BHEAD		*bp;
	const PARTTB	*reg_pp;
	HDINFO		hdinfo;
	int		reg_index;

	/*
	 *	Obtém a partição inicial do dispositivo
	 */
	if ((up = disktb_get_first_entry (dev)) == NODISKTB)
		return (-1);

	/*
	 *	Le o Bloco 0 do volume
	 */
	bp = bread (up->p_dev, 0, 0);

	if (bp->b_flags & B_ERROR)
		{ block_put (bp); return (-1); }

	if (*(ushort *)(bp->b_addr + MAGIC_OFF) != 0xAA55)
	{
		printf
		(	"%s: O bloco 0 NÃO contém a assinatura \"0x55AA\"\n",
			up->p_name
		);
	}

	/*
	 *	Tenta obter a geometria do disco
	 */
	geo_get_parttb_geo (up->p_name, bp->b_addr, &hdinfo, sp->scsi_disksz);

	/*
	 *	Processa (por enquanto) somente a primeira partição regular
	 */
	for
	(	reg_index = 0, reg_pp = (PARTTB *)(bp->b_addr + PARTB_OFF);
		/* abaixo */;
		reg_index++, reg_pp++
	)
	{
		if (reg_index >= NPART)
		{
			printf
			(	"%s: Volume NÃO tem partição regular\n",
				up->p_name
			);
			u.u_error = ENXIO; block_put (bp); return (-1);
		}

		if (reg_pp->pt_size == 0)
			continue;

		if (!IS_EXT (reg_pp->pt_type))
			break;

		printf
		(	"%s: Partição ESTENDIDA ignorada\n",
			up->p_name
		);
	}

	/*
	 *	Completa a entrada do disco inteiro
	 */
   /***	up->p_offset	= ...; ***/
	up->p_size	= sp->scsi_disksz;

   /***	up->p_type	= 0; ***/
   /***	up->p_flags	= 0; ***/
   /***	up->p_lock	= 0; ***/
	up->p_blshift	= sp->scsi_blshift;

   /***	up->p_dev	= ...; ***/
   /***	up->p_unit	= ...; ***/
   /***	up->p_target	= ...; ***/

	up->p_head	= hdinfo.h_head;
	up->p_sect	= hdinfo.h_sect;
	up->p_cyl	= hdinfo.h_cyl;
   /***	up->p_nopen	= 0; ***/

	/*
	 *	Prepara a entrada da partição regular
	 */
	up++;

	up->p_offset	= reg_pp->pt_offset;
	up->p_size	= reg_pp->pt_size;

	up->p_type	= reg_pp->pt_type;
	up->p_flags	= (reg_pp->pt_active == 0x80) ?  DISK_ACTIVE : 0;
   /***	up->p_lock	= 0; ***/
	up->p_blshift	= sp->scsi_blshift;

   /***	up->p_dev	= ...; ***/
   /***	up->p_unit	= ...; ***/
   /***	up->p_target	= ...; ***/

	up->p_head	= hdinfo.h_head;
	up->p_sect	= hdinfo.h_sect;
	up->p_cyl	= hdinfo.h_cyl;
   /***	up->p_nopen	= 0; ***/

	block_put (bp);
	return (0);

}	/* end disktb_open_entries */
Beispiel #21
0
/*
 ****************************************************************
 *	Lê as partições do volume e atualiza a "disktb"		*
 ****************************************************************
 */
DISKTB *
disktb_create_partitions (DISKTB *base_up)
{
	DISKTB		*up, *slot_up = NODISKTB;
	const DISKTB	*end_up;
	dev_t		dev;
	BHEAD		*bp;
	const PARTTB	*reg_pp, *log_pp;
	daddr_t		log_offset, ext_begin, ext_end;
	int		reg_index, log_index, minor_index = 1;
	int		slot_sz, dec;
	HDINFO		hdinfo;
	char		area[BLSZ];

	/*
	 *	A partição global do volume acabou de ser criada
	 *
	 *	("base_up" é idêntico a "next_disktb")
	 *
	 *	Lê o Bloco 0 do volume e extrai a tabela de partições
	 */
	up = base_up; dev = up->p_dev;

	bp = bread (dev, 0, 0);

	if (bp->b_flags & B_ERROR)
		{ block_put (bp); return (NODISKTB); }

	if (*(ushort *)(bp->b_addr + MAGIC_OFF) != 0xAA55)
		printf ("%s: O bloco 0 NÃO contém a assinatura \"0x55AA\"\n", up->p_name);

	memmove (area, bp->b_addr, BLSZ);

	block_put (bp); bp = NOBHEAD;

	/*
	 *	Tenta obter a geometria do volume
	 */
	geo_get_parttb_geo (up->p_name, area, &hdinfo, up->p_size);

	/*
	 *	Completa a entrada para o volume inteiro
	 */
   /***	up->p_name	= ...;	***/

   /***	up->p_offset	= 0;	***/
   /***	up->p_size	= ...;	***/

   /***	up->p_type	= 0;	***/
   /***	up->p_flags	= 0;	***/
   /***	up->p_lock	= 0;	***/
   /***	up->p_blshift	= ...;	***/

   /***	up->p_dev	= ...;	***/
   /***	up->p_unit	= ...;	***/
   /***	up->p_target	= ...;	***/

	up->p_head	= hdinfo.h_head;
	up->p_sect	= hdinfo.h_sect;
	up->p_cyl	= hdinfo.h_cyl;

   /***	up->p_nopen	= 0;	   ***/
   /***	up->p_sb	= NOSB;    ***/
   /***	up->p_inode	= NOINODE; ***/

	up++;

	/*
	 *	Processa todas as partições
	 */
	for (reg_pp = (PARTTB *)(area + PARTB_OFF), reg_index = 1; reg_index <= NPART; reg_index++, reg_pp++)
	{
		if (reg_pp->pt_size == 0)
			continue;

		/* Encontrou uma partição regular/estendida válida */

		if (up >= end_disktb - 1)
			{ printf ("%s: DISKTB cheia\n", base_up->p_name); break; }

		sprintf (up->p_name, "%s%d", base_up->p_name, reg_index);

		up->p_offset	= reg_pp->pt_offset;
		up->p_size	= reg_pp->pt_size;

		up->p_type	= reg_pp->pt_type;
		up->p_flags	= (reg_pp->pt_active == 0x80) ? DISK_ACTIVE : 0;
	   /***	up->p_lock	= 0;       ***/
		up->p_blshift	= base_up->p_blshift;

		up->p_dev	= dev + minor_index++;	/* incrementa o MINOR */
		up->p_unit	= base_up->p_unit;
		up->p_target	= base_up->p_target;

		up->p_head	= hdinfo.h_head;
		up->p_sect	= hdinfo.h_sect;
		up->p_cyl	= hdinfo.h_cyl;

	   /***	up->p_nopen	= 0;	   ***/
	   /***	up->p_sb	= NOSB;	   ***/
	   /***	up->p_inode	= NOINODE; ***/

		up++;

		if (!IS_EXT (reg_pp->pt_type))
			continue;

		/*
		 *	Temos uma partição estendida
		 */
		ext_begin  = reg_pp->pt_offset;
		ext_end    = reg_pp->pt_offset + reg_pp->pt_size;

		log_offset = ext_begin;

		/*
		 *	Percorre a cadeia de partições lógicas
		 */
		for (log_index = 0; /* abaixo */; log_index++)
		{
			if (log_offset < ext_begin || log_offset >= ext_end)
			{
				printf
				(	"%s: Deslocamento %d inválido na partição estendida %d\n",
					base_up->p_name, log_offset, reg_index
				);
				break;
			}

			if (bp != NOBHEAD)
				block_put (bp);

			bp = bread (dev, log_offset, 0);

			if (bp->b_flags & B_ERROR)
				{ block_put (bp); bp = NOBHEAD; break; }

			if (*(ushort *)(bp->b_addr + MAGIC_OFF) != 0xAA55)
			{
				printf
				(	"%s: O bloco %d da partição estendida %d "
					"NÃO contém a assinatura \"0x55AA\"\n",
					base_up->p_name, log_offset, reg_index
				);
			}

			log_pp = (PARTTB *)(bp->b_addr + PARTB_OFF);

			if (log_pp[0].pt_size == 0) /* Primeiro método de EOF */
				break;

			/* Encontrou uma partição lógica válida */

			if (up >= end_disktb - 1)
				{ printf ("%s: DISKTB cheia\n", base_up->p_name); goto out; }

			sprintf (up->p_name, "%s%d%c", base_up->p_name, reg_index, 'a' + log_index);

			up->p_offset	= log_offset + log_pp->pt_offset;
			up->p_size	= log_pp->pt_size;

			up->p_type	= log_pp->pt_type;
			up->p_flags	= (log_pp->pt_active == 0x80) ? DISK_ACTIVE : 0;
		   /***	up->p_lock	= 0;       ***/
			up->p_blshift	= base_up->p_blshift;

			up->p_dev	= dev + minor_index++;	/* incrementa o MINOR */
			up->p_unit	= base_up->p_unit;
			up->p_target	= base_up->p_target;

			up->p_head	= hdinfo.h_head;
			up->p_sect	= hdinfo.h_sect;
			up->p_cyl	= hdinfo.h_cyl;

		   /***	up->p_nopen	= 0;	   ***/
		   /***	up->p_sb	= NOSB;	   ***/
		   /***	up->p_inode	= NOINODE; ***/

			up++;

			/*
			 *	Procura a partição seguinte
			 */
			if (log_pp[1].pt_size == 0)	/* Segundo método de EOF */
				break;

			log_offset = ext_begin + log_pp[1].pt_offset;

		}	/* end for (cadeia de partições lógicas) */

	}	/* end for (partições regulares/estendeidas) */

    out:
	if (bp != NOBHEAD)
		block_put (bp);

	/*
	 *	Atualiza o final da "disktb"
	 */
	next_disktb = up; up->p_name[0] = '\0';

	/*
	 *	Neste ponto, "minor_index" contém o número de entradas total
	 *
	 *	Procura um grupo de "minor_index" entradas vagas contíguas
	 */
	for (slot_sz = 0, up = disktb; /* abaixo */; up++)
	{
		if (up >= base_up)
			return (base_up);

		if (up->p_name[0] != '*')
			{ slot_sz = 0; continue; }

		if (slot_sz++ == 0)
			slot_up = up;

		if (slot_sz >= minor_index)
			break;
	}

	/*
	 *	Encontrou um grupo adequado
	 */
	memmove (slot_up, base_up, minor_index * sizeof (DISKTB));

	dec = base_up - slot_up;

	for (up = slot_up, end_up = up + minor_index; up < end_up; up++)
		up->p_dev -= dec;	/* Supondo que o MINOR esteja na parte baixa */

	memclr (base_up, minor_index * sizeof (DISKTB));

	next_disktb = base_up;

	return (slot_up);

}	/* end disktb_create_partitions */