udf_readwrite.c revision 1.1.2.3 1 1.1.2.3 yamt /* $NetBSD: udf_readwrite.c,v 1.1.2.3 2009/05/04 08:13:44 yamt Exp $ */
2 1.1.2.2 yamt
3 1.1.2.2 yamt /*
4 1.1.2.2 yamt * Copyright (c) 2007, 2008 Reinoud Zandijk
5 1.1.2.2 yamt * All rights reserved.
6 1.1.2.2 yamt *
7 1.1.2.2 yamt * Redistribution and use in source and binary forms, with or without
8 1.1.2.2 yamt * modification, are permitted provided that the following conditions
9 1.1.2.2 yamt * are met:
10 1.1.2.2 yamt * 1. Redistributions of source code must retain the above copyright
11 1.1.2.2 yamt * notice, this list of conditions and the following disclaimer.
12 1.1.2.2 yamt * 2. Redistributions in binary form must reproduce the above copyright
13 1.1.2.2 yamt * notice, this list of conditions and the following disclaimer in the
14 1.1.2.2 yamt * documentation and/or other materials provided with the distribution.
15 1.1.2.2 yamt *
16 1.1.2.2 yamt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 1.1.2.2 yamt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 1.1.2.2 yamt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 1.1.2.2 yamt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 1.1.2.2 yamt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 1.1.2.2 yamt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 1.1.2.2 yamt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 1.1.2.2 yamt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 1.1.2.2 yamt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 1.1.2.2 yamt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 1.1.2.2 yamt *
27 1.1.2.2 yamt */
28 1.1.2.2 yamt
29 1.1.2.2 yamt #include <sys/cdefs.h>
30 1.1.2.2 yamt #ifndef lint
31 1.1.2.3 yamt __KERNEL_RCSID(0, "$NetBSD: udf_readwrite.c,v 1.1.2.3 2009/05/04 08:13:44 yamt Exp $");
32 1.1.2.2 yamt #endif /* not lint */
33 1.1.2.2 yamt
34 1.1.2.2 yamt
35 1.1.2.2 yamt #if defined(_KERNEL_OPT)
36 1.1.2.2 yamt #include "opt_compat_netbsd.h"
37 1.1.2.2 yamt #endif
38 1.1.2.2 yamt
39 1.1.2.2 yamt #include <sys/param.h>
40 1.1.2.2 yamt #include <sys/systm.h>
41 1.1.2.2 yamt #include <sys/sysctl.h>
42 1.1.2.2 yamt #include <sys/namei.h>
43 1.1.2.2 yamt #include <sys/proc.h>
44 1.1.2.2 yamt #include <sys/kernel.h>
45 1.1.2.2 yamt #include <sys/vnode.h>
46 1.1.2.2 yamt #include <miscfs/genfs/genfs_node.h>
47 1.1.2.2 yamt #include <sys/mount.h>
48 1.1.2.2 yamt #include <sys/buf.h>
49 1.1.2.2 yamt #include <sys/file.h>
50 1.1.2.2 yamt #include <sys/device.h>
51 1.1.2.2 yamt #include <sys/disklabel.h>
52 1.1.2.2 yamt #include <sys/ioctl.h>
53 1.1.2.2 yamt #include <sys/malloc.h>
54 1.1.2.2 yamt #include <sys/dirent.h>
55 1.1.2.2 yamt #include <sys/stat.h>
56 1.1.2.2 yamt #include <sys/conf.h>
57 1.1.2.2 yamt #include <sys/kauth.h>
58 1.1.2.2 yamt #include <sys/kthread.h>
59 1.1.2.2 yamt #include <dev/clock_subr.h>
60 1.1.2.2 yamt
61 1.1.2.2 yamt #include <fs/udf/ecma167-udf.h>
62 1.1.2.2 yamt #include <fs/udf/udf_mount.h>
63 1.1.2.2 yamt
64 1.1.2.2 yamt #include "udf.h"
65 1.1.2.2 yamt #include "udf_subr.h"
66 1.1.2.2 yamt #include "udf_bswap.h"
67 1.1.2.2 yamt
68 1.1.2.2 yamt
69 1.1.2.2 yamt #define VTOI(vnode) ((struct udf_node *) vnode->v_data)
70 1.1.2.2 yamt
71 1.1.2.2 yamt /* --------------------------------------------------------------------- */
72 1.1.2.2 yamt
73 1.1.2.2 yamt void
74 1.1.2.2 yamt udf_fixup_fid_block(uint8_t *blob, int lb_size,
75 1.1.2.2 yamt int rfix_pos, int max_rfix_pos, uint32_t lb_num)
76 1.1.2.2 yamt {
77 1.1.2.2 yamt struct fileid_desc *fid;
78 1.1.2.2 yamt uint8_t *fid_pos;
79 1.1.2.2 yamt int fid_len, found;
80 1.1.2.2 yamt
81 1.1.2.2 yamt /* needs to be word aligned */
82 1.1.2.2 yamt KASSERT(rfix_pos % 4 == 0);
83 1.1.2.2 yamt
84 1.1.2.2 yamt /* first resync with the FID stream !!! */
85 1.1.2.2 yamt found = 0;
86 1.1.2.2 yamt while (rfix_pos + sizeof(struct desc_tag) <= max_rfix_pos) {
87 1.1.2.2 yamt fid_pos = blob + rfix_pos;
88 1.1.2.2 yamt fid = (struct fileid_desc *) fid_pos;
89 1.1.2.2 yamt if (udf_rw16(fid->tag.id) == TAGID_FID) {
90 1.1.2.2 yamt if (udf_check_tag((union dscrptr *) fid) == 0)
91 1.1.2.2 yamt found = 1;
92 1.1.2.2 yamt }
93 1.1.2.2 yamt if (found)
94 1.1.2.2 yamt break;
95 1.1.2.2 yamt /* try next location; can only be 4 bytes aligned */
96 1.1.2.2 yamt rfix_pos += 4;
97 1.1.2.2 yamt }
98 1.1.2.2 yamt
99 1.1.2.2 yamt /* walk over the fids */
100 1.1.2.2 yamt fid_pos = blob + rfix_pos;
101 1.1.2.2 yamt while (rfix_pos + sizeof(struct desc_tag) <= max_rfix_pos) {
102 1.1.2.2 yamt fid = (struct fileid_desc *) fid_pos;
103 1.1.2.2 yamt if (udf_rw16(fid->tag.id) != TAGID_FID) {
104 1.1.2.2 yamt /* end of FID stream; end of directory or currupted */
105 1.1.2.2 yamt break;
106 1.1.2.2 yamt }
107 1.1.2.2 yamt
108 1.1.2.2 yamt /* update sector number and recalculate checkum */
109 1.1.2.2 yamt fid->tag.tag_loc = udf_rw32(lb_num);
110 1.1.2.2 yamt udf_validate_tag_sum((union dscrptr *) fid);
111 1.1.2.2 yamt
112 1.1.2.2 yamt /* if the FID crosses the memory, we're done! */
113 1.1.2.2 yamt if (rfix_pos + UDF_FID_SIZE >= max_rfix_pos)
114 1.1.2.2 yamt break;
115 1.1.2.2 yamt
116 1.1.2.2 yamt fid_len = udf_fidsize(fid);
117 1.1.2.2 yamt fid_pos += fid_len;
118 1.1.2.2 yamt rfix_pos += fid_len;
119 1.1.2.2 yamt }
120 1.1.2.2 yamt }
121 1.1.2.2 yamt
122 1.1.2.2 yamt
123 1.1.2.2 yamt void
124 1.1.2.2 yamt udf_fixup_internal_extattr(uint8_t *blob, uint32_t lb_num)
125 1.1.2.2 yamt {
126 1.1.2.2 yamt struct desc_tag *tag;
127 1.1.2.2 yamt struct file_entry *fe;
128 1.1.2.2 yamt struct extfile_entry *efe;
129 1.1.2.2 yamt struct extattrhdr_desc *eahdr;
130 1.1.2.3 yamt int l_ea;
131 1.1.2.2 yamt
132 1.1.2.2 yamt /* get information from fe/efe */
133 1.1.2.2 yamt tag = (struct desc_tag *) blob;
134 1.1.2.2 yamt switch (udf_rw16(tag->id)) {
135 1.1.2.2 yamt case TAGID_FENTRY :
136 1.1.2.2 yamt fe = (struct file_entry *) blob;
137 1.1.2.2 yamt l_ea = udf_rw32(fe->l_ea);
138 1.1.2.2 yamt eahdr = (struct extattrhdr_desc *) fe->data;
139 1.1.2.2 yamt break;
140 1.1.2.2 yamt case TAGID_EXTFENTRY :
141 1.1.2.2 yamt efe = (struct extfile_entry *) blob;
142 1.1.2.2 yamt l_ea = udf_rw32(efe->l_ea);
143 1.1.2.2 yamt eahdr = (struct extattrhdr_desc *) efe->data;
144 1.1.2.2 yamt break;
145 1.1.2.2 yamt case TAGID_INDIRECTENTRY :
146 1.1.2.2 yamt case TAGID_ALLOCEXTENT :
147 1.1.2.2 yamt case TAGID_EXTATTR_HDR :
148 1.1.2.2 yamt return;
149 1.1.2.2 yamt default:
150 1.1.2.3 yamt panic("%s: passed bad tag\n", __func__);
151 1.1.2.2 yamt }
152 1.1.2.2 yamt
153 1.1.2.2 yamt /* something recorded here? (why am i called?) */
154 1.1.2.2 yamt if (l_ea == 0)
155 1.1.2.2 yamt return;
156 1.1.2.2 yamt
157 1.1.2.3 yamt #if 0
158 1.1.2.2 yamt /* check extended attribute tag */
159 1.1.2.2 yamt /* TODO XXX what to do when we encounter an error here? */
160 1.1.2.2 yamt error = udf_check_tag(eahdr);
161 1.1.2.2 yamt if (error)
162 1.1.2.2 yamt return; /* for now */
163 1.1.2.2 yamt if (udf_rw16(eahdr->tag.id) != TAGID_EXTATTR_HDR)
164 1.1.2.2 yamt return; /* for now */
165 1.1.2.2 yamt error = udf_check_tag_payload(eahdr, sizeof(struct extattrhdr_desc));
166 1.1.2.2 yamt if (error)
167 1.1.2.2 yamt return; /* for now */
168 1.1.2.3 yamt #endif
169 1.1.2.2 yamt
170 1.1.2.2 yamt DPRINTF(EXTATTR, ("node fixup: found %d bytes of extended attributes\n",
171 1.1.2.2 yamt l_ea));
172 1.1.2.2 yamt
173 1.1.2.2 yamt /* fixup eahdr tag */
174 1.1.2.2 yamt eahdr->tag.tag_loc = udf_rw32(lb_num);
175 1.1.2.3 yamt udf_validate_tag_and_crc_sums((union dscrptr *) eahdr);
176 1.1.2.2 yamt }
177 1.1.2.2 yamt
178 1.1.2.2 yamt
179 1.1.2.2 yamt void
180 1.1.2.2 yamt udf_fixup_node_internals(struct udf_mount *ump, uint8_t *blob, int udf_c_type)
181 1.1.2.2 yamt {
182 1.1.2.3 yamt struct desc_tag *tag, *sbm_tag;
183 1.1.2.2 yamt struct file_entry *fe;
184 1.1.2.2 yamt struct extfile_entry *efe;
185 1.1.2.3 yamt struct alloc_ext_entry *ext;
186 1.1.2.2 yamt uint32_t lb_size, lb_num;
187 1.1.2.3 yamt uint32_t intern_pos, max_intern_pos;
188 1.1.2.3 yamt int icbflags, addr_type, file_type, intern, has_fids, has_sbm, l_ea;
189 1.1.2.2 yamt
190 1.1.2.2 yamt lb_size = udf_rw32(ump->logical_vol->lb_size);
191 1.1.2.2 yamt /* if its not a node we're done */
192 1.1.2.2 yamt if (udf_c_type != UDF_C_NODE)
193 1.1.2.2 yamt return;
194 1.1.2.2 yamt
195 1.1.2.2 yamt /* NOTE this could also be done in write_internal */
196 1.1.2.2 yamt /* start of a descriptor */
197 1.1.2.3 yamt l_ea = 0;
198 1.1.2.3 yamt has_fids = 0;
199 1.1.2.3 yamt has_sbm = 0;
200 1.1.2.3 yamt intern = 0;
201 1.1.2.3 yamt file_type = 0;
202 1.1.2.3 yamt max_intern_pos = intern_pos = lb_num = 0; /* shut up gcc! */
203 1.1.2.2 yamt
204 1.1.2.2 yamt tag = (struct desc_tag *) blob;
205 1.1.2.2 yamt switch (udf_rw16(tag->id)) {
206 1.1.2.2 yamt case TAGID_FENTRY :
207 1.1.2.2 yamt fe = (struct file_entry *) tag;
208 1.1.2.2 yamt l_ea = udf_rw32(fe->l_ea);
209 1.1.2.2 yamt icbflags = udf_rw16(fe->icbtag.flags);
210 1.1.2.2 yamt addr_type = (icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK);
211 1.1.2.3 yamt file_type = fe->icbtag.file_type;
212 1.1.2.3 yamt intern = (addr_type == UDF_ICB_INTERN_ALLOC);
213 1.1.2.3 yamt intern_pos = UDF_FENTRY_SIZE + l_ea;
214 1.1.2.3 yamt max_intern_pos = intern_pos + udf_rw64(fe->inf_len);
215 1.1.2.2 yamt lb_num = udf_rw32(fe->tag.tag_loc);
216 1.1.2.2 yamt break;
217 1.1.2.2 yamt case TAGID_EXTFENTRY :
218 1.1.2.2 yamt efe = (struct extfile_entry *) tag;
219 1.1.2.2 yamt l_ea = udf_rw32(efe->l_ea);
220 1.1.2.2 yamt icbflags = udf_rw16(efe->icbtag.flags);
221 1.1.2.2 yamt addr_type = (icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK);
222 1.1.2.3 yamt file_type = efe->icbtag.file_type;
223 1.1.2.3 yamt intern = (addr_type == UDF_ICB_INTERN_ALLOC);
224 1.1.2.3 yamt intern_pos = UDF_EXTFENTRY_SIZE + l_ea;
225 1.1.2.3 yamt max_intern_pos = intern_pos + udf_rw64(efe->inf_len);
226 1.1.2.2 yamt lb_num = udf_rw32(efe->tag.tag_loc);
227 1.1.2.2 yamt break;
228 1.1.2.2 yamt case TAGID_INDIRECTENTRY :
229 1.1.2.2 yamt case TAGID_EXTATTR_HDR :
230 1.1.2.3 yamt break;
231 1.1.2.3 yamt case TAGID_ALLOCEXTENT :
232 1.1.2.3 yamt /* force crclen to 8 for UDF version < 2.01 */
233 1.1.2.3 yamt ext = (struct alloc_ext_entry *) tag;
234 1.1.2.3 yamt if (udf_rw16(ump->logvol_info->min_udf_readver) <= 0x200)
235 1.1.2.3 yamt ext->tag.desc_crc_len = udf_rw16(8);
236 1.1.2.2 yamt break;
237 1.1.2.2 yamt default:
238 1.1.2.3 yamt panic("%s: passed bad tag\n", __func__);
239 1.1.2.2 yamt break;
240 1.1.2.2 yamt }
241 1.1.2.2 yamt
242 1.1.2.3 yamt /* determine what to fix if its internally recorded */
243 1.1.2.3 yamt if (intern) {
244 1.1.2.3 yamt has_fids = (file_type == UDF_ICB_FILETYPE_DIRECTORY) ||
245 1.1.2.3 yamt (file_type == UDF_ICB_FILETYPE_STREAMDIR);
246 1.1.2.3 yamt has_sbm = (file_type == UDF_ICB_FILETYPE_META_BITMAP);
247 1.1.2.3 yamt }
248 1.1.2.3 yamt
249 1.1.2.2 yamt /* fixup internal extended attributes if present */
250 1.1.2.2 yamt if (l_ea)
251 1.1.2.2 yamt udf_fixup_internal_extattr(blob, lb_num);
252 1.1.2.2 yamt
253 1.1.2.3 yamt /* fixup fids lb numbers */
254 1.1.2.3 yamt if (has_fids)
255 1.1.2.3 yamt udf_fixup_fid_block(blob, lb_size, intern_pos,
256 1.1.2.3 yamt max_intern_pos, lb_num);
257 1.1.2.3 yamt
258 1.1.2.3 yamt /* fixup space bitmap descriptor */
259 1.1.2.3 yamt if (has_sbm) {
260 1.1.2.3 yamt sbm_tag = (struct desc_tag *) (blob + intern_pos);
261 1.1.2.3 yamt sbm_tag->tag_loc = tag->tag_loc;
262 1.1.2.3 yamt udf_validate_tag_and_crc_sums((uint8_t *) sbm_tag);
263 1.1.2.2 yamt }
264 1.1.2.3 yamt
265 1.1.2.2 yamt udf_validate_tag_and_crc_sums(blob);
266 1.1.2.2 yamt }
267 1.1.2.2 yamt
268 1.1.2.2 yamt /* --------------------------------------------------------------------- */
269 1.1.2.2 yamt
270 1.1.2.2 yamt /*
271 1.1.2.2 yamt * Set of generic descriptor readers and writers and their helper functions.
272 1.1.2.2 yamt * Descriptors inside `logical space' i.e. inside logically mapped partitions
273 1.1.2.2 yamt * can never be longer than one logical sector.
274 1.1.2.2 yamt *
275 1.1.2.2 yamt * NOTE that these functions *can* be used by the sheduler backends to read
276 1.1.2.2 yamt * node descriptors too.
277 1.1.2.2 yamt *
278 1.1.2.2 yamt * For reading, the size of allocated piece is returned in multiple of sector
279 1.1.2.2 yamt * size due to udf_calc_udf_malloc_size().
280 1.1.2.2 yamt */
281 1.1.2.2 yamt
282 1.1.2.2 yamt
283 1.1.2.2 yamt /* SYNC reading of n blocks from specified sector */
284 1.1.2.3 yamt int
285 1.1.2.2 yamt udf_read_phys_sectors(struct udf_mount *ump, int what, void *blob,
286 1.1.2.2 yamt uint32_t start, uint32_t sectors)
287 1.1.2.2 yamt {
288 1.1.2.2 yamt struct buf *buf, *nestbuf;
289 1.1.2.2 yamt uint32_t buf_offset;
290 1.1.2.2 yamt off_t lblkno, rblkno;
291 1.1.2.2 yamt int sector_size = ump->discinfo.sector_size;
292 1.1.2.2 yamt int blks = sector_size / DEV_BSIZE;
293 1.1.2.2 yamt int piece;
294 1.1.2.2 yamt int error;
295 1.1.2.2 yamt
296 1.1.2.2 yamt DPRINTF(READ, ("udf_intbreadn() : sectors = %d, sector_size = %d\n",
297 1.1.2.2 yamt sectors, sector_size));
298 1.1.2.2 yamt buf = getiobuf(ump->devvp, true);
299 1.1.2.2 yamt buf->b_flags = B_READ;
300 1.1.2.2 yamt buf->b_cflags = BC_BUSY; /* needed? */
301 1.1.2.2 yamt buf->b_iodone = NULL;
302 1.1.2.2 yamt buf->b_data = blob;
303 1.1.2.2 yamt buf->b_bcount = sectors * sector_size;
304 1.1.2.2 yamt buf->b_resid = buf->b_bcount;
305 1.1.2.2 yamt buf->b_bufsize = buf->b_bcount;
306 1.1.2.2 yamt buf->b_private = NULL; /* not needed yet */
307 1.1.2.2 yamt BIO_SETPRIO(buf, BPRIO_DEFAULT);
308 1.1.2.2 yamt buf->b_lblkno = buf->b_blkno = buf->b_rawblkno = start * blks;
309 1.1.2.2 yamt buf->b_proc = NULL;
310 1.1.2.2 yamt
311 1.1.2.2 yamt error = 0;
312 1.1.2.2 yamt buf_offset = 0;
313 1.1.2.2 yamt rblkno = start;
314 1.1.2.2 yamt lblkno = 0;
315 1.1.2.2 yamt while ((sectors > 0) && (error == 0)) {
316 1.1.2.2 yamt piece = MIN(MAXPHYS/sector_size, sectors);
317 1.1.2.2 yamt DPRINTF(READ, ("read in %d + %d\n", (uint32_t) rblkno, piece));
318 1.1.2.2 yamt
319 1.1.2.2 yamt nestbuf = getiobuf(NULL, true);
320 1.1.2.2 yamt nestiobuf_setup(buf, nestbuf, buf_offset, piece * sector_size);
321 1.1.2.2 yamt /* nestbuf is B_ASYNC */
322 1.1.2.2 yamt
323 1.1.2.2 yamt /* identify this nestbuf */
324 1.1.2.2 yamt nestbuf->b_lblkno = lblkno;
325 1.1.2.2 yamt
326 1.1.2.2 yamt /* CD shedules on raw blkno */
327 1.1.2.2 yamt nestbuf->b_blkno = rblkno * blks;
328 1.1.2.2 yamt nestbuf->b_proc = NULL;
329 1.1.2.2 yamt nestbuf->b_rawblkno = rblkno * blks;
330 1.1.2.2 yamt nestbuf->b_udf_c_type = what;
331 1.1.2.2 yamt
332 1.1.2.2 yamt udf_discstrat_queuebuf(ump, nestbuf);
333 1.1.2.2 yamt
334 1.1.2.2 yamt lblkno += piece;
335 1.1.2.2 yamt rblkno += piece;
336 1.1.2.2 yamt buf_offset += piece * sector_size;
337 1.1.2.2 yamt sectors -= piece;
338 1.1.2.2 yamt }
339 1.1.2.2 yamt error = biowait(buf);
340 1.1.2.2 yamt putiobuf(buf);
341 1.1.2.2 yamt
342 1.1.2.2 yamt return error;
343 1.1.2.2 yamt }
344 1.1.2.2 yamt
345 1.1.2.2 yamt
346 1.1.2.2 yamt /* synchronous generic descriptor read */
347 1.1.2.2 yamt int
348 1.1.2.2 yamt udf_read_phys_dscr(struct udf_mount *ump, uint32_t sector,
349 1.1.2.2 yamt struct malloc_type *mtype, union dscrptr **dstp)
350 1.1.2.2 yamt {
351 1.1.2.2 yamt union dscrptr *dst, *new_dst;
352 1.1.2.2 yamt uint8_t *pos;
353 1.1.2.2 yamt int sectors, dscrlen;
354 1.1.2.2 yamt int i, error, sector_size;
355 1.1.2.2 yamt
356 1.1.2.2 yamt sector_size = ump->discinfo.sector_size;
357 1.1.2.2 yamt
358 1.1.2.2 yamt *dstp = dst = NULL;
359 1.1.2.2 yamt dscrlen = sector_size;
360 1.1.2.2 yamt
361 1.1.2.2 yamt /* read initial piece */
362 1.1.2.2 yamt dst = malloc(sector_size, mtype, M_WAITOK);
363 1.1.2.2 yamt error = udf_read_phys_sectors(ump, UDF_C_DSCR, dst, sector, 1);
364 1.1.2.2 yamt DPRINTFIF(DESCRIPTOR, error, ("read error (%d)\n", error));
365 1.1.2.2 yamt
366 1.1.2.2 yamt if (!error) {
367 1.1.2.2 yamt /* check if its a valid tag */
368 1.1.2.2 yamt error = udf_check_tag(dst);
369 1.1.2.2 yamt if (error) {
370 1.1.2.2 yamt /* check if its an empty block */
371 1.1.2.2 yamt pos = (uint8_t *) dst;
372 1.1.2.2 yamt for (i = 0; i < sector_size; i++, pos++) {
373 1.1.2.2 yamt if (*pos) break;
374 1.1.2.2 yamt }
375 1.1.2.2 yamt if (i == sector_size) {
376 1.1.2.2 yamt /* return no error but with no dscrptr */
377 1.1.2.2 yamt /* dispose first block */
378 1.1.2.2 yamt free(dst, mtype);
379 1.1.2.2 yamt return 0;
380 1.1.2.2 yamt }
381 1.1.2.2 yamt }
382 1.1.2.2 yamt /* calculate descriptor size */
383 1.1.2.2 yamt dscrlen = udf_tagsize(dst, sector_size);
384 1.1.2.2 yamt }
385 1.1.2.2 yamt DPRINTFIF(DESCRIPTOR, error, ("bad tag checksum\n"));
386 1.1.2.2 yamt
387 1.1.2.2 yamt if (!error && (dscrlen > sector_size)) {
388 1.1.2.2 yamt DPRINTF(DESCRIPTOR, ("multi block descriptor read\n"));
389 1.1.2.2 yamt /*
390 1.1.2.2 yamt * Read the rest of descriptor. Since it is only used at mount
391 1.1.2.2 yamt * time its overdone to define and use a specific udf_intbreadn
392 1.1.2.2 yamt * for this alone.
393 1.1.2.2 yamt */
394 1.1.2.2 yamt
395 1.1.2.2 yamt new_dst = realloc(dst, dscrlen, mtype, M_WAITOK);
396 1.1.2.2 yamt if (new_dst == NULL) {
397 1.1.2.2 yamt free(dst, mtype);
398 1.1.2.2 yamt return ENOMEM;
399 1.1.2.2 yamt }
400 1.1.2.2 yamt dst = new_dst;
401 1.1.2.2 yamt
402 1.1.2.2 yamt sectors = (dscrlen + sector_size -1) / sector_size;
403 1.1.2.2 yamt DPRINTF(DESCRIPTOR, ("dscrlen = %d (%d blk)\n", dscrlen, sectors));
404 1.1.2.2 yamt
405 1.1.2.2 yamt pos = (uint8_t *) dst + sector_size;
406 1.1.2.2 yamt error = udf_read_phys_sectors(ump, UDF_C_DSCR, pos,
407 1.1.2.2 yamt sector + 1, sectors-1);
408 1.1.2.2 yamt
409 1.1.2.2 yamt DPRINTFIF(DESCRIPTOR, error, ("read error on multi (%d)\n",
410 1.1.2.2 yamt error));
411 1.1.2.2 yamt }
412 1.1.2.2 yamt if (!error) {
413 1.1.2.2 yamt error = udf_check_tag_payload(dst, dscrlen);
414 1.1.2.2 yamt DPRINTFIF(DESCRIPTOR, error, ("bad payload check sum\n"));
415 1.1.2.2 yamt }
416 1.1.2.2 yamt if (error && dst) {
417 1.1.2.2 yamt free(dst, mtype);
418 1.1.2.2 yamt dst = NULL;
419 1.1.2.2 yamt }
420 1.1.2.2 yamt *dstp = dst;
421 1.1.2.2 yamt
422 1.1.2.2 yamt return error;
423 1.1.2.2 yamt }
424 1.1.2.2 yamt
425 1.1.2.2 yamt
426 1.1.2.2 yamt static void
427 1.1.2.2 yamt udf_write_phys_buf(struct udf_mount *ump, int what, struct buf *buf)
428 1.1.2.2 yamt {
429 1.1.2.2 yamt struct buf *nestbuf;
430 1.1.2.2 yamt uint32_t buf_offset;
431 1.1.2.2 yamt off_t lblkno, rblkno;
432 1.1.2.2 yamt int sector_size = ump->discinfo.sector_size;
433 1.1.2.2 yamt int blks = sector_size / DEV_BSIZE;
434 1.1.2.2 yamt uint32_t sectors;
435 1.1.2.2 yamt int piece;
436 1.1.2.2 yamt int error;
437 1.1.2.2 yamt
438 1.1.2.2 yamt sectors = buf->b_bcount / sector_size;
439 1.1.2.2 yamt DPRINTF(WRITE, ("udf_intbwriten() : sectors = %d, sector_size = %d\n",
440 1.1.2.2 yamt sectors, sector_size));
441 1.1.2.2 yamt
442 1.1.2.2 yamt /* don't forget to increase pending count for the bwrite itself */
443 1.1.2.2 yamt /* panic("NO WRITING\n"); */
444 1.1.2.2 yamt if (buf->b_vp) {
445 1.1.2.2 yamt mutex_enter(&buf->b_vp->v_interlock);
446 1.1.2.2 yamt buf->b_vp->v_numoutput++;
447 1.1.2.2 yamt mutex_exit(&buf->b_vp->v_interlock);
448 1.1.2.2 yamt }
449 1.1.2.2 yamt
450 1.1.2.2 yamt error = 0;
451 1.1.2.2 yamt buf_offset = 0;
452 1.1.2.2 yamt rblkno = buf->b_blkno / blks;
453 1.1.2.2 yamt lblkno = 0;
454 1.1.2.2 yamt while ((sectors > 0) && (error == 0)) {
455 1.1.2.2 yamt piece = MIN(MAXPHYS/sector_size, sectors);
456 1.1.2.2 yamt DPRINTF(WRITE, ("write out %d + %d\n",
457 1.1.2.2 yamt (uint32_t) rblkno, piece));
458 1.1.2.2 yamt
459 1.1.2.2 yamt nestbuf = getiobuf(NULL, true);
460 1.1.2.2 yamt nestiobuf_setup(buf, nestbuf, buf_offset, piece * sector_size);
461 1.1.2.2 yamt /* nestbuf is B_ASYNC */
462 1.1.2.2 yamt
463 1.1.2.2 yamt /* identify this nestbuf */
464 1.1.2.2 yamt nestbuf->b_lblkno = lblkno;
465 1.1.2.2 yamt
466 1.1.2.2 yamt /* CD shedules on raw blkno */
467 1.1.2.2 yamt nestbuf->b_blkno = rblkno * blks;
468 1.1.2.2 yamt nestbuf->b_proc = NULL;
469 1.1.2.2 yamt nestbuf->b_rawblkno = rblkno * blks;
470 1.1.2.2 yamt nestbuf->b_udf_c_type = what;
471 1.1.2.2 yamt
472 1.1.2.2 yamt udf_discstrat_queuebuf(ump, nestbuf);
473 1.1.2.2 yamt
474 1.1.2.2 yamt lblkno += piece;
475 1.1.2.2 yamt rblkno += piece;
476 1.1.2.2 yamt buf_offset += piece * sector_size;
477 1.1.2.2 yamt sectors -= piece;
478 1.1.2.2 yamt }
479 1.1.2.2 yamt }
480 1.1.2.2 yamt
481 1.1.2.2 yamt
482 1.1.2.3 yamt /* SYNC writing of n blocks from specified sector */
483 1.1.2.3 yamt int
484 1.1.2.3 yamt udf_write_phys_sectors(struct udf_mount *ump, int what, void *blob,
485 1.1.2.3 yamt uint32_t start, uint32_t sectors)
486 1.1.2.3 yamt {
487 1.1.2.3 yamt struct vnode *vp;
488 1.1.2.3 yamt struct buf *buf;
489 1.1.2.3 yamt int sector_size = ump->discinfo.sector_size;
490 1.1.2.3 yamt int blks = sector_size / DEV_BSIZE;
491 1.1.2.3 yamt int error;
492 1.1.2.3 yamt
493 1.1.2.3 yamt /* get transfer buffer */
494 1.1.2.3 yamt vp = ump->devvp;
495 1.1.2.3 yamt buf = getiobuf(vp, true);
496 1.1.2.3 yamt buf->b_flags = B_WRITE;
497 1.1.2.3 yamt buf->b_cflags = BC_BUSY; /* needed? */
498 1.1.2.3 yamt buf->b_iodone = NULL;
499 1.1.2.3 yamt buf->b_data = blob;
500 1.1.2.3 yamt buf->b_bcount = sectors * sector_size;
501 1.1.2.3 yamt buf->b_resid = buf->b_bcount;
502 1.1.2.3 yamt buf->b_bufsize = buf->b_bcount;
503 1.1.2.3 yamt buf->b_private = NULL; /* not needed yet */
504 1.1.2.3 yamt BIO_SETPRIO(buf, BPRIO_DEFAULT);
505 1.1.2.3 yamt buf->b_lblkno = buf->b_blkno = buf->b_rawblkno = start * blks;
506 1.1.2.3 yamt buf->b_proc = NULL;
507 1.1.2.3 yamt
508 1.1.2.3 yamt /* do the write, wait and return error */
509 1.1.2.3 yamt udf_write_phys_buf(ump, what, buf);
510 1.1.2.3 yamt error = biowait(buf);
511 1.1.2.3 yamt putiobuf(buf);
512 1.1.2.3 yamt
513 1.1.2.3 yamt return error;
514 1.1.2.3 yamt }
515 1.1.2.3 yamt
516 1.1.2.3 yamt
517 1.1.2.2 yamt /* synchronous generic descriptor write */
518 1.1.2.2 yamt int
519 1.1.2.2 yamt udf_write_phys_dscr_sync(struct udf_mount *ump, struct udf_node *udf_node, int what,
520 1.1.2.2 yamt union dscrptr *dscr, uint32_t sector, uint32_t logsector)
521 1.1.2.2 yamt {
522 1.1.2.2 yamt struct vnode *vp;
523 1.1.2.2 yamt struct buf *buf;
524 1.1.2.2 yamt int sector_size = ump->discinfo.sector_size;
525 1.1.2.2 yamt int blks = sector_size / DEV_BSIZE;
526 1.1.2.2 yamt int dscrlen;
527 1.1.2.2 yamt int error;
528 1.1.2.2 yamt
529 1.1.2.2 yamt /* set sector number in the descriptor and validate */
530 1.1.2.2 yamt dscr->tag.tag_loc = udf_rw32(logsector);
531 1.1.2.2 yamt udf_validate_tag_and_crc_sums(dscr);
532 1.1.2.2 yamt
533 1.1.2.2 yamt /* calculate descriptor size */
534 1.1.2.2 yamt dscrlen = udf_tagsize(dscr, sector_size);
535 1.1.2.2 yamt
536 1.1.2.2 yamt /* get transfer buffer */
537 1.1.2.2 yamt vp = udf_node ? udf_node->vnode : ump->devvp;
538 1.1.2.2 yamt buf = getiobuf(vp, true);
539 1.1.2.2 yamt buf->b_flags = B_WRITE;
540 1.1.2.2 yamt buf->b_cflags = BC_BUSY; /* needed? */
541 1.1.2.2 yamt buf->b_iodone = NULL;
542 1.1.2.2 yamt buf->b_data = (void *) dscr;
543 1.1.2.2 yamt buf->b_bcount = dscrlen;
544 1.1.2.2 yamt buf->b_resid = buf->b_bcount;
545 1.1.2.2 yamt buf->b_bufsize = buf->b_bcount;
546 1.1.2.2 yamt buf->b_private = NULL; /* not needed yet */
547 1.1.2.2 yamt BIO_SETPRIO(buf, BPRIO_DEFAULT);
548 1.1.2.2 yamt buf->b_lblkno = buf->b_blkno = buf->b_rawblkno = sector * blks;
549 1.1.2.2 yamt buf->b_proc = NULL;
550 1.1.2.2 yamt
551 1.1.2.2 yamt /* do the write, wait and return error */
552 1.1.2.2 yamt udf_write_phys_buf(ump, what, buf);
553 1.1.2.2 yamt error = biowait(buf);
554 1.1.2.2 yamt putiobuf(buf);
555 1.1.2.2 yamt
556 1.1.2.2 yamt return error;
557 1.1.2.2 yamt }
558 1.1.2.2 yamt
559 1.1.2.2 yamt
560 1.1.2.2 yamt /* asynchronous generic descriptor write */
561 1.1.2.2 yamt int
562 1.1.2.2 yamt udf_write_phys_dscr_async(struct udf_mount *ump, struct udf_node *udf_node,
563 1.1.2.2 yamt int what, union dscrptr *dscr,
564 1.1.2.2 yamt uint32_t sector, uint32_t logsector,
565 1.1.2.2 yamt void (*dscrwr_callback)(struct buf *))
566 1.1.2.2 yamt {
567 1.1.2.2 yamt struct vnode *vp;
568 1.1.2.2 yamt struct buf *buf;
569 1.1.2.2 yamt int dscrlen;
570 1.1.2.2 yamt int sector_size = ump->discinfo.sector_size;
571 1.1.2.2 yamt int blks = sector_size / DEV_BSIZE;
572 1.1.2.2 yamt
573 1.1.2.2 yamt KASSERT(dscrwr_callback);
574 1.1.2.2 yamt DPRINTF(NODE, ("udf_write_phys_dscr_async() called\n"));
575 1.1.2.2 yamt
576 1.1.2.2 yamt /* set sector number in the descriptor and validate */
577 1.1.2.2 yamt dscr->tag.tag_loc = udf_rw32(logsector);
578 1.1.2.2 yamt udf_validate_tag_and_crc_sums(dscr);
579 1.1.2.2 yamt
580 1.1.2.2 yamt /* calculate descriptor size */
581 1.1.2.2 yamt dscrlen = udf_tagsize(dscr, sector_size);
582 1.1.2.2 yamt
583 1.1.2.2 yamt /* get transfer buffer */
584 1.1.2.2 yamt vp = udf_node ? udf_node->vnode : ump->devvp;
585 1.1.2.2 yamt buf = getiobuf(vp, true);
586 1.1.2.2 yamt buf->b_flags = B_WRITE; // | B_ASYNC;
587 1.1.2.2 yamt buf->b_cflags = BC_BUSY;
588 1.1.2.2 yamt buf->b_iodone = dscrwr_callback;
589 1.1.2.2 yamt buf->b_data = dscr;
590 1.1.2.2 yamt buf->b_bcount = dscrlen;
591 1.1.2.2 yamt buf->b_resid = buf->b_bcount;
592 1.1.2.2 yamt buf->b_bufsize = buf->b_bcount;
593 1.1.2.2 yamt buf->b_private = NULL; /* not needed yet */
594 1.1.2.2 yamt BIO_SETPRIO(buf, BPRIO_DEFAULT);
595 1.1.2.2 yamt buf->b_lblkno = buf->b_blkno = buf->b_rawblkno = sector * blks;
596 1.1.2.2 yamt buf->b_proc = NULL;
597 1.1.2.2 yamt
598 1.1.2.2 yamt /* do the write and return no error */
599 1.1.2.2 yamt udf_write_phys_buf(ump, what, buf);
600 1.1.2.2 yamt return 0;
601 1.1.2.2 yamt }
602 1.1.2.2 yamt
603 1.1.2.2 yamt /* --------------------------------------------------------------------- */
604 1.1.2.2 yamt
605 1.1.2.2 yamt /* disc strategy dispatchers */
606 1.1.2.2 yamt
607 1.1.2.2 yamt int
608 1.1.2.2 yamt udf_create_logvol_dscr(struct udf_mount *ump, struct udf_node *udf_node, struct long_ad *icb,
609 1.1.2.2 yamt union dscrptr **dscrptr)
610 1.1.2.2 yamt {
611 1.1.2.2 yamt struct udf_strategy *strategy = ump->strategy;
612 1.1.2.2 yamt struct udf_strat_args args;
613 1.1.2.2 yamt int error;
614 1.1.2.2 yamt
615 1.1.2.3 yamt KASSERT(strategy);
616 1.1.2.2 yamt args.ump = ump;
617 1.1.2.2 yamt args.udf_node = udf_node;
618 1.1.2.2 yamt args.icb = icb;
619 1.1.2.2 yamt args.dscr = NULL;
620 1.1.2.2 yamt
621 1.1.2.2 yamt error = (strategy->create_logvol_dscr)(&args);
622 1.1.2.2 yamt *dscrptr = args.dscr;
623 1.1.2.2 yamt
624 1.1.2.2 yamt return error;
625 1.1.2.2 yamt }
626 1.1.2.2 yamt
627 1.1.2.2 yamt
628 1.1.2.2 yamt void
629 1.1.2.2 yamt udf_free_logvol_dscr(struct udf_mount *ump, struct long_ad *icb,
630 1.1.2.2 yamt void *dscr)
631 1.1.2.2 yamt {
632 1.1.2.2 yamt struct udf_strategy *strategy = ump->strategy;
633 1.1.2.2 yamt struct udf_strat_args args;
634 1.1.2.2 yamt
635 1.1.2.3 yamt KASSERT(strategy);
636 1.1.2.2 yamt args.ump = ump;
637 1.1.2.2 yamt args.icb = icb;
638 1.1.2.2 yamt args.dscr = dscr;
639 1.1.2.2 yamt
640 1.1.2.2 yamt (strategy->free_logvol_dscr)(&args);
641 1.1.2.2 yamt }
642 1.1.2.2 yamt
643 1.1.2.2 yamt
644 1.1.2.2 yamt int
645 1.1.2.2 yamt udf_read_logvol_dscr(struct udf_mount *ump, struct long_ad *icb,
646 1.1.2.2 yamt union dscrptr **dscrptr)
647 1.1.2.2 yamt {
648 1.1.2.2 yamt struct udf_strategy *strategy = ump->strategy;
649 1.1.2.2 yamt struct udf_strat_args args;
650 1.1.2.2 yamt int error;
651 1.1.2.2 yamt
652 1.1.2.3 yamt KASSERT(strategy);
653 1.1.2.2 yamt args.ump = ump;
654 1.1.2.2 yamt args.icb = icb;
655 1.1.2.2 yamt args.dscr = NULL;
656 1.1.2.2 yamt
657 1.1.2.2 yamt error = (strategy->read_logvol_dscr)(&args);
658 1.1.2.2 yamt *dscrptr = args.dscr;
659 1.1.2.2 yamt
660 1.1.2.2 yamt return error;
661 1.1.2.2 yamt }
662 1.1.2.2 yamt
663 1.1.2.2 yamt
664 1.1.2.2 yamt int
665 1.1.2.2 yamt udf_write_logvol_dscr(struct udf_node *udf_node, union dscrptr *dscr,
666 1.1.2.2 yamt struct long_ad *icb, int waitfor)
667 1.1.2.2 yamt {
668 1.1.2.2 yamt struct udf_strategy *strategy = udf_node->ump->strategy;
669 1.1.2.2 yamt struct udf_strat_args args;
670 1.1.2.2 yamt int error;
671 1.1.2.2 yamt
672 1.1.2.3 yamt KASSERT(strategy);
673 1.1.2.2 yamt args.ump = udf_node->ump;
674 1.1.2.2 yamt args.udf_node = udf_node;
675 1.1.2.2 yamt args.icb = icb;
676 1.1.2.2 yamt args.dscr = dscr;
677 1.1.2.2 yamt args.waitfor = waitfor;
678 1.1.2.2 yamt
679 1.1.2.2 yamt error = (strategy->write_logvol_dscr)(&args);
680 1.1.2.2 yamt return error;
681 1.1.2.2 yamt }
682 1.1.2.2 yamt
683 1.1.2.2 yamt
684 1.1.2.2 yamt void
685 1.1.2.2 yamt udf_discstrat_queuebuf(struct udf_mount *ump, struct buf *nestbuf)
686 1.1.2.2 yamt {
687 1.1.2.2 yamt struct udf_strategy *strategy = ump->strategy;
688 1.1.2.2 yamt struct udf_strat_args args;
689 1.1.2.2 yamt
690 1.1.2.3 yamt KASSERT(strategy);
691 1.1.2.2 yamt args.ump = ump;
692 1.1.2.2 yamt args.nestbuf = nestbuf;
693 1.1.2.2 yamt
694 1.1.2.2 yamt (strategy->queuebuf)(&args);
695 1.1.2.2 yamt }
696 1.1.2.2 yamt
697 1.1.2.2 yamt
698 1.1.2.2 yamt void
699 1.1.2.2 yamt udf_discstrat_init(struct udf_mount *ump)
700 1.1.2.2 yamt {
701 1.1.2.2 yamt struct udf_strategy *strategy = ump->strategy;
702 1.1.2.2 yamt struct udf_strat_args args;
703 1.1.2.2 yamt
704 1.1.2.3 yamt KASSERT(strategy);
705 1.1.2.2 yamt args.ump = ump;
706 1.1.2.2 yamt (strategy->discstrat_init)(&args);
707 1.1.2.2 yamt }
708 1.1.2.2 yamt
709 1.1.2.2 yamt
710 1.1.2.2 yamt void udf_discstrat_finish(struct udf_mount *ump)
711 1.1.2.2 yamt {
712 1.1.2.2 yamt struct udf_strategy *strategy = ump->strategy;
713 1.1.2.2 yamt struct udf_strat_args args;
714 1.1.2.2 yamt
715 1.1.2.3 yamt /* strategy might not have been set, so ignore if not set */
716 1.1.2.3 yamt if (strategy) {
717 1.1.2.3 yamt args.ump = ump;
718 1.1.2.3 yamt (strategy->discstrat_finish)(&args);
719 1.1.2.3 yamt }
720 1.1.2.2 yamt }
721 1.1.2.2 yamt
722 1.1.2.2 yamt /* --------------------------------------------------------------------- */
723 1.1.2.2 yamt
724