Exemplo n.º 1
0
static int
udf_write_dscr_phys(union dscrptr *dscr, uint32_t location,
	uint32_t sects)
{
	dscr->tag.tag_loc = udf_rw32(location);
	(void) udf_validate_tag_and_crc_sums(dscr);

	return udf_write_phys(dscr, location, sects);
}
Exemplo n.º 2
0
int
udf_write_dscr_virt(union dscrptr *dscr, uint32_t location, uint32_t vpart,
	uint32_t sects)
{
	struct file_entry *fe;
	struct extfile_entry *efe;
	struct extattrhdr_desc *extattrhdr;
	uint32_t phys;

	extattrhdr = NULL;
	if (udf_rw16(dscr->tag.id) == TAGID_FENTRY) {
		fe = (struct file_entry *) dscr;
		if (udf_rw32(fe->l_ea) > 0)
			extattrhdr = (struct extattrhdr_desc *) fe->data;
	}
	if (udf_rw16(dscr->tag.id) == TAGID_EXTFENTRY) {
		efe = (struct extfile_entry *) dscr;
		if (udf_rw32(efe->l_ea) > 0)
			extattrhdr = (struct extattrhdr_desc *) efe->data;
	}
	if (extattrhdr) {
		extattrhdr->tag.tag_loc = udf_rw32(location);
		udf_validate_tag_and_crc_sums((union dscrptr *) extattrhdr);
	}

	dscr->tag.tag_loc = udf_rw32(location);
	udf_validate_tag_and_crc_sums(dscr);

	/* determine physical location */
	phys = context.vtop_offset[vpart];
	if (context.vtop_tp[vpart] == UDF_VTOP_TYPE_VIRT) {
		udf_vat_update(location, context.data_alloc_pos);
		phys += context.data_alloc_pos++;
	} else {
		phys += location;
	}

	return udf_write_phys(dscr, phys, sects);
}
static void
udf_issue_buf(struct udf_mount *ump, int queue, struct buf *buf)
{
	union dscrptr *dscr;
	struct long_ad *node_ad_cpy;
	struct part_desc *pdesc;
	uint64_t *lmapping, *lmappos;
	uint32_t sectornr, bpos;
	uint32_t ptov;
	uint16_t vpart_num;
	uint8_t *fidblk;
	int sector_size = ump->discinfo.sector_size;
	int blks = sector_size / DEV_BSIZE;
	int len, buf_len;

	/* if reading, just pass to the device's STRATEGY */
	if (queue == UDF_SHED_READING) {
		DPRINTF(SHEDULE, ("\nudf_issue_buf READ %p : sector %d type %d,"
			"b_resid %d, b_bcount %d, b_bufsize %d\n",
			buf, (uint32_t) buf->b_blkno / blks, buf->b_udf_c_type,
			buf->b_resid, buf->b_bcount, buf->b_bufsize));
		VOP_STRATEGY(ump->devvp, buf);
		return;
	}

	if (queue == UDF_SHED_WRITING) {
		DPRINTF(SHEDULE, ("\nudf_issue_buf WRITE %p : sector %d "
			"type %d, b_resid %d, b_bcount %d, b_bufsize %d\n",
			buf, (uint32_t) buf->b_blkno / blks, buf->b_udf_c_type,
			buf->b_resid, buf->b_bcount, buf->b_bufsize));
		KASSERT(buf->b_udf_c_type == UDF_C_ABSOLUTE);

		// udf_fixup_node_internals(ump, buf->b_data, buf->b_udf_c_type);
		VOP_STRATEGY(ump->devvp, buf);
		return;
	}

	KASSERT(queue == UDF_SHED_SEQWRITING);
	DPRINTF(SHEDULE, ("\nudf_issue_buf SEQWRITE %p : sector XXXX "
		"type %d, b_resid %d, b_bcount %d, b_bufsize %d\n",
		buf, buf->b_udf_c_type, buf->b_resid, buf->b_bcount,
		buf->b_bufsize));

	/*
	 * Buffers should not have been allocated to disc addresses yet on
	 * this queue. Note that a buffer can get multiple extents allocated.
	 *
	 * lmapping contains lb_num relative to base partition.
	 */
	lmapping    = ump->la_lmapping;
	node_ad_cpy = ump->la_node_ad_cpy;

	/* logically allocate buf and map it in the file */
	udf_late_allocate_buf(ump, buf, lmapping, node_ad_cpy, &vpart_num);

	/*
	 * NOTE We are using the knowledge here that sequential media will
	 * always be mapped linearly. Thus no use to explicitly translate the
	 * lmapping list.
	 */

	/* calculate offset from physical base partition */
	pdesc = ump->partitions[ump->vtop[vpart_num]];
	ptov  = udf_rw32(pdesc->start_loc);

	/* set buffers blkno to the physical block number */
	buf->b_blkno = (*lmapping + ptov) * blks;

	/* fixate floating descriptors */
	if (buf->b_udf_c_type == UDF_C_FLOAT_DSCR) {
		/* set our tag location to the absolute position */
		dscr = (union dscrptr *) buf->b_data;
		dscr->tag.tag_loc = udf_rw32(*lmapping + ptov);
		udf_validate_tag_and_crc_sums(dscr);
	}

	/* update mapping in the VAT */
	if (buf->b_udf_c_type == UDF_C_NODE) {
		udf_VAT_mapping_update(ump, buf, *lmapping);
		udf_fixup_node_internals(ump, buf->b_data, buf->b_udf_c_type);
	}

	/* if we have FIDs, fixup using the new allocation table */
	if (buf->b_udf_c_type == UDF_C_FIDS) {
		buf_len = buf->b_bcount;
		bpos = 0;
		lmappos = lmapping;
		while (buf_len) {
			sectornr = *lmappos++;
			len = MIN(buf_len, sector_size);
			fidblk = (uint8_t *) buf->b_data + bpos;
			udf_fixup_fid_block(fidblk, sector_size,
				0, len, sectornr);
			bpos += len;
			buf_len -= len;
		}
	}

	VOP_STRATEGY(ump->devvp, buf);
}