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); }
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); }