Thu Jun 18 15:09:18 2009 UTC ()
Fix nitpicky spacing and debug printout


(reinoud)
diff -r1.24 -r1.25 src/sys/fs/udf/udf_allocation.c

cvs diff -r1.24 -r1.25 src/sys/fs/udf/udf_allocation.c (switch to unified diff)

--- src/sys/fs/udf/udf_allocation.c 2009/06/18 15:06:38 1.24
+++ src/sys/fs/udf/udf_allocation.c 2009/06/18 15:09:18 1.25
@@ -1,2740 +1,2740 @@ @@ -1,2740 +1,2740 @@
1/* $NetBSD: udf_allocation.c,v 1.24 2009/06/18 15:06:38 reinoud Exp $ */ 1/* $NetBSD: udf_allocation.c,v 1.25 2009/06/18 15:09:18 reinoud Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006, 2008 Reinoud Zandijk 4 * Copyright (c) 2006, 2008 Reinoud Zandijk
5 * All rights reserved. 5 * All rights reserved.
6 *  6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 *  15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *  26 *
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30#ifndef lint 30#ifndef lint
31__KERNEL_RCSID(0, "$NetBSD: udf_allocation.c,v 1.24 2009/06/18 15:06:38 reinoud Exp $"); 31__KERNEL_RCSID(0, "$NetBSD: udf_allocation.c,v 1.25 2009/06/18 15:09:18 reinoud Exp $");
32#endif /* not lint */ 32#endif /* not lint */
33 33
34 34
35#if defined(_KERNEL_OPT) 35#if defined(_KERNEL_OPT)
36#include "opt_compat_netbsd.h" 36#include "opt_compat_netbsd.h"
37#endif 37#endif
38 38
39/* TODO strip */ 39/* TODO strip */
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/systm.h> 41#include <sys/systm.h>
42#include <sys/sysctl.h> 42#include <sys/sysctl.h>
43#include <sys/namei.h> 43#include <sys/namei.h>
44#include <sys/proc.h> 44#include <sys/proc.h>
45#include <sys/kernel.h> 45#include <sys/kernel.h>
46#include <sys/vnode.h> 46#include <sys/vnode.h>
47#include <miscfs/genfs/genfs_node.h> 47#include <miscfs/genfs/genfs_node.h>
48#include <sys/mount.h> 48#include <sys/mount.h>
49#include <sys/buf.h> 49#include <sys/buf.h>
50#include <sys/file.h> 50#include <sys/file.h>
51#include <sys/device.h> 51#include <sys/device.h>
52#include <sys/disklabel.h> 52#include <sys/disklabel.h>
53#include <sys/ioctl.h> 53#include <sys/ioctl.h>
54#include <sys/malloc.h> 54#include <sys/malloc.h>
55#include <sys/dirent.h> 55#include <sys/dirent.h>
56#include <sys/stat.h> 56#include <sys/stat.h>
57#include <sys/conf.h> 57#include <sys/conf.h>
58#include <sys/kauth.h> 58#include <sys/kauth.h>
59#include <sys/kthread.h> 59#include <sys/kthread.h>
60#include <dev/clock_subr.h> 60#include <dev/clock_subr.h>
61 61
62#include <fs/udf/ecma167-udf.h> 62#include <fs/udf/ecma167-udf.h>
63#include <fs/udf/udf_mount.h> 63#include <fs/udf/udf_mount.h>
64 64
65#include "udf.h" 65#include "udf.h"
66#include "udf_subr.h" 66#include "udf_subr.h"
67#include "udf_bswap.h" 67#include "udf_bswap.h"
68 68
69 69
70#define VTOI(vnode) ((struct udf_node *) vnode->v_data) 70#define VTOI(vnode) ((struct udf_node *) vnode->v_data)
71 71
72static void udf_record_allocation_in_node(struct udf_mount *ump, 72static void udf_record_allocation_in_node(struct udf_mount *ump,
73 struct buf *buf, uint16_t vpart_num, uint64_t *mapping, 73 struct buf *buf, uint16_t vpart_num, uint64_t *mapping,
74 struct long_ad *node_ad_cpy); 74 struct long_ad *node_ad_cpy);
75 75
76/* 76/*
77 * IDEA/BUSY: Each udf_node gets its own extentwalker state for all operations; 77 * IDEA/BUSY: Each udf_node gets its own extentwalker state for all operations;
78 * this will hopefully/likely reduce O(nlog(n)) to O(1) for most functionality 78 * this will hopefully/likely reduce O(nlog(n)) to O(1) for most functionality
79 * since actions are most likely sequencial and thus seeking doesn't need 79 * since actions are most likely sequencial and thus seeking doesn't need
80 * searching for the same or adjacent position again. 80 * searching for the same or adjacent position again.
81 */ 81 */
82 82
83/* --------------------------------------------------------------------- */ 83/* --------------------------------------------------------------------- */
84 84
85#if 0 85#if 0
86#if 1 86#if 1
87static void 87static void
88udf_node_dump(struct udf_node *udf_node) { 88udf_node_dump(struct udf_node *udf_node) {
89 struct file_entry *fe; 89 struct file_entry *fe;
90 struct extfile_entry *efe; 90 struct extfile_entry *efe;
91 struct icb_tag *icbtag; 91 struct icb_tag *icbtag;
92 struct long_ad s_ad; 92 struct long_ad s_ad;
93 uint64_t inflen; 93 uint64_t inflen;
94 uint32_t icbflags, addr_type; 94 uint32_t icbflags, addr_type;
95 uint32_t len, lb_num; 95 uint32_t len, lb_num;
96 uint32_t flags; 96 uint32_t flags;
97 int part_num; 97 int part_num;
98 int lb_size, eof, slot; 98 int lb_size, eof, slot;
99 99
100 if ((udf_verbose & UDF_DEBUG_NODEDUMP) == 0) 100 if ((udf_verbose & UDF_DEBUG_NODEDUMP) == 0)
101 return; 101 return;
102 102
103 lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size); 103 lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size);
104 104
105 fe = udf_node->fe; 105 fe = udf_node->fe;
106 efe = udf_node->efe; 106 efe = udf_node->efe;
107 if (fe) { 107 if (fe) {
108 icbtag = &fe->icbtag; 108 icbtag = &fe->icbtag;
109 inflen = udf_rw64(fe->inf_len); 109 inflen = udf_rw64(fe->inf_len);
110 } else { 110 } else {
111 icbtag = &efe->icbtag; 111 icbtag = &efe->icbtag;
112 inflen = udf_rw64(efe->inf_len); 112 inflen = udf_rw64(efe->inf_len);
113 } 113 }
114 114
115 icbflags = udf_rw16(icbtag->flags); 115 icbflags = udf_rw16(icbtag->flags);
116 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK; 116 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK;
117 117
118 printf("udf_node_dump %p :\n", udf_node); 118 printf("udf_node_dump %p :\n", udf_node);
119 119
120 if (addr_type == UDF_ICB_INTERN_ALLOC) { 120 if (addr_type == UDF_ICB_INTERN_ALLOC) {
121 printf("\tIntern alloc, len = %"PRIu64"\n", inflen); 121 printf("\tIntern alloc, len = %"PRIu64"\n", inflen);
122 return; 122 return;
123 } 123 }
124 124
125 printf("\tInflen = %"PRIu64"\n", inflen); 125 printf("\tInflen = %"PRIu64"\n", inflen);
126 printf("\t\t"); 126 printf("\t\t");
127 127
128 slot = 0; 128 slot = 0;
129 for (;;) { 129 for (;;) {
130 udf_get_adslot(udf_node, slot, &s_ad, &eof); 130 udf_get_adslot(udf_node, slot, &s_ad, &eof);
131 if (eof) 131 if (eof)
132 break; 132 break;
133 part_num = udf_rw16(s_ad.loc.part_num); 133 part_num = udf_rw16(s_ad.loc.part_num);
134 lb_num = udf_rw32(s_ad.loc.lb_num); 134 lb_num = udf_rw32(s_ad.loc.lb_num);
135 len = udf_rw32(s_ad.len); 135 len = udf_rw32(s_ad.len);
136 flags = UDF_EXT_FLAGS(len); 136 flags = UDF_EXT_FLAGS(len);
137 len = UDF_EXT_LEN(len); 137 len = UDF_EXT_LEN(len);
138 138
139 printf("["); 139 printf("[");
140 if (part_num >= 0) 140 if (part_num >= 0)
141 printf("part %d, ", part_num); 141 printf("part %d, ", part_num);
142 printf("lb_num %d, len %d", lb_num, len); 142 printf("lb_num %d, len %d", lb_num, len);
143 if (flags) 143 if (flags)
144 printf(", flags %d", flags>>30); 144 printf(", flags %d", flags>>30);
145 printf("] "); 145 printf("] ");
146 146
147 if (flags == UDF_EXT_REDIRECT) { 147 if (flags == UDF_EXT_REDIRECT) {
148 printf("\n\textent END\n\tallocation extent\n\t\t"); 148 printf("\n\textent END\n\tallocation extent\n\t\t");
149 } 149 }
150 150
151 slot++; 151 slot++;
152 } 152 }
153 printf("\n\tl_ad END\n\n"); 153 printf("\n\tl_ad END\n\n");
154} 154}
155#else 155#else
156#define udf_node_dump(a) 156#define udf_node_dump(a)
157#endif 157#endif
158 158
159 159
160static void 160static void
161udf_assert_allocated(struct udf_mount *ump, uint16_t vpart_num, 161udf_assert_allocated(struct udf_mount *ump, uint16_t vpart_num,
162 uint32_t lb_num, uint32_t num_lb) 162 uint32_t lb_num, uint32_t num_lb)
163{ 163{
164 struct udf_bitmap *bitmap; 164 struct udf_bitmap *bitmap;
165 struct part_desc *pdesc; 165 struct part_desc *pdesc;
166 uint32_t ptov; 166 uint32_t ptov;
167 uint32_t bitval; 167 uint32_t bitval;
168 uint8_t *bpos; 168 uint8_t *bpos;
169 int bit; 169 int bit;
170 int phys_part; 170 int phys_part;
171 int ok; 171 int ok;
172 172
173 DPRINTF(PARANOIA, ("udf_assert_allocated: check virt lbnum %d " 173 DPRINTF(PARANOIA, ("udf_assert_allocated: check virt lbnum %d "
174 "part %d + %d sect\n", lb_num, vpart_num, num_lb)); 174 "part %d + %d sect\n", lb_num, vpart_num, num_lb));
175 175
176 /* get partition backing up this vpart_num */ 176 /* get partition backing up this vpart_num */
177 pdesc = ump->partitions[ump->vtop[vpart_num]]; 177 pdesc = ump->partitions[ump->vtop[vpart_num]];
178 178
179 switch (ump->vtop_tp[vpart_num]) { 179 switch (ump->vtop_tp[vpart_num]) {
180 case UDF_VTOP_TYPE_PHYS : 180 case UDF_VTOP_TYPE_PHYS :
181 case UDF_VTOP_TYPE_SPARABLE : 181 case UDF_VTOP_TYPE_SPARABLE :
182 /* free space to freed or unallocated space bitmap */ 182 /* free space to freed or unallocated space bitmap */
183 ptov = udf_rw32(pdesc->start_loc); 183 ptov = udf_rw32(pdesc->start_loc);
184 phys_part = ump->vtop[vpart_num]; 184 phys_part = ump->vtop[vpart_num];
185 185
186 /* use unallocated bitmap */ 186 /* use unallocated bitmap */
187 bitmap = &ump->part_unalloc_bits[phys_part]; 187 bitmap = &ump->part_unalloc_bits[phys_part];
188 188
189 /* if no bitmaps are defined, bail out */ 189 /* if no bitmaps are defined, bail out */
190 if (bitmap->bits == NULL) 190 if (bitmap->bits == NULL)
191 break; 191 break;
192 192
193 /* check bits */ 193 /* check bits */
194 KASSERT(bitmap->bits); 194 KASSERT(bitmap->bits);
195 ok = 1; 195 ok = 1;
196 bpos = bitmap->bits + lb_num/8; 196 bpos = bitmap->bits + lb_num/8;
197 bit = lb_num % 8; 197 bit = lb_num % 8;
198 while (num_lb > 0) { 198 while (num_lb > 0) {
199 bitval = (1 << bit); 199 bitval = (1 << bit);
200 DPRINTF(PARANOIA, ("XXX : check %d, %p, bit %d\n", 200 DPRINTF(PARANOIA, ("XXX : check %d, %p, bit %d\n",
201 lb_num, bpos, bit)); 201 lb_num, bpos, bit));
202 KASSERT(bitmap->bits + lb_num/8 == bpos); 202 KASSERT(bitmap->bits + lb_num/8 == bpos);
203 if (*bpos & bitval) { 203 if (*bpos & bitval) {
204 printf("\tlb_num %d is NOT marked busy\n", 204 printf("\tlb_num %d is NOT marked busy\n",
205 lb_num); 205 lb_num);
206 ok = 0; 206 ok = 0;
207 } 207 }
208 lb_num++; num_lb--; 208 lb_num++; num_lb--;
209 bit = (bit + 1) % 8; 209 bit = (bit + 1) % 8;
210 if (bit == 0) 210 if (bit == 0)
211 bpos++; 211 bpos++;
212 } 212 }
213 if (!ok) { 213 if (!ok) {
214 /* KASSERT(0); */ 214 /* KASSERT(0); */
215 } 215 }
216 216
217 break; 217 break;
218 case UDF_VTOP_TYPE_VIRT : 218 case UDF_VTOP_TYPE_VIRT :
219 /* TODO check space */ 219 /* TODO check space */
220 KASSERT(num_lb == 1); 220 KASSERT(num_lb == 1);
221 break; 221 break;
222 case UDF_VTOP_TYPE_META : 222 case UDF_VTOP_TYPE_META :
223 /* TODO check space in the metadata bitmap */ 223 /* TODO check space in the metadata bitmap */
224 default: 224 default:
225 /* not implemented */ 225 /* not implemented */
226 break; 226 break;
227 } 227 }
228} 228}
229 229
230 230
231static void 231static void
232udf_node_sanity_check(struct udf_node *udf_node, 232udf_node_sanity_check(struct udf_node *udf_node,
233 uint64_t *cnt_inflen, uint64_t *cnt_logblksrec) 233 uint64_t *cnt_inflen, uint64_t *cnt_logblksrec)
234{ 234{
235 union dscrptr *dscr; 235 union dscrptr *dscr;
236 struct file_entry *fe; 236 struct file_entry *fe;
237 struct extfile_entry *efe; 237 struct extfile_entry *efe;
238 struct icb_tag *icbtag; 238 struct icb_tag *icbtag;
239 struct long_ad s_ad; 239 struct long_ad s_ad;
240 uint64_t inflen, logblksrec; 240 uint64_t inflen, logblksrec;
241 uint32_t icbflags, addr_type; 241 uint32_t icbflags, addr_type;
242 uint32_t len, lb_num, l_ea, l_ad, max_l_ad; 242 uint32_t len, lb_num, l_ea, l_ad, max_l_ad;
243 uint16_t part_num; 243 uint16_t part_num;
244 uint8_t *data_pos; 244 uint8_t *data_pos;
245 int dscr_size, lb_size, flags, whole_lb; 245 int dscr_size, lb_size, flags, whole_lb;
246 int i, slot, eof; 246 int i, slot, eof;
247 247
248// KASSERT(mutex_owned(&udf_node->ump->allocate_mutex)); 248// KASSERT(mutex_owned(&udf_node->ump->allocate_mutex));
249 249
250 if (1) 250 if (1)
251 udf_node_dump(udf_node); 251 udf_node_dump(udf_node);
252 252
253 lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size); 253 lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size);
254 254
255 fe = udf_node->fe; 255 fe = udf_node->fe;
256 efe = udf_node->efe; 256 efe = udf_node->efe;
257 if (fe) { 257 if (fe) {
258 dscr = (union dscrptr *) fe; 258 dscr = (union dscrptr *) fe;
259 icbtag = &fe->icbtag; 259 icbtag = &fe->icbtag;
260 inflen = udf_rw64(fe->inf_len); 260 inflen = udf_rw64(fe->inf_len);
261 dscr_size = sizeof(struct file_entry) -1; 261 dscr_size = sizeof(struct file_entry) -1;
262 logblksrec = udf_rw64(fe->logblks_rec); 262 logblksrec = udf_rw64(fe->logblks_rec);
263 l_ad = udf_rw32(fe->l_ad); 263 l_ad = udf_rw32(fe->l_ad);
264 l_ea = udf_rw32(fe->l_ea); 264 l_ea = udf_rw32(fe->l_ea);
265 } else { 265 } else {
266 dscr = (union dscrptr *) efe; 266 dscr = (union dscrptr *) efe;
267 icbtag = &efe->icbtag; 267 icbtag = &efe->icbtag;
268 inflen = udf_rw64(efe->inf_len); 268 inflen = udf_rw64(efe->inf_len);
269 dscr_size = sizeof(struct extfile_entry) -1; 269 dscr_size = sizeof(struct extfile_entry) -1;
270 logblksrec = udf_rw64(efe->logblks_rec); 270 logblksrec = udf_rw64(efe->logblks_rec);
271 l_ad = udf_rw32(efe->l_ad); 271 l_ad = udf_rw32(efe->l_ad);
272 l_ea = udf_rw32(efe->l_ea); 272 l_ea = udf_rw32(efe->l_ea);
273 } 273 }
274 data_pos = (uint8_t *) dscr + dscr_size + l_ea; 274 data_pos = (uint8_t *) dscr + dscr_size + l_ea;
275 max_l_ad = lb_size - dscr_size - l_ea; 275 max_l_ad = lb_size - dscr_size - l_ea;
276 icbflags = udf_rw16(icbtag->flags); 276 icbflags = udf_rw16(icbtag->flags);
277 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK; 277 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK;
278 278
279 /* check if tail is zero */ 279 /* check if tail is zero */
280 DPRINTF(PARANOIA, ("Sanity check blank tail\n")); 280 DPRINTF(PARANOIA, ("Sanity check blank tail\n"));
281 for (i = l_ad; i < max_l_ad; i++) { 281 for (i = l_ad; i < max_l_ad; i++) {
282 if (data_pos[i] != 0) 282 if (data_pos[i] != 0)
283 printf( "sanity_check: violation: node byte %d " 283 printf( "sanity_check: violation: node byte %d "
284 "has value %d\n", i, data_pos[i]); 284 "has value %d\n", i, data_pos[i]);
285 } 285 }
286 286
287 /* reset counters */ 287 /* reset counters */
288 *cnt_inflen = 0; 288 *cnt_inflen = 0;
289 *cnt_logblksrec = 0; 289 *cnt_logblksrec = 0;
290 290
291 if (addr_type == UDF_ICB_INTERN_ALLOC) { 291 if (addr_type == UDF_ICB_INTERN_ALLOC) {
292 KASSERT(l_ad <= max_l_ad); 292 KASSERT(l_ad <= max_l_ad);
293 KASSERT(l_ad == inflen); 293 KASSERT(l_ad == inflen);
294 *cnt_inflen = inflen; 294 *cnt_inflen = inflen;
295 return; 295 return;
296 } 296 }
297 297
298 /* start counting */ 298 /* start counting */
299 whole_lb = 1; 299 whole_lb = 1;
300 slot = 0; 300 slot = 0;
301 for (;;) { 301 for (;;) {
302 udf_get_adslot(udf_node, slot, &s_ad, &eof); 302 udf_get_adslot(udf_node, slot, &s_ad, &eof);
303 if (eof) 303 if (eof)
304 break; 304 break;
305 KASSERT(whole_lb == 1); 305 KASSERT(whole_lb == 1);
306 306
307 part_num = udf_rw16(s_ad.loc.part_num); 307 part_num = udf_rw16(s_ad.loc.part_num);
308 lb_num = udf_rw32(s_ad.loc.lb_num); 308 lb_num = udf_rw32(s_ad.loc.lb_num);
309 len = udf_rw32(s_ad.len); 309 len = udf_rw32(s_ad.len);
310 flags = UDF_EXT_FLAGS(len); 310 flags = UDF_EXT_FLAGS(len);
311 len = UDF_EXT_LEN(len); 311 len = UDF_EXT_LEN(len);
312 312
313 if (flags != UDF_EXT_REDIRECT) { 313 if (flags != UDF_EXT_REDIRECT) {
314 *cnt_inflen += len; 314 *cnt_inflen += len;
315 if (flags == UDF_EXT_ALLOCATED) { 315 if (flags == UDF_EXT_ALLOCATED) {
316 *cnt_logblksrec += (len + lb_size -1) / lb_size; 316 *cnt_logblksrec += (len + lb_size -1) / lb_size;
317 } 317 }
318 } else { 318 } else {
319 KASSERT(len == lb_size); 319 KASSERT(len == lb_size);
320 } 320 }
321 /* check allocation */ 321 /* check allocation */
322 if (flags == UDF_EXT_ALLOCATED) 322 if (flags == UDF_EXT_ALLOCATED)
323 udf_assert_allocated(udf_node->ump, part_num, lb_num, 323 udf_assert_allocated(udf_node->ump, part_num, lb_num,
324 (len + lb_size - 1) / lb_size); 324 (len + lb_size - 1) / lb_size);
325 325
326 /* check whole lb */ 326 /* check whole lb */
327 whole_lb = ((len % lb_size) == 0); 327 whole_lb = ((len % lb_size) == 0);
328 328
329 slot++; 329 slot++;
330 } 330 }
331 /* rest should be zero (ad_off > l_ad < max_l_ad - adlen) */ 331 /* rest should be zero (ad_off > l_ad < max_l_ad - adlen) */
332 332
333 KASSERT(*cnt_inflen == inflen); 333 KASSERT(*cnt_inflen == inflen);
334 KASSERT(*cnt_logblksrec == logblksrec); 334 KASSERT(*cnt_logblksrec == logblksrec);
335 335
336// KASSERT(mutex_owned(&udf_node->ump->allocate_mutex)); 336// KASSERT(mutex_owned(&udf_node->ump->allocate_mutex));
337} 337}
338#else 338#else
339static void 339static void
340udf_node_sanity_check(struct udf_node *udf_node, 340udf_node_sanity_check(struct udf_node *udf_node,
341 uint64_t *cnt_inflen, uint64_t *cnt_logblksrec) { 341 uint64_t *cnt_inflen, uint64_t *cnt_logblksrec) {
342 struct file_entry *fe; 342 struct file_entry *fe;
343 struct extfile_entry *efe; 343 struct extfile_entry *efe;
344 struct icb_tag *icbtag; 344 struct icb_tag *icbtag;
345 uint64_t inflen, logblksrec; 345 uint64_t inflen, logblksrec;
346 int dscr_size, lb_size; 346 int dscr_size, lb_size;
347 347
348 lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size); 348 lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size);
349 349
350 fe = udf_node->fe; 350 fe = udf_node->fe;
351 efe = udf_node->efe; 351 efe = udf_node->efe;
352 if (fe) { 352 if (fe) {
353 icbtag = &fe->icbtag; 353 icbtag = &fe->icbtag;
354 inflen = udf_rw64(fe->inf_len); 354 inflen = udf_rw64(fe->inf_len);
355 dscr_size = sizeof(struct file_entry) -1; 355 dscr_size = sizeof(struct file_entry) -1;
356 logblksrec = udf_rw64(fe->logblks_rec); 356 logblksrec = udf_rw64(fe->logblks_rec);
357 } else { 357 } else {
358 icbtag = &efe->icbtag; 358 icbtag = &efe->icbtag;
359 inflen = udf_rw64(efe->inf_len); 359 inflen = udf_rw64(efe->inf_len);
360 dscr_size = sizeof(struct extfile_entry) -1; 360 dscr_size = sizeof(struct extfile_entry) -1;
361 logblksrec = udf_rw64(efe->logblks_rec); 361 logblksrec = udf_rw64(efe->logblks_rec);
362 } 362 }
363 *cnt_logblksrec = logblksrec; 363 *cnt_logblksrec = logblksrec;
364 *cnt_inflen = inflen; 364 *cnt_inflen = inflen;
365} 365}
366#endif 366#endif
367 367
368/* --------------------------------------------------------------------- */ 368/* --------------------------------------------------------------------- */
369 369
370int 370int
371udf_translate_vtop(struct udf_mount *ump, struct long_ad *icb_loc, 371udf_translate_vtop(struct udf_mount *ump, struct long_ad *icb_loc,
372 uint32_t *lb_numres, uint32_t *extres) 372 uint32_t *lb_numres, uint32_t *extres)
373{ 373{
374 struct part_desc *pdesc; 374 struct part_desc *pdesc;
375 struct spare_map_entry *sme; 375 struct spare_map_entry *sme;
376 struct long_ad s_icb_loc; 376 struct long_ad s_icb_loc;
377 uint64_t foffset, end_foffset; 377 uint64_t foffset, end_foffset;
378 uint32_t lb_size, len; 378 uint32_t lb_size, len;
379 uint32_t lb_num, lb_rel, lb_packet; 379 uint32_t lb_num, lb_rel, lb_packet;
380 uint32_t udf_rw32_lbmap, ext_offset; 380 uint32_t udf_rw32_lbmap, ext_offset;
381 uint16_t vpart; 381 uint16_t vpart;
382 int rel, part, error, eof, slot, flags; 382 int rel, part, error, eof, slot, flags;
383 383
384 assert(ump && icb_loc && lb_numres); 384 assert(ump && icb_loc && lb_numres);
385 385
386 vpart = udf_rw16(icb_loc->loc.part_num); 386 vpart = udf_rw16(icb_loc->loc.part_num);
387 lb_num = udf_rw32(icb_loc->loc.lb_num); 387 lb_num = udf_rw32(icb_loc->loc.lb_num);
388 if (vpart > UDF_VTOP_RAWPART) 388 if (vpart > UDF_VTOP_RAWPART)
389 return EINVAL; 389 return EINVAL;
390 390
391translate_again: 391translate_again:
392 part = ump->vtop[vpart]; 392 part = ump->vtop[vpart];
393 pdesc = ump->partitions[part]; 393 pdesc = ump->partitions[part];
394 394
395 switch (ump->vtop_tp[vpart]) { 395 switch (ump->vtop_tp[vpart]) {
396 case UDF_VTOP_TYPE_RAW : 396 case UDF_VTOP_TYPE_RAW :
397 /* 1:1 to the end of the device */ 397 /* 1:1 to the end of the device */
398 *lb_numres = lb_num; 398 *lb_numres = lb_num;
399 *extres = INT_MAX; 399 *extres = INT_MAX;
400 return 0; 400 return 0;
401 case UDF_VTOP_TYPE_PHYS : 401 case UDF_VTOP_TYPE_PHYS :
402 /* transform into its disc logical block */ 402 /* transform into its disc logical block */
403 if (lb_num > udf_rw32(pdesc->part_len)) 403 if (lb_num > udf_rw32(pdesc->part_len))
404 return EINVAL; 404 return EINVAL;
405 *lb_numres = lb_num + udf_rw32(pdesc->start_loc); 405 *lb_numres = lb_num + udf_rw32(pdesc->start_loc);
406 406
407 /* extent from here to the end of the partition */ 407 /* extent from here to the end of the partition */
408 *extres = udf_rw32(pdesc->part_len) - lb_num; 408 *extres = udf_rw32(pdesc->part_len) - lb_num;
409 return 0; 409 return 0;
410 case UDF_VTOP_TYPE_VIRT : 410 case UDF_VTOP_TYPE_VIRT :
411 /* only maps one logical block, lookup in VAT */ 411 /* only maps one logical block, lookup in VAT */
412 if (lb_num >= ump->vat_entries) /* XXX > or >= ? */ 412 if (lb_num >= ump->vat_entries) /* XXX > or >= ? */
413 return EINVAL; 413 return EINVAL;
414 414
415 /* lookup in virtual allocation table file */ 415 /* lookup in virtual allocation table file */
416 mutex_enter(&ump->allocate_mutex); 416 mutex_enter(&ump->allocate_mutex);
417 error = udf_vat_read(ump->vat_node, 417 error = udf_vat_read(ump->vat_node,
418 (uint8_t *) &udf_rw32_lbmap, 4, 418 (uint8_t *) &udf_rw32_lbmap, 4,
419 ump->vat_offset + lb_num * 4); 419 ump->vat_offset + lb_num * 4);
420 mutex_exit(&ump->allocate_mutex); 420 mutex_exit(&ump->allocate_mutex);
421 421
422 if (error) 422 if (error)
423 return error; 423 return error;
424 424
425 lb_num = udf_rw32(udf_rw32_lbmap); 425 lb_num = udf_rw32(udf_rw32_lbmap);
426 426
427 /* transform into its disc logical block */ 427 /* transform into its disc logical block */
428 if (lb_num > udf_rw32(pdesc->part_len)) 428 if (lb_num > udf_rw32(pdesc->part_len))
429 return EINVAL; 429 return EINVAL;
430 *lb_numres = lb_num + udf_rw32(pdesc->start_loc); 430 *lb_numres = lb_num + udf_rw32(pdesc->start_loc);
431 431
432 /* just one logical block */ 432 /* just one logical block */
433 *extres = 1; 433 *extres = 1;
434 return 0; 434 return 0;
435 case UDF_VTOP_TYPE_SPARABLE : 435 case UDF_VTOP_TYPE_SPARABLE :
436 /* check if the packet containing the lb_num is remapped */ 436 /* check if the packet containing the lb_num is remapped */
437 lb_packet = lb_num / ump->sparable_packet_size; 437 lb_packet = lb_num / ump->sparable_packet_size;
438 lb_rel = lb_num % ump->sparable_packet_size; 438 lb_rel = lb_num % ump->sparable_packet_size;
439 439
440 for (rel = 0; rel < udf_rw16(ump->sparing_table->rt_l); rel++) { 440 for (rel = 0; rel < udf_rw16(ump->sparing_table->rt_l); rel++) {
441 sme = &ump->sparing_table->entries[rel]; 441 sme = &ump->sparing_table->entries[rel];
442 if (lb_packet == udf_rw32(sme->org)) { 442 if (lb_packet == udf_rw32(sme->org)) {
443 /* NOTE maps to absolute disc logical block! */ 443 /* NOTE maps to absolute disc logical block! */
444 *lb_numres = udf_rw32(sme->map) + lb_rel; 444 *lb_numres = udf_rw32(sme->map) + lb_rel;
445 *extres = ump->sparable_packet_size - lb_rel; 445 *extres = ump->sparable_packet_size - lb_rel;
446 return 0; 446 return 0;
447 } 447 }
448 } 448 }
449 449
450 /* transform into its disc logical block */ 450 /* transform into its disc logical block */
451 if (lb_num > udf_rw32(pdesc->part_len)) 451 if (lb_num > udf_rw32(pdesc->part_len))
452 return EINVAL; 452 return EINVAL;
453 *lb_numres = lb_num + udf_rw32(pdesc->start_loc); 453 *lb_numres = lb_num + udf_rw32(pdesc->start_loc);
454 454
455 /* rest of block */ 455 /* rest of block */
456 *extres = ump->sparable_packet_size - lb_rel; 456 *extres = ump->sparable_packet_size - lb_rel;
457 return 0; 457 return 0;
458 case UDF_VTOP_TYPE_META : 458 case UDF_VTOP_TYPE_META :
459 /* we have to look into the file's allocation descriptors */ 459 /* we have to look into the file's allocation descriptors */
460 460
461 /* use metadatafile allocation mutex */ 461 /* use metadatafile allocation mutex */
462 lb_size = udf_rw32(ump->logical_vol->lb_size); 462 lb_size = udf_rw32(ump->logical_vol->lb_size);
463 463
464 UDF_LOCK_NODE(ump->metadata_node, 0); 464 UDF_LOCK_NODE(ump->metadata_node, 0);
465 465
466 /* get first overlapping extent */ 466 /* get first overlapping extent */
467 foffset = 0; 467 foffset = 0;
468 slot = 0; 468 slot = 0;
469 for (;;) { 469 for (;;) {
470 udf_get_adslot(ump->metadata_node, 470 udf_get_adslot(ump->metadata_node,
471 slot, &s_icb_loc, &eof); 471 slot, &s_icb_loc, &eof);
472 DPRINTF(ADWLK, ("slot %d, eof = %d, flags = %d, " 472 DPRINTF(ADWLK, ("slot %d, eof = %d, flags = %d, "
473 "len = %d, lb_num = %d, part = %d\n", 473 "len = %d, lb_num = %d, part = %d\n",
474 slot, eof, 474 slot, eof,
475 UDF_EXT_FLAGS(udf_rw32(s_icb_loc.len)), 475 UDF_EXT_FLAGS(udf_rw32(s_icb_loc.len)),
476 UDF_EXT_LEN(udf_rw32(s_icb_loc.len)), 476 UDF_EXT_LEN(udf_rw32(s_icb_loc.len)),
477 udf_rw32(s_icb_loc.loc.lb_num), 477 udf_rw32(s_icb_loc.loc.lb_num),
478 udf_rw16(s_icb_loc.loc.part_num))); 478 udf_rw16(s_icb_loc.loc.part_num)));
479 if (eof) { 479 if (eof) {
480 DPRINTF(TRANSLATE, 480 DPRINTF(TRANSLATE,
481 ("Meta partition translation " 481 ("Meta partition translation "
482 "failed: can't seek location\n")); 482 "failed: can't seek location\n"));
483 UDF_UNLOCK_NODE(ump->metadata_node, 0); 483 UDF_UNLOCK_NODE(ump->metadata_node, 0);
484 return EINVAL; 484 return EINVAL;
485 } 485 }
486 len = udf_rw32(s_icb_loc.len); 486 len = udf_rw32(s_icb_loc.len);
487 flags = UDF_EXT_FLAGS(len); 487 flags = UDF_EXT_FLAGS(len);
488 len = UDF_EXT_LEN(len); 488 len = UDF_EXT_LEN(len);
489 489
490 if (flags == UDF_EXT_REDIRECT) { 490 if (flags == UDF_EXT_REDIRECT) {
491 slot++; 491 slot++;
492 continue; 492 continue;
493 } 493 }
494 494
495 end_foffset = foffset + len; 495 end_foffset = foffset + len;
496 496
497 if (end_foffset > lb_num * lb_size) 497 if (end_foffset > lb_num * lb_size)
498 break; /* found */ 498 break; /* found */
499 foffset = end_foffset; 499 foffset = end_foffset;
500 slot++; 500 slot++;
501 } 501 }
502 /* found overlapping slot */ 502 /* found overlapping slot */
503 ext_offset = lb_num * lb_size - foffset; 503 ext_offset = lb_num * lb_size - foffset;
504 504
505 /* process extent offset */ 505 /* process extent offset */
506 lb_num = udf_rw32(s_icb_loc.loc.lb_num); 506 lb_num = udf_rw32(s_icb_loc.loc.lb_num);
507 vpart = udf_rw16(s_icb_loc.loc.part_num); 507 vpart = udf_rw16(s_icb_loc.loc.part_num);
508 lb_num += (ext_offset + lb_size -1) / lb_size; 508 lb_num += (ext_offset + lb_size -1) / lb_size;
509 ext_offset = 0; 509 ext_offset = 0;
510 510
511 UDF_UNLOCK_NODE(ump->metadata_node, 0); 511 UDF_UNLOCK_NODE(ump->metadata_node, 0);
512 if (flags != UDF_EXT_ALLOCATED) { 512 if (flags != UDF_EXT_ALLOCATED) {
513 DPRINTF(TRANSLATE, ("Metadata partition translation " 513 DPRINTF(TRANSLATE, ("Metadata partition translation "
514 "failed: not allocated\n")); 514 "failed: not allocated\n"));
515 return EINVAL; 515 return EINVAL;
516 } 516 }
517 517
518 /* 518 /*
519 * vpart and lb_num are updated, translate again since we 519 * vpart and lb_num are updated, translate again since we
520 * might be mapped on sparable media 520 * might be mapped on sparable media
521 */ 521 */
522 goto translate_again; 522 goto translate_again;
523 default: 523 default:
524 printf("UDF vtop translation scheme %d unimplemented yet\n", 524 printf("UDF vtop translation scheme %d unimplemented yet\n",
525 ump->vtop_tp[vpart]); 525 ump->vtop_tp[vpart]);
526 } 526 }
527 527
528 return EINVAL; 528 return EINVAL;
529} 529}
530 530
531 531
532/* XXX provisional primitive braindead version */ 532/* XXX provisional primitive braindead version */
533/* TODO use ext_res */ 533/* TODO use ext_res */
534void 534void
535udf_translate_vtop_list(struct udf_mount *ump, uint32_t sectors, 535udf_translate_vtop_list(struct udf_mount *ump, uint32_t sectors,
536 uint16_t vpart_num, uint64_t *lmapping, uint64_t *pmapping) 536 uint16_t vpart_num, uint64_t *lmapping, uint64_t *pmapping)
537{ 537{
538 struct long_ad loc; 538 struct long_ad loc;
539 uint32_t lb_numres, ext_res; 539 uint32_t lb_numres, ext_res;
540 int sector; 540 int sector;
541 541
542 for (sector = 0; sector < sectors; sector++) { 542 for (sector = 0; sector < sectors; sector++) {
543 memset(&loc, 0, sizeof(struct long_ad)); 543 memset(&loc, 0, sizeof(struct long_ad));
544 loc.loc.part_num = udf_rw16(vpart_num); 544 loc.loc.part_num = udf_rw16(vpart_num);
545 loc.loc.lb_num = udf_rw32(*lmapping); 545 loc.loc.lb_num = udf_rw32(*lmapping);
546 udf_translate_vtop(ump, &loc, &lb_numres, &ext_res); 546 udf_translate_vtop(ump, &loc, &lb_numres, &ext_res);
547 *pmapping = lb_numres; 547 *pmapping = lb_numres;
548 lmapping++; pmapping++; 548 lmapping++; pmapping++;
549 } 549 }
550} 550}
551 551
552 552
553/* --------------------------------------------------------------------- */ 553/* --------------------------------------------------------------------- */
554 554
555/* 555/*
556 * Translate an extent (in logical_blocks) into logical block numbers; used 556 * Translate an extent (in logical_blocks) into logical block numbers; used
557 * for read and write operations. DOESNT't check extents. 557 * for read and write operations. DOESNT't check extents.
558 */ 558 */
559 559
560int 560int
561udf_translate_file_extent(struct udf_node *udf_node, 561udf_translate_file_extent(struct udf_node *udf_node,
562 uint32_t from, uint32_t num_lb, 562 uint32_t from, uint32_t num_lb,
563 uint64_t *map) 563 uint64_t *map)
564{ 564{
565 struct udf_mount *ump; 565 struct udf_mount *ump;
566 struct icb_tag *icbtag; 566 struct icb_tag *icbtag;
567 struct long_ad t_ad, s_ad; 567 struct long_ad t_ad, s_ad;
568 uint64_t transsec; 568 uint64_t transsec;
569 uint64_t foffset, end_foffset; 569 uint64_t foffset, end_foffset;
570 uint32_t transsec32; 570 uint32_t transsec32;
571 uint32_t lb_size; 571 uint32_t lb_size;
572 uint32_t ext_offset; 572 uint32_t ext_offset;
573 uint32_t lb_num, len; 573 uint32_t lb_num, len;
574 uint32_t overlap, translen; 574 uint32_t overlap, translen;
575 uint16_t vpart_num; 575 uint16_t vpart_num;
576 int eof, error, flags; 576 int eof, error, flags;
577 int slot, addr_type, icbflags; 577 int slot, addr_type, icbflags;
578 578
579 if (!udf_node) 579 if (!udf_node)
580 return ENOENT; 580 return ENOENT;
581 581
582 KASSERT(num_lb > 0); 582 KASSERT(num_lb > 0);
583 583
584 UDF_LOCK_NODE(udf_node, 0); 584 UDF_LOCK_NODE(udf_node, 0);
585 585
586 /* initialise derivative vars */ 586 /* initialise derivative vars */
587 ump = udf_node->ump; 587 ump = udf_node->ump;
588 lb_size = udf_rw32(ump->logical_vol->lb_size); 588 lb_size = udf_rw32(ump->logical_vol->lb_size);
589 589
590 if (udf_node->fe) { 590 if (udf_node->fe) {
591 icbtag = &udf_node->fe->icbtag; 591 icbtag = &udf_node->fe->icbtag;
592 } else { 592 } else {
593 icbtag = &udf_node->efe->icbtag; 593 icbtag = &udf_node->efe->icbtag;
594 } 594 }
595 icbflags = udf_rw16(icbtag->flags); 595 icbflags = udf_rw16(icbtag->flags);
596 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK; 596 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK;
597 597
598 /* do the work */ 598 /* do the work */
599 if (addr_type == UDF_ICB_INTERN_ALLOC) { 599 if (addr_type == UDF_ICB_INTERN_ALLOC) {
600 *map = UDF_TRANS_INTERN; 600 *map = UDF_TRANS_INTERN;
601 UDF_UNLOCK_NODE(udf_node, 0); 601 UDF_UNLOCK_NODE(udf_node, 0);
602 return 0; 602 return 0;
603 } 603 }
604 604
605 /* find first overlapping extent */ 605 /* find first overlapping extent */
606 foffset = 0; 606 foffset = 0;
607 slot = 0; 607 slot = 0;
608 for (;;) { 608 for (;;) {
609 udf_get_adslot(udf_node, slot, &s_ad, &eof); 609 udf_get_adslot(udf_node, slot, &s_ad, &eof);
610 DPRINTF(ADWLK, ("slot %d, eof = %d, flags = %d, len = %d, " 610 DPRINTF(ADWLK, ("slot %d, eof = %d, flags = %d, len = %d, "
611 "lb_num = %d, part = %d\n", slot, eof, 611 "lb_num = %d, part = %d\n", slot, eof,
612 UDF_EXT_FLAGS(udf_rw32(s_ad.len)), 612 UDF_EXT_FLAGS(udf_rw32(s_ad.len)),
613 UDF_EXT_LEN(udf_rw32(s_ad.len)), 613 UDF_EXT_LEN(udf_rw32(s_ad.len)),
614 udf_rw32(s_ad.loc.lb_num), 614 udf_rw32(s_ad.loc.lb_num),
615 udf_rw16(s_ad.loc.part_num))); 615 udf_rw16(s_ad.loc.part_num)));
616 if (eof) { 616 if (eof) {
617 DPRINTF(TRANSLATE, 617 DPRINTF(TRANSLATE,
618 ("Translate file extent " 618 ("Translate file extent "
619 "failed: can't seek location\n")); 619 "failed: can't seek location\n"));
620 UDF_UNLOCK_NODE(udf_node, 0); 620 UDF_UNLOCK_NODE(udf_node, 0);
621 return EINVAL; 621 return EINVAL;
622 } 622 }
623 len = udf_rw32(s_ad.len); 623 len = udf_rw32(s_ad.len);
624 flags = UDF_EXT_FLAGS(len); 624 flags = UDF_EXT_FLAGS(len);
625 len = UDF_EXT_LEN(len); 625 len = UDF_EXT_LEN(len);
626 lb_num = udf_rw32(s_ad.loc.lb_num); 626 lb_num = udf_rw32(s_ad.loc.lb_num);
627 627
628 if (flags == UDF_EXT_REDIRECT) { 628 if (flags == UDF_EXT_REDIRECT) {
629 slot++; 629 slot++;
630 continue; 630 continue;
631 } 631 }
632 632
633 end_foffset = foffset + len; 633 end_foffset = foffset + len;
634 634
635 if (end_foffset > from * lb_size) 635 if (end_foffset > from * lb_size)
636 break; /* found */ 636 break; /* found */
637 foffset = end_foffset; 637 foffset = end_foffset;
638 slot++; 638 slot++;
639 } 639 }
640 /* found overlapping slot */ 640 /* found overlapping slot */
641 ext_offset = from * lb_size - foffset; 641 ext_offset = from * lb_size - foffset;
642 642
643 for (;;) { 643 for (;;) {
644 udf_get_adslot(udf_node, slot, &s_ad, &eof); 644 udf_get_adslot(udf_node, slot, &s_ad, &eof);
645 DPRINTF(ADWLK, ("slot %d, eof = %d, flags = %d, len = %d, " 645 DPRINTF(ADWLK, ("slot %d, eof = %d, flags = %d, len = %d, "
646 "lb_num = %d, part = %d\n", slot, eof, 646 "lb_num = %d, part = %d\n", slot, eof,
647 UDF_EXT_FLAGS(udf_rw32(s_ad.len)), 647 UDF_EXT_FLAGS(udf_rw32(s_ad.len)),
648 UDF_EXT_LEN(udf_rw32(s_ad.len)), 648 UDF_EXT_LEN(udf_rw32(s_ad.len)),
649 udf_rw32(s_ad.loc.lb_num), 649 udf_rw32(s_ad.loc.lb_num),
650 udf_rw16(s_ad.loc.part_num))); 650 udf_rw16(s_ad.loc.part_num)));
651 if (eof) { 651 if (eof) {
652 DPRINTF(TRANSLATE, 652 DPRINTF(TRANSLATE,
653 ("Translate file extent " 653 ("Translate file extent "
654 "failed: past eof\n")); 654 "failed: past eof\n"));
655 UDF_UNLOCK_NODE(udf_node, 0); 655 UDF_UNLOCK_NODE(udf_node, 0);
656 return EINVAL; 656 return EINVAL;
657 } 657 }
658  658
659 len = udf_rw32(s_ad.len); 659 len = udf_rw32(s_ad.len);
660 flags = UDF_EXT_FLAGS(len); 660 flags = UDF_EXT_FLAGS(len);
661 len = UDF_EXT_LEN(len); 661 len = UDF_EXT_LEN(len);
662 662
663 lb_num = udf_rw32(s_ad.loc.lb_num); 663 lb_num = udf_rw32(s_ad.loc.lb_num);
664 vpart_num = udf_rw16(s_ad.loc.part_num); 664 vpart_num = udf_rw16(s_ad.loc.part_num);
665 665
666 end_foffset = foffset + len; 666 end_foffset = foffset + len;
667 667
668 /* process extent, don't forget to advance on ext_offset! */ 668 /* process extent, don't forget to advance on ext_offset! */
669 lb_num += (ext_offset + lb_size -1) / lb_size; 669 lb_num += (ext_offset + lb_size -1) / lb_size;
670 overlap = (len - ext_offset + lb_size -1) / lb_size; 670 overlap = (len - ext_offset + lb_size -1) / lb_size;
671 ext_offset = 0; 671 ext_offset = 0;
672 672
673 /* 673 /*
674 * note that the while(){} is nessisary for the extent that 674 * note that the while(){} is nessisary for the extent that
675 * the udf_translate_vtop() returns doens't have to span the 675 * the udf_translate_vtop() returns doens't have to span the
676 * whole extent. 676 * whole extent.
677 */ 677 */
678  678
679 overlap = MIN(overlap, num_lb); 679 overlap = MIN(overlap, num_lb);
680 while (overlap && (flags != UDF_EXT_REDIRECT)) { 680 while (overlap && (flags != UDF_EXT_REDIRECT)) {
681 switch (flags) { 681 switch (flags) {
682 case UDF_EXT_FREE : 682 case UDF_EXT_FREE :
683 case UDF_EXT_ALLOCATED_BUT_NOT_USED : 683 case UDF_EXT_ALLOCATED_BUT_NOT_USED :
684 transsec = UDF_TRANS_ZERO; 684 transsec = UDF_TRANS_ZERO;
685 translen = overlap; 685 translen = overlap;
686 while (overlap && num_lb && translen) { 686 while (overlap && num_lb && translen) {
687 *map++ = transsec; 687 *map++ = transsec;
688 lb_num++; 688 lb_num++;
689 overlap--; num_lb--; translen--; 689 overlap--; num_lb--; translen--;
690 } 690 }
691 break; 691 break;
692 case UDF_EXT_ALLOCATED : 692 case UDF_EXT_ALLOCATED :
693 t_ad.loc.lb_num = udf_rw32(lb_num); 693 t_ad.loc.lb_num = udf_rw32(lb_num);
694 t_ad.loc.part_num = udf_rw16(vpart_num); 694 t_ad.loc.part_num = udf_rw16(vpart_num);
695 error = udf_translate_vtop(ump, 695 error = udf_translate_vtop(ump,
696 &t_ad, &transsec32, &translen); 696 &t_ad, &transsec32, &translen);
697 transsec = transsec32; 697 transsec = transsec32;
698 if (error) { 698 if (error) {
699 UDF_UNLOCK_NODE(udf_node, 0); 699 UDF_UNLOCK_NODE(udf_node, 0);
700 return error; 700 return error;
701 } 701 }
702 while (overlap && num_lb && translen) { 702 while (overlap && num_lb && translen) {
703 *map++ = transsec; 703 *map++ = transsec;
704 lb_num++; transsec++; 704 lb_num++; transsec++;
705 overlap--; num_lb--; translen--; 705 overlap--; num_lb--; translen--;
706 } 706 }
707 break; 707 break;
708 default: 708 default:
709 DPRINTF(TRANSLATE, 709 DPRINTF(TRANSLATE,
710 ("Translate file extent " 710 ("Translate file extent "
711 "failed: bad flags %x\n", flags)); 711 "failed: bad flags %x\n", flags));
712 UDF_UNLOCK_NODE(udf_node, 0); 712 UDF_UNLOCK_NODE(udf_node, 0);
713 return EINVAL; 713 return EINVAL;
714 } 714 }
715 } 715 }
716 if (num_lb == 0) 716 if (num_lb == 0)
717 break; 717 break;
718 718
719 if (flags != UDF_EXT_REDIRECT) 719 if (flags != UDF_EXT_REDIRECT)
720 foffset = end_foffset; 720 foffset = end_foffset;
721 slot++; 721 slot++;
722 } 722 }
723 UDF_UNLOCK_NODE(udf_node, 0); 723 UDF_UNLOCK_NODE(udf_node, 0);
724 724
725 return 0; 725 return 0;
726} 726}
727 727
728/* --------------------------------------------------------------------- */ 728/* --------------------------------------------------------------------- */
729 729
730static int 730static int
731udf_search_free_vatloc(struct udf_mount *ump, uint32_t *lbnumres) 731udf_search_free_vatloc(struct udf_mount *ump, uint32_t *lbnumres)
732{ 732{
733 uint32_t lb_size, lb_num, lb_map, udf_rw32_lbmap; 733 uint32_t lb_size, lb_num, lb_map, udf_rw32_lbmap;
734 uint8_t *blob; 734 uint8_t *blob;
735 int entry, chunk, found, error; 735 int entry, chunk, found, error;
736 736
737 KASSERT(ump); 737 KASSERT(ump);
738 KASSERT(ump->logical_vol); 738 KASSERT(ump->logical_vol);
739 739
740 lb_size = udf_rw32(ump->logical_vol->lb_size); 740 lb_size = udf_rw32(ump->logical_vol->lb_size);
741 blob = malloc(lb_size, M_UDFTEMP, M_WAITOK); 741 blob = malloc(lb_size, M_UDFTEMP, M_WAITOK);
742 742
743 /* TODO static allocation of search chunk */ 743 /* TODO static allocation of search chunk */
744 744
745 lb_num = MIN(ump->vat_entries, ump->vat_last_free_lb); 745 lb_num = MIN(ump->vat_entries, ump->vat_last_free_lb);
746 found = 0; 746 found = 0;
747 error = 0; 747 error = 0;
748 entry = 0; 748 entry = 0;
749 do { 749 do {
750 chunk = MIN(lb_size, (ump->vat_entries - lb_num) * 4); 750 chunk = MIN(lb_size, (ump->vat_entries - lb_num) * 4);
751 if (chunk <= 0) 751 if (chunk <= 0)
752 break; 752 break;
753 /* load in chunk */ 753 /* load in chunk */
754 error = udf_vat_read(ump->vat_node, blob, chunk, 754 error = udf_vat_read(ump->vat_node, blob, chunk,
755 ump->vat_offset + lb_num * 4); 755 ump->vat_offset + lb_num * 4);
756 756
757 if (error) 757 if (error)
758 break; 758 break;
759 759
760 /* search this chunk */ 760 /* search this chunk */
761 for (entry=0; entry < chunk /4; entry++, lb_num++) { 761 for (entry=0; entry < chunk /4; entry++, lb_num++) {
762 udf_rw32_lbmap = *((uint32_t *) (blob + entry * 4)); 762 udf_rw32_lbmap = *((uint32_t *) (blob + entry * 4));
763 lb_map = udf_rw32(udf_rw32_lbmap); 763 lb_map = udf_rw32(udf_rw32_lbmap);
764 if (lb_map == 0xffffffff) { 764 if (lb_map == 0xffffffff) {
765 found = 1; 765 found = 1;
766 break; 766 break;
767 } 767 }
768 } 768 }
769 } while (!found); 769 } while (!found);
770 if (error) { 770 if (error) {
771 printf("udf_search_free_vatloc: error reading in vat chunk " 771 printf("udf_search_free_vatloc: error reading in vat chunk "
772 "(lb %d, size %d)\n", lb_num, chunk); 772 "(lb %d, size %d)\n", lb_num, chunk);
773 } 773 }
774 774
775 if (!found) { 775 if (!found) {
776 /* extend VAT */ 776 /* extend VAT */
777 DPRINTF(WRITE, ("udf_search_free_vatloc: extending\n")); 777 DPRINTF(WRITE, ("udf_search_free_vatloc: extending\n"));
778 lb_num = ump->vat_entries; 778 lb_num = ump->vat_entries;
779 ump->vat_entries++; 779 ump->vat_entries++;
780 } 780 }
781 781
782 /* mark entry with initialiser just in case */ 782 /* mark entry with initialiser just in case */
783 lb_map = udf_rw32(0xfffffffe); 783 lb_map = udf_rw32(0xfffffffe);
784 udf_vat_write(ump->vat_node, (uint8_t *) &lb_map, 4, 784 udf_vat_write(ump->vat_node, (uint8_t *) &lb_map, 4,
785 ump->vat_offset + lb_num *4); 785 ump->vat_offset + lb_num *4);
786 ump->vat_last_free_lb = lb_num; 786 ump->vat_last_free_lb = lb_num;
787 787
788 free(blob, M_UDFTEMP); 788 free(blob, M_UDFTEMP);
789 *lbnumres = lb_num; 789 *lbnumres = lb_num;
790 return 0; 790 return 0;
791} 791}
792 792
793 793
794static void 794static void
795udf_bitmap_allocate(struct udf_bitmap *bitmap, int ismetadata, 795udf_bitmap_allocate(struct udf_bitmap *bitmap, int ismetadata,
796 uint32_t *num_lb, uint64_t *lmappos) 796 uint32_t *num_lb, uint64_t *lmappos)
797{ 797{
798 uint32_t offset, lb_num, bit; 798 uint32_t offset, lb_num, bit;
799 int32_t diff; 799 int32_t diff;
800 uint8_t *bpos; 800 uint8_t *bpos;
801 int pass; 801 int pass;
802 802
803 if (!ismetadata) { 803 if (!ismetadata) {
804 /* heuristic to keep the two pointers not too close */ 804 /* heuristic to keep the two pointers not too close */
805 diff = bitmap->data_pos - bitmap->metadata_pos; 805 diff = bitmap->data_pos - bitmap->metadata_pos;
806 if ((diff >= 0) && (diff < 1024)) 806 if ((diff >= 0) && (diff < 1024))
807 bitmap->data_pos = bitmap->metadata_pos + 1024; 807 bitmap->data_pos = bitmap->metadata_pos + 1024;
808 } 808 }
809 offset = ismetadata ? bitmap->metadata_pos : bitmap->data_pos; 809 offset = ismetadata ? bitmap->metadata_pos : bitmap->data_pos;
810 offset &= ~7; 810 offset &= ~7;
811 for (pass = 0; pass < 2; pass++) { 811 for (pass = 0; pass < 2; pass++) {
812 if (offset >= bitmap->max_offset) 812 if (offset >= bitmap->max_offset)
813 offset = 0; 813 offset = 0;
814 814
815 while (offset < bitmap->max_offset) { 815 while (offset < bitmap->max_offset) {
816 if (*num_lb == 0) 816 if (*num_lb == 0)
817 break; 817 break;
818 818
819 /* use first bit not set */ 819 /* use first bit not set */
820 bpos = bitmap->bits + offset/8; 820 bpos = bitmap->bits + offset/8;
821 bit = ffs(*bpos); /* returns 0 or 1..8 */ 821 bit = ffs(*bpos); /* returns 0 or 1..8 */
822 if (bit == 0) { 822 if (bit == 0) {
823 offset += 8; 823 offset += 8;
824 continue; 824 continue;
825 } 825 }
826 826
827 /* check for ffs overshoot */ 827 /* check for ffs overshoot */
828 if (offset + bit-1 >= bitmap->max_offset) { 828 if (offset + bit-1 >= bitmap->max_offset) {
829 offset = bitmap->max_offset; 829 offset = bitmap->max_offset;
830 break; 830 break;
831 } 831 }
832 832
833 DPRINTF(PARANOIA, ("XXX : allocate %d, %p, bit %d\n", 833 DPRINTF(PARANOIA, ("XXX : allocate %d, %p, bit %d\n",
834 offset + bit -1, bpos, bit-1)); 834 offset + bit -1, bpos, bit-1));
835 *bpos &= ~(1 << (bit-1)); 835 *bpos &= ~(1 << (bit-1));
836 lb_num = offset + bit-1; 836 lb_num = offset + bit-1;
837 *lmappos++ = lb_num; 837 *lmappos++ = lb_num;
838 *num_lb = *num_lb - 1; 838 *num_lb = *num_lb - 1;
839 // offset = (offset & ~7); 839 // offset = (offset & ~7);
840 } 840 }
841 } 841 }
842 842
843 if (ismetadata) { 843 if (ismetadata) {
844 bitmap->metadata_pos = offset; 844 bitmap->metadata_pos = offset;
845 } else { 845 } else {
846 bitmap->data_pos = offset; 846 bitmap->data_pos = offset;
847 } 847 }
848} 848}
849 849
850 850
851static void 851static void
852udf_bitmap_free(struct udf_bitmap *bitmap, uint32_t lb_num, uint32_t num_lb) 852udf_bitmap_free(struct udf_bitmap *bitmap, uint32_t lb_num, uint32_t num_lb)
853{ 853{
854 uint32_t offset; 854 uint32_t offset;
855 uint32_t bit, bitval; 855 uint32_t bit, bitval;
856 uint8_t *bpos; 856 uint8_t *bpos;
857 857
858 offset = lb_num; 858 offset = lb_num;
859 859
860 /* starter bits */ 860 /* starter bits */
861 bpos = bitmap->bits + offset/8; 861 bpos = bitmap->bits + offset/8;
862 bit = offset % 8; 862 bit = offset % 8;
863 while ((bit != 0) && (num_lb > 0)) { 863 while ((bit != 0) && (num_lb > 0)) {
864 bitval = (1 << bit); 864 bitval = (1 << bit);
865 KASSERT((*bpos & bitval) == 0); 865 KASSERT((*bpos & bitval) == 0);
866 DPRINTF(PARANOIA, ("XXX : free %d, %p, %d\n", 866 DPRINTF(PARANOIA, ("XXX : free %d, %p, %d\n",
867 offset, bpos, bit)); 867 offset, bpos, bit));
868 *bpos |= bitval; 868 *bpos |= bitval;
869 offset++; num_lb--; 869 offset++; num_lb--;
870 bit = (bit + 1) % 8; 870 bit = (bit + 1) % 8;
871 } 871 }
872 if (num_lb == 0) 872 if (num_lb == 0)
873 return; 873 return;
874 874
875 /* whole bytes */ 875 /* whole bytes */
876 KASSERT(bit == 0); 876 KASSERT(bit == 0);
877 bpos = bitmap->bits + offset / 8; 877 bpos = bitmap->bits + offset / 8;
878 while (num_lb >= 8) { 878 while (num_lb >= 8) {
879 KASSERT((*bpos == 0)); 879 KASSERT((*bpos == 0));
880 DPRINTF(PARANOIA, ("XXX : free %d + 8, %p\n", offset, bpos)); 880 DPRINTF(PARANOIA, ("XXX : free %d + 8, %p\n", offset, bpos));
881 *bpos = 255; 881 *bpos = 255;
882 offset += 8; num_lb -= 8; 882 offset += 8; num_lb -= 8;
883 bpos++; 883 bpos++;
884 } 884 }
885 885
886 /* stop bits */ 886 /* stop bits */
887 KASSERT(num_lb < 8); 887 KASSERT(num_lb < 8);
888 bit = 0; 888 bit = 0;
889 while (num_lb > 0) { 889 while (num_lb > 0) {
890 bitval = (1 << bit); 890 bitval = (1 << bit);
891 KASSERT((*bpos & bitval) == 0); 891 KASSERT((*bpos & bitval) == 0);
892 DPRINTF(PARANOIA, ("XXX : free %d, %p, %d\n", 892 DPRINTF(PARANOIA, ("XXX : free %d, %p, %d\n",
893 offset, bpos, bit)); 893 offset, bpos, bit));
894 *bpos |= bitval; 894 *bpos |= bitval;
895 offset++; num_lb--; 895 offset++; num_lb--;
896 bit = (bit + 1) % 8; 896 bit = (bit + 1) % 8;
897 } 897 }
898} 898}
899 899
900 900
901/* allocate a contiguous sequence of sectornumbers */ 901/* allocate a contiguous sequence of sectornumbers */
902static int 902static int
903udf_allocate_space(struct udf_mount *ump, int udf_c_type, 903udf_allocate_space(struct udf_mount *ump, int udf_c_type,
904 uint16_t vpart_num, uint32_t num_lb, uint64_t *lmapping) 904 uint16_t vpart_num, uint32_t num_lb, uint64_t *lmapping)
905{ 905{
906 struct mmc_trackinfo *alloc_track, *other_track; 906 struct mmc_trackinfo *alloc_track, *other_track;
907 struct udf_bitmap *bitmap; 907 struct udf_bitmap *bitmap;
908 struct part_desc *pdesc; 908 struct part_desc *pdesc;
909 struct logvol_int_desc *lvid; 909 struct logvol_int_desc *lvid;
910 uint64_t *lmappos; 910 uint64_t *lmappos;
911 uint32_t ptov, lb_num, *freepos, free_lbs; 911 uint32_t ptov, lb_num, *freepos, free_lbs;
912 int lb_size, alloc_num_lb; 912 int lb_size, alloc_num_lb;
913 int alloc_type, error; 913 int alloc_type, error;
914 int is_node; 914 int is_node;
915 915
916 DPRINTF(CALL, ("udf_allocate_space(ctype %d, vpart %d, num_lb %d\n", 916 DPRINTF(CALL, ("udf_allocate_space(ctype %d, vpart %d, num_lb %d\n",
917 udf_c_type, vpart_num, num_lb)); 917 udf_c_type, vpart_num, num_lb));
918 mutex_enter(&ump->allocate_mutex); 918 mutex_enter(&ump->allocate_mutex);
919 919
920 lb_size = udf_rw32(ump->logical_vol->lb_size); 920 lb_size = udf_rw32(ump->logical_vol->lb_size);
921 KASSERT(lb_size == ump->discinfo.sector_size); 921 KASSERT(lb_size == ump->discinfo.sector_size);
922 922
923 /* XXX TODO check disc space */ 923 /* XXX TODO check disc space */
924 924
925 alloc_type = ump->vtop_alloc[vpart_num]; 925 alloc_type = ump->vtop_alloc[vpart_num];
926 is_node = (udf_c_type == UDF_C_NODE); 926 is_node = (udf_c_type == UDF_C_NODE);
927 927
928 lmappos = lmapping; 928 lmappos = lmapping;
929 error = 0; 929 error = 0;
930 switch (alloc_type) { 930 switch (alloc_type) {
931 case UDF_ALLOC_VAT : 931 case UDF_ALLOC_VAT :
932 /* search empty slot in VAT file */ 932 /* search empty slot in VAT file */
933 KASSERT(num_lb == 1); 933 KASSERT(num_lb == 1);
934 error = udf_search_free_vatloc(ump, &lb_num); 934 error = udf_search_free_vatloc(ump, &lb_num);
935 if (!error) 935 if (!error)
936 *lmappos = lb_num; 936 *lmappos = lb_num;
937 break; 937 break;
938 case UDF_ALLOC_SEQUENTIAL : 938 case UDF_ALLOC_SEQUENTIAL :
939 /* sequential allocation on recordable media */ 939 /* sequential allocation on recordable media */
940 /* get partition backing up this vpart_num_num */ 940 /* get partition backing up this vpart_num_num */
941 pdesc = ump->partitions[ump->vtop[vpart_num]]; 941 pdesc = ump->partitions[ump->vtop[vpart_num]];
942 942
943 /* calculate offset from physical base partition */ 943 /* calculate offset from physical base partition */
944 ptov = udf_rw32(pdesc->start_loc); 944 ptov = udf_rw32(pdesc->start_loc);
945 945
946 /* get our track descriptors */ 946 /* get our track descriptors */
947 if (vpart_num == ump->node_part) { 947 if (vpart_num == ump->node_part) {
948 alloc_track = &ump->metadata_track; 948 alloc_track = &ump->metadata_track;
949 other_track = &ump->data_track; 949 other_track = &ump->data_track;
950 } else { 950 } else {
951 alloc_track = &ump->data_track; 951 alloc_track = &ump->data_track;
952 other_track = &ump->metadata_track; 952 other_track = &ump->metadata_track;
953 } 953 }
954 954
955 /* allocate */ 955 /* allocate */
956 for (lb_num = 0; lb_num < num_lb; lb_num++) { 956 for (lb_num = 0; lb_num < num_lb; lb_num++) {
957 *lmappos++ = alloc_track->next_writable - ptov; 957 *lmappos++ = alloc_track->next_writable - ptov;
958 alloc_track->next_writable++; 958 alloc_track->next_writable++;
959 alloc_track->free_blocks--; 959 alloc_track->free_blocks--;
960 } 960 }
961 961
962 /* keep other track up-to-date */ 962 /* keep other track up-to-date */
963 if (alloc_track->tracknr == other_track->tracknr) 963 if (alloc_track->tracknr == other_track->tracknr)
964 memcpy(other_track, alloc_track, 964 memcpy(other_track, alloc_track,
965 sizeof(struct mmc_trackinfo)); 965 sizeof(struct mmc_trackinfo));
966 break; 966 break;
967 case UDF_ALLOC_SPACEMAP : 967 case UDF_ALLOC_SPACEMAP :
968 /* try to allocate on unallocated bits */ 968 /* try to allocate on unallocated bits */
969 alloc_num_lb = num_lb; 969 alloc_num_lb = num_lb;
970 bitmap = &ump->part_unalloc_bits[vpart_num]; 970 bitmap = &ump->part_unalloc_bits[vpart_num];
971 udf_bitmap_allocate(bitmap, is_node, &alloc_num_lb, lmappos); 971 udf_bitmap_allocate(bitmap, is_node, &alloc_num_lb, lmappos);
972 ump->lvclose |= UDF_WRITE_PART_BITMAPS; 972 ump->lvclose |= UDF_WRITE_PART_BITMAPS;
973 973
974 /* have we allocated all? */ 974 /* have we allocated all? */
975 if (alloc_num_lb) { 975 if (alloc_num_lb) {
976 /* TODO convert freed to unalloc and try again */ 976 /* TODO convert freed to unalloc and try again */
977 /* free allocated piece for now */ 977 /* free allocated piece for now */
978 lmappos = lmapping; 978 lmappos = lmapping;
979 for (lb_num=0; lb_num < num_lb-alloc_num_lb; lb_num++) { 979 for (lb_num=0; lb_num < num_lb-alloc_num_lb; lb_num++) {
980 udf_bitmap_free(bitmap, *lmappos++, 1); 980 udf_bitmap_free(bitmap, *lmappos++, 1);
981 } 981 }
982 error = ENOSPC; 982 error = ENOSPC;
983 } 983 }
984 if (!error) { 984 if (!error) {
985 /* adjust freecount */ 985 /* adjust freecount */
986 lvid = ump->logvol_integrity; 986 lvid = ump->logvol_integrity;
987 freepos = &lvid->tables[0] + vpart_num; 987 freepos = &lvid->tables[0] + vpart_num;
988 free_lbs = udf_rw32(*freepos); 988 free_lbs = udf_rw32(*freepos);
989 *freepos = udf_rw32(free_lbs - num_lb); 989 *freepos = udf_rw32(free_lbs - num_lb);
990 } 990 }
991 break; 991 break;
992 case UDF_ALLOC_METABITMAP : /* UDF 2.50, 2.60 BluRay-RE */ 992 case UDF_ALLOC_METABITMAP : /* UDF 2.50, 2.60 BluRay-RE */
993 /* allocate on metadata unallocated bits */ 993 /* allocate on metadata unallocated bits */
994 alloc_num_lb = num_lb; 994 alloc_num_lb = num_lb;
995 bitmap = &ump->metadata_unalloc_bits; 995 bitmap = &ump->metadata_unalloc_bits;
996 udf_bitmap_allocate(bitmap, is_node, &alloc_num_lb, lmappos); 996 udf_bitmap_allocate(bitmap, is_node, &alloc_num_lb, lmappos);
997 ump->lvclose |= UDF_WRITE_PART_BITMAPS; 997 ump->lvclose |= UDF_WRITE_PART_BITMAPS;
998 998
999 /* have we allocated all? */ 999 /* have we allocated all? */
1000 if (alloc_num_lb) { 1000 if (alloc_num_lb) {
1001 /* YIKES! TODO we need to extend the metadata partition */ 1001 /* YIKES! TODO we need to extend the metadata partition */
1002 /* free allocated piece for now */ 1002 /* free allocated piece for now */
1003 lmappos = lmapping; 1003 lmappos = lmapping;
1004 for (lb_num=0; lb_num < num_lb-alloc_num_lb; lb_num++) { 1004 for (lb_num=0; lb_num < num_lb-alloc_num_lb; lb_num++) {
1005 udf_bitmap_free(bitmap, *lmappos++, 1); 1005 udf_bitmap_free(bitmap, *lmappos++, 1);
1006 } 1006 }
1007 error = ENOSPC; 1007 error = ENOSPC;
1008 } 1008 }
1009 if (!error) { 1009 if (!error) {
1010 /* adjust freecount */ 1010 /* adjust freecount */
1011 lvid = ump->logvol_integrity; 1011 lvid = ump->logvol_integrity;
1012 freepos = &lvid->tables[0] + vpart_num; 1012 freepos = &lvid->tables[0] + vpart_num;
1013 free_lbs = udf_rw32(*freepos); 1013 free_lbs = udf_rw32(*freepos);
1014 *freepos = udf_rw32(free_lbs - num_lb); 1014 *freepos = udf_rw32(free_lbs - num_lb);
1015 } 1015 }
1016 break; 1016 break;
1017 case UDF_ALLOC_METASEQUENTIAL : /* UDF 2.60 BluRay-R */ 1017 case UDF_ALLOC_METASEQUENTIAL : /* UDF 2.60 BluRay-R */
1018 case UDF_ALLOC_RELAXEDSEQUENTIAL : /* UDF 2.50/~meta BluRay-R */ 1018 case UDF_ALLOC_RELAXEDSEQUENTIAL : /* UDF 2.50/~meta BluRay-R */
1019 printf("ALERT: udf_allocate_space : allocation %d " 1019 printf("ALERT: udf_allocate_space : allocation %d "
1020 "not implemented yet!\n", alloc_type); 1020 "not implemented yet!\n", alloc_type);
1021 /* TODO implement, doesn't have to be contiguous */ 1021 /* TODO implement, doesn't have to be contiguous */
1022 error = ENOSPC; 1022 error = ENOSPC;
1023 break; 1023 break;
1024 } 1024 }
1025 1025
1026#ifdef DEBUG 1026#ifdef DEBUG
1027 if (udf_verbose & UDF_DEBUG_ALLOC) { 1027 if (udf_verbose & UDF_DEBUG_ALLOC) {
1028 lmappos = lmapping; 1028 lmappos = lmapping;
1029 printf("udf_allocate_space, allocated logical lba :\n"); 1029 printf("udf_allocate_space, allocated logical lba :\n");
1030 for (lb_num = 0; lb_num < num_lb; lb_num++) { 1030 for (lb_num = 0; lb_num < num_lb; lb_num++) {
1031 printf("%s %"PRIu64",", (lb_num > 0)?",":"",  1031 printf("%s %"PRIu64, (lb_num > 0)?",":"",
1032 *lmappos++); 1032 *lmappos++);
1033 } 1033 }
1034 printf("\n"); 1034 printf("\n");
1035 } 1035 }
1036#endif 1036#endif
1037 mutex_exit(&ump->allocate_mutex); 1037 mutex_exit(&ump->allocate_mutex);
1038 1038
1039 return error; 1039 return error;
1040} 1040}
1041 1041
1042/* --------------------------------------------------------------------- */ 1042/* --------------------------------------------------------------------- */
1043 1043
1044void 1044void
1045udf_free_allocated_space(struct udf_mount *ump, uint32_t lb_num, 1045udf_free_allocated_space(struct udf_mount *ump, uint32_t lb_num,
1046 uint16_t vpart_num, uint32_t num_lb) 1046 uint16_t vpart_num, uint32_t num_lb)
1047{ 1047{
1048 struct udf_bitmap *bitmap; 1048 struct udf_bitmap *bitmap;
1049 struct part_desc *pdesc; 1049 struct part_desc *pdesc;
1050 struct logvol_int_desc *lvid; 1050 struct logvol_int_desc *lvid;
1051 uint32_t ptov, lb_map, udf_rw32_lbmap; 1051 uint32_t ptov, lb_map, udf_rw32_lbmap;
1052 uint32_t *freepos, free_lbs; 1052 uint32_t *freepos, free_lbs;
1053 int phys_part; 1053 int phys_part;
1054 int error; 1054 int error;
1055 1055
1056 DPRINTF(ALLOC, ("udf_free_allocated_space: freeing virt lbnum %d " 1056 DPRINTF(ALLOC, ("udf_free_allocated_space: freeing virt lbnum %d "
1057 "part %d + %d sect\n", lb_num, vpart_num, num_lb)); 1057 "part %d + %d sect\n", lb_num, vpart_num, num_lb));
1058 1058
1059 /* no use freeing zero length */ 1059 /* no use freeing zero length */
1060 if (num_lb == 0) 1060 if (num_lb == 0)
1061 return; 1061 return;
1062 1062
1063 mutex_enter(&ump->allocate_mutex); 1063 mutex_enter(&ump->allocate_mutex);
1064 1064
1065 /* get partition backing up this vpart_num */ 1065 /* get partition backing up this vpart_num */
1066 pdesc = ump->partitions[ump->vtop[vpart_num]]; 1066 pdesc = ump->partitions[ump->vtop[vpart_num]];
1067 1067
1068 switch (ump->vtop_tp[vpart_num]) { 1068 switch (ump->vtop_tp[vpart_num]) {
1069 case UDF_VTOP_TYPE_PHYS : 1069 case UDF_VTOP_TYPE_PHYS :
1070 case UDF_VTOP_TYPE_SPARABLE : 1070 case UDF_VTOP_TYPE_SPARABLE :
1071 /* free space to freed or unallocated space bitmap */ 1071 /* free space to freed or unallocated space bitmap */
1072 ptov = udf_rw32(pdesc->start_loc); 1072 ptov = udf_rw32(pdesc->start_loc);
1073 phys_part = ump->vtop[vpart_num]; 1073 phys_part = ump->vtop[vpart_num];
1074 1074
1075 /* first try freed space bitmap */ 1075 /* first try freed space bitmap */
1076 bitmap = &ump->part_freed_bits[phys_part]; 1076 bitmap = &ump->part_freed_bits[phys_part];
1077 1077
1078 /* if not defined, use unallocated bitmap */ 1078 /* if not defined, use unallocated bitmap */
1079 if (bitmap->bits == NULL) 1079 if (bitmap->bits == NULL)
1080 bitmap = &ump->part_unalloc_bits[phys_part]; 1080 bitmap = &ump->part_unalloc_bits[phys_part];
1081 1081
1082 /* if no bitmaps are defined, bail out; XXX OK? */ 1082 /* if no bitmaps are defined, bail out; XXX OK? */
1083 if (bitmap->bits == NULL) 1083 if (bitmap->bits == NULL)
1084 break; 1084 break;
1085 1085
1086 /* free bits if its defined */ 1086 /* free bits if its defined */
1087 KASSERT(bitmap->bits); 1087 KASSERT(bitmap->bits);
1088 ump->lvclose |= UDF_WRITE_PART_BITMAPS; 1088 ump->lvclose |= UDF_WRITE_PART_BITMAPS;
1089 udf_bitmap_free(bitmap, lb_num, num_lb); 1089 udf_bitmap_free(bitmap, lb_num, num_lb);
1090 1090
1091 /* adjust freecount */ 1091 /* adjust freecount */
1092 lvid = ump->logvol_integrity; 1092 lvid = ump->logvol_integrity;
1093 freepos = &lvid->tables[0] + vpart_num; 1093 freepos = &lvid->tables[0] + vpart_num;
1094 free_lbs = udf_rw32(*freepos); 1094 free_lbs = udf_rw32(*freepos);
1095 *freepos = udf_rw32(free_lbs + num_lb); 1095 *freepos = udf_rw32(free_lbs + num_lb);
1096 break; 1096 break;
1097 case UDF_VTOP_TYPE_VIRT : 1097 case UDF_VTOP_TYPE_VIRT :
1098 /* free this VAT entry */ 1098 /* free this VAT entry */
1099 KASSERT(num_lb == 1); 1099 KASSERT(num_lb == 1);
1100 1100
1101 lb_map = 0xffffffff; 1101 lb_map = 0xffffffff;
1102 udf_rw32_lbmap = udf_rw32(lb_map); 1102 udf_rw32_lbmap = udf_rw32(lb_map);
1103 error = udf_vat_write(ump->vat_node, 1103 error = udf_vat_write(ump->vat_node,
1104 (uint8_t *) &udf_rw32_lbmap, 4, 1104 (uint8_t *) &udf_rw32_lbmap, 4,
1105 ump->vat_offset + lb_num * 4); 1105 ump->vat_offset + lb_num * 4);
1106 KASSERT(error == 0); 1106 KASSERT(error == 0);
1107 ump->vat_last_free_lb = MIN(ump->vat_last_free_lb, lb_num); 1107 ump->vat_last_free_lb = MIN(ump->vat_last_free_lb, lb_num);
1108 break; 1108 break;
1109 case UDF_VTOP_TYPE_META : 1109 case UDF_VTOP_TYPE_META :
1110 /* free space in the metadata bitmap */ 1110 /* free space in the metadata bitmap */
1111 bitmap = &ump->metadata_unalloc_bits; 1111 bitmap = &ump->metadata_unalloc_bits;
1112 KASSERT(bitmap->bits); 1112 KASSERT(bitmap->bits);
1113 1113
1114 ump->lvclose |= UDF_WRITE_PART_BITMAPS; 1114 ump->lvclose |= UDF_WRITE_PART_BITMAPS;
1115 udf_bitmap_free(bitmap, lb_num, num_lb); 1115 udf_bitmap_free(bitmap, lb_num, num_lb);
1116 1116
1117 /* adjust freecount */ 1117 /* adjust freecount */
1118 lvid = ump->logvol_integrity; 1118 lvid = ump->logvol_integrity;
1119 freepos = &lvid->tables[0] + vpart_num; 1119 freepos = &lvid->tables[0] + vpart_num;
1120 free_lbs = udf_rw32(*freepos); 1120 free_lbs = udf_rw32(*freepos);
1121 *freepos = udf_rw32(free_lbs + num_lb); 1121 *freepos = udf_rw32(free_lbs + num_lb);
1122 break; 1122 break;
1123 default: 1123 default:
1124 printf("ALERT: udf_free_allocated_space : allocation %d " 1124 printf("ALERT: udf_free_allocated_space : allocation %d "
1125 "not implemented yet!\n", ump->vtop_tp[vpart_num]); 1125 "not implemented yet!\n", ump->vtop_tp[vpart_num]);
1126 break; 1126 break;
1127 } 1127 }
1128 1128
1129 mutex_exit(&ump->allocate_mutex); 1129 mutex_exit(&ump->allocate_mutex);
1130} 1130}
1131 1131
1132/* --------------------------------------------------------------------- */ 1132/* --------------------------------------------------------------------- */
1133 1133
1134int 1134int
1135udf_pre_allocate_space(struct udf_mount *ump, int udf_c_type, 1135udf_pre_allocate_space(struct udf_mount *ump, int udf_c_type,
1136 uint32_t num_lb, uint16_t vpartnr, uint64_t *lmapping) 1136 uint32_t num_lb, uint16_t vpartnr, uint64_t *lmapping)
1137{ 1137{
1138 /* TODO properly maintain uncomitted_lb per partition */ 1138 /* TODO properly maintain uncomitted_lb per partition */
1139 1139
1140 /* reserve size for VAT allocated data */ 1140 /* reserve size for VAT allocated data */
1141 if (ump->vtop_alloc[vpartnr] == UDF_ALLOC_VAT) { 1141 if (ump->vtop_alloc[vpartnr] == UDF_ALLOC_VAT) {
1142 mutex_enter(&ump->allocate_mutex); 1142 mutex_enter(&ump->allocate_mutex);
1143 ump->uncomitted_lb += num_lb; 1143 ump->uncomitted_lb += num_lb;
1144 mutex_exit(&ump->allocate_mutex); 1144 mutex_exit(&ump->allocate_mutex);
1145 } 1145 }
1146 1146
1147 return udf_allocate_space(ump, udf_c_type, vpartnr, num_lb, lmapping); 1147 return udf_allocate_space(ump, udf_c_type, vpartnr, num_lb, lmapping);
1148} 1148}
1149 1149
1150/* --------------------------------------------------------------------- */ 1150/* --------------------------------------------------------------------- */
1151 1151
1152/* 1152/*
1153 * Allocate a buf on disc for direct write out. The space doesn't have to be 1153 * Allocate a buf on disc for direct write out. The space doesn't have to be
1154 * contiguous as the caller takes care of this. 1154 * contiguous as the caller takes care of this.
1155 */ 1155 */
1156 1156
1157void 1157void
1158udf_late_allocate_buf(struct udf_mount *ump, struct buf *buf, 1158udf_late_allocate_buf(struct udf_mount *ump, struct buf *buf,
1159 uint64_t *lmapping, struct long_ad *node_ad_cpy, uint16_t *vpart_nump) 1159 uint64_t *lmapping, struct long_ad *node_ad_cpy, uint16_t *vpart_nump)
1160{ 1160{
1161 struct udf_node *udf_node = VTOI(buf->b_vp); 1161 struct udf_node *udf_node = VTOI(buf->b_vp);
1162 int lb_size, blks, udf_c_type; 1162 int lb_size, blks, udf_c_type;
1163 int vpart_num, num_lb; 1163 int vpart_num, num_lb;
1164 int error, s; 1164 int error, s;
1165 1165
1166 /* 1166 /*
1167 * for each sector in the buf, allocate a sector on disc and record 1167 * for each sector in the buf, allocate a sector on disc and record
1168 * its position in the provided mapping array. 1168 * its position in the provided mapping array.
1169 * 1169 *
1170 * If its userdata or FIDs, record its location in its node. 1170 * If its userdata or FIDs, record its location in its node.
1171 */ 1171 */
1172 1172
1173 lb_size = udf_rw32(ump->logical_vol->lb_size); 1173 lb_size = udf_rw32(ump->logical_vol->lb_size);
1174 num_lb = (buf->b_bcount + lb_size -1) / lb_size; 1174 num_lb = (buf->b_bcount + lb_size -1) / lb_size;
1175 blks = lb_size / DEV_BSIZE; 1175 blks = lb_size / DEV_BSIZE;
1176 udf_c_type = buf->b_udf_c_type; 1176 udf_c_type = buf->b_udf_c_type;
1177 1177
1178 KASSERT(lb_size == ump->discinfo.sector_size); 1178 KASSERT(lb_size == ump->discinfo.sector_size);
1179 1179
1180 /* select partition to record the buffer on */ 1180 /* select partition to record the buffer on */
1181 vpart_num = ump->data_part; 1181 vpart_num = ump->data_part;
1182 if (udf_c_type == UDF_C_NODE) 1182 if (udf_c_type == UDF_C_NODE)
1183 vpart_num = ump->node_part; 1183 vpart_num = ump->node_part;
1184 if (udf_c_type == UDF_C_FIDS) 1184 if (udf_c_type == UDF_C_FIDS)
1185 vpart_num = ump->fids_part; 1185 vpart_num = ump->fids_part;
1186 *vpart_nump = vpart_num; 1186 *vpart_nump = vpart_num;
1187 1187
1188 if (udf_c_type == UDF_C_NODE) { 1188 if (udf_c_type == UDF_C_NODE) {
1189 /* if not VAT, its allready allocated */ 1189 /* if not VAT, its allready allocated */
1190 if (ump->vtop_alloc[ump->node_part] != UDF_ALLOC_VAT) 1190 if (ump->vtop_alloc[ump->node_part] != UDF_ALLOC_VAT)
1191 return; 1191 return;
1192 1192
1193 /* allocate on its backing sequential partition */ 1193 /* allocate on its backing sequential partition */
1194 vpart_num = ump->data_part; 1194 vpart_num = ump->data_part;
1195 } 1195 }
1196 1196
1197 /* do allocation on the selected partition */ 1197 /* do allocation on the selected partition */
1198 error = udf_allocate_space(ump, udf_c_type, 1198 error = udf_allocate_space(ump, udf_c_type,
1199 vpart_num, num_lb, lmapping); 1199 vpart_num, num_lb, lmapping);
1200 if (error) { 1200 if (error) {
1201 /* ARGH! we've not done our accounting right! */ 1201 /* ARGH! we've not done our accounting right! */
1202 panic("UDF disc allocation accounting gone wrong"); 1202 panic("UDF disc allocation accounting gone wrong");
1203 } 1203 }
1204 1204
1205 /* commit our sector count */ 1205 /* commit our sector count */
1206 mutex_enter(&ump->allocate_mutex); 1206 mutex_enter(&ump->allocate_mutex);
1207 if (num_lb > ump->uncomitted_lb) { 1207 if (num_lb > ump->uncomitted_lb) {
1208 ump->uncomitted_lb = 0; 1208 ump->uncomitted_lb = 0;
1209 } else { 1209 } else {
1210 ump->uncomitted_lb -= num_lb; 1210 ump->uncomitted_lb -= num_lb;
1211 } 1211 }
1212 mutex_exit(&ump->allocate_mutex); 1212 mutex_exit(&ump->allocate_mutex);
1213 1213
1214 /* If its userdata or FIDs, record its allocation in its node. */ 1214 /* If its userdata or FIDs, record its allocation in its node. */
1215 if ((udf_c_type == UDF_C_USERDATA) || 1215 if ((udf_c_type == UDF_C_USERDATA) ||
1216 (udf_c_type == UDF_C_FIDS) || 1216 (udf_c_type == UDF_C_FIDS) ||
1217 (udf_c_type == UDF_C_METADATA_SBM)) 1217 (udf_c_type == UDF_C_METADATA_SBM))
1218 { 1218 {
1219 udf_record_allocation_in_node(ump, buf, vpart_num, lmapping, 1219 udf_record_allocation_in_node(ump, buf, vpart_num, lmapping,
1220 node_ad_cpy); 1220 node_ad_cpy);
1221 /* decrement our outstanding bufs counter */ 1221 /* decrement our outstanding bufs counter */
1222 s = splbio(); 1222 s = splbio();
1223 udf_node->outstanding_bufs--; 1223 udf_node->outstanding_bufs--;
1224 splx(s); 1224 splx(s);
1225 } 1225 }
1226} 1226}
1227 1227
1228/* --------------------------------------------------------------------- */ 1228/* --------------------------------------------------------------------- */
1229 1229
1230/* 1230/*
1231 * Try to merge a1 with the new piece a2. udf_ads_merge returns error when not 1231 * Try to merge a1 with the new piece a2. udf_ads_merge returns error when not
1232 * possible (anymore); a2 returns the rest piece. 1232 * possible (anymore); a2 returns the rest piece.
1233 */ 1233 */
1234 1234
1235static int 1235static int
1236udf_ads_merge(uint32_t lb_size, struct long_ad *a1, struct long_ad *a2) 1236udf_ads_merge(uint32_t lb_size, struct long_ad *a1, struct long_ad *a2)
1237{ 1237{
1238 uint32_t max_len, merge_len; 1238 uint32_t max_len, merge_len;
1239 uint32_t a1_len, a2_len; 1239 uint32_t a1_len, a2_len;
1240 uint32_t a1_flags, a2_flags; 1240 uint32_t a1_flags, a2_flags;
1241 uint32_t a1_lbnum, a2_lbnum; 1241 uint32_t a1_lbnum, a2_lbnum;
1242 uint16_t a1_part, a2_part; 1242 uint16_t a1_part, a2_part;
1243 1243
1244 max_len = ((UDF_EXT_MAXLEN / lb_size) * lb_size); 1244 max_len = ((UDF_EXT_MAXLEN / lb_size) * lb_size);
1245 1245
1246 a1_flags = UDF_EXT_FLAGS(udf_rw32(a1->len)); 1246 a1_flags = UDF_EXT_FLAGS(udf_rw32(a1->len));
1247 a1_len = UDF_EXT_LEN(udf_rw32(a1->len)); 1247 a1_len = UDF_EXT_LEN(udf_rw32(a1->len));
1248 a1_lbnum = udf_rw32(a1->loc.lb_num); 1248 a1_lbnum = udf_rw32(a1->loc.lb_num);
1249 a1_part = udf_rw16(a1->loc.part_num); 1249 a1_part = udf_rw16(a1->loc.part_num);
1250 1250
1251 a2_flags = UDF_EXT_FLAGS(udf_rw32(a2->len)); 1251 a2_flags = UDF_EXT_FLAGS(udf_rw32(a2->len));
1252 a2_len = UDF_EXT_LEN(udf_rw32(a2->len)); 1252 a2_len = UDF_EXT_LEN(udf_rw32(a2->len));
1253 a2_lbnum = udf_rw32(a2->loc.lb_num); 1253 a2_lbnum = udf_rw32(a2->loc.lb_num);
1254 a2_part = udf_rw16(a2->loc.part_num); 1254 a2_part = udf_rw16(a2->loc.part_num);
1255 1255
1256 /* defines same space */ 1256 /* defines same space */
1257 if (a1_flags != a2_flags) 1257 if (a1_flags != a2_flags)
1258 return 1; 1258 return 1;
1259 1259
1260 if (a1_flags != UDF_EXT_FREE) { 1260 if (a1_flags != UDF_EXT_FREE) {
1261 /* the same partition */ 1261 /* the same partition */
1262 if (a1_part != a2_part) 1262 if (a1_part != a2_part)
1263 return 1; 1263 return 1;
1264 1264
1265 /* a2 is successor of a1 */ 1265 /* a2 is successor of a1 */
1266 if (a1_lbnum * lb_size + a1_len != a2_lbnum * lb_size) 1266 if (a1_lbnum * lb_size + a1_len != a2_lbnum * lb_size)
1267 return 1; 1267 return 1;
1268 } 1268 }
1269 1269
1270 /* merge as most from a2 if possible */ 1270 /* merge as most from a2 if possible */
1271 merge_len = MIN(a2_len, max_len - a1_len); 1271 merge_len = MIN(a2_len, max_len - a1_len);
1272 a1_len += merge_len; 1272 a1_len += merge_len;
1273 a2_len -= merge_len; 1273 a2_len -= merge_len;
1274 a2_lbnum += merge_len/lb_size; 1274 a2_lbnum += merge_len/lb_size;
1275 1275
1276 a1->len = udf_rw32(a1_len | a1_flags); 1276 a1->len = udf_rw32(a1_len | a1_flags);
1277 a2->len = udf_rw32(a2_len | a2_flags); 1277 a2->len = udf_rw32(a2_len | a2_flags);
1278 a2->loc.lb_num = udf_rw32(a2_lbnum); 1278 a2->loc.lb_num = udf_rw32(a2_lbnum);
1279 1279
1280 if (a2_len > 0) 1280 if (a2_len > 0)
1281 return 1; 1281 return 1;
1282 1282
1283 /* there is space over to merge */ 1283 /* there is space over to merge */
1284 return 0; 1284 return 0;
1285} 1285}
1286 1286
1287/* --------------------------------------------------------------------- */ 1287/* --------------------------------------------------------------------- */
1288 1288
1289static void 1289static void
1290udf_wipe_adslots(struct udf_node *udf_node) 1290udf_wipe_adslots(struct udf_node *udf_node)
1291{ 1291{
1292 struct file_entry *fe; 1292 struct file_entry *fe;
1293 struct extfile_entry *efe; 1293 struct extfile_entry *efe;
1294 struct alloc_ext_entry *ext; 1294 struct alloc_ext_entry *ext;
1295 uint64_t inflen, objsize; 1295 uint64_t inflen, objsize;
1296 uint32_t lb_size, dscr_size, l_ea, l_ad, max_l_ad, crclen; 1296 uint32_t lb_size, dscr_size, l_ea, l_ad, max_l_ad, crclen;
1297 uint8_t *data_pos; 1297 uint8_t *data_pos;
1298 int extnr; 1298 int extnr;
1299 1299
1300 lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size); 1300 lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size);
1301 1301
1302 fe = udf_node->fe; 1302 fe = udf_node->fe;
1303 efe = udf_node->efe; 1303 efe = udf_node->efe;
1304 if (fe) { 1304 if (fe) {
1305 inflen = udf_rw64(fe->inf_len); 1305 inflen = udf_rw64(fe->inf_len);
1306 objsize = inflen; 1306 objsize = inflen;
1307 dscr_size = sizeof(struct file_entry) -1; 1307 dscr_size = sizeof(struct file_entry) -1;
1308 l_ea = udf_rw32(fe->l_ea); 1308 l_ea = udf_rw32(fe->l_ea);
1309 l_ad = udf_rw32(fe->l_ad); 1309 l_ad = udf_rw32(fe->l_ad);
1310 data_pos = (uint8_t *) fe + dscr_size + l_ea; 1310 data_pos = (uint8_t *) fe + dscr_size + l_ea;
1311 } else { 1311 } else {
1312 inflen = udf_rw64(efe->inf_len); 1312 inflen = udf_rw64(efe->inf_len);
1313 objsize = udf_rw64(efe->obj_size); 1313 objsize = udf_rw64(efe->obj_size);
1314 dscr_size = sizeof(struct extfile_entry) -1; 1314 dscr_size = sizeof(struct extfile_entry) -1;
1315 l_ea = udf_rw32(efe->l_ea); 1315 l_ea = udf_rw32(efe->l_ea);
1316 l_ad = udf_rw32(efe->l_ad); 1316 l_ad = udf_rw32(efe->l_ad);
1317 data_pos = (uint8_t *) efe + dscr_size + l_ea; 1317 data_pos = (uint8_t *) efe + dscr_size + l_ea;
1318 } 1318 }
1319 max_l_ad = lb_size - dscr_size - l_ea; 1319 max_l_ad = lb_size - dscr_size - l_ea;
1320 1320
1321 /* wipe fe/efe */ 1321 /* wipe fe/efe */
1322 memset(data_pos, 0, max_l_ad); 1322 memset(data_pos, 0, max_l_ad);
1323 crclen = dscr_size - UDF_DESC_TAG_LENGTH + l_ea; 1323 crclen = dscr_size - UDF_DESC_TAG_LENGTH + l_ea;
1324 if (fe) { 1324 if (fe) {
1325 fe->l_ad = udf_rw32(0); 1325 fe->l_ad = udf_rw32(0);
1326 fe->logblks_rec = udf_rw64(0); 1326 fe->logblks_rec = udf_rw64(0);
1327 fe->tag.desc_crc_len = udf_rw16(crclen); 1327 fe->tag.desc_crc_len = udf_rw16(crclen);
1328 } else { 1328 } else {
1329 efe->l_ad = udf_rw32(0); 1329 efe->l_ad = udf_rw32(0);
1330 efe->logblks_rec = udf_rw64(0); 1330 efe->logblks_rec = udf_rw64(0);
1331 efe->tag.desc_crc_len = udf_rw16(crclen); 1331 efe->tag.desc_crc_len = udf_rw16(crclen);
1332 } 1332 }
1333 1333
1334 /* wipe all allocation extent entries */ 1334 /* wipe all allocation extent entries */
1335 for (extnr = 0; extnr < udf_node->num_extensions; extnr++) { 1335 for (extnr = 0; extnr < udf_node->num_extensions; extnr++) {
1336 ext = udf_node->ext[extnr]; 1336 ext = udf_node->ext[extnr];
1337 dscr_size = sizeof(struct alloc_ext_entry) -1; 1337 dscr_size = sizeof(struct alloc_ext_entry) -1;
1338 data_pos = (uint8_t *) ext->data; 1338 data_pos = (uint8_t *) ext->data;
1339 max_l_ad = lb_size - dscr_size; 1339 max_l_ad = lb_size - dscr_size;
1340 memset(data_pos, 0, max_l_ad); 1340 memset(data_pos, 0, max_l_ad);
1341 ext->l_ad = udf_rw32(0); 1341 ext->l_ad = udf_rw32(0);
1342 1342
1343 crclen = dscr_size - UDF_DESC_TAG_LENGTH; 1343 crclen = dscr_size - UDF_DESC_TAG_LENGTH;
1344 ext->tag.desc_crc_len = udf_rw16(crclen); 1344 ext->tag.desc_crc_len = udf_rw16(crclen);
1345 } 1345 }
1346 udf_node->i_flags |= IN_NODE_REBUILD; 1346 udf_node->i_flags |= IN_NODE_REBUILD;
1347} 1347}
1348 1348
1349/* --------------------------------------------------------------------- */ 1349/* --------------------------------------------------------------------- */
1350 1350
1351void 1351void
1352udf_get_adslot(struct udf_node *udf_node, int slot, struct long_ad *icb, 1352udf_get_adslot(struct udf_node *udf_node, int slot, struct long_ad *icb,
1353 int *eof) { 1353 int *eof) {
1354 struct file_entry *fe; 1354 struct file_entry *fe;
1355 struct extfile_entry *efe; 1355 struct extfile_entry *efe;
1356 struct alloc_ext_entry *ext; 1356 struct alloc_ext_entry *ext;
1357 struct icb_tag *icbtag; 1357 struct icb_tag *icbtag;
1358 struct short_ad *short_ad; 1358 struct short_ad *short_ad;
1359 struct long_ad *long_ad, l_icb; 1359 struct long_ad *long_ad, l_icb;
1360 uint32_t offset; 1360 uint32_t offset;
1361 uint32_t lb_size, dscr_size, l_ea, l_ad, flags; 1361 uint32_t lb_size, dscr_size, l_ea, l_ad, flags;
1362 uint8_t *data_pos; 1362 uint8_t *data_pos;
1363 int icbflags, addr_type, adlen, extnr; 1363 int icbflags, addr_type, adlen, extnr;
1364 1364
1365 /* determine what descriptor we are in */ 1365 /* determine what descriptor we are in */
1366 lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size); 1366 lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size);
1367 1367
1368 fe = udf_node->fe; 1368 fe = udf_node->fe;
1369 efe = udf_node->efe; 1369 efe = udf_node->efe;
1370 if (fe) { 1370 if (fe) {
1371 icbtag = &fe->icbtag; 1371 icbtag = &fe->icbtag;
1372 dscr_size = sizeof(struct file_entry) -1; 1372 dscr_size = sizeof(struct file_entry) -1;
1373 l_ea = udf_rw32(fe->l_ea); 1373 l_ea = udf_rw32(fe->l_ea);
1374 l_ad = udf_rw32(fe->l_ad); 1374 l_ad = udf_rw32(fe->l_ad);
1375 data_pos = (uint8_t *) fe + dscr_size + l_ea; 1375 data_pos = (uint8_t *) fe + dscr_size + l_ea;
1376 } else { 1376 } else {
1377 icbtag = &efe->icbtag; 1377 icbtag = &efe->icbtag;
1378 dscr_size = sizeof(struct extfile_entry) -1; 1378 dscr_size = sizeof(struct extfile_entry) -1;
1379 l_ea = udf_rw32(efe->l_ea); 1379 l_ea = udf_rw32(efe->l_ea);
1380 l_ad = udf_rw32(efe->l_ad); 1380 l_ad = udf_rw32(efe->l_ad);
1381 data_pos = (uint8_t *) efe + dscr_size + l_ea; 1381 data_pos = (uint8_t *) efe + dscr_size + l_ea;
1382 } 1382 }
1383 1383
1384 icbflags = udf_rw16(icbtag->flags); 1384 icbflags = udf_rw16(icbtag->flags);
1385 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK; 1385 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK;
1386 1386
1387 /* just in case we're called on an intern, its EOF */ 1387 /* just in case we're called on an intern, its EOF */
1388 if (addr_type == UDF_ICB_INTERN_ALLOC) { 1388 if (addr_type == UDF_ICB_INTERN_ALLOC) {
1389 memset(icb, 0, sizeof(struct long_ad)); 1389 memset(icb, 0, sizeof(struct long_ad));
1390 *eof = 1; 1390 *eof = 1;
1391 return; 1391 return;
1392 } 1392 }
1393 1393
1394 adlen = 0; 1394 adlen = 0;
1395 if (addr_type == UDF_ICB_SHORT_ALLOC) { 1395 if (addr_type == UDF_ICB_SHORT_ALLOC) {
1396 adlen = sizeof(struct short_ad); 1396 adlen = sizeof(struct short_ad);
1397 } else if (addr_type == UDF_ICB_LONG_ALLOC) { 1397 } else if (addr_type == UDF_ICB_LONG_ALLOC) {
1398 adlen = sizeof(struct long_ad); 1398 adlen = sizeof(struct long_ad);
1399 } 1399 }
1400 1400
1401 /* if offset too big, we go to the allocation extensions */ 1401 /* if offset too big, we go to the allocation extensions */
1402 offset = slot * adlen; 1402 offset = slot * adlen;
1403 extnr = -1; 1403 extnr = -1;
1404 while (offset >= l_ad) { 1404 while (offset >= l_ad) {
1405 /* check if our last entry is a redirect */ 1405 /* check if our last entry is a redirect */
1406 if (addr_type == UDF_ICB_SHORT_ALLOC) { 1406 if (addr_type == UDF_ICB_SHORT_ALLOC) {
1407 short_ad = (struct short_ad *) (data_pos + l_ad-adlen); 1407 short_ad = (struct short_ad *) (data_pos + l_ad-adlen);
1408 l_icb.len = short_ad->len; 1408 l_icb.len = short_ad->len;
1409 l_icb.loc.part_num = udf_node->loc.loc.part_num; 1409 l_icb.loc.part_num = udf_node->loc.loc.part_num;
1410 l_icb.loc.lb_num = short_ad->lb_num; 1410 l_icb.loc.lb_num = short_ad->lb_num;
1411 } else { 1411 } else {
1412 KASSERT(addr_type == UDF_ICB_LONG_ALLOC); 1412 KASSERT(addr_type == UDF_ICB_LONG_ALLOC);
1413 long_ad = (struct long_ad *) (data_pos + l_ad-adlen); 1413 long_ad = (struct long_ad *) (data_pos + l_ad-adlen);
1414 l_icb = *long_ad; 1414 l_icb = *long_ad;
1415 } 1415 }
1416 flags = UDF_EXT_FLAGS(udf_rw32(l_icb.len)); 1416 flags = UDF_EXT_FLAGS(udf_rw32(l_icb.len));
1417 if (flags != UDF_EXT_REDIRECT) { 1417 if (flags != UDF_EXT_REDIRECT) {
1418 l_ad = 0; /* force EOF */ 1418 l_ad = 0; /* force EOF */
1419 break; 1419 break;
1420 } 1420 }
1421 1421
1422 /* advance to next extent */ 1422 /* advance to next extent */
1423 extnr++; 1423 extnr++;
1424 if (extnr >= udf_node->num_extensions) { 1424 if (extnr >= udf_node->num_extensions) {
1425 l_ad = 0; /* force EOF */ 1425 l_ad = 0; /* force EOF */
1426 break; 1426 break;
1427 } 1427 }
1428 offset = offset - l_ad; 1428 offset = offset - l_ad;
1429 ext = udf_node->ext[extnr]; 1429 ext = udf_node->ext[extnr];
1430 dscr_size = sizeof(struct alloc_ext_entry) -1; 1430 dscr_size = sizeof(struct alloc_ext_entry) -1;
1431 l_ad = udf_rw32(ext->l_ad); 1431 l_ad = udf_rw32(ext->l_ad);
1432 data_pos = (uint8_t *) ext + dscr_size; 1432 data_pos = (uint8_t *) ext + dscr_size;
1433 } 1433 }
1434 1434
1435 /* XXX l_ad == 0 should be enough to check */ 1435 /* XXX l_ad == 0 should be enough to check */
1436 *eof = (offset >= l_ad) || (l_ad == 0); 1436 *eof = (offset >= l_ad) || (l_ad == 0);
1437 if (*eof) { 1437 if (*eof) {
1438 DPRINTF(PARANOIDADWLK, ("returning EOF, extnr %d, offset %d, " 1438 DPRINTF(PARANOIDADWLK, ("returning EOF, extnr %d, offset %d, "
1439 "l_ad %d\n", extnr, offset, l_ad)); 1439 "l_ad %d\n", extnr, offset, l_ad));
1440 memset(icb, 0, sizeof(struct long_ad)); 1440 memset(icb, 0, sizeof(struct long_ad));
1441 return; 1441 return;
1442 } 1442 }
1443 1443
1444 /* get the element */ 1444 /* get the element */
1445 if (addr_type == UDF_ICB_SHORT_ALLOC) { 1445 if (addr_type == UDF_ICB_SHORT_ALLOC) {
1446 short_ad = (struct short_ad *) (data_pos + offset); 1446 short_ad = (struct short_ad *) (data_pos + offset);
1447 icb->len = short_ad->len; 1447 icb->len = short_ad->len;
1448 icb->loc.part_num = udf_node->loc.loc.part_num; 1448 icb->loc.part_num = udf_node->loc.loc.part_num;
1449 icb->loc.lb_num = short_ad->lb_num; 1449 icb->loc.lb_num = short_ad->lb_num;
1450 } else if (addr_type == UDF_ICB_LONG_ALLOC) { 1450 } else if (addr_type == UDF_ICB_LONG_ALLOC) {
1451 long_ad = (struct long_ad *) (data_pos + offset); 1451 long_ad = (struct long_ad *) (data_pos + offset);
1452 *icb = *long_ad; 1452 *icb = *long_ad;
1453 } 1453 }
1454 DPRINTF(PARANOIDADWLK, ("returning element : v %d, lb %d, len %d, " 1454 DPRINTF(PARANOIDADWLK, ("returning element : v %d, lb %d, len %d, "
1455 "flags %d\n", icb->loc.part_num, icb->loc.lb_num, 1455 "flags %d\n", icb->loc.part_num, icb->loc.lb_num,
1456 UDF_EXT_LEN(icb->len), UDF_EXT_FLAGS(icb->len))); 1456 UDF_EXT_LEN(icb->len), UDF_EXT_FLAGS(icb->len)));
1457} 1457}
1458 1458
1459/* --------------------------------------------------------------------- */ 1459/* --------------------------------------------------------------------- */
1460 1460
1461int 1461int
1462udf_append_adslot(struct udf_node *udf_node, int *slot, struct long_ad *icb) { 1462udf_append_adslot(struct udf_node *udf_node, int *slot, struct long_ad *icb) {
1463 struct udf_mount *ump = udf_node->ump; 1463 struct udf_mount *ump = udf_node->ump;
1464 union dscrptr *dscr, *extdscr; 1464 union dscrptr *dscr, *extdscr;
1465 struct file_entry *fe; 1465 struct file_entry *fe;
1466 struct extfile_entry *efe; 1466 struct extfile_entry *efe;
1467 struct alloc_ext_entry *ext; 1467 struct alloc_ext_entry *ext;
1468 struct icb_tag *icbtag; 1468 struct icb_tag *icbtag;
1469 struct short_ad *short_ad; 1469 struct short_ad *short_ad;
1470 struct long_ad *long_ad, o_icb, l_icb; 1470 struct long_ad *long_ad, o_icb, l_icb;
1471 uint64_t logblks_rec, *logblks_rec_p; 1471 uint64_t logblks_rec, *logblks_rec_p;
1472 uint64_t lmapping; 1472 uint64_t lmapping;
1473 uint32_t offset, rest, len, lb_num; 1473 uint32_t offset, rest, len, lb_num;
1474 uint32_t lb_size, dscr_size, l_ea, l_ad, *l_ad_p, max_l_ad, crclen; 1474 uint32_t lb_size, dscr_size, l_ea, l_ad, *l_ad_p, max_l_ad, crclen;
1475 uint32_t flags; 1475 uint32_t flags;
1476 uint16_t vpart_num; 1476 uint16_t vpart_num;
1477 uint8_t *data_pos; 1477 uint8_t *data_pos;
1478 int icbflags, addr_type, adlen, extnr; 1478 int icbflags, addr_type, adlen, extnr;
1479 int error; 1479 int error;
1480 1480
1481 lb_size = udf_rw32(ump->logical_vol->lb_size); 1481 lb_size = udf_rw32(ump->logical_vol->lb_size);
1482 vpart_num = udf_rw16(udf_node->loc.loc.part_num); 1482 vpart_num = udf_rw16(udf_node->loc.loc.part_num);
1483 1483
1484 /* determine what descriptor we are in */ 1484 /* determine what descriptor we are in */
1485 fe = udf_node->fe; 1485 fe = udf_node->fe;
1486 efe = udf_node->efe; 1486 efe = udf_node->efe;
1487 if (fe) { 1487 if (fe) {
1488 icbtag = &fe->icbtag; 1488 icbtag = &fe->icbtag;
1489 dscr = (union dscrptr *) fe; 1489 dscr = (union dscrptr *) fe;
1490 dscr_size = sizeof(struct file_entry) -1; 1490 dscr_size = sizeof(struct file_entry) -1;
1491 1491
1492 l_ea = udf_rw32(fe->l_ea); 1492 l_ea = udf_rw32(fe->l_ea);
1493 l_ad_p = &fe->l_ad; 1493 l_ad_p = &fe->l_ad;
1494 logblks_rec_p = &fe->logblks_rec; 1494 logblks_rec_p = &fe->logblks_rec;
1495 } else { 1495 } else {
1496 icbtag = &efe->icbtag; 1496 icbtag = &efe->icbtag;
1497 dscr = (union dscrptr *) efe; 1497 dscr = (union dscrptr *) efe;
1498 dscr_size = sizeof(struct extfile_entry) -1; 1498 dscr_size = sizeof(struct extfile_entry) -1;
1499 1499
1500 l_ea = udf_rw32(efe->l_ea); 1500 l_ea = udf_rw32(efe->l_ea);
1501 l_ad_p = &efe->l_ad; 1501 l_ad_p = &efe->l_ad;
1502 logblks_rec_p = &efe->logblks_rec; 1502 logblks_rec_p = &efe->logblks_rec;
1503 } 1503 }
1504 data_pos = (uint8_t *) dscr + dscr_size + l_ea; 1504 data_pos = (uint8_t *) dscr + dscr_size + l_ea;
1505 max_l_ad = lb_size - dscr_size - l_ea; 1505 max_l_ad = lb_size - dscr_size - l_ea;
1506 1506
1507 icbflags = udf_rw16(icbtag->flags); 1507 icbflags = udf_rw16(icbtag->flags);
1508 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK; 1508 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK;
1509 1509
1510 /* just in case we're called on an intern, its EOF */ 1510 /* just in case we're called on an intern, its EOF */
1511 if (addr_type == UDF_ICB_INTERN_ALLOC) { 1511 if (addr_type == UDF_ICB_INTERN_ALLOC) {
1512 panic("udf_append_adslot on UDF_ICB_INTERN_ALLOC\n"); 1512 panic("udf_append_adslot on UDF_ICB_INTERN_ALLOC\n");
1513 } 1513 }
1514 1514
1515 adlen = 0; 1515 adlen = 0;
1516 if (addr_type == UDF_ICB_SHORT_ALLOC) { 1516 if (addr_type == UDF_ICB_SHORT_ALLOC) {
1517 adlen = sizeof(struct short_ad); 1517 adlen = sizeof(struct short_ad);
1518 } else if (addr_type == UDF_ICB_LONG_ALLOC) { 1518 } else if (addr_type == UDF_ICB_LONG_ALLOC) {
1519 adlen = sizeof(struct long_ad); 1519 adlen = sizeof(struct long_ad);
1520 } 1520 }
1521 1521
1522 /* clean up given long_ad since it can be a synthesized one */ 1522 /* clean up given long_ad since it can be a synthesized one */
1523 flags = UDF_EXT_FLAGS(udf_rw32(icb->len)); 1523 flags = UDF_EXT_FLAGS(udf_rw32(icb->len));
1524 if (flags == UDF_EXT_FREE) { 1524 if (flags == UDF_EXT_FREE) {
1525 icb->loc.part_num = udf_rw16(0); 1525 icb->loc.part_num = udf_rw16(0);
1526 icb->loc.lb_num = udf_rw32(0); 1526 icb->loc.lb_num = udf_rw32(0);
1527 } 1527 }
1528 1528
1529 /* if offset too big, we go to the allocation extensions */ 1529 /* if offset too big, we go to the allocation extensions */
1530 l_ad = udf_rw32(*l_ad_p); 1530 l_ad = udf_rw32(*l_ad_p);
1531 offset = (*slot) * adlen; 1531 offset = (*slot) * adlen;
1532 extnr = -1; 1532 extnr = -1;
1533 while (offset >= l_ad) { 1533 while (offset >= l_ad) {
1534 /* check if our last entry is a redirect */ 1534 /* check if our last entry is a redirect */
1535 if (addr_type == UDF_ICB_SHORT_ALLOC) { 1535 if (addr_type == UDF_ICB_SHORT_ALLOC) {
1536 short_ad = (struct short_ad *) (data_pos + l_ad-adlen); 1536 short_ad = (struct short_ad *) (data_pos + l_ad-adlen);
1537 l_icb.len = short_ad->len; 1537 l_icb.len = short_ad->len;
1538 l_icb.loc.part_num = udf_node->loc.loc.part_num; 1538 l_icb.loc.part_num = udf_node->loc.loc.part_num;
1539 l_icb.loc.lb_num = short_ad->lb_num; 1539 l_icb.loc.lb_num = short_ad->lb_num;
1540 } else { 1540 } else {
1541 KASSERT(addr_type == UDF_ICB_LONG_ALLOC); 1541 KASSERT(addr_type == UDF_ICB_LONG_ALLOC);
1542 long_ad = (struct long_ad *) (data_pos + l_ad-adlen); 1542 long_ad = (struct long_ad *) (data_pos + l_ad-adlen);
1543 l_icb = *long_ad; 1543 l_icb = *long_ad;
1544 } 1544 }
1545 flags = UDF_EXT_FLAGS(udf_rw32(l_icb.len)); 1545 flags = UDF_EXT_FLAGS(udf_rw32(l_icb.len));
1546 if (flags != UDF_EXT_REDIRECT) { 1546 if (flags != UDF_EXT_REDIRECT) {
1547 /* only one past the last one is adressable */ 1547 /* only one past the last one is adressable */
1548 break; 1548 break;
1549 } 1549 }
1550 1550
1551 /* advance to next extent */ 1551 /* advance to next extent */
1552 extnr++; 1552 extnr++;
1553 KASSERT(extnr < udf_node->num_extensions); 1553 KASSERT(extnr < udf_node->num_extensions);
1554 offset = offset - l_ad; 1554 offset = offset - l_ad;
1555 1555
1556 ext = udf_node->ext[extnr]; 1556 ext = udf_node->ext[extnr];
1557 dscr = (union dscrptr *) ext; 1557 dscr = (union dscrptr *) ext;
1558 dscr_size = sizeof(struct alloc_ext_entry) -1; 1558 dscr_size = sizeof(struct alloc_ext_entry) -1;
1559 max_l_ad = lb_size - dscr_size; 1559 max_l_ad = lb_size - dscr_size;
1560 l_ad_p = &ext->l_ad; 1560 l_ad_p = &ext->l_ad;
1561 l_ad = udf_rw32(*l_ad_p); 1561 l_ad = udf_rw32(*l_ad_p);
1562 data_pos = (uint8_t *) ext + dscr_size; 1562 data_pos = (uint8_t *) ext + dscr_size;
1563 } 1563 }
1564 DPRINTF(PARANOIDADWLK, ("append, ext %d, offset %d, l_ad %d\n", 1564 DPRINTF(PARANOIDADWLK, ("append, ext %d, offset %d, l_ad %d\n",
1565 extnr, offset, udf_rw32(*l_ad_p))); 1565 extnr, offset, udf_rw32(*l_ad_p)));
1566 KASSERT(l_ad == udf_rw32(*l_ad_p)); 1566 KASSERT(l_ad == udf_rw32(*l_ad_p));
1567 1567
1568 /* offset is offset within the current (E)FE/AED */ 1568 /* offset is offset within the current (E)FE/AED */
1569 l_ad = udf_rw32(*l_ad_p); 1569 l_ad = udf_rw32(*l_ad_p);
1570 crclen = udf_rw16(dscr->tag.desc_crc_len); 1570 crclen = udf_rw16(dscr->tag.desc_crc_len);
1571 logblks_rec = udf_rw64(*logblks_rec_p); 1571 logblks_rec = udf_rw64(*logblks_rec_p);
1572 1572
1573 /* overwriting old piece? */ 1573 /* overwriting old piece? */
1574 if (offset < l_ad) { 1574 if (offset < l_ad) {
1575 /* overwrite entry; compensate for the old element */ 1575 /* overwrite entry; compensate for the old element */
1576 if (addr_type == UDF_ICB_SHORT_ALLOC) { 1576 if (addr_type == UDF_ICB_SHORT_ALLOC) {
1577 short_ad = (struct short_ad *) (data_pos + offset); 1577 short_ad = (struct short_ad *) (data_pos + offset);
1578 o_icb.len = short_ad->len; 1578 o_icb.len = short_ad->len;
1579 o_icb.loc.part_num = udf_rw16(0); /* ignore */ 1579 o_icb.loc.part_num = udf_rw16(0); /* ignore */
1580 o_icb.loc.lb_num = short_ad->lb_num; 1580 o_icb.loc.lb_num = short_ad->lb_num;
1581 } else if (addr_type == UDF_ICB_LONG_ALLOC) { 1581 } else if (addr_type == UDF_ICB_LONG_ALLOC) {
1582 long_ad = (struct long_ad *) (data_pos + offset); 1582 long_ad = (struct long_ad *) (data_pos + offset);
1583 o_icb = *long_ad; 1583 o_icb = *long_ad;
1584 } else { 1584 } else {
1585 panic("Invalid address type in udf_append_adslot\n"); 1585 panic("Invalid address type in udf_append_adslot\n");
1586 } 1586 }
1587 1587
1588 len = udf_rw32(o_icb.len); 1588 len = udf_rw32(o_icb.len);
1589 if (UDF_EXT_FLAGS(len) == UDF_EXT_ALLOCATED) { 1589 if (UDF_EXT_FLAGS(len) == UDF_EXT_ALLOCATED) {
1590 /* adjust counts */ 1590 /* adjust counts */
1591 len = UDF_EXT_LEN(len); 1591 len = UDF_EXT_LEN(len);
1592 logblks_rec -= (len + lb_size -1) / lb_size; 1592 logblks_rec -= (len + lb_size -1) / lb_size;
1593 } 1593 }
1594 } 1594 }
1595 1595
1596 /* check if we're not appending a redirection */ 1596 /* check if we're not appending a redirection */
1597 flags = UDF_EXT_FLAGS(udf_rw32(icb->len)); 1597 flags = UDF_EXT_FLAGS(udf_rw32(icb->len));
1598 KASSERT(flags != UDF_EXT_REDIRECT); 1598 KASSERT(flags != UDF_EXT_REDIRECT);
1599 1599
1600 /* round down available space */ 1600 /* round down available space */
1601 rest = adlen * ((max_l_ad - offset) / adlen); 1601 rest = adlen * ((max_l_ad - offset) / adlen);
1602 if (rest <= adlen) { 1602 if (rest <= adlen) {
1603 /* have to append aed, see if we already have a spare one */ 1603 /* have to append aed, see if we already have a spare one */
1604 extnr++; 1604 extnr++;
1605 ext = udf_node->ext[extnr]; 1605 ext = udf_node->ext[extnr];
1606 l_icb = udf_node->ext_loc[extnr]; 1606 l_icb = udf_node->ext_loc[extnr];
1607 if (ext == NULL) { 1607 if (ext == NULL) {
1608 DPRINTF(ALLOC,("adding allocation extent %d\n", extnr)); 1608 DPRINTF(ALLOC,("adding allocation extent %d\n", extnr));
1609 1609
1610 error = udf_pre_allocate_space(ump, UDF_C_NODE, 1, 1610 error = udf_pre_allocate_space(ump, UDF_C_NODE, 1,
1611 vpart_num, &lmapping); 1611 vpart_num, &lmapping);
1612 lb_num = lmapping; 1612 lb_num = lmapping;
1613 if (error) 1613 if (error)
1614 return error; 1614 return error;
1615 1615
1616 /* initialise pointer to location */ 1616 /* initialise pointer to location */
1617 memset(&l_icb, 0, sizeof(struct long_ad)); 1617 memset(&l_icb, 0, sizeof(struct long_ad));
1618 l_icb.len = udf_rw32(lb_size | UDF_EXT_REDIRECT); 1618 l_icb.len = udf_rw32(lb_size | UDF_EXT_REDIRECT);
1619 l_icb.loc.lb_num = udf_rw32(lb_num); 1619 l_icb.loc.lb_num = udf_rw32(lb_num);
1620 l_icb.loc.part_num = udf_rw16(vpart_num); 1620 l_icb.loc.part_num = udf_rw16(vpart_num);
1621 1621
1622 /* create new aed descriptor */ 1622 /* create new aed descriptor */
1623 udf_create_logvol_dscr(ump, udf_node, &l_icb, &extdscr); 1623 udf_create_logvol_dscr(ump, udf_node, &l_icb, &extdscr);
1624 ext = &extdscr->aee; 1624 ext = &extdscr->aee;
1625 1625
1626 udf_inittag(ump, &ext->tag, TAGID_ALLOCEXTENT, lb_num); 1626 udf_inittag(ump, &ext->tag, TAGID_ALLOCEXTENT, lb_num);
1627 dscr_size = sizeof(struct alloc_ext_entry) -1; 1627 dscr_size = sizeof(struct alloc_ext_entry) -1;
1628 max_l_ad = lb_size - dscr_size; 1628 max_l_ad = lb_size - dscr_size;
1629 memset(ext->data, 0, max_l_ad); 1629 memset(ext->data, 0, max_l_ad);
1630 ext->l_ad = udf_rw32(0); 1630 ext->l_ad = udf_rw32(0);
1631 ext->tag.desc_crc_len = 1631 ext->tag.desc_crc_len =
1632 udf_rw16(dscr_size - UDF_DESC_TAG_LENGTH); 1632 udf_rw16(dscr_size - UDF_DESC_TAG_LENGTH);
1633 1633
1634 /* declare aed */ 1634 /* declare aed */
1635 udf_node->num_extensions++; 1635 udf_node->num_extensions++;
1636 udf_node->ext_loc[extnr] = l_icb; 1636 udf_node->ext_loc[extnr] = l_icb;
1637 udf_node->ext[extnr] = ext; 1637 udf_node->ext[extnr] = ext;
1638 } 1638 }
1639 /* add redirect and adjust l_ad and crclen for old descr */ 1639 /* add redirect and adjust l_ad and crclen for old descr */
1640 if (addr_type == UDF_ICB_SHORT_ALLOC) { 1640 if (addr_type == UDF_ICB_SHORT_ALLOC) {
1641 short_ad = (struct short_ad *) (data_pos + offset); 1641 short_ad = (struct short_ad *) (data_pos + offset);
1642 short_ad->len = l_icb.len; 1642 short_ad->len = l_icb.len;
1643 short_ad->lb_num = l_icb.loc.lb_num; 1643 short_ad->lb_num = l_icb.loc.lb_num;
1644 } else if (addr_type == UDF_ICB_LONG_ALLOC) { 1644 } else if (addr_type == UDF_ICB_LONG_ALLOC) {
1645 long_ad = (struct long_ad *) (data_pos + offset); 1645 long_ad = (struct long_ad *) (data_pos + offset);
1646 *long_ad = l_icb; 1646 *long_ad = l_icb;
1647 } 1647 }
1648 l_ad += adlen; 1648 l_ad += adlen;
1649 crclen += adlen; 1649 crclen += adlen;
1650 dscr->tag.desc_crc_len = udf_rw16(crclen); 1650 dscr->tag.desc_crc_len = udf_rw16(crclen);
1651 *l_ad_p = udf_rw32(l_ad); 1651 *l_ad_p = udf_rw32(l_ad);
1652 1652
1653 /* advance to the new extension */ 1653 /* advance to the new extension */
1654 KASSERT(ext != NULL); 1654 KASSERT(ext != NULL);
1655 dscr = (union dscrptr *) ext; 1655 dscr = (union dscrptr *) ext;
1656 dscr_size = sizeof(struct alloc_ext_entry) -1; 1656 dscr_size = sizeof(struct alloc_ext_entry) -1;
1657 max_l_ad = lb_size - dscr_size; 1657 max_l_ad = lb_size - dscr_size;
1658 data_pos = (uint8_t *) dscr + dscr_size; 1658 data_pos = (uint8_t *) dscr + dscr_size;
1659 1659
1660 l_ad_p = &ext->l_ad; 1660 l_ad_p = &ext->l_ad;
1661 l_ad = udf_rw32(*l_ad_p); 1661 l_ad = udf_rw32(*l_ad_p);
1662 crclen = udf_rw16(dscr->tag.desc_crc_len); 1662 crclen = udf_rw16(dscr->tag.desc_crc_len);
1663 offset = 0; 1663 offset = 0;
1664 1664
1665 /* adjust callees slot count for link insert */ 1665 /* adjust callees slot count for link insert */
1666 *slot += 1; 1666 *slot += 1;
1667 } 1667 }
1668 1668
1669 /* write out the element */ 1669 /* write out the element */
1670 DPRINTF(PARANOIDADWLK, ("adding element : %p : v %d, lb %d, " 1670 DPRINTF(PARANOIDADWLK, ("adding element : %p : v %d, lb %d, "
1671 "len %d, flags %d\n", data_pos + offset, 1671 "len %d, flags %d\n", data_pos + offset,
1672 icb->loc.part_num, icb->loc.lb_num, 1672 icb->loc.part_num, icb->loc.lb_num,
1673 UDF_EXT_LEN(icb->len), UDF_EXT_FLAGS(icb->len))); 1673 UDF_EXT_LEN(icb->len), UDF_EXT_FLAGS(icb->len)));
1674 if (addr_type == UDF_ICB_SHORT_ALLOC) { 1674 if (addr_type == UDF_ICB_SHORT_ALLOC) {
1675 short_ad = (struct short_ad *) (data_pos + offset); 1675 short_ad = (struct short_ad *) (data_pos + offset);
1676 short_ad->len = icb->len; 1676 short_ad->len = icb->len;
1677 short_ad->lb_num = icb->loc.lb_num; 1677 short_ad->lb_num = icb->loc.lb_num;
1678 } else if (addr_type == UDF_ICB_LONG_ALLOC) { 1678 } else if (addr_type == UDF_ICB_LONG_ALLOC) {
1679 long_ad = (struct long_ad *) (data_pos + offset); 1679 long_ad = (struct long_ad *) (data_pos + offset);
1680 *long_ad = *icb; 1680 *long_ad = *icb;
1681 } 1681 }
1682 1682
1683 /* adjust logblks recorded count */ 1683 /* adjust logblks recorded count */
1684 len = udf_rw32(icb->len); 1684 len = udf_rw32(icb->len);
1685 flags = UDF_EXT_FLAGS(len); 1685 flags = UDF_EXT_FLAGS(len);
1686 if (flags == UDF_EXT_ALLOCATED) 1686 if (flags == UDF_EXT_ALLOCATED)
1687 logblks_rec += (UDF_EXT_LEN(len) + lb_size -1) / lb_size; 1687 logblks_rec += (UDF_EXT_LEN(len) + lb_size -1) / lb_size;
1688 *logblks_rec_p = udf_rw64(logblks_rec); 1688 *logblks_rec_p = udf_rw64(logblks_rec);
1689 1689
1690 /* adjust l_ad and crclen when needed */ 1690 /* adjust l_ad and crclen when needed */
1691 if (offset >= l_ad) { 1691 if (offset >= l_ad) {
1692 l_ad += adlen; 1692 l_ad += adlen;
1693 crclen += adlen; 1693 crclen += adlen;
1694 dscr->tag.desc_crc_len = udf_rw16(crclen); 1694 dscr->tag.desc_crc_len = udf_rw16(crclen);
1695 *l_ad_p = udf_rw32(l_ad); 1695 *l_ad_p = udf_rw32(l_ad);
1696 } 1696 }
1697 1697
1698 return 0; 1698 return 0;
1699} 1699}
1700 1700
1701/* --------------------------------------------------------------------- */ 1701/* --------------------------------------------------------------------- */
1702 1702
1703static void 1703static void
1704udf_count_alloc_exts(struct udf_node *udf_node) 1704udf_count_alloc_exts(struct udf_node *udf_node)
1705{ 1705{
1706 struct long_ad s_ad; 1706 struct long_ad s_ad;
1707 uint32_t lb_num, len, flags; 1707 uint32_t lb_num, len, flags;
1708 uint16_t vpart_num; 1708 uint16_t vpart_num;
1709 int slot, eof; 1709 int slot, eof;
1710 int num_extents, extnr; 1710 int num_extents, extnr;
1711 int lb_size; 1711 int lb_size;
1712 1712
1713 if (udf_node->num_extensions == 0) 1713 if (udf_node->num_extensions == 0)
1714 return; 1714 return;
1715 1715
1716 lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size); 1716 lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size);
1717 /* count number of allocation extents in use */ 1717 /* count number of allocation extents in use */
1718 num_extents = 0; 1718 num_extents = 0;
1719 slot = 0; 1719 slot = 0;
1720 for (;;) { 1720 for (;;) {
1721 udf_get_adslot(udf_node, slot, &s_ad, &eof); 1721 udf_get_adslot(udf_node, slot, &s_ad, &eof);
1722 if (eof) 1722 if (eof)
1723 break; 1723 break;
1724 len = udf_rw32(s_ad.len); 1724 len = udf_rw32(s_ad.len);
1725 flags = UDF_EXT_FLAGS(len); 1725 flags = UDF_EXT_FLAGS(len);
1726 1726
1727 if (flags == UDF_EXT_REDIRECT) 1727 if (flags == UDF_EXT_REDIRECT)
1728 num_extents++; 1728 num_extents++;
1729 1729
1730 slot++; 1730 slot++;
1731 } 1731 }
1732 1732
1733 DPRINTF(ALLOC, ("udf_count_alloc_ext counted %d live extents\n", 1733 DPRINTF(ALLOC, ("udf_count_alloc_ext counted %d live extents\n",
1734 num_extents)); 1734 num_extents));
1735 1735
1736 /* XXX choice: we could delay freeing them on node writeout */ 1736 /* XXX choice: we could delay freeing them on node writeout */
1737 /* free excess entries */ 1737 /* free excess entries */
1738 extnr = num_extents; 1738 extnr = num_extents;
1739 for (;extnr < udf_node->num_extensions; extnr++) { 1739 for (;extnr < udf_node->num_extensions; extnr++) {
1740 DPRINTF(ALLOC, ("freeing alloc ext %d\n", extnr)); 1740 DPRINTF(ALLOC, ("freeing alloc ext %d\n", extnr));
1741 /* free dscriptor */ 1741 /* free dscriptor */
1742 s_ad = udf_node->ext_loc[extnr]; 1742 s_ad = udf_node->ext_loc[extnr];
1743 udf_free_logvol_dscr(udf_node->ump, &s_ad, 1743 udf_free_logvol_dscr(udf_node->ump, &s_ad,
1744 udf_node->ext[extnr]); 1744 udf_node->ext[extnr]);
1745 udf_node->ext[extnr] = NULL; 1745 udf_node->ext[extnr] = NULL;
1746 1746
1747 /* free disc space */ 1747 /* free disc space */
1748 lb_num = udf_rw32(s_ad.loc.lb_num); 1748 lb_num = udf_rw32(s_ad.loc.lb_num);
1749 vpart_num = udf_rw16(s_ad.loc.part_num); 1749 vpart_num = udf_rw16(s_ad.loc.part_num);
1750 udf_free_allocated_space(udf_node->ump, lb_num, vpart_num, 1); 1750 udf_free_allocated_space(udf_node->ump, lb_num, vpart_num, 1);
1751 1751
1752 memset(&udf_node->ext_loc[extnr], 0, sizeof(struct long_ad)); 1752 memset(&udf_node->ext_loc[extnr], 0, sizeof(struct long_ad));
1753 } 1753 }
1754 1754
1755 /* set our new number of allocation extents */ 1755 /* set our new number of allocation extents */
1756 udf_node->num_extensions = num_extents; 1756 udf_node->num_extensions = num_extents;
1757} 1757}
1758 1758
1759 1759
1760/* --------------------------------------------------------------------- */ 1760/* --------------------------------------------------------------------- */
1761 1761
1762/* 1762/*
1763 * Adjust the node's allocation descriptors to reflect the new mapping; do 1763 * Adjust the node's allocation descriptors to reflect the new mapping; do
1764 * take note that we might glue to existing allocation descriptors. 1764 * take note that we might glue to existing allocation descriptors.
1765 * 1765 *
1766 * XXX Note there can only be one allocation being recorded/mount; maybe 1766 * XXX Note there can only be one allocation being recorded/mount; maybe
1767 * explicit allocation in shedule thread? 1767 * explicit allocation in shedule thread?
1768 */ 1768 */
1769 1769
1770static void 1770static void
1771udf_record_allocation_in_node(struct udf_mount *ump, struct buf *buf, 1771udf_record_allocation_in_node(struct udf_mount *ump, struct buf *buf,
1772 uint16_t vpart_num, uint64_t *mapping, struct long_ad *node_ad_cpy) 1772 uint16_t vpart_num, uint64_t *mapping, struct long_ad *node_ad_cpy)
1773{ 1773{
1774 struct vnode *vp = buf->b_vp; 1774 struct vnode *vp = buf->b_vp;
1775 struct udf_node *udf_node = VTOI(vp); 1775 struct udf_node *udf_node = VTOI(vp);
1776 struct file_entry *fe; 1776 struct file_entry *fe;
1777 struct extfile_entry *efe; 1777 struct extfile_entry *efe;
1778 struct icb_tag *icbtag; 1778 struct icb_tag *icbtag;
1779 struct long_ad s_ad, c_ad; 1779 struct long_ad s_ad, c_ad;
1780 uint64_t inflen, from, till; 1780 uint64_t inflen, from, till;
1781 uint64_t foffset, end_foffset, restart_foffset; 1781 uint64_t foffset, end_foffset, restart_foffset;
1782 uint64_t orig_inflen, orig_lbrec, new_inflen, new_lbrec; 1782 uint64_t orig_inflen, orig_lbrec, new_inflen, new_lbrec;
1783 uint32_t num_lb, len, flags, lb_num; 1783 uint32_t num_lb, len, flags, lb_num;
1784 uint32_t run_start; 1784 uint32_t run_start;
1785 uint32_t slot_offset, replace_len, replace; 1785 uint32_t slot_offset, replace_len, replace;
1786 int addr_type, icbflags; 1786 int addr_type, icbflags;
1787// int udf_c_type = buf->b_udf_c_type; 1787// int udf_c_type = buf->b_udf_c_type;
1788 int lb_size, run_length, eof; 1788 int lb_size, run_length, eof;
1789 int slot, cpy_slot, cpy_slots, restart_slot; 1789 int slot, cpy_slot, cpy_slots, restart_slot;
1790 int error; 1790 int error;
1791 1791
1792 DPRINTF(ALLOC, ("udf_record_allocation_in_node\n")); 1792 DPRINTF(ALLOC, ("udf_record_allocation_in_node\n"));
1793 1793
1794#if 0 1794#if 0
1795 /* XXX disable sanity check for now */ 1795 /* XXX disable sanity check for now */
1796 /* sanity check ... should be panic ? */ 1796 /* sanity check ... should be panic ? */
1797 if ((udf_c_type != UDF_C_USERDATA) && (udf_c_type != UDF_C_FIDS)) 1797 if ((udf_c_type != UDF_C_USERDATA) && (udf_c_type != UDF_C_FIDS))
1798 return; 1798 return;
1799#endif 1799#endif
1800 1800
1801 lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size); 1801 lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size);
1802 1802
1803 /* do the job */ 1803 /* do the job */
1804 UDF_LOCK_NODE(udf_node, 0); /* XXX can deadlock ? */ 1804 UDF_LOCK_NODE(udf_node, 0); /* XXX can deadlock ? */
1805 udf_node_sanity_check(udf_node, &orig_inflen, &orig_lbrec); 1805 udf_node_sanity_check(udf_node, &orig_inflen, &orig_lbrec);
1806 1806
1807 fe = udf_node->fe; 1807 fe = udf_node->fe;
1808 efe = udf_node->efe; 1808 efe = udf_node->efe;
1809 if (fe) { 1809 if (fe) {
1810 icbtag = &fe->icbtag; 1810 icbtag = &fe->icbtag;
1811 inflen = udf_rw64(fe->inf_len); 1811 inflen = udf_rw64(fe->inf_len);
1812 } else { 1812 } else {
1813 icbtag = &efe->icbtag; 1813 icbtag = &efe->icbtag;
1814 inflen = udf_rw64(efe->inf_len); 1814 inflen = udf_rw64(efe->inf_len);
1815 } 1815 }
1816 1816
1817 /* do check if `till' is not past file information length */ 1817 /* do check if `till' is not past file information length */
1818 from = buf->b_lblkno * lb_size; 1818 from = buf->b_lblkno * lb_size;
1819 till = MIN(inflen, from + buf->b_resid); 1819 till = MIN(inflen, from + buf->b_resid);
1820 1820
1821 num_lb = (till - from + lb_size -1) / lb_size; 1821 num_lb = (till - from + lb_size -1) / lb_size;
1822 1822
1823 DPRINTF(ALLOC, ("record allocation from %"PRIu64" + %d\n", from, buf->b_bcount)); 1823 DPRINTF(ALLOC, ("record allocation from %"PRIu64" + %d\n", from, buf->b_bcount));
1824 1824
1825 icbflags = udf_rw16(icbtag->flags); 1825 icbflags = udf_rw16(icbtag->flags);
1826 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK; 1826 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK;
1827 1827
1828 if (addr_type == UDF_ICB_INTERN_ALLOC) { 1828 if (addr_type == UDF_ICB_INTERN_ALLOC) {
1829 /* nothing to do */ 1829 /* nothing to do */
1830 /* XXX clean up rest of node? just in case? */ 1830 /* XXX clean up rest of node? just in case? */
1831 UDF_UNLOCK_NODE(udf_node, 0); 1831 UDF_UNLOCK_NODE(udf_node, 0);
1832 return; 1832 return;
1833 } 1833 }
1834 1834
1835 slot = 0; 1835 slot = 0;
1836 cpy_slot = 0; 1836 cpy_slot = 0;
1837 foffset = 0; 1837 foffset = 0;
1838 1838
1839 /* 1) copy till first overlap piece to the rewrite buffer */ 1839 /* 1) copy till first overlap piece to the rewrite buffer */
1840 for (;;) { 1840 for (;;) {
1841 udf_get_adslot(udf_node, slot, &s_ad, &eof); 1841 udf_get_adslot(udf_node, slot, &s_ad, &eof);
1842 if (eof) { 1842 if (eof) {
1843 DPRINTF(WRITE, 1843 DPRINTF(WRITE,
1844 ("Record allocation in node " 1844 ("Record allocation in node "
1845 "failed: encountered EOF\n")); 1845 "failed: encountered EOF\n"));
1846 UDF_UNLOCK_NODE(udf_node, 0); 1846 UDF_UNLOCK_NODE(udf_node, 0);
1847 buf->b_error = EINVAL; 1847 buf->b_error = EINVAL;
1848 return; 1848 return;
1849 } 1849 }
1850 len = udf_rw32(s_ad.len); 1850 len = udf_rw32(s_ad.len);
1851 flags = UDF_EXT_FLAGS(len); 1851 flags = UDF_EXT_FLAGS(len);
1852 len = UDF_EXT_LEN(len); 1852 len = UDF_EXT_LEN(len);
1853 1853
1854 if (flags == UDF_EXT_REDIRECT) { 1854 if (flags == UDF_EXT_REDIRECT) {
1855 slot++; 1855 slot++;
1856 continue; 1856 continue;
1857 } 1857 }
1858 1858
1859 end_foffset = foffset + len; 1859 end_foffset = foffset + len;
1860 if (end_foffset > from) 1860 if (end_foffset > from)
1861 break; /* found */ 1861 break; /* found */
1862 1862
1863 node_ad_cpy[cpy_slot++] = s_ad; 1863 node_ad_cpy[cpy_slot++] = s_ad;
1864 1864
1865 DPRINTF(ALLOC, ("\t1: vp %d, lb %d, len %d, flags %d " 1865 DPRINTF(ALLOC, ("\t1: vp %d, lb %d, len %d, flags %d "
1866 "-> stack\n", 1866 "-> stack\n",
1867 udf_rw16(s_ad.loc.part_num), 1867 udf_rw16(s_ad.loc.part_num),
1868 udf_rw32(s_ad.loc.lb_num), 1868 udf_rw32(s_ad.loc.lb_num),
1869 UDF_EXT_LEN(udf_rw32(s_ad.len)), 1869 UDF_EXT_LEN(udf_rw32(s_ad.len)),
1870 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30)); 1870 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30));
1871 1871
1872 foffset = end_foffset; 1872 foffset = end_foffset;
1873 slot++; 1873 slot++;
1874 } 1874 }
1875 restart_slot = slot; 1875 restart_slot = slot;
1876 restart_foffset = foffset; 1876 restart_foffset = foffset;
1877 1877
1878 /* 2) trunc overlapping slot at overlap and copy it */ 1878 /* 2) trunc overlapping slot at overlap and copy it */
1879 slot_offset = from - foffset; 1879 slot_offset = from - foffset;
1880 if (slot_offset > 0) { 1880 if (slot_offset > 0) {
1881 DPRINTF(ALLOC, ("\tslot_offset = %d, flags = %d (%d)\n", 1881 DPRINTF(ALLOC, ("\tslot_offset = %d, flags = %d (%d)\n",
1882 slot_offset, flags >> 30, flags)); 1882 slot_offset, flags >> 30, flags));
1883 1883
1884 s_ad.len = udf_rw32(slot_offset | flags); 1884 s_ad.len = udf_rw32(slot_offset | flags);
1885 node_ad_cpy[cpy_slot++] = s_ad; 1885 node_ad_cpy[cpy_slot++] = s_ad;
1886 1886
1887 DPRINTF(ALLOC, ("\t2: vp %d, lb %d, len %d, flags %d " 1887 DPRINTF(ALLOC, ("\t2: vp %d, lb %d, len %d, flags %d "
1888 "-> stack\n", 1888 "-> stack\n",
1889 udf_rw16(s_ad.loc.part_num), 1889 udf_rw16(s_ad.loc.part_num),
1890 udf_rw32(s_ad.loc.lb_num), 1890 udf_rw32(s_ad.loc.lb_num),
1891 UDF_EXT_LEN(udf_rw32(s_ad.len)), 1891 UDF_EXT_LEN(udf_rw32(s_ad.len)),
1892 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30)); 1892 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30));
1893 } 1893 }
1894 foffset += slot_offset; 1894 foffset += slot_offset;
1895 1895
1896 /* 3) insert new mappings */ 1896 /* 3) insert new mappings */
1897 memset(&s_ad, 0, sizeof(struct long_ad)); 1897 memset(&s_ad, 0, sizeof(struct long_ad));
1898 lb_num = 0; 1898 lb_num = 0;
1899 for (lb_num = 0; lb_num < num_lb; lb_num++) { 1899 for (lb_num = 0; lb_num < num_lb; lb_num++) {
1900 run_start = mapping[lb_num]; 1900 run_start = mapping[lb_num];
1901 run_length = 1; 1901 run_length = 1;
1902 while (lb_num < num_lb-1) { 1902 while (lb_num < num_lb-1) {
1903 if (mapping[lb_num+1] != mapping[lb_num]+1) 1903 if (mapping[lb_num+1] != mapping[lb_num]+1)
1904 if (mapping[lb_num+1] != mapping[lb_num]) 1904 if (mapping[lb_num+1] != mapping[lb_num])
1905 break; 1905 break;
1906 run_length++; 1906 run_length++;
1907 lb_num++; 1907 lb_num++;
1908 } 1908 }
1909 /* insert slot for this mapping */ 1909 /* insert slot for this mapping */
1910 len = run_length * lb_size; 1910 len = run_length * lb_size;
1911 1911
1912 /* bounds checking */ 1912 /* bounds checking */
1913 if (foffset + len > till) 1913 if (foffset + len > till)
1914 len = till - foffset; 1914 len = till - foffset;
1915 KASSERT(foffset + len <= inflen); 1915 KASSERT(foffset + len <= inflen);
1916 1916
1917 s_ad.len = udf_rw32(len | UDF_EXT_ALLOCATED); 1917 s_ad.len = udf_rw32(len | UDF_EXT_ALLOCATED);
1918 s_ad.loc.part_num = udf_rw16(vpart_num); 1918 s_ad.loc.part_num = udf_rw16(vpart_num);
1919 s_ad.loc.lb_num = udf_rw32(run_start); 1919 s_ad.loc.lb_num = udf_rw32(run_start);
1920 1920
1921 foffset += len; 1921 foffset += len;
1922 1922
1923 /* paranoia */ 1923 /* paranoia */
1924 if (len == 0) { 1924 if (len == 0) {
1925 DPRINTF(WRITE, 1925 DPRINTF(WRITE,
1926 ("Record allocation in node " 1926 ("Record allocation in node "
1927 "failed: insert failed\n")); 1927 "failed: insert failed\n"));
1928 UDF_UNLOCK_NODE(udf_node, 0); 1928 UDF_UNLOCK_NODE(udf_node, 0);
1929 buf->b_error = EINVAL; 1929 buf->b_error = EINVAL;
1930 return; 1930 return;
1931 } 1931 }
1932 node_ad_cpy[cpy_slot++] = s_ad; 1932 node_ad_cpy[cpy_slot++] = s_ad;
1933 1933
1934 DPRINTF(ALLOC, ("\t3: insert new mapping vp %d lb %d, len %d, " 1934 DPRINTF(ALLOC, ("\t3: insert new mapping vp %d lb %d, len %d, "
1935 "flags %d -> stack\n", 1935 "flags %d -> stack\n",
1936 udf_rw16(s_ad.loc.part_num), udf_rw32(s_ad.loc.lb_num), 1936 udf_rw16(s_ad.loc.part_num), udf_rw32(s_ad.loc.lb_num),
1937 UDF_EXT_LEN(udf_rw32(s_ad.len)), 1937 UDF_EXT_LEN(udf_rw32(s_ad.len)),
1938 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30)); 1938 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30));
1939 } 1939 }
1940 1940
1941 /* 4) pop replaced length */ 1941 /* 4) pop replaced length */
1942 slot = restart_slot; 1942 slot = restart_slot;
1943 foffset = restart_foffset; 1943 foffset = restart_foffset;
1944 1944
1945 replace_len = till - foffset; /* total amount of bytes to pop */ 1945 replace_len = till - foffset; /* total amount of bytes to pop */
1946 slot_offset = from - foffset; /* offset in first encounted slot */ 1946 slot_offset = from - foffset; /* offset in first encounted slot */
1947 KASSERT((slot_offset % lb_size) == 0); 1947 KASSERT((slot_offset % lb_size) == 0);
1948 1948
1949 for (;;) { 1949 for (;;) {
1950 udf_get_adslot(udf_node, slot, &s_ad, &eof); 1950 udf_get_adslot(udf_node, slot, &s_ad, &eof);
1951 if (eof) 1951 if (eof)
1952 break; 1952 break;
1953 1953
1954 len = udf_rw32(s_ad.len); 1954 len = udf_rw32(s_ad.len);
1955 flags = UDF_EXT_FLAGS(len); 1955 flags = UDF_EXT_FLAGS(len);
1956 len = UDF_EXT_LEN(len); 1956 len = UDF_EXT_LEN(len);
1957 lb_num = udf_rw32(s_ad.loc.lb_num); 1957 lb_num = udf_rw32(s_ad.loc.lb_num);
1958 1958
1959 if (flags == UDF_EXT_REDIRECT) { 1959 if (flags == UDF_EXT_REDIRECT) {
1960 slot++; 1960 slot++;
1961 continue; 1961 continue;
1962 } 1962 }
1963 1963
1964 DPRINTF(ALLOC, ("\t4i: got slot %d, slot_offset %d, " 1964 DPRINTF(ALLOC, ("\t4i: got slot %d, slot_offset %d, "
1965 "replace_len %d, " 1965 "replace_len %d, "
1966 "vp %d, lb %d, len %d, flags %d\n", 1966 "vp %d, lb %d, len %d, flags %d\n",
1967 slot, slot_offset, replace_len, 1967 slot, slot_offset, replace_len,
1968 udf_rw16(s_ad.loc.part_num), 1968 udf_rw16(s_ad.loc.part_num),
1969 udf_rw32(s_ad.loc.lb_num), 1969 udf_rw32(s_ad.loc.lb_num),
1970 UDF_EXT_LEN(udf_rw32(s_ad.len)), 1970 UDF_EXT_LEN(udf_rw32(s_ad.len)),
1971 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30)); 1971 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30));
1972 1972
1973 /* adjust for slot offset */ 1973 /* adjust for slot offset */
1974 if (slot_offset) { 1974 if (slot_offset) {
1975 DPRINTF(ALLOC, ("\t4s: skipping %d\n", slot_offset)); 1975 DPRINTF(ALLOC, ("\t4s: skipping %d\n", slot_offset));
1976 lb_num += slot_offset / lb_size; 1976 lb_num += slot_offset / lb_size;
1977 len -= slot_offset; 1977 len -= slot_offset;
1978 foffset += slot_offset; 1978 foffset += slot_offset;
1979 replace_len -= slot_offset; 1979 replace_len -= slot_offset;
1980 1980
1981 /* mark adjusted */ 1981 /* mark adjusted */
1982 slot_offset = 0; 1982 slot_offset = 0;
1983 } 1983 }
1984 1984
1985 /* advance for (the rest of) this slot */ 1985 /* advance for (the rest of) this slot */
1986 replace = MIN(len, replace_len); 1986 replace = MIN(len, replace_len);
1987 DPRINTF(ALLOC, ("\t4d: replacing %d\n", replace)); 1987 DPRINTF(ALLOC, ("\t4d: replacing %d\n", replace));
1988 1988
1989 /* advance for this slot */ 1989 /* advance for this slot */
1990 if (replace) { 1990 if (replace) {
1991 /* note: dont round DOWN on num_lb since we then 1991 /* note: dont round DOWN on num_lb since we then
1992 * forget the last partial one */ 1992 * forget the last partial one */
1993 num_lb = (replace + lb_size - 1) / lb_size; 1993 num_lb = (replace + lb_size - 1) / lb_size;
1994 if (flags != UDF_EXT_FREE) { 1994 if (flags != UDF_EXT_FREE) {
1995 udf_free_allocated_space(ump, lb_num, 1995 udf_free_allocated_space(ump, lb_num,
1996 udf_rw16(s_ad.loc.part_num), num_lb); 1996 udf_rw16(s_ad.loc.part_num), num_lb);
1997 } 1997 }
1998 lb_num += num_lb; 1998 lb_num += num_lb;
1999 len -= replace; 1999 len -= replace;
2000 foffset += replace; 2000 foffset += replace;
2001 replace_len -= replace; 2001 replace_len -= replace;
2002 } 2002 }
2003 2003
2004 /* do we have a slot tail ? */ 2004 /* do we have a slot tail ? */
2005 if (len) { 2005 if (len) {
2006 KASSERT(foffset % lb_size == 0); 2006 KASSERT(foffset % lb_size == 0);
2007 2007
2008 /* we arrived at our point, push remainder */ 2008 /* we arrived at our point, push remainder */
2009 s_ad.len = udf_rw32(len | flags); 2009 s_ad.len = udf_rw32(len | flags);
2010 s_ad.loc.lb_num = udf_rw32(lb_num); 2010 s_ad.loc.lb_num = udf_rw32(lb_num);
2011 if (flags == UDF_EXT_FREE) 2011 if (flags == UDF_EXT_FREE)
2012 s_ad.loc.lb_num = udf_rw32(0); 2012 s_ad.loc.lb_num = udf_rw32(0);
2013 node_ad_cpy[cpy_slot++] = s_ad; 2013 node_ad_cpy[cpy_slot++] = s_ad;
2014 foffset += len; 2014 foffset += len;
2015 slot++; 2015 slot++;
2016 2016
2017 DPRINTF(ALLOC, ("\t4: vp %d, lb %d, len %d, flags %d " 2017 DPRINTF(ALLOC, ("\t4: vp %d, lb %d, len %d, flags %d "
2018 "-> stack\n", 2018 "-> stack\n",
2019 udf_rw16(s_ad.loc.part_num), 2019 udf_rw16(s_ad.loc.part_num),
2020 udf_rw32(s_ad.loc.lb_num), 2020 udf_rw32(s_ad.loc.lb_num),
2021 UDF_EXT_LEN(udf_rw32(s_ad.len)), 2021 UDF_EXT_LEN(udf_rw32(s_ad.len)),
2022 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30)); 2022 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30));
2023 break; 2023 break;
2024 } 2024 }
2025 2025
2026 slot++; 2026 slot++;
2027 } 2027 }
2028 2028
2029 /* 5) copy remainder */ 2029 /* 5) copy remainder */
2030 for (;;) { 2030 for (;;) {
2031 udf_get_adslot(udf_node, slot, &s_ad, &eof); 2031 udf_get_adslot(udf_node, slot, &s_ad, &eof);
2032 if (eof) 2032 if (eof)
2033 break; 2033 break;
2034 2034
2035 len = udf_rw32(s_ad.len); 2035 len = udf_rw32(s_ad.len);
2036 flags = UDF_EXT_FLAGS(len); 2036 flags = UDF_EXT_FLAGS(len);
2037 len = UDF_EXT_LEN(len); 2037 len = UDF_EXT_LEN(len);
2038 2038
2039 if (flags == UDF_EXT_REDIRECT) { 2039 if (flags == UDF_EXT_REDIRECT) {
2040 slot++; 2040 slot++;
2041 continue; 2041 continue;
2042 } 2042 }
2043 2043
2044 node_ad_cpy[cpy_slot++] = s_ad; 2044 node_ad_cpy[cpy_slot++] = s_ad;
2045 2045
2046 DPRINTF(ALLOC, ("\t5: insert new mapping " 2046 DPRINTF(ALLOC, ("\t5: insert new mapping "
2047 "vp %d lb %d, len %d, flags %d " 2047 "vp %d lb %d, len %d, flags %d "
2048 "-> stack\n", 2048 "-> stack\n",
2049 udf_rw16(s_ad.loc.part_num), 2049 udf_rw16(s_ad.loc.part_num),
2050 udf_rw32(s_ad.loc.lb_num), 2050 udf_rw32(s_ad.loc.lb_num),
2051 UDF_EXT_LEN(udf_rw32(s_ad.len)), 2051 UDF_EXT_LEN(udf_rw32(s_ad.len)),
2052 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30)); 2052 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30));
2053 2053
2054 slot++; 2054 slot++;
2055 } 2055 }
2056 2056
2057 /* 6) reset node descriptors */ 2057 /* 6) reset node descriptors */
2058 udf_wipe_adslots(udf_node); 2058 udf_wipe_adslots(udf_node);
2059 2059
2060 /* 7) copy back extents; merge when possible. Recounting on the fly */ 2060 /* 7) copy back extents; merge when possible. Recounting on the fly */
2061 cpy_slots = cpy_slot; 2061 cpy_slots = cpy_slot;
2062 2062
2063 c_ad = node_ad_cpy[0]; 2063 c_ad = node_ad_cpy[0];
2064 slot = 0; 2064 slot = 0;
2065 DPRINTF(ALLOC, ("\t7s: stack -> got mapping vp %d " 2065 DPRINTF(ALLOC, ("\t7s: stack -> got mapping vp %d "
2066 "lb %d, len %d, flags %d\n", 2066 "lb %d, len %d, flags %d\n",
2067 udf_rw16(c_ad.loc.part_num), 2067 udf_rw16(c_ad.loc.part_num),
2068 udf_rw32(c_ad.loc.lb_num), 2068 udf_rw32(c_ad.loc.lb_num),
2069 UDF_EXT_LEN(udf_rw32(c_ad.len)), 2069 UDF_EXT_LEN(udf_rw32(c_ad.len)),
2070 UDF_EXT_FLAGS(udf_rw32(c_ad.len)) >> 30)); 2070 UDF_EXT_FLAGS(udf_rw32(c_ad.len)) >> 30));
2071 2071
2072 for (cpy_slot = 1; cpy_slot < cpy_slots; cpy_slot++) { 2072 for (cpy_slot = 1; cpy_slot < cpy_slots; cpy_slot++) {
2073 s_ad = node_ad_cpy[cpy_slot]; 2073 s_ad = node_ad_cpy[cpy_slot];
2074 2074
2075 DPRINTF(ALLOC, ("\t7i: stack -> got mapping vp %d " 2075 DPRINTF(ALLOC, ("\t7i: stack -> got mapping vp %d "
2076 "lb %d, len %d, flags %d\n", 2076 "lb %d, len %d, flags %d\n",
2077 udf_rw16(s_ad.loc.part_num), 2077 udf_rw16(s_ad.loc.part_num),
2078 udf_rw32(s_ad.loc.lb_num), 2078 udf_rw32(s_ad.loc.lb_num),
2079 UDF_EXT_LEN(udf_rw32(s_ad.len)), 2079 UDF_EXT_LEN(udf_rw32(s_ad.len)),
2080 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30)); 2080 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30));
2081 2081
2082 /* see if we can merge */ 2082 /* see if we can merge */
2083 if (udf_ads_merge(lb_size, &c_ad, &s_ad)) { 2083 if (udf_ads_merge(lb_size, &c_ad, &s_ad)) {
2084 /* not mergable (anymore) */ 2084 /* not mergable (anymore) */
2085 DPRINTF(ALLOC, ("\t7: appending vp %d lb %d, " 2085 DPRINTF(ALLOC, ("\t7: appending vp %d lb %d, "
2086 "len %d, flags %d\n", 2086 "len %d, flags %d\n",
2087 udf_rw16(c_ad.loc.part_num), 2087 udf_rw16(c_ad.loc.part_num),
2088 udf_rw32(c_ad.loc.lb_num), 2088 udf_rw32(c_ad.loc.lb_num),
2089 UDF_EXT_LEN(udf_rw32(c_ad.len)), 2089 UDF_EXT_LEN(udf_rw32(c_ad.len)),
2090 UDF_EXT_FLAGS(udf_rw32(c_ad.len)) >> 30)); 2090 UDF_EXT_FLAGS(udf_rw32(c_ad.len)) >> 30));
2091 2091
2092 error = udf_append_adslot(udf_node, &slot, &c_ad); 2092 error = udf_append_adslot(udf_node, &slot, &c_ad);
2093 if (error) { 2093 if (error) {
2094 buf->b_error = error; 2094 buf->b_error = error;
2095 goto out; 2095 goto out;
2096 } 2096 }
2097 c_ad = s_ad; 2097 c_ad = s_ad;
2098 slot++; 2098 slot++;
2099 } 2099 }
2100 } 2100 }
2101 2101
2102 /* 8) push rest slot (if any) */ 2102 /* 8) push rest slot (if any) */
2103 if (UDF_EXT_LEN(c_ad.len) > 0) { 2103 if (UDF_EXT_LEN(c_ad.len) > 0) {
2104 DPRINTF(ALLOC, ("\t8: last append vp %d lb %d, " 2104 DPRINTF(ALLOC, ("\t8: last append vp %d lb %d, "
2105 "len %d, flags %d\n", 2105 "len %d, flags %d\n",
2106 udf_rw16(c_ad.loc.part_num), 2106 udf_rw16(c_ad.loc.part_num),
2107 udf_rw32(c_ad.loc.lb_num), 2107 udf_rw32(c_ad.loc.lb_num),
2108 UDF_EXT_LEN(udf_rw32(c_ad.len)), 2108 UDF_EXT_LEN(udf_rw32(c_ad.len)),
2109 UDF_EXT_FLAGS(udf_rw32(c_ad.len)) >> 30)); 2109 UDF_EXT_FLAGS(udf_rw32(c_ad.len)) >> 30));
2110 2110
2111 error = udf_append_adslot(udf_node, &slot, &c_ad); 2111 error = udf_append_adslot(udf_node, &slot, &c_ad);
2112 if (error) { 2112 if (error) {
2113 buf->b_error = error; 2113 buf->b_error = error;
2114 goto out; 2114 goto out;
2115 } 2115 }
2116 } 2116 }
2117 2117
2118out: 2118out:
2119 udf_count_alloc_exts(udf_node); 2119 udf_count_alloc_exts(udf_node);
2120 2120
2121 /* the node's descriptors should now be sane */ 2121 /* the node's descriptors should now be sane */
2122 udf_node_sanity_check(udf_node, &new_inflen, &new_lbrec); 2122 udf_node_sanity_check(udf_node, &new_inflen, &new_lbrec);
2123 UDF_UNLOCK_NODE(udf_node, 0); 2123 UDF_UNLOCK_NODE(udf_node, 0);
2124 2124
2125 KASSERT(orig_inflen == new_inflen); 2125 KASSERT(orig_inflen == new_inflen);
2126 KASSERT(new_lbrec >= orig_lbrec); 2126 KASSERT(new_lbrec >= orig_lbrec);
2127 2127
2128 return; 2128 return;
2129} 2129}
2130 2130
2131/* --------------------------------------------------------------------- */ 2131/* --------------------------------------------------------------------- */
2132 2132
2133int 2133int
2134udf_grow_node(struct udf_node *udf_node, uint64_t new_size) 2134udf_grow_node(struct udf_node *udf_node, uint64_t new_size)
2135{ 2135{
2136 union dscrptr *dscr; 2136 union dscrptr *dscr;
2137 struct vnode *vp = udf_node->vnode; 2137 struct vnode *vp = udf_node->vnode;
2138 struct udf_mount *ump = udf_node->ump; 2138 struct udf_mount *ump = udf_node->ump;
2139 struct file_entry *fe; 2139 struct file_entry *fe;
2140 struct extfile_entry *efe; 2140 struct extfile_entry *efe;
2141 struct icb_tag *icbtag; 2141 struct icb_tag *icbtag;
2142 struct long_ad c_ad, s_ad; 2142 struct long_ad c_ad, s_ad;
2143 uint64_t size_diff, old_size, inflen, objsize, chunk, append_len; 2143 uint64_t size_diff, old_size, inflen, objsize, chunk, append_len;
2144 uint64_t foffset, end_foffset; 2144 uint64_t foffset, end_foffset;
2145 uint64_t orig_inflen, orig_lbrec, new_inflen, new_lbrec; 2145 uint64_t orig_inflen, orig_lbrec, new_inflen, new_lbrec;
2146 uint32_t lb_size, dscr_size, crclen, lastblock_grow; 2146 uint32_t lb_size, dscr_size, crclen, lastblock_grow;
2147 uint32_t icbflags, len, flags, max_len; 2147 uint32_t icbflags, len, flags, max_len;
2148 uint32_t max_l_ad, l_ad, l_ea; 2148 uint32_t max_l_ad, l_ad, l_ea;
2149 uint16_t my_part, dst_part; 2149 uint16_t my_part, dst_part;
2150 uint8_t *data_pos, *evacuated_data; 2150 uint8_t *data_pos, *evacuated_data;
2151 int addr_type; 2151 int addr_type;
2152 int slot, cpy_slot; 2152 int slot, cpy_slot;
2153 int isdir, eof, error; 2153 int isdir, eof, error;
2154 2154
2155 DPRINTF(ALLOC, ("udf_grow_node\n")); 2155 DPRINTF(ALLOC, ("udf_grow_node\n"));
2156 2156
2157 UDF_LOCK_NODE(udf_node, 0); 2157 UDF_LOCK_NODE(udf_node, 0);
2158 udf_node_sanity_check(udf_node, &orig_inflen, &orig_lbrec); 2158 udf_node_sanity_check(udf_node, &orig_inflen, &orig_lbrec);
2159 2159
2160 lb_size = udf_rw32(ump->logical_vol->lb_size); 2160 lb_size = udf_rw32(ump->logical_vol->lb_size);
2161 max_len = ((UDF_EXT_MAXLEN / lb_size) * lb_size); 2161 max_len = ((UDF_EXT_MAXLEN / lb_size) * lb_size);
2162 2162
2163 fe = udf_node->fe; 2163 fe = udf_node->fe;
2164 efe = udf_node->efe; 2164 efe = udf_node->efe;
2165 if (fe) { 2165 if (fe) {
2166 dscr = (union dscrptr *) fe; 2166 dscr = (union dscrptr *) fe;
2167 icbtag = &fe->icbtag; 2167 icbtag = &fe->icbtag;
2168 inflen = udf_rw64(fe->inf_len); 2168 inflen = udf_rw64(fe->inf_len);
2169 objsize = inflen; 2169 objsize = inflen;
2170 dscr_size = sizeof(struct file_entry) -1; 2170 dscr_size = sizeof(struct file_entry) -1;
2171 l_ea = udf_rw32(fe->l_ea); 2171 l_ea = udf_rw32(fe->l_ea);
2172 l_ad = udf_rw32(fe->l_ad); 2172 l_ad = udf_rw32(fe->l_ad);
2173 } else { 2173 } else {
2174 dscr = (union dscrptr *) efe; 2174 dscr = (union dscrptr *) efe;
2175 icbtag = &efe->icbtag; 2175 icbtag = &efe->icbtag;
2176 inflen = udf_rw64(efe->inf_len); 2176 inflen = udf_rw64(efe->inf_len);
2177 objsize = udf_rw64(efe->obj_size); 2177 objsize = udf_rw64(efe->obj_size);
2178 dscr_size = sizeof(struct extfile_entry) -1; 2178 dscr_size = sizeof(struct extfile_entry) -1;
2179 l_ea = udf_rw32(efe->l_ea); 2179 l_ea = udf_rw32(efe->l_ea);
2180 l_ad = udf_rw32(efe->l_ad); 2180 l_ad = udf_rw32(efe->l_ad);
2181 } 2181 }
2182 data_pos = (uint8_t *) dscr + dscr_size + l_ea; 2182 data_pos = (uint8_t *) dscr + dscr_size + l_ea;
2183 max_l_ad = lb_size - dscr_size - l_ea; 2183 max_l_ad = lb_size - dscr_size - l_ea;
2184 2184
2185 icbflags = udf_rw16(icbtag->flags); 2185 icbflags = udf_rw16(icbtag->flags);
2186 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK; 2186 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK;
2187 2187
2188 old_size = inflen; 2188 old_size = inflen;
2189 size_diff = new_size - old_size; 2189 size_diff = new_size - old_size;
2190 2190
2191 DPRINTF(ALLOC, ("\tfrom %"PRIu64" to %"PRIu64"\n", old_size, new_size)); 2191 DPRINTF(ALLOC, ("\tfrom %"PRIu64" to %"PRIu64"\n", old_size, new_size));
2192 2192
2193 evacuated_data = NULL; 2193 evacuated_data = NULL;
2194 if (addr_type == UDF_ICB_INTERN_ALLOC) { 2194 if (addr_type == UDF_ICB_INTERN_ALLOC) {
2195 if (l_ad + size_diff <= max_l_ad) { 2195 if (l_ad + size_diff <= max_l_ad) {
2196 /* only reflect size change directly in the node */ 2196 /* only reflect size change directly in the node */
2197 inflen += size_diff; 2197 inflen += size_diff;
2198 objsize += size_diff; 2198 objsize += size_diff;
2199 l_ad += size_diff; 2199 l_ad += size_diff;
2200 crclen = dscr_size - UDF_DESC_TAG_LENGTH + l_ea + l_ad; 2200 crclen = dscr_size - UDF_DESC_TAG_LENGTH + l_ea + l_ad;
2201 if (fe) { 2201 if (fe) {
2202 fe->inf_len = udf_rw64(inflen); 2202 fe->inf_len = udf_rw64(inflen);
2203 fe->l_ad = udf_rw32(l_ad); 2203 fe->l_ad = udf_rw32(l_ad);
2204 fe->tag.desc_crc_len = udf_rw16(crclen); 2204 fe->tag.desc_crc_len = udf_rw16(crclen);
2205 } else { 2205 } else {
2206 efe->inf_len = udf_rw64(inflen); 2206 efe->inf_len = udf_rw64(inflen);
2207 efe->obj_size = udf_rw64(objsize); 2207 efe->obj_size = udf_rw64(objsize);
2208 efe->l_ad = udf_rw32(l_ad); 2208 efe->l_ad = udf_rw32(l_ad);
2209 efe->tag.desc_crc_len = udf_rw16(crclen); 2209 efe->tag.desc_crc_len = udf_rw16(crclen);
2210 } 2210 }
2211 error = 0; 2211 error = 0;
2212 2212
2213 /* set new size for uvm */ 2213 /* set new size for uvm */
2214 uvm_vnp_setsize(vp, old_size); 2214 uvm_vnp_setsize(vp, old_size);
2215 uvm_vnp_setwritesize(vp, new_size); 2215 uvm_vnp_setwritesize(vp, new_size);
2216 2216
2217#if 0 2217#if 0
2218 /* zero append space in buffer */ 2218 /* zero append space in buffer */
2219 uvm_vnp_zerorange(vp, old_size, new_size - old_size); 2219 uvm_vnp_zerorange(vp, old_size, new_size - old_size);
2220#endif 2220#endif
2221  2221
2222 udf_node_sanity_check(udf_node, &new_inflen, &new_lbrec); 2222 udf_node_sanity_check(udf_node, &new_inflen, &new_lbrec);
2223 2223
2224 /* unlock */ 2224 /* unlock */
2225 UDF_UNLOCK_NODE(udf_node, 0); 2225 UDF_UNLOCK_NODE(udf_node, 0);
2226 2226
2227 KASSERT(new_inflen == orig_inflen + size_diff); 2227 KASSERT(new_inflen == orig_inflen + size_diff);
2228 KASSERT(new_lbrec == orig_lbrec); 2228 KASSERT(new_lbrec == orig_lbrec);
2229 KASSERT(new_lbrec == 0); 2229 KASSERT(new_lbrec == 0);
2230 return 0; 2230 return 0;
2231 } 2231 }
2232 2232
2233 DPRINTF(ALLOC, ("\tCONVERT from internal\n")); 2233 DPRINTF(ALLOC, ("\tCONVERT from internal\n"));
2234 2234
2235 if (old_size > 0) { 2235 if (old_size > 0) {
2236 /* allocate some space and copy in the stuff to keep */ 2236 /* allocate some space and copy in the stuff to keep */
2237 evacuated_data = malloc(lb_size, M_UDFTEMP, M_WAITOK); 2237 evacuated_data = malloc(lb_size, M_UDFTEMP, M_WAITOK);
2238 memset(evacuated_data, 0, lb_size); 2238 memset(evacuated_data, 0, lb_size);
2239 2239
2240 /* node is locked, so safe to exit mutex */ 2240 /* node is locked, so safe to exit mutex */
2241 UDF_UNLOCK_NODE(udf_node, 0); 2241 UDF_UNLOCK_NODE(udf_node, 0);
2242 2242
2243 /* read in using the `normal' vn_rdwr() */ 2243 /* read in using the `normal' vn_rdwr() */
2244 error = vn_rdwr(UIO_READ, udf_node->vnode, 2244 error = vn_rdwr(UIO_READ, udf_node->vnode,
2245 evacuated_data, old_size, 0,  2245 evacuated_data, old_size, 0,
2246 UIO_SYSSPACE, IO_ALTSEMANTICS | IO_NODELOCKED, 2246 UIO_SYSSPACE, IO_ALTSEMANTICS | IO_NODELOCKED,
2247 FSCRED, NULL, NULL); 2247 FSCRED, NULL, NULL);
2248 2248
2249 /* enter again */ 2249 /* enter again */
2250 UDF_LOCK_NODE(udf_node, 0); 2250 UDF_LOCK_NODE(udf_node, 0);
2251 } 2251 }
2252 2252
2253 /* convert to a normal alloc and select type */ 2253 /* convert to a normal alloc and select type */
2254 isdir = (vp->v_type == VDIR); 2254 isdir = (vp->v_type == VDIR);
2255 my_part = udf_rw16(udf_node->loc.loc.part_num); 2255 my_part = udf_rw16(udf_node->loc.loc.part_num);
2256 dst_part = isdir? ump->fids_part : ump->data_part; 2256 dst_part = isdir ? ump->fids_part : ump->data_part;
2257 addr_type = UDF_ICB_SHORT_ALLOC; 2257 addr_type = UDF_ICB_SHORT_ALLOC;
2258 if (dst_part != my_part) 2258 if (dst_part != my_part)
2259 addr_type = UDF_ICB_LONG_ALLOC; 2259 addr_type = UDF_ICB_LONG_ALLOC;
2260 2260
2261 icbflags &= ~UDF_ICB_TAG_FLAGS_ALLOC_MASK; 2261 icbflags &= ~UDF_ICB_TAG_FLAGS_ALLOC_MASK;
2262 icbflags |= addr_type; 2262 icbflags |= addr_type;
2263 icbtag->flags = udf_rw16(icbflags); 2263 icbtag->flags = udf_rw16(icbflags);
2264 2264
2265 /* wipe old descriptor space */ 2265 /* wipe old descriptor space */
2266 udf_wipe_adslots(udf_node); 2266 udf_wipe_adslots(udf_node);
2267 2267
2268 memset(&c_ad, 0, sizeof(struct long_ad)); 2268 memset(&c_ad, 0, sizeof(struct long_ad));
2269 c_ad.len = udf_rw32(old_size | UDF_EXT_FREE); 2269 c_ad.len = udf_rw32(old_size | UDF_EXT_FREE);
2270 c_ad.loc.part_num = udf_rw16(0); /* not relevant */ 2270 c_ad.loc.part_num = udf_rw16(0); /* not relevant */
2271 c_ad.loc.lb_num = udf_rw32(0); /* not relevant */ 2271 c_ad.loc.lb_num = udf_rw32(0); /* not relevant */
2272 2272
2273 slot = 0; 2273 slot = 0;
2274 } else { 2274 } else {
2275 /* goto the last entry (if any) */ 2275 /* goto the last entry (if any) */
2276 slot = 0; 2276 slot = 0;
2277 cpy_slot = 0; 2277 cpy_slot = 0;
2278 foffset = 0; 2278 foffset = 0;
2279 memset(&c_ad, 0, sizeof(struct long_ad)); 2279 memset(&c_ad, 0, sizeof(struct long_ad));
2280 for (;;) { 2280 for (;;) {
2281 udf_get_adslot(udf_node, slot, &c_ad, &eof); 2281 udf_get_adslot(udf_node, slot, &c_ad, &eof);
2282 if (eof) 2282 if (eof)
2283 break; 2283 break;
2284 2284
2285 len = udf_rw32(c_ad.len); 2285 len = udf_rw32(c_ad.len);
2286 flags = UDF_EXT_FLAGS(len); 2286 flags = UDF_EXT_FLAGS(len);
2287 len = UDF_EXT_LEN(len); 2287 len = UDF_EXT_LEN(len);
2288 2288
2289 end_foffset = foffset + len; 2289 end_foffset = foffset + len;
2290 if (flags != UDF_EXT_REDIRECT) 2290 if (flags != UDF_EXT_REDIRECT)
2291 foffset = end_foffset; 2291 foffset = end_foffset;
2292 2292
2293 slot++; 2293 slot++;
2294 } 2294 }
2295 /* at end of adslots */ 2295 /* at end of adslots */
2296 2296
2297 /* special case if the old size was zero, then there is no last slot */ 2297 /* special case if the old size was zero, then there is no last slot */
2298 if (old_size == 0) { 2298 if (old_size == 0) {
2299 c_ad.len = udf_rw32(0 | UDF_EXT_FREE); 2299 c_ad.len = udf_rw32(0 | UDF_EXT_FREE);
2300 c_ad.loc.part_num = udf_rw16(0); /* not relevant */ 2300 c_ad.loc.part_num = udf_rw16(0); /* not relevant */
2301 c_ad.loc.lb_num = udf_rw32(0); /* not relevant */ 2301 c_ad.loc.lb_num = udf_rw32(0); /* not relevant */
2302 } else { 2302 } else {
2303 /* refetch last slot */ 2303 /* refetch last slot */
2304 slot--; 2304 slot--;
2305 udf_get_adslot(udf_node, slot, &c_ad, &eof); 2305 udf_get_adslot(udf_node, slot, &c_ad, &eof);
2306 } 2306 }
2307 } 2307 }
2308 2308
2309 /* 2309 /*
2310 * If the length of the last slot is not a multiple of lb_size, adjust 2310 * If the length of the last slot is not a multiple of lb_size, adjust
2311 * length so that it is; don't forget to adjust `append_len'! relevant for 2311 * length so that it is; don't forget to adjust `append_len'! relevant for
2312 * extending existing files 2312 * extending existing files
2313 */ 2313 */
2314 len = udf_rw32(c_ad.len); 2314 len = udf_rw32(c_ad.len);
2315 flags = UDF_EXT_FLAGS(len); 2315 flags = UDF_EXT_FLAGS(len);
2316 len = UDF_EXT_LEN(len); 2316 len = UDF_EXT_LEN(len);
2317 2317
2318 lastblock_grow = 0; 2318 lastblock_grow = 0;
2319 if (len % lb_size > 0) { 2319 if (len % lb_size > 0) {
2320 lastblock_grow = lb_size - (len % lb_size); 2320 lastblock_grow = lb_size - (len % lb_size);
2321 lastblock_grow = MIN(size_diff, lastblock_grow); 2321 lastblock_grow = MIN(size_diff, lastblock_grow);
2322 len += lastblock_grow; 2322 len += lastblock_grow;
2323 c_ad.len = udf_rw32(len | flags); 2323 c_ad.len = udf_rw32(len | flags);
2324 2324
2325 /* TODO zero appened space in buffer! */ 2325 /* TODO zero appened space in buffer! */
2326 /* using uvm_vnp_zerorange(vp, old_size, new_size - old_size); ? */ 2326 /* using uvm_vnp_zerorange(vp, old_size, new_size - old_size); ? */
2327 } 2327 }
2328 memset(&s_ad, 0, sizeof(struct long_ad)); 2328 memset(&s_ad, 0, sizeof(struct long_ad));
2329 2329
2330 /* size_diff can be bigger than allowed, so grow in chunks */ 2330 /* size_diff can be bigger than allowed, so grow in chunks */
2331 append_len = size_diff - lastblock_grow; 2331 append_len = size_diff - lastblock_grow;
2332 while (append_len > 0) { 2332 while (append_len > 0) {
2333 chunk = MIN(append_len, max_len); 2333 chunk = MIN(append_len, max_len);
2334 s_ad.len = udf_rw32(chunk | UDF_EXT_FREE); 2334 s_ad.len = udf_rw32(chunk | UDF_EXT_FREE);
2335 s_ad.loc.part_num = udf_rw16(0); 2335 s_ad.loc.part_num = udf_rw16(0);
2336 s_ad.loc.lb_num = udf_rw32(0); 2336 s_ad.loc.lb_num = udf_rw32(0);
2337 2337
2338 if (udf_ads_merge(lb_size, &c_ad, &s_ad)) { 2338 if (udf_ads_merge(lb_size, &c_ad, &s_ad)) {
2339 /* not mergable (anymore) */ 2339 /* not mergable (anymore) */
2340 error = udf_append_adslot(udf_node, &slot, &c_ad); 2340 error = udf_append_adslot(udf_node, &slot, &c_ad);
2341 if (error) 2341 if (error)
2342 goto errorout; 2342 goto errorout;
2343 slot++; 2343 slot++;
2344 c_ad = s_ad; 2344 c_ad = s_ad;
2345 memset(&s_ad, 0, sizeof(struct long_ad)); 2345 memset(&s_ad, 0, sizeof(struct long_ad));
2346 } 2346 }
2347 append_len -= chunk; 2347 append_len -= chunk;
2348 } 2348 }
2349 2349
2350 /* if there is a rest piece in the accumulator, append it */ 2350 /* if there is a rest piece in the accumulator, append it */
2351 if (UDF_EXT_LEN(udf_rw32(c_ad.len)) > 0) { 2351 if (UDF_EXT_LEN(udf_rw32(c_ad.len)) > 0) {
2352 error = udf_append_adslot(udf_node, &slot, &c_ad); 2352 error = udf_append_adslot(udf_node, &slot, &c_ad);
2353 if (error) 2353 if (error)
2354 goto errorout; 2354 goto errorout;
2355 slot++; 2355 slot++;
2356 } 2356 }
2357 2357
2358 /* if there is a rest piece that didn't fit, append it */ 2358 /* if there is a rest piece that didn't fit, append it */
2359 if (UDF_EXT_LEN(udf_rw32(s_ad.len)) > 0) { 2359 if (UDF_EXT_LEN(udf_rw32(s_ad.len)) > 0) {
2360 error = udf_append_adslot(udf_node, &slot, &s_ad); 2360 error = udf_append_adslot(udf_node, &slot, &s_ad);
2361 if (error) 2361 if (error)
2362 goto errorout; 2362 goto errorout;
2363 slot++; 2363 slot++;
2364 } 2364 }
2365 2365
2366 inflen += size_diff; 2366 inflen += size_diff;
2367 objsize += size_diff; 2367 objsize += size_diff;
2368 if (fe) { 2368 if (fe) {
2369 fe->inf_len = udf_rw64(inflen); 2369 fe->inf_len = udf_rw64(inflen);
2370 } else { 2370 } else {
2371 efe->inf_len = udf_rw64(inflen); 2371 efe->inf_len = udf_rw64(inflen);
2372 efe->obj_size = udf_rw64(objsize); 2372 efe->obj_size = udf_rw64(objsize);
2373 } 2373 }
2374 error = 0; 2374 error = 0;
2375 2375
2376 if (evacuated_data) { 2376 if (evacuated_data) {
2377 /* set new write size for uvm */ 2377 /* set new write size for uvm */
2378 uvm_vnp_setwritesize(vp, old_size); 2378 uvm_vnp_setwritesize(vp, old_size);
2379 2379
2380 /* write out evacuated data */ 2380 /* write out evacuated data */
2381 error = vn_rdwr(UIO_WRITE, udf_node->vnode, 2381 error = vn_rdwr(UIO_WRITE, udf_node->vnode,
2382 evacuated_data, old_size, 0,  2382 evacuated_data, old_size, 0,
2383 UIO_SYSSPACE, IO_ALTSEMANTICS | IO_NODELOCKED, 2383 UIO_SYSSPACE, IO_ALTSEMANTICS | IO_NODELOCKED,
2384 FSCRED, NULL, NULL); 2384 FSCRED, NULL, NULL);
2385 uvm_vnp_setsize(vp, old_size); 2385 uvm_vnp_setsize(vp, old_size);
2386 } 2386 }
2387 2387
2388errorout: 2388errorout:
2389 if (evacuated_data) 2389 if (evacuated_data)
2390 free(evacuated_data, M_UDFTEMP); 2390 free(evacuated_data, M_UDFTEMP);
2391 2391
2392 udf_count_alloc_exts(udf_node); 2392 udf_count_alloc_exts(udf_node);
2393 2393
2394 udf_node_sanity_check(udf_node, &new_inflen, &new_lbrec); 2394 udf_node_sanity_check(udf_node, &new_inflen, &new_lbrec);
2395 UDF_UNLOCK_NODE(udf_node, 0); 2395 UDF_UNLOCK_NODE(udf_node, 0);
2396 2396
2397 KASSERT(new_inflen == orig_inflen + size_diff); 2397 KASSERT(new_inflen == orig_inflen + size_diff);
2398 KASSERT(new_lbrec == orig_lbrec); 2398 KASSERT(new_lbrec == orig_lbrec);
2399 2399
2400 return error; 2400 return error;
2401} 2401}
2402 2402
2403/* --------------------------------------------------------------------- */ 2403/* --------------------------------------------------------------------- */
2404 2404
2405int 2405int
2406udf_shrink_node(struct udf_node *udf_node, uint64_t new_size) 2406udf_shrink_node(struct udf_node *udf_node, uint64_t new_size)
2407{ 2407{
2408 struct vnode *vp = udf_node->vnode; 2408 struct vnode *vp = udf_node->vnode;
2409 struct udf_mount *ump = udf_node->ump; 2409 struct udf_mount *ump = udf_node->ump;
2410 struct file_entry *fe; 2410 struct file_entry *fe;
2411 struct extfile_entry *efe; 2411 struct extfile_entry *efe;
2412 struct icb_tag *icbtag; 2412 struct icb_tag *icbtag;
2413 struct long_ad c_ad, s_ad, *node_ad_cpy; 2413 struct long_ad c_ad, s_ad, *node_ad_cpy;
2414 uint64_t size_diff, old_size, inflen, objsize; 2414 uint64_t size_diff, old_size, inflen, objsize;
2415 uint64_t foffset, end_foffset; 2415 uint64_t foffset, end_foffset;
2416 uint64_t orig_inflen, orig_lbrec, new_inflen, new_lbrec; 2416 uint64_t orig_inflen, orig_lbrec, new_inflen, new_lbrec;
2417 uint32_t lb_size, dscr_size, crclen; 2417 uint32_t lb_size, dscr_size, crclen;
2418 uint32_t slot_offset; 2418 uint32_t slot_offset;
2419 uint32_t len, flags, max_len; 2419 uint32_t len, flags, max_len;
2420 uint32_t num_lb, lb_num; 2420 uint32_t num_lb, lb_num;
2421 uint32_t max_l_ad, l_ad, l_ea; 2421 uint32_t max_l_ad, l_ad, l_ea;
2422 uint16_t vpart_num; 2422 uint16_t vpart_num;
2423 uint8_t *data_pos; 2423 uint8_t *data_pos;
2424 int icbflags, addr_type; 2424 int icbflags, addr_type;
2425 int slot, cpy_slot, cpy_slots; 2425 int slot, cpy_slot, cpy_slots;
2426 int eof, error; 2426 int eof, error;
2427 2427
2428 DPRINTF(ALLOC, ("udf_shrink_node\n")); 2428 DPRINTF(ALLOC, ("udf_shrink_node\n"));
2429 2429
2430 UDF_LOCK_NODE(udf_node, 0); 2430 UDF_LOCK_NODE(udf_node, 0);
2431 udf_node_sanity_check(udf_node, &orig_inflen, &orig_lbrec); 2431 udf_node_sanity_check(udf_node, &orig_inflen, &orig_lbrec);
2432 2432
2433 lb_size = udf_rw32(ump->logical_vol->lb_size); 2433 lb_size = udf_rw32(ump->logical_vol->lb_size);
2434 max_len = ((UDF_EXT_MAXLEN / lb_size) * lb_size); 2434 max_len = ((UDF_EXT_MAXLEN / lb_size) * lb_size);
2435 2435
2436 /* do the work */ 2436 /* do the work */
2437 fe = udf_node->fe; 2437 fe = udf_node->fe;
2438 efe = udf_node->efe; 2438 efe = udf_node->efe;
2439 if (fe) { 2439 if (fe) {
2440 icbtag = &fe->icbtag; 2440 icbtag = &fe->icbtag;
2441 inflen = udf_rw64(fe->inf_len); 2441 inflen = udf_rw64(fe->inf_len);
2442 objsize = inflen; 2442 objsize = inflen;
2443 dscr_size = sizeof(struct file_entry) -1; 2443 dscr_size = sizeof(struct file_entry) -1;
2444 l_ea = udf_rw32(fe->l_ea); 2444 l_ea = udf_rw32(fe->l_ea);
2445 l_ad = udf_rw32(fe->l_ad); 2445 l_ad = udf_rw32(fe->l_ad);
2446 data_pos = (uint8_t *) fe + dscr_size + l_ea; 2446 data_pos = (uint8_t *) fe + dscr_size + l_ea;
2447 } else { 2447 } else {
2448 icbtag = &efe->icbtag; 2448 icbtag = &efe->icbtag;
2449 inflen = udf_rw64(efe->inf_len); 2449 inflen = udf_rw64(efe->inf_len);
2450 objsize = udf_rw64(efe->obj_size); 2450 objsize = udf_rw64(efe->obj_size);
2451 dscr_size = sizeof(struct extfile_entry) -1; 2451 dscr_size = sizeof(struct extfile_entry) -1;
2452 l_ea = udf_rw32(efe->l_ea); 2452 l_ea = udf_rw32(efe->l_ea);
2453 l_ad = udf_rw32(efe->l_ad); 2453 l_ad = udf_rw32(efe->l_ad);
2454 data_pos = (uint8_t *) efe + dscr_size + l_ea; 2454 data_pos = (uint8_t *) efe + dscr_size + l_ea;
2455 } 2455 }
2456 max_l_ad = lb_size - dscr_size - l_ea; 2456 max_l_ad = lb_size - dscr_size - l_ea;
2457 2457
2458 icbflags = udf_rw16(icbtag->flags); 2458 icbflags = udf_rw16(icbtag->flags);
2459 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK; 2459 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK;
2460 2460
2461 old_size = inflen; 2461 old_size = inflen;
2462 size_diff = old_size - new_size; 2462 size_diff = old_size - new_size;
2463 2463
2464 DPRINTF(ALLOC, ("\tfrom %"PRIu64" to %"PRIu64"\n", old_size, new_size)); 2464 DPRINTF(ALLOC, ("\tfrom %"PRIu64" to %"PRIu64"\n", old_size, new_size));
2465 2465
2466 /* shrink the node to its new size */ 2466 /* shrink the node to its new size */
2467 if (addr_type == UDF_ICB_INTERN_ALLOC) { 2467 if (addr_type == UDF_ICB_INTERN_ALLOC) {
2468 /* only reflect size change directly in the node */ 2468 /* only reflect size change directly in the node */
2469 KASSERT(new_size <= max_l_ad); 2469 KASSERT(new_size <= max_l_ad);
2470 inflen -= size_diff; 2470 inflen -= size_diff;
2471 objsize -= size_diff; 2471 objsize -= size_diff;
2472 l_ad -= size_diff; 2472 l_ad -= size_diff;
2473 crclen = dscr_size - UDF_DESC_TAG_LENGTH + l_ea + l_ad; 2473 crclen = dscr_size - UDF_DESC_TAG_LENGTH + l_ea + l_ad;
2474 if (fe) { 2474 if (fe) {
2475 fe->inf_len = udf_rw64(inflen); 2475 fe->inf_len = udf_rw64(inflen);
2476 fe->l_ad = udf_rw32(l_ad); 2476 fe->l_ad = udf_rw32(l_ad);
2477 fe->tag.desc_crc_len = udf_rw16(crclen); 2477 fe->tag.desc_crc_len = udf_rw16(crclen);
2478 } else { 2478 } else {
2479 efe->inf_len = udf_rw64(inflen); 2479 efe->inf_len = udf_rw64(inflen);
2480 efe->obj_size = udf_rw64(objsize); 2480 efe->obj_size = udf_rw64(objsize);
2481 efe->l_ad = udf_rw32(l_ad); 2481 efe->l_ad = udf_rw32(l_ad);
2482 efe->tag.desc_crc_len = udf_rw16(crclen); 2482 efe->tag.desc_crc_len = udf_rw16(crclen);
2483 } 2483 }
2484 error = 0; 2484 error = 0;
2485 2485
2486 /* clear the space in the descriptor */ 2486 /* clear the space in the descriptor */
2487 KASSERT(old_size > new_size); 2487 KASSERT(old_size > new_size);
2488 memset(data_pos + new_size, 0, old_size - new_size); 2488 memset(data_pos + new_size, 0, old_size - new_size);
2489 2489
2490 /* TODO zero appened space in buffer! */ 2490 /* TODO zero appened space in buffer! */
2491 /* using uvm_vnp_zerorange(vp, old_size, old_size - new_size); ? */ 2491 /* using uvm_vnp_zerorange(vp, old_size, old_size - new_size); ? */
2492 2492
2493 /* set new size for uvm */ 2493 /* set new size for uvm */
2494 uvm_vnp_setsize(vp, new_size); 2494 uvm_vnp_setsize(vp, new_size);
2495 2495
2496 udf_node_sanity_check(udf_node, &new_inflen, &new_lbrec); 2496 udf_node_sanity_check(udf_node, &new_inflen, &new_lbrec);
2497 UDF_UNLOCK_NODE(udf_node, 0); 2497 UDF_UNLOCK_NODE(udf_node, 0);
2498 2498
2499 KASSERT(new_inflen == orig_inflen - size_diff); 2499 KASSERT(new_inflen == orig_inflen - size_diff);
2500 KASSERT(new_lbrec == orig_lbrec); 2500 KASSERT(new_lbrec == orig_lbrec);
2501 KASSERT(new_lbrec == 0); 2501 KASSERT(new_lbrec == 0);
2502 2502
2503 return 0; 2503 return 0;
2504 } 2504 }
2505 2505
2506 /* setup node cleanup extents copy space */ 2506 /* setup node cleanup extents copy space */
2507 node_ad_cpy = malloc(lb_size * UDF_MAX_ALLOC_EXTENTS, 2507 node_ad_cpy = malloc(lb_size * UDF_MAX_ALLOC_EXTENTS,
2508 M_UDFMNT, M_WAITOK); 2508 M_UDFMNT, M_WAITOK);
2509 memset(node_ad_cpy, 0, lb_size * UDF_MAX_ALLOC_EXTENTS); 2509 memset(node_ad_cpy, 0, lb_size * UDF_MAX_ALLOC_EXTENTS);
2510 2510
2511 /* 2511 /*
2512 * Shrink the node by releasing the allocations and truncate the last 2512 * Shrink the node by releasing the allocations and truncate the last
2513 * allocation to the new size. If the new size fits into the 2513 * allocation to the new size. If the new size fits into the
2514 * allocation descriptor itself, transform it into an 2514 * allocation descriptor itself, transform it into an
2515 * UDF_ICB_INTERN_ALLOC. 2515 * UDF_ICB_INTERN_ALLOC.
2516 */ 2516 */
2517 slot = 0; 2517 slot = 0;
2518 cpy_slot = 0; 2518 cpy_slot = 0;
2519 foffset = 0; 2519 foffset = 0;
2520 2520
2521 /* 1) copy till first overlap piece to the rewrite buffer */ 2521 /* 1) copy till first overlap piece to the rewrite buffer */
2522 for (;;) { 2522 for (;;) {
2523 udf_get_adslot(udf_node, slot, &s_ad, &eof); 2523 udf_get_adslot(udf_node, slot, &s_ad, &eof);
2524 if (eof) { 2524 if (eof) {
2525 DPRINTF(WRITE, 2525 DPRINTF(WRITE,
2526 ("Shrink node failed: " 2526 ("Shrink node failed: "
2527 "encountered EOF\n")); 2527 "encountered EOF\n"));
2528 error = EINVAL; 2528 error = EINVAL;
2529 goto errorout; /* panic? */ 2529 goto errorout; /* panic? */
2530 } 2530 }
2531 len = udf_rw32(s_ad.len); 2531 len = udf_rw32(s_ad.len);
2532 flags = UDF_EXT_FLAGS(len); 2532 flags = UDF_EXT_FLAGS(len);
2533 len = UDF_EXT_LEN(len); 2533 len = UDF_EXT_LEN(len);
2534 2534
2535 if (flags == UDF_EXT_REDIRECT) { 2535 if (flags == UDF_EXT_REDIRECT) {
2536 slot++; 2536 slot++;
2537 continue; 2537 continue;
2538 } 2538 }
2539 2539
2540 end_foffset = foffset + len; 2540 end_foffset = foffset + len;
2541 if (end_foffset > new_size) 2541 if (end_foffset > new_size)
2542 break; /* found */ 2542 break; /* found */
2543 2543
2544 node_ad_cpy[cpy_slot++] = s_ad; 2544 node_ad_cpy[cpy_slot++] = s_ad;
2545 2545
2546 DPRINTF(ALLOC, ("\t1: vp %d, lb %d, len %d, flags %d " 2546 DPRINTF(ALLOC, ("\t1: vp %d, lb %d, len %d, flags %d "
2547 "-> stack\n", 2547 "-> stack\n",
2548 udf_rw16(s_ad.loc.part_num), 2548 udf_rw16(s_ad.loc.part_num),
2549 udf_rw32(s_ad.loc.lb_num), 2549 udf_rw32(s_ad.loc.lb_num),
2550 UDF_EXT_LEN(udf_rw32(s_ad.len)), 2550 UDF_EXT_LEN(udf_rw32(s_ad.len)),
2551 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30)); 2551 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30));
2552 2552
2553 foffset = end_foffset; 2553 foffset = end_foffset;
2554 slot++; 2554 slot++;
2555 } 2555 }
2556 slot_offset = new_size - foffset; 2556 slot_offset = new_size - foffset;
2557 2557
2558 /* 2) trunc overlapping slot at overlap and copy it */ 2558 /* 2) trunc overlapping slot at overlap and copy it */
2559 if (slot_offset > 0) { 2559 if (slot_offset > 0) {
2560 lb_num = udf_rw32(s_ad.loc.lb_num); 2560 lb_num = udf_rw32(s_ad.loc.lb_num);
2561 vpart_num = udf_rw16(s_ad.loc.part_num); 2561 vpart_num = udf_rw16(s_ad.loc.part_num);
2562 2562
2563 if (flags == UDF_EXT_ALLOCATED) { 2563 if (flags == UDF_EXT_ALLOCATED) {
2564 /* note: round DOWN on num_lb */ 2564 /* note: round DOWN on num_lb */
2565 lb_num += (slot_offset + lb_size -1) / lb_size; 2565 lb_num += (slot_offset + lb_size -1) / lb_size;
2566 num_lb = (len - slot_offset) / lb_size; 2566 num_lb = (len - slot_offset) / lb_size;
2567 2567
2568 udf_free_allocated_space(ump, lb_num, vpart_num, num_lb); 2568 udf_free_allocated_space(ump, lb_num, vpart_num, num_lb);
2569 } 2569 }
2570 2570
2571 s_ad.len = udf_rw32(slot_offset | flags); 2571 s_ad.len = udf_rw32(slot_offset | flags);
2572 node_ad_cpy[cpy_slot++] = s_ad; 2572 node_ad_cpy[cpy_slot++] = s_ad;
2573 slot++; 2573 slot++;
2574 2574
2575 DPRINTF(ALLOC, ("\t2: vp %d, lb %d, len %d, flags %d " 2575 DPRINTF(ALLOC, ("\t2: vp %d, lb %d, len %d, flags %d "
2576 "-> stack\n", 2576 "-> stack\n",
2577 udf_rw16(s_ad.loc.part_num), 2577 udf_rw16(s_ad.loc.part_num),
2578 udf_rw32(s_ad.loc.lb_num), 2578 udf_rw32(s_ad.loc.lb_num),
2579 UDF_EXT_LEN(udf_rw32(s_ad.len)), 2579 UDF_EXT_LEN(udf_rw32(s_ad.len)),
2580 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30)); 2580 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30));
2581 } 2581 }
2582 2582
2583 /* 3) delete remainder */ 2583 /* 3) delete remainder */
2584 for (;;) { 2584 for (;;) {
2585 udf_get_adslot(udf_node, slot, &s_ad, &eof); 2585 udf_get_adslot(udf_node, slot, &s_ad, &eof);
2586 if (eof) 2586 if (eof)
2587 break; 2587 break;
2588 2588
2589 len = udf_rw32(s_ad.len); 2589 len = udf_rw32(s_ad.len);
2590 flags = UDF_EXT_FLAGS(len); 2590 flags = UDF_EXT_FLAGS(len);
2591 len = UDF_EXT_LEN(len); 2591 len = UDF_EXT_LEN(len);
2592 2592
2593 if (flags == UDF_EXT_REDIRECT) { 2593 if (flags == UDF_EXT_REDIRECT) {
2594 slot++; 2594 slot++;
2595 continue; 2595 continue;
2596 } 2596 }
2597 2597
2598 DPRINTF(ALLOC, ("\t3: delete remainder " 2598 DPRINTF(ALLOC, ("\t3: delete remainder "
2599 "vp %d lb %d, len %d, flags %d\n", 2599 "vp %d lb %d, len %d, flags %d\n",
2600 udf_rw16(s_ad.loc.part_num), 2600 udf_rw16(s_ad.loc.part_num),
2601 udf_rw32(s_ad.loc.lb_num), 2601 udf_rw32(s_ad.loc.lb_num),
2602 UDF_EXT_LEN(udf_rw32(s_ad.len)), 2602 UDF_EXT_LEN(udf_rw32(s_ad.len)),
2603 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30)); 2603 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30));
2604 2604
2605 if (flags == UDF_EXT_ALLOCATED) { 2605 if (flags == UDF_EXT_ALLOCATED) {
2606 lb_num = udf_rw32(s_ad.loc.lb_num); 2606 lb_num = udf_rw32(s_ad.loc.lb_num);
2607 vpart_num = udf_rw16(s_ad.loc.part_num); 2607 vpart_num = udf_rw16(s_ad.loc.part_num);
2608 num_lb = (len + lb_size - 1) / lb_size; 2608 num_lb = (len + lb_size - 1) / lb_size;
2609 2609
2610 udf_free_allocated_space(ump, lb_num, vpart_num, 2610 udf_free_allocated_space(ump, lb_num, vpart_num,
2611 num_lb); 2611 num_lb);
2612 } 2612 }
2613 2613
2614 slot++; 2614 slot++;
2615 } 2615 }
2616 2616
2617 /* 4) if it will fit into the descriptor then convert */ 2617 /* 4) if it will fit into the descriptor then convert */
2618 if (new_size < max_l_ad) { 2618 if (new_size < max_l_ad) {
2619 /* 2619 /*
2620 * resque/evacuate old piece by reading it in, and convert it 2620 * resque/evacuate old piece by reading it in, and convert it
2621 * to internal alloc. 2621 * to internal alloc.
2622 */ 2622 */
2623 if (new_size == 0) { 2623 if (new_size == 0) {
2624 /* XXX/TODO only for zero sizing now */ 2624 /* XXX/TODO only for zero sizing now */
2625 udf_wipe_adslots(udf_node); 2625 udf_wipe_adslots(udf_node);
2626 2626
2627 icbflags &= ~UDF_ICB_TAG_FLAGS_ALLOC_MASK; 2627 icbflags &= ~UDF_ICB_TAG_FLAGS_ALLOC_MASK;
2628 icbflags |= UDF_ICB_INTERN_ALLOC; 2628 icbflags |= UDF_ICB_INTERN_ALLOC;
2629 icbtag->flags = udf_rw16(icbflags); 2629 icbtag->flags = udf_rw16(icbflags);
2630 2630
2631 inflen -= size_diff; KASSERT(inflen == 0); 2631 inflen -= size_diff; KASSERT(inflen == 0);
2632 objsize -= size_diff; 2632 objsize -= size_diff;
2633 l_ad = new_size; 2633 l_ad = new_size;
2634 crclen = dscr_size - UDF_DESC_TAG_LENGTH + l_ea + l_ad; 2634 crclen = dscr_size - UDF_DESC_TAG_LENGTH + l_ea + l_ad;
2635 if (fe) { 2635 if (fe) {
2636 fe->inf_len = udf_rw64(inflen); 2636 fe->inf_len = udf_rw64(inflen);
2637 fe->l_ad = udf_rw32(l_ad); 2637 fe->l_ad = udf_rw32(l_ad);
2638 fe->tag.desc_crc_len = udf_rw16(crclen); 2638 fe->tag.desc_crc_len = udf_rw16(crclen);
2639 } else { 2639 } else {
2640 efe->inf_len = udf_rw64(inflen); 2640 efe->inf_len = udf_rw64(inflen);
2641 efe->obj_size = udf_rw64(objsize); 2641 efe->obj_size = udf_rw64(objsize);
2642 efe->l_ad = udf_rw32(l_ad); 2642 efe->l_ad = udf_rw32(l_ad);
2643 efe->tag.desc_crc_len = udf_rw16(crclen); 2643 efe->tag.desc_crc_len = udf_rw16(crclen);
2644 } 2644 }
2645 /* eventually copy in evacuated piece */ 2645 /* eventually copy in evacuated piece */
2646 /* set new size for uvm */ 2646 /* set new size for uvm */
2647 uvm_vnp_setsize(vp, new_size); 2647 uvm_vnp_setsize(vp, new_size);
2648 2648
2649 free(node_ad_cpy, M_UDFMNT); 2649 free(node_ad_cpy, M_UDFMNT);
2650 udf_node_sanity_check(udf_node, &new_inflen, &new_lbrec); 2650 udf_node_sanity_check(udf_node, &new_inflen, &new_lbrec);
2651 2651
2652 UDF_UNLOCK_NODE(udf_node, 0); 2652 UDF_UNLOCK_NODE(udf_node, 0);
2653 2653
2654 KASSERT(new_inflen == orig_inflen - size_diff); 2654 KASSERT(new_inflen == orig_inflen - size_diff);
2655 KASSERT(new_inflen == 0); 2655 KASSERT(new_inflen == 0);
2656 KASSERT(new_lbrec == 0); 2656 KASSERT(new_lbrec == 0);
2657 2657
2658 return 0; 2658 return 0;
2659 } 2659 }
2660 2660
2661 printf("UDF_SHRINK_NODE: could convert to internal alloc!\n"); 2661 printf("UDF_SHRINK_NODE: could convert to internal alloc!\n");
2662 } 2662 }
2663 2663
2664 /* 5) reset node descriptors */ 2664 /* 5) reset node descriptors */
2665 udf_wipe_adslots(udf_node); 2665 udf_wipe_adslots(udf_node);
2666 2666
2667 /* 6) copy back extents; merge when possible. Recounting on the fly */ 2667 /* 6) copy back extents; merge when possible. Recounting on the fly */
2668 cpy_slots = cpy_slot; 2668 cpy_slots = cpy_slot;
2669 2669
2670 c_ad = node_ad_cpy[0]; 2670 c_ad = node_ad_cpy[0];
2671 slot = 0; 2671 slot = 0;
2672 for (cpy_slot = 1; cpy_slot < cpy_slots; cpy_slot++) { 2672 for (cpy_slot = 1; cpy_slot < cpy_slots; cpy_slot++) {
2673 s_ad = node_ad_cpy[cpy_slot]; 2673 s_ad = node_ad_cpy[cpy_slot];
2674 2674
2675 DPRINTF(ALLOC, ("\t6: stack -> got mapping vp %d " 2675 DPRINTF(ALLOC, ("\t6: stack -> got mapping vp %d "
2676 "lb %d, len %d, flags %d\n", 2676 "lb %d, len %d, flags %d\n",
2677 udf_rw16(s_ad.loc.part_num), 2677 udf_rw16(s_ad.loc.part_num),
2678 udf_rw32(s_ad.loc.lb_num), 2678 udf_rw32(s_ad.loc.lb_num),
2679 UDF_EXT_LEN(udf_rw32(s_ad.len)), 2679 UDF_EXT_LEN(udf_rw32(s_ad.len)),
2680 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30)); 2680 UDF_EXT_FLAGS(udf_rw32(s_ad.len)) >> 30));
2681 2681
2682 /* see if we can merge */ 2682 /* see if we can merge */
2683 if (udf_ads_merge(lb_size, &c_ad, &s_ad)) { 2683 if (udf_ads_merge(lb_size, &c_ad, &s_ad)) {
2684 /* not mergable (anymore) */ 2684 /* not mergable (anymore) */
2685 DPRINTF(ALLOC, ("\t6: appending vp %d lb %d, " 2685 DPRINTF(ALLOC, ("\t6: appending vp %d lb %d, "
2686 "len %d, flags %d\n", 2686 "len %d, flags %d\n",
2687 udf_rw16(c_ad.loc.part_num), 2687 udf_rw16(c_ad.loc.part_num),
2688 udf_rw32(c_ad.loc.lb_num), 2688 udf_rw32(c_ad.loc.lb_num),
2689 UDF_EXT_LEN(udf_rw32(c_ad.len)), 2689 UDF_EXT_LEN(udf_rw32(c_ad.len)),
2690 UDF_EXT_FLAGS(udf_rw32(c_ad.len)) >> 30)); 2690 UDF_EXT_FLAGS(udf_rw32(c_ad.len)) >> 30));
2691 2691
2692 error = udf_append_adslot(udf_node, &slot, &c_ad); 2692 error = udf_append_adslot(udf_node, &slot, &c_ad);
2693 if (error) 2693 if (error)
2694 goto errorout; /* panic? */ 2694 goto errorout; /* panic? */
2695 c_ad = s_ad; 2695 c_ad = s_ad;
2696 slot++; 2696 slot++;
2697 } 2697 }
2698 } 2698 }
2699 2699
2700 /* 7) push rest slot (if any) */ 2700 /* 7) push rest slot (if any) */
2701 if (UDF_EXT_LEN(c_ad.len) > 0) { 2701 if (UDF_EXT_LEN(c_ad.len) > 0) {
2702 DPRINTF(ALLOC, ("\t7: last append vp %d lb %d, " 2702 DPRINTF(ALLOC, ("\t7: last append vp %d lb %d, "
2703 "len %d, flags %d\n", 2703 "len %d, flags %d\n",
2704 udf_rw16(c_ad.loc.part_num), 2704 udf_rw16(c_ad.loc.part_num),
2705 udf_rw32(c_ad.loc.lb_num), 2705 udf_rw32(c_ad.loc.lb_num),
2706 UDF_EXT_LEN(udf_rw32(c_ad.len)), 2706 UDF_EXT_LEN(udf_rw32(c_ad.len)),
2707 UDF_EXT_FLAGS(udf_rw32(c_ad.len)) >> 30)); 2707 UDF_EXT_FLAGS(udf_rw32(c_ad.len)) >> 30));
2708 2708
2709 error = udf_append_adslot(udf_node, &slot, &c_ad); 2709 error = udf_append_adslot(udf_node, &slot, &c_ad);
2710 if (error) 2710 if (error)
2711 goto errorout; /* panic? */ 2711 goto errorout; /* panic? */
2712 ; 2712 ;
2713 } 2713 }
2714 2714
2715 inflen -= size_diff; 2715 inflen -= size_diff;
2716 objsize -= size_diff; 2716 objsize -= size_diff;
2717 if (fe) { 2717 if (fe) {
2718 fe->inf_len = udf_rw64(inflen); 2718 fe->inf_len = udf_rw64(inflen);
2719 } else { 2719 } else {
2720 efe->inf_len = udf_rw64(inflen); 2720 efe->inf_len = udf_rw64(inflen);
2721 efe->obj_size = udf_rw64(objsize); 2721 efe->obj_size = udf_rw64(objsize);
2722 } 2722 }
2723 error = 0; 2723 error = 0;
2724 2724
2725 /* set new size for uvm */ 2725 /* set new size for uvm */
2726 uvm_vnp_setsize(vp, new_size); 2726 uvm_vnp_setsize(vp, new_size);
2727 2727
2728errorout: 2728errorout:
2729 free(node_ad_cpy, M_UDFMNT); 2729 free(node_ad_cpy, M_UDFMNT);
2730 2730
2731 udf_count_alloc_exts(udf_node); 2731 udf_count_alloc_exts(udf_node);
2732 2732
2733 udf_node_sanity_check(udf_node, &new_inflen, &new_lbrec); 2733 udf_node_sanity_check(udf_node, &new_inflen, &new_lbrec);
2734 UDF_UNLOCK_NODE(udf_node, 0); 2734 UDF_UNLOCK_NODE(udf_node, 0);
2735 2735
2736 KASSERT(new_inflen == orig_inflen - size_diff); 2736 KASSERT(new_inflen == orig_inflen - size_diff);
2737 2737
2738 return error; 2738 return error;
2739} 2739}
2740 2740