aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf')
-rw-r--r--fs/udf/Makefile9
-rw-r--r--fs/udf/balloc.c959
-rw-r--r--fs/udf/crc.c178
-rw-r--r--fs/udf/dir.c268
-rw-r--r--fs/udf/directory.c343
-rw-r--r--fs/udf/ecma_167.h864
-rw-r--r--fs/udf/file.c270
-rw-r--r--fs/udf/fsync.c56
-rw-r--r--fs/udf/ialloc.c170
-rw-r--r--fs/udf/inode.c2010
-rw-r--r--fs/udf/lowlevel.c77
-rw-r--r--fs/udf/misc.c313
-rw-r--r--fs/udf/namei.c1334
-rw-r--r--fs/udf/osta_udf.h296
-rw-r--r--fs/udf/partition.c226
-rw-r--r--fs/udf/super.c1934
-rw-r--r--fs/udf/symlink.c123
-rw-r--r--fs/udf/truncate.c284
-rw-r--r--fs/udf/udf_i.h26
-rw-r--r--fs/udf/udf_sb.h139
-rw-r--r--fs/udf/udfdecl.h167
-rw-r--r--fs/udf/udfend.h81
-rw-r--r--fs/udf/udftime.c174
-rw-r--r--fs/udf/unicode.c516
24 files changed, 10817 insertions, 0 deletions
diff --git a/fs/udf/Makefile b/fs/udf/Makefile
new file mode 100644
index 000000000000..be845e7540ef
--- /dev/null
+++ b/fs/udf/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for the linux udf-filesystem routines.
3#
4
5obj-$(CONFIG_UDF_FS) += udf.o
6
7udf-objs := balloc.o dir.o file.o ialloc.o inode.o lowlevel.o namei.o \
8 partition.o super.o truncate.o symlink.o fsync.o \
9 crc.o directory.o misc.o udftime.o unicode.o
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
new file mode 100644
index 000000000000..b9ded26b10a9
--- /dev/null
+++ b/fs/udf/balloc.c
@@ -0,0 +1,959 @@
1/*
2 * balloc.c
3 *
4 * PURPOSE
5 * Block allocation handling routines for the OSTA-UDF(tm) filesystem.
6 *
7 * CONTACTS
8 * E-mail regarding any portion of the Linux UDF file system should be
9 * directed to the development team mailing list (run by majordomo):
10 * linux_udf@hpesjro.fc.hp.com
11 *
12 * COPYRIGHT
13 * This file is distributed under the terms of the GNU General Public
14 * License (GPL). Copies of the GPL can be obtained from:
15 * ftp://prep.ai.mit.edu/pub/gnu/GPL
16 * Each contributing author retains all rights to their own work.
17 *
18 * (C) 1999-2001 Ben Fennema
19 * (C) 1999 Stelias Computing Inc
20 *
21 * HISTORY
22 *
23 * 02/24/99 blf Created.
24 *
25 */
26
27#include "udfdecl.h"
28
29#include <linux/quotaops.h>
30#include <linux/buffer_head.h>
31#include <linux/bitops.h>
32
33#include "udf_i.h"
34#include "udf_sb.h"
35
36#define udf_clear_bit(nr,addr) ext2_clear_bit(nr,addr)
37#define udf_set_bit(nr,addr) ext2_set_bit(nr,addr)
38#define udf_test_bit(nr, addr) ext2_test_bit(nr, addr)
39#define udf_find_first_one_bit(addr, size) find_first_one_bit(addr, size)
40#define udf_find_next_one_bit(addr, size, offset) find_next_one_bit(addr, size, offset)
41
42#define leBPL_to_cpup(x) leNUM_to_cpup(BITS_PER_LONG, x)
43#define leNUM_to_cpup(x,y) xleNUM_to_cpup(x,y)
44#define xleNUM_to_cpup(x,y) (le ## x ## _to_cpup(y))
45#define uintBPL_t uint(BITS_PER_LONG)
46#define uint(x) xuint(x)
47#define xuint(x) __le ## x
48
49extern inline int find_next_one_bit (void * addr, int size, int offset)
50{
51 uintBPL_t * p = ((uintBPL_t *) addr) + (offset / BITS_PER_LONG);
52 int result = offset & ~(BITS_PER_LONG-1);
53 unsigned long tmp;
54
55 if (offset >= size)
56 return size;
57 size -= result;
58 offset &= (BITS_PER_LONG-1);
59 if (offset)
60 {
61 tmp = leBPL_to_cpup(p++);
62 tmp &= ~0UL << offset;
63 if (size < BITS_PER_LONG)
64 goto found_first;
65 if (tmp)
66 goto found_middle;
67 size -= BITS_PER_LONG;
68 result += BITS_PER_LONG;
69 }
70 while (size & ~(BITS_PER_LONG-1))
71 {
72 if ((tmp = leBPL_to_cpup(p++)))
73 goto found_middle;
74 result += BITS_PER_LONG;
75 size -= BITS_PER_LONG;
76 }
77 if (!size)
78 return result;
79 tmp = leBPL_to_cpup(p);
80found_first:
81 tmp &= ~0UL >> (BITS_PER_LONG-size);
82found_middle:
83 return result + ffz(~tmp);
84}
85
86#define find_first_one_bit(addr, size)\
87 find_next_one_bit((addr), (size), 0)
88
89static int read_block_bitmap(struct super_block * sb,
90 struct udf_bitmap *bitmap, unsigned int block, unsigned long bitmap_nr)
91{
92 struct buffer_head *bh = NULL;
93 int retval = 0;
94 kernel_lb_addr loc;
95
96 loc.logicalBlockNum = bitmap->s_extPosition;
97 loc.partitionReferenceNum = UDF_SB_PARTITION(sb);
98
99 bh = udf_tread(sb, udf_get_lb_pblock(sb, loc, block));
100 if (!bh)
101 {
102 retval = -EIO;
103 }
104 bitmap->s_block_bitmap[bitmap_nr] = bh;
105 return retval;
106}
107
108static int __load_block_bitmap(struct super_block * sb,
109 struct udf_bitmap *bitmap, unsigned int block_group)
110{
111 int retval = 0;
112 int nr_groups = bitmap->s_nr_groups;
113
114 if (block_group >= nr_groups)
115 {
116 udf_debug("block_group (%d) > nr_groups (%d)\n", block_group, nr_groups);
117 }
118
119 if (bitmap->s_block_bitmap[block_group])
120 return block_group;
121 else
122 {
123 retval = read_block_bitmap(sb, bitmap, block_group, block_group);
124 if (retval < 0)
125 return retval;
126 return block_group;
127 }
128}
129
130static inline int load_block_bitmap(struct super_block * sb,
131 struct udf_bitmap *bitmap, unsigned int block_group)
132{
133 int slot;
134
135 slot = __load_block_bitmap(sb, bitmap, block_group);
136
137 if (slot < 0)
138 return slot;
139
140 if (!bitmap->s_block_bitmap[slot])
141 return -EIO;
142
143 return slot;
144}
145
146static void udf_bitmap_free_blocks(struct super_block * sb,
147 struct inode * inode,
148 struct udf_bitmap *bitmap,
149 kernel_lb_addr bloc, uint32_t offset, uint32_t count)
150{
151 struct udf_sb_info *sbi = UDF_SB(sb);
152 struct buffer_head * bh = NULL;
153 unsigned long block;
154 unsigned long block_group;
155 unsigned long bit;
156 unsigned long i;
157 int bitmap_nr;
158 unsigned long overflow;
159
160 down(&sbi->s_alloc_sem);
161 if (bloc.logicalBlockNum < 0 ||
162 (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
163 {
164 udf_debug("%d < %d || %d + %d > %d\n",
165 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
166 UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum));
167 goto error_return;
168 }
169
170 block = bloc.logicalBlockNum + offset + (sizeof(struct spaceBitmapDesc) << 3);
171
172do_more:
173 overflow = 0;
174 block_group = block >> (sb->s_blocksize_bits + 3);
175 bit = block % (sb->s_blocksize << 3);
176
177 /*
178 * Check to see if we are freeing blocks across a group boundary.
179 */
180 if (bit + count > (sb->s_blocksize << 3))
181 {
182 overflow = bit + count - (sb->s_blocksize << 3);
183 count -= overflow;
184 }
185 bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
186 if (bitmap_nr < 0)
187 goto error_return;
188
189 bh = bitmap->s_block_bitmap[bitmap_nr];
190 for (i=0; i < count; i++)
191 {
192 if (udf_set_bit(bit + i, bh->b_data))
193 {
194 udf_debug("bit %ld already set\n", bit + i);
195 udf_debug("byte=%2x\n", ((char *)bh->b_data)[(bit + i) >> 3]);
196 }
197 else
198 {
199 if (inode)
200 DQUOT_FREE_BLOCK(inode, 1);
201 if (UDF_SB_LVIDBH(sb))
202 {
203 UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
204 cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)])+1);
205 }
206 }
207 }
208 mark_buffer_dirty(bh);
209 if (overflow)
210 {
211 block += count;
212 count = overflow;
213 goto do_more;
214 }
215error_return:
216 sb->s_dirt = 1;
217 if (UDF_SB_LVIDBH(sb))
218 mark_buffer_dirty(UDF_SB_LVIDBH(sb));
219 up(&sbi->s_alloc_sem);
220 return;
221}
222
223static int udf_bitmap_prealloc_blocks(struct super_block * sb,
224 struct inode * inode,
225 struct udf_bitmap *bitmap, uint16_t partition, uint32_t first_block,
226 uint32_t block_count)
227{
228 struct udf_sb_info *sbi = UDF_SB(sb);
229 int alloc_count = 0;
230 int bit, block, block_group, group_start;
231 int nr_groups, bitmap_nr;
232 struct buffer_head *bh;
233
234 down(&sbi->s_alloc_sem);
235 if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
236 goto out;
237
238 if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
239 block_count = UDF_SB_PARTLEN(sb, partition) - first_block;
240
241repeat:
242 nr_groups = (UDF_SB_PARTLEN(sb, partition) +
243 (sizeof(struct spaceBitmapDesc) << 3) + (sb->s_blocksize * 8) - 1) / (sb->s_blocksize * 8);
244 block = first_block + (sizeof(struct spaceBitmapDesc) << 3);
245 block_group = block >> (sb->s_blocksize_bits + 3);
246 group_start = block_group ? 0 : sizeof(struct spaceBitmapDesc);
247
248 bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
249 if (bitmap_nr < 0)
250 goto out;
251 bh = bitmap->s_block_bitmap[bitmap_nr];
252
253 bit = block % (sb->s_blocksize << 3);
254
255 while (bit < (sb->s_blocksize << 3) && block_count > 0)
256 {
257 if (!udf_test_bit(bit, bh->b_data))
258 goto out;
259 else if (DQUOT_PREALLOC_BLOCK(inode, 1))
260 goto out;
261 else if (!udf_clear_bit(bit, bh->b_data))
262 {
263 udf_debug("bit already cleared for block %d\n", bit);
264 DQUOT_FREE_BLOCK(inode, 1);
265 goto out;
266 }
267 block_count --;
268 alloc_count ++;
269 bit ++;
270 block ++;
271 }
272 mark_buffer_dirty(bh);
273 if (block_count > 0)
274 goto repeat;
275out:
276 if (UDF_SB_LVIDBH(sb))
277 {
278 UDF_SB_LVID(sb)->freeSpaceTable[partition] =
279 cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-alloc_count);
280 mark_buffer_dirty(UDF_SB_LVIDBH(sb));
281 }
282 sb->s_dirt = 1;
283 up(&sbi->s_alloc_sem);
284 return alloc_count;
285}
286
287static int udf_bitmap_new_block(struct super_block * sb,
288 struct inode * inode,
289 struct udf_bitmap *bitmap, uint16_t partition, uint32_t goal, int *err)
290{
291 struct udf_sb_info *sbi = UDF_SB(sb);
292 int newbit, bit=0, block, block_group, group_start;
293 int end_goal, nr_groups, bitmap_nr, i;
294 struct buffer_head *bh = NULL;
295 char *ptr;
296 int newblock = 0;
297
298 *err = -ENOSPC;
299 down(&sbi->s_alloc_sem);
300
301repeat:
302 if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
303 goal = 0;
304
305 nr_groups = bitmap->s_nr_groups;
306 block = goal + (sizeof(struct spaceBitmapDesc) << 3);
307 block_group = block >> (sb->s_blocksize_bits + 3);
308 group_start = block_group ? 0 : sizeof(struct spaceBitmapDesc);
309
310 bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
311 if (bitmap_nr < 0)
312 goto error_return;
313 bh = bitmap->s_block_bitmap[bitmap_nr];
314 ptr = memscan((char *)bh->b_data + group_start, 0xFF, sb->s_blocksize - group_start);
315
316 if ((ptr - ((char *)bh->b_data)) < sb->s_blocksize)
317 {
318 bit = block % (sb->s_blocksize << 3);
319
320 if (udf_test_bit(bit, bh->b_data))
321 {
322 goto got_block;
323 }
324 end_goal = (bit + 63) & ~63;
325 bit = udf_find_next_one_bit(bh->b_data, end_goal, bit);
326 if (bit < end_goal)
327 goto got_block;
328 ptr = memscan((char *)bh->b_data + (bit >> 3), 0xFF, sb->s_blocksize - ((bit + 7) >> 3));
329 newbit = (ptr - ((char *)bh->b_data)) << 3;
330 if (newbit < sb->s_blocksize << 3)
331 {
332 bit = newbit;
333 goto search_back;
334 }
335 newbit = udf_find_next_one_bit(bh->b_data, sb->s_blocksize << 3, bit);
336 if (newbit < sb->s_blocksize << 3)
337 {
338 bit = newbit;
339 goto got_block;
340 }
341 }
342
343 for (i=0; i<(nr_groups*2); i++)
344 {
345 block_group ++;
346 if (block_group >= nr_groups)
347 block_group = 0;
348 group_start = block_group ? 0 : sizeof(struct spaceBitmapDesc);
349
350 bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
351 if (bitmap_nr < 0)
352 goto error_return;
353 bh = bitmap->s_block_bitmap[bitmap_nr];
354 if (i < nr_groups)
355 {
356 ptr = memscan((char *)bh->b_data + group_start, 0xFF, sb->s_blocksize - group_start);
357 if ((ptr - ((char *)bh->b_data)) < sb->s_blocksize)
358 {
359 bit = (ptr - ((char *)bh->b_data)) << 3;
360 break;
361 }
362 }
363 else
364 {
365 bit = udf_find_next_one_bit((char *)bh->b_data, sb->s_blocksize << 3, group_start << 3);
366 if (bit < sb->s_blocksize << 3)
367 break;
368 }
369 }
370 if (i >= (nr_groups*2))
371 {
372 up(&sbi->s_alloc_sem);
373 return newblock;
374 }
375 if (bit < sb->s_blocksize << 3)
376 goto search_back;
377 else
378 bit = udf_find_next_one_bit(bh->b_data, sb->s_blocksize << 3, group_start << 3);
379 if (bit >= sb->s_blocksize << 3)
380 {
381 up(&sbi->s_alloc_sem);
382 return 0;
383 }
384
385search_back:
386 for (i=0; i<7 && bit > (group_start << 3) && udf_test_bit(bit - 1, bh->b_data); i++, bit--);
387
388got_block:
389
390 /*
391 * Check quota for allocation of this block.
392 */
393 if (inode && DQUOT_ALLOC_BLOCK(inode, 1))
394 {
395 up(&sbi->s_alloc_sem);
396 *err = -EDQUOT;
397 return 0;
398 }
399
400 newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) -
401 (sizeof(struct spaceBitmapDesc) << 3);
402
403 if (!udf_clear_bit(bit, bh->b_data))
404 {
405 udf_debug("bit already cleared for block %d\n", bit);
406 goto repeat;
407 }
408
409 mark_buffer_dirty(bh);
410
411 if (UDF_SB_LVIDBH(sb))
412 {
413 UDF_SB_LVID(sb)->freeSpaceTable[partition] =
414 cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-1);
415 mark_buffer_dirty(UDF_SB_LVIDBH(sb));
416 }
417 sb->s_dirt = 1;
418 up(&sbi->s_alloc_sem);
419 *err = 0;
420 return newblock;
421
422error_return:
423 *err = -EIO;
424 up(&sbi->s_alloc_sem);
425 return 0;
426}
427
428static void udf_table_free_blocks(struct super_block * sb,
429 struct inode * inode,
430 struct inode * table,
431 kernel_lb_addr bloc, uint32_t offset, uint32_t count)
432{
433 struct udf_sb_info *sbi = UDF_SB(sb);
434 uint32_t start, end;
435 uint32_t nextoffset, oextoffset, elen;
436 kernel_lb_addr nbloc, obloc, eloc;
437 struct buffer_head *obh, *nbh;
438 int8_t etype;
439 int i;
440
441 down(&sbi->s_alloc_sem);
442 if (bloc.logicalBlockNum < 0 ||
443 (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
444 {
445 udf_debug("%d < %d || %d + %d > %d\n",
446 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
447 UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum));
448 goto error_return;
449 }
450
451 /* We do this up front - There are some error conditions that could occure,
452 but.. oh well */
453 if (inode)
454 DQUOT_FREE_BLOCK(inode, count);
455 if (UDF_SB_LVIDBH(sb))
456 {
457 UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
458 cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)])+count);
459 mark_buffer_dirty(UDF_SB_LVIDBH(sb));
460 }
461
462 start = bloc.logicalBlockNum + offset;
463 end = bloc.logicalBlockNum + offset + count - 1;
464
465 oextoffset = nextoffset = sizeof(struct unallocSpaceEntry);
466 elen = 0;
467 obloc = nbloc = UDF_I_LOCATION(table);
468
469 obh = nbh = NULL;
470
471 while (count && (etype =
472 udf_next_aext(table, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
473 {
474 if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) ==
475 start))
476 {
477 if ((0x3FFFFFFF - elen) < (count << sb->s_blocksize_bits))
478 {
479 count -= ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
480 start += ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
481 elen = (etype << 30) | (0x40000000 - sb->s_blocksize);
482 }
483 else
484 {
485 elen = (etype << 30) |
486 (elen + (count << sb->s_blocksize_bits));
487 start += count;
488 count = 0;
489 }
490 udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1);
491 }
492 else if (eloc.logicalBlockNum == (end + 1))
493 {
494 if ((0x3FFFFFFF - elen) < (count << sb->s_blocksize_bits))
495 {
496 count -= ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
497 end -= ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
498 eloc.logicalBlockNum -=
499 ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
500 elen = (etype << 30) | (0x40000000 - sb->s_blocksize);
501 }
502 else
503 {
504 eloc.logicalBlockNum = start;
505 elen = (etype << 30) |
506 (elen + (count << sb->s_blocksize_bits));
507 end -= count;
508 count = 0;
509 }
510 udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1);
511 }
512
513 if (nbh != obh)
514 {
515 i = -1;
516 obloc = nbloc;
517 udf_release_data(obh);
518 atomic_inc(&nbh->b_count);
519 obh = nbh;
520 oextoffset = 0;
521 }
522 else
523 oextoffset = nextoffset;
524 }
525
526 if (count)
527 {
528 /* NOTE: we CANNOT use udf_add_aext here, as it can try to allocate
529 a new block, and since we hold the super block lock already
530 very bad things would happen :)
531
532 We copy the behavior of udf_add_aext, but instead of
533 trying to allocate a new block close to the existing one,
534 we just steal a block from the extent we are trying to add.
535
536 It would be nice if the blocks were close together, but it
537 isn't required.
538 */
539
540 int adsize;
541 short_ad *sad = NULL;
542 long_ad *lad = NULL;
543 struct allocExtDesc *aed;
544
545 eloc.logicalBlockNum = start;
546 elen = EXT_RECORDED_ALLOCATED |
547 (count << sb->s_blocksize_bits);
548
549 if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
550 adsize = sizeof(short_ad);
551 else if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_LONG)
552 adsize = sizeof(long_ad);
553 else
554 {
555 udf_release_data(obh);
556 udf_release_data(nbh);
557 goto error_return;
558 }
559
560 if (nextoffset + (2 * adsize) > sb->s_blocksize)
561 {
562 char *sptr, *dptr;
563 int loffset;
564
565 udf_release_data(obh);
566 obh = nbh;
567 obloc = nbloc;
568 oextoffset = nextoffset;
569
570 /* Steal a block from the extent being free'd */
571 nbloc.logicalBlockNum = eloc.logicalBlockNum;
572 eloc.logicalBlockNum ++;
573 elen -= sb->s_blocksize;
574
575 if (!(nbh = udf_tread(sb,
576 udf_get_lb_pblock(sb, nbloc, 0))))
577 {
578 udf_release_data(obh);
579 goto error_return;
580 }
581 aed = (struct allocExtDesc *)(nbh->b_data);
582 aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
583 if (nextoffset + adsize > sb->s_blocksize)
584 {
585 loffset = nextoffset;
586 aed->lengthAllocDescs = cpu_to_le32(adsize);
587 if (obh)
588 sptr = UDF_I_DATA(inode) + nextoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode) - adsize;
589 else
590 sptr = obh->b_data + nextoffset - adsize;
591 dptr = nbh->b_data + sizeof(struct allocExtDesc);
592 memcpy(dptr, sptr, adsize);
593 nextoffset = sizeof(struct allocExtDesc) + adsize;
594 }
595 else
596 {
597 loffset = nextoffset + adsize;
598 aed->lengthAllocDescs = cpu_to_le32(0);
599 sptr = (obh)->b_data + nextoffset;
600 nextoffset = sizeof(struct allocExtDesc);
601
602 if (obh)
603 {
604 aed = (struct allocExtDesc *)(obh)->b_data;
605 aed->lengthAllocDescs =
606 cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
607 }
608 else
609 {
610 UDF_I_LENALLOC(table) += adsize;
611 mark_inode_dirty(table);
612 }
613 }
614 if (UDF_SB_UDFREV(sb) >= 0x0200)
615 udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
616 nbloc.logicalBlockNum, sizeof(tag));
617 else
618 udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
619 nbloc.logicalBlockNum, sizeof(tag));
620 switch (UDF_I_ALLOCTYPE(table))
621 {
622 case ICBTAG_FLAG_AD_SHORT:
623 {
624 sad = (short_ad *)sptr;
625 sad->extLength = cpu_to_le32(
626 EXT_NEXT_EXTENT_ALLOCDECS |
627 sb->s_blocksize);
628 sad->extPosition = cpu_to_le32(nbloc.logicalBlockNum);
629 break;
630 }
631 case ICBTAG_FLAG_AD_LONG:
632 {
633 lad = (long_ad *)sptr;
634 lad->extLength = cpu_to_le32(
635 EXT_NEXT_EXTENT_ALLOCDECS |
636 sb->s_blocksize);
637 lad->extLocation = cpu_to_lelb(nbloc);
638 break;
639 }
640 }
641 if (obh)
642 {
643 udf_update_tag(obh->b_data, loffset);
644 mark_buffer_dirty(obh);
645 }
646 else
647 mark_inode_dirty(table);
648 }
649
650 if (elen) /* It's possible that stealing the block emptied the extent */
651 {
652 udf_write_aext(table, nbloc, &nextoffset, eloc, elen, nbh, 1);
653
654 if (!nbh)
655 {
656 UDF_I_LENALLOC(table) += adsize;
657 mark_inode_dirty(table);
658 }
659 else
660 {
661 aed = (struct allocExtDesc *)nbh->b_data;
662 aed->lengthAllocDescs =
663 cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
664 udf_update_tag(nbh->b_data, nextoffset);
665 mark_buffer_dirty(nbh);
666 }
667 }
668 }
669
670 udf_release_data(nbh);
671 udf_release_data(obh);
672
673error_return:
674 sb->s_dirt = 1;
675 up(&sbi->s_alloc_sem);
676 return;
677}
678
679static int udf_table_prealloc_blocks(struct super_block * sb,
680 struct inode * inode,
681 struct inode *table, uint16_t partition, uint32_t first_block,
682 uint32_t block_count)
683{
684 struct udf_sb_info *sbi = UDF_SB(sb);
685 int alloc_count = 0;
686 uint32_t extoffset, elen, adsize;
687 kernel_lb_addr bloc, eloc;
688 struct buffer_head *bh;
689 int8_t etype = -1;
690
691 if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
692 return 0;
693
694 if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
695 adsize = sizeof(short_ad);
696 else if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_LONG)
697 adsize = sizeof(long_ad);
698 else
699 return 0;
700
701 down(&sbi->s_alloc_sem);
702 extoffset = sizeof(struct unallocSpaceEntry);
703 bloc = UDF_I_LOCATION(table);
704
705 bh = NULL;
706 eloc.logicalBlockNum = 0xFFFFFFFF;
707
708 while (first_block != eloc.logicalBlockNum && (etype =
709 udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
710 {
711 udf_debug("eloc=%d, elen=%d, first_block=%d\n",
712 eloc.logicalBlockNum, elen, first_block);
713 ; /* empty loop body */
714 }
715
716 if (first_block == eloc.logicalBlockNum)
717 {
718 extoffset -= adsize;
719
720 alloc_count = (elen >> sb->s_blocksize_bits);
721 if (inode && DQUOT_PREALLOC_BLOCK(inode, alloc_count > block_count ? block_count : alloc_count))
722 alloc_count = 0;
723 else if (alloc_count > block_count)
724 {
725 alloc_count = block_count;
726 eloc.logicalBlockNum += alloc_count;
727 elen -= (alloc_count << sb->s_blocksize_bits);
728 udf_write_aext(table, bloc, &extoffset, eloc, (etype << 30) | elen, bh, 1);
729 }
730 else
731 udf_delete_aext(table, bloc, extoffset, eloc, (etype << 30) | elen, bh);
732 }
733 else
734 alloc_count = 0;
735
736 udf_release_data(bh);
737
738 if (alloc_count && UDF_SB_LVIDBH(sb))
739 {
740 UDF_SB_LVID(sb)->freeSpaceTable[partition] =
741 cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-alloc_count);
742 mark_buffer_dirty(UDF_SB_LVIDBH(sb));
743 sb->s_dirt = 1;
744 }
745 up(&sbi->s_alloc_sem);
746 return alloc_count;
747}
748
749static int udf_table_new_block(struct super_block * sb,
750 struct inode * inode,
751 struct inode *table, uint16_t partition, uint32_t goal, int *err)
752{
753 struct udf_sb_info *sbi = UDF_SB(sb);
754 uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF;
755 uint32_t newblock = 0, adsize;
756 uint32_t extoffset, goal_extoffset, elen, goal_elen = 0;
757 kernel_lb_addr bloc, goal_bloc, eloc, goal_eloc;
758 struct buffer_head *bh, *goal_bh;
759 int8_t etype;
760
761 *err = -ENOSPC;
762
763 if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
764 adsize = sizeof(short_ad);
765 else if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_LONG)
766 adsize = sizeof(long_ad);
767 else
768 return newblock;
769
770 down(&sbi->s_alloc_sem);
771 if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
772 goal = 0;
773
774 /* We search for the closest matching block to goal. If we find a exact hit,
775 we stop. Otherwise we keep going till we run out of extents.
776 We store the buffer_head, bloc, and extoffset of the current closest
777 match and use that when we are done.
778 */
779
780 extoffset = sizeof(struct unallocSpaceEntry);
781 bloc = UDF_I_LOCATION(table);
782
783 goal_bh = bh = NULL;
784
785 while (spread && (etype =
786 udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
787 {
788 if (goal >= eloc.logicalBlockNum)
789 {
790 if (goal < eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits))
791 nspread = 0;
792 else
793 nspread = goal - eloc.logicalBlockNum -
794 (elen >> sb->s_blocksize_bits);
795 }
796 else
797 nspread = eloc.logicalBlockNum - goal;
798
799 if (nspread < spread)
800 {
801 spread = nspread;
802 if (goal_bh != bh)
803 {
804 udf_release_data(goal_bh);
805 goal_bh = bh;
806 atomic_inc(&goal_bh->b_count);
807 }
808 goal_bloc = bloc;
809 goal_extoffset = extoffset - adsize;
810 goal_eloc = eloc;
811 goal_elen = (etype << 30) | elen;
812 }
813 }
814
815 udf_release_data(bh);
816
817 if (spread == 0xFFFFFFFF)
818 {
819 udf_release_data(goal_bh);
820 up(&sbi->s_alloc_sem);
821 return 0;
822 }
823
824 /* Only allocate blocks from the beginning of the extent.
825 That way, we only delete (empty) extents, never have to insert an
826 extent because of splitting */
827 /* This works, but very poorly.... */
828
829 newblock = goal_eloc.logicalBlockNum;
830 goal_eloc.logicalBlockNum ++;
831 goal_elen -= sb->s_blocksize;
832
833 if (inode && DQUOT_ALLOC_BLOCK(inode, 1))
834 {
835 udf_release_data(goal_bh);
836 up(&sbi->s_alloc_sem);
837 *err = -EDQUOT;
838 return 0;
839 }
840
841 if (goal_elen)
842 udf_write_aext(table, goal_bloc, &goal_extoffset, goal_eloc, goal_elen, goal_bh, 1);
843 else
844 udf_delete_aext(table, goal_bloc, goal_extoffset, goal_eloc, goal_elen, goal_bh);
845 udf_release_data(goal_bh);
846
847 if (UDF_SB_LVIDBH(sb))
848 {
849 UDF_SB_LVID(sb)->freeSpaceTable[partition] =
850 cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-1);
851 mark_buffer_dirty(UDF_SB_LVIDBH(sb));
852 }
853
854 sb->s_dirt = 1;
855 up(&sbi->s_alloc_sem);
856 *err = 0;
857 return newblock;
858}
859
860inline void udf_free_blocks(struct super_block * sb,
861 struct inode * inode,
862 kernel_lb_addr bloc, uint32_t offset, uint32_t count)
863{
864 uint16_t partition = bloc.partitionReferenceNum;
865
866 if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
867 {
868 return udf_bitmap_free_blocks(sb, inode,
869 UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
870 bloc, offset, count);
871 }
872 else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
873 {
874 return udf_table_free_blocks(sb, inode,
875 UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
876 bloc, offset, count);
877 }
878 else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
879 {
880 return udf_bitmap_free_blocks(sb, inode,
881 UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
882 bloc, offset, count);
883 }
884 else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE)
885 {
886 return udf_table_free_blocks(sb, inode,
887 UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
888 bloc, offset, count);
889 }
890 else
891 return;
892}
893
894inline int udf_prealloc_blocks(struct super_block * sb,
895 struct inode * inode,
896 uint16_t partition, uint32_t first_block, uint32_t block_count)
897{
898 if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
899 {
900 return udf_bitmap_prealloc_blocks(sb, inode,
901 UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
902 partition, first_block, block_count);
903 }
904 else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
905 {
906 return udf_table_prealloc_blocks(sb, inode,
907 UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
908 partition, first_block, block_count);
909 }
910 else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
911 {
912 return udf_bitmap_prealloc_blocks(sb, inode,
913 UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
914 partition, first_block, block_count);
915 }
916 else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE)
917 {
918 return udf_table_prealloc_blocks(sb, inode,
919 UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
920 partition, first_block, block_count);
921 }
922 else
923 return 0;
924}
925
926inline int udf_new_block(struct super_block * sb,
927 struct inode * inode,
928 uint16_t partition, uint32_t goal, int *err)
929{
930 if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
931 {
932 return udf_bitmap_new_block(sb, inode,
933 UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
934 partition, goal, err);
935 }
936 else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
937 {
938 return udf_table_new_block(sb, inode,
939 UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
940 partition, goal, err);
941 }
942 else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
943 {
944 return udf_bitmap_new_block(sb, inode,
945 UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
946 partition, goal, err);
947 }
948 else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE)
949 {
950 return udf_table_new_block(sb, inode,
951 UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
952 partition, goal, err);
953 }
954 else
955 {
956 *err = -EIO;
957 return 0;
958 }
959}
diff --git a/fs/udf/crc.c b/fs/udf/crc.c
new file mode 100644
index 000000000000..d95c6e38a455
--- /dev/null
+++ b/fs/udf/crc.c
@@ -0,0 +1,178 @@
1/*
2 * crc.c
3 *
4 * PURPOSE
5 * Routines to generate, calculate, and test a 16-bit CRC.
6 *
7 * DESCRIPTION
8 * The CRC code was devised by Don P. Mitchell of AT&T Bell Laboratories
9 * and Ned W. Rhodes of Software Systems Group. It has been published in
10 * "Design and Validation of Computer Protocols", Prentice Hall,
11 * Englewood Cliffs, NJ, 1991, Chapter 3, ISBN 0-13-539925-4.
12 *
13 * Copyright is held by AT&T.
14 *
15 * AT&T gives permission for the free use of the CRC source code.
16 *
17 * CONTACTS
18 * E-mail regarding any portion of the Linux UDF file system should be
19 * directed to the development team mailing list (run by majordomo):
20 * linux_udf@hpesjro.fc.hp.com
21 *
22 * COPYRIGHT
23 * This file is distributed under the terms of the GNU General Public
24 * License (GPL). Copies of the GPL can be obtained from:
25 * ftp://prep.ai.mit.edu/pub/gnu/GPL
26 * Each contributing author retains all rights to their own work.
27 */
28
29#include "udfdecl.h"
30
31static uint16_t crc_table[256] = {
32 0x0000U, 0x1021U, 0x2042U, 0x3063U, 0x4084U, 0x50a5U, 0x60c6U, 0x70e7U,
33 0x8108U, 0x9129U, 0xa14aU, 0xb16bU, 0xc18cU, 0xd1adU, 0xe1ceU, 0xf1efU,
34 0x1231U, 0x0210U, 0x3273U, 0x2252U, 0x52b5U, 0x4294U, 0x72f7U, 0x62d6U,
35 0x9339U, 0x8318U, 0xb37bU, 0xa35aU, 0xd3bdU, 0xc39cU, 0xf3ffU, 0xe3deU,
36 0x2462U, 0x3443U, 0x0420U, 0x1401U, 0x64e6U, 0x74c7U, 0x44a4U, 0x5485U,
37 0xa56aU, 0xb54bU, 0x8528U, 0x9509U, 0xe5eeU, 0xf5cfU, 0xc5acU, 0xd58dU,
38 0x3653U, 0x2672U, 0x1611U, 0x0630U, 0x76d7U, 0x66f6U, 0x5695U, 0x46b4U,
39 0xb75bU, 0xa77aU, 0x9719U, 0x8738U, 0xf7dfU, 0xe7feU, 0xd79dU, 0xc7bcU,
40 0x48c4U, 0x58e5U, 0x6886U, 0x78a7U, 0x0840U, 0x1861U, 0x2802U, 0x3823U,
41 0xc9ccU, 0xd9edU, 0xe98eU, 0xf9afU, 0x8948U, 0x9969U, 0xa90aU, 0xb92bU,
42 0x5af5U, 0x4ad4U, 0x7ab7U, 0x6a96U, 0x1a71U, 0x0a50U, 0x3a33U, 0x2a12U,
43 0xdbfdU, 0xcbdcU, 0xfbbfU, 0xeb9eU, 0x9b79U, 0x8b58U, 0xbb3bU, 0xab1aU,
44 0x6ca6U, 0x7c87U, 0x4ce4U, 0x5cc5U, 0x2c22U, 0x3c03U, 0x0c60U, 0x1c41U,
45 0xedaeU, 0xfd8fU, 0xcdecU, 0xddcdU, 0xad2aU, 0xbd0bU, 0x8d68U, 0x9d49U,
46 0x7e97U, 0x6eb6U, 0x5ed5U, 0x4ef4U, 0x3e13U, 0x2e32U, 0x1e51U, 0x0e70U,
47 0xff9fU, 0xefbeU, 0xdfddU, 0xcffcU, 0xbf1bU, 0xaf3aU, 0x9f59U, 0x8f78U,
48 0x9188U, 0x81a9U, 0xb1caU, 0xa1ebU, 0xd10cU, 0xc12dU, 0xf14eU, 0xe16fU,
49 0x1080U, 0x00a1U, 0x30c2U, 0x20e3U, 0x5004U, 0x4025U, 0x7046U, 0x6067U,
50 0x83b9U, 0x9398U, 0xa3fbU, 0xb3daU, 0xc33dU, 0xd31cU, 0xe37fU, 0xf35eU,
51 0x02b1U, 0x1290U, 0x22f3U, 0x32d2U, 0x4235U, 0x5214U, 0x6277U, 0x7256U,
52 0xb5eaU, 0xa5cbU, 0x95a8U, 0x8589U, 0xf56eU, 0xe54fU, 0xd52cU, 0xc50dU,
53 0x34e2U, 0x24c3U, 0x14a0U, 0x0481U, 0x7466U, 0x6447U, 0x5424U, 0x4405U,
54 0xa7dbU, 0xb7faU, 0x8799U, 0x97b8U, 0xe75fU, 0xf77eU, 0xc71dU, 0xd73cU,
55 0x26d3U, 0x36f2U, 0x0691U, 0x16b0U, 0x6657U, 0x7676U, 0x4615U, 0x5634U,
56 0xd94cU, 0xc96dU, 0xf90eU, 0xe92fU, 0x99c8U, 0x89e9U, 0xb98aU, 0xa9abU,
57 0x5844U, 0x4865U, 0x7806U, 0x6827U, 0x18c0U, 0x08e1U, 0x3882U, 0x28a3U,
58 0xcb7dU, 0xdb5cU, 0xeb3fU, 0xfb1eU, 0x8bf9U, 0x9bd8U, 0xabbbU, 0xbb9aU,
59 0x4a75U, 0x5a54U, 0x6a37U, 0x7a16U, 0x0af1U, 0x1ad0U, 0x2ab3U, 0x3a92U,
60 0xfd2eU, 0xed0fU, 0xdd6cU, 0xcd4dU, 0xbdaaU, 0xad8bU, 0x9de8U, 0x8dc9U,
61 0x7c26U, 0x6c07U, 0x5c64U, 0x4c45U, 0x3ca2U, 0x2c83U, 0x1ce0U, 0x0cc1U,
62 0xef1fU, 0xff3eU, 0xcf5dU, 0xdf7cU, 0xaf9bU, 0xbfbaU, 0x8fd9U, 0x9ff8U,
63 0x6e17U, 0x7e36U, 0x4e55U, 0x5e74U, 0x2e93U, 0x3eb2U, 0x0ed1U, 0x1ef0U
64};
65
66/*
67 * udf_crc
68 *
69 * PURPOSE
70 * Calculate a 16-bit CRC checksum using ITU-T V.41 polynomial.
71 *
72 * DESCRIPTION
73 * The OSTA-UDF(tm) 1.50 standard states that using CRCs is mandatory.
74 * The polynomial used is: x^16 + x^12 + x^15 + 1
75 *
76 * PRE-CONDITIONS
77 * data Pointer to the data block.
78 * size Size of the data block.
79 *
80 * POST-CONDITIONS
81 * <return> CRC of the data block.
82 *
83 * HISTORY
84 * July 21, 1997 - Andrew E. Mileski
85 * Adapted from OSTA-UDF(tm) 1.50 standard.
86 */
87uint16_t
88udf_crc(uint8_t *data, uint32_t size, uint16_t crc)
89{
90 while (size--)
91 crc = crc_table[(crc >> 8 ^ *(data++)) & 0xffU] ^ (crc << 8);
92
93 return crc;
94}
95
96/****************************************************************************/
97#if defined(TEST)
98
99/*
100 * PURPOSE
101 * Test udf_crc()
102 *
103 * HISTORY
104 * July 21, 1997 - Andrew E. Mileski
105 * Adapted from OSTA-UDF(tm) 1.50 standard.
106 */
107
108unsigned char bytes[] = { 0x70U, 0x6AU, 0x77U };
109
110int main(void)
111{
112 unsigned short x;
113
114 x = udf_crc16(bytes, sizeof bytes);
115 printf("udf_crc16: calculated = %4.4x, correct = %4.4x\n", x, 0x3299U);
116
117 return 0;
118}
119
120#endif /* defined(TEST) */
121
122/****************************************************************************/
123#if defined(GENERATE)
124
125/*
126 * PURPOSE
127 * Generate a table for fast 16-bit CRC calculations (any polynomial).
128 *
129 * DESCRIPTION
130 * The ITU-T V.41 polynomial is 010041.
131 *
132 * HISTORY
133 * July 21, 1997 - Andrew E. Mileski
134 * Adapted from OSTA-UDF(tm) 1.50 standard.
135 */
136
137#include <stdio.h>
138
139int main(int argc, char **argv)
140{
141 unsigned long crc, poly;
142 int n, i;
143
144 /* Get the polynomial */
145 sscanf(argv[1], "%lo", &poly);
146 if (poly & 0xffff0000U){
147 fprintf(stderr, "polynomial is too large\en");
148 exit(1);
149 }
150
151 printf("/* CRC 0%o */\n", poly);
152
153 /* Create a table */
154 printf("static unsigned short crc_table[256] = {\n");
155 for (n = 0; n < 256; n++){
156 if (n % 8 == 0)
157 printf("\t");
158 crc = n << 8;
159 for (i = 0; i < 8; i++){
160 if(crc & 0x8000U)
161 crc = (crc << 1) ^ poly;
162 else
163 crc <<= 1;
164 crc &= 0xFFFFU;
165 }
166 if (n == 255)
167 printf("0x%04xU ", crc);
168 else
169 printf("0x%04xU, ", crc);
170 if(n % 8 == 7)
171 printf("\n");
172 }
173 printf("};\n");
174
175 return 0;
176}
177
178#endif /* defined(GENERATE) */
diff --git a/fs/udf/dir.c b/fs/udf/dir.c
new file mode 100644
index 000000000000..82440b731142
--- /dev/null
+++ b/fs/udf/dir.c
@@ -0,0 +1,268 @@
1/*
2 * dir.c
3 *
4 * PURPOSE
5 * Directory handling routines for the OSTA-UDF(tm) filesystem.
6 *
7 * CONTACTS
8 * E-mail regarding any portion of the Linux UDF file system should be
9 * directed to the development team mailing list (run by majordomo):
10 * linux_udf@hpesjro.fc.hp.com
11 *
12 * COPYRIGHT
13 * This file is distributed under the terms of the GNU General Public
14 * License (GPL). Copies of the GPL can be obtained from:
15 * ftp://prep.ai.mit.edu/pub/gnu/GPL
16 * Each contributing author retains all rights to their own work.
17 *
18 * (C) 1998-2004 Ben Fennema
19 *
20 * HISTORY
21 *
22 * 10/05/98 dgb Split directory operations into its own file
23 * Implemented directory reads via do_udf_readdir
24 * 10/06/98 Made directory operations work!
25 * 11/17/98 Rewrote directory to support ICBTAG_FLAG_AD_LONG
26 * 11/25/98 blf Rewrote directory handling (readdir+lookup) to support reading
27 * across blocks.
28 * 12/12/98 Split out the lookup code to namei.c. bulk of directory
29 * code now in directory.c:udf_fileident_read.
30 */
31
32#include "udfdecl.h"
33
34#include <linux/string.h>
35#include <linux/errno.h>
36#include <linux/mm.h>
37#include <linux/slab.h>
38#include <linux/smp_lock.h>
39#include <linux/buffer_head.h>
40
41#include "udf_i.h"
42#include "udf_sb.h"
43
44/* Prototypes for file operations */
45static int udf_readdir(struct file *, void *, filldir_t);
46static int do_udf_readdir(struct inode *, struct file *, filldir_t, void *);
47
48/* readdir and lookup functions */
49
50struct file_operations udf_dir_operations = {
51 .read = generic_read_dir,
52 .readdir = udf_readdir,
53 .ioctl = udf_ioctl,
54 .fsync = udf_fsync_file,
55};
56
57/*
58 * udf_readdir
59 *
60 * PURPOSE
61 * Read a directory entry.
62 *
63 * DESCRIPTION
64 * Optional - sys_getdents() will return -ENOTDIR if this routine is not
65 * available.
66 *
67 * Refer to sys_getdents() in fs/readdir.c
68 * sys_getdents() -> .
69 *
70 * PRE-CONDITIONS
71 * filp Pointer to directory file.
72 * buf Pointer to directory entry buffer.
73 * filldir Pointer to filldir function.
74 *
75 * POST-CONDITIONS
76 * <return> >=0 on success.
77 *
78 * HISTORY
79 * July 1, 1997 - Andrew E. Mileski
80 * Written, tested, and released.
81 */
82
83int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
84{
85 struct inode *dir = filp->f_dentry->d_inode;
86 int result;
87
88 lock_kernel();
89
90 if ( filp->f_pos == 0 )
91 {
92 if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0)
93 {
94 unlock_kernel();
95 return 0;
96 }
97 filp->f_pos ++;
98 }
99
100 result = do_udf_readdir(dir, filp, filldir, dirent);
101 unlock_kernel();
102 return result;
103}
104
105static int
106do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *dirent)
107{
108 struct udf_fileident_bh fibh;
109 struct fileIdentDesc *fi=NULL;
110 struct fileIdentDesc cfi;
111 int block, iblock;
112 loff_t nf_pos = filp->f_pos - 1;
113 int flen;
114 char fname[UDF_NAME_LEN];
115 char *nameptr;
116 uint16_t liu;
117 uint8_t lfi;
118 loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
119 struct buffer_head * bh = NULL, * tmp, * bha[16];
120 kernel_lb_addr bloc, eloc;
121 uint32_t extoffset, elen, offset;
122 int i, num;
123 unsigned int dt_type;
124
125 if (nf_pos >= size)
126 return 0;
127
128 if (nf_pos == 0)
129 nf_pos = (udf_ext0_offset(dir) >> 2);
130
131 fibh.soffset = fibh.eoffset = (nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
132 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
133 fibh.sbh = fibh.ebh = NULL;
134 else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2),
135 &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
136 {
137 offset >>= dir->i_sb->s_blocksize_bits;
138 block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
139 if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
140 {
141 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
142 extoffset -= sizeof(short_ad);
143 else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
144 extoffset -= sizeof(long_ad);
145 }
146 else
147 offset = 0;
148
149 if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block)))
150 {
151 udf_release_data(bh);
152 return -EIO;
153 }
154
155 if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9))-1)))
156 {
157 i = 16 >> (dir->i_sb->s_blocksize_bits - 9);
158 if (i+offset > (elen >> dir->i_sb->s_blocksize_bits))
159 i = (elen >> dir->i_sb->s_blocksize_bits)-offset;
160 for (num=0; i>0; i--)
161 {
162 block = udf_get_lb_pblock(dir->i_sb, eloc, offset+i);
163 tmp = udf_tgetblk(dir->i_sb, block);
164 if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
165 bha[num++] = tmp;
166 else
167 brelse(tmp);
168 }
169 if (num)
170 {
171 ll_rw_block(READA, num, bha);
172 for (i=0; i<num; i++)
173 brelse(bha[i]);
174 }
175 }
176 }
177 else
178 {
179 udf_release_data(bh);
180 return -ENOENT;
181 }
182
183 while ( nf_pos < size )
184 {
185 filp->f_pos = nf_pos + 1;
186
187 fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
188
189 if (!fi)
190 {
191 if (fibh.sbh != fibh.ebh)
192 udf_release_data(fibh.ebh);
193 udf_release_data(fibh.sbh);
194 udf_release_data(bh);
195 return 0;
196 }
197
198 liu = le16_to_cpu(cfi.lengthOfImpUse);
199 lfi = cfi.lengthFileIdent;
200
201 if (fibh.sbh == fibh.ebh)
202 nameptr = fi->fileIdent + liu;
203 else
204 {
205 int poffset; /* Unpaded ending offset */
206
207 poffset = fibh.soffset + sizeof(struct fileIdentDesc) + liu + lfi;
208
209 if (poffset >= lfi)
210 nameptr = (char *)(fibh.ebh->b_data + poffset - lfi);
211 else
212 {
213 nameptr = fname;
214 memcpy(nameptr, fi->fileIdent + liu, lfi - poffset);
215 memcpy(nameptr + lfi - poffset, fibh.ebh->b_data, poffset);
216 }
217 }
218
219 if ( (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) != 0 )
220 {
221 if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE) )
222 continue;
223 }
224
225 if ( (cfi.fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0 )
226 {
227 if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE) )
228 continue;
229 }
230
231 if ( cfi.fileCharacteristics & FID_FILE_CHAR_PARENT )
232 {
233 iblock = parent_ino(filp->f_dentry);
234 flen = 2;
235 memcpy(fname, "..", flen);
236 dt_type = DT_DIR;
237 }
238 else
239 {
240 kernel_lb_addr tloc = lelb_to_cpu(cfi.icb.extLocation);
241
242 iblock = udf_get_lb_pblock(dir->i_sb, tloc, 0);
243 flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi);
244 dt_type = DT_UNKNOWN;
245 }
246
247 if (flen)
248 {
249 if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0)
250 {
251 if (fibh.sbh != fibh.ebh)
252 udf_release_data(fibh.ebh);
253 udf_release_data(fibh.sbh);
254 udf_release_data(bh);
255 return 0;
256 }
257 }
258 } /* end while */
259
260 filp->f_pos = nf_pos + 1;
261
262 if (fibh.sbh != fibh.ebh)
263 udf_release_data(fibh.ebh);
264 udf_release_data(fibh.sbh);
265 udf_release_data(bh);
266
267 return 0;
268}
diff --git a/fs/udf/directory.c b/fs/udf/directory.c
new file mode 100644
index 000000000000..9a61ecc5451b
--- /dev/null
+++ b/fs/udf/directory.c
@@ -0,0 +1,343 @@
1/*
2 * directory.c
3 *
4 * PURPOSE
5 * Directory related functions
6 *
7 * CONTACTS
8 * E-mail regarding any portion of the Linux UDF file system should be
9 * directed to the development team mailing list (run by majordomo):
10 * linux_udf@hpesjro.fc.hp.com
11 *
12 * COPYRIGHT
13 * This file is distributed under the terms of the GNU General Public
14 * License (GPL). Copies of the GPL can be obtained from:
15 * ftp://prep.ai.mit.edu/pub/gnu/GPL
16 * Each contributing author retains all rights to their own work.
17 */
18
19#include "udfdecl.h"
20#include "udf_i.h"
21
22#include <linux/fs.h>
23#include <linux/string.h>
24#include <linux/buffer_head.h>
25
26#if 0
27static uint8_t *
28udf_filead_read(struct inode *dir, uint8_t *tmpad, uint8_t ad_size,
29 kernel_lb_addr fe_loc, int *pos, int *offset,
30 struct buffer_head **bh, int *error)
31{
32 int loffset = *offset;
33 int block;
34 uint8_t *ad;
35 int remainder;
36
37 *error = 0;
38
39 ad = (uint8_t *)(*bh)->b_data + *offset;
40 *offset += ad_size;
41
42 if (!ad)
43 {
44 udf_release_data(*bh);
45 *error = 1;
46 return NULL;
47 }
48
49 if (*offset == dir->i_sb->s_blocksize)
50 {
51 udf_release_data(*bh);
52 block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
53 if (!block)
54 return NULL;
55 if (!(*bh = udf_tread(dir->i_sb, block)))
56 return NULL;
57 }
58 else if (*offset > dir->i_sb->s_blocksize)
59 {
60 ad = tmpad;
61
62 remainder = dir->i_sb->s_blocksize - loffset;
63 memcpy((uint8_t *)ad, (*bh)->b_data + loffset, remainder);
64
65 udf_release_data(*bh);
66 block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
67 if (!block)
68 return NULL;
69 if (!((*bh) = udf_tread(dir->i_sb, block)))
70 return NULL;
71
72 memcpy((uint8_t *)ad + remainder, (*bh)->b_data, ad_size - remainder);
73 *offset = ad_size - remainder;
74 }
75 return ad;
76}
77#endif
78
79struct fileIdentDesc *
80udf_fileident_read(struct inode *dir, loff_t *nf_pos,
81 struct udf_fileident_bh *fibh,
82 struct fileIdentDesc *cfi,
83 kernel_lb_addr *bloc, uint32_t *extoffset,
84 kernel_lb_addr *eloc, uint32_t *elen,
85 uint32_t *offset, struct buffer_head **bh)
86{
87 struct fileIdentDesc *fi;
88 int i, num, block;
89 struct buffer_head * tmp, * bha[16];
90
91 fibh->soffset = fibh->eoffset;
92
93 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
94 {
95 fi = udf_get_fileident(UDF_I_DATA(dir) -
96 (UDF_I_EFE(dir) ?
97 sizeof(struct extendedFileEntry) :
98 sizeof(struct fileEntry)),
99 dir->i_sb->s_blocksize, &(fibh->eoffset));
100
101 if (!fi)
102 return NULL;
103
104 *nf_pos += ((fibh->eoffset - fibh->soffset) >> 2);
105
106 memcpy((uint8_t *)cfi, (uint8_t *)fi, sizeof(struct fileIdentDesc));
107
108 return fi;
109 }
110
111 if (fibh->eoffset == dir->i_sb->s_blocksize)
112 {
113 int lextoffset = *extoffset;
114
115 if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) !=
116 (EXT_RECORDED_ALLOCATED >> 30))
117 {
118 return NULL;
119 }
120
121 block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
122
123 (*offset) ++;
124
125 if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
126 *offset = 0;
127 else
128 *extoffset = lextoffset;
129
130 udf_release_data(fibh->sbh);
131 if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block)))
132 return NULL;
133 fibh->soffset = fibh->eoffset = 0;
134
135 if (!(*offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9))-1)))
136 {
137 i = 16 >> (dir->i_sb->s_blocksize_bits - 9);
138 if (i+*offset > (*elen >> dir->i_sb->s_blocksize_bits))
139 i = (*elen >> dir->i_sb->s_blocksize_bits)-*offset;
140 for (num=0; i>0; i--)
141 {
142 block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset+i);
143 tmp = udf_tgetblk(dir->i_sb, block);
144 if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
145 bha[num++] = tmp;
146 else
147 brelse(tmp);
148 }
149 if (num)
150 {
151 ll_rw_block(READA, num, bha);
152 for (i=0; i<num; i++)
153 brelse(bha[i]);
154 }
155 }
156 }
157 else if (fibh->sbh != fibh->ebh)
158 {
159 udf_release_data(fibh->sbh);
160 fibh->sbh = fibh->ebh;
161 }
162
163 fi = udf_get_fileident(fibh->sbh->b_data, dir->i_sb->s_blocksize,
164 &(fibh->eoffset));
165
166 if (!fi)
167 return NULL;
168
169 *nf_pos += ((fibh->eoffset - fibh->soffset) >> 2);
170
171 if (fibh->eoffset <= dir->i_sb->s_blocksize)
172 {
173 memcpy((uint8_t *)cfi, (uint8_t *)fi, sizeof(struct fileIdentDesc));
174 }
175 else if (fibh->eoffset > dir->i_sb->s_blocksize)
176 {
177 int lextoffset = *extoffset;
178
179 if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) !=
180 (EXT_RECORDED_ALLOCATED >> 30))
181 {
182 return NULL;
183 }
184
185 block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
186
187 (*offset) ++;
188
189 if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
190 *offset = 0;
191 else
192 *extoffset = lextoffset;
193
194 fibh->soffset -= dir->i_sb->s_blocksize;
195 fibh->eoffset -= dir->i_sb->s_blocksize;
196
197 if (!(fibh->ebh = udf_tread(dir->i_sb, block)))
198 return NULL;
199
200 if (sizeof(struct fileIdentDesc) > - fibh->soffset)
201 {
202 int fi_len;
203
204 memcpy((uint8_t *)cfi, (uint8_t *)fi, - fibh->soffset);
205 memcpy((uint8_t *)cfi - fibh->soffset, fibh->ebh->b_data,
206 sizeof(struct fileIdentDesc) + fibh->soffset);
207
208 fi_len = (sizeof(struct fileIdentDesc) + cfi->lengthFileIdent +
209 le16_to_cpu(cfi->lengthOfImpUse) + 3) & ~3;
210
211 *nf_pos += ((fi_len - (fibh->eoffset - fibh->soffset)) >> 2);
212 fibh->eoffset = fibh->soffset + fi_len;
213 }
214 else
215 {
216 memcpy((uint8_t *)cfi, (uint8_t *)fi, sizeof(struct fileIdentDesc));
217 }
218 }
219 return fi;
220}
221
222struct fileIdentDesc *
223udf_get_fileident(void * buffer, int bufsize, int * offset)
224{
225 struct fileIdentDesc *fi;
226 int lengthThisIdent;
227 uint8_t * ptr;
228 int padlen;
229
230 if ( (!buffer) || (!offset) ) {
231 udf_debug("invalidparms\n, buffer=%p, offset=%p\n", buffer, offset);
232 return NULL;
233 }
234
235 ptr = buffer;
236
237 if ( (*offset > 0) && (*offset < bufsize) ) {
238 ptr += *offset;
239 }
240 fi=(struct fileIdentDesc *)ptr;
241 if (le16_to_cpu(fi->descTag.tagIdent) != TAG_IDENT_FID)
242 {
243 udf_debug("0x%x != TAG_IDENT_FID\n",
244 le16_to_cpu(fi->descTag.tagIdent));
245 udf_debug("offset: %u sizeof: %lu bufsize: %u\n",
246 *offset, (unsigned long)sizeof(struct fileIdentDesc), bufsize);
247 return NULL;
248 }
249 if ( (*offset + sizeof(struct fileIdentDesc)) > bufsize )
250 {
251 lengthThisIdent = sizeof(struct fileIdentDesc);
252 }
253 else
254 lengthThisIdent = sizeof(struct fileIdentDesc) +
255 fi->lengthFileIdent + le16_to_cpu(fi->lengthOfImpUse);
256
257 /* we need to figure padding, too! */
258 padlen = lengthThisIdent % UDF_NAME_PAD;
259 if (padlen)
260 lengthThisIdent += (UDF_NAME_PAD - padlen);
261 *offset = *offset + lengthThisIdent;
262
263 return fi;
264}
265
266#if 0
267static extent_ad *
268udf_get_fileextent(void * buffer, int bufsize, int * offset)
269{
270 extent_ad * ext;
271 struct fileEntry *fe;
272 uint8_t * ptr;
273
274 if ( (!buffer) || (!offset) )
275 {
276 printk(KERN_ERR "udf: udf_get_fileextent() invalidparms\n");
277 return NULL;
278 }
279
280 fe = (struct fileEntry *)buffer;
281
282 if ( le16_to_cpu(fe->descTag.tagIdent) != TAG_IDENT_FE )
283 {
284 udf_debug("0x%x != TAG_IDENT_FE\n",
285 le16_to_cpu(fe->descTag.tagIdent));
286 return NULL;
287 }
288
289 ptr=(uint8_t *)(fe->extendedAttr) + le32_to_cpu(fe->lengthExtendedAttr);
290
291 if ( (*offset > 0) && (*offset < le32_to_cpu(fe->lengthAllocDescs)) )
292 {
293 ptr += *offset;
294 }
295
296 ext = (extent_ad *)ptr;
297
298 *offset = *offset + sizeof(extent_ad);
299 return ext;
300}
301#endif
302
303short_ad *
304udf_get_fileshortad(uint8_t *ptr, int maxoffset, int *offset, int inc)
305{
306 short_ad *sa;
307
308 if ( (!ptr) || (!offset) )
309 {
310 printk(KERN_ERR "udf: udf_get_fileshortad() invalidparms\n");
311 return NULL;
312 }
313
314 if ( (*offset < 0) || ((*offset + sizeof(short_ad)) > maxoffset) )
315 return NULL;
316 else if ((sa = (short_ad *)ptr)->extLength == 0)
317 return NULL;
318
319 if (inc)
320 *offset += sizeof(short_ad);
321 return sa;
322}
323
324long_ad *
325udf_get_filelongad(uint8_t *ptr, int maxoffset, int * offset, int inc)
326{
327 long_ad *la;
328
329 if ( (!ptr) || (!offset) )
330 {
331 printk(KERN_ERR "udf: udf_get_filelongad() invalidparms\n");
332 return NULL;
333 }
334
335 if ( (*offset < 0) || ((*offset + sizeof(long_ad)) > maxoffset) )
336 return NULL;
337 else if ((la = (long_ad *)ptr)->extLength == 0)
338 return NULL;
339
340 if (inc)
341 *offset += sizeof(long_ad);
342 return la;
343}
diff --git a/fs/udf/ecma_167.h b/fs/udf/ecma_167.h
new file mode 100644
index 000000000000..f81f2ebbf508
--- /dev/null
+++ b/fs/udf/ecma_167.h
@@ -0,0 +1,864 @@
1/*
2 * ecma_167.h
3 *
4 * This file is based on ECMA-167 3rd edition (June 1997)
5 * http://www.ecma.ch
6 *
7 * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions, and the following disclaimer,
15 * without modification.
16 * 2. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * Alternatively, this software may be distributed under the terms of the
20 * GNU Public License ("GPL").
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
26 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#include <linux/types.h>
36
37#ifndef _ECMA_167_H
38#define _ECMA_167_H 1
39
40/* Character set specification (ECMA 167r3 1/7.2.1) */
41typedef struct
42{
43 uint8_t charSetType;
44 uint8_t charSetInfo[63];
45} __attribute__ ((packed)) charspec;
46
47/* Character Set Type (ECMA 167r3 1/7.2.1.1) */
48#define CHARSPEC_TYPE_CS0 0x00 /* (1/7.2.2) */
49#define CHARSPEC_TYPE_CS1 0x01 /* (1/7.2.3) */
50#define CHARSPEC_TYPE_CS2 0x02 /* (1/7.2.4) */
51#define CHARSPEC_TYPE_CS3 0x03 /* (1/7.2.5) */
52#define CHARSPEC_TYPE_CS4 0x04 /* (1/7.2.6) */
53#define CHARSPEC_TYPE_CS5 0x05 /* (1/7.2.7) */
54#define CHARSPEC_TYPE_CS6 0x06 /* (1/7.2.8) */
55#define CHARSPEC_TYPE_CS7 0x07 /* (1/7.2.9) */
56#define CHARSPEC_TYPE_CS8 0x08 /* (1/7.2.10) */
57
58typedef uint8_t dstring;
59
60/* Timestamp (ECMA 167r3 1/7.3) */
61typedef struct
62{
63 __le16 typeAndTimezone;
64 __le16 year;
65 uint8_t month;
66 uint8_t day;
67 uint8_t hour;
68 uint8_t minute;
69 uint8_t second;
70 uint8_t centiseconds;
71 uint8_t hundredsOfMicroseconds;
72 uint8_t microseconds;
73} __attribute__ ((packed)) timestamp;
74
75typedef struct
76{
77 uint16_t typeAndTimezone;
78 int16_t year;
79 uint8_t month;
80 uint8_t day;
81 uint8_t hour;
82 uint8_t minute;
83 uint8_t second;
84 uint8_t centiseconds;
85 uint8_t hundredsOfMicroseconds;
86 uint8_t microseconds;
87} __attribute__ ((packed)) kernel_timestamp;
88
89/* Type and Time Zone (ECMA 167r3 1/7.3.1) */
90#define TIMESTAMP_TYPE_MASK 0xF000
91#define TIMESTAMP_TYPE_CUT 0x0000
92#define TIMESTAMP_TYPE_LOCAL 0x1000
93#define TIMESTAMP_TYPE_AGREEMENT 0x2000
94#define TIMESTAMP_TIMEZONE_MASK 0x0FFF
95
96/* Entity identifier (ECMA 167r3 1/7.4) */
97typedef struct
98{
99 uint8_t flags;
100 uint8_t ident[23];
101 uint8_t identSuffix[8];
102} __attribute__ ((packed)) regid;
103
104/* Flags (ECMA 167r3 1/7.4.1) */
105#define ENTITYID_FLAGS_DIRTY 0x00
106#define ENTITYID_FLAGS_PROTECTED 0x01
107
108/* Volume Structure Descriptor (ECMA 167r3 2/9.1) */
109#define VSD_STD_ID_LEN 5
110struct volStructDesc
111{
112 uint8_t structType;
113 uint8_t stdIdent[VSD_STD_ID_LEN];
114 uint8_t structVersion;
115 uint8_t structData[2041];
116} __attribute__ ((packed));
117
118/* Standard Identifier (EMCA 167r2 2/9.1.2) */
119#define VSD_STD_ID_NSR02 "NSR02" /* (3/9.1) */
120
121/* Standard Identifier (ECMA 167r3 2/9.1.2) */
122#define VSD_STD_ID_BEA01 "BEA01" /* (2/9.2) */
123#define VSD_STD_ID_BOOT2 "BOOT2" /* (2/9.4) */
124#define VSD_STD_ID_CD001 "CD001" /* (ECMA-119) */
125#define VSD_STD_ID_CDW02 "CDW02" /* (ECMA-168) */
126#define VSD_STD_ID_NSR03 "NSR03" /* (3/9.1) */
127#define VSD_STD_ID_TEA01 "TEA01" /* (2/9.3) */
128
129/* Beginning Extended Area Descriptor (ECMA 167r3 2/9.2) */
130struct beginningExtendedAreaDesc
131{
132 uint8_t structType;
133 uint8_t stdIdent[VSD_STD_ID_LEN];
134 uint8_t structVersion;
135 uint8_t structData[2041];
136} __attribute__ ((packed));
137
138/* Terminating Extended Area Descriptor (ECMA 167r3 2/9.3) */
139struct terminatingExtendedAreaDesc
140{
141 uint8_t structType;
142 uint8_t stdIdent[VSD_STD_ID_LEN];
143 uint8_t structVersion;
144 uint8_t structData[2041];
145} __attribute__ ((packed));
146
147/* Boot Descriptor (ECMA 167r3 2/9.4) */
148struct bootDesc
149{
150 uint8_t structType;
151 uint8_t stdIdent[VSD_STD_ID_LEN];
152 uint8_t structVersion;
153 uint8_t reserved1;
154 regid archType;
155 regid bootIdent;
156 __le32 bootExtLocation;
157 __le32 bootExtLength;
158 __le64 loadAddress;
159 __le64 startAddress;
160 timestamp descCreationDateAndTime;
161 __le16 flags;
162 uint8_t reserved2[32];
163 uint8_t bootUse[1906];
164} __attribute__ ((packed));
165
166/* Flags (ECMA 167r3 2/9.4.12) */
167#define BOOT_FLAGS_ERASE 0x01
168
169/* Extent Descriptor (ECMA 167r3 3/7.1) */
170typedef struct
171{
172 __le32 extLength;
173 __le32 extLocation;
174} __attribute__ ((packed)) extent_ad;
175
176typedef struct
177{
178 uint32_t extLength;
179 uint32_t extLocation;
180} kernel_extent_ad;
181
182/* Descriptor Tag (ECMA 167r3 3/7.2) */
183typedef struct
184{
185 __le16 tagIdent;
186 __le16 descVersion;
187 uint8_t tagChecksum;
188 uint8_t reserved;
189 __le16 tagSerialNum;
190 __le16 descCRC;
191 __le16 descCRCLength;
192 __le32 tagLocation;
193} __attribute__ ((packed)) tag;
194
195/* Tag Identifier (ECMA 167r3 3/7.2.1) */
196#define TAG_IDENT_PVD 0x0001
197#define TAG_IDENT_AVDP 0x0002
198#define TAG_IDENT_VDP 0x0003
199#define TAG_IDENT_IUVD 0x0004
200#define TAG_IDENT_PD 0x0005
201#define TAG_IDENT_LVD 0x0006
202#define TAG_IDENT_USD 0x0007
203#define TAG_IDENT_TD 0x0008
204#define TAG_IDENT_LVID 0x0009
205
206/* NSR Descriptor (ECMA 167r3 3/9.1) */
207struct NSRDesc
208{
209 uint8_t structType;
210 uint8_t stdIdent[VSD_STD_ID_LEN];
211 uint8_t structVersion;
212 uint8_t reserved;
213 uint8_t structData[2040];
214} __attribute__ ((packed));
215
216/* Primary Volume Descriptor (ECMA 167r3 3/10.1) */
217struct primaryVolDesc
218{
219 tag descTag;
220 __le32 volDescSeqNum;
221 __le32 primaryVolDescNum;
222 dstring volIdent[32];
223 __le16 volSeqNum;
224 __le16 maxVolSeqNum;
225 __le16 interchangeLvl;
226 __le16 maxInterchangeLvl;
227 __le32 charSetList;
228 __le32 maxCharSetList;
229 dstring volSetIdent[128];
230 charspec descCharSet;
231 charspec explanatoryCharSet;
232 extent_ad volAbstract;
233 extent_ad volCopyright;
234 regid appIdent;
235 timestamp recordingDateAndTime;
236 regid impIdent;
237 uint8_t impUse[64];
238 __le32 predecessorVolDescSeqLocation;
239 __le16 flags;
240 uint8_t reserved[22];
241} __attribute__ ((packed));
242
243/* Flags (ECMA 167r3 3/10.1.21) */
244#define PVD_FLAGS_VSID_COMMON 0x0001
245
246/* Anchor Volume Descriptor Pointer (ECMA 167r3 3/10.2) */
247struct anchorVolDescPtr
248{
249 tag descTag;
250 extent_ad mainVolDescSeqExt;
251 extent_ad reserveVolDescSeqExt;
252 uint8_t reserved[480];
253} __attribute__ ((packed));
254
255/* Volume Descriptor Pointer (ECMA 167r3 3/10.3) */
256struct volDescPtr
257{
258 tag descTag;
259 __le32 volDescSeqNum;
260 extent_ad nextVolDescSeqExt;
261 uint8_t reserved[484];
262} __attribute__ ((packed));
263
264/* Implementation Use Volume Descriptor (ECMA 167r3 3/10.4) */
265struct impUseVolDesc
266{
267 tag descTag;
268 __le32 volDescSeqNum;
269 regid impIdent;
270 uint8_t impUse[460];
271} __attribute__ ((packed));
272
273/* Partition Descriptor (ECMA 167r3 3/10.5) */
274struct partitionDesc
275{
276 tag descTag;
277 __le32 volDescSeqNum;
278 __le16 partitionFlags;
279 __le16 partitionNumber;
280 regid partitionContents;
281 uint8_t partitionContentsUse[128];
282 __le32 accessType;
283 __le32 partitionStartingLocation;
284 __le32 partitionLength;
285 regid impIdent;
286 uint8_t impUse[128];
287 uint8_t reserved[156];
288} __attribute__ ((packed));
289
290/* Partition Flags (ECMA 167r3 3/10.5.3) */
291#define PD_PARTITION_FLAGS_ALLOC 0x0001
292
293/* Partition Contents (ECMA 167r2 3/10.5.3) */
294#define PD_PARTITION_CONTENTS_NSR02 "+NSR02"
295
296/* Partition Contents (ECMA 167r3 3/10.5.5) */
297#define PD_PARTITION_CONTENTS_FDC01 "+FDC01"
298#define PD_PARTITION_CONTENTS_CD001 "+CD001"
299#define PD_PARTITION_CONTENTS_CDW02 "+CDW02"
300#define PD_PARTITION_CONTENTS_NSR03 "+NSR03"
301
302/* Access Type (ECMA 167r3 3/10.5.7) */
303#define PD_ACCESS_TYPE_NONE 0x00000000
304#define PD_ACCESS_TYPE_READ_ONLY 0x00000001
305#define PD_ACCESS_TYPE_WRITE_ONCE 0x00000002
306#define PD_ACCESS_TYPE_REWRITABLE 0x00000003
307#define PD_ACCESS_TYPE_OVERWRITABLE 0x00000004
308
309/* Logical Volume Descriptor (ECMA 167r3 3/10.6) */
310struct logicalVolDesc
311{
312 tag descTag;
313 __le32 volDescSeqNum;
314 charspec descCharSet;
315 dstring logicalVolIdent[128];
316 __le32 logicalBlockSize;
317 regid domainIdent;
318 uint8_t logicalVolContentsUse[16];
319 __le32 mapTableLength;
320 __le32 numPartitionMaps;
321 regid impIdent;
322 uint8_t impUse[128];
323 extent_ad integritySeqExt;
324 uint8_t partitionMaps[0];
325} __attribute__ ((packed));
326
327/* Generic Partition Map (ECMA 167r3 3/10.7.1) */
328struct genericPartitionMap
329{
330 uint8_t partitionMapType;
331 uint8_t partitionMapLength;
332 uint8_t partitionMapping[0];
333} __attribute__ ((packed));
334
335/* Partition Map Type (ECMA 167r3 3/10.7.1.1) */
336#define GP_PARTITION_MAP_TYPE_UNDEF 0x00
337#define GP_PARTIITON_MAP_TYPE_1 0x01
338#define GP_PARTITION_MAP_TYPE_2 0x02
339
340/* Type 1 Partition Map (ECMA 167r3 3/10.7.2) */
341struct genericPartitionMap1
342{
343 uint8_t partitionMapType;
344 uint8_t partitionMapLength;
345 __le16 volSeqNum;
346 __le16 partitionNum;
347} __attribute__ ((packed));
348
349/* Type 2 Partition Map (ECMA 167r3 3/10.7.3) */
350struct genericPartitionMap2
351{
352 uint8_t partitionMapType;
353 uint8_t partitionMapLength;
354 uint8_t partitionIdent[62];
355} __attribute__ ((packed));
356
357/* Unallocated Space Descriptor (ECMA 167r3 3/10.8) */
358struct unallocSpaceDesc
359{
360 tag descTag;
361 __le32 volDescSeqNum;
362 __le32 numAllocDescs;
363 extent_ad allocDescs[0];
364} __attribute__ ((packed));
365
366/* Terminating Descriptor (ECMA 167r3 3/10.9) */
367struct terminatingDesc
368{
369 tag descTag;
370 uint8_t reserved[496];
371} __attribute__ ((packed));
372
373/* Logical Volume Integrity Descriptor (ECMA 167r3 3/10.10) */
374struct logicalVolIntegrityDesc
375{
376 tag descTag;
377 timestamp recordingDateAndTime;
378 __le32 integrityType;
379 extent_ad nextIntegrityExt;
380 uint8_t logicalVolContentsUse[32];
381 __le32 numOfPartitions;
382 __le32 lengthOfImpUse;
383 __le32 freeSpaceTable[0];
384 __le32 sizeTable[0];
385 uint8_t impUse[0];
386} __attribute__ ((packed));
387
388/* Integrity Type (ECMA 167r3 3/10.10.3) */
389#define LVID_INTEGRITY_TYPE_OPEN 0x00000000
390#define LVID_INTEGRITY_TYPE_CLOSE 0x00000001
391
392/* Recorded Address (ECMA 167r3 4/7.1) */
393typedef struct
394{
395 __le32 logicalBlockNum;
396 __le16 partitionReferenceNum;
397} __attribute__ ((packed)) lb_addr;
398
399/* ... and its in-core analog */
400typedef struct
401{
402 uint32_t logicalBlockNum;
403 uint16_t partitionReferenceNum;
404} kernel_lb_addr;
405
406/* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */
407typedef struct
408{
409 __le32 extLength;
410 __le32 extPosition;
411} __attribute__ ((packed)) short_ad;
412
413/* Long Allocation Descriptor (ECMA 167r3 4/14.14.2) */
414typedef struct
415{
416 __le32 extLength;
417 lb_addr extLocation;
418 uint8_t impUse[6];
419} __attribute__ ((packed)) long_ad;
420
421typedef struct
422{
423 uint32_t extLength;
424 kernel_lb_addr extLocation;
425 uint8_t impUse[6];
426} kernel_long_ad;
427
428/* Extended Allocation Descriptor (ECMA 167r3 4/14.14.3) */
429typedef struct
430{
431 __le32 extLength;
432 __le32 recordedLength;
433 __le32 informationLength;
434 lb_addr extLocation;
435} __attribute__ ((packed)) ext_ad;
436
437typedef struct
438{
439 uint32_t extLength;
440 uint32_t recordedLength;
441 uint32_t informationLength;
442 kernel_lb_addr extLocation;
443} kernel_ext_ad;
444
445/* Descriptor Tag (ECMA 167r3 4/7.2 - See 3/7.2) */
446
447/* Tag Identifier (ECMA 167r3 4/7.2.1) */
448#define TAG_IDENT_FSD 0x0100
449#define TAG_IDENT_FID 0x0101
450#define TAG_IDENT_AED 0x0102
451#define TAG_IDENT_IE 0x0103
452#define TAG_IDENT_TE 0x0104
453#define TAG_IDENT_FE 0x0105
454#define TAG_IDENT_EAHD 0x0106
455#define TAG_IDENT_USE 0x0107
456#define TAG_IDENT_SBD 0x0108
457#define TAG_IDENT_PIE 0x0109
458#define TAG_IDENT_EFE 0x010A
459
460/* File Set Descriptor (ECMA 167r3 4/14.1) */
461struct fileSetDesc
462{
463 tag descTag;
464 timestamp recordingDateAndTime;
465 __le16 interchangeLvl;
466 __le16 maxInterchangeLvl;
467 __le32 charSetList;
468 __le32 maxCharSetList;
469 __le32 fileSetNum;
470 __le32 fileSetDescNum;
471 charspec logicalVolIdentCharSet;
472 dstring logicalVolIdent[128];
473 charspec fileSetCharSet;
474 dstring fileSetIdent[32];
475 dstring copyrightFileIdent[32];
476 dstring abstractFileIdent[32];
477 long_ad rootDirectoryICB;
478 regid domainIdent;
479 long_ad nextExt;
480 long_ad streamDirectoryICB;
481 uint8_t reserved[32];
482} __attribute__ ((packed));
483
484/* Partition Header Descriptor (ECMA 167r3 4/14.3) */
485struct partitionHeaderDesc
486{
487 short_ad unallocSpaceTable;
488 short_ad unallocSpaceBitmap;
489 short_ad partitionIntegrityTable;
490 short_ad freedSpaceTable;
491 short_ad freedSpaceBitmap;
492 uint8_t reserved[88];
493} __attribute__ ((packed));
494
495/* File Identifier Descriptor (ECMA 167r3 4/14.4) */
496struct fileIdentDesc
497{
498 tag descTag;
499 __le16 fileVersionNum;
500 uint8_t fileCharacteristics;
501 uint8_t lengthFileIdent;
502 long_ad icb;
503 __le16 lengthOfImpUse;
504 uint8_t impUse[0];
505 uint8_t fileIdent[0];
506 uint8_t padding[0];
507} __attribute__ ((packed));
508
509/* File Characteristics (ECMA 167r3 4/14.4.3) */
510#define FID_FILE_CHAR_HIDDEN 0x01
511#define FID_FILE_CHAR_DIRECTORY 0x02
512#define FID_FILE_CHAR_DELETED 0x04
513#define FID_FILE_CHAR_PARENT 0x08
514#define FID_FILE_CHAR_METADATA 0x10
515
516/* Allocation Ext Descriptor (ECMA 167r3 4/14.5) */
517struct allocExtDesc
518{
519 tag descTag;
520 __le32 previousAllocExtLocation;
521 __le32 lengthAllocDescs;
522} __attribute__ ((packed));
523
524/* ICB Tag (ECMA 167r3 4/14.6) */
525typedef struct
526{
527 __le32 priorRecordedNumDirectEntries;
528 __le16 strategyType;
529 __le16 strategyParameter;
530 __le16 numEntries;
531 uint8_t reserved;
532 uint8_t fileType;
533 lb_addr parentICBLocation;
534 __le16 flags;
535} __attribute__ ((packed)) icbtag;
536
537/* Strategy Type (ECMA 167r3 4/14.6.2) */
538#define ICBTAG_STRATEGY_TYPE_UNDEF 0x0000
539#define ICBTAG_STRATEGY_TYPE_1 0x0001
540#define ICBTAG_STRATEGY_TYPE_2 0x0002
541#define ICBTAG_STRATEGY_TYPE_3 0x0003
542#define ICBTAG_STRATEGY_TYPE_4 0x0004
543
544/* File Type (ECMA 167r3 4/14.6.6) */
545#define ICBTAG_FILE_TYPE_UNDEF 0x00
546#define ICBTAG_FILE_TYPE_USE 0x01
547#define ICBTAG_FILE_TYPE_PIE 0x02
548#define ICBTAG_FILE_TYPE_IE 0x03
549#define ICBTAG_FILE_TYPE_DIRECTORY 0x04
550#define ICBTAG_FILE_TYPE_REGULAR 0x05
551#define ICBTAG_FILE_TYPE_BLOCK 0x06
552#define ICBTAG_FILE_TYPE_CHAR 0x07
553#define ICBTAG_FILE_TYPE_EA 0x08
554#define ICBTAG_FILE_TYPE_FIFO 0x09
555#define ICBTAG_FILE_TYPE_SOCKET 0x0A
556#define ICBTAG_FILE_TYPE_TE 0x0B
557#define ICBTAG_FILE_TYPE_SYMLINK 0x0C
558#define ICBTAG_FILE_TYPE_STREAMDIR 0x0D
559
560/* Flags (ECMA 167r3 4/14.6.8) */
561#define ICBTAG_FLAG_AD_MASK 0x0007
562#define ICBTAG_FLAG_AD_SHORT 0x0000
563#define ICBTAG_FLAG_AD_LONG 0x0001
564#define ICBTAG_FLAG_AD_EXTENDED 0x0002
565#define ICBTAG_FLAG_AD_IN_ICB 0x0003
566#define ICBTAG_FLAG_SORTED 0x0008
567#define ICBTAG_FLAG_NONRELOCATABLE 0x0010
568#define ICBTAG_FLAG_ARCHIVE 0x0020
569#define ICBTAG_FLAG_SETUID 0x0040
570#define ICBTAG_FLAG_SETGID 0x0080
571#define ICBTAG_FLAG_STICKY 0x0100
572#define ICBTAG_FLAG_CONTIGUOUS 0x0200
573#define ICBTAG_FLAG_SYSTEM 0x0400
574#define ICBTAG_FLAG_TRANSFORMED 0x0800
575#define ICBTAG_FLAG_MULTIVERSIONS 0x1000
576#define ICBTAG_FLAG_STREAM 0x2000
577
578/* Indirect Entry (ECMA 167r3 4/14.7) */
579struct indirectEntry
580{
581 tag descTag;
582 icbtag icbTag;
583 long_ad indirectICB;
584} __attribute__ ((packed));
585
586/* Terminal Entry (ECMA 167r3 4/14.8) */
587struct terminalEntry
588{
589 tag descTag;
590 icbtag icbTag;
591} __attribute__ ((packed));
592
593/* File Entry (ECMA 167r3 4/14.9) */
594struct fileEntry
595{
596 tag descTag;
597 icbtag icbTag;
598 __le32 uid;
599 __le32 gid;
600 __le32 permissions;
601 __le16 fileLinkCount;
602 uint8_t recordFormat;
603 uint8_t recordDisplayAttr;
604 __le32 recordLength;
605 __le64 informationLength;
606 __le64 logicalBlocksRecorded;
607 timestamp accessTime;
608 timestamp modificationTime;
609 timestamp attrTime;
610 __le32 checkpoint;
611 long_ad extendedAttrICB;
612 regid impIdent;
613 __le64 uniqueID;
614 __le32 lengthExtendedAttr;
615 __le32 lengthAllocDescs;
616 uint8_t extendedAttr[0];
617 uint8_t allocDescs[0];
618} __attribute__ ((packed));
619
620/* Permissions (ECMA 167r3 4/14.9.5) */
621#define FE_PERM_O_EXEC 0x00000001U
622#define FE_PERM_O_WRITE 0x00000002U
623#define FE_PERM_O_READ 0x00000004U
624#define FE_PERM_O_CHATTR 0x00000008U
625#define FE_PERM_O_DELETE 0x00000010U
626#define FE_PERM_G_EXEC 0x00000020U
627#define FE_PERM_G_WRITE 0x00000040U
628#define FE_PERM_G_READ 0x00000080U
629#define FE_PERM_G_CHATTR 0x00000100U
630#define FE_PERM_G_DELETE 0x00000200U
631#define FE_PERM_U_EXEC 0x00000400U
632#define FE_PERM_U_WRITE 0x00000800U
633#define FE_PERM_U_READ 0x00001000U
634#define FE_PERM_U_CHATTR 0x00002000U
635#define FE_PERM_U_DELETE 0x00004000U
636
637/* Record Format (ECMA 167r3 4/14.9.7) */
638#define FE_RECORD_FMT_UNDEF 0x00
639#define FE_RECORD_FMT_FIXED_PAD 0x01
640#define FE_RECORD_FMT_FIXED 0x02
641#define FE_RECORD_FMT_VARIABLE8 0x03
642#define FE_RECORD_FMT_VARIABLE16 0x04
643#define FE_RECORD_FMT_VARIABLE16_MSB 0x05
644#define FE_RECORD_FMT_VARIABLE32 0x06
645#define FE_RECORD_FMT_PRINT 0x07
646#define FE_RECORD_FMT_LF 0x08
647#define FE_RECORD_FMT_CR 0x09
648#define FE_RECORD_FMT_CRLF 0x0A
649#define FE_RECORD_FMT_LFCR 0x0B
650
651/* Record Display Attributes (ECMA 167r3 4/14.9.8) */
652#define FE_RECORD_DISPLAY_ATTR_UNDEF 0x00
653#define FE_RECORD_DISPLAY_ATTR_1 0x01
654#define FE_RECORD_DISPLAY_ATTR_2 0x02
655#define FE_RECORD_DISPLAY_ATTR_3 0x03
656
657/* Extended Attribute Header Descriptor (ECMA 167r3 4/14.10.1) */
658struct extendedAttrHeaderDesc
659{
660 tag descTag;
661 __le32 impAttrLocation;
662 __le32 appAttrLocation;
663} __attribute__ ((packed));
664
665/* Generic Format (ECMA 167r3 4/14.10.2) */
666struct genericFormat
667{
668 __le32 attrType;
669 uint8_t attrSubtype;
670 uint8_t reserved[3];
671 __le32 attrLength;
672 uint8_t attrData[0];
673} __attribute__ ((packed));
674
675/* Character Set Information (ECMA 167r3 4/14.10.3) */
676struct charSetInfo
677{
678 __le32 attrType;
679 uint8_t attrSubtype;
680 uint8_t reserved[3];
681 __le32 attrLength;
682 __le32 escapeSeqLength;
683 uint8_t charSetType;
684 uint8_t escapeSeq[0];
685} __attribute__ ((packed));
686
687/* Alternate Permissions (ECMA 167r3 4/14.10.4) */
688struct altPerms
689{
690 __le32 attrType;
691 uint8_t attrSubtype;
692 uint8_t reserved[3];
693 __le32 attrLength;
694 __le16 ownerIdent;
695 __le16 groupIdent;
696 __le16 permission;
697} __attribute__ ((packed));
698
699/* File Times Extended Attribute (ECMA 167r3 4/14.10.5) */
700struct fileTimesExtAttr
701{
702 __le32 attrType;
703 uint8_t attrSubtype;
704 uint8_t reserved[3];
705 __le32 attrLength;
706 __le32 dataLength;
707 __le32 fileTimeExistence;
708 uint8_t fileTimes;
709} __attribute__ ((packed));
710
711/* FileTimeExistence (ECMA 167r3 4/14.10.5.6) */
712#define FTE_CREATION 0x00000001
713#define FTE_DELETION 0x00000004
714#define FTE_EFFECTIVE 0x00000008
715#define FTE_BACKUP 0x00000002
716
717/* Information Times Extended Attribute (ECMA 167r3 4/14.10.6) */
718struct infoTimesExtAttr
719{
720 __le32 attrType;
721 uint8_t attrSubtype;
722 uint8_t reserved[3];
723 __le32 attrLength;
724 __le32 dataLength;
725 __le32 infoTimeExistence;
726 uint8_t infoTimes[0];
727} __attribute__ ((packed));
728
729/* Device Specification (ECMA 167r3 4/14.10.7) */
730struct deviceSpec
731{
732 __le32 attrType;
733 uint8_t attrSubtype;
734 uint8_t reserved[3];
735 __le32 attrLength;
736 __le32 impUseLength;
737 __le32 majorDeviceIdent;
738 __le32 minorDeviceIdent;
739 uint8_t impUse[0];
740} __attribute__ ((packed));
741
742/* Implementation Use Extended Attr (ECMA 167r3 4/14.10.8) */
743struct impUseExtAttr
744{
745 __le32 attrType;
746 uint8_t attrSubtype;
747 uint8_t reserved[3];
748 __le32 attrLength;
749 __le32 impUseLength;
750 regid impIdent;
751 uint8_t impUse[0];
752} __attribute__ ((packed));
753
754/* Application Use Extended Attribute (ECMA 167r3 4/14.10.9) */
755struct appUseExtAttr
756{
757 __le32 attrType;
758 uint8_t attrSubtype;
759 uint8_t reserved[3];
760 __le32 attrLength;
761 __le32 appUseLength;
762 regid appIdent;
763 uint8_t appUse[0];
764} __attribute__ ((packed));
765
766#define EXTATTR_CHAR_SET 1
767#define EXTATTR_ALT_PERMS 3
768#define EXTATTR_FILE_TIMES 5
769#define EXTATTR_INFO_TIMES 6
770#define EXTATTR_DEV_SPEC 12
771#define EXTATTR_IMP_USE 2048
772#define EXTATTR_APP_USE 65536
773
774
775/* Unallocated Space Entry (ECMA 167r3 4/14.11) */
776struct unallocSpaceEntry
777{
778 tag descTag;
779 icbtag icbTag;
780 __le32 lengthAllocDescs;
781 uint8_t allocDescs[0];
782} __attribute__ ((packed));
783
784/* Space Bitmap Descriptor (ECMA 167r3 4/14.12) */
785struct spaceBitmapDesc
786{
787 tag descTag;
788 __le32 numOfBits;
789 __le32 numOfBytes;
790 uint8_t bitmap[0];
791} __attribute__ ((packed));
792
793/* Partition Integrity Entry (ECMA 167r3 4/14.13) */
794struct partitionIntegrityEntry
795{
796 tag descTag;
797 icbtag icbTag;
798 timestamp recordingDateAndTime;
799 uint8_t integrityType;
800 uint8_t reserved[175];
801 regid impIdent;
802 uint8_t impUse[256];
803} __attribute__ ((packed));
804
805/* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */
806
807/* Extent Length (ECMA 167r3 4/14.14.1.1) */
808#define EXT_RECORDED_ALLOCATED 0x00000000
809#define EXT_NOT_RECORDED_ALLOCATED 0x40000000
810#define EXT_NOT_RECORDED_NOT_ALLOCATED 0x80000000
811#define EXT_NEXT_EXTENT_ALLOCDECS 0xC0000000
812
813/* Long Allocation Descriptor (ECMA 167r3 4/14.14.2) */
814
815/* Extended Allocation Descriptor (ECMA 167r3 4/14.14.3) */
816
817/* Logical Volume Header Descriptor (ECMA 167r3 4/14.15) */
818struct logicalVolHeaderDesc
819{
820 __le64 uniqueID;
821 uint8_t reserved[24];
822} __attribute__ ((packed));
823
824/* Path Component (ECMA 167r3 4/14.16.1) */
825struct pathComponent
826{
827 uint8_t componentType;
828 uint8_t lengthComponentIdent;
829 __le16 componentFileVersionNum;
830 dstring componentIdent[0];
831} __attribute__ ((packed));
832
833/* File Entry (ECMA 167r3 4/14.17) */
834struct extendedFileEntry
835{
836 tag descTag;
837 icbtag icbTag;
838 __le32 uid;
839 __le32 gid;
840 __le32 permissions;
841 __le16 fileLinkCount;
842 uint8_t recordFormat;
843 uint8_t recordDisplayAttr;
844 __le32 recordLength;
845 __le64 informationLength;
846 __le64 objectSize;
847 __le64 logicalBlocksRecorded;
848 timestamp accessTime;
849 timestamp modificationTime;
850 timestamp createTime;
851 timestamp attrTime;
852 __le32 checkpoint;
853 __le32 reserved;
854 long_ad extendedAttrICB;
855 long_ad streamDirectoryICB;
856 regid impIdent;
857 __le64 uniqueID;
858 __le32 lengthExtendedAttr;
859 __le32 lengthAllocDescs;
860 uint8_t extendedAttr[0];
861 uint8_t allocDescs[0];
862} __attribute__ ((packed));
863
864#endif /* _ECMA_167_H */
diff --git a/fs/udf/file.c b/fs/udf/file.c
new file mode 100644
index 000000000000..2faa4172b9f7
--- /dev/null
+++ b/fs/udf/file.c
@@ -0,0 +1,270 @@
1/*
2 * file.c
3 *
4 * PURPOSE
5 * File handling routines for the OSTA-UDF(tm) filesystem.
6 *
7 * CONTACTS
8 * E-mail regarding any portion of the Linux UDF file system should be
9 * directed to the development team mailing list (run by majordomo):
10 * linux_udf@hpesjro.fc.hp.com
11 *
12 * COPYRIGHT
13 * This file is distributed under the terms of the GNU General Public
14 * License (GPL). Copies of the GPL can be obtained from:
15 * ftp://prep.ai.mit.edu/pub/gnu/GPL
16 * Each contributing author retains all rights to their own work.
17 *
18 * (C) 1998-1999 Dave Boynton
19 * (C) 1998-2004 Ben Fennema
20 * (C) 1999-2000 Stelias Computing Inc
21 *
22 * HISTORY
23 *
24 * 10/02/98 dgb Attempt to integrate into udf.o
25 * 10/07/98 Switched to using generic_readpage, etc., like isofs
26 * And it works!
27 * 12/06/98 blf Added udf_file_read. uses generic_file_read for all cases but
28 * ICBTAG_FLAG_AD_IN_ICB.
29 * 04/06/99 64 bit file handling on 32 bit systems taken from ext2 file.c
30 * 05/12/99 Preliminary file write support
31 */
32
33#include "udfdecl.h"
34#include <linux/fs.h>
35#include <linux/udf_fs.h>
36#include <asm/uaccess.h>
37#include <linux/kernel.h>
38#include <linux/string.h> /* memset */
39#include <linux/errno.h>
40#include <linux/smp_lock.h>
41#include <linux/pagemap.h>
42#include <linux/buffer_head.h>
43
44#include "udf_i.h"
45#include "udf_sb.h"
46
47static int udf_adinicb_readpage(struct file *file, struct page * page)
48{
49 struct inode *inode = page->mapping->host;
50 char *kaddr;
51
52 if (!PageLocked(page))
53 PAGE_BUG(page);
54
55 kaddr = kmap(page);
56 memset(kaddr, 0, PAGE_CACHE_SIZE);
57 memcpy(kaddr, UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), inode->i_size);
58 flush_dcache_page(page);
59 SetPageUptodate(page);
60 kunmap(page);
61 unlock_page(page);
62 return 0;
63}
64
65static int udf_adinicb_writepage(struct page *page, struct writeback_control *wbc)
66{
67 struct inode *inode = page->mapping->host;
68 char *kaddr;
69
70 if (!PageLocked(page))
71 PAGE_BUG(page);
72
73 kaddr = kmap(page);
74 memcpy(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), kaddr, inode->i_size);
75 mark_inode_dirty(inode);
76 SetPageUptodate(page);
77 kunmap(page);
78 unlock_page(page);
79 return 0;
80}
81
82static int udf_adinicb_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
83{
84 kmap(page);
85 return 0;
86}
87
88static int udf_adinicb_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
89{
90 struct inode *inode = page->mapping->host;
91 char *kaddr = page_address(page);
92
93 memcpy(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset,
94 kaddr + offset, to - offset);
95 mark_inode_dirty(inode);
96 SetPageUptodate(page);
97 kunmap(page);
98 /* only one page here */
99 if (to > inode->i_size)
100 inode->i_size = to;
101 return 0;
102}
103
104struct address_space_operations udf_adinicb_aops = {
105 .readpage = udf_adinicb_readpage,
106 .writepage = udf_adinicb_writepage,
107 .sync_page = block_sync_page,
108 .prepare_write = udf_adinicb_prepare_write,
109 .commit_write = udf_adinicb_commit_write,
110};
111
112static ssize_t udf_file_write(struct file * file, const char __user * buf,
113 size_t count, loff_t *ppos)
114{
115 ssize_t retval;
116 struct inode *inode = file->f_dentry->d_inode;
117 int err, pos;
118
119 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
120 {
121 if (file->f_flags & O_APPEND)
122 pos = inode->i_size;
123 else
124 pos = *ppos;
125
126 if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
127 pos + count))
128 {
129 udf_expand_file_adinicb(inode, pos + count, &err);
130 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
131 {
132 udf_debug("udf_expand_adinicb: err=%d\n", err);
133 return err;
134 }
135 }
136 else
137 {
138 if (pos + count > inode->i_size)
139 UDF_I_LENALLOC(inode) = pos + count;
140 else
141 UDF_I_LENALLOC(inode) = inode->i_size;
142 }
143 }
144
145 retval = generic_file_write(file, buf, count, ppos);
146
147 if (retval > 0)
148 mark_inode_dirty(inode);
149 return retval;
150}
151
152/*
153 * udf_ioctl
154 *
155 * PURPOSE
156 * Issue an ioctl.
157 *
158 * DESCRIPTION
159 * Optional - sys_ioctl() will return -ENOTTY if this routine is not
160 * available, and the ioctl cannot be handled without filesystem help.
161 *
162 * sys_ioctl() handles these ioctls that apply only to regular files:
163 * FIBMAP [requires udf_block_map()], FIGETBSZ, FIONREAD
164 * These ioctls are also handled by sys_ioctl():
165 * FIOCLEX, FIONCLEX, FIONBIO, FIOASYNC
166 * All other ioctls are passed to the filesystem.
167 *
168 * Refer to sys_ioctl() in fs/ioctl.c
169 * sys_ioctl() -> .
170 *
171 * PRE-CONDITIONS
172 * inode Pointer to inode that ioctl was issued on.
173 * filp Pointer to file that ioctl was issued on.
174 * cmd The ioctl command.
175 * arg The ioctl argument [can be interpreted as a
176 * user-space pointer if desired].
177 *
178 * POST-CONDITIONS
179 * <return> Success (>=0) or an error code (<=0) that
180 * sys_ioctl() will return.
181 *
182 * HISTORY
183 * July 1, 1997 - Andrew E. Mileski
184 * Written, tested, and released.
185 */
186int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
187 unsigned long arg)
188{
189 int result = -EINVAL;
190
191 if ( permission(inode, MAY_READ, NULL) != 0 )
192 {
193 udf_debug("no permission to access inode %lu\n",
194 inode->i_ino);
195 return -EPERM;
196 }
197
198 if ( !arg )
199 {
200 udf_debug("invalid argument to udf_ioctl\n");
201 return -EINVAL;
202 }
203
204 switch (cmd)
205 {
206 case UDF_GETVOLIDENT:
207 return copy_to_user((char __user *)arg,
208 UDF_SB_VOLIDENT(inode->i_sb), 32) ? -EFAULT : 0;
209 case UDF_RELOCATE_BLOCKS:
210 {
211 long old, new;
212
213 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
214 if (get_user(old, (long __user *)arg)) return -EFAULT;
215 if ((result = udf_relocate_blocks(inode->i_sb,
216 old, &new)) == 0)
217 result = put_user(new, (long __user *)arg);
218
219 return result;
220 }
221 case UDF_GETEASIZE:
222 result = put_user(UDF_I_LENEATTR(inode), (int __user *)arg);
223 break;
224
225 case UDF_GETEABLOCK:
226 result = copy_to_user((char __user *)arg, UDF_I_DATA(inode),
227 UDF_I_LENEATTR(inode)) ? -EFAULT : 0;
228 break;
229 }
230
231 return result;
232}
233
234/*
235 * udf_release_file
236 *
237 * PURPOSE
238 * Called when all references to the file are closed
239 *
240 * DESCRIPTION
241 * Discard prealloced blocks
242 *
243 * HISTORY
244 *
245 */
246static int udf_release_file(struct inode * inode, struct file * filp)
247{
248 if (filp->f_mode & FMODE_WRITE)
249 {
250 lock_kernel();
251 udf_discard_prealloc(inode);
252 unlock_kernel();
253 }
254 return 0;
255}
256
257struct file_operations udf_file_operations = {
258 .read = generic_file_read,
259 .ioctl = udf_ioctl,
260 .open = generic_file_open,
261 .mmap = generic_file_mmap,
262 .write = udf_file_write,
263 .release = udf_release_file,
264 .fsync = udf_fsync_file,
265 .sendfile = generic_file_sendfile,
266};
267
268struct inode_operations udf_file_inode_operations = {
269 .truncate = udf_truncate,
270};
diff --git a/fs/udf/fsync.c b/fs/udf/fsync.c
new file mode 100644
index 000000000000..2dde6b888c2b
--- /dev/null
+++ b/fs/udf/fsync.c
@@ -0,0 +1,56 @@
1/*
2 * fsync.c
3 *
4 * PURPOSE
5 * Fsync handling routines for the OSTA-UDF(tm) filesystem.
6 *
7 * CONTACTS
8 * E-mail regarding any portion of the Linux UDF file system should be
9 * directed to the development team mailing list (run by majordomo):
10 * linux_udf@hpesjro.fc.hp.com
11 *
12 * COPYRIGHT
13 * This file is distributed under the terms of the GNU General Public
14 * License (GPL). Copies of the GPL can be obtained from:
15 * ftp://prep.ai.mit.edu/pub/gnu/GPL
16 * Each contributing author retains all rights to their own work.
17 *
18 * (C) 1999-2001 Ben Fennema
19 * (C) 1999-2000 Stelias Computing Inc
20 *
21 * HISTORY
22 *
23 * 05/22/99 blf Created.
24 */
25
26#include "udfdecl.h"
27
28#include <linux/fs.h>
29#include <linux/smp_lock.h>
30
31static int udf_fsync_inode(struct inode *, int);
32
33/*
34 * File may be NULL when we are called. Perhaps we shouldn't
35 * even pass file to fsync ?
36 */
37
38int udf_fsync_file(struct file * file, struct dentry *dentry, int datasync)
39{
40 struct inode *inode = dentry->d_inode;
41 return udf_fsync_inode(inode, datasync);
42}
43
44static int udf_fsync_inode(struct inode *inode, int datasync)
45{
46 int err;
47
48 err = sync_mapping_buffers(inode->i_mapping);
49 if (!(inode->i_state & I_DIRTY))
50 return err;
51 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
52 return err;
53
54 err |= udf_sync_inode (inode);
55 return err ? -EIO : 0;
56}
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c
new file mode 100644
index 000000000000..a7e5d40f1ebc
--- /dev/null
+++ b/fs/udf/ialloc.c
@@ -0,0 +1,170 @@
1/*
2 * ialloc.c
3 *
4 * PURPOSE
5 * Inode allocation handling routines for the OSTA-UDF(tm) filesystem.
6 *
7 * CONTACTS
8 * E-mail regarding any portion of the Linux UDF file system should be
9 * directed to the development team mailing list (run by majordomo):
10 * linux_udf@hpesjro.fc.hp.com
11 *
12 * COPYRIGHT
13 * This file is distributed under the terms of the GNU General Public
14 * License (GPL). Copies of the GPL can be obtained from:
15 * ftp://prep.ai.mit.edu/pub/gnu/GPL
16 * Each contributing author retains all rights to their own work.
17 *
18 * (C) 1998-2001 Ben Fennema
19 *
20 * HISTORY
21 *
22 * 02/24/99 blf Created.
23 *
24 */
25
26#include "udfdecl.h"
27#include <linux/fs.h>
28#include <linux/quotaops.h>
29#include <linux/udf_fs.h>
30#include <linux/sched.h>
31#include <linux/slab.h>
32
33#include "udf_i.h"
34#include "udf_sb.h"
35
36void udf_free_inode(struct inode * inode)
37{
38 struct super_block *sb = inode->i_sb;
39 struct udf_sb_info *sbi = UDF_SB(sb);
40
41 /*
42 * Note: we must free any quota before locking the superblock,
43 * as writing the quota to disk may need the lock as well.
44 */
45 DQUOT_FREE_INODE(inode);
46 DQUOT_DROP(inode);
47
48 clear_inode(inode);
49
50 down(&sbi->s_alloc_sem);
51 if (sbi->s_lvidbh) {
52 if (S_ISDIR(inode->i_mode))
53 UDF_SB_LVIDIU(sb)->numDirs =
54 cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) - 1);
55 else
56 UDF_SB_LVIDIU(sb)->numFiles =
57 cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) - 1);
58
59 mark_buffer_dirty(sbi->s_lvidbh);
60 }
61 up(&sbi->s_alloc_sem);
62
63 udf_free_blocks(sb, NULL, UDF_I_LOCATION(inode), 0, 1);
64}
65
66struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
67{
68 struct super_block *sb = dir->i_sb;
69 struct udf_sb_info *sbi = UDF_SB(sb);
70 struct inode * inode;
71 int block;
72 uint32_t start = UDF_I_LOCATION(dir).logicalBlockNum;
73
74 inode = new_inode(sb);
75
76 if (!inode)
77 {
78 *err = -ENOMEM;
79 return NULL;
80 }
81 *err = -ENOSPC;
82
83 block = udf_new_block(dir->i_sb, NULL, UDF_I_LOCATION(dir).partitionReferenceNum,
84 start, err);
85 if (*err)
86 {
87 iput(inode);
88 return NULL;
89 }
90
91 down(&sbi->s_alloc_sem);
92 UDF_I_UNIQUE(inode) = 0;
93 UDF_I_LENEXTENTS(inode) = 0;
94 UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
95 UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
96 UDF_I_STRAT4096(inode) = 0;
97 if (UDF_SB_LVIDBH(sb))
98 {
99 struct logicalVolHeaderDesc *lvhd;
100 uint64_t uniqueID;
101 lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(sb)->logicalVolContentsUse);
102 if (S_ISDIR(mode))
103 UDF_SB_LVIDIU(sb)->numDirs =
104 cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) + 1);
105 else
106 UDF_SB_LVIDIU(sb)->numFiles =
107 cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) + 1);
108 UDF_I_UNIQUE(inode) = uniqueID = le64_to_cpu(lvhd->uniqueID);
109 if (!(++uniqueID & 0x00000000FFFFFFFFUL))
110 uniqueID += 16;
111 lvhd->uniqueID = cpu_to_le64(uniqueID);
112 mark_buffer_dirty(UDF_SB_LVIDBH(sb));
113 }
114 inode->i_mode = mode;
115 inode->i_uid = current->fsuid;
116 if (dir->i_mode & S_ISGID)
117 {
118 inode->i_gid = dir->i_gid;
119 if (S_ISDIR(mode))
120 mode |= S_ISGID;
121 }
122 else
123 inode->i_gid = current->fsgid;
124
125 UDF_I_LOCATION(inode).logicalBlockNum = block;
126 UDF_I_LOCATION(inode).partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum;
127 inode->i_ino = udf_get_lb_pblock(sb, UDF_I_LOCATION(inode), 0);
128 inode->i_blksize = PAGE_SIZE;
129 inode->i_blocks = 0;
130 UDF_I_LENEATTR(inode) = 0;
131 UDF_I_LENALLOC(inode) = 0;
132 UDF_I_USE(inode) = 0;
133 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE))
134 {
135 UDF_I_EFE(inode) = 1;
136 UDF_UPDATE_UDFREV(inode->i_sb, UDF_VERS_USE_EXTENDED_FE);
137 UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry), GFP_KERNEL);
138 memset(UDF_I_DATA(inode), 0x00, inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry));
139 }
140 else
141 {
142 UDF_I_EFE(inode) = 0;
143 UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct fileEntry), GFP_KERNEL);
144 memset(UDF_I_DATA(inode), 0x00, inode->i_sb->s_blocksize - sizeof(struct fileEntry));
145 }
146 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB))
147 UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
148 else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
149 UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
150 else
151 UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
152 inode->i_mtime = inode->i_atime = inode->i_ctime =
153 UDF_I_CRTIME(inode) = current_fs_time(inode->i_sb);
154 insert_inode_hash(inode);
155 mark_inode_dirty(inode);
156 up(&sbi->s_alloc_sem);
157
158 if (DQUOT_ALLOC_INODE(inode))
159 {
160 DQUOT_DROP(inode);
161 inode->i_flags |= S_NOQUOTA;
162 inode->i_nlink = 0;
163 iput(inode);
164 *err = -EDQUOT;
165 return NULL;
166 }
167
168 *err = 0;
169 return inode;
170}
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
new file mode 100644
index 000000000000..0506e1173784
--- /dev/null
+++ b/fs/udf/inode.c
@@ -0,0 +1,2010 @@
1/*
2 * inode.c
3 *
4 * PURPOSE
5 * Inode handling routines for the OSTA-UDF(tm) filesystem.
6 *
7 * CONTACTS
8 * E-mail regarding any portion of the Linux UDF file system should be
9 * directed to the development team mailing list (run by majordomo):
10 * linux_udf@hpesjro.fc.hp.com
11 *
12 * COPYRIGHT
13 * This file is distributed under the terms of the GNU General Public
14 * License (GPL). Copies of the GPL can be obtained from:
15 * ftp://prep.ai.mit.edu/pub/gnu/GPL
16 * Each contributing author retains all rights to their own work.
17 *
18 * (C) 1998 Dave Boynton
19 * (C) 1998-2004 Ben Fennema
20 * (C) 1999-2000 Stelias Computing Inc
21 *
22 * HISTORY
23 *
24 * 10/04/98 dgb Added rudimentary directory functions
25 * 10/07/98 Fully working udf_block_map! It works!
26 * 11/25/98 bmap altered to better support extents
27 * 12/06/98 blf partition support in udf_iget, udf_block_map and udf_read_inode
28 * 12/12/98 rewrote udf_block_map to handle next extents and descs across
29 * block boundaries (which is not actually allowed)
30 * 12/20/98 added support for strategy 4096
31 * 03/07/99 rewrote udf_block_map (again)
32 * New funcs, inode_bmap, udf_next_aext
33 * 04/19/99 Support for writing device EA's for major/minor #
34 */
35
36#include "udfdecl.h"
37#include <linux/mm.h>
38#include <linux/smp_lock.h>
39#include <linux/module.h>
40#include <linux/pagemap.h>
41#include <linux/buffer_head.h>
42#include <linux/writeback.h>
43#include <linux/slab.h>
44
45#include "udf_i.h"
46#include "udf_sb.h"
47
48MODULE_AUTHOR("Ben Fennema");
49MODULE_DESCRIPTION("Universal Disk Format Filesystem");
50MODULE_LICENSE("GPL");
51
52#define EXTENT_MERGE_SIZE 5
53
54static mode_t udf_convert_permissions(struct fileEntry *);
55static int udf_update_inode(struct inode *, int);
56static void udf_fill_inode(struct inode *, struct buffer_head *);
57static struct buffer_head *inode_getblk(struct inode *, long, int *,
58 long *, int *);
59static int8_t udf_insert_aext(struct inode *, kernel_lb_addr, int,
60 kernel_lb_addr, uint32_t, struct buffer_head *);
61static void udf_split_extents(struct inode *, int *, int, int,
62 kernel_long_ad [EXTENT_MERGE_SIZE], int *);
63static void udf_prealloc_extents(struct inode *, int, int,
64 kernel_long_ad [EXTENT_MERGE_SIZE], int *);
65static void udf_merge_extents(struct inode *,
66 kernel_long_ad [EXTENT_MERGE_SIZE], int *);
67static void udf_update_extents(struct inode *,
68 kernel_long_ad [EXTENT_MERGE_SIZE], int, int,
69 kernel_lb_addr, uint32_t, struct buffer_head **);
70static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
71
72/*
73 * udf_delete_inode
74 *
75 * PURPOSE
76 * Clean-up before the specified inode is destroyed.
77 *
78 * DESCRIPTION
79 * This routine is called when the kernel destroys an inode structure
80 * ie. when iput() finds i_count == 0.
81 *
82 * HISTORY
83 * July 1, 1997 - Andrew E. Mileski
84 * Written, tested, and released.
85 *
86 * Called at the last iput() if i_nlink is zero.
87 */
88void udf_delete_inode(struct inode * inode)
89{
90 if (is_bad_inode(inode))
91 goto no_delete;
92
93 inode->i_size = 0;
94 udf_truncate(inode);
95 lock_kernel();
96
97 udf_update_inode(inode, IS_SYNC(inode));
98 udf_free_inode(inode);
99
100 unlock_kernel();
101 return;
102no_delete:
103 clear_inode(inode);
104}
105
106void udf_clear_inode(struct inode *inode)
107{
108 if (!(inode->i_sb->s_flags & MS_RDONLY)) {
109 lock_kernel();
110 udf_discard_prealloc(inode);
111 unlock_kernel();
112 }
113
114 kfree(UDF_I_DATA(inode));
115 UDF_I_DATA(inode) = NULL;
116}
117
118static int udf_writepage(struct page *page, struct writeback_control *wbc)
119{
120 return block_write_full_page(page, udf_get_block, wbc);
121}
122
123static int udf_readpage(struct file *file, struct page *page)
124{
125 return block_read_full_page(page, udf_get_block);
126}
127
128static int udf_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
129{
130 return block_prepare_write(page, from, to, udf_get_block);
131}
132
133static sector_t udf_bmap(struct address_space *mapping, sector_t block)
134{
135 return generic_block_bmap(mapping,block,udf_get_block);
136}
137
138struct address_space_operations udf_aops = {
139 .readpage = udf_readpage,
140 .writepage = udf_writepage,
141 .sync_page = block_sync_page,
142 .prepare_write = udf_prepare_write,
143 .commit_write = generic_commit_write,
144 .bmap = udf_bmap,
145};
146
147void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err)
148{
149 struct page *page;
150 char *kaddr;
151 struct writeback_control udf_wbc = {
152 .sync_mode = WB_SYNC_NONE,
153 .nr_to_write = 1,
154 };
155
156 /* from now on we have normal address_space methods */
157 inode->i_data.a_ops = &udf_aops;
158
159 if (!UDF_I_LENALLOC(inode))
160 {
161 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
162 UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
163 else
164 UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
165 mark_inode_dirty(inode);
166 return;
167 }
168
169 page = grab_cache_page(inode->i_mapping, 0);
170 if (!PageLocked(page))
171 PAGE_BUG(page);
172 if (!PageUptodate(page))
173 {
174 kaddr = kmap(page);
175 memset(kaddr + UDF_I_LENALLOC(inode), 0x00,
176 PAGE_CACHE_SIZE - UDF_I_LENALLOC(inode));
177 memcpy(kaddr, UDF_I_DATA(inode) + UDF_I_LENEATTR(inode),
178 UDF_I_LENALLOC(inode));
179 flush_dcache_page(page);
180 SetPageUptodate(page);
181 kunmap(page);
182 }
183 memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0x00,
184 UDF_I_LENALLOC(inode));
185 UDF_I_LENALLOC(inode) = 0;
186 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
187 UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
188 else
189 UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
190
191 inode->i_data.a_ops->writepage(page, &udf_wbc);
192 page_cache_release(page);
193
194 mark_inode_dirty(inode);
195}
196
197struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err)
198{
199 int newblock;
200 struct buffer_head *sbh = NULL, *dbh = NULL;
201 kernel_lb_addr bloc, eloc;
202 uint32_t elen, extoffset;
203 uint8_t alloctype;
204
205 struct udf_fileident_bh sfibh, dfibh;
206 loff_t f_pos = udf_ext0_offset(inode) >> 2;
207 int size = (udf_ext0_offset(inode) + inode->i_size) >> 2;
208 struct fileIdentDesc cfi, *sfi, *dfi;
209
210 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
211 alloctype = ICBTAG_FLAG_AD_SHORT;
212 else
213 alloctype = ICBTAG_FLAG_AD_LONG;
214
215 if (!inode->i_size)
216 {
217 UDF_I_ALLOCTYPE(inode) = alloctype;
218 mark_inode_dirty(inode);
219 return NULL;
220 }
221
222 /* alloc block, and copy data to it */
223 *block = udf_new_block(inode->i_sb, inode,
224 UDF_I_LOCATION(inode).partitionReferenceNum,
225 UDF_I_LOCATION(inode).logicalBlockNum, err);
226
227 if (!(*block))
228 return NULL;
229 newblock = udf_get_pblock(inode->i_sb, *block,
230 UDF_I_LOCATION(inode).partitionReferenceNum, 0);
231 if (!newblock)
232 return NULL;
233 dbh = udf_tgetblk(inode->i_sb, newblock);
234 if (!dbh)
235 return NULL;
236 lock_buffer(dbh);
237 memset(dbh->b_data, 0x00, inode->i_sb->s_blocksize);
238 set_buffer_uptodate(dbh);
239 unlock_buffer(dbh);
240 mark_buffer_dirty_inode(dbh, inode);
241
242 sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2;
243 sbh = sfibh.sbh = sfibh.ebh = NULL;
244 dfibh.soffset = dfibh.eoffset = 0;
245 dfibh.sbh = dfibh.ebh = dbh;
246 while ( (f_pos < size) )
247 {
248 UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
249 sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL, NULL, NULL);
250 if (!sfi)
251 {
252 udf_release_data(dbh);
253 return NULL;
254 }
255 UDF_I_ALLOCTYPE(inode) = alloctype;
256 sfi->descTag.tagLocation = cpu_to_le32(*block);
257 dfibh.soffset = dfibh.eoffset;
258 dfibh.eoffset += (sfibh.eoffset - sfibh.soffset);
259 dfi = (struct fileIdentDesc *)(dbh->b_data + dfibh.soffset);
260 if (udf_write_fi(inode, sfi, dfi, &dfibh, sfi->impUse,
261 sfi->fileIdent + le16_to_cpu(sfi->lengthOfImpUse)))
262 {
263 UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
264 udf_release_data(dbh);
265 return NULL;
266 }
267 }
268 mark_buffer_dirty_inode(dbh, inode);
269
270 memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode));
271 UDF_I_LENALLOC(inode) = 0;
272 bloc = UDF_I_LOCATION(inode);
273 eloc.logicalBlockNum = *block;
274 eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
275 elen = inode->i_size;
276 UDF_I_LENEXTENTS(inode) = elen;
277 extoffset = udf_file_entry_alloc_offset(inode);
278 udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &sbh, 0);
279 /* UniqueID stuff */
280
281 udf_release_data(sbh);
282 mark_inode_dirty(inode);
283 return dbh;
284}
285
286static int udf_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create)
287{
288 int err, new;
289 struct buffer_head *bh;
290 unsigned long phys;
291
292 if (!create)
293 {
294 phys = udf_block_map(inode, block);
295 if (phys)
296 map_bh(bh_result, inode->i_sb, phys);
297 return 0;
298 }
299
300 err = -EIO;
301 new = 0;
302 bh = NULL;
303
304 lock_kernel();
305
306 if (block < 0)
307 goto abort_negative;
308
309 if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1)
310 {
311 UDF_I_NEXT_ALLOC_BLOCK(inode) ++;
312 UDF_I_NEXT_ALLOC_GOAL(inode) ++;
313 }
314
315 err = 0;
316
317 bh = inode_getblk(inode, block, &err, &phys, &new);
318 if (bh)
319 BUG();
320 if (err)
321 goto abort;
322 if (!phys)
323 BUG();
324
325 if (new)
326 set_buffer_new(bh_result);
327 map_bh(bh_result, inode->i_sb, phys);
328abort:
329 unlock_kernel();
330 return err;
331
332abort_negative:
333 udf_warning(inode->i_sb, "udf_get_block", "block < 0");
334 goto abort;
335}
336
337static struct buffer_head *
338udf_getblk(struct inode *inode, long block, int create, int *err)
339{
340 struct buffer_head dummy;
341
342 dummy.b_state = 0;
343 dummy.b_blocknr = -1000;
344 *err = udf_get_block(inode, block, &dummy, create);
345 if (!*err && buffer_mapped(&dummy))
346 {
347 struct buffer_head *bh;
348 bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
349 if (buffer_new(&dummy))
350 {
351 lock_buffer(bh);
352 memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
353 set_buffer_uptodate(bh);
354 unlock_buffer(bh);
355 mark_buffer_dirty_inode(bh, inode);
356 }
357 return bh;
358 }
359 return NULL;
360}
361
362static struct buffer_head * inode_getblk(struct inode * inode, long block,
363 int *err, long *phys, int *new)
364{
365 struct buffer_head *pbh = NULL, *cbh = NULL, *nbh = NULL, *result = NULL;
366 kernel_long_ad laarr[EXTENT_MERGE_SIZE];
367 uint32_t pextoffset = 0, cextoffset = 0, nextoffset = 0;
368 int count = 0, startnum = 0, endnum = 0;
369 uint32_t elen = 0;
370 kernel_lb_addr eloc, pbloc, cbloc, nbloc;
371 int c = 1;
372 uint64_t lbcount = 0, b_off = 0;
373 uint32_t newblocknum, newblock, offset = 0;
374 int8_t etype;
375 int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum;
376 char lastblock = 0;
377
378 pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode);
379 b_off = (uint64_t)block << inode->i_sb->s_blocksize_bits;
380 pbloc = cbloc = nbloc = UDF_I_LOCATION(inode);
381
382 /* find the extent which contains the block we are looking for.
383 alternate between laarr[0] and laarr[1] for locations of the
384 current extent, and the previous extent */
385 do
386 {
387 if (pbh != cbh)
388 {
389 udf_release_data(pbh);
390 atomic_inc(&cbh->b_count);
391 pbh = cbh;
392 }
393 if (cbh != nbh)
394 {
395 udf_release_data(cbh);
396 atomic_inc(&nbh->b_count);
397 cbh = nbh;
398 }
399
400 lbcount += elen;
401
402 pbloc = cbloc;
403 cbloc = nbloc;
404
405 pextoffset = cextoffset;
406 cextoffset = nextoffset;
407
408 if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) == -1)
409 break;
410
411 c = !c;
412
413 laarr[c].extLength = (etype << 30) | elen;
414 laarr[c].extLocation = eloc;
415
416 if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
417 pgoal = eloc.logicalBlockNum +
418 ((elen + inode->i_sb->s_blocksize - 1) >>
419 inode->i_sb->s_blocksize_bits);
420
421 count ++;
422 } while (lbcount + elen <= b_off);
423
424 b_off -= lbcount;
425 offset = b_off >> inode->i_sb->s_blocksize_bits;
426
427 /* if the extent is allocated and recorded, return the block
428 if the extent is not a multiple of the blocksize, round up */
429
430 if (etype == (EXT_RECORDED_ALLOCATED >> 30))
431 {
432 if (elen & (inode->i_sb->s_blocksize - 1))
433 {
434 elen = EXT_RECORDED_ALLOCATED |
435 ((elen + inode->i_sb->s_blocksize - 1) &
436 ~(inode->i_sb->s_blocksize - 1));
437 etype = udf_write_aext(inode, nbloc, &cextoffset, eloc, elen, nbh, 1);
438 }
439 udf_release_data(pbh);
440 udf_release_data(cbh);
441 udf_release_data(nbh);
442 newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset);
443 *phys = newblock;
444 return NULL;
445 }
446
447 if (etype == -1)
448 {
449 endnum = startnum = ((count > 1) ? 1 : count);
450 if (laarr[c].extLength & (inode->i_sb->s_blocksize - 1))
451 {
452 laarr[c].extLength =
453 (laarr[c].extLength & UDF_EXTENT_FLAG_MASK) |
454 (((laarr[c].extLength & UDF_EXTENT_LENGTH_MASK) +
455 inode->i_sb->s_blocksize - 1) &
456 ~(inode->i_sb->s_blocksize - 1));
457 UDF_I_LENEXTENTS(inode) =
458 (UDF_I_LENEXTENTS(inode) + inode->i_sb->s_blocksize - 1) &
459 ~(inode->i_sb->s_blocksize - 1);
460 }
461 c = !c;
462 laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
463 ((offset + 1) << inode->i_sb->s_blocksize_bits);
464 memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr));
465 count ++;
466 endnum ++;
467 lastblock = 1;
468 }
469 else
470 endnum = startnum = ((count > 2) ? 2 : count);
471
472 /* if the current extent is in position 0, swap it with the previous */
473 if (!c && count != 1)
474 {
475 laarr[2] = laarr[0];
476 laarr[0] = laarr[1];
477 laarr[1] = laarr[2];
478 c = 1;
479 }
480
481 /* if the current block is located in a extent, read the next extent */
482 if (etype != -1)
483 {
484 if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 0)) != -1)
485 {
486 laarr[c+1].extLength = (etype << 30) | elen;
487 laarr[c+1].extLocation = eloc;
488 count ++;
489 startnum ++;
490 endnum ++;
491 }
492 else
493 lastblock = 1;
494 }
495 udf_release_data(cbh);
496 udf_release_data(nbh);
497
498 /* if the current extent is not recorded but allocated, get the
499 block in the extent corresponding to the requested block */
500 if ((laarr[c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
501 newblocknum = laarr[c].extLocation.logicalBlockNum + offset;
502 else /* otherwise, allocate a new block */
503 {
504 if (UDF_I_NEXT_ALLOC_BLOCK(inode) == block)
505 goal = UDF_I_NEXT_ALLOC_GOAL(inode);
506
507 if (!goal)
508 {
509 if (!(goal = pgoal))
510 goal = UDF_I_LOCATION(inode).logicalBlockNum + 1;
511 }
512
513 if (!(newblocknum = udf_new_block(inode->i_sb, inode,
514 UDF_I_LOCATION(inode).partitionReferenceNum, goal, err)))
515 {
516 udf_release_data(pbh);
517 *err = -ENOSPC;
518 return NULL;
519 }
520 UDF_I_LENEXTENTS(inode) += inode->i_sb->s_blocksize;
521 }
522
523 /* if the extent the requsted block is located in contains multiple blocks,
524 split the extent into at most three extents. blocks prior to requested
525 block, requested block, and blocks after requested block */
526 udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum);
527
528#ifdef UDF_PREALLOCATE
529 /* preallocate blocks */
530 udf_prealloc_extents(inode, c, lastblock, laarr, &endnum);
531#endif
532
533 /* merge any continuous blocks in laarr */
534 udf_merge_extents(inode, laarr, &endnum);
535
536 /* write back the new extents, inserting new extents if the new number
537 of extents is greater than the old number, and deleting extents if
538 the new number of extents is less than the old number */
539 udf_update_extents(inode, laarr, startnum, endnum, pbloc, pextoffset, &pbh);
540
541 udf_release_data(pbh);
542
543 if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum,
544 UDF_I_LOCATION(inode).partitionReferenceNum, 0)))
545 {
546 return NULL;
547 }
548 *phys = newblock;
549 *err = 0;
550 *new = 1;
551 UDF_I_NEXT_ALLOC_BLOCK(inode) = block;
552 UDF_I_NEXT_ALLOC_GOAL(inode) = newblocknum;
553 inode->i_ctime = current_fs_time(inode->i_sb);
554
555 if (IS_SYNC(inode))
556 udf_sync_inode(inode);
557 else
558 mark_inode_dirty(inode);
559 return result;
560}
561
562static void udf_split_extents(struct inode *inode, int *c, int offset, int newblocknum,
563 kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum)
564{
565 if ((laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30) ||
566 (laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
567 {
568 int curr = *c;
569 int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) +
570 inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
571 int8_t etype = (laarr[curr].extLength >> 30);
572
573 if (blen == 1)
574 ;
575 else if (!offset || blen == offset + 1)
576 {
577 laarr[curr+2] = laarr[curr+1];
578 laarr[curr+1] = laarr[curr];
579 }
580 else
581 {
582 laarr[curr+3] = laarr[curr+1];
583 laarr[curr+2] = laarr[curr+1] = laarr[curr];
584 }
585
586 if (offset)
587 {
588 if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
589 {
590 udf_free_blocks(inode->i_sb, inode, laarr[curr].extLocation, 0, offset);
591 laarr[curr].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
592 (offset << inode->i_sb->s_blocksize_bits);
593 laarr[curr].extLocation.logicalBlockNum = 0;
594 laarr[curr].extLocation.partitionReferenceNum = 0;
595 }
596 else
597 laarr[curr].extLength = (etype << 30) |
598 (offset << inode->i_sb->s_blocksize_bits);
599 curr ++;
600 (*c) ++;
601 (*endnum) ++;
602 }
603
604 laarr[curr].extLocation.logicalBlockNum = newblocknum;
605 if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
606 laarr[curr].extLocation.partitionReferenceNum =
607 UDF_I_LOCATION(inode).partitionReferenceNum;
608 laarr[curr].extLength = EXT_RECORDED_ALLOCATED |
609 inode->i_sb->s_blocksize;
610 curr ++;
611
612 if (blen != offset + 1)
613 {
614 if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
615 laarr[curr].extLocation.logicalBlockNum += (offset + 1);
616 laarr[curr].extLength = (etype << 30) |
617 ((blen - (offset + 1)) << inode->i_sb->s_blocksize_bits);
618 curr ++;
619 (*endnum) ++;
620 }
621 }
622}
623
624static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
625 kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum)
626{
627 int start, length = 0, currlength = 0, i;
628
629 if (*endnum >= (c+1))
630 {
631 if (!lastblock)
632 return;
633 else
634 start = c;
635 }
636 else
637 {
638 if ((laarr[c+1].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
639 {
640 start = c+1;
641 length = currlength = (((laarr[c+1].extLength & UDF_EXTENT_LENGTH_MASK) +
642 inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
643 }
644 else
645 start = c;
646 }
647
648 for (i=start+1; i<=*endnum; i++)
649 {
650 if (i == *endnum)
651 {
652 if (lastblock)
653 length += UDF_DEFAULT_PREALLOC_BLOCKS;
654 }
655 else if ((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
656 length += (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
657 inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
658 else
659 break;
660 }
661
662 if (length)
663 {
664 int next = laarr[start].extLocation.logicalBlockNum +
665 (((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) +
666 inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
667 int numalloc = udf_prealloc_blocks(inode->i_sb, inode,
668 laarr[start].extLocation.partitionReferenceNum,
669 next, (UDF_DEFAULT_PREALLOC_BLOCKS > length ? length :
670 UDF_DEFAULT_PREALLOC_BLOCKS) - currlength);
671
672 if (numalloc)
673 {
674 if (start == (c+1))
675 laarr[start].extLength +=
676 (numalloc << inode->i_sb->s_blocksize_bits);
677 else
678 {
679 memmove(&laarr[c+2], &laarr[c+1],
680 sizeof(long_ad) * (*endnum - (c+1)));
681 (*endnum) ++;
682 laarr[c+1].extLocation.logicalBlockNum = next;
683 laarr[c+1].extLocation.partitionReferenceNum =
684 laarr[c].extLocation.partitionReferenceNum;
685 laarr[c+1].extLength = EXT_NOT_RECORDED_ALLOCATED |
686 (numalloc << inode->i_sb->s_blocksize_bits);
687 start = c+1;
688 }
689
690 for (i=start+1; numalloc && i<*endnum; i++)
691 {
692 int elen = ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
693 inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
694
695 if (elen > numalloc)
696 {
697 laarr[i].extLength -=
698 (numalloc << inode->i_sb->s_blocksize_bits);
699 numalloc = 0;
700 }
701 else
702 {
703 numalloc -= elen;
704 if (*endnum > (i+1))
705 memmove(&laarr[i], &laarr[i+1],
706 sizeof(long_ad) * (*endnum - (i+1)));
707 i --;
708 (*endnum) --;
709 }
710 }
711 UDF_I_LENEXTENTS(inode) += numalloc << inode->i_sb->s_blocksize_bits;
712 }
713 }
714}
715
716static void udf_merge_extents(struct inode *inode,
717 kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum)
718{
719 int i;
720
721 for (i=0; i<(*endnum-1); i++)
722 {
723 if ((laarr[i].extLength >> 30) == (laarr[i+1].extLength >> 30))
724 {
725 if (((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) ||
726 ((laarr[i+1].extLocation.logicalBlockNum - laarr[i].extLocation.logicalBlockNum) ==
727 (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
728 inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits)))
729 {
730 if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
731 (laarr[i+1].extLength & UDF_EXTENT_LENGTH_MASK) +
732 inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK)
733 {
734 laarr[i+1].extLength = (laarr[i+1].extLength -
735 (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
736 UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize-1);
737 laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_FLAG_MASK) +
738 (UDF_EXTENT_LENGTH_MASK + 1) - inode->i_sb->s_blocksize;
739 laarr[i+1].extLocation.logicalBlockNum =
740 laarr[i].extLocation.logicalBlockNum +
741 ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) >>
742 inode->i_sb->s_blocksize_bits);
743 }
744 else
745 {
746 laarr[i].extLength = laarr[i+1].extLength +
747 (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
748 inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize-1));
749 if (*endnum > (i+2))
750 memmove(&laarr[i+1], &laarr[i+2],
751 sizeof(long_ad) * (*endnum - (i+2)));
752 i --;
753 (*endnum) --;
754 }
755 }
756 }
757 else if (((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) &&
758 ((laarr[i+1].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)))
759 {
760 udf_free_blocks(inode->i_sb, inode, laarr[i].extLocation, 0,
761 ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
762 inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
763 laarr[i].extLocation.logicalBlockNum = 0;
764 laarr[i].extLocation.partitionReferenceNum = 0;
765
766 if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
767 (laarr[i+1].extLength & UDF_EXTENT_LENGTH_MASK) +
768 inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK)
769 {
770 laarr[i+1].extLength = (laarr[i+1].extLength -
771 (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
772 UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize-1);
773 laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_FLAG_MASK) +
774 (UDF_EXTENT_LENGTH_MASK + 1) - inode->i_sb->s_blocksize;
775 }
776 else
777 {
778 laarr[i].extLength = laarr[i+1].extLength +
779 (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
780 inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize-1));
781 if (*endnum > (i+2))
782 memmove(&laarr[i+1], &laarr[i+2],
783 sizeof(long_ad) * (*endnum - (i+2)));
784 i --;
785 (*endnum) --;
786 }
787 }
788 else if ((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
789 {
790 udf_free_blocks(inode->i_sb, inode, laarr[i].extLocation, 0,
791 ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
792 inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
793 laarr[i].extLocation.logicalBlockNum = 0;
794 laarr[i].extLocation.partitionReferenceNum = 0;
795 laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) |
796 EXT_NOT_RECORDED_NOT_ALLOCATED;
797 }
798 }
799}
800
801static void udf_update_extents(struct inode *inode,
802 kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum,
803 kernel_lb_addr pbloc, uint32_t pextoffset, struct buffer_head **pbh)
804{
805 int start = 0, i;
806 kernel_lb_addr tmploc;
807 uint32_t tmplen;
808
809 if (startnum > endnum)
810 {
811 for (i=0; i<(startnum-endnum); i++)
812 {
813 udf_delete_aext(inode, pbloc, pextoffset, laarr[i].extLocation,
814 laarr[i].extLength, *pbh);
815 }
816 }
817 else if (startnum < endnum)
818 {
819 for (i=0; i<(endnum-startnum); i++)
820 {
821 udf_insert_aext(inode, pbloc, pextoffset, laarr[i].extLocation,
822 laarr[i].extLength, *pbh);
823 udf_next_aext(inode, &pbloc, &pextoffset, &laarr[i].extLocation,
824 &laarr[i].extLength, pbh, 1);
825 start ++;
826 }
827 }
828
829 for (i=start; i<endnum; i++)
830 {
831 udf_next_aext(inode, &pbloc, &pextoffset, &tmploc, &tmplen, pbh, 0);
832 udf_write_aext(inode, pbloc, &pextoffset, laarr[i].extLocation,
833 laarr[i].extLength, *pbh, 1);
834 }
835}
836
837struct buffer_head * udf_bread(struct inode * inode, int block,
838 int create, int * err)
839{
840 struct buffer_head * bh = NULL;
841
842 bh = udf_getblk(inode, block, create, err);
843 if (!bh)
844 return NULL;
845
846 if (buffer_uptodate(bh))
847 return bh;
848 ll_rw_block(READ, 1, &bh);
849 wait_on_buffer(bh);
850 if (buffer_uptodate(bh))
851 return bh;
852 brelse(bh);
853 *err = -EIO;
854 return NULL;
855}
856
857void udf_truncate(struct inode * inode)
858{
859 int offset;
860 int err;
861
862 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
863 S_ISLNK(inode->i_mode)))
864 return;
865 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
866 return;
867
868 lock_kernel();
869 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
870 {
871 if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
872 inode->i_size))
873 {
874 udf_expand_file_adinicb(inode, inode->i_size, &err);
875 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
876 {
877 inode->i_size = UDF_I_LENALLOC(inode);
878 unlock_kernel();
879 return;
880 }
881 else
882 udf_truncate_extents(inode);
883 }
884 else
885 {
886 offset = inode->i_size & (inode->i_sb->s_blocksize - 1);
887 memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset, 0x00, inode->i_sb->s_blocksize - offset - udf_file_entry_alloc_offset(inode));
888 UDF_I_LENALLOC(inode) = inode->i_size;
889 }
890 }
891 else
892 {
893 block_truncate_page(inode->i_mapping, inode->i_size, udf_get_block);
894 udf_truncate_extents(inode);
895 }
896
897 inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
898 if (IS_SYNC(inode))
899 udf_sync_inode (inode);
900 else
901 mark_inode_dirty(inode);
902 unlock_kernel();
903}
904
905static void
906__udf_read_inode(struct inode *inode)
907{
908 struct buffer_head *bh = NULL;
909 struct fileEntry *fe;
910 uint16_t ident;
911
912 /*
913 * Set defaults, but the inode is still incomplete!
914 * Note: get_new_inode() sets the following on a new inode:
915 * i_sb = sb
916 * i_no = ino
917 * i_flags = sb->s_flags
918 * i_state = 0
919 * clean_inode(): zero fills and sets
920 * i_count = 1
921 * i_nlink = 1
922 * i_op = NULL;
923 */
924 inode->i_blksize = PAGE_SIZE;
925
926 bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident);
927
928 if (!bh)
929 {
930 printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed !bh\n",
931 inode->i_ino);
932 make_bad_inode(inode);
933 return;
934 }
935
936 if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE &&
937 ident != TAG_IDENT_USE)
938 {
939 printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n",
940 inode->i_ino, ident);
941 udf_release_data(bh);
942 make_bad_inode(inode);
943 return;
944 }
945
946 fe = (struct fileEntry *)bh->b_data;
947
948 if (le16_to_cpu(fe->icbTag.strategyType) == 4096)
949 {
950 struct buffer_head *ibh = NULL, *nbh = NULL;
951 struct indirectEntry *ie;
952
953 ibh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 1, &ident);
954 if (ident == TAG_IDENT_IE)
955 {
956 if (ibh)
957 {
958 kernel_lb_addr loc;
959 ie = (struct indirectEntry *)ibh->b_data;
960
961 loc = lelb_to_cpu(ie->indirectICB.extLocation);
962
963 if (ie->indirectICB.extLength &&
964 (nbh = udf_read_ptagged(inode->i_sb, loc, 0, &ident)))
965 {
966 if (ident == TAG_IDENT_FE ||
967 ident == TAG_IDENT_EFE)
968 {
969 memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(kernel_lb_addr));
970 udf_release_data(bh);
971 udf_release_data(ibh);
972 udf_release_data(nbh);
973 __udf_read_inode(inode);
974 return;
975 }
976 else
977 {
978 udf_release_data(nbh);
979 udf_release_data(ibh);
980 }
981 }
982 else
983 udf_release_data(ibh);
984 }
985 }
986 else
987 udf_release_data(ibh);
988 }
989 else if (le16_to_cpu(fe->icbTag.strategyType) != 4)
990 {
991 printk(KERN_ERR "udf: unsupported strategy type: %d\n",
992 le16_to_cpu(fe->icbTag.strategyType));
993 udf_release_data(bh);
994 make_bad_inode(inode);
995 return;
996 }
997 udf_fill_inode(inode, bh);
998 udf_release_data(bh);
999}
1000
1001static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
1002{
1003 struct fileEntry *fe;
1004 struct extendedFileEntry *efe;
1005 time_t convtime;
1006 long convtime_usec;
1007 int offset;
1008
1009 fe = (struct fileEntry *)bh->b_data;
1010 efe = (struct extendedFileEntry *)bh->b_data;
1011
1012 if (le16_to_cpu(fe->icbTag.strategyType) == 4)
1013 UDF_I_STRAT4096(inode) = 0;
1014 else /* if (le16_to_cpu(fe->icbTag.strategyType) == 4096) */
1015 UDF_I_STRAT4096(inode) = 1;
1016
1017 UDF_I_ALLOCTYPE(inode) = le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK;
1018 UDF_I_UNIQUE(inode) = 0;
1019 UDF_I_LENEATTR(inode) = 0;
1020 UDF_I_LENEXTENTS(inode) = 0;
1021 UDF_I_LENALLOC(inode) = 0;
1022 UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
1023 UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
1024 if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_EFE)
1025 {
1026 UDF_I_EFE(inode) = 1;
1027 UDF_I_USE(inode) = 0;
1028 UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry), GFP_KERNEL);
1029 memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct extendedFileEntry), inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry));
1030 }
1031 else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_FE)
1032 {
1033 UDF_I_EFE(inode) = 0;
1034 UDF_I_USE(inode) = 0;
1035 UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct fileEntry), GFP_KERNEL);
1036 memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct fileEntry), inode->i_sb->s_blocksize - sizeof(struct fileEntry));
1037 }
1038 else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE)
1039 {
1040 UDF_I_EFE(inode) = 0;
1041 UDF_I_USE(inode) = 1;
1042 UDF_I_LENALLOC(inode) =
1043 le32_to_cpu(
1044 ((struct unallocSpaceEntry *)bh->b_data)->lengthAllocDescs);
1045 UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry), GFP_KERNEL);
1046 memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct unallocSpaceEntry), inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry));
1047 return;
1048 }
1049
1050 inode->i_uid = le32_to_cpu(fe->uid);
1051 if ( inode->i_uid == -1 ) inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
1052
1053 inode->i_gid = le32_to_cpu(fe->gid);
1054 if ( inode->i_gid == -1 ) inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
1055
1056 inode->i_nlink = le16_to_cpu(fe->fileLinkCount);
1057 if (!inode->i_nlink)
1058 inode->i_nlink = 1;
1059
1060 inode->i_size = le64_to_cpu(fe->informationLength);
1061 UDF_I_LENEXTENTS(inode) = inode->i_size;
1062
1063 inode->i_mode = udf_convert_permissions(fe);
1064 inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask;
1065
1066 if (UDF_I_EFE(inode) == 0)
1067 {
1068 inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
1069 (inode->i_sb->s_blocksize_bits - 9);
1070
1071 if ( udf_stamp_to_time(&convtime, &convtime_usec,
1072 lets_to_cpu(fe->accessTime)) )
1073 {
1074 inode->i_atime.tv_sec = convtime;
1075 inode->i_atime.tv_nsec = convtime_usec * 1000;
1076 }
1077 else
1078 {
1079 inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
1080 }
1081
1082 if ( udf_stamp_to_time(&convtime, &convtime_usec,
1083 lets_to_cpu(fe->modificationTime)) )
1084 {
1085 inode->i_mtime.tv_sec = convtime;
1086 inode->i_mtime.tv_nsec = convtime_usec * 1000;
1087 }
1088 else
1089 {
1090 inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
1091 }
1092
1093 if ( udf_stamp_to_time(&convtime, &convtime_usec,
1094 lets_to_cpu(fe->attrTime)) )
1095 {
1096 inode->i_ctime.tv_sec = convtime;
1097 inode->i_ctime.tv_nsec = convtime_usec * 1000;
1098 }
1099 else
1100 {
1101 inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
1102 }
1103
1104 UDF_I_UNIQUE(inode) = le64_to_cpu(fe->uniqueID);
1105 UDF_I_LENEATTR(inode) = le32_to_cpu(fe->lengthExtendedAttr);
1106 UDF_I_LENALLOC(inode) = le32_to_cpu(fe->lengthAllocDescs);
1107 offset = sizeof(struct fileEntry) + UDF_I_LENEATTR(inode);
1108 }
1109 else
1110 {
1111 inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
1112 (inode->i_sb->s_blocksize_bits - 9);
1113
1114 if ( udf_stamp_to_time(&convtime, &convtime_usec,
1115 lets_to_cpu(efe->accessTime)) )
1116 {
1117 inode->i_atime.tv_sec = convtime;
1118 inode->i_atime.tv_nsec = convtime_usec * 1000;
1119 }
1120 else
1121 {
1122 inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
1123 }
1124
1125 if ( udf_stamp_to_time(&convtime, &convtime_usec,
1126 lets_to_cpu(efe->modificationTime)) )
1127 {
1128 inode->i_mtime.tv_sec = convtime;
1129 inode->i_mtime.tv_nsec = convtime_usec * 1000;
1130 }
1131 else
1132 {
1133 inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
1134 }
1135
1136 if ( udf_stamp_to_time(&convtime, &convtime_usec,
1137 lets_to_cpu(efe->createTime)) )
1138 {
1139 UDF_I_CRTIME(inode).tv_sec = convtime;
1140 UDF_I_CRTIME(inode).tv_nsec = convtime_usec * 1000;
1141 }
1142 else
1143 {
1144 UDF_I_CRTIME(inode) = UDF_SB_RECORDTIME(inode->i_sb);
1145 }
1146
1147 if ( udf_stamp_to_time(&convtime, &convtime_usec,
1148 lets_to_cpu(efe->attrTime)) )
1149 {
1150 inode->i_ctime.tv_sec = convtime;
1151 inode->i_ctime.tv_nsec = convtime_usec * 1000;
1152 }
1153 else
1154 {
1155 inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
1156 }
1157
1158 UDF_I_UNIQUE(inode) = le64_to_cpu(efe->uniqueID);
1159 UDF_I_LENEATTR(inode) = le32_to_cpu(efe->lengthExtendedAttr);
1160 UDF_I_LENALLOC(inode) = le32_to_cpu(efe->lengthAllocDescs);
1161 offset = sizeof(struct extendedFileEntry) + UDF_I_LENEATTR(inode);
1162 }
1163
1164 switch (fe->icbTag.fileType)
1165 {
1166 case ICBTAG_FILE_TYPE_DIRECTORY:
1167 {
1168 inode->i_op = &udf_dir_inode_operations;
1169 inode->i_fop = &udf_dir_operations;
1170 inode->i_mode |= S_IFDIR;
1171 inode->i_nlink ++;
1172 break;
1173 }
1174 case ICBTAG_FILE_TYPE_REALTIME:
1175 case ICBTAG_FILE_TYPE_REGULAR:
1176 case ICBTAG_FILE_TYPE_UNDEF:
1177 {
1178 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
1179 inode->i_data.a_ops = &udf_adinicb_aops;
1180 else
1181 inode->i_data.a_ops = &udf_aops;
1182 inode->i_op = &udf_file_inode_operations;
1183 inode->i_fop = &udf_file_operations;
1184 inode->i_mode |= S_IFREG;
1185 break;
1186 }
1187 case ICBTAG_FILE_TYPE_BLOCK:
1188 {
1189 inode->i_mode |= S_IFBLK;
1190 break;
1191 }
1192 case ICBTAG_FILE_TYPE_CHAR:
1193 {
1194 inode->i_mode |= S_IFCHR;
1195 break;
1196 }
1197 case ICBTAG_FILE_TYPE_FIFO:
1198 {
1199 init_special_inode(inode, inode->i_mode | S_IFIFO, 0);
1200 break;
1201 }
1202 case ICBTAG_FILE_TYPE_SOCKET:
1203 {
1204 init_special_inode(inode, inode->i_mode | S_IFSOCK, 0);
1205 break;
1206 }
1207 case ICBTAG_FILE_TYPE_SYMLINK:
1208 {
1209 inode->i_data.a_ops = &udf_symlink_aops;
1210 inode->i_op = &page_symlink_inode_operations;
1211 inode->i_mode = S_IFLNK|S_IRWXUGO;
1212 break;
1213 }
1214 default:
1215 {
1216 printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown file type=%d\n",
1217 inode->i_ino, fe->icbTag.fileType);
1218 make_bad_inode(inode);
1219 return;
1220 }
1221 }
1222 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
1223 {
1224 struct deviceSpec *dsea =
1225 (struct deviceSpec *)
1226 udf_get_extendedattr(inode, 12, 1);
1227
1228 if (dsea)
1229 {
1230 init_special_inode(inode, inode->i_mode, MKDEV(
1231 le32_to_cpu(dsea->majorDeviceIdent),
1232 le32_to_cpu(dsea->minorDeviceIdent)));
1233 /* Developer ID ??? */
1234 }
1235 else
1236 {
1237 make_bad_inode(inode);
1238 }
1239 }
1240}
1241
1242static mode_t
1243udf_convert_permissions(struct fileEntry *fe)
1244{
1245 mode_t mode;
1246 uint32_t permissions;
1247 uint32_t flags;
1248
1249 permissions = le32_to_cpu(fe->permissions);
1250 flags = le16_to_cpu(fe->icbTag.flags);
1251
1252 mode = (( permissions ) & S_IRWXO) |
1253 (( permissions >> 2 ) & S_IRWXG) |
1254 (( permissions >> 4 ) & S_IRWXU) |
1255 (( flags & ICBTAG_FLAG_SETUID) ? S_ISUID : 0) |
1256 (( flags & ICBTAG_FLAG_SETGID) ? S_ISGID : 0) |
1257 (( flags & ICBTAG_FLAG_STICKY) ? S_ISVTX : 0);
1258
1259 return mode;
1260}
1261
1262/*
1263 * udf_write_inode
1264 *
1265 * PURPOSE
1266 * Write out the specified inode.
1267 *
1268 * DESCRIPTION
1269 * This routine is called whenever an inode is synced.
1270 * Currently this routine is just a placeholder.
1271 *
1272 * HISTORY
1273 * July 1, 1997 - Andrew E. Mileski
1274 * Written, tested, and released.
1275 */
1276
1277int udf_write_inode(struct inode * inode, int sync)
1278{
1279 int ret;
1280 lock_kernel();
1281 ret = udf_update_inode(inode, sync);
1282 unlock_kernel();
1283 return ret;
1284}
1285
1286int udf_sync_inode(struct inode * inode)
1287{
1288 return udf_update_inode(inode, 1);
1289}
1290
1291static int
1292udf_update_inode(struct inode *inode, int do_sync)
1293{
1294 struct buffer_head *bh = NULL;
1295 struct fileEntry *fe;
1296 struct extendedFileEntry *efe;
1297 uint32_t udfperms;
1298 uint16_t icbflags;
1299 uint16_t crclen;
1300 int i;
1301 kernel_timestamp cpu_time;
1302 int err = 0;
1303
1304 bh = udf_tread(inode->i_sb,
1305 udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0));
1306
1307 if (!bh)
1308 {
1309 udf_debug("bread failure\n");
1310 return -EIO;
1311 }
1312
1313 memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
1314
1315 fe = (struct fileEntry *)bh->b_data;
1316 efe = (struct extendedFileEntry *)bh->b_data;
1317
1318 if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE)
1319 {
1320 struct unallocSpaceEntry *use =
1321 (struct unallocSpaceEntry *)bh->b_data;
1322
1323 use->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
1324 memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry));
1325 crclen = sizeof(struct unallocSpaceEntry) + UDF_I_LENALLOC(inode) -
1326 sizeof(tag);
1327 use->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
1328 use->descTag.descCRCLength = cpu_to_le16(crclen);
1329 use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0));
1330
1331 use->descTag.tagChecksum = 0;
1332 for (i=0; i<16; i++)
1333 if (i != 4)
1334 use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i];
1335
1336 mark_buffer_dirty(bh);
1337 udf_release_data(bh);
1338 return err;
1339 }
1340
1341 if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid)
1342 fe->uid = cpu_to_le32(inode->i_uid);
1343
1344 if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid)
1345 fe->gid = cpu_to_le32(inode->i_gid);
1346
1347 udfperms = ((inode->i_mode & S_IRWXO) ) |
1348 ((inode->i_mode & S_IRWXG) << 2) |
1349 ((inode->i_mode & S_IRWXU) << 4);
1350
1351 udfperms |= (le32_to_cpu(fe->permissions) &
1352 (FE_PERM_O_DELETE | FE_PERM_O_CHATTR |
1353 FE_PERM_G_DELETE | FE_PERM_G_CHATTR |
1354 FE_PERM_U_DELETE | FE_PERM_U_CHATTR));
1355 fe->permissions = cpu_to_le32(udfperms);
1356
1357 if (S_ISDIR(inode->i_mode))
1358 fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1);
1359 else
1360 fe->fileLinkCount = cpu_to_le16(inode->i_nlink);
1361
1362 fe->informationLength = cpu_to_le64(inode->i_size);
1363
1364 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
1365 {
1366 regid *eid;
1367 struct deviceSpec *dsea =
1368 (struct deviceSpec *)
1369 udf_get_extendedattr(inode, 12, 1);
1370
1371 if (!dsea)
1372 {
1373 dsea = (struct deviceSpec *)
1374 udf_add_extendedattr(inode,
1375 sizeof(struct deviceSpec) +
1376 sizeof(regid), 12, 0x3);
1377 dsea->attrType = cpu_to_le32(12);
1378 dsea->attrSubtype = 1;
1379 dsea->attrLength = cpu_to_le32(sizeof(struct deviceSpec) +
1380 sizeof(regid));
1381 dsea->impUseLength = cpu_to_le32(sizeof(regid));
1382 }
1383 eid = (regid *)dsea->impUse;
1384 memset(eid, 0, sizeof(regid));
1385 strcpy(eid->ident, UDF_ID_DEVELOPER);
1386 eid->identSuffix[0] = UDF_OS_CLASS_UNIX;
1387 eid->identSuffix[1] = UDF_OS_ID_LINUX;
1388 dsea->majorDeviceIdent = cpu_to_le32(imajor(inode));
1389 dsea->minorDeviceIdent = cpu_to_le32(iminor(inode));
1390 }
1391
1392 if (UDF_I_EFE(inode) == 0)
1393 {
1394 memcpy(bh->b_data + sizeof(struct fileEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct fileEntry));
1395 fe->logicalBlocksRecorded = cpu_to_le64(
1396 (inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >>
1397 (inode->i_sb->s_blocksize_bits - 9));
1398
1399 if (udf_time_to_stamp(&cpu_time, inode->i_atime))
1400 fe->accessTime = cpu_to_lets(cpu_time);
1401 if (udf_time_to_stamp(&cpu_time, inode->i_mtime))
1402 fe->modificationTime = cpu_to_lets(cpu_time);
1403 if (udf_time_to_stamp(&cpu_time, inode->i_ctime))
1404 fe->attrTime = cpu_to_lets(cpu_time);
1405 memset(&(fe->impIdent), 0, sizeof(regid));
1406 strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);
1407 fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
1408 fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
1409 fe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));
1410 fe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));
1411 fe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
1412 fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE);
1413 crclen = sizeof(struct fileEntry);
1414 }
1415 else
1416 {
1417 memcpy(bh->b_data + sizeof(struct extendedFileEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry));
1418 efe->objectSize = cpu_to_le64(inode->i_size);
1419 efe->logicalBlocksRecorded = cpu_to_le64(
1420 (inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >>
1421 (inode->i_sb->s_blocksize_bits - 9));
1422
1423 if (UDF_I_CRTIME(inode).tv_sec > inode->i_atime.tv_sec ||
1424 (UDF_I_CRTIME(inode).tv_sec == inode->i_atime.tv_sec &&
1425 UDF_I_CRTIME(inode).tv_nsec > inode->i_atime.tv_nsec))
1426 {
1427 UDF_I_CRTIME(inode) = inode->i_atime;
1428 }
1429 if (UDF_I_CRTIME(inode).tv_sec > inode->i_mtime.tv_sec ||
1430 (UDF_I_CRTIME(inode).tv_sec == inode->i_mtime.tv_sec &&
1431 UDF_I_CRTIME(inode).tv_nsec > inode->i_mtime.tv_nsec))
1432 {
1433 UDF_I_CRTIME(inode) = inode->i_mtime;
1434 }
1435 if (UDF_I_CRTIME(inode).tv_sec > inode->i_ctime.tv_sec ||
1436 (UDF_I_CRTIME(inode).tv_sec == inode->i_ctime.tv_sec &&
1437 UDF_I_CRTIME(inode).tv_nsec > inode->i_ctime.tv_nsec))
1438 {
1439 UDF_I_CRTIME(inode) = inode->i_ctime;
1440 }
1441
1442 if (udf_time_to_stamp(&cpu_time, inode->i_atime))
1443 efe->accessTime = cpu_to_lets(cpu_time);
1444 if (udf_time_to_stamp(&cpu_time, inode->i_mtime))
1445 efe->modificationTime = cpu_to_lets(cpu_time);
1446 if (udf_time_to_stamp(&cpu_time, UDF_I_CRTIME(inode)))
1447 efe->createTime = cpu_to_lets(cpu_time);
1448 if (udf_time_to_stamp(&cpu_time, inode->i_ctime))
1449 efe->attrTime = cpu_to_lets(cpu_time);
1450
1451 memset(&(efe->impIdent), 0, sizeof(regid));
1452 strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER);
1453 efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
1454 efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
1455 efe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));
1456 efe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));
1457 efe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
1458 efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE);
1459 crclen = sizeof(struct extendedFileEntry);
1460 }
1461 if (UDF_I_STRAT4096(inode))
1462 {
1463 fe->icbTag.strategyType = cpu_to_le16(4096);
1464 fe->icbTag.strategyParameter = cpu_to_le16(1);
1465 fe->icbTag.numEntries = cpu_to_le16(2);
1466 }
1467 else
1468 {
1469 fe->icbTag.strategyType = cpu_to_le16(4);
1470 fe->icbTag.numEntries = cpu_to_le16(1);
1471 }
1472
1473 if (S_ISDIR(inode->i_mode))
1474 fe->icbTag.fileType = ICBTAG_FILE_TYPE_DIRECTORY;
1475 else if (S_ISREG(inode->i_mode))
1476 fe->icbTag.fileType = ICBTAG_FILE_TYPE_REGULAR;
1477 else if (S_ISLNK(inode->i_mode))
1478 fe->icbTag.fileType = ICBTAG_FILE_TYPE_SYMLINK;
1479 else if (S_ISBLK(inode->i_mode))
1480 fe->icbTag.fileType = ICBTAG_FILE_TYPE_BLOCK;
1481 else if (S_ISCHR(inode->i_mode))
1482 fe->icbTag.fileType = ICBTAG_FILE_TYPE_CHAR;
1483 else if (S_ISFIFO(inode->i_mode))
1484 fe->icbTag.fileType = ICBTAG_FILE_TYPE_FIFO;
1485 else if (S_ISSOCK(inode->i_mode))
1486 fe->icbTag.fileType = ICBTAG_FILE_TYPE_SOCKET;
1487
1488 icbflags = UDF_I_ALLOCTYPE(inode) |
1489 ((inode->i_mode & S_ISUID) ? ICBTAG_FLAG_SETUID : 0) |
1490 ((inode->i_mode & S_ISGID) ? ICBTAG_FLAG_SETGID : 0) |
1491 ((inode->i_mode & S_ISVTX) ? ICBTAG_FLAG_STICKY : 0) |
1492 (le16_to_cpu(fe->icbTag.flags) &
1493 ~(ICBTAG_FLAG_AD_MASK | ICBTAG_FLAG_SETUID |
1494 ICBTAG_FLAG_SETGID | ICBTAG_FLAG_STICKY));
1495
1496 fe->icbTag.flags = cpu_to_le16(icbflags);
1497 if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
1498 fe->descTag.descVersion = cpu_to_le16(3);
1499 else
1500 fe->descTag.descVersion = cpu_to_le16(2);
1501 fe->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb));
1502 fe->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
1503 crclen += UDF_I_LENEATTR(inode) + UDF_I_LENALLOC(inode) - sizeof(tag);
1504 fe->descTag.descCRCLength = cpu_to_le16(crclen);
1505 fe->descTag.descCRC = cpu_to_le16(udf_crc((char *)fe + sizeof(tag), crclen, 0));
1506
1507 fe->descTag.tagChecksum = 0;
1508 for (i=0; i<16; i++)
1509 if (i != 4)
1510 fe->descTag.tagChecksum += ((uint8_t *)&(fe->descTag))[i];
1511
1512 /* write the data blocks */
1513 mark_buffer_dirty(bh);
1514 if (do_sync)
1515 {
1516 sync_dirty_buffer(bh);
1517 if (buffer_req(bh) && !buffer_uptodate(bh))
1518 {
1519 printk("IO error syncing udf inode [%s:%08lx]\n",
1520 inode->i_sb->s_id, inode->i_ino);
1521 err = -EIO;
1522 }
1523 }
1524 udf_release_data(bh);
1525 return err;
1526}
1527
1528struct inode *
1529udf_iget(struct super_block *sb, kernel_lb_addr ino)
1530{
1531 unsigned long block = udf_get_lb_pblock(sb, ino, 0);
1532 struct inode *inode = iget_locked(sb, block);
1533
1534 if (!inode)
1535 return NULL;
1536
1537 if (inode->i_state & I_NEW) {
1538 memcpy(&UDF_I_LOCATION(inode), &ino, sizeof(kernel_lb_addr));
1539 __udf_read_inode(inode);
1540 unlock_new_inode(inode);
1541 }
1542
1543 if (is_bad_inode(inode))
1544 goto out_iput;
1545
1546 if (ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum)) {
1547 udf_debug("block=%d, partition=%d out of range\n",
1548 ino.logicalBlockNum, ino.partitionReferenceNum);
1549 make_bad_inode(inode);
1550 goto out_iput;
1551 }
1552
1553 return inode;
1554
1555 out_iput:
1556 iput(inode);
1557 return NULL;
1558}
1559
1560int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
1561 kernel_lb_addr eloc, uint32_t elen, struct buffer_head **bh, int inc)
1562{
1563 int adsize;
1564 short_ad *sad = NULL;
1565 long_ad *lad = NULL;
1566 struct allocExtDesc *aed;
1567 int8_t etype;
1568 uint8_t *ptr;
1569
1570 if (!*bh)
1571 ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
1572 else
1573 ptr = (*bh)->b_data + *extoffset;
1574
1575 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
1576 adsize = sizeof(short_ad);
1577 else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
1578 adsize = sizeof(long_ad);
1579 else
1580 return -1;
1581
1582 if (*extoffset + (2 * adsize) > inode->i_sb->s_blocksize)
1583 {
1584 char *sptr, *dptr;
1585 struct buffer_head *nbh;
1586 int err, loffset;
1587 kernel_lb_addr obloc = *bloc;
1588
1589 if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, NULL,
1590 obloc.partitionReferenceNum, obloc.logicalBlockNum, &err)))
1591 {
1592 return -1;
1593 }
1594 if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
1595 *bloc, 0))))
1596 {
1597 return -1;
1598 }
1599 lock_buffer(nbh);
1600 memset(nbh->b_data, 0x00, inode->i_sb->s_blocksize);
1601 set_buffer_uptodate(nbh);
1602 unlock_buffer(nbh);
1603 mark_buffer_dirty_inode(nbh, inode);
1604
1605 aed = (struct allocExtDesc *)(nbh->b_data);
1606 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
1607 aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
1608 if (*extoffset + adsize > inode->i_sb->s_blocksize)
1609 {
1610 loffset = *extoffset;
1611 aed->lengthAllocDescs = cpu_to_le32(adsize);
1612 sptr = ptr - adsize;
1613 dptr = nbh->b_data + sizeof(struct allocExtDesc);
1614 memcpy(dptr, sptr, adsize);
1615 *extoffset = sizeof(struct allocExtDesc) + adsize;
1616 }
1617 else
1618 {
1619 loffset = *extoffset + adsize;
1620 aed->lengthAllocDescs = cpu_to_le32(0);
1621 sptr = ptr;
1622 *extoffset = sizeof(struct allocExtDesc);
1623
1624 if (*bh)
1625 {
1626 aed = (struct allocExtDesc *)(*bh)->b_data;
1627 aed->lengthAllocDescs =
1628 cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
1629 }
1630 else
1631 {
1632 UDF_I_LENALLOC(inode) += adsize;
1633 mark_inode_dirty(inode);
1634 }
1635 }
1636 if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
1637 udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
1638 bloc->logicalBlockNum, sizeof(tag));
1639 else
1640 udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
1641 bloc->logicalBlockNum, sizeof(tag));
1642 switch (UDF_I_ALLOCTYPE(inode))
1643 {
1644 case ICBTAG_FLAG_AD_SHORT:
1645 {
1646 sad = (short_ad *)sptr;
1647 sad->extLength = cpu_to_le32(
1648 EXT_NEXT_EXTENT_ALLOCDECS |
1649 inode->i_sb->s_blocksize);
1650 sad->extPosition = cpu_to_le32(bloc->logicalBlockNum);
1651 break;
1652 }
1653 case ICBTAG_FLAG_AD_LONG:
1654 {
1655 lad = (long_ad *)sptr;
1656 lad->extLength = cpu_to_le32(
1657 EXT_NEXT_EXTENT_ALLOCDECS |
1658 inode->i_sb->s_blocksize);
1659 lad->extLocation = cpu_to_lelb(*bloc);
1660 memset(lad->impUse, 0x00, sizeof(lad->impUse));
1661 break;
1662 }
1663 }
1664 if (*bh)
1665 {
1666 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
1667 udf_update_tag((*bh)->b_data, loffset);
1668 else
1669 udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc));
1670 mark_buffer_dirty_inode(*bh, inode);
1671 udf_release_data(*bh);
1672 }
1673 else
1674 mark_inode_dirty(inode);
1675 *bh = nbh;
1676 }
1677
1678 etype = udf_write_aext(inode, *bloc, extoffset, eloc, elen, *bh, inc);
1679
1680 if (!*bh)
1681 {
1682 UDF_I_LENALLOC(inode) += adsize;
1683 mark_inode_dirty(inode);
1684 }
1685 else
1686 {
1687 aed = (struct allocExtDesc *)(*bh)->b_data;
1688 aed->lengthAllocDescs =
1689 cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
1690 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
1691 udf_update_tag((*bh)->b_data, *extoffset + (inc ? 0 : adsize));
1692 else
1693 udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc));
1694 mark_buffer_dirty_inode(*bh, inode);
1695 }
1696
1697 return etype;
1698}
1699
1700int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset,
1701 kernel_lb_addr eloc, uint32_t elen, struct buffer_head *bh, int inc)
1702{
1703 int adsize;
1704 uint8_t *ptr;
1705
1706 if (!bh)
1707 ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
1708 else
1709 {
1710 ptr = bh->b_data + *extoffset;
1711 atomic_inc(&bh->b_count);
1712 }
1713
1714 switch (UDF_I_ALLOCTYPE(inode))
1715 {
1716 case ICBTAG_FLAG_AD_SHORT:
1717 {
1718 short_ad *sad = (short_ad *)ptr;
1719 sad->extLength = cpu_to_le32(elen);
1720 sad->extPosition = cpu_to_le32(eloc.logicalBlockNum);
1721 adsize = sizeof(short_ad);
1722 break;
1723 }
1724 case ICBTAG_FLAG_AD_LONG:
1725 {
1726 long_ad *lad = (long_ad *)ptr;
1727 lad->extLength = cpu_to_le32(elen);
1728 lad->extLocation = cpu_to_lelb(eloc);
1729 memset(lad->impUse, 0x00, sizeof(lad->impUse));
1730 adsize = sizeof(long_ad);
1731 break;
1732 }
1733 default:
1734 return -1;
1735 }
1736
1737 if (bh)
1738 {
1739 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
1740 {
1741 struct allocExtDesc *aed = (struct allocExtDesc *)(bh)->b_data;
1742 udf_update_tag((bh)->b_data,
1743 le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc));
1744 }
1745 mark_buffer_dirty_inode(bh, inode);
1746 udf_release_data(bh);
1747 }
1748 else
1749 mark_inode_dirty(inode);
1750
1751 if (inc)
1752 *extoffset += adsize;
1753 return (elen >> 30);
1754}
1755
1756int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
1757 kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc)
1758{
1759 int8_t etype;
1760
1761 while ((etype = udf_current_aext(inode, bloc, extoffset, eloc, elen, bh, inc)) ==
1762 (EXT_NEXT_EXTENT_ALLOCDECS >> 30))
1763 {
1764 *bloc = *eloc;
1765 *extoffset = sizeof(struct allocExtDesc);
1766 udf_release_data(*bh);
1767 if (!(*bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, *bloc, 0))))
1768 {
1769 udf_debug("reading block %d failed!\n",
1770 udf_get_lb_pblock(inode->i_sb, *bloc, 0));
1771 return -1;
1772 }
1773 }
1774
1775 return etype;
1776}
1777
1778int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
1779 kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc)
1780{
1781 int alen;
1782 int8_t etype;
1783 uint8_t *ptr;
1784
1785 if (!*bh)
1786 {
1787 if (!(*extoffset))
1788 *extoffset = udf_file_entry_alloc_offset(inode);
1789 ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
1790 alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode);
1791 }
1792 else
1793 {
1794 if (!(*extoffset))
1795 *extoffset = sizeof(struct allocExtDesc);
1796 ptr = (*bh)->b_data + *extoffset;
1797 alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)(*bh)->b_data)->lengthAllocDescs);
1798 }
1799
1800 switch (UDF_I_ALLOCTYPE(inode))
1801 {
1802 case ICBTAG_FLAG_AD_SHORT:
1803 {
1804 short_ad *sad;
1805
1806 if (!(sad = udf_get_fileshortad(ptr, alen, extoffset, inc)))
1807 return -1;
1808
1809 etype = le32_to_cpu(sad->extLength) >> 30;
1810 eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
1811 eloc->partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
1812 *elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK;
1813 break;
1814 }
1815 case ICBTAG_FLAG_AD_LONG:
1816 {
1817 long_ad *lad;
1818
1819 if (!(lad = udf_get_filelongad(ptr, alen, extoffset, inc)))
1820 return -1;
1821
1822 etype = le32_to_cpu(lad->extLength) >> 30;
1823 *eloc = lelb_to_cpu(lad->extLocation);
1824 *elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK;
1825 break;
1826 }
1827 default:
1828 {
1829 udf_debug("alloc_type = %d unsupported\n", UDF_I_ALLOCTYPE(inode));
1830 return -1;
1831 }
1832 }
1833
1834 return etype;
1835}
1836
1837static int8_t
1838udf_insert_aext(struct inode *inode, kernel_lb_addr bloc, int extoffset,
1839 kernel_lb_addr neloc, uint32_t nelen, struct buffer_head *bh)
1840{
1841 kernel_lb_addr oeloc;
1842 uint32_t oelen;
1843 int8_t etype;
1844
1845 if (bh)
1846 atomic_inc(&bh->b_count);
1847
1848 while ((etype = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1)
1849 {
1850 udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
1851
1852 neloc = oeloc;
1853 nelen = (etype << 30) | oelen;
1854 }
1855 udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1);
1856 udf_release_data(bh);
1857 return (nelen >> 30);
1858}
1859
1860int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset,
1861 kernel_lb_addr eloc, uint32_t elen, struct buffer_head *nbh)
1862{
1863 struct buffer_head *obh;
1864 kernel_lb_addr obloc;
1865 int oextoffset, adsize;
1866 int8_t etype;
1867 struct allocExtDesc *aed;
1868
1869 if (nbh)
1870 {
1871 atomic_inc(&nbh->b_count);
1872 atomic_inc(&nbh->b_count);
1873 }
1874
1875 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
1876 adsize = sizeof(short_ad);
1877 else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
1878 adsize = sizeof(long_ad);
1879 else
1880 adsize = 0;
1881
1882 obh = nbh;
1883 obloc = nbloc;
1884 oextoffset = nextoffset;
1885
1886 if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1)
1887 return -1;
1888
1889 while ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
1890 {
1891 udf_write_aext(inode, obloc, &oextoffset, eloc, (etype << 30) | elen, obh, 1);
1892 if (obh != nbh)
1893 {
1894 obloc = nbloc;
1895 udf_release_data(obh);
1896 atomic_inc(&nbh->b_count);
1897 obh = nbh;
1898 oextoffset = nextoffset - adsize;
1899 }
1900 }
1901 memset(&eloc, 0x00, sizeof(kernel_lb_addr));
1902 elen = 0;
1903
1904 if (nbh != obh)
1905 {
1906 udf_free_blocks(inode->i_sb, inode, nbloc, 0, 1);
1907 udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
1908 udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
1909 if (!obh)
1910 {
1911 UDF_I_LENALLOC(inode) -= (adsize * 2);
1912 mark_inode_dirty(inode);
1913 }
1914 else
1915 {
1916 aed = (struct allocExtDesc *)(obh)->b_data;
1917 aed->lengthAllocDescs =
1918 cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize));
1919 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
1920 udf_update_tag((obh)->b_data, oextoffset - (2*adsize));
1921 else
1922 udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc));
1923 mark_buffer_dirty_inode(obh, inode);
1924 }
1925 }
1926 else
1927 {
1928 udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
1929 if (!obh)
1930 {
1931 UDF_I_LENALLOC(inode) -= adsize;
1932 mark_inode_dirty(inode);
1933 }
1934 else
1935 {
1936 aed = (struct allocExtDesc *)(obh)->b_data;
1937 aed->lengthAllocDescs =
1938 cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize);
1939 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
1940 udf_update_tag((obh)->b_data, oextoffset - adsize);
1941 else
1942 udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc));
1943 mark_buffer_dirty_inode(obh, inode);
1944 }
1945 }
1946
1947 udf_release_data(nbh);
1948 udf_release_data(obh);
1949 return (elen >> 30);
1950}
1951
1952int8_t inode_bmap(struct inode *inode, int block, kernel_lb_addr *bloc, uint32_t *extoffset,
1953 kernel_lb_addr *eloc, uint32_t *elen, uint32_t *offset, struct buffer_head **bh)
1954{
1955 uint64_t lbcount = 0, bcount = (uint64_t)block << inode->i_sb->s_blocksize_bits;
1956 int8_t etype;
1957
1958 if (block < 0)
1959 {
1960 printk(KERN_ERR "udf: inode_bmap: block < 0\n");
1961 return -1;
1962 }
1963 if (!inode)
1964 {
1965 printk(KERN_ERR "udf: inode_bmap: NULL inode\n");
1966 return -1;
1967 }
1968
1969 *extoffset = 0;
1970 *elen = 0;
1971 *bloc = UDF_I_LOCATION(inode);
1972
1973 do
1974 {
1975 if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1)
1976 {
1977 *offset = bcount - lbcount;
1978 UDF_I_LENEXTENTS(inode) = lbcount;
1979 return -1;
1980 }
1981 lbcount += *elen;
1982 } while (lbcount <= bcount);
1983
1984 *offset = bcount + *elen - lbcount;
1985
1986 return etype;
1987}
1988
1989long udf_block_map(struct inode *inode, long block)
1990{
1991 kernel_lb_addr eloc, bloc;
1992 uint32_t offset, extoffset, elen;
1993 struct buffer_head *bh = NULL;
1994 int ret;
1995
1996 lock_kernel();
1997
1998 if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
1999 ret = udf_get_lb_pblock(inode->i_sb, eloc, offset >> inode->i_sb->s_blocksize_bits);
2000 else
2001 ret = 0;
2002
2003 unlock_kernel();
2004 udf_release_data(bh);
2005
2006 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV))
2007 return udf_fixed_to_variable(ret);
2008 else
2009 return ret;
2010}
diff --git a/fs/udf/lowlevel.c b/fs/udf/lowlevel.c
new file mode 100644
index 000000000000..2da5087dfe05
--- /dev/null
+++ b/fs/udf/lowlevel.c
@@ -0,0 +1,77 @@
1/*
2 * lowlevel.c
3 *
4 * PURPOSE
5 * Low Level Device Routines for the UDF filesystem
6 *
7 * CONTACTS
8 * E-mail regarding any portion of the Linux UDF file system should be
9 * directed to the development team mailing list (run by majordomo):
10 * linux_udf@hpesjro.fc.hp.com
11 *
12 * COPYRIGHT
13 * This file is distributed under the terms of the GNU General Public
14 * License (GPL). Copies of the GPL can be obtained from:
15 * ftp://prep.ai.mit.edu/pub/gnu/GPL
16 * Each contributing author retains all rights to their own work.
17 *
18 * (C) 1999-2001 Ben Fennema
19 *
20 * HISTORY
21 *
22 * 03/26/99 blf Created.
23 */
24
25#include "udfdecl.h"
26
27#include <linux/blkdev.h>
28#include <linux/cdrom.h>
29#include <asm/uaccess.h>
30
31#include <linux/udf_fs.h>
32#include "udf_sb.h"
33
34unsigned int
35udf_get_last_session(struct super_block *sb)
36{
37 struct cdrom_multisession ms_info;
38 unsigned int vol_desc_start;
39 struct block_device *bdev = sb->s_bdev;
40 int i;
41
42 vol_desc_start=0;
43 ms_info.addr_format=CDROM_LBA;
44 i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long) &ms_info);
45
46#define WE_OBEY_THE_WRITTEN_STANDARDS 1
47
48 if (i == 0)
49 {
50 udf_debug("XA disk: %s, vol_desc_start=%d\n",
51 (ms_info.xa_flag ? "yes" : "no"), ms_info.addr.lba);
52#if WE_OBEY_THE_WRITTEN_STANDARDS
53 if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */
54#endif
55 vol_desc_start = ms_info.addr.lba;
56 }
57 else
58 {
59 udf_debug("CDROMMULTISESSION not supported: rc=%d\n", i);
60 }
61 return vol_desc_start;
62}
63
64unsigned long
65udf_get_last_block(struct super_block *sb)
66{
67 struct block_device *bdev = sb->s_bdev;
68 unsigned long lblock = 0;
69
70 if (ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock))
71 lblock = bdev->bd_inode->i_size >> sb->s_blocksize_bits;
72
73 if (lblock)
74 return lblock - 1;
75 else
76 return 0;
77}
diff --git a/fs/udf/misc.c b/fs/udf/misc.c
new file mode 100644
index 000000000000..fd321f9ace83
--- /dev/null
+++ b/fs/udf/misc.c
@@ -0,0 +1,313 @@
1/*
2 * misc.c
3 *
4 * PURPOSE
5 * Miscellaneous routines for the OSTA-UDF(tm) filesystem.
6 *
7 * CONTACTS
8 * E-mail regarding any portion of the Linux UDF file system should be
9 * directed to the development team mailing list (run by majordomo):
10 * linux_udf@hpesjro.fc.hp.com
11 *
12 * COPYRIGHT
13 * This file is distributed under the terms of the GNU General Public
14 * License (GPL). Copies of the GPL can be obtained from:
15 * ftp://prep.ai.mit.edu/pub/gnu/GPL
16 * Each contributing author retains all rights to their own work.
17 *
18 * (C) 1998 Dave Boynton
19 * (C) 1998-2004 Ben Fennema
20 * (C) 1999-2000 Stelias Computing Inc
21 *
22 * HISTORY
23 *
24 * 04/19/99 blf partial support for reading/writing specific EA's
25 */
26
27#include "udfdecl.h"
28
29#include <linux/fs.h>
30#include <linux/string.h>
31#include <linux/udf_fs.h>
32#include <linux/buffer_head.h>
33
34#include "udf_i.h"
35#include "udf_sb.h"
36
37struct buffer_head *
38udf_tgetblk(struct super_block *sb, int block)
39{
40 if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV))
41 return sb_getblk(sb, udf_fixed_to_variable(block));
42 else
43 return sb_getblk(sb, block);
44}
45
46struct buffer_head *
47udf_tread(struct super_block *sb, int block)
48{
49 if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV))
50 return sb_bread(sb, udf_fixed_to_variable(block));
51 else
52 return sb_bread(sb, block);
53}
54
55struct genericFormat *
56udf_add_extendedattr(struct inode * inode, uint32_t size, uint32_t type,
57 uint8_t loc)
58{
59 uint8_t *ea = NULL, *ad = NULL;
60 int offset;
61 uint16_t crclen;
62 int i;
63
64 ea = UDF_I_DATA(inode);
65 if (UDF_I_LENEATTR(inode))
66 ad = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
67 else
68 {
69 ad = ea;
70 size += sizeof(struct extendedAttrHeaderDesc);
71 }
72
73 offset = inode->i_sb->s_blocksize - udf_file_entry_alloc_offset(inode) -
74 UDF_I_LENALLOC(inode);
75
76 /* TODO - Check for FreeEASpace */
77
78 if (loc & 0x01 && offset >= size)
79 {
80 struct extendedAttrHeaderDesc *eahd;
81 eahd = (struct extendedAttrHeaderDesc *)ea;
82
83 if (UDF_I_LENALLOC(inode))
84 {
85 memmove(&ad[size], ad, UDF_I_LENALLOC(inode));
86 }
87
88 if (UDF_I_LENEATTR(inode))
89 {
90 /* check checksum/crc */
91 if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD ||
92 le32_to_cpu(eahd->descTag.tagLocation) != UDF_I_LOCATION(inode).logicalBlockNum)
93 {
94 return NULL;
95 }
96 }
97 else
98 {
99 size -= sizeof(struct extendedAttrHeaderDesc);
100 UDF_I_LENEATTR(inode) += sizeof(struct extendedAttrHeaderDesc);
101 eahd->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EAHD);
102 if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
103 eahd->descTag.descVersion = cpu_to_le16(3);
104 else
105 eahd->descTag.descVersion = cpu_to_le16(2);
106 eahd->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb));
107 eahd->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
108 eahd->impAttrLocation = cpu_to_le32(0xFFFFFFFF);
109 eahd->appAttrLocation = cpu_to_le32(0xFFFFFFFF);
110 }
111
112 offset = UDF_I_LENEATTR(inode);
113 if (type < 2048)
114 {
115 if (le32_to_cpu(eahd->appAttrLocation) < UDF_I_LENEATTR(inode))
116 {
117 uint32_t aal = le32_to_cpu(eahd->appAttrLocation);
118 memmove(&ea[offset - aal + size],
119 &ea[aal], offset - aal);
120 offset -= aal;
121 eahd->appAttrLocation = cpu_to_le32(aal + size);
122 }
123 if (le32_to_cpu(eahd->impAttrLocation) < UDF_I_LENEATTR(inode))
124 {
125 uint32_t ial = le32_to_cpu(eahd->impAttrLocation);
126 memmove(&ea[offset - ial + size],
127 &ea[ial], offset - ial);
128 offset -= ial;
129 eahd->impAttrLocation = cpu_to_le32(ial + size);
130 }
131 }
132 else if (type < 65536)
133 {
134 if (le32_to_cpu(eahd->appAttrLocation) < UDF_I_LENEATTR(inode))
135 {
136 uint32_t aal = le32_to_cpu(eahd->appAttrLocation);
137 memmove(&ea[offset - aal + size],
138 &ea[aal], offset - aal);
139 offset -= aal;
140 eahd->appAttrLocation = cpu_to_le32(aal + size);
141 }
142 }
143 /* rewrite CRC + checksum of eahd */
144 crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(tag);
145 eahd->descTag.descCRCLength = cpu_to_le16(crclen);
146 eahd->descTag.descCRC = cpu_to_le16(udf_crc((char *)eahd + sizeof(tag), crclen, 0));
147 eahd->descTag.tagChecksum = 0;
148 for (i=0; i<16; i++)
149 if (i != 4)
150 eahd->descTag.tagChecksum += ((uint8_t *)&(eahd->descTag))[i];
151 UDF_I_LENEATTR(inode) += size;
152 return (struct genericFormat *)&ea[offset];
153 }
154 if (loc & 0x02)
155 {
156 }
157 return NULL;
158}
159
160struct genericFormat *
161udf_get_extendedattr(struct inode *inode, uint32_t type, uint8_t subtype)
162{
163 struct genericFormat *gaf;
164 uint8_t *ea = NULL;
165 uint32_t offset;
166
167 ea = UDF_I_DATA(inode);
168
169 if (UDF_I_LENEATTR(inode))
170 {
171 struct extendedAttrHeaderDesc *eahd;
172 eahd = (struct extendedAttrHeaderDesc *)ea;
173
174 /* check checksum/crc */
175 if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD ||
176 le32_to_cpu(eahd->descTag.tagLocation) != UDF_I_LOCATION(inode).logicalBlockNum)
177 {
178 return NULL;
179 }
180
181 if (type < 2048)
182 offset = sizeof(struct extendedAttrHeaderDesc);
183 else if (type < 65536)
184 offset = le32_to_cpu(eahd->impAttrLocation);
185 else
186 offset = le32_to_cpu(eahd->appAttrLocation);
187
188 while (offset < UDF_I_LENEATTR(inode))
189 {
190 gaf = (struct genericFormat *)&ea[offset];
191 if (le32_to_cpu(gaf->attrType) == type && gaf->attrSubtype == subtype)
192 return gaf;
193 else
194 offset += le32_to_cpu(gaf->attrLength);
195 }
196 }
197 return NULL;
198}
199
200/*
201 * udf_read_tagged
202 *
203 * PURPOSE
204 * Read the first block of a tagged descriptor.
205 *
206 * HISTORY
207 * July 1, 1997 - Andrew E. Mileski
208 * Written, tested, and released.
209 */
210struct buffer_head *
211udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint16_t *ident)
212{
213 tag *tag_p;
214 struct buffer_head *bh = NULL;
215 register uint8_t checksum;
216 register int i;
217
218 /* Read the block */
219 if (block == 0xFFFFFFFF)
220 return NULL;
221
222 bh = udf_tread(sb, block + UDF_SB_SESSION(sb));
223 if (!bh)
224 {
225 udf_debug("block=%d, location=%d: read failed\n", block + UDF_SB_SESSION(sb), location);
226 return NULL;
227 }
228
229 tag_p = (tag *)(bh->b_data);
230
231 *ident = le16_to_cpu(tag_p->tagIdent);
232
233 if ( location != le32_to_cpu(tag_p->tagLocation) )
234 {
235 udf_debug("location mismatch block %u, tag %u != %u\n",
236 block + UDF_SB_SESSION(sb), le32_to_cpu(tag_p->tagLocation), location);
237 goto error_out;
238 }
239
240 /* Verify the tag checksum */
241 checksum = 0U;
242 for (i = 0; i < 4; i++)
243 checksum += (uint8_t)(bh->b_data[i]);
244 for (i = 5; i < 16; i++)
245 checksum += (uint8_t)(bh->b_data[i]);
246 if (checksum != tag_p->tagChecksum) {
247 printk(KERN_ERR "udf: tag checksum failed block %d\n", block);
248 goto error_out;
249 }
250
251 /* Verify the tag version */
252 if (le16_to_cpu(tag_p->descVersion) != 0x0002U &&
253 le16_to_cpu(tag_p->descVersion) != 0x0003U)
254 {
255 udf_debug("tag version 0x%04x != 0x0002 || 0x0003 block %d\n",
256 le16_to_cpu(tag_p->descVersion), block);
257 goto error_out;
258 }
259
260 /* Verify the descriptor CRC */
261 if (le16_to_cpu(tag_p->descCRCLength) + sizeof(tag) > sb->s_blocksize ||
262 le16_to_cpu(tag_p->descCRC) == udf_crc(bh->b_data + sizeof(tag),
263 le16_to_cpu(tag_p->descCRCLength), 0))
264 {
265 return bh;
266 }
267 udf_debug("Crc failure block %d: crc = %d, crclen = %d\n",
268 block + UDF_SB_SESSION(sb), le16_to_cpu(tag_p->descCRC), le16_to_cpu(tag_p->descCRCLength));
269
270error_out:
271 brelse(bh);
272 return NULL;
273}
274
275struct buffer_head *
276udf_read_ptagged(struct super_block *sb, kernel_lb_addr loc, uint32_t offset, uint16_t *ident)
277{
278 return udf_read_tagged(sb, udf_get_lb_pblock(sb, loc, offset),
279 loc.logicalBlockNum + offset, ident);
280}
281
282void udf_release_data(struct buffer_head *bh)
283{
284 if (bh)
285 brelse(bh);
286}
287
288void udf_update_tag(char *data, int length)
289{
290 tag *tptr = (tag *)data;
291 int i;
292
293 length -= sizeof(tag);
294
295 tptr->tagChecksum = 0;
296 tptr->descCRCLength = cpu_to_le16(length);
297 tptr->descCRC = cpu_to_le16(udf_crc(data + sizeof(tag), length, 0));
298
299 for (i=0; i<16; i++)
300 if (i != 4)
301 tptr->tagChecksum += (uint8_t)(data[i]);
302}
303
304void udf_new_tag(char *data, uint16_t ident, uint16_t version, uint16_t snum,
305 uint32_t loc, int length)
306{
307 tag *tptr = (tag *)data;
308 tptr->tagIdent = cpu_to_le16(ident);
309 tptr->descVersion = cpu_to_le16(version);
310 tptr->tagSerialNum = cpu_to_le16(snum);
311 tptr->tagLocation = cpu_to_le32(loc);
312 udf_update_tag(data, length);
313}
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
new file mode 100644
index 000000000000..3f6dc7112bc6
--- /dev/null
+++ b/fs/udf/namei.c
@@ -0,0 +1,1334 @@
1/*
2 * namei.c
3 *
4 * PURPOSE
5 * Inode name handling routines for the OSTA-UDF(tm) filesystem.
6 *
7 * CONTACTS
8 * E-mail regarding any portion of the Linux UDF file system should be
9 * directed to the development team mailing list (run by majordomo):
10 * linux_udf@hpesjro.fc.hp.com
11 *
12 * COPYRIGHT
13 * This file is distributed under the terms of the GNU General Public
14 * License (GPL). Copies of the GPL can be obtained from:
15 * ftp://prep.ai.mit.edu/pub/gnu/GPL
16 * Each contributing author retains all rights to their own work.
17 *
18 * (C) 1998-2004 Ben Fennema
19 * (C) 1999-2000 Stelias Computing Inc
20 *
21 * HISTORY
22 *
23 * 12/12/98 blf Created. Split out the lookup code from dir.c
24 * 04/19/99 blf link, mknod, symlink support
25 */
26
27#include "udfdecl.h"
28
29#include "udf_i.h"
30#include "udf_sb.h"
31#include <linux/string.h>
32#include <linux/errno.h>
33#include <linux/mm.h>
34#include <linux/slab.h>
35#include <linux/quotaops.h>
36#include <linux/smp_lock.h>
37#include <linux/buffer_head.h>
38
39static inline int udf_match(int len1, const char *name1, int len2, const char *name2)
40{
41 if (len1 != len2)
42 return 0;
43 return !memcmp(name1, name2, len1);
44}
45
46int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi,
47 struct fileIdentDesc *sfi, struct udf_fileident_bh *fibh,
48 uint8_t *impuse, uint8_t *fileident)
49{
50 uint16_t crclen = fibh->eoffset - fibh->soffset - sizeof(tag);
51 uint16_t crc;
52 uint8_t checksum = 0;
53 int i;
54 int offset;
55 uint16_t liu = le16_to_cpu(cfi->lengthOfImpUse);
56 uint8_t lfi = cfi->lengthFileIdent;
57 int padlen = fibh->eoffset - fibh->soffset - liu - lfi -
58 sizeof(struct fileIdentDesc);
59 int adinicb = 0;
60
61 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
62 adinicb = 1;
63
64 offset = fibh->soffset + sizeof(struct fileIdentDesc);
65
66 if (impuse)
67 {
68 if (adinicb || (offset + liu < 0))
69 memcpy((uint8_t *)sfi->impUse, impuse, liu);
70 else if (offset >= 0)
71 memcpy(fibh->ebh->b_data + offset, impuse, liu);
72 else
73 {
74 memcpy((uint8_t *)sfi->impUse, impuse, -offset);
75 memcpy(fibh->ebh->b_data, impuse - offset, liu + offset);
76 }
77 }
78
79 offset += liu;
80
81 if (fileident)
82 {
83 if (adinicb || (offset + lfi < 0))
84 memcpy((uint8_t *)sfi->fileIdent + liu, fileident, lfi);
85 else if (offset >= 0)
86 memcpy(fibh->ebh->b_data + offset, fileident, lfi);
87 else
88 {
89 memcpy((uint8_t *)sfi->fileIdent + liu, fileident, -offset);
90 memcpy(fibh->ebh->b_data, fileident - offset, lfi + offset);
91 }
92 }
93
94 offset += lfi;
95
96 if (adinicb || (offset + padlen < 0))
97 memset((uint8_t *)sfi->padding + liu + lfi, 0x00, padlen);
98 else if (offset >= 0)
99 memset(fibh->ebh->b_data + offset, 0x00, padlen);
100 else
101 {
102 memset((uint8_t *)sfi->padding + liu + lfi, 0x00, -offset);
103 memset(fibh->ebh->b_data, 0x00, padlen + offset);
104 }
105
106 crc = udf_crc((uint8_t *)cfi + sizeof(tag), sizeof(struct fileIdentDesc) -
107 sizeof(tag), 0);
108
109 if (fibh->sbh == fibh->ebh)
110 crc = udf_crc((uint8_t *)sfi->impUse,
111 crclen + sizeof(tag) - sizeof(struct fileIdentDesc), crc);
112 else if (sizeof(struct fileIdentDesc) >= -fibh->soffset)
113 crc = udf_crc(fibh->ebh->b_data + sizeof(struct fileIdentDesc) + fibh->soffset,
114 crclen + sizeof(tag) - sizeof(struct fileIdentDesc), crc);
115 else
116 {
117 crc = udf_crc((uint8_t *)sfi->impUse,
118 -fibh->soffset - sizeof(struct fileIdentDesc), crc);
119 crc = udf_crc(fibh->ebh->b_data, fibh->eoffset, crc);
120 }
121
122 cfi->descTag.descCRC = cpu_to_le16(crc);
123 cfi->descTag.descCRCLength = cpu_to_le16(crclen);
124
125 for (i=0; i<16; i++)
126 if (i != 4)
127 checksum += ((uint8_t *)&cfi->descTag)[i];
128
129 cfi->descTag.tagChecksum = checksum;
130 if (adinicb || (sizeof(struct fileIdentDesc) <= -fibh->soffset))
131 memcpy((uint8_t *)sfi, (uint8_t *)cfi, sizeof(struct fileIdentDesc));
132 else
133 {
134 memcpy((uint8_t *)sfi, (uint8_t *)cfi, -fibh->soffset);
135 memcpy(fibh->ebh->b_data, (uint8_t *)cfi - fibh->soffset,
136 sizeof(struct fileIdentDesc) + fibh->soffset);
137 }
138
139 if (adinicb)
140 mark_inode_dirty(inode);
141 else
142 {
143 if (fibh->sbh != fibh->ebh)
144 mark_buffer_dirty_inode(fibh->ebh, inode);
145 mark_buffer_dirty_inode(fibh->sbh, inode);
146 }
147 return 0;
148}
149
150static struct fileIdentDesc *
151udf_find_entry(struct inode *dir, struct dentry *dentry,
152 struct udf_fileident_bh *fibh,
153 struct fileIdentDesc *cfi)
154{
155 struct fileIdentDesc *fi=NULL;
156 loff_t f_pos;
157 int block, flen;
158 char fname[UDF_NAME_LEN];
159 char *nameptr;
160 uint8_t lfi;
161 uint16_t liu;
162 loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
163 kernel_lb_addr bloc, eloc;
164 uint32_t extoffset, elen, offset;
165 struct buffer_head *bh = NULL;
166
167 if (!dir)
168 return NULL;
169
170 f_pos = (udf_ext0_offset(dir) >> 2);
171
172 fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
173 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
174 fibh->sbh = fibh->ebh = NULL;
175 else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
176 &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
177 {
178 offset >>= dir->i_sb->s_blocksize_bits;
179 block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
180 if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
181 {
182 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
183 extoffset -= sizeof(short_ad);
184 else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
185 extoffset -= sizeof(long_ad);
186 }
187 else
188 offset = 0;
189
190 if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block)))
191 {
192 udf_release_data(bh);
193 return NULL;
194 }
195 }
196 else
197 {
198 udf_release_data(bh);
199 return NULL;
200 }
201
202 while ( (f_pos < size) )
203 {
204 fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
205
206 if (!fi)
207 {
208 if (fibh->sbh != fibh->ebh)
209 udf_release_data(fibh->ebh);
210 udf_release_data(fibh->sbh);
211 udf_release_data(bh);
212 return NULL;
213 }
214
215 liu = le16_to_cpu(cfi->lengthOfImpUse);
216 lfi = cfi->lengthFileIdent;
217
218 if (fibh->sbh == fibh->ebh)
219 {
220 nameptr = fi->fileIdent + liu;
221 }
222 else
223 {
224 int poffset; /* Unpaded ending offset */
225
226 poffset = fibh->soffset + sizeof(struct fileIdentDesc) + liu + lfi;
227
228 if (poffset >= lfi)
229 nameptr = (uint8_t *)(fibh->ebh->b_data + poffset - lfi);
230 else
231 {
232 nameptr = fname;
233 memcpy(nameptr, fi->fileIdent + liu, lfi - poffset);
234 memcpy(nameptr + lfi - poffset, fibh->ebh->b_data, poffset);
235 }
236 }
237
238 if ( (cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0 )
239 {
240 if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE) )
241 continue;
242 }
243
244 if ( (cfi->fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0 )
245 {
246 if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE) )
247 continue;
248 }
249
250 if (!lfi)
251 continue;
252
253 if ((flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi)))
254 {
255 if (udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name))
256 {
257 udf_release_data(bh);
258 return fi;
259 }
260 }
261 }
262 if (fibh->sbh != fibh->ebh)
263 udf_release_data(fibh->ebh);
264 udf_release_data(fibh->sbh);
265 udf_release_data(bh);
266 return NULL;
267}
268
269/*
270 * udf_lookup
271 *
272 * PURPOSE
273 * Look-up the inode for a given name.
274 *
275 * DESCRIPTION
276 * Required - lookup_dentry() will return -ENOTDIR if this routine is not
277 * available for a directory. The filesystem is useless if this routine is
278 * not available for at least the filesystem's root directory.
279 *
280 * This routine is passed an incomplete dentry - it must be completed by
281 * calling d_add(dentry, inode). If the name does not exist, then the
282 * specified inode must be set to null. An error should only be returned
283 * when the lookup fails for a reason other than the name not existing.
284 * Note that the directory inode semaphore is held during the call.
285 *
286 * Refer to lookup_dentry() in fs/namei.c
287 * lookup_dentry() -> lookup() -> real_lookup() -> .
288 *
289 * PRE-CONDITIONS
290 * dir Pointer to inode of parent directory.
291 * dentry Pointer to dentry to complete.
292 * nd Pointer to lookup nameidata
293 *
294 * POST-CONDITIONS
295 * <return> Zero on success.
296 *
297 * HISTORY
298 * July 1, 1997 - Andrew E. Mileski
299 * Written, tested, and released.
300 */
301
302static struct dentry *
303udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
304{
305 struct inode *inode = NULL;
306 struct fileIdentDesc cfi, *fi;
307 struct udf_fileident_bh fibh;
308
309 if (dentry->d_name.len > UDF_NAME_LEN-2)
310 return ERR_PTR(-ENAMETOOLONG);
311
312 lock_kernel();
313#ifdef UDF_RECOVERY
314 /* temporary shorthand for specifying files by inode number */
315 if (!strncmp(dentry->d_name.name, ".B=", 3) )
316 {
317 kernel_lb_addr lb = { 0, simple_strtoul(dentry->d_name.name+3, NULL, 0) };
318 inode = udf_iget(dir->i_sb, lb);
319 if (!inode)
320 {
321 unlock_kernel();
322 return ERR_PTR(-EACCES);
323 }
324 }
325 else
326#endif /* UDF_RECOVERY */
327
328 if ((fi = udf_find_entry(dir, dentry, &fibh, &cfi)))
329 {
330 if (fibh.sbh != fibh.ebh)
331 udf_release_data(fibh.ebh);
332 udf_release_data(fibh.sbh);
333
334 inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation));
335 if ( !inode )
336 {
337 unlock_kernel();
338 return ERR_PTR(-EACCES);
339 }
340 }
341 unlock_kernel();
342 d_add(dentry, inode);
343 return NULL;
344}
345
346static struct fileIdentDesc *
347udf_add_entry(struct inode *dir, struct dentry *dentry,
348 struct udf_fileident_bh *fibh,
349 struct fileIdentDesc *cfi, int *err)
350{
351 struct super_block *sb;
352 struct fileIdentDesc *fi=NULL;
353 char name[UDF_NAME_LEN], fname[UDF_NAME_LEN];
354 int namelen;
355 loff_t f_pos;
356 int flen;
357 char *nameptr;
358 loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
359 int nfidlen;
360 uint8_t lfi;
361 uint16_t liu;
362 int block;
363 kernel_lb_addr bloc, eloc;
364 uint32_t extoffset, elen, offset;
365 struct buffer_head *bh = NULL;
366
367 sb = dir->i_sb;
368
369 if (dentry)
370 {
371 if (!dentry->d_name.len)
372 {
373 *err = -EINVAL;
374 return NULL;
375 }
376
377 if ( !(namelen = udf_put_filename(sb, dentry->d_name.name, name, dentry->d_name.len)))
378 {
379 *err = -ENAMETOOLONG;
380 return NULL;
381 }
382 }
383 else
384 namelen = 0;
385
386 nfidlen = (sizeof(struct fileIdentDesc) + namelen + 3) & ~3;
387
388 f_pos = (udf_ext0_offset(dir) >> 2);
389
390 fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
391 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
392 fibh->sbh = fibh->ebh = NULL;
393 else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
394 &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
395 {
396 offset >>= dir->i_sb->s_blocksize_bits;
397 block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
398 if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
399 {
400 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
401 extoffset -= sizeof(short_ad);
402 else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
403 extoffset -= sizeof(long_ad);
404 }
405 else
406 offset = 0;
407
408 if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block)))
409 {
410 udf_release_data(bh);
411 *err = -EIO;
412 return NULL;
413 }
414
415 block = UDF_I_LOCATION(dir).logicalBlockNum;
416
417 }
418 else
419 {
420 block = udf_get_lb_pblock(dir->i_sb, UDF_I_LOCATION(dir), 0);
421 fibh->sbh = fibh->ebh = NULL;
422 fibh->soffset = fibh->eoffset = sb->s_blocksize;
423 goto add;
424 }
425
426 while ( (f_pos < size) )
427 {
428 fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
429
430 if (!fi)
431 {
432 if (fibh->sbh != fibh->ebh)
433 udf_release_data(fibh->ebh);
434 udf_release_data(fibh->sbh);
435 udf_release_data(bh);
436 *err = -EIO;
437 return NULL;
438 }
439
440 liu = le16_to_cpu(cfi->lengthOfImpUse);
441 lfi = cfi->lengthFileIdent;
442
443 if (fibh->sbh == fibh->ebh)
444 nameptr = fi->fileIdent + liu;
445 else
446 {
447 int poffset; /* Unpaded ending offset */
448
449 poffset = fibh->soffset + sizeof(struct fileIdentDesc) + liu + lfi;
450
451 if (poffset >= lfi)
452 nameptr = (char *)(fibh->ebh->b_data + poffset - lfi);
453 else
454 {
455 nameptr = fname;
456 memcpy(nameptr, fi->fileIdent + liu, lfi - poffset);
457 memcpy(nameptr + lfi - poffset, fibh->ebh->b_data, poffset);
458 }
459 }
460
461 if ( (cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0 )
462 {
463 if (((sizeof(struct fileIdentDesc) + liu + lfi + 3) & ~3) == nfidlen)
464 {
465 udf_release_data(bh);
466 cfi->descTag.tagSerialNum = cpu_to_le16(1);
467 cfi->fileVersionNum = cpu_to_le16(1);
468 cfi->fileCharacteristics = 0;
469 cfi->lengthFileIdent = namelen;
470 cfi->lengthOfImpUse = cpu_to_le16(0);
471 if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name))
472 return fi;
473 else
474 {
475 *err = -EIO;
476 return NULL;
477 }
478 }
479 }
480
481 if (!lfi || !dentry)
482 continue;
483
484 if ((flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi)) &&
485 udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name))
486 {
487 if (fibh->sbh != fibh->ebh)
488 udf_release_data(fibh->ebh);
489 udf_release_data(fibh->sbh);
490 udf_release_data(bh);
491 *err = -EEXIST;
492 return NULL;
493 }
494 }
495
496add:
497 f_pos += nfidlen;
498
499 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB &&
500 sb->s_blocksize - fibh->eoffset < nfidlen)
501 {
502 udf_release_data(bh);
503 bh = NULL;
504 fibh->soffset -= udf_ext0_offset(dir);
505 fibh->eoffset -= udf_ext0_offset(dir);
506 f_pos -= (udf_ext0_offset(dir) >> 2);
507 if (fibh->sbh != fibh->ebh)
508 udf_release_data(fibh->ebh);
509 udf_release_data(fibh->sbh);
510 if (!(fibh->sbh = fibh->ebh = udf_expand_dir_adinicb(dir, &block, err)))
511 return NULL;
512 bloc = UDF_I_LOCATION(dir);
513 eloc.logicalBlockNum = block;
514 eloc.partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum;
515 elen = dir->i_sb->s_blocksize;
516 extoffset = udf_file_entry_alloc_offset(dir);
517 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
518 extoffset += sizeof(short_ad);
519 else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
520 extoffset += sizeof(long_ad);
521 }
522
523 if (sb->s_blocksize - fibh->eoffset >= nfidlen)
524 {
525 fibh->soffset = fibh->eoffset;
526 fibh->eoffset += nfidlen;
527 if (fibh->sbh != fibh->ebh)
528 {
529 udf_release_data(fibh->sbh);
530 fibh->sbh = fibh->ebh;
531 }
532
533 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
534 {
535 block = UDF_I_LOCATION(dir).logicalBlockNum;
536 fi = (struct fileIdentDesc *)(UDF_I_DATA(dir) + fibh->soffset - udf_ext0_offset(dir) + UDF_I_LENEATTR(dir));
537 }
538 else
539 {
540 block = eloc.logicalBlockNum + ((elen - 1) >>
541 dir->i_sb->s_blocksize_bits);
542 fi = (struct fileIdentDesc *)(fibh->sbh->b_data + fibh->soffset);
543 }
544 }
545 else
546 {
547 fibh->soffset = fibh->eoffset - sb->s_blocksize;
548 fibh->eoffset += nfidlen - sb->s_blocksize;
549 if (fibh->sbh != fibh->ebh)
550 {
551 udf_release_data(fibh->sbh);
552 fibh->sbh = fibh->ebh;
553 }
554
555 block = eloc.logicalBlockNum + ((elen - 1) >>
556 dir->i_sb->s_blocksize_bits);
557
558 if (!(fibh->ebh = udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 1, err)))
559 {
560 udf_release_data(bh);
561 udf_release_data(fibh->sbh);
562 return NULL;
563 }
564
565 if (!(fibh->soffset))
566 {
567 if (udf_next_aext(dir, &bloc, &extoffset, &eloc, &elen, &bh, 1) ==
568 (EXT_RECORDED_ALLOCATED >> 30))
569 {
570 block = eloc.logicalBlockNum + ((elen - 1) >>
571 dir->i_sb->s_blocksize_bits);
572 }
573 else
574 block ++;
575
576 udf_release_data(fibh->sbh);
577 fibh->sbh = fibh->ebh;
578 fi = (struct fileIdentDesc *)(fibh->sbh->b_data);
579 }
580 else
581 {
582 fi = (struct fileIdentDesc *)
583 (fibh->sbh->b_data + sb->s_blocksize + fibh->soffset);
584 }
585 }
586
587 memset(cfi, 0, sizeof(struct fileIdentDesc));
588 if (UDF_SB_UDFREV(sb) >= 0x0200)
589 udf_new_tag((char *)cfi, TAG_IDENT_FID, 3, 1, block, sizeof(tag));
590 else
591 udf_new_tag((char *)cfi, TAG_IDENT_FID, 2, 1, block, sizeof(tag));
592 cfi->fileVersionNum = cpu_to_le16(1);
593 cfi->lengthFileIdent = namelen;
594 cfi->lengthOfImpUse = cpu_to_le16(0);
595 if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name))
596 {
597 udf_release_data(bh);
598 dir->i_size += nfidlen;
599 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
600 UDF_I_LENALLOC(dir) += nfidlen;
601 mark_inode_dirty(dir);
602 return fi;
603 }
604 else
605 {
606 udf_release_data(bh);
607 if (fibh->sbh != fibh->ebh)
608 udf_release_data(fibh->ebh);
609 udf_release_data(fibh->sbh);
610 *err = -EIO;
611 return NULL;
612 }
613}
614
615static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi,
616 struct udf_fileident_bh *fibh, struct fileIdentDesc *cfi)
617{
618 cfi->fileCharacteristics |= FID_FILE_CHAR_DELETED;
619 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
620 memset(&(cfi->icb), 0x00, sizeof(long_ad));
621 return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL);
622}
623
624static int udf_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
625{
626 struct udf_fileident_bh fibh;
627 struct inode *inode;
628 struct fileIdentDesc cfi, *fi;
629 int err;
630
631 lock_kernel();
632 inode = udf_new_inode(dir, mode, &err);
633 if (!inode)
634 {
635 unlock_kernel();
636 return err;
637 }
638
639 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
640 inode->i_data.a_ops = &udf_adinicb_aops;
641 else
642 inode->i_data.a_ops = &udf_aops;
643 inode->i_op = &udf_file_inode_operations;
644 inode->i_fop = &udf_file_operations;
645 inode->i_mode = mode;
646 mark_inode_dirty(inode);
647
648 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err)))
649 {
650 inode->i_nlink --;
651 mark_inode_dirty(inode);
652 iput(inode);
653 unlock_kernel();
654 return err;
655 }
656 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
657 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
658 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
659 cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
660 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
661 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
662 {
663 mark_inode_dirty(dir);
664 }
665 if (fibh.sbh != fibh.ebh)
666 udf_release_data(fibh.ebh);
667 udf_release_data(fibh.sbh);
668 unlock_kernel();
669 d_instantiate(dentry, inode);
670 return 0;
671}
672
673static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t rdev)
674{
675 struct inode * inode;
676 struct udf_fileident_bh fibh;
677 struct fileIdentDesc cfi, *fi;
678 int err;
679
680 if (!old_valid_dev(rdev))
681 return -EINVAL;
682
683 lock_kernel();
684 err = -EIO;
685 inode = udf_new_inode(dir, mode, &err);
686 if (!inode)
687 goto out;
688
689 inode->i_uid = current->fsuid;
690 init_special_inode(inode, mode, rdev);
691 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err)))
692 {
693 inode->i_nlink --;
694 mark_inode_dirty(inode);
695 iput(inode);
696 unlock_kernel();
697 return err;
698 }
699 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
700 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
701 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
702 cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
703 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
704 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
705 {
706 mark_inode_dirty(dir);
707 }
708 mark_inode_dirty(inode);
709
710 if (fibh.sbh != fibh.ebh)
711 udf_release_data(fibh.ebh);
712 udf_release_data(fibh.sbh);
713 d_instantiate(dentry, inode);
714 err = 0;
715out:
716 unlock_kernel();
717 return err;
718}
719
720static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode)
721{
722 struct inode * inode;
723 struct udf_fileident_bh fibh;
724 struct fileIdentDesc cfi, *fi;
725 int err;
726
727 lock_kernel();
728 err = -EMLINK;
729 if (dir->i_nlink >= (256<<sizeof(dir->i_nlink))-1)
730 goto out;
731
732 err = -EIO;
733 inode = udf_new_inode(dir, S_IFDIR, &err);
734 if (!inode)
735 goto out;
736
737 inode->i_op = &udf_dir_inode_operations;
738 inode->i_fop = &udf_dir_operations;
739 if (!(fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err)))
740 {
741 inode->i_nlink--;
742 mark_inode_dirty(inode);
743 iput(inode);
744 goto out;
745 }
746 inode->i_nlink = 2;
747 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
748 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(dir));
749 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
750 cpu_to_le32(UDF_I_UNIQUE(dir) & 0x00000000FFFFFFFFUL);
751 cfi.fileCharacteristics = FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT;
752 udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL);
753 udf_release_data(fibh.sbh);
754 inode->i_mode = S_IFDIR | mode;
755 if (dir->i_mode & S_ISGID)
756 inode->i_mode |= S_ISGID;
757 mark_inode_dirty(inode);
758
759 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err)))
760 {
761 inode->i_nlink = 0;
762 mark_inode_dirty(inode);
763 iput(inode);
764 goto out;
765 }
766 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
767 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
768 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
769 cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
770 cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY;
771 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
772 dir->i_nlink++;
773 mark_inode_dirty(dir);
774 d_instantiate(dentry, inode);
775 if (fibh.sbh != fibh.ebh)
776 udf_release_data(fibh.ebh);
777 udf_release_data(fibh.sbh);
778 err = 0;
779out:
780 unlock_kernel();
781 return err;
782}
783
784static int empty_dir(struct inode *dir)
785{
786 struct fileIdentDesc *fi, cfi;
787 struct udf_fileident_bh fibh;
788 loff_t f_pos;
789 loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
790 int block;
791 kernel_lb_addr bloc, eloc;
792 uint32_t extoffset, elen, offset;
793 struct buffer_head *bh = NULL;
794
795 f_pos = (udf_ext0_offset(dir) >> 2);
796
797 fibh.soffset = fibh.eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
798
799 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
800 fibh.sbh = fibh.ebh = NULL;
801 else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
802 &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
803 {
804 offset >>= dir->i_sb->s_blocksize_bits;
805 block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
806 if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
807 {
808 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
809 extoffset -= sizeof(short_ad);
810 else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
811 extoffset -= sizeof(long_ad);
812 }
813 else
814 offset = 0;
815
816 if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block)))
817 {
818 udf_release_data(bh);
819 return 0;
820 }
821 }
822 else
823 {
824 udf_release_data(bh);
825 return 0;
826 }
827
828
829 while ( (f_pos < size) )
830 {
831 fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
832
833 if (!fi)
834 {
835 if (fibh.sbh != fibh.ebh)
836 udf_release_data(fibh.ebh);
837 udf_release_data(fibh.sbh);
838 udf_release_data(bh);
839 return 0;
840 }
841
842 if (cfi.lengthFileIdent && (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0)
843 {
844 if (fibh.sbh != fibh.ebh)
845 udf_release_data(fibh.ebh);
846 udf_release_data(fibh.sbh);
847 udf_release_data(bh);
848 return 0;
849 }
850 }
851 if (fibh.sbh != fibh.ebh)
852 udf_release_data(fibh.ebh);
853 udf_release_data(fibh.sbh);
854 udf_release_data(bh);
855 return 1;
856}
857
858static int udf_rmdir(struct inode * dir, struct dentry * dentry)
859{
860 int retval;
861 struct inode * inode = dentry->d_inode;
862 struct udf_fileident_bh fibh;
863 struct fileIdentDesc *fi, cfi;
864 kernel_lb_addr tloc;
865
866 retval = -ENOENT;
867 lock_kernel();
868 fi = udf_find_entry(dir, dentry, &fibh, &cfi);
869 if (!fi)
870 goto out;
871
872 retval = -EIO;
873 tloc = lelb_to_cpu(cfi.icb.extLocation);
874 if (udf_get_lb_pblock(dir->i_sb, tloc, 0) != inode->i_ino)
875 goto end_rmdir;
876 retval = -ENOTEMPTY;
877 if (!empty_dir(inode))
878 goto end_rmdir;
879 retval = udf_delete_entry(dir, fi, &fibh, &cfi);
880 if (retval)
881 goto end_rmdir;
882 if (inode->i_nlink != 2)
883 udf_warning(inode->i_sb, "udf_rmdir",
884 "empty directory has nlink != 2 (%d)",
885 inode->i_nlink);
886 inode->i_nlink = 0;
887 inode->i_size = 0;
888 mark_inode_dirty(inode);
889 dir->i_nlink --;
890 inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
891 mark_inode_dirty(dir);
892
893end_rmdir:
894 if (fibh.sbh != fibh.ebh)
895 udf_release_data(fibh.ebh);
896 udf_release_data(fibh.sbh);
897out:
898 unlock_kernel();
899 return retval;
900}
901
902static int udf_unlink(struct inode * dir, struct dentry * dentry)
903{
904 int retval;
905 struct inode * inode = dentry->d_inode;
906 struct udf_fileident_bh fibh;
907 struct fileIdentDesc *fi;
908 struct fileIdentDesc cfi;
909 kernel_lb_addr tloc;
910
911 retval = -ENOENT;
912 lock_kernel();
913 fi = udf_find_entry(dir, dentry, &fibh, &cfi);
914 if (!fi)
915 goto out;
916
917 retval = -EIO;
918 tloc = lelb_to_cpu(cfi.icb.extLocation);
919 if (udf_get_lb_pblock(dir->i_sb, tloc, 0) != inode->i_ino)
920 goto end_unlink;
921
922 if (!inode->i_nlink)
923 {
924 udf_debug("Deleting nonexistent file (%lu), %d\n",
925 inode->i_ino, inode->i_nlink);
926 inode->i_nlink = 1;
927 }
928 retval = udf_delete_entry(dir, fi, &fibh, &cfi);
929 if (retval)
930 goto end_unlink;
931 dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
932 mark_inode_dirty(dir);
933 inode->i_nlink--;
934 mark_inode_dirty(inode);
935 inode->i_ctime = dir->i_ctime;
936 retval = 0;
937
938end_unlink:
939 if (fibh.sbh != fibh.ebh)
940 udf_release_data(fibh.ebh);
941 udf_release_data(fibh.sbh);
942out:
943 unlock_kernel();
944 return retval;
945}
946
947static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * symname)
948{
949 struct inode * inode;
950 struct pathComponent *pc;
951 char *compstart;
952 struct udf_fileident_bh fibh;
953 struct buffer_head *bh = NULL;
954 int eoffset, elen = 0;
955 struct fileIdentDesc *fi;
956 struct fileIdentDesc cfi;
957 char *ea;
958 int err;
959 int block;
960 char name[UDF_NAME_LEN];
961 int namelen;
962
963 lock_kernel();
964 if (!(inode = udf_new_inode(dir, S_IFLNK, &err)))
965 goto out;
966
967 inode->i_mode = S_IFLNK | S_IRWXUGO;
968 inode->i_data.a_ops = &udf_symlink_aops;
969 inode->i_op = &page_symlink_inode_operations;
970
971 if (UDF_I_ALLOCTYPE(inode) != ICBTAG_FLAG_AD_IN_ICB)
972 {
973 struct buffer_head *bh = NULL;
974 kernel_lb_addr bloc, eloc;
975 uint32_t elen, extoffset;
976
977 block = udf_new_block(inode->i_sb, inode,
978 UDF_I_LOCATION(inode).partitionReferenceNum,
979 UDF_I_LOCATION(inode).logicalBlockNum, &err);
980 if (!block)
981 goto out_no_entry;
982 bloc = UDF_I_LOCATION(inode);
983 eloc.logicalBlockNum = block;
984 eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
985 elen = inode->i_sb->s_blocksize;
986 UDF_I_LENEXTENTS(inode) = elen;
987 extoffset = udf_file_entry_alloc_offset(inode);
988 udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 0);
989 udf_release_data(bh);
990
991 block = udf_get_pblock(inode->i_sb, block,
992 UDF_I_LOCATION(inode).partitionReferenceNum, 0);
993 bh = udf_tread(inode->i_sb, block);
994 lock_buffer(bh);
995 memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
996 set_buffer_uptodate(bh);
997 unlock_buffer(bh);
998 mark_buffer_dirty_inode(bh, inode);
999 ea = bh->b_data + udf_ext0_offset(inode);
1000 }
1001 else
1002 ea = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
1003
1004 eoffset = inode->i_sb->s_blocksize - udf_ext0_offset(inode);
1005 pc = (struct pathComponent *)ea;
1006
1007 if (*symname == '/')
1008 {
1009 do
1010 {
1011 symname++;
1012 } while (*symname == '/');
1013
1014 pc->componentType = 1;
1015 pc->lengthComponentIdent = 0;
1016 pc->componentFileVersionNum = 0;
1017 pc += sizeof(struct pathComponent);
1018 elen += sizeof(struct pathComponent);
1019 }
1020
1021 err = -ENAMETOOLONG;
1022
1023 while (*symname)
1024 {
1025 if (elen + sizeof(struct pathComponent) > eoffset)
1026 goto out_no_entry;
1027
1028 pc = (struct pathComponent *)(ea + elen);
1029
1030 compstart = (char *)symname;
1031
1032 do
1033 {
1034 symname++;
1035 } while (*symname && *symname != '/');
1036
1037 pc->componentType = 5;
1038 pc->lengthComponentIdent = 0;
1039 pc->componentFileVersionNum = 0;
1040 if (compstart[0] == '.')
1041 {
1042 if ((symname-compstart) == 1)
1043 pc->componentType = 4;
1044 else if ((symname-compstart) == 2 && compstart[1] == '.')
1045 pc->componentType = 3;
1046 }
1047
1048 if (pc->componentType == 5)
1049 {
1050 if ( !(namelen = udf_put_filename(inode->i_sb, compstart, name, symname-compstart)))
1051 goto out_no_entry;
1052
1053 if (elen + sizeof(struct pathComponent) + namelen > eoffset)
1054 goto out_no_entry;
1055 else
1056 pc->lengthComponentIdent = namelen;
1057
1058 memcpy(pc->componentIdent, name, namelen);
1059 }
1060
1061 elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
1062
1063 if (*symname)
1064 {
1065 do
1066 {
1067 symname++;
1068 } while (*symname == '/');
1069 }
1070 }
1071
1072 udf_release_data(bh);
1073 inode->i_size = elen;
1074 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
1075 UDF_I_LENALLOC(inode) = inode->i_size;
1076 mark_inode_dirty(inode);
1077
1078 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err)))
1079 goto out_no_entry;
1080 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
1081 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
1082 if (UDF_SB_LVIDBH(inode->i_sb))
1083 {
1084 struct logicalVolHeaderDesc *lvhd;
1085 uint64_t uniqueID;
1086 lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->logicalVolContentsUse);
1087 uniqueID = le64_to_cpu(lvhd->uniqueID);
1088 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
1089 cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
1090 if (!(++uniqueID & 0x00000000FFFFFFFFUL))
1091 uniqueID += 16;
1092 lvhd->uniqueID = cpu_to_le64(uniqueID);
1093 mark_buffer_dirty(UDF_SB_LVIDBH(inode->i_sb));
1094 }
1095 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
1096 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
1097 {
1098 mark_inode_dirty(dir);
1099 }
1100 if (fibh.sbh != fibh.ebh)
1101 udf_release_data(fibh.ebh);
1102 udf_release_data(fibh.sbh);
1103 d_instantiate(dentry, inode);
1104 err = 0;
1105
1106out:
1107 unlock_kernel();
1108 return err;
1109
1110out_no_entry:
1111 inode->i_nlink--;
1112 mark_inode_dirty(inode);
1113 iput(inode);
1114 goto out;
1115}
1116
1117static int udf_link(struct dentry * old_dentry, struct inode * dir,
1118 struct dentry *dentry)
1119{
1120 struct inode *inode = old_dentry->d_inode;
1121 struct udf_fileident_bh fibh;
1122 struct fileIdentDesc cfi, *fi;
1123 int err;
1124
1125 lock_kernel();
1126 if (inode->i_nlink >= (256<<sizeof(inode->i_nlink))-1)
1127 {
1128 unlock_kernel();
1129 return -EMLINK;
1130 }
1131
1132 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err)))
1133 {
1134 unlock_kernel();
1135 return err;
1136 }
1137 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
1138 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
1139 if (UDF_SB_LVIDBH(inode->i_sb))
1140 {
1141 struct logicalVolHeaderDesc *lvhd;
1142 uint64_t uniqueID;
1143 lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->logicalVolContentsUse);
1144 uniqueID = le64_to_cpu(lvhd->uniqueID);
1145 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
1146 cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
1147 if (!(++uniqueID & 0x00000000FFFFFFFFUL))
1148 uniqueID += 16;
1149 lvhd->uniqueID = cpu_to_le64(uniqueID);
1150 mark_buffer_dirty(UDF_SB_LVIDBH(inode->i_sb));
1151 }
1152 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
1153 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
1154 {
1155 mark_inode_dirty(dir);
1156 }
1157 if (fibh.sbh != fibh.ebh)
1158 udf_release_data(fibh.ebh);
1159 udf_release_data(fibh.sbh);
1160 inode->i_nlink ++;
1161 inode->i_ctime = current_fs_time(inode->i_sb);
1162 mark_inode_dirty(inode);
1163 atomic_inc(&inode->i_count);
1164 d_instantiate(dentry, inode);
1165 unlock_kernel();
1166 return 0;
1167}
1168
1169/* Anybody can rename anything with this: the permission checks are left to the
1170 * higher-level routines.
1171 */
1172static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
1173 struct inode * new_dir, struct dentry * new_dentry)
1174{
1175 struct inode * old_inode = old_dentry->d_inode;
1176 struct inode * new_inode = new_dentry->d_inode;
1177 struct udf_fileident_bh ofibh, nfibh;
1178 struct fileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL, ocfi, ncfi;
1179 struct buffer_head *dir_bh = NULL;
1180 int retval = -ENOENT;
1181 kernel_lb_addr tloc;
1182
1183 lock_kernel();
1184 if ((ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi)))
1185 {
1186 if (ofibh.sbh != ofibh.ebh)
1187 udf_release_data(ofibh.ebh);
1188 udf_release_data(ofibh.sbh);
1189 }
1190 tloc = lelb_to_cpu(ocfi.icb.extLocation);
1191 if (!ofi || udf_get_lb_pblock(old_dir->i_sb, tloc, 0)
1192 != old_inode->i_ino)
1193 goto end_rename;
1194
1195 nfi = udf_find_entry(new_dir, new_dentry, &nfibh, &ncfi);
1196 if (nfi)
1197 {
1198 if (!new_inode)
1199 {
1200 if (nfibh.sbh != nfibh.ebh)
1201 udf_release_data(nfibh.ebh);
1202 udf_release_data(nfibh.sbh);
1203 nfi = NULL;
1204 }
1205 }
1206 if (S_ISDIR(old_inode->i_mode))
1207 {
1208 uint32_t offset = udf_ext0_offset(old_inode);
1209
1210 if (new_inode)
1211 {
1212 retval = -ENOTEMPTY;
1213 if (!empty_dir(new_inode))
1214 goto end_rename;
1215 }
1216 retval = -EIO;
1217 if (UDF_I_ALLOCTYPE(old_inode) == ICBTAG_FLAG_AD_IN_ICB)
1218 {
1219 dir_fi = udf_get_fileident(UDF_I_DATA(old_inode) -
1220 (UDF_I_EFE(old_inode) ?
1221 sizeof(struct extendedFileEntry) :
1222 sizeof(struct fileEntry)),
1223 old_inode->i_sb->s_blocksize, &offset);
1224 }
1225 else
1226 {
1227 dir_bh = udf_bread(old_inode, 0, 0, &retval);
1228 if (!dir_bh)
1229 goto end_rename;
1230 dir_fi = udf_get_fileident(dir_bh->b_data, old_inode->i_sb->s_blocksize, &offset);
1231 }
1232 if (!dir_fi)
1233 goto end_rename;
1234 tloc = lelb_to_cpu(dir_fi->icb.extLocation);
1235 if (udf_get_lb_pblock(old_inode->i_sb, tloc, 0)
1236 != old_dir->i_ino)
1237 goto end_rename;
1238
1239 retval = -EMLINK;
1240 if (!new_inode && new_dir->i_nlink >= (256<<sizeof(new_dir->i_nlink))-1)
1241 goto end_rename;
1242 }
1243 if (!nfi)
1244 {
1245 nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi, &retval);
1246 if (!nfi)
1247 goto end_rename;
1248 }
1249
1250 /*
1251 * Like most other Unix systems, set the ctime for inodes on a
1252 * rename.
1253 */
1254 old_inode->i_ctime = current_fs_time(old_inode->i_sb);
1255 mark_inode_dirty(old_inode);
1256
1257 /*
1258 * ok, that's it
1259 */
1260 ncfi.fileVersionNum = ocfi.fileVersionNum;
1261 ncfi.fileCharacteristics = ocfi.fileCharacteristics;
1262 memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(long_ad));
1263 udf_write_fi(new_dir, &ncfi, nfi, &nfibh, NULL, NULL);
1264
1265 /* The old fid may have moved - find it again */
1266 ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi);
1267 udf_delete_entry(old_dir, ofi, &ofibh, &ocfi);
1268
1269 if (new_inode)
1270 {
1271 new_inode->i_nlink--;
1272 new_inode->i_ctime = current_fs_time(new_inode->i_sb);
1273 mark_inode_dirty(new_inode);
1274 }
1275 old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb);
1276 mark_inode_dirty(old_dir);
1277
1278 if (dir_fi)
1279 {
1280 dir_fi->icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(new_dir));
1281 udf_update_tag((char *)dir_fi, (sizeof(struct fileIdentDesc) +
1282 le16_to_cpu(dir_fi->lengthOfImpUse) + 3) & ~3);
1283 if (UDF_I_ALLOCTYPE(old_inode) == ICBTAG_FLAG_AD_IN_ICB)
1284 {
1285 mark_inode_dirty(old_inode);
1286 }
1287 else
1288 mark_buffer_dirty_inode(dir_bh, old_inode);
1289 old_dir->i_nlink --;
1290 mark_inode_dirty(old_dir);
1291 if (new_inode)
1292 {
1293 new_inode->i_nlink --;
1294 mark_inode_dirty(new_inode);
1295 }
1296 else
1297 {
1298 new_dir->i_nlink ++;
1299 mark_inode_dirty(new_dir);
1300 }
1301 }
1302
1303 if (ofi)
1304 {
1305 if (ofibh.sbh != ofibh.ebh)
1306 udf_release_data(ofibh.ebh);
1307 udf_release_data(ofibh.sbh);
1308 }
1309
1310 retval = 0;
1311
1312end_rename:
1313 udf_release_data(dir_bh);
1314 if (nfi)
1315 {
1316 if (nfibh.sbh != nfibh.ebh)
1317 udf_release_data(nfibh.ebh);
1318 udf_release_data(nfibh.sbh);
1319 }
1320 unlock_kernel();
1321 return retval;
1322}
1323
1324struct inode_operations udf_dir_inode_operations = {
1325 .lookup = udf_lookup,
1326 .create = udf_create,
1327 .link = udf_link,
1328 .unlink = udf_unlink,
1329 .symlink = udf_symlink,
1330 .mkdir = udf_mkdir,
1331 .rmdir = udf_rmdir,
1332 .mknod = udf_mknod,
1333 .rename = udf_rename,
1334};
diff --git a/fs/udf/osta_udf.h b/fs/udf/osta_udf.h
new file mode 100644
index 000000000000..e82aae652697
--- /dev/null
+++ b/fs/udf/osta_udf.h
@@ -0,0 +1,296 @@
1/*
2 * osta_udf.h
3 *
4 * This file is based on OSTA UDF(tm) 2.50 (April 30, 2003)
5 * http://www.osta.org
6 *
7 * Copyright (c) 2001-2004 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions, and the following disclaimer,
15 * without modification.
16 * 2. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * Alternatively, this software may be distributed under the terms of the
20 * GNU Public License ("GPL").
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
26 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#include "ecma_167.h"
36
37#ifndef _OSTA_UDF_H
38#define _OSTA_UDF_H 1
39
40/* OSTA CS0 Charspec (UDF 2.50 2.1.2) */
41#define UDF_CHAR_SET_TYPE 0
42#define UDF_CHAR_SET_INFO "OSTA Compressed Unicode"
43
44/* Entity Identifier (UDF 2.50 2.1.5) */
45/* Identifiers (UDF 2.50 2.1.5.2) */
46#define UDF_ID_DEVELOPER "*Linux UDFFS"
47#define UDF_ID_COMPLIANT "*OSTA UDF Compliant"
48#define UDF_ID_LV_INFO "*UDF LV Info"
49#define UDF_ID_FREE_EA "*UDF FreeEASpace"
50#define UDF_ID_FREE_APP_EA "*UDF FreeAppEASpace"
51#define UDF_ID_DVD_CGMS "*UDF DVD CGMS Info"
52#define UDF_ID_OS2_EA "*UDF OS/2 EA"
53#define UDF_ID_OS2_EA_LENGTH "*UDF OS/2 EALength"
54#define UDF_ID_MAC_VOLUME "*UDF Mac VolumeInfo"
55#define UDF_ID_MAC_FINDER "*UDF Mac FinderInfo"
56#define UDF_ID_MAC_UNIQUE "*UDF Mac UniqueIDTable"
57#define UDF_ID_MAC_RESOURCE "*UDF Mac ResourceFork"
58#define UDF_ID_VIRTUAL "*UDF Virtual Partition"
59#define UDF_ID_SPARABLE "*UDF Sparable Partition"
60#define UDF_ID_ALLOC "*UDF Virtual Alloc Tbl"
61#define UDF_ID_SPARING "*UDF Sparing Table"
62#define UDF_ID_METADATA "*UDF Metadata Partition"
63
64/* Identifier Suffix (UDF 2.50 2.1.5.3) */
65#define IS_DF_HARD_WRITE_PROTECT 0x01
66#define IS_DF_SOFT_WRITE_PROTECT 0x02
67
68struct UDFIdentSuffix
69{
70 __le16 UDFRevision;
71 uint8_t OSClass;
72 uint8_t OSIdentifier;
73 uint8_t reserved[4];
74} __attribute__ ((packed));
75
76struct impIdentSuffix
77{
78 uint8_t OSClass;
79 uint8_t OSIdentifier;
80 uint8_t reserved[6];
81} __attribute__ ((packed));
82
83struct appIdentSuffix
84{
85 uint8_t impUse[8];
86} __attribute__ ((packed));
87
88/* Logical Volume Integrity Descriptor (UDF 2.50 2.2.6) */
89/* Implementation Use (UDF 2.50 2.2.6.4) */
90struct logicalVolIntegrityDescImpUse
91{
92 regid impIdent;
93 __le32 numFiles;
94 __le32 numDirs;
95 __le16 minUDFReadRev;
96 __le16 minUDFWriteRev;
97 __le16 maxUDFWriteRev;
98 uint8_t impUse[0];
99} __attribute__ ((packed));
100
101/* Implementation Use Volume Descriptor (UDF 2.50 2.2.7) */
102/* Implementation Use (UDF 2.50 2.2.7.2) */
103struct impUseVolDescImpUse
104{
105 charspec LVICharset;
106 dstring logicalVolIdent[128];
107 dstring LVInfo1[36];
108 dstring LVInfo2[36];
109 dstring LVInfo3[36];
110 regid impIdent;
111 uint8_t impUse[128];
112} __attribute__ ((packed));
113
114struct udfPartitionMap2
115{
116 uint8_t partitionMapType;
117 uint8_t partitionMapLength;
118 uint8_t reserved1[2];
119 regid partIdent;
120 __le16 volSeqNum;
121 __le16 partitionNum;
122} __attribute__ ((packed));
123
124/* Virtual Partition Map (UDF 2.50 2.2.8) */
125struct virtualPartitionMap
126{
127 uint8_t partitionMapType;
128 uint8_t partitionMapLength;
129 uint8_t reserved1[2];
130 regid partIdent;
131 __le16 volSeqNum;
132 __le16 partitionNum;
133 uint8_t reserved2[24];
134} __attribute__ ((packed));
135
136/* Sparable Partition Map (UDF 2.50 2.2.9) */
137struct sparablePartitionMap
138{
139 uint8_t partitionMapType;
140 uint8_t partitionMapLength;
141 uint8_t reserved1[2];
142 regid partIdent;
143 __le16 volSeqNum;
144 __le16 partitionNum;
145 __le16 packetLength;
146 uint8_t numSparingTables;
147 uint8_t reserved2[1];
148 __le32 sizeSparingTable;
149 __le32 locSparingTable[4];
150} __attribute__ ((packed));
151
152/* Metadata Partition Map (UDF 2.4.0 2.2.10) */
153struct metadataPartitionMap
154{
155 uint8_t partitionMapType;
156 uint8_t partitionMapLength;
157 uint8_t reserved1[2];
158 regid partIdent;
159 __le16 volSeqNum;
160 __le16 partitionNum;
161 __le32 metadataFileLoc;
162 __le32 metadataMirrorFileLoc;
163 __le32 metadataBitmapFileLoc;
164 __le32 allocUnitSize;
165 __le16 alignUnitSize;
166 uint8_t flags;
167 uint8_t reserved2[5];
168} __attribute__ ((packed));
169
170/* Virtual Allocation Table (UDF 1.5 2.2.10) */
171struct virtualAllocationTable15
172{
173 __le32 VirtualSector[0];
174 regid vatIdent;
175 __le32 previousVATICBLoc;
176} __attribute__ ((packed));
177
178#define ICBTAG_FILE_TYPE_VAT15 0x00U
179
180/* Virtual Allocation Table (UDF 2.50 2.2.11) */
181struct virtualAllocationTable20
182{
183 __le16 lengthHeader;
184 __le16 lengthImpUse;
185 dstring logicalVolIdent[128];
186 __le32 previousVATICBLoc;
187 __le32 numFiles;
188 __le32 numDirs;
189 __le16 minReadRevision;
190 __le16 minWriteRevision;
191 __le16 maxWriteRevision;
192 __le16 reserved;
193 uint8_t impUse[0];
194 __le32 vatEntry[0];
195} __attribute__ ((packed));
196
197#define ICBTAG_FILE_TYPE_VAT20 0xF8U
198
199/* Sparing Table (UDF 2.50 2.2.12) */
200struct sparingEntry
201{
202 __le32 origLocation;
203 __le32 mappedLocation;
204} __attribute__ ((packed));
205
206struct sparingTable
207{
208 tag descTag;
209 regid sparingIdent;
210 __le16 reallocationTableLen;
211 __le16 reserved;
212 __le32 sequenceNum;
213 struct sparingEntry
214 mapEntry[0];
215} __attribute__ ((packed));
216
217/* Metadata File (and Metadata Mirror File) (UDF 2.50 2.2.13.1) */
218#define ICBTAG_FILE_TYPE_MAIN 0xFA
219#define ICBTAG_FILE_TYPE_MIRROR 0xFB
220#define ICBTAG_FILE_TYPE_BITMAP 0xFC
221
222/* struct long_ad ICB - ADImpUse (UDF 2.50 2.2.4.3) */
223struct allocDescImpUse
224{
225 __le16 flags;
226 uint8_t impUse[4];
227} __attribute__ ((packed));
228
229#define AD_IU_EXT_ERASED 0x0001
230
231/* Real-Time Files (UDF 2.50 6.11) */
232#define ICBTAG_FILE_TYPE_REALTIME 0xF9U
233
234/* Implementation Use Extended Attribute (UDF 2.50 3.3.4.5) */
235/* FreeEASpace (UDF 2.50 3.3.4.5.1.1) */
236struct freeEaSpace
237{
238 __le16 headerChecksum;
239 uint8_t freeEASpace[0];
240} __attribute__ ((packed));
241
242/* DVD Copyright Management Information (UDF 2.50 3.3.4.5.1.2) */
243struct DVDCopyrightImpUse
244{
245 __le16 headerChecksum;
246 uint8_t CGMSInfo;
247 uint8_t dataType;
248 uint8_t protectionSystemInfo[4];
249} __attribute__ ((packed));
250
251/* Application Use Extended Attribute (UDF 2.50 3.3.4.6) */
252/* FreeAppEASpace (UDF 2.50 3.3.4.6.1) */
253struct freeAppEASpace
254{
255 __le16 headerChecksum;
256 uint8_t freeEASpace[0];
257} __attribute__ ((packed));
258
259/* UDF Defined System Stream (UDF 2.50 3.3.7) */
260#define UDF_ID_UNIQUE_ID "*UDF Unique ID Mapping Data"
261#define UDF_ID_NON_ALLOC "*UDF Non-Allocatable Space"
262#define UDF_ID_POWER_CAL "*UDF Power Cal Table"
263#define UDF_ID_BACKUP "*UDF Backup"
264
265/* Operating System Identifiers (UDF 2.50 6.3) */
266#define UDF_OS_CLASS_UNDEF 0x00U
267#define UDF_OS_CLASS_DOS 0x01U
268#define UDF_OS_CLASS_OS2 0x02U
269#define UDF_OS_CLASS_MAC 0x03U
270#define UDF_OS_CLASS_UNIX 0x04U
271#define UDF_OS_CLASS_WIN9X 0x05U
272#define UDF_OS_CLASS_WINNT 0x06U
273#define UDF_OS_CLASS_OS400 0x07U
274#define UDF_OS_CLASS_BEOS 0x08U
275#define UDF_OS_CLASS_WINCE 0x09U
276
277#define UDF_OS_ID_UNDEF 0x00U
278#define UDF_OS_ID_DOS 0x00U
279#define UDF_OS_ID_OS2 0x00U
280#define UDF_OS_ID_MAC 0x00U
281#define UDF_OS_ID_MAX_OSX 0x01U
282#define UDF_OS_ID_UNIX 0x00U
283#define UDF_OS_ID_AIX 0x01U
284#define UDF_OS_ID_SOLARIS 0x02U
285#define UDF_OS_ID_HPUX 0x03U
286#define UDF_OS_ID_IRIX 0x04U
287#define UDF_OS_ID_LINUX 0x05U
288#define UDF_OS_ID_MKLINUX 0x06U
289#define UDF_OS_ID_FREEBSD 0x07U
290#define UDF_OS_ID_WIN9X 0x00U
291#define UDF_OS_ID_WINNT 0x00U
292#define UDF_OS_ID_OS400 0x00U
293#define UDF_OS_ID_BEOS 0x00U
294#define UDF_OS_ID_WINCE 0x00U
295
296#endif /* _OSTA_UDF_H */
diff --git a/fs/udf/partition.c b/fs/udf/partition.c
new file mode 100644
index 000000000000..4d36f264be0d
--- /dev/null
+++ b/fs/udf/partition.c
@@ -0,0 +1,226 @@
1/*
2 * partition.c
3 *
4 * PURPOSE
5 * Partition handling routines for the OSTA-UDF(tm) filesystem.
6 *
7 * CONTACTS
8 * E-mail regarding any portion of the Linux UDF file system should be
9 * directed to the development team mailing list (run by majordomo):
10 * linux_udf@hpesjro.fc.hp.com
11 *
12 * COPYRIGHT
13 * This file is distributed under the terms of the GNU General Public
14 * License (GPL). Copies of the GPL can be obtained from:
15 * ftp://prep.ai.mit.edu/pub/gnu/GPL
16 * Each contributing author retains all rights to their own work.
17 *
18 * (C) 1998-2001 Ben Fennema
19 *
20 * HISTORY
21 *
22 * 12/06/98 blf Created file.
23 *
24 */
25
26#include "udfdecl.h"
27#include "udf_sb.h"
28#include "udf_i.h"
29
30#include <linux/fs.h>
31#include <linux/string.h>
32#include <linux/udf_fs.h>
33#include <linux/slab.h>
34#include <linux/buffer_head.h>
35
36inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset)
37{
38 if (partition >= UDF_SB_NUMPARTS(sb))
39 {
40 udf_debug("block=%d, partition=%d, offset=%d: invalid partition\n",
41 block, partition, offset);
42 return 0xFFFFFFFF;
43 }
44 if (UDF_SB_PARTFUNC(sb, partition))
45 return UDF_SB_PARTFUNC(sb, partition)(sb, block, partition, offset);
46 else
47 return UDF_SB_PARTROOT(sb, partition) + block + offset;
48}
49
50uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset)
51{
52 struct buffer_head *bh = NULL;
53 uint32_t newblock;
54 uint32_t index;
55 uint32_t loc;
56
57 index = (sb->s_blocksize - UDF_SB_TYPEVIRT(sb,partition).s_start_offset) / sizeof(uint32_t);
58
59 if (block > UDF_SB_TYPEVIRT(sb,partition).s_num_entries)
60 {
61 udf_debug("Trying to access block beyond end of VAT (%d max %d)\n",
62 block, UDF_SB_TYPEVIRT(sb,partition).s_num_entries);
63 return 0xFFFFFFFF;
64 }
65
66 if (block >= index)
67 {
68 block -= index;
69 newblock = 1 + (block / (sb->s_blocksize / sizeof(uint32_t)));
70 index = block % (sb->s_blocksize / sizeof(uint32_t));
71 }
72 else
73 {
74 newblock = 0;
75 index = UDF_SB_TYPEVIRT(sb,partition).s_start_offset / sizeof(uint32_t) + block;
76 }
77
78 loc = udf_block_map(UDF_SB_VAT(sb), newblock);
79
80 if (!(bh = sb_bread(sb, loc)))
81 {
82 udf_debug("get_pblock(UDF_VIRTUAL_MAP:%p,%d,%d) VAT: %d[%d]\n",
83 sb, block, partition, loc, index);
84 return 0xFFFFFFFF;
85 }
86
87 loc = le32_to_cpu(((__le32 *)bh->b_data)[index]);
88
89 udf_release_data(bh);
90
91 if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition)
92 {
93 udf_debug("recursive call to udf_get_pblock!\n");
94 return 0xFFFFFFFF;
95 }
96
97 return udf_get_pblock(sb, loc, UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum, offset);
98}
99
100inline uint32_t udf_get_pblock_virt20(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset)
101{
102 return udf_get_pblock_virt15(sb, block, partition, offset);
103}
104
105uint32_t udf_get_pblock_spar15(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset)
106{
107 int i;
108 struct sparingTable *st = NULL;
109 uint32_t packet = (block + offset) & ~(UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1);
110
111 for (i=0; i<4; i++)
112 {
113 if (UDF_SB_TYPESPAR(sb,partition).s_spar_map[i] != NULL)
114 {
115 st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,partition).s_spar_map[i]->b_data;
116 break;
117 }
118 }
119
120 if (st)
121 {
122 for (i=0; i<le16_to_cpu(st->reallocationTableLen); i++)
123 {
124 if (le32_to_cpu(st->mapEntry[i].origLocation) >= 0xFFFFFFF0)
125 break;
126 else if (le32_to_cpu(st->mapEntry[i].origLocation) == packet)
127 {
128 return le32_to_cpu(st->mapEntry[i].mappedLocation) +
129 ((block + offset) & (UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1));
130 }
131 else if (le32_to_cpu(st->mapEntry[i].origLocation) > packet)
132 break;
133 }
134 }
135 return UDF_SB_PARTROOT(sb,partition) + block + offset;
136}
137
138int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
139{
140 struct udf_sparing_data *sdata;
141 struct sparingTable *st = NULL;
142 struct sparingEntry mapEntry;
143 uint32_t packet;
144 int i, j, k, l;
145
146 for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
147 {
148 if (old_block > UDF_SB_PARTROOT(sb,i) &&
149 old_block < UDF_SB_PARTROOT(sb,i) + UDF_SB_PARTLEN(sb,i))
150 {
151 sdata = &UDF_SB_TYPESPAR(sb,i);
152 packet = (old_block - UDF_SB_PARTROOT(sb,i)) & ~(sdata->s_packet_len - 1);
153
154 for (j=0; j<4; j++)
155 {
156 if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL)
157 {
158 st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
159 break;
160 }
161 }
162
163 if (!st)
164 return 1;
165
166 for (k=0; k<le16_to_cpu(st->reallocationTableLen); k++)
167 {
168 if (le32_to_cpu(st->mapEntry[k].origLocation) == 0xFFFFFFFF)
169 {
170 for (; j<4; j++)
171 {
172 if (sdata->s_spar_map[j])
173 {
174 st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
175 st->mapEntry[k].origLocation = cpu_to_le32(packet);
176 udf_update_tag((char *)st, sizeof(struct sparingTable) + le16_to_cpu(st->reallocationTableLen) * sizeof(struct sparingEntry));
177 mark_buffer_dirty(sdata->s_spar_map[j]);
178 }
179 }
180 *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
181 ((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
182 return 0;
183 }
184 else if (le32_to_cpu(st->mapEntry[k].origLocation) == packet)
185 {
186 *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
187 ((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
188 return 0;
189 }
190 else if (le32_to_cpu(st->mapEntry[k].origLocation) > packet)
191 break;
192 }
193 for (l=k; l<le16_to_cpu(st->reallocationTableLen); l++)
194 {
195 if (le32_to_cpu(st->mapEntry[l].origLocation) == 0xFFFFFFFF)
196 {
197 for (; j<4; j++)
198 {
199 if (sdata->s_spar_map[j])
200 {
201 st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
202 mapEntry = st->mapEntry[l];
203 mapEntry.origLocation = cpu_to_le32(packet);
204 memmove(&st->mapEntry[k+1], &st->mapEntry[k], (l-k)*sizeof(struct sparingEntry));
205 st->mapEntry[k] = mapEntry;
206 udf_update_tag((char *)st, sizeof(struct sparingTable) + le16_to_cpu(st->reallocationTableLen) * sizeof(struct sparingEntry));
207 mark_buffer_dirty(sdata->s_spar_map[j]);
208 }
209 }
210 *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
211 ((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
212 return 0;
213 }
214 }
215 return 1;
216 }
217 }
218 if (i == UDF_SB_NUMPARTS(sb))
219 {
220 /* outside of partitions */
221 /* for now, fail =) */
222 return 1;
223 }
224
225 return 0;
226}
diff --git a/fs/udf/super.c b/fs/udf/super.c
new file mode 100644
index 000000000000..15bd4f24c5b7
--- /dev/null
+++ b/fs/udf/super.c
@@ -0,0 +1,1934 @@
1/*
2 * super.c
3 *
4 * PURPOSE
5 * Super block routines for the OSTA-UDF(tm) filesystem.
6 *
7 * DESCRIPTION
8 * OSTA-UDF(tm) = Optical Storage Technology Association
9 * Universal Disk Format.
10 *
11 * This code is based on version 2.00 of the UDF specification,
12 * and revision 3 of the ECMA 167 standard [equivalent to ISO 13346].
13 * http://www.osta.org/
14 * http://www.ecma.ch/
15 * http://www.iso.org/
16 *
17 * CONTACTS
18 * E-mail regarding any portion of the Linux UDF file system should be
19 * directed to the development team mailing list (run by majordomo):
20 * linux_udf@hpesjro.fc.hp.com
21 *
22 * COPYRIGHT
23 * This file is distributed under the terms of the GNU General Public
24 * License (GPL). Copies of the GPL can be obtained from:
25 * ftp://prep.ai.mit.edu/pub/gnu/GPL
26 * Each contributing author retains all rights to their own work.
27 *
28 * (C) 1998 Dave Boynton
29 * (C) 1998-2004 Ben Fennema
30 * (C) 2000 Stelias Computing Inc
31 *
32 * HISTORY
33 *
34 * 09/24/98 dgb changed to allow compiling outside of kernel, and
35 * added some debugging.
36 * 10/01/98 dgb updated to allow (some) possibility of compiling w/2.0.34
37 * 10/16/98 attempting some multi-session support
38 * 10/17/98 added freespace count for "df"
39 * 11/11/98 gr added novrs option
40 * 11/26/98 dgb added fileset,anchor mount options
41 * 12/06/98 blf really hosed things royally. vat/sparing support. sequenced vol descs
42 * rewrote option handling based on isofs
43 * 12/20/98 find the free space bitmap (if it exists)
44 */
45
46#include "udfdecl.h"
47
48#include <linux/config.h>
49#include <linux/blkdev.h>
50#include <linux/slab.h>
51#include <linux/kernel.h>
52#include <linux/module.h>
53#include <linux/parser.h>
54#include <linux/stat.h>
55#include <linux/cdrom.h>
56#include <linux/nls.h>
57#include <linux/smp_lock.h>
58#include <linux/buffer_head.h>
59#include <linux/vfs.h>
60#include <linux/vmalloc.h>
61#include <asm/byteorder.h>
62
63#include <linux/udf_fs.h>
64#include "udf_sb.h"
65#include "udf_i.h"
66
67#include <linux/init.h>
68#include <asm/uaccess.h>
69
70#define VDS_POS_PRIMARY_VOL_DESC 0
71#define VDS_POS_UNALLOC_SPACE_DESC 1
72#define VDS_POS_LOGICAL_VOL_DESC 2
73#define VDS_POS_PARTITION_DESC 3
74#define VDS_POS_IMP_USE_VOL_DESC 4
75#define VDS_POS_VOL_DESC_PTR 5
76#define VDS_POS_TERMINATING_DESC 6
77#define VDS_POS_LENGTH 7
78
79static char error_buf[1024];
80
81/* These are the "meat" - everything else is stuffing */
82static int udf_fill_super(struct super_block *, void *, int);
83static void udf_put_super(struct super_block *);
84static void udf_write_super(struct super_block *);
85static int udf_remount_fs(struct super_block *, int *, char *);
86static int udf_check_valid(struct super_block *, int, int);
87static int udf_vrs(struct super_block *sb, int silent);
88static int udf_load_partition(struct super_block *, kernel_lb_addr *);
89static int udf_load_logicalvol(struct super_block *, struct buffer_head *, kernel_lb_addr *);
90static void udf_load_logicalvolint(struct super_block *, kernel_extent_ad);
91static void udf_find_anchor(struct super_block *);
92static int udf_find_fileset(struct super_block *, kernel_lb_addr *, kernel_lb_addr *);
93static void udf_load_pvoldesc(struct super_block *, struct buffer_head *);
94static void udf_load_fileset(struct super_block *, struct buffer_head *, kernel_lb_addr *);
95static void udf_load_partdesc(struct super_block *, struct buffer_head *);
96static void udf_open_lvid(struct super_block *);
97static void udf_close_lvid(struct super_block *);
98static unsigned int udf_count_free(struct super_block *);
99static int udf_statfs(struct super_block *, struct kstatfs *);
100
101/* UDF filesystem type */
102static struct super_block *udf_get_sb(struct file_system_type *fs_type,
103 int flags, const char *dev_name, void *data)
104{
105 return get_sb_bdev(fs_type, flags, dev_name, data, udf_fill_super);
106}
107
108static struct file_system_type udf_fstype = {
109 .owner = THIS_MODULE,
110 .name = "udf",
111 .get_sb = udf_get_sb,
112 .kill_sb = kill_block_super,
113 .fs_flags = FS_REQUIRES_DEV,
114};
115
116static kmem_cache_t * udf_inode_cachep;
117
118static struct inode *udf_alloc_inode(struct super_block *sb)
119{
120 struct udf_inode_info *ei;
121 ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep, SLAB_KERNEL);
122 if (!ei)
123 return NULL;
124 return &ei->vfs_inode;
125}
126
127static void udf_destroy_inode(struct inode *inode)
128{
129 kmem_cache_free(udf_inode_cachep, UDF_I(inode));
130}
131
132static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
133{
134 struct udf_inode_info *ei = (struct udf_inode_info *) foo;
135
136 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
137 SLAB_CTOR_CONSTRUCTOR)
138 {
139 ei->i_ext.i_data = NULL;
140 inode_init_once(&ei->vfs_inode);
141 }
142}
143
144static int init_inodecache(void)
145{
146 udf_inode_cachep = kmem_cache_create("udf_inode_cache",
147 sizeof(struct udf_inode_info),
148 0, SLAB_RECLAIM_ACCOUNT,
149 init_once, NULL);
150 if (udf_inode_cachep == NULL)
151 return -ENOMEM;
152 return 0;
153}
154
155static void destroy_inodecache(void)
156{
157 if (kmem_cache_destroy(udf_inode_cachep))
158 printk(KERN_INFO "udf_inode_cache: not all structures were freed\n");
159}
160
161/* Superblock operations */
162static struct super_operations udf_sb_ops = {
163 .alloc_inode = udf_alloc_inode,
164 .destroy_inode = udf_destroy_inode,
165 .write_inode = udf_write_inode,
166 .delete_inode = udf_delete_inode,
167 .clear_inode = udf_clear_inode,
168 .put_super = udf_put_super,
169 .write_super = udf_write_super,
170 .statfs = udf_statfs,
171 .remount_fs = udf_remount_fs,
172};
173
174struct udf_options
175{
176 unsigned char novrs;
177 unsigned int blocksize;
178 unsigned int session;
179 unsigned int lastblock;
180 unsigned int anchor;
181 unsigned int volume;
182 unsigned short partition;
183 unsigned int fileset;
184 unsigned int rootdir;
185 unsigned int flags;
186 mode_t umask;
187 gid_t gid;
188 uid_t uid;
189 struct nls_table *nls_map;
190};
191
192static int __init init_udf_fs(void)
193{
194 int err;
195 err = init_inodecache();
196 if (err)
197 goto out1;
198 err = register_filesystem(&udf_fstype);
199 if (err)
200 goto out;
201 return 0;
202out:
203 destroy_inodecache();
204out1:
205 return err;
206}
207
208static void __exit exit_udf_fs(void)
209{
210 unregister_filesystem(&udf_fstype);
211 destroy_inodecache();
212}
213
214module_init(init_udf_fs)
215module_exit(exit_udf_fs)
216
217/*
218 * udf_parse_options
219 *
220 * PURPOSE
221 * Parse mount options.
222 *
223 * DESCRIPTION
224 * The following mount options are supported:
225 *
226 * gid= Set the default group.
227 * umask= Set the default umask.
228 * uid= Set the default user.
229 * bs= Set the block size.
230 * unhide Show otherwise hidden files.
231 * undelete Show deleted files in lists.
232 * adinicb Embed data in the inode (default)
233 * noadinicb Don't embed data in the inode
234 * shortad Use short ad's
235 * longad Use long ad's (default)
236 * nostrict Unset strict conformance
237 * iocharset= Set the NLS character set
238 *
239 * The remaining are for debugging and disaster recovery:
240 *
241 * novrs Skip volume sequence recognition
242 *
243 * The following expect a offset from 0.
244 *
245 * session= Set the CDROM session (default= last session)
246 * anchor= Override standard anchor location. (default= 256)
247 * volume= Override the VolumeDesc location. (unused)
248 * partition= Override the PartitionDesc location. (unused)
249 * lastblock= Set the last block of the filesystem/
250 *
251 * The following expect a offset from the partition root.
252 *
253 * fileset= Override the fileset block location. (unused)
254 * rootdir= Override the root directory location. (unused)
255 * WARNING: overriding the rootdir to a non-directory may
256 * yield highly unpredictable results.
257 *
258 * PRE-CONDITIONS
259 * options Pointer to mount options string.
260 * uopts Pointer to mount options variable.
261 *
262 * POST-CONDITIONS
263 * <return> 1 Mount options parsed okay.
264 * <return> 0 Error parsing mount options.
265 *
266 * HISTORY
267 * July 1, 1997 - Andrew E. Mileski
268 * Written, tested, and released.
269 */
270
271enum {
272 Opt_novrs, Opt_nostrict, Opt_bs, Opt_unhide, Opt_undelete,
273 Opt_noadinicb, Opt_adinicb, Opt_shortad, Opt_longad,
274 Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
275 Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
276 Opt_rootdir, Opt_utf8, Opt_iocharset,
277 Opt_err
278};
279
280static match_table_t tokens = {
281 {Opt_novrs, "novrs"},
282 {Opt_nostrict, "nostrict"},
283 {Opt_bs, "bs=%u"},
284 {Opt_unhide, "unhide"},
285 {Opt_undelete, "undelete"},
286 {Opt_noadinicb, "noadinicb"},
287 {Opt_adinicb, "adinicb"},
288 {Opt_shortad, "shortad"},
289 {Opt_longad, "longad"},
290 {Opt_gid, "gid=%u"},
291 {Opt_uid, "uid=%u"},
292 {Opt_umask, "umask=%o"},
293 {Opt_session, "session=%u"},
294 {Opt_lastblock, "lastblock=%u"},
295 {Opt_anchor, "anchor=%u"},
296 {Opt_volume, "volume=%u"},
297 {Opt_partition, "partition=%u"},
298 {Opt_fileset, "fileset=%u"},
299 {Opt_rootdir, "rootdir=%u"},
300 {Opt_utf8, "utf8"},
301 {Opt_iocharset, "iocharset=%s"},
302 {Opt_err, NULL}
303};
304
305static int
306udf_parse_options(char *options, struct udf_options *uopt)
307{
308 char *p;
309 int option;
310
311 uopt->novrs = 0;
312 uopt->blocksize = 2048;
313 uopt->partition = 0xFFFF;
314 uopt->session = 0xFFFFFFFF;
315 uopt->lastblock = 0;
316 uopt->anchor = 0;
317 uopt->volume = 0xFFFFFFFF;
318 uopt->rootdir = 0xFFFFFFFF;
319 uopt->fileset = 0xFFFFFFFF;
320 uopt->nls_map = NULL;
321
322 if (!options)
323 return 1;
324
325 while ((p = strsep(&options, ",")) != NULL)
326 {
327 substring_t args[MAX_OPT_ARGS];
328 int token;
329 if (!*p)
330 continue;
331
332 token = match_token(p, tokens, args);
333 switch (token)
334 {
335 case Opt_novrs:
336 uopt->novrs = 1;
337 case Opt_bs:
338 if (match_int(&args[0], &option))
339 return 0;
340 uopt->blocksize = option;
341 break;
342 case Opt_unhide:
343 uopt->flags |= (1 << UDF_FLAG_UNHIDE);
344 break;
345 case Opt_undelete:
346 uopt->flags |= (1 << UDF_FLAG_UNDELETE);
347 break;
348 case Opt_noadinicb:
349 uopt->flags &= ~(1 << UDF_FLAG_USE_AD_IN_ICB);
350 break;
351 case Opt_adinicb:
352 uopt->flags |= (1 << UDF_FLAG_USE_AD_IN_ICB);
353 break;
354 case Opt_shortad:
355 uopt->flags |= (1 << UDF_FLAG_USE_SHORT_AD);
356 break;
357 case Opt_longad:
358 uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD);
359 break;
360 case Opt_gid:
361 if (match_int(args, &option))
362 return 0;
363 uopt->gid = option;
364 break;
365 case Opt_uid:
366 if (match_int(args, &option))
367 return 0;
368 uopt->uid = option;
369 break;
370 case Opt_umask:
371 if (match_octal(args, &option))
372 return 0;
373 uopt->umask = option;
374 break;
375 case Opt_nostrict:
376 uopt->flags &= ~(1 << UDF_FLAG_STRICT);
377 break;
378 case Opt_session:
379 if (match_int(args, &option))
380 return 0;
381 uopt->session = option;
382 break;
383 case Opt_lastblock:
384 if (match_int(args, &option))
385 return 0;
386 uopt->lastblock = option;
387 break;
388 case Opt_anchor:
389 if (match_int(args, &option))
390 return 0;
391 uopt->anchor = option;
392 break;
393 case Opt_volume:
394 if (match_int(args, &option))
395 return 0;
396 uopt->volume = option;
397 break;
398 case Opt_partition:
399 if (match_int(args, &option))
400 return 0;
401 uopt->partition = option;
402 break;
403 case Opt_fileset:
404 if (match_int(args, &option))
405 return 0;
406 uopt->fileset = option;
407 break;
408 case Opt_rootdir:
409 if (match_int(args, &option))
410 return 0;
411 uopt->rootdir = option;
412 break;
413 case Opt_utf8:
414 uopt->flags |= (1 << UDF_FLAG_UTF8);
415 break;
416#ifdef CONFIG_UDF_NLS
417 case Opt_iocharset:
418 uopt->nls_map = load_nls(args[0].from);
419 uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
420 break;
421#endif
422 default:
423 printk(KERN_ERR "udf: bad mount option \"%s\" "
424 "or missing value\n", p);
425 return 0;
426 }
427 }
428 return 1;
429}
430
431void
432udf_write_super(struct super_block *sb)
433{
434 lock_kernel();
435 if (!(sb->s_flags & MS_RDONLY))
436 udf_open_lvid(sb);
437 sb->s_dirt = 0;
438 unlock_kernel();
439}
440
441static int
442udf_remount_fs(struct super_block *sb, int *flags, char *options)
443{
444 struct udf_options uopt;
445
446 uopt.flags = UDF_SB(sb)->s_flags ;
447 uopt.uid = UDF_SB(sb)->s_uid ;
448 uopt.gid = UDF_SB(sb)->s_gid ;
449 uopt.umask = UDF_SB(sb)->s_umask ;
450
451 if ( !udf_parse_options(options, &uopt) )
452 return -EINVAL;
453
454 UDF_SB(sb)->s_flags = uopt.flags;
455 UDF_SB(sb)->s_uid = uopt.uid;
456 UDF_SB(sb)->s_gid = uopt.gid;
457 UDF_SB(sb)->s_umask = uopt.umask;
458
459 if (UDF_SB_LVIDBH(sb)) {
460 int write_rev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev);
461 if (write_rev > UDF_MAX_WRITE_VERSION)
462 *flags |= MS_RDONLY;
463 }
464
465 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
466 return 0;
467 if (*flags & MS_RDONLY)
468 udf_close_lvid(sb);
469 else
470 udf_open_lvid(sb);
471
472 return 0;
473}
474
475/*
476 * udf_set_blocksize
477 *
478 * PURPOSE
479 * Set the block size to be used in all transfers.
480 *
481 * DESCRIPTION
482 * To allow room for a DMA transfer, it is best to guess big when unsure.
483 * This routine picks 2048 bytes as the blocksize when guessing. This
484 * should be adequate until devices with larger block sizes become common.
485 *
486 * Note that the Linux kernel can currently only deal with blocksizes of
487 * 512, 1024, 2048, 4096, and 8192 bytes.
488 *
489 * PRE-CONDITIONS
490 * sb Pointer to _locked_ superblock.
491 *
492 * POST-CONDITIONS
493 * sb->s_blocksize Blocksize.
494 * sb->s_blocksize_bits log2 of blocksize.
495 * <return> 0 Blocksize is valid.
496 * <return> 1 Blocksize is invalid.
497 *
498 * HISTORY
499 * July 1, 1997 - Andrew E. Mileski
500 * Written, tested, and released.
501 */
502static int
503udf_set_blocksize(struct super_block *sb, int bsize)
504{
505 if (!sb_min_blocksize(sb, bsize)) {
506 udf_debug("Bad block size (%d)\n", bsize);
507 printk(KERN_ERR "udf: bad block size (%d)\n", bsize);
508 return 0;
509 }
510 return sb->s_blocksize;
511}
512
513static int
514udf_vrs(struct super_block *sb, int silent)
515{
516 struct volStructDesc *vsd = NULL;
517 int sector = 32768;
518 int sectorsize;
519 struct buffer_head *bh = NULL;
520 int iso9660=0;
521 int nsr02=0;
522 int nsr03=0;
523
524 /* Block size must be a multiple of 512 */
525 if (sb->s_blocksize & 511)
526 return 0;
527
528 if (sb->s_blocksize < sizeof(struct volStructDesc))
529 sectorsize = sizeof(struct volStructDesc);
530 else
531 sectorsize = sb->s_blocksize;
532
533 sector += (UDF_SB_SESSION(sb) << sb->s_blocksize_bits);
534
535 udf_debug("Starting at sector %u (%ld byte sectors)\n",
536 (sector >> sb->s_blocksize_bits), sb->s_blocksize);
537 /* Process the sequence (if applicable) */
538 for (;!nsr02 && !nsr03; sector += sectorsize)
539 {
540 /* Read a block */
541 bh = udf_tread(sb, sector >> sb->s_blocksize_bits);
542 if (!bh)
543 break;
544
545 /* Look for ISO descriptors */
546 vsd = (struct volStructDesc *)(bh->b_data +
547 (sector & (sb->s_blocksize - 1)));
548
549 if (vsd->stdIdent[0] == 0)
550 {
551 udf_release_data(bh);
552 break;
553 }
554 else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN))
555 {
556 iso9660 = sector;
557 switch (vsd->structType)
558 {
559 case 0:
560 udf_debug("ISO9660 Boot Record found\n");
561 break;
562 case 1:
563 udf_debug("ISO9660 Primary Volume Descriptor found\n");
564 break;
565 case 2:
566 udf_debug("ISO9660 Supplementary Volume Descriptor found\n");
567 break;
568 case 3:
569 udf_debug("ISO9660 Volume Partition Descriptor found\n");
570 break;
571 case 255:
572 udf_debug("ISO9660 Volume Descriptor Set Terminator found\n");
573 break;
574 default:
575 udf_debug("ISO9660 VRS (%u) found\n", vsd->structType);
576 break;
577 }
578 }
579 else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN))
580 {
581 }
582 else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN))
583 {
584 udf_release_data(bh);
585 break;
586 }
587 else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN))
588 {
589 nsr02 = sector;
590 }
591 else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN))
592 {
593 nsr03 = sector;
594 }
595 udf_release_data(bh);
596 }
597
598 if (nsr03)
599 return nsr03;
600 else if (nsr02)
601 return nsr02;
602 else if (sector - (UDF_SB_SESSION(sb) << sb->s_blocksize_bits) == 32768)
603 return -1;
604 else
605 return 0;
606}
607
608/*
609 * udf_find_anchor
610 *
611 * PURPOSE
612 * Find an anchor volume descriptor.
613 *
614 * PRE-CONDITIONS
615 * sb Pointer to _locked_ superblock.
616 * lastblock Last block on media.
617 *
618 * POST-CONDITIONS
619 * <return> 1 if not found, 0 if ok
620 *
621 * HISTORY
622 * July 1, 1997 - Andrew E. Mileski
623 * Written, tested, and released.
624 */
625static void
626udf_find_anchor(struct super_block *sb)
627{
628 int lastblock = UDF_SB_LASTBLOCK(sb);
629 struct buffer_head *bh = NULL;
630 uint16_t ident;
631 uint32_t location;
632 int i;
633
634 if (lastblock)
635 {
636 int varlastblock = udf_variable_to_fixed(lastblock);
637 int last[] = { lastblock, lastblock - 2,
638 lastblock - 150, lastblock - 152,
639 varlastblock, varlastblock - 2,
640 varlastblock - 150, varlastblock - 152 };
641
642 lastblock = 0;
643
644 /* Search for an anchor volume descriptor pointer */
645
646 /* according to spec, anchor is in either:
647 * block 256
648 * lastblock-256
649 * lastblock
650 * however, if the disc isn't closed, it could be 512 */
651
652 for (i=0; (!lastblock && i<sizeof(last)/sizeof(int)); i++)
653 {
654 if (last[i] < 0 || !(bh = sb_bread(sb, last[i])))
655 {
656 ident = location = 0;
657 }
658 else
659 {
660 ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
661 location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
662 udf_release_data(bh);
663 }
664
665 if (ident == TAG_IDENT_AVDP)
666 {
667 if (location == last[i] - UDF_SB_SESSION(sb))
668 {
669 lastblock = UDF_SB_ANCHOR(sb)[0] = last[i] - UDF_SB_SESSION(sb);
670 UDF_SB_ANCHOR(sb)[1] = last[i] - 256 - UDF_SB_SESSION(sb);
671 }
672 else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb))
673 {
674 UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
675 lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb);
676 UDF_SB_ANCHOR(sb)[1] = lastblock - 256 - UDF_SB_SESSION(sb);
677 }
678 else
679 udf_debug("Anchor found at block %d, location mismatch %d.\n",
680 last[i], location);
681 }
682 else if (ident == TAG_IDENT_FE || ident == TAG_IDENT_EFE)
683 {
684 lastblock = last[i];
685 UDF_SB_ANCHOR(sb)[3] = 512;
686 }
687 else
688 {
689 if (last[i] < 256 || !(bh = sb_bread(sb, last[i] - 256)))
690 {
691 ident = location = 0;
692 }
693 else
694 {
695 ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
696 location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
697 udf_release_data(bh);
698 }
699
700 if (ident == TAG_IDENT_AVDP &&
701 location == last[i] - 256 - UDF_SB_SESSION(sb))
702 {
703 lastblock = last[i];
704 UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
705 }
706 else
707 {
708 if (last[i] < 312 + UDF_SB_SESSION(sb) || !(bh = sb_bread(sb, last[i] - 312 - UDF_SB_SESSION(sb))))
709 {
710 ident = location = 0;
711 }
712 else
713 {
714 ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
715 location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
716 udf_release_data(bh);
717 }
718
719 if (ident == TAG_IDENT_AVDP &&
720 location == udf_variable_to_fixed(last[i]) - 256)
721 {
722 UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
723 lastblock = udf_variable_to_fixed(last[i]);
724 UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
725 }
726 }
727 }
728 }
729 }
730
731 if (!lastblock)
732 {
733 /* We havn't found the lastblock. check 312 */
734 if ((bh = sb_bread(sb, 312 + UDF_SB_SESSION(sb))))
735 {
736 ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
737 location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
738 udf_release_data(bh);
739
740 if (ident == TAG_IDENT_AVDP && location == 256)
741 UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
742 }
743 }
744
745 for (i=0; i<sizeof(UDF_SB_ANCHOR(sb))/sizeof(int); i++)
746 {
747 if (UDF_SB_ANCHOR(sb)[i])
748 {
749 if (!(bh = udf_read_tagged(sb,
750 UDF_SB_ANCHOR(sb)[i], UDF_SB_ANCHOR(sb)[i], &ident)))
751 {
752 UDF_SB_ANCHOR(sb)[i] = 0;
753 }
754 else
755 {
756 udf_release_data(bh);
757 if ((ident != TAG_IDENT_AVDP) && (i ||
758 (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE)))
759 {
760 UDF_SB_ANCHOR(sb)[i] = 0;
761 }
762 }
763 }
764 }
765
766 UDF_SB_LASTBLOCK(sb) = lastblock;
767}
768
769static int
770udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr *root)
771{
772 struct buffer_head *bh = NULL;
773 long lastblock;
774 uint16_t ident;
775
776 if (fileset->logicalBlockNum != 0xFFFFFFFF ||
777 fileset->partitionReferenceNum != 0xFFFF)
778 {
779 bh = udf_read_ptagged(sb, *fileset, 0, &ident);
780
781 if (!bh)
782 return 1;
783 else if (ident != TAG_IDENT_FSD)
784 {
785 udf_release_data(bh);
786 return 1;
787 }
788
789 }
790
791 if (!bh) /* Search backwards through the partitions */
792 {
793 kernel_lb_addr newfileset;
794
795 return 1;
796
797 for (newfileset.partitionReferenceNum=UDF_SB_NUMPARTS(sb)-1;
798 (newfileset.partitionReferenceNum != 0xFFFF &&
799 fileset->logicalBlockNum == 0xFFFFFFFF &&
800 fileset->partitionReferenceNum == 0xFFFF);
801 newfileset.partitionReferenceNum--)
802 {
803 lastblock = UDF_SB_PARTLEN(sb, newfileset.partitionReferenceNum);
804 newfileset.logicalBlockNum = 0;
805
806 do
807 {
808 bh = udf_read_ptagged(sb, newfileset, 0, &ident);
809 if (!bh)
810 {
811 newfileset.logicalBlockNum ++;
812 continue;
813 }
814
815 switch (ident)
816 {
817 case TAG_IDENT_SBD:
818 {
819 struct spaceBitmapDesc *sp;
820 sp = (struct spaceBitmapDesc *)bh->b_data;
821 newfileset.logicalBlockNum += 1 +
822 ((le32_to_cpu(sp->numOfBytes) + sizeof(struct spaceBitmapDesc) - 1)
823 >> sb->s_blocksize_bits);
824 udf_release_data(bh);
825 break;
826 }
827 case TAG_IDENT_FSD:
828 {
829 *fileset = newfileset;
830 break;
831 }
832 default:
833 {
834 newfileset.logicalBlockNum ++;
835 udf_release_data(bh);
836 bh = NULL;
837 break;
838 }
839 }
840 }
841 while (newfileset.logicalBlockNum < lastblock &&
842 fileset->logicalBlockNum == 0xFFFFFFFF &&
843 fileset->partitionReferenceNum == 0xFFFF);
844 }
845 }
846
847 if ((fileset->logicalBlockNum != 0xFFFFFFFF ||
848 fileset->partitionReferenceNum != 0xFFFF) && bh)
849 {
850 udf_debug("Fileset at block=%d, partition=%d\n",
851 fileset->logicalBlockNum, fileset->partitionReferenceNum);
852
853 UDF_SB_PARTITION(sb) = fileset->partitionReferenceNum;
854 udf_load_fileset(sb, bh, root);
855 udf_release_data(bh);
856 return 0;
857 }
858 return 1;
859}
860
861static void
862udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh)
863{
864 struct primaryVolDesc *pvoldesc;
865 time_t recording;
866 long recording_usec;
867 struct ustr instr;
868 struct ustr outstr;
869
870 pvoldesc = (struct primaryVolDesc *)bh->b_data;
871
872 if ( udf_stamp_to_time(&recording, &recording_usec,
873 lets_to_cpu(pvoldesc->recordingDateAndTime)) )
874 {
875 kernel_timestamp ts;
876 ts = lets_to_cpu(pvoldesc->recordingDateAndTime);
877 udf_debug("recording time %ld/%ld, %04u/%02u/%02u %02u:%02u (%x)\n",
878 recording, recording_usec,
879 ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.typeAndTimezone);
880 UDF_SB_RECORDTIME(sb).tv_sec = recording;
881 UDF_SB_RECORDTIME(sb).tv_nsec = recording_usec * 1000;
882 }
883
884 if ( !udf_build_ustr(&instr, pvoldesc->volIdent, 32) )
885 {
886 if (udf_CS0toUTF8(&outstr, &instr))
887 {
888 strncpy( UDF_SB_VOLIDENT(sb), outstr.u_name,
889 outstr.u_len > 31 ? 31 : outstr.u_len);
890 udf_debug("volIdent[] = '%s'\n", UDF_SB_VOLIDENT(sb));
891 }
892 }
893
894 if ( !udf_build_ustr(&instr, pvoldesc->volSetIdent, 128) )
895 {
896 if (udf_CS0toUTF8(&outstr, &instr))
897 udf_debug("volSetIdent[] = '%s'\n", outstr.u_name);
898 }
899}
900
901static void
902udf_load_fileset(struct super_block *sb, struct buffer_head *bh, kernel_lb_addr *root)
903{
904 struct fileSetDesc *fset;
905
906 fset = (struct fileSetDesc *)bh->b_data;
907
908 *root = lelb_to_cpu(fset->rootDirectoryICB.extLocation);
909
910 UDF_SB_SERIALNUM(sb) = le16_to_cpu(fset->descTag.tagSerialNum);
911
912 udf_debug("Rootdir at block=%d, partition=%d\n",
913 root->logicalBlockNum, root->partitionReferenceNum);
914}
915
916static void
917udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
918{
919 struct partitionDesc *p;
920 int i;
921
922 p = (struct partitionDesc *)bh->b_data;
923
924 for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
925 {
926 udf_debug("Searching map: (%d == %d)\n",
927 UDF_SB_PARTMAPS(sb)[i].s_partition_num, le16_to_cpu(p->partitionNumber));
928 if (UDF_SB_PARTMAPS(sb)[i].s_partition_num == le16_to_cpu(p->partitionNumber))
929 {
930 UDF_SB_PARTLEN(sb,i) = le32_to_cpu(p->partitionLength); /* blocks */
931 UDF_SB_PARTROOT(sb,i) = le32_to_cpu(p->partitionStartingLocation);
932 if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_READ_ONLY)
933 UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_READ_ONLY;
934 if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_WRITE_ONCE)
935 UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_WRITE_ONCE;
936 if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_REWRITABLE)
937 UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_REWRITABLE;
938 if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_OVERWRITABLE)
939 UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_OVERWRITABLE;
940
941 if (!strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) ||
942 !strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03))
943 {
944 struct partitionHeaderDesc *phd;
945
946 phd = (struct partitionHeaderDesc *)(p->partitionContentsUse);
947 if (phd->unallocSpaceTable.extLength)
948 {
949 kernel_lb_addr loc = { le32_to_cpu(phd->unallocSpaceTable.extPosition), i };
950
951 UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table =
952 udf_iget(sb, loc);
953 UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_TABLE;
954 udf_debug("unallocSpaceTable (part %d) @ %ld\n",
955 i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table->i_ino);
956 }
957 if (phd->unallocSpaceBitmap.extLength)
958 {
959 UDF_SB_ALLOC_BITMAP(sb, i, s_uspace);
960 if (UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap != NULL)
961 {
962 UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extLength =
963 le32_to_cpu(phd->unallocSpaceBitmap.extLength);
964 UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition =
965 le32_to_cpu(phd->unallocSpaceBitmap.extPosition);
966 UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_BITMAP;
967 udf_debug("unallocSpaceBitmap (part %d) @ %d\n",
968 i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition);
969 }
970 }
971 if (phd->partitionIntegrityTable.extLength)
972 udf_debug("partitionIntegrityTable (part %d)\n", i);
973 if (phd->freedSpaceTable.extLength)
974 {
975 kernel_lb_addr loc = { le32_to_cpu(phd->freedSpaceTable.extPosition), i };
976
977 UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table =
978 udf_iget(sb, loc);
979 UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_TABLE;
980 udf_debug("freedSpaceTable (part %d) @ %ld\n",
981 i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table->i_ino);
982 }
983 if (phd->freedSpaceBitmap.extLength)
984 {
985 UDF_SB_ALLOC_BITMAP(sb, i, s_fspace);
986 if (UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap != NULL)
987 {
988 UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extLength =
989 le32_to_cpu(phd->freedSpaceBitmap.extLength);
990 UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extPosition =
991 le32_to_cpu(phd->freedSpaceBitmap.extPosition);
992 UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_BITMAP;
993 udf_debug("freedSpaceBitmap (part %d) @ %d\n",
994 i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extPosition);
995 }
996 }
997 }
998 break;
999 }
1000 }
1001 if (i == UDF_SB_NUMPARTS(sb))
1002 {
1003 udf_debug("Partition (%d) not found in partition map\n", le16_to_cpu(p->partitionNumber));
1004 }
1005 else
1006 {
1007 udf_debug("Partition (%d:%d type %x) starts at physical %d, block length %d\n",
1008 le16_to_cpu(p->partitionNumber), i, UDF_SB_PARTTYPE(sb,i),
1009 UDF_SB_PARTROOT(sb,i), UDF_SB_PARTLEN(sb,i));
1010 }
1011}
1012
1013static int
1014udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, kernel_lb_addr *fileset)
1015{
1016 struct logicalVolDesc *lvd;
1017 int i, j, offset;
1018 uint8_t type;
1019
1020 lvd = (struct logicalVolDesc *)bh->b_data;
1021
1022 UDF_SB_ALLOC_PARTMAPS(sb, le32_to_cpu(lvd->numPartitionMaps));
1023
1024 for (i=0,offset=0;
1025 i<UDF_SB_NUMPARTS(sb) && offset<le32_to_cpu(lvd->mapTableLength);
1026 i++,offset+=((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapLength)
1027 {
1028 type = ((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapType;
1029 if (type == 1)
1030 {
1031 struct genericPartitionMap1 *gpm1 = (struct genericPartitionMap1 *)&(lvd->partitionMaps[offset]);
1032 UDF_SB_PARTTYPE(sb,i) = UDF_TYPE1_MAP15;
1033 UDF_SB_PARTVSN(sb,i) = le16_to_cpu(gpm1->volSeqNum);
1034 UDF_SB_PARTNUM(sb,i) = le16_to_cpu(gpm1->partitionNum);
1035 UDF_SB_PARTFUNC(sb,i) = NULL;
1036 }
1037 else if (type == 2)
1038 {
1039 struct udfPartitionMap2 *upm2 = (struct udfPartitionMap2 *)&(lvd->partitionMaps[offset]);
1040 if (!strncmp(upm2->partIdent.ident, UDF_ID_VIRTUAL, strlen(UDF_ID_VIRTUAL)))
1041 {
1042 if (le16_to_cpu(((__le16 *)upm2->partIdent.identSuffix)[0]) == 0x0150)
1043 {
1044 UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP15;
1045 UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt15;
1046 }
1047 else if (le16_to_cpu(((__le16 *)upm2->partIdent.identSuffix)[0]) == 0x0200)
1048 {
1049 UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP20;
1050 UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt20;
1051 }
1052 }
1053 else if (!strncmp(upm2->partIdent.ident, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE)))
1054 {
1055 uint32_t loc;
1056 uint16_t ident;
1057 struct sparingTable *st;
1058 struct sparablePartitionMap *spm = (struct sparablePartitionMap *)&(lvd->partitionMaps[offset]);
1059
1060 UDF_SB_PARTTYPE(sb,i) = UDF_SPARABLE_MAP15;
1061 UDF_SB_TYPESPAR(sb,i).s_packet_len = le16_to_cpu(spm->packetLength);
1062 for (j=0; j<spm->numSparingTables; j++)
1063 {
1064 loc = le32_to_cpu(spm->locSparingTable[j]);
1065 UDF_SB_TYPESPAR(sb,i).s_spar_map[j] =
1066 udf_read_tagged(sb, loc, loc, &ident);
1067 if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL)
1068 {
1069 st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,i).s_spar_map[j]->b_data;
1070 if (ident != 0 ||
1071 strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING)))
1072 {
1073 udf_release_data(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]);
1074 UDF_SB_TYPESPAR(sb,i).s_spar_map[j] = NULL;
1075 }
1076 }
1077 }
1078 UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_spar15;
1079 }
1080 else
1081 {
1082 udf_debug("Unknown ident: %s\n", upm2->partIdent.ident);
1083 continue;
1084 }
1085 UDF_SB_PARTVSN(sb,i) = le16_to_cpu(upm2->volSeqNum);
1086 UDF_SB_PARTNUM(sb,i) = le16_to_cpu(upm2->partitionNum);
1087 }
1088 udf_debug("Partition (%d:%d) type %d on volume %d\n",
1089 i, UDF_SB_PARTNUM(sb,i), type, UDF_SB_PARTVSN(sb,i));
1090 }
1091
1092 if (fileset)
1093 {
1094 long_ad *la = (long_ad *)&(lvd->logicalVolContentsUse[0]);
1095
1096 *fileset = lelb_to_cpu(la->extLocation);
1097 udf_debug("FileSet found in LogicalVolDesc at block=%d, partition=%d\n",
1098 fileset->logicalBlockNum,
1099 fileset->partitionReferenceNum);
1100 }
1101 if (lvd->integritySeqExt.extLength)
1102 udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt));
1103 return 0;
1104}
1105
1106/*
1107 * udf_load_logicalvolint
1108 *
1109 */
1110static void
1111udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc)
1112{
1113 struct buffer_head *bh = NULL;
1114 uint16_t ident;
1115
1116 while (loc.extLength > 0 &&
1117 (bh = udf_read_tagged(sb, loc.extLocation,
1118 loc.extLocation, &ident)) &&
1119 ident == TAG_IDENT_LVID)
1120 {
1121 UDF_SB_LVIDBH(sb) = bh;
1122
1123 if (UDF_SB_LVID(sb)->nextIntegrityExt.extLength)
1124 udf_load_logicalvolint(sb, leea_to_cpu(UDF_SB_LVID(sb)->nextIntegrityExt));
1125
1126 if (UDF_SB_LVIDBH(sb) != bh)
1127 udf_release_data(bh);
1128 loc.extLength -= sb->s_blocksize;
1129 loc.extLocation ++;
1130 }
1131 if (UDF_SB_LVIDBH(sb) != bh)
1132 udf_release_data(bh);
1133}
1134
1135/*
1136 * udf_process_sequence
1137 *
1138 * PURPOSE
1139 * Process a main/reserve volume descriptor sequence.
1140 *
1141 * PRE-CONDITIONS
1142 * sb Pointer to _locked_ superblock.
1143 * block First block of first extent of the sequence.
1144 * lastblock Lastblock of first extent of the sequence.
1145 *
1146 * HISTORY
1147 * July 1, 1997 - Andrew E. Mileski
1148 * Written, tested, and released.
1149 */
1150static int
1151udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_lb_addr *fileset)
1152{
1153 struct buffer_head *bh = NULL;
1154 struct udf_vds_record vds[VDS_POS_LENGTH];
1155 struct generic_desc *gd;
1156 struct volDescPtr *vdp;
1157 int done=0;
1158 int i,j;
1159 uint32_t vdsn;
1160 uint16_t ident;
1161 long next_s = 0, next_e = 0;
1162
1163 memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
1164
1165 /* Read the main descriptor sequence */
1166 for (;(!done && block <= lastblock); block++)
1167 {
1168
1169 bh = udf_read_tagged(sb, block, block, &ident);
1170 if (!bh)
1171 break;
1172
1173 /* Process each descriptor (ISO 13346 3/8.3-8.4) */
1174 gd = (struct generic_desc *)bh->b_data;
1175 vdsn = le32_to_cpu(gd->volDescSeqNum);
1176 switch (ident)
1177 {
1178 case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */
1179 if (vdsn >= vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum)
1180 {
1181 vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum = vdsn;
1182 vds[VDS_POS_PRIMARY_VOL_DESC].block = block;
1183 }
1184 break;
1185 case TAG_IDENT_VDP: /* ISO 13346 3/10.3 */
1186 if (vdsn >= vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum)
1187 {
1188 vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum = vdsn;
1189 vds[VDS_POS_VOL_DESC_PTR].block = block;
1190
1191 vdp = (struct volDescPtr *)bh->b_data;
1192 next_s = le32_to_cpu(vdp->nextVolDescSeqExt.extLocation);
1193 next_e = le32_to_cpu(vdp->nextVolDescSeqExt.extLength);
1194 next_e = next_e >> sb->s_blocksize_bits;
1195 next_e += next_s;
1196 }
1197 break;
1198 case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */
1199 if (vdsn >= vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum)
1200 {
1201 vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum = vdsn;
1202 vds[VDS_POS_IMP_USE_VOL_DESC].block = block;
1203 }
1204 break;
1205 case TAG_IDENT_PD: /* ISO 13346 3/10.5 */
1206 if (!vds[VDS_POS_PARTITION_DESC].block)
1207 vds[VDS_POS_PARTITION_DESC].block = block;
1208 break;
1209 case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */
1210 if (vdsn >= vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum)
1211 {
1212 vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum = vdsn;
1213 vds[VDS_POS_LOGICAL_VOL_DESC].block = block;
1214 }
1215 break;
1216 case TAG_IDENT_USD: /* ISO 13346 3/10.8 */
1217 if (vdsn >= vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum)
1218 {
1219 vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum = vdsn;
1220 vds[VDS_POS_UNALLOC_SPACE_DESC].block = block;
1221 }
1222 break;
1223 case TAG_IDENT_TD: /* ISO 13346 3/10.9 */
1224 vds[VDS_POS_TERMINATING_DESC].block = block;
1225 if (next_e)
1226 {
1227 block = next_s;
1228 lastblock = next_e;
1229 next_s = next_e = 0;
1230 }
1231 else
1232 done = 1;
1233 break;
1234 }
1235 udf_release_data(bh);
1236 }
1237 for (i=0; i<VDS_POS_LENGTH; i++)
1238 {
1239 if (vds[i].block)
1240 {
1241 bh = udf_read_tagged(sb, vds[i].block, vds[i].block, &ident);
1242
1243 if (i == VDS_POS_PRIMARY_VOL_DESC)
1244 udf_load_pvoldesc(sb, bh);
1245 else if (i == VDS_POS_LOGICAL_VOL_DESC)
1246 udf_load_logicalvol(sb, bh, fileset);
1247 else if (i == VDS_POS_PARTITION_DESC)
1248 {
1249 struct buffer_head *bh2 = NULL;
1250 udf_load_partdesc(sb, bh);
1251 for (j=vds[i].block+1; j<vds[VDS_POS_TERMINATING_DESC].block; j++)
1252 {
1253 bh2 = udf_read_tagged(sb, j, j, &ident);
1254 gd = (struct generic_desc *)bh2->b_data;
1255 if (ident == TAG_IDENT_PD)
1256 udf_load_partdesc(sb, bh2);
1257 udf_release_data(bh2);
1258 }
1259 }
1260 udf_release_data(bh);
1261 }
1262 }
1263
1264 return 0;
1265}
1266
1267/*
1268 * udf_check_valid()
1269 */
1270static int
1271udf_check_valid(struct super_block *sb, int novrs, int silent)
1272{
1273 long block;
1274
1275 if (novrs)
1276 {
1277 udf_debug("Validity check skipped because of novrs option\n");
1278 return 0;
1279 }
1280 /* Check that it is NSR02 compliant */
1281 /* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */
1282 else if ((block = udf_vrs(sb, silent)) == -1)
1283 {
1284 udf_debug("Failed to read byte 32768. Assuming open disc. Skipping validity check\n");
1285 if (!UDF_SB_LASTBLOCK(sb))
1286 UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
1287 return 0;
1288 }
1289 else
1290 return !block;
1291}
1292
1293static int
1294udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
1295{
1296 struct anchorVolDescPtr *anchor;
1297 uint16_t ident;
1298 struct buffer_head *bh;
1299 long main_s, main_e, reserve_s, reserve_e;
1300 int i, j;
1301
1302 if (!sb)
1303 return 1;
1304
1305 for (i=0; i<sizeof(UDF_SB_ANCHOR(sb))/sizeof(int); i++)
1306 {
1307 if (UDF_SB_ANCHOR(sb)[i] && (bh = udf_read_tagged(sb,
1308 UDF_SB_ANCHOR(sb)[i], UDF_SB_ANCHOR(sb)[i], &ident)))
1309 {
1310 anchor = (struct anchorVolDescPtr *)bh->b_data;
1311
1312 /* Locate the main sequence */
1313 main_s = le32_to_cpu( anchor->mainVolDescSeqExt.extLocation );
1314 main_e = le32_to_cpu( anchor->mainVolDescSeqExt.extLength );
1315 main_e = main_e >> sb->s_blocksize_bits;
1316 main_e += main_s;
1317
1318 /* Locate the reserve sequence */
1319 reserve_s = le32_to_cpu(anchor->reserveVolDescSeqExt.extLocation);
1320 reserve_e = le32_to_cpu(anchor->reserveVolDescSeqExt.extLength);
1321 reserve_e = reserve_e >> sb->s_blocksize_bits;
1322 reserve_e += reserve_s;
1323
1324 udf_release_data(bh);
1325
1326 /* Process the main & reserve sequences */
1327 /* responsible for finding the PartitionDesc(s) */
1328 if (!(udf_process_sequence(sb, main_s, main_e, fileset) &&
1329 udf_process_sequence(sb, reserve_s, reserve_e, fileset)))
1330 {
1331 break;
1332 }
1333 }
1334 }
1335
1336 if (i == sizeof(UDF_SB_ANCHOR(sb))/sizeof(int))
1337 {
1338 udf_debug("No Anchor block found\n");
1339 return 1;
1340 }
1341 else
1342 udf_debug("Using anchor in block %d\n", UDF_SB_ANCHOR(sb)[i]);
1343
1344 for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
1345 {
1346 switch UDF_SB_PARTTYPE(sb, i)
1347 {
1348 case UDF_VIRTUAL_MAP15:
1349 case UDF_VIRTUAL_MAP20:
1350 {
1351 kernel_lb_addr ino;
1352
1353 if (!UDF_SB_LASTBLOCK(sb))
1354 {
1355 UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
1356 udf_find_anchor(sb);
1357 }
1358
1359 if (!UDF_SB_LASTBLOCK(sb))
1360 {
1361 udf_debug("Unable to determine Lastblock (For Virtual Partition)\n");
1362 return 1;
1363 }
1364
1365 for (j=0; j<UDF_SB_NUMPARTS(sb); j++)
1366 {
1367 if (j != i &&
1368 UDF_SB_PARTVSN(sb,i) == UDF_SB_PARTVSN(sb,j) &&
1369 UDF_SB_PARTNUM(sb,i) == UDF_SB_PARTNUM(sb,j))
1370 {
1371 ino.partitionReferenceNum = j;
1372 ino.logicalBlockNum = UDF_SB_LASTBLOCK(sb) -
1373 UDF_SB_PARTROOT(sb,j);
1374 break;
1375 }
1376 }
1377
1378 if (j == UDF_SB_NUMPARTS(sb))
1379 return 1;
1380
1381 if (!(UDF_SB_VAT(sb) = udf_iget(sb, ino)))
1382 return 1;
1383
1384 if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP15)
1385 {
1386 UDF_SB_TYPEVIRT(sb,i).s_start_offset = udf_ext0_offset(UDF_SB_VAT(sb));
1387 UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size - 36) >> 2;
1388 }
1389 else if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP20)
1390 {
1391 struct buffer_head *bh = NULL;
1392 uint32_t pos;
1393
1394 pos = udf_block_map(UDF_SB_VAT(sb), 0);
1395 bh = sb_bread(sb, pos);
1396 UDF_SB_TYPEVIRT(sb,i).s_start_offset =
1397 le16_to_cpu(((struct virtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) +
1398 udf_ext0_offset(UDF_SB_VAT(sb));
1399 UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size -
1400 UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2;
1401 udf_release_data(bh);
1402 }
1403 UDF_SB_PARTROOT(sb,i) = udf_get_pblock(sb, 0, i, 0);
1404 UDF_SB_PARTLEN(sb,i) = UDF_SB_PARTLEN(sb,ino.partitionReferenceNum);
1405 }
1406 }
1407 }
1408 return 0;
1409}
1410
1411static void udf_open_lvid(struct super_block *sb)
1412{
1413 if (UDF_SB_LVIDBH(sb))
1414 {
1415 int i;
1416 kernel_timestamp cpu_time;
1417
1418 UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
1419 UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
1420 if (udf_time_to_stamp(&cpu_time, CURRENT_TIME))
1421 UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time);
1422 UDF_SB_LVID(sb)->integrityType = LVID_INTEGRITY_TYPE_OPEN;
1423
1424 UDF_SB_LVID(sb)->descTag.descCRC =
1425 cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
1426 le16_to_cpu(UDF_SB_LVID(sb)->descTag.descCRCLength), 0));
1427
1428 UDF_SB_LVID(sb)->descTag.tagChecksum = 0;
1429 for (i=0; i<16; i++)
1430 if (i != 4)
1431 UDF_SB_LVID(sb)->descTag.tagChecksum +=
1432 ((uint8_t *)&(UDF_SB_LVID(sb)->descTag))[i];
1433
1434 mark_buffer_dirty(UDF_SB_LVIDBH(sb));
1435 }
1436}
1437
1438static void udf_close_lvid(struct super_block *sb)
1439{
1440 if (UDF_SB_LVIDBH(sb) &&
1441 UDF_SB_LVID(sb)->integrityType == LVID_INTEGRITY_TYPE_OPEN)
1442 {
1443 int i;
1444 kernel_timestamp cpu_time;
1445
1446 UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
1447 UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
1448 if (udf_time_to_stamp(&cpu_time, CURRENT_TIME))
1449 UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time);
1450 if (UDF_MAX_WRITE_VERSION > le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev))
1451 UDF_SB_LVIDIU(sb)->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION);
1452 if (UDF_SB_UDFREV(sb) > le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev))
1453 UDF_SB_LVIDIU(sb)->minUDFReadRev = cpu_to_le16(UDF_SB_UDFREV(sb));
1454 if (UDF_SB_UDFREV(sb) > le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev))
1455 UDF_SB_LVIDIU(sb)->minUDFWriteRev = cpu_to_le16(UDF_SB_UDFREV(sb));
1456 UDF_SB_LVID(sb)->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE);
1457
1458 UDF_SB_LVID(sb)->descTag.descCRC =
1459 cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
1460 le16_to_cpu(UDF_SB_LVID(sb)->descTag.descCRCLength), 0));
1461
1462 UDF_SB_LVID(sb)->descTag.tagChecksum = 0;
1463 for (i=0; i<16; i++)
1464 if (i != 4)
1465 UDF_SB_LVID(sb)->descTag.tagChecksum +=
1466 ((uint8_t *)&(UDF_SB_LVID(sb)->descTag))[i];
1467
1468 mark_buffer_dirty(UDF_SB_LVIDBH(sb));
1469 }
1470}
1471
1472/*
1473 * udf_read_super
1474 *
1475 * PURPOSE
1476 * Complete the specified super block.
1477 *
1478 * PRE-CONDITIONS
1479 * sb Pointer to superblock to complete - never NULL.
1480 * sb->s_dev Device to read suberblock from.
1481 * options Pointer to mount options.
1482 * silent Silent flag.
1483 *
1484 * HISTORY
1485 * July 1, 1997 - Andrew E. Mileski
1486 * Written, tested, and released.
1487 */
1488static int udf_fill_super(struct super_block *sb, void *options, int silent)
1489{
1490 int i;
1491 struct inode *inode=NULL;
1492 struct udf_options uopt;
1493 kernel_lb_addr rootdir, fileset;
1494 struct udf_sb_info *sbi;
1495
1496 uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
1497 uopt.uid = -1;
1498 uopt.gid = -1;
1499 uopt.umask = 0;
1500
1501 sbi = kmalloc(sizeof(struct udf_sb_info), GFP_KERNEL);
1502 if (!sbi)
1503 return -ENOMEM;
1504 sb->s_fs_info = sbi;
1505 memset(UDF_SB(sb), 0x00, sizeof(struct udf_sb_info));
1506
1507 init_MUTEX(&sbi->s_alloc_sem);
1508
1509 if (!udf_parse_options((char *)options, &uopt))
1510 goto error_out;
1511
1512 if (uopt.flags & (1 << UDF_FLAG_UTF8) &&
1513 uopt.flags & (1 << UDF_FLAG_NLS_MAP))
1514 {
1515 udf_error(sb, "udf_read_super",
1516 "utf8 cannot be combined with iocharset\n");
1517 goto error_out;
1518 }
1519#ifdef CONFIG_UDF_NLS
1520 if ((uopt.flags & (1 << UDF_FLAG_NLS_MAP)) && !uopt.nls_map)
1521 {
1522 uopt.nls_map = load_nls_default();
1523 if (!uopt.nls_map)
1524 uopt.flags &= ~(1 << UDF_FLAG_NLS_MAP);
1525 else
1526 udf_debug("Using default NLS map\n");
1527 }
1528#endif
1529 if (!(uopt.flags & (1 << UDF_FLAG_NLS_MAP)))
1530 uopt.flags |= (1 << UDF_FLAG_UTF8);
1531
1532 fileset.logicalBlockNum = 0xFFFFFFFF;
1533 fileset.partitionReferenceNum = 0xFFFF;
1534
1535 UDF_SB(sb)->s_flags = uopt.flags;
1536 UDF_SB(sb)->s_uid = uopt.uid;
1537 UDF_SB(sb)->s_gid = uopt.gid;
1538 UDF_SB(sb)->s_umask = uopt.umask;
1539 UDF_SB(sb)->s_nls_map = uopt.nls_map;
1540
1541 /* Set the block size for all transfers */
1542 if (!udf_set_blocksize(sb, uopt.blocksize))
1543 goto error_out;
1544
1545 if ( uopt.session == 0xFFFFFFFF )
1546 UDF_SB_SESSION(sb) = udf_get_last_session(sb);
1547 else
1548 UDF_SB_SESSION(sb) = uopt.session;
1549
1550 udf_debug("Multi-session=%d\n", UDF_SB_SESSION(sb));
1551
1552 UDF_SB_LASTBLOCK(sb) = uopt.lastblock;
1553 UDF_SB_ANCHOR(sb)[0] = UDF_SB_ANCHOR(sb)[1] = 0;
1554 UDF_SB_ANCHOR(sb)[2] = uopt.anchor;
1555 UDF_SB_ANCHOR(sb)[3] = 256;
1556
1557 if (udf_check_valid(sb, uopt.novrs, silent)) /* read volume recognition sequences */
1558 {
1559 printk("UDF-fs: No VRS found\n");
1560 goto error_out;
1561 }
1562
1563 udf_find_anchor(sb);
1564
1565 /* Fill in the rest of the superblock */
1566 sb->s_op = &udf_sb_ops;
1567 sb->dq_op = NULL;
1568 sb->s_dirt = 0;
1569 sb->s_magic = UDF_SUPER_MAGIC;
1570 sb->s_time_gran = 1000;
1571
1572 if (udf_load_partition(sb, &fileset))
1573 {
1574 printk("UDF-fs: No partition found (1)\n");
1575 goto error_out;
1576 }
1577
1578 udf_debug("Lastblock=%d\n", UDF_SB_LASTBLOCK(sb));
1579
1580 if ( UDF_SB_LVIDBH(sb) )
1581 {
1582 uint16_t minUDFReadRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev);
1583 uint16_t minUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev);
1584 /* uint16_t maxUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev); */
1585
1586 if (minUDFReadRev > UDF_MAX_READ_VERSION)
1587 {
1588 printk("UDF-fs: minUDFReadRev=%x (max is %x)\n",
1589 le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev),
1590 UDF_MAX_READ_VERSION);
1591 goto error_out;
1592 }
1593 else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION)
1594 {
1595 sb->s_flags |= MS_RDONLY;
1596 }
1597
1598 UDF_SB_UDFREV(sb) = minUDFWriteRev;
1599
1600 if (minUDFReadRev >= UDF_VERS_USE_EXTENDED_FE)
1601 UDF_SET_FLAG(sb, UDF_FLAG_USE_EXTENDED_FE);
1602 if (minUDFReadRev >= UDF_VERS_USE_STREAMS)
1603 UDF_SET_FLAG(sb, UDF_FLAG_USE_STREAMS);
1604 }
1605
1606 if ( !UDF_SB_NUMPARTS(sb) )
1607 {
1608 printk("UDF-fs: No partition found (2)\n");
1609 goto error_out;
1610 }
1611
1612 if ( udf_find_fileset(sb, &fileset, &rootdir) )
1613 {
1614 printk("UDF-fs: No fileset found\n");
1615 goto error_out;
1616 }
1617
1618 if (!silent)
1619 {
1620 kernel_timestamp ts;
1621 udf_time_to_stamp(&ts, UDF_SB_RECORDTIME(sb));
1622 udf_info("UDF %s (%s) Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
1623 UDFFS_VERSION, UDFFS_DATE,
1624 UDF_SB_VOLIDENT(sb), ts.year, ts.month, ts.day, ts.hour, ts.minute,
1625 ts.typeAndTimezone);
1626 }
1627 if (!(sb->s_flags & MS_RDONLY))
1628 udf_open_lvid(sb);
1629
1630 /* Assign the root inode */
1631 /* assign inodes by physical block number */
1632 /* perhaps it's not extensible enough, but for now ... */
1633 inode = udf_iget(sb, rootdir);
1634 if (!inode)
1635 {
1636 printk("UDF-fs: Error in udf_iget, block=%d, partition=%d\n",
1637 rootdir.logicalBlockNum, rootdir.partitionReferenceNum);
1638 goto error_out;
1639 }
1640
1641 /* Allocate a dentry for the root inode */
1642 sb->s_root = d_alloc_root(inode);
1643 if (!sb->s_root)
1644 {
1645 printk("UDF-fs: Couldn't allocate root dentry\n");
1646 iput(inode);
1647 goto error_out;
1648 }
1649 sb->s_maxbytes = MAX_LFS_FILESIZE;
1650 return 0;
1651
1652error_out:
1653 if (UDF_SB_VAT(sb))
1654 iput(UDF_SB_VAT(sb));
1655 if (UDF_SB_NUMPARTS(sb))
1656 {
1657 if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
1658 iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
1659 if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
1660 iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
1661 if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
1662 UDF_SB_FREE_BITMAP(sb,UDF_SB_PARTITION(sb),s_uspace);
1663 if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
1664 UDF_SB_FREE_BITMAP(sb,UDF_SB_PARTITION(sb),s_fspace);
1665 if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15)
1666 {
1667 for (i=0; i<4; i++)
1668 udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
1669 }
1670 }
1671#ifdef CONFIG_UDF_NLS
1672 if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
1673 unload_nls(UDF_SB(sb)->s_nls_map);
1674#endif
1675 if (!(sb->s_flags & MS_RDONLY))
1676 udf_close_lvid(sb);
1677 udf_release_data(UDF_SB_LVIDBH(sb));
1678 UDF_SB_FREE(sb);
1679 kfree(sbi);
1680 sb->s_fs_info = NULL;
1681 return -EINVAL;
1682}
1683
1684void udf_error(struct super_block *sb, const char *function,
1685 const char *fmt, ...)
1686{
1687 va_list args;
1688
1689 if (!(sb->s_flags & MS_RDONLY))
1690 {
1691 /* mark sb error */
1692 sb->s_dirt = 1;
1693 }
1694 va_start(args, fmt);
1695 vsprintf(error_buf, fmt, args);
1696 va_end(args);
1697 printk (KERN_CRIT "UDF-fs error (device %s): %s: %s\n",
1698 sb->s_id, function, error_buf);
1699}
1700
1701void udf_warning(struct super_block *sb, const char *function,
1702 const char *fmt, ...)
1703{
1704 va_list args;
1705
1706 va_start (args, fmt);
1707 vsprintf(error_buf, fmt, args);
1708 va_end(args);
1709 printk(KERN_WARNING "UDF-fs warning (device %s): %s: %s\n",
1710 sb->s_id, function, error_buf);
1711}
1712
1713/*
1714 * udf_put_super
1715 *
1716 * PURPOSE
1717 * Prepare for destruction of the superblock.
1718 *
1719 * DESCRIPTION
1720 * Called before the filesystem is unmounted.
1721 *
1722 * HISTORY
1723 * July 1, 1997 - Andrew E. Mileski
1724 * Written, tested, and released.
1725 */
1726static void
1727udf_put_super(struct super_block *sb)
1728{
1729 int i;
1730
1731 if (UDF_SB_VAT(sb))
1732 iput(UDF_SB_VAT(sb));
1733 if (UDF_SB_NUMPARTS(sb))
1734 {
1735 if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
1736 iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
1737 if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
1738 iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
1739 if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
1740 UDF_SB_FREE_BITMAP(sb,UDF_SB_PARTITION(sb),s_uspace);
1741 if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
1742 UDF_SB_FREE_BITMAP(sb,UDF_SB_PARTITION(sb),s_fspace);
1743 if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15)
1744 {
1745 for (i=0; i<4; i++)
1746 udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
1747 }
1748 }
1749#ifdef CONFIG_UDF_NLS
1750 if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
1751 unload_nls(UDF_SB(sb)->s_nls_map);
1752#endif
1753 if (!(sb->s_flags & MS_RDONLY))
1754 udf_close_lvid(sb);
1755 udf_release_data(UDF_SB_LVIDBH(sb));
1756 UDF_SB_FREE(sb);
1757 kfree(sb->s_fs_info);
1758 sb->s_fs_info = NULL;
1759}
1760
1761/*
1762 * udf_stat_fs
1763 *
1764 * PURPOSE
1765 * Return info about the filesystem.
1766 *
1767 * DESCRIPTION
1768 * Called by sys_statfs()
1769 *
1770 * HISTORY
1771 * July 1, 1997 - Andrew E. Mileski
1772 * Written, tested, and released.
1773 */
1774static int
1775udf_statfs(struct super_block *sb, struct kstatfs *buf)
1776{
1777 buf->f_type = UDF_SUPER_MAGIC;
1778 buf->f_bsize = sb->s_blocksize;
1779 buf->f_blocks = UDF_SB_PARTLEN(sb, UDF_SB_PARTITION(sb));
1780 buf->f_bfree = udf_count_free(sb);
1781 buf->f_bavail = buf->f_bfree;
1782 buf->f_files = (UDF_SB_LVIDBH(sb) ?
1783 (le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) +
1784 le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs)) : 0) + buf->f_bfree;
1785 buf->f_ffree = buf->f_bfree;
1786 /* __kernel_fsid_t f_fsid */
1787 buf->f_namelen = UDF_NAME_LEN-2;
1788
1789 return 0;
1790}
1791
1792static unsigned char udf_bitmap_lookup[16] = {
1793 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
1794};
1795
1796static unsigned int
1797udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
1798{
1799 struct buffer_head *bh = NULL;
1800 unsigned int accum = 0;
1801 int index;
1802 int block = 0, newblock;
1803 kernel_lb_addr loc;
1804 uint32_t bytes;
1805 uint8_t value;
1806 uint8_t *ptr;
1807 uint16_t ident;
1808 struct spaceBitmapDesc *bm;
1809
1810 lock_kernel();
1811
1812 loc.logicalBlockNum = bitmap->s_extPosition;
1813 loc.partitionReferenceNum = UDF_SB_PARTITION(sb);
1814 bh = udf_read_ptagged(sb, loc, 0, &ident);
1815
1816 if (!bh)
1817 {
1818 printk(KERN_ERR "udf: udf_count_free failed\n");
1819 goto out;
1820 }
1821 else if (ident != TAG_IDENT_SBD)
1822 {
1823 udf_release_data(bh);
1824 printk(KERN_ERR "udf: udf_count_free failed\n");
1825 goto out;
1826 }
1827
1828 bm = (struct spaceBitmapDesc *)bh->b_data;
1829 bytes = le32_to_cpu(bm->numOfBytes);
1830 index = sizeof(struct spaceBitmapDesc); /* offset in first block only */
1831 ptr = (uint8_t *)bh->b_data;
1832
1833 while ( bytes > 0 )
1834 {
1835 while ((bytes > 0) && (index < sb->s_blocksize))
1836 {
1837 value = ptr[index];
1838 accum += udf_bitmap_lookup[ value & 0x0f ];
1839 accum += udf_bitmap_lookup[ value >> 4 ];
1840 index++;
1841 bytes--;
1842 }
1843 if ( bytes )
1844 {
1845 udf_release_data(bh);
1846 newblock = udf_get_lb_pblock(sb, loc, ++block);
1847 bh = udf_tread(sb, newblock);
1848 if (!bh)
1849 {
1850 udf_debug("read failed\n");
1851 goto out;
1852 }
1853 index = 0;
1854 ptr = (uint8_t *)bh->b_data;
1855 }
1856 }
1857 udf_release_data(bh);
1858
1859out:
1860 unlock_kernel();
1861
1862 return accum;
1863}
1864
1865static unsigned int
1866udf_count_free_table(struct super_block *sb, struct inode * table)
1867{
1868 unsigned int accum = 0;
1869 uint32_t extoffset, elen;
1870 kernel_lb_addr bloc, eloc;
1871 int8_t etype;
1872 struct buffer_head *bh = NULL;
1873
1874 lock_kernel();
1875
1876 bloc = UDF_I_LOCATION(table);
1877 extoffset = sizeof(struct unallocSpaceEntry);
1878
1879 while ((etype = udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
1880 {
1881 accum += (elen >> table->i_sb->s_blocksize_bits);
1882 }
1883 udf_release_data(bh);
1884
1885 unlock_kernel();
1886
1887 return accum;
1888}
1889
1890static unsigned int
1891udf_count_free(struct super_block *sb)
1892{
1893 unsigned int accum = 0;
1894
1895 if (UDF_SB_LVIDBH(sb))
1896 {
1897 if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) > UDF_SB_PARTITION(sb))
1898 {
1899 accum = le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]);
1900
1901 if (accum == 0xFFFFFFFF)
1902 accum = 0;
1903 }
1904 }
1905
1906 if (accum)
1907 return accum;
1908
1909 if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
1910 {
1911 accum += udf_count_free_bitmap(sb,
1912 UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_bitmap);
1913 }
1914 if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
1915 {
1916 accum += udf_count_free_bitmap(sb,
1917 UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_bitmap);
1918 }
1919 if (accum)
1920 return accum;
1921
1922 if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
1923 {
1924 accum += udf_count_free_table(sb,
1925 UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
1926 }
1927 if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
1928 {
1929 accum += udf_count_free_table(sb,
1930 UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
1931 }
1932
1933 return accum;
1934}
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
new file mode 100644
index 000000000000..43f3051ef756
--- /dev/null
+++ b/fs/udf/symlink.c
@@ -0,0 +1,123 @@
1/*
2 * symlink.c
3 *
4 * PURPOSE
5 * Symlink handling routines for the OSTA-UDF(tm) filesystem.
6 *
7 * CONTACTS
8 * E-mail regarding any portion of the Linux UDF file system should be
9 * directed to the development team mailing list (run by majordomo):
10 * linux_udf@hpesjro.fc.hp.com
11 *
12 * COPYRIGHT
13 * This file is distributed under the terms of the GNU General Public
14 * License (GPL). Copies of the GPL can be obtained from:
15 * ftp://prep.ai.mit.edu/pub/gnu/GPL
16 * Each contributing author retains all rights to their own work.
17 *
18 * (C) 1998-2001 Ben Fennema
19 * (C) 1999 Stelias Computing Inc
20 *
21 * HISTORY
22 *
23 * 04/16/99 blf Created.
24 *
25 */
26
27#include "udfdecl.h"
28#include <asm/uaccess.h>
29#include <linux/errno.h>
30#include <linux/fs.h>
31#include <linux/udf_fs.h>
32#include <linux/time.h>
33#include <linux/mm.h>
34#include <linux/stat.h>
35#include <linux/slab.h>
36#include <linux/pagemap.h>
37#include <linux/smp_lock.h>
38#include <linux/buffer_head.h>
39#include "udf_i.h"
40
41static void udf_pc_to_char(struct super_block *sb, char *from, int fromlen, char *to)
42{
43 struct pathComponent *pc;
44 int elen = 0;
45 char *p = to;
46
47 while (elen < fromlen)
48 {
49 pc = (struct pathComponent *)(from + elen);
50 switch (pc->componentType)
51 {
52 case 1:
53 if (pc->lengthComponentIdent == 0)
54 {
55 p = to;
56 *p++ = '/';
57 }
58 break;
59 case 3:
60 memcpy(p, "../", 3);
61 p += 3;
62 break;
63 case 4:
64 memcpy(p, "./", 2);
65 p += 2;
66 /* that would be . - just ignore */
67 break;
68 case 5:
69 p += udf_get_filename(sb, pc->componentIdent, p, pc->lengthComponentIdent);
70 *p++ = '/';
71 break;
72 }
73 elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
74 }
75 if (p > to+1)
76 p[-1] = '\0';
77 else
78 p[0] = '\0';
79}
80
81static int udf_symlink_filler(struct file *file, struct page *page)
82{
83 struct inode *inode = page->mapping->host;
84 struct buffer_head *bh = NULL;
85 char *symlink;
86 int err = -EIO;
87 char *p = kmap(page);
88
89 lock_kernel();
90 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
91 symlink = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
92 else
93 {
94 bh = sb_bread(inode->i_sb, udf_block_map(inode, 0));
95
96 if (!bh)
97 goto out;
98
99 symlink = bh->b_data;
100 }
101
102 udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p);
103 udf_release_data(bh);
104
105 unlock_kernel();
106 SetPageUptodate(page);
107 kunmap(page);
108 unlock_page(page);
109 return 0;
110out:
111 unlock_kernel();
112 SetPageError(page);
113 kunmap(page);
114 unlock_page(page);
115 return err;
116}
117
118/*
119 * symlinks can't do much...
120 */
121struct address_space_operations udf_symlink_aops = {
122 .readpage = udf_symlink_filler,
123};
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c
new file mode 100644
index 000000000000..7dc8a5572ca1
--- /dev/null
+++ b/fs/udf/truncate.c
@@ -0,0 +1,284 @@
1/*
2 * truncate.c
3 *
4 * PURPOSE
5 * Truncate handling routines for the OSTA-UDF(tm) filesystem.
6 *
7 * CONTACTS
8 * E-mail regarding any portion of the Linux UDF file system should be
9 * directed to the development team mailing list (run by majordomo):
10 * linux_udf@hpesjro.fc.hp.com
11 *
12 * COPYRIGHT
13 * This file is distributed under the terms of the GNU General Public
14 * License (GPL). Copies of the GPL can be obtained from:
15 * ftp://prep.ai.mit.edu/pub/gnu/GPL
16 * Each contributing author retains all rights to their own work.
17 *
18 * (C) 1999-2004 Ben Fennema
19 * (C) 1999 Stelias Computing Inc
20 *
21 * HISTORY
22 *
23 * 02/24/99 blf Created.
24 *
25 */
26
27#include "udfdecl.h"
28#include <linux/fs.h>
29#include <linux/mm.h>
30#include <linux/udf_fs.h>
31#include <linux/buffer_head.h>
32
33#include "udf_i.h"
34#include "udf_sb.h"
35
36static void extent_trunc(struct inode * inode, kernel_lb_addr bloc, int extoffset,
37 kernel_lb_addr eloc, int8_t etype, uint32_t elen, struct buffer_head *bh, uint32_t nelen)
38{
39 kernel_lb_addr neloc = { 0, 0 };
40 int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
41 int first_block = (nelen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
42
43 if (nelen)
44 {
45 if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
46 {
47 udf_free_blocks(inode->i_sb, inode, eloc, 0, last_block);
48 etype = (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30);
49 }
50 else
51 neloc = eloc;
52 nelen = (etype << 30) | nelen;
53 }
54
55 if (elen != nelen)
56 {
57 udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0);
58 if (last_block - first_block > 0)
59 {
60 if (etype == (EXT_RECORDED_ALLOCATED >> 30))
61 mark_inode_dirty(inode);
62
63 if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
64 udf_free_blocks(inode->i_sb, inode, eloc, first_block, last_block - first_block);
65 }
66 }
67}
68
69void udf_discard_prealloc(struct inode * inode)
70{
71 kernel_lb_addr bloc, eloc;
72 uint32_t extoffset = 0, elen, nelen;
73 uint64_t lbcount = 0;
74 int8_t etype = -1, netype;
75 struct buffer_head *bh = NULL;
76 int adsize;
77
78 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB ||
79 inode->i_size == UDF_I_LENEXTENTS(inode))
80 {
81 return;
82 }
83
84 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
85 adsize = sizeof(short_ad);
86 else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
87 adsize = sizeof(long_ad);
88 else
89 adsize = 0;
90
91 bloc = UDF_I_LOCATION(inode);
92
93 while ((netype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
94 {
95 etype = netype;
96 lbcount += elen;
97 if (lbcount > inode->i_size && lbcount - inode->i_size < inode->i_sb->s_blocksize)
98 {
99 nelen = elen - (lbcount - inode->i_size);
100 extent_trunc(inode, bloc, extoffset-adsize, eloc, etype, elen, bh, nelen);
101 lbcount = inode->i_size;
102 }
103 }
104 if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
105 {
106 extoffset -= adsize;
107 lbcount -= elen;
108 extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0);
109 if (!bh)
110 {
111 UDF_I_LENALLOC(inode) = extoffset - udf_file_entry_alloc_offset(inode);
112 mark_inode_dirty(inode);
113 }
114 else
115 {
116 struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data);
117 aed->lengthAllocDescs = cpu_to_le32(extoffset - sizeof(struct allocExtDesc));
118 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
119 udf_update_tag(bh->b_data, extoffset);
120 else
121 udf_update_tag(bh->b_data, sizeof(struct allocExtDesc));
122 mark_buffer_dirty_inode(bh, inode);
123 }
124 }
125 UDF_I_LENEXTENTS(inode) = lbcount;
126
127 udf_release_data(bh);
128}
129
130void udf_truncate_extents(struct inode * inode)
131{
132 kernel_lb_addr bloc, eloc, neloc = { 0, 0 };
133 uint32_t extoffset, elen, offset, nelen = 0, lelen = 0, lenalloc;
134 int8_t etype;
135 int first_block = inode->i_size >> inode->i_sb->s_blocksize_bits;
136 struct buffer_head *bh = NULL;
137 int adsize;
138
139 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
140 adsize = sizeof(short_ad);
141 else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
142 adsize = sizeof(long_ad);
143 else
144 adsize = 0;
145
146 etype = inode_bmap(inode, first_block, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
147 offset += (inode->i_size & (inode->i_sb->s_blocksize - 1));
148 if (etype != -1)
149 {
150 extoffset -= adsize;
151 extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, offset);
152 extoffset += adsize;
153
154 if (offset)
155 lenalloc = extoffset;
156 else
157 lenalloc = extoffset - adsize;
158
159 if (!bh)
160 lenalloc -= udf_file_entry_alloc_offset(inode);
161 else
162 lenalloc -= sizeof(struct allocExtDesc);
163
164 while ((etype = udf_current_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 0)) != -1)
165 {
166 if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30))
167 {
168 udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0);
169 extoffset = 0;
170 if (lelen)
171 {
172 if (!bh)
173 BUG();
174 else
175 memset(bh->b_data, 0x00, sizeof(struct allocExtDesc));
176 udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
177 }
178 else
179 {
180 if (!bh)
181 {
182 UDF_I_LENALLOC(inode) = lenalloc;
183 mark_inode_dirty(inode);
184 }
185 else
186 {
187 struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data);
188 aed->lengthAllocDescs = cpu_to_le32(lenalloc);
189 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
190 udf_update_tag(bh->b_data, lenalloc +
191 sizeof(struct allocExtDesc));
192 else
193 udf_update_tag(bh->b_data, sizeof(struct allocExtDesc));
194 mark_buffer_dirty_inode(bh, inode);
195 }
196 }
197
198 udf_release_data(bh);
199 extoffset = sizeof(struct allocExtDesc);
200 bloc = eloc;
201 bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, bloc, 0));
202 if (elen)
203 lelen = (elen + inode->i_sb->s_blocksize - 1) >>
204 inode->i_sb->s_blocksize_bits;
205 else
206 lelen = 1;
207 }
208 else
209 {
210 extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0);
211 extoffset += adsize;
212 }
213 }
214
215 if (lelen)
216 {
217 if (!bh)
218 BUG();
219 else
220 memset(bh->b_data, 0x00, sizeof(struct allocExtDesc));
221 udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
222 }
223 else
224 {
225 if (!bh)
226 {
227 UDF_I_LENALLOC(inode) = lenalloc;
228 mark_inode_dirty(inode);
229 }
230 else
231 {
232 struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data);
233 aed->lengthAllocDescs = cpu_to_le32(lenalloc);
234 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
235 udf_update_tag(bh->b_data, lenalloc +
236 sizeof(struct allocExtDesc));
237 else
238 udf_update_tag(bh->b_data, sizeof(struct allocExtDesc));
239 mark_buffer_dirty_inode(bh, inode);
240 }
241 }
242 }
243 else if (inode->i_size)
244 {
245 if (offset)
246 {
247 extoffset -= adsize;
248 etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1);
249 if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
250 {
251 extoffset -= adsize;
252 elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset);
253 udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0);
254 }
255 else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
256 {
257 kernel_lb_addr neloc = { 0, 0 };
258 extoffset -= adsize;
259 nelen = EXT_NOT_RECORDED_NOT_ALLOCATED |
260 ((elen + offset + inode->i_sb->s_blocksize - 1) &
261 ~(inode->i_sb->s_blocksize - 1));
262 udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
263 udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1);
264 }
265 else
266 {
267 if (elen & (inode->i_sb->s_blocksize - 1))
268 {
269 extoffset -= adsize;
270 elen = EXT_RECORDED_ALLOCATED |
271 ((elen + inode->i_sb->s_blocksize - 1) &
272 ~(inode->i_sb->s_blocksize - 1));
273 udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1);
274 }
275 memset(&eloc, 0x00, sizeof(kernel_lb_addr));
276 elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
277 udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
278 }
279 }
280 }
281 UDF_I_LENEXTENTS(inode) = inode->i_size;
282
283 udf_release_data(bh);
284}
diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h
new file mode 100644
index 000000000000..d7dbe6f3ba0c
--- /dev/null
+++ b/fs/udf/udf_i.h
@@ -0,0 +1,26 @@
1#ifndef __LINUX_UDF_I_H
2#define __LINUX_UDF_I_H
3
4#include <linux/udf_fs_i.h>
5static inline struct udf_inode_info *UDF_I(struct inode *inode)
6{
7 return list_entry(inode, struct udf_inode_info, vfs_inode);
8}
9
10#define UDF_I_LOCATION(X) ( UDF_I(X)->i_location )
11#define UDF_I_LENEATTR(X) ( UDF_I(X)->i_lenEAttr )
12#define UDF_I_LENALLOC(X) ( UDF_I(X)->i_lenAlloc )
13#define UDF_I_LENEXTENTS(X) ( UDF_I(X)->i_lenExtents )
14#define UDF_I_UNIQUE(X) ( UDF_I(X)->i_unique )
15#define UDF_I_ALLOCTYPE(X) ( UDF_I(X)->i_alloc_type )
16#define UDF_I_EFE(X) ( UDF_I(X)->i_efe )
17#define UDF_I_USE(X) ( UDF_I(X)->i_use )
18#define UDF_I_STRAT4096(X) ( UDF_I(X)->i_strat4096 )
19#define UDF_I_NEXT_ALLOC_BLOCK(X) ( UDF_I(X)->i_next_alloc_block )
20#define UDF_I_NEXT_ALLOC_GOAL(X) ( UDF_I(X)->i_next_alloc_goal )
21#define UDF_I_CRTIME(X) ( UDF_I(X)->i_crtime )
22#define UDF_I_SAD(X) ( UDF_I(X)->i_ext.i_sad )
23#define UDF_I_LAD(X) ( UDF_I(X)->i_ext.i_lad )
24#define UDF_I_DATA(X) ( UDF_I(X)->i_ext.i_data )
25
26#endif /* !defined(_LINUX_UDF_I_H) */
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
new file mode 100644
index 000000000000..0e54922daa09
--- /dev/null
+++ b/fs/udf/udf_sb.h
@@ -0,0 +1,139 @@
1#ifndef __LINUX_UDF_SB_H
2#define __LINUX_UDF_SB_H
3
4/* Since UDF 2.01 is ISO 13346 based... */
5#define UDF_SUPER_MAGIC 0x15013346
6
7#define UDF_MAX_READ_VERSION 0x0201
8#define UDF_MAX_WRITE_VERSION 0x0201
9
10#define UDF_FLAG_USE_EXTENDED_FE 0
11#define UDF_VERS_USE_EXTENDED_FE 0x0200
12#define UDF_FLAG_USE_STREAMS 1
13#define UDF_VERS_USE_STREAMS 0x0200
14#define UDF_FLAG_USE_SHORT_AD 2
15#define UDF_FLAG_USE_AD_IN_ICB 3
16#define UDF_FLAG_USE_FILE_CTIME_EA 4
17#define UDF_FLAG_STRICT 5
18#define UDF_FLAG_UNDELETE 6
19#define UDF_FLAG_UNHIDE 7
20#define UDF_FLAG_VARCONV 8
21#define UDF_FLAG_NLS_MAP 9
22#define UDF_FLAG_UTF8 10
23
24#define UDF_PART_FLAG_UNALLOC_BITMAP 0x0001
25#define UDF_PART_FLAG_UNALLOC_TABLE 0x0002
26#define UDF_PART_FLAG_FREED_BITMAP 0x0004
27#define UDF_PART_FLAG_FREED_TABLE 0x0008
28#define UDF_PART_FLAG_READ_ONLY 0x0010
29#define UDF_PART_FLAG_WRITE_ONCE 0x0020
30#define UDF_PART_FLAG_REWRITABLE 0x0040
31#define UDF_PART_FLAG_OVERWRITABLE 0x0080
32
33static inline struct udf_sb_info *UDF_SB(struct super_block *sb)
34{
35 return sb->s_fs_info;
36}
37
38#define UDF_SB_FREE(X)\
39{\
40 if (UDF_SB(X))\
41 {\
42 if (UDF_SB_PARTMAPS(X))\
43 kfree(UDF_SB_PARTMAPS(X));\
44 UDF_SB_PARTMAPS(X) = NULL;\
45 }\
46}
47
48#define UDF_SB_ALLOC_PARTMAPS(X,Y)\
49{\
50 UDF_SB_PARTMAPS(X) = kmalloc(sizeof(struct udf_part_map) * Y, GFP_KERNEL);\
51 if (UDF_SB_PARTMAPS(X) != NULL)\
52 {\
53 UDF_SB_NUMPARTS(X) = Y;\
54 memset(UDF_SB_PARTMAPS(X), 0x00, sizeof(struct udf_part_map) * Y);\
55 }\
56 else\
57 {\
58 UDF_SB_NUMPARTS(X) = 0;\
59 udf_error(X, __FUNCTION__, "Unable to allocate space for %d partition maps", Y);\
60 }\
61}
62
63#define UDF_SB_ALLOC_BITMAP(X,Y,Z)\
64{\
65 int nr_groups = ((UDF_SB_PARTLEN((X),(Y)) + (sizeof(struct spaceBitmapDesc) << 3) +\
66 ((X)->s_blocksize * 8) - 1) / ((X)->s_blocksize * 8));\
67 int size = sizeof(struct udf_bitmap) + (sizeof(struct buffer_head *) * nr_groups);\
68 if (size <= PAGE_SIZE)\
69 UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap = kmalloc(size, GFP_KERNEL);\
70 else\
71 UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap = vmalloc(size);\
72 if (UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap != NULL)\
73 {\
74 memset(UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap, 0x00, size);\
75 UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap->s_block_bitmap =\
76 (struct buffer_head **)(UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap + 1);\
77 UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap->s_nr_groups = nr_groups;\
78 }\
79 else\
80 {\
81 udf_error(X, __FUNCTION__, "Unable to allocate space for bitmap and %d buffer_head pointers", nr_groups);\
82 }\
83}
84
85#define UDF_SB_FREE_BITMAP(X,Y,Z)\
86{\
87 int i;\
88 int nr_groups = UDF_SB_BITMAP_NR_GROUPS(X,Y,Z);\
89 int size = sizeof(struct udf_bitmap) + (sizeof(struct buffer_head *) * nr_groups);\
90 for (i=0; i<nr_groups; i++)\
91 {\
92 if (UDF_SB_BITMAP(X,Y,Z,i))\
93 udf_release_data(UDF_SB_BITMAP(X,Y,Z,i));\
94 }\
95 if (size <= PAGE_SIZE)\
96 kfree(UDF_SB_PARTMAPS(X)[Y].Z.s_bitmap);\
97 else\
98 vfree(UDF_SB_PARTMAPS(X)[Y].Z.s_bitmap);\
99}
100
101#define UDF_QUERY_FLAG(X,Y) ( UDF_SB(X)->s_flags & ( 1 << (Y) ) )
102#define UDF_SET_FLAG(X,Y) ( UDF_SB(X)->s_flags |= ( 1 << (Y) ) )
103#define UDF_CLEAR_FLAG(X,Y) ( UDF_SB(X)->s_flags &= ~( 1 << (Y) ) )
104
105#define UDF_UPDATE_UDFREV(X,Y) ( ((Y) > UDF_SB_UDFREV(X)) ? UDF_SB_UDFREV(X) = (Y) : UDF_SB_UDFREV(X) )
106
107#define UDF_SB_PARTMAPS(X) ( UDF_SB(X)->s_partmaps )
108#define UDF_SB_PARTTYPE(X,Y) ( UDF_SB_PARTMAPS(X)[(Y)].s_partition_type )
109#define UDF_SB_PARTROOT(X,Y) ( UDF_SB_PARTMAPS(X)[(Y)].s_partition_root )
110#define UDF_SB_PARTLEN(X,Y) ( UDF_SB_PARTMAPS(X)[(Y)].s_partition_len )
111#define UDF_SB_PARTVSN(X,Y) ( UDF_SB_PARTMAPS(X)[(Y)].s_volumeseqnum )
112#define UDF_SB_PARTNUM(X,Y) ( UDF_SB_PARTMAPS(X)[(Y)].s_partition_num )
113#define UDF_SB_TYPESPAR(X,Y) ( UDF_SB_PARTMAPS(X)[(Y)].s_type_specific.s_sparing )
114#define UDF_SB_TYPEVIRT(X,Y) ( UDF_SB_PARTMAPS(X)[(Y)].s_type_specific.s_virtual )
115#define UDF_SB_PARTFUNC(X,Y) ( UDF_SB_PARTMAPS(X)[(Y)].s_partition_func )
116#define UDF_SB_PARTFLAGS(X,Y) ( UDF_SB_PARTMAPS(X)[(Y)].s_partition_flags )
117#define UDF_SB_BITMAP(X,Y,Z,I) ( UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap->s_block_bitmap[I] )
118#define UDF_SB_BITMAP_NR_GROUPS(X,Y,Z) ( UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap->s_nr_groups )
119
120#define UDF_SB_VOLIDENT(X) ( UDF_SB(X)->s_volident )
121#define UDF_SB_NUMPARTS(X) ( UDF_SB(X)->s_partitions )
122#define UDF_SB_PARTITION(X) ( UDF_SB(X)->s_partition )
123#define UDF_SB_SESSION(X) ( UDF_SB(X)->s_session )
124#define UDF_SB_ANCHOR(X) ( UDF_SB(X)->s_anchor )
125#define UDF_SB_LASTBLOCK(X) ( UDF_SB(X)->s_lastblock )
126#define UDF_SB_LVIDBH(X) ( UDF_SB(X)->s_lvidbh )
127#define UDF_SB_LVID(X) ( (struct logicalVolIntegrityDesc *)UDF_SB_LVIDBH(X)->b_data )
128#define UDF_SB_LVIDIU(X) ( (struct logicalVolIntegrityDescImpUse *)&(UDF_SB_LVID(X)->impUse[le32_to_cpu(UDF_SB_LVID(X)->numOfPartitions) * 2 * sizeof(uint32_t)/sizeof(uint8_t)]) )
129
130#define UDF_SB_UMASK(X) ( UDF_SB(X)->s_umask )
131#define UDF_SB_GID(X) ( UDF_SB(X)->s_gid )
132#define UDF_SB_UID(X) ( UDF_SB(X)->s_uid )
133#define UDF_SB_RECORDTIME(X) ( UDF_SB(X)->s_recordtime )
134#define UDF_SB_SERIALNUM(X) ( UDF_SB(X)->s_serialnum )
135#define UDF_SB_UDFREV(X) ( UDF_SB(X)->s_udfrev )
136#define UDF_SB_FLAGS(X) ( UDF_SB(X)->s_flags )
137#define UDF_SB_VAT(X) ( UDF_SB(X)->s_vat )
138
139#endif /* __LINUX_UDF_SB_H */
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
new file mode 100644
index 000000000000..1d5800e0cbe7
--- /dev/null
+++ b/fs/udf/udfdecl.h
@@ -0,0 +1,167 @@
1#ifndef __UDF_DECL_H
2#define __UDF_DECL_H
3
4#include <linux/udf_fs.h>
5#include "ecma_167.h"
6#include "osta_udf.h"
7
8#include <linux/fs.h>
9#include <linux/config.h>
10#include <linux/types.h>
11#include <linux/udf_fs_i.h>
12#include <linux/udf_fs_sb.h>
13#include <linux/buffer_head.h>
14
15#include "udfend.h"
16
17#define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) )
18#define udf_variable_to_fixed(x) ( ( ( (x) / 39 ) << 5 ) + ( (x) % 39 ) )
19
20#define UDF_EXTENT_LENGTH_MASK 0x3FFFFFFF
21#define UDF_EXTENT_FLAG_MASK 0xC0000000
22
23#define UDF_NAME_PAD 4
24#define UDF_NAME_LEN 256
25#define UDF_PATH_LEN 1023
26
27#define udf_file_entry_alloc_offset(inode)\
28 (UDF_I_USE(inode) ?\
29 sizeof(struct unallocSpaceEntry) :\
30 ((UDF_I_EFE(inode) ?\
31 sizeof(struct extendedFileEntry) :\
32 sizeof(struct fileEntry)) + UDF_I_LENEATTR(inode)))
33
34#define udf_ext0_offset(inode)\
35 (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB ?\
36 udf_file_entry_alloc_offset(inode) : 0)
37
38#define udf_get_lb_pblock(sb,loc,offset) udf_get_pblock((sb), (loc).logicalBlockNum, (loc).partitionReferenceNum, (offset))
39
40struct dentry;
41struct inode;
42struct task_struct;
43struct buffer_head;
44struct super_block;
45
46extern struct inode_operations udf_dir_inode_operations;
47extern struct file_operations udf_dir_operations;
48extern struct inode_operations udf_file_inode_operations;
49extern struct file_operations udf_file_operations;
50extern struct address_space_operations udf_aops;
51extern struct address_space_operations udf_adinicb_aops;
52extern struct address_space_operations udf_symlink_aops;
53
54struct udf_fileident_bh
55{
56 struct buffer_head *sbh;
57 struct buffer_head *ebh;
58 int soffset;
59 int eoffset;
60};
61
62struct udf_vds_record
63{
64 uint32_t block;
65 uint32_t volDescSeqNum;
66};
67
68struct generic_desc
69{
70 tag descTag;
71 __le32 volDescSeqNum;
72};
73
74struct ustr
75{
76 uint8_t u_cmpID;
77 uint8_t u_name[UDF_NAME_LEN-2];
78 uint8_t u_len;
79};
80
81/* super.c */
82extern void udf_error(struct super_block *, const char *, const char *, ...);
83extern void udf_warning(struct super_block *, const char *, const char *, ...);
84
85/* namei.c */
86extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, struct fileIdentDesc *, struct udf_fileident_bh *, uint8_t *, uint8_t *);
87
88/* file.c */
89extern int udf_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
90
91/* inode.c */
92extern struct inode *udf_iget(struct super_block *, kernel_lb_addr);
93extern int udf_sync_inode(struct inode *);
94extern void udf_expand_file_adinicb(struct inode *, int, int *);
95extern struct buffer_head * udf_expand_dir_adinicb(struct inode *, int *, int *);
96extern struct buffer_head * udf_bread(struct inode *, int, int, int *);
97extern void udf_truncate(struct inode *);
98extern void udf_read_inode(struct inode *);
99extern void udf_delete_inode(struct inode *);
100extern void udf_clear_inode(struct inode *);
101extern int udf_write_inode(struct inode *, int);
102extern long udf_block_map(struct inode *, long);
103extern int8_t inode_bmap(struct inode *, int, kernel_lb_addr *, uint32_t *, kernel_lb_addr *, uint32_t *, uint32_t *, struct buffer_head **);
104extern int8_t udf_add_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr, uint32_t, struct buffer_head **, int);
105extern int8_t udf_write_aext(struct inode *, kernel_lb_addr, int *, kernel_lb_addr, uint32_t, struct buffer_head *, int);
106extern int8_t udf_delete_aext(struct inode *, kernel_lb_addr, int, kernel_lb_addr, uint32_t, struct buffer_head *);
107extern int8_t udf_next_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr *, uint32_t *, struct buffer_head **, int);
108extern int8_t udf_current_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr *, uint32_t *, struct buffer_head **, int);
109
110/* misc.c */
111extern struct buffer_head *udf_tgetblk(struct super_block *, int);
112extern struct buffer_head *udf_tread(struct super_block *, int);
113extern struct genericFormat *udf_add_extendedattr(struct inode *, uint32_t, uint32_t, uint8_t);
114extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t, uint8_t);
115extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t, uint32_t, uint16_t *);
116extern struct buffer_head *udf_read_ptagged(struct super_block *, kernel_lb_addr, uint32_t, uint16_t *);
117extern void udf_release_data(struct buffer_head *);
118extern void udf_update_tag(char *, int);
119extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int);
120
121/* lowlevel.c */
122extern unsigned int udf_get_last_session(struct super_block *);
123extern unsigned long udf_get_last_block(struct super_block *);
124
125/* partition.c */
126extern uint32_t udf_get_pblock(struct super_block *, uint32_t, uint16_t, uint32_t);
127extern uint32_t udf_get_pblock_virt15(struct super_block *, uint32_t, uint16_t, uint32_t);
128extern uint32_t udf_get_pblock_virt20(struct super_block *, uint32_t, uint16_t, uint32_t);
129extern uint32_t udf_get_pblock_spar15(struct super_block *, uint32_t, uint16_t, uint32_t);
130extern int udf_relocate_blocks(struct super_block *, long, long *);
131
132/* unicode.c */
133extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int);
134extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *, int);
135extern int udf_build_ustr(struct ustr *, dstring *, int);
136extern int udf_CS0toUTF8(struct ustr *, struct ustr *);
137
138/* ialloc.c */
139extern void udf_free_inode(struct inode *);
140extern struct inode * udf_new_inode (struct inode *, int, int *);
141
142/* truncate.c */
143extern void udf_discard_prealloc(struct inode *);
144extern void udf_truncate_extents(struct inode *);
145
146/* balloc.c */
147extern void udf_free_blocks(struct super_block *, struct inode *, kernel_lb_addr, uint32_t, uint32_t);
148extern int udf_prealloc_blocks(struct super_block *, struct inode *, uint16_t, uint32_t, uint32_t);
149extern int udf_new_block(struct super_block *, struct inode *, uint16_t, uint32_t, int *);
150
151/* fsync.c */
152extern int udf_fsync_file(struct file *, struct dentry *, int);
153
154/* directory.c */
155extern struct fileIdentDesc * udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct fileIdentDesc *, kernel_lb_addr *, uint32_t *, kernel_lb_addr *, uint32_t *, uint32_t *, struct buffer_head **);
156extern struct fileIdentDesc * udf_get_fileident(void * buffer, int bufsize, int * offset);
157extern long_ad * udf_get_filelongad(uint8_t *, int, int *, int);
158extern short_ad * udf_get_fileshortad(uint8_t *, int, int *, int);
159
160/* crc.c */
161extern uint16_t udf_crc(uint8_t *, uint32_t, uint16_t);
162
163/* udftime.c */
164extern time_t *udf_stamp_to_time(time_t *, long *, kernel_timestamp);
165extern kernel_timestamp *udf_time_to_stamp(kernel_timestamp *, struct timespec);
166
167#endif /* __UDF_DECL_H */
diff --git a/fs/udf/udfend.h b/fs/udf/udfend.h
new file mode 100644
index 000000000000..17d378879561
--- /dev/null
+++ b/fs/udf/udfend.h
@@ -0,0 +1,81 @@
1#ifndef __UDF_ENDIAN_H
2#define __UDF_ENDIAN_H
3
4#include <asm/byteorder.h>
5#include <linux/string.h>
6
7static inline kernel_lb_addr lelb_to_cpu(lb_addr in)
8{
9 kernel_lb_addr out;
10 out.logicalBlockNum = le32_to_cpu(in.logicalBlockNum);
11 out.partitionReferenceNum = le16_to_cpu(in.partitionReferenceNum);
12 return out;
13}
14
15static inline lb_addr cpu_to_lelb(kernel_lb_addr in)
16{
17 lb_addr out;
18 out.logicalBlockNum = cpu_to_le32(in.logicalBlockNum);
19 out.partitionReferenceNum = cpu_to_le16(in.partitionReferenceNum);
20 return out;
21}
22
23static inline kernel_timestamp lets_to_cpu(timestamp in)
24{
25 kernel_timestamp out;
26 memcpy(&out, &in, sizeof(timestamp));
27 out.typeAndTimezone = le16_to_cpu(in.typeAndTimezone);
28 out.year = le16_to_cpu(in.year);
29 return out;
30}
31
32static inline short_ad lesa_to_cpu(short_ad in)
33{
34 short_ad out;
35 out.extLength = le32_to_cpu(in.extLength);
36 out.extPosition = le32_to_cpu(in.extPosition);
37 return out;
38}
39
40static inline short_ad cpu_to_lesa(short_ad in)
41{
42 short_ad out;
43 out.extLength = cpu_to_le32(in.extLength);
44 out.extPosition = cpu_to_le32(in.extPosition);
45 return out;
46}
47
48static inline kernel_long_ad lela_to_cpu(long_ad in)
49{
50 kernel_long_ad out;
51 out.extLength = le32_to_cpu(in.extLength);
52 out.extLocation = lelb_to_cpu(in.extLocation);
53 return out;
54}
55
56static inline long_ad cpu_to_lela(kernel_long_ad in)
57{
58 long_ad out;
59 out.extLength = cpu_to_le32(in.extLength);
60 out.extLocation = cpu_to_lelb(in.extLocation);
61 return out;
62}
63
64static inline kernel_extent_ad leea_to_cpu(extent_ad in)
65{
66 kernel_extent_ad out;
67 out.extLength = le32_to_cpu(in.extLength);
68 out.extLocation = le32_to_cpu(in.extLocation);
69 return out;
70}
71
72static inline timestamp cpu_to_lets(kernel_timestamp in)
73{
74 timestamp out;
75 memcpy(&out, &in, sizeof(timestamp));
76 out.typeAndTimezone = cpu_to_le16(in.typeAndTimezone);
77 out.year = cpu_to_le16(in.year);
78 return out;
79}
80
81#endif /* __UDF_ENDIAN_H */
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c
new file mode 100644
index 000000000000..c2634bda6b50
--- /dev/null
+++ b/fs/udf/udftime.c
@@ -0,0 +1,174 @@
1/* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Paul Eggert (eggert@twinsun.com).
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
19
20/*
21 * dgb 10/02/98: ripped this from glibc source to help convert timestamps to unix time
22 * 10/04/98: added new table-based lookup after seeing how ugly the gnu code is
23 * blf 09/27/99: ripped out all the old code and inserted new table from
24 * John Brockmeyer (without leap second corrections)
25 * rewrote udf_stamp_to_time and fixed timezone accounting in
26 udf_time_to_stamp.
27 */
28
29/*
30 * We don't take into account leap seconds. This may be correct or incorrect.
31 * For more NIST information (especially dealing with leap seconds), see:
32 * http://www.boulder.nist.gov/timefreq/pubs/bulletin/leapsecond.htm
33 */
34
35#include <linux/types.h>
36#include <linux/kernel.h>
37#include "udfdecl.h"
38
39#define EPOCH_YEAR 1970
40
41#ifndef __isleap
42/* Nonzero if YEAR is a leap year (every 4 years,
43 except every 100th isn't, and every 400th is). */
44#define __isleap(year) \
45 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
46#endif
47
48/* How many days come before each month (0-12). */
49const unsigned short int __mon_yday[2][13] =
50{
51 /* Normal years. */
52 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
53 /* Leap years. */
54 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
55};
56
57#define MAX_YEAR_SECONDS 69
58#define SPD 0x15180 /*3600*24*/
59#define SPY(y,l,s) (SPD * (365*y+l)+s)
60
61static time_t year_seconds[MAX_YEAR_SECONDS]= {
62/*1970*/ SPY( 0, 0,0), SPY( 1, 0,0), SPY( 2, 0,0), SPY( 3, 1,0),
63/*1974*/ SPY( 4, 1,0), SPY( 5, 1,0), SPY( 6, 1,0), SPY( 7, 2,0),
64/*1978*/ SPY( 8, 2,0), SPY( 9, 2,0), SPY(10, 2,0), SPY(11, 3,0),
65/*1982*/ SPY(12, 3,0), SPY(13, 3,0), SPY(14, 3,0), SPY(15, 4,0),
66/*1986*/ SPY(16, 4,0), SPY(17, 4,0), SPY(18, 4,0), SPY(19, 5,0),
67/*1990*/ SPY(20, 5,0), SPY(21, 5,0), SPY(22, 5,0), SPY(23, 6,0),
68/*1994*/ SPY(24, 6,0), SPY(25, 6,0), SPY(26, 6,0), SPY(27, 7,0),
69/*1998*/ SPY(28, 7,0), SPY(29, 7,0), SPY(30, 7,0), SPY(31, 8,0),
70/*2002*/ SPY(32, 8,0), SPY(33, 8,0), SPY(34, 8,0), SPY(35, 9,0),
71/*2006*/ SPY(36, 9,0), SPY(37, 9,0), SPY(38, 9,0), SPY(39,10,0),
72/*2010*/ SPY(40,10,0), SPY(41,10,0), SPY(42,10,0), SPY(43,11,0),
73/*2014*/ SPY(44,11,0), SPY(45,11,0), SPY(46,11,0), SPY(47,12,0),
74/*2018*/ SPY(48,12,0), SPY(49,12,0), SPY(50,12,0), SPY(51,13,0),
75/*2022*/ SPY(52,13,0), SPY(53,13,0), SPY(54,13,0), SPY(55,14,0),
76/*2026*/ SPY(56,14,0), SPY(57,14,0), SPY(58,14,0), SPY(59,15,0),
77/*2030*/ SPY(60,15,0), SPY(61,15,0), SPY(62,15,0), SPY(63,16,0),
78/*2034*/ SPY(64,16,0), SPY(65,16,0), SPY(66,16,0), SPY(67,17,0),
79/*2038*/ SPY(68,17,0)
80};
81
82extern struct timezone sys_tz;
83
84#define SECS_PER_HOUR (60 * 60)
85#define SECS_PER_DAY (SECS_PER_HOUR * 24)
86
87time_t *
88udf_stamp_to_time(time_t *dest, long *dest_usec, kernel_timestamp src)
89{
90 int yday;
91 uint8_t type = src.typeAndTimezone >> 12;
92 int16_t offset;
93
94 if (type == 1)
95 {
96 offset = src.typeAndTimezone << 4;
97 /* sign extent offset */
98 offset = (offset >> 4);
99 if (offset == -2047) /* unspecified offset */
100 offset = 0;
101 }
102 else
103 offset = 0;
104
105 if ((src.year < EPOCH_YEAR) ||
106 (src.year > EPOCH_YEAR+MAX_YEAR_SECONDS))
107 {
108 *dest = -1;
109 *dest_usec = -1;
110 return NULL;
111 }
112 *dest = year_seconds[src.year - EPOCH_YEAR];
113 *dest -= offset * 60;
114
115 yday = ((__mon_yday[__isleap (src.year)]
116 [src.month-1]) + (src.day-1));
117 *dest += ( ( (yday* 24) + src.hour ) * 60 + src.minute ) * 60 + src.second;
118 *dest_usec = src.centiseconds * 10000 + src.hundredsOfMicroseconds * 100 + src.microseconds;
119 return dest;
120}
121
122
123kernel_timestamp *
124udf_time_to_stamp(kernel_timestamp *dest, struct timespec ts)
125{
126 long int days, rem, y;
127 const unsigned short int *ip;
128 int16_t offset;
129
130 offset = -sys_tz.tz_minuteswest;
131
132 if (!dest)
133 return NULL;
134
135 dest->typeAndTimezone = 0x1000 | (offset & 0x0FFF);
136
137 ts.tv_sec += offset * 60;
138 days = ts.tv_sec / SECS_PER_DAY;
139 rem = ts.tv_sec % SECS_PER_DAY;
140 dest->hour = rem / SECS_PER_HOUR;
141 rem %= SECS_PER_HOUR;
142 dest->minute = rem / 60;
143 dest->second = rem % 60;
144 y = 1970;
145
146#define DIV(a,b) ((a) / (b) - ((a) % (b) < 0))
147#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
148
149 while (days < 0 || days >= (__isleap(y) ? 366 : 365))
150 {
151 long int yg = y + days / 365 - (days % 365 < 0);
152
153 /* Adjust DAYS and Y to match the guessed year. */
154 days -= ((yg - y) * 365
155 + LEAPS_THRU_END_OF (yg - 1)
156 - LEAPS_THRU_END_OF (y - 1));
157 y = yg;
158 }
159 dest->year = y;
160 ip = __mon_yday[__isleap(y)];
161 for (y = 11; days < (long int) ip[y]; --y)
162 continue;
163 days -= ip[y];
164 dest->month = y + 1;
165 dest->day = days + 1;
166
167 dest->centiseconds = ts.tv_nsec / 10000000;
168 dest->hundredsOfMicroseconds = (ts.tv_nsec / 1000 - dest->centiseconds * 10000) / 100;
169 dest->microseconds = (ts.tv_nsec / 1000 - dest->centiseconds * 10000 -
170 dest->hundredsOfMicroseconds * 100);
171 return dest;
172}
173
174/* EOF */
diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c
new file mode 100644
index 000000000000..5a80efd8debc
--- /dev/null
+++ b/fs/udf/unicode.c
@@ -0,0 +1,516 @@
1/*
2 * unicode.c
3 *
4 * PURPOSE
5 * Routines for converting between UTF-8 and OSTA Compressed Unicode.
6 * Also handles filename mangling
7 *
8 * DESCRIPTION
9 * OSTA Compressed Unicode is explained in the OSTA UDF specification.
10 * http://www.osta.org/
11 * UTF-8 is explained in the IETF RFC XXXX.
12 * ftp://ftp.internic.net/rfc/rfcxxxx.txt
13 *
14 * CONTACTS
15 * E-mail regarding any portion of the Linux UDF file system should be
16 * directed to the development team's mailing list (run by majordomo):
17 * linux_udf@hpesjro.fc.hp.com
18 *
19 * COPYRIGHT
20 * This file is distributed under the terms of the GNU General Public
21 * License (GPL). Copies of the GPL can be obtained from:
22 * ftp://prep.ai.mit.edu/pub/gnu/GPL
23 * Each contributing author retains all rights to their own work.
24 */
25
26#include "udfdecl.h"
27
28#include <linux/kernel.h>
29#include <linux/string.h> /* for memset */
30#include <linux/nls.h>
31#include <linux/udf_fs.h>
32
33#include "udf_sb.h"
34
35static int udf_translate_to_linux(uint8_t *, uint8_t *, int, uint8_t *, int);
36
37static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen)
38{
39 if ( (!dest) || (!src) || (!strlen) || (strlen > UDF_NAME_LEN-2) )
40 return 0;
41 memset(dest, 0, sizeof(struct ustr));
42 memcpy(dest->u_name, src, strlen);
43 dest->u_cmpID = 0x08;
44 dest->u_len = strlen;
45 return strlen;
46}
47
48/*
49 * udf_build_ustr
50 */
51int udf_build_ustr(struct ustr *dest, dstring *ptr, int size)
52{
53 int usesize;
54
55 if ( (!dest) || (!ptr) || (!size) )
56 return -1;
57
58 memset(dest, 0, sizeof(struct ustr));
59 usesize= (size > UDF_NAME_LEN) ? UDF_NAME_LEN : size;
60 dest->u_cmpID=ptr[0];
61 dest->u_len=ptr[size-1];
62 memcpy(dest->u_name, ptr+1, usesize-1);
63 return 0;
64}
65
66/*
67 * udf_build_ustr_exact
68 */
69static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize)
70{
71 if ( (!dest) || (!ptr) || (!exactsize) )
72 return -1;
73
74 memset(dest, 0, sizeof(struct ustr));
75 dest->u_cmpID=ptr[0];
76 dest->u_len=exactsize-1;
77 memcpy(dest->u_name, ptr+1, exactsize-1);
78 return 0;
79}
80
81/*
82 * udf_ocu_to_utf8
83 *
84 * PURPOSE
85 * Convert OSTA Compressed Unicode to the UTF-8 equivalent.
86 *
87 * DESCRIPTION
88 * This routine is only called by udf_filldir().
89 *
90 * PRE-CONDITIONS
91 * utf Pointer to UTF-8 output buffer.
92 * ocu Pointer to OSTA Compressed Unicode input buffer
93 * of size UDF_NAME_LEN bytes.
94 * both of type "struct ustr *"
95 *
96 * POST-CONDITIONS
97 * <return> Zero on success.
98 *
99 * HISTORY
100 * November 12, 1997 - Andrew E. Mileski
101 * Written, tested, and released.
102 */
103int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i)
104{
105 uint8_t *ocu;
106 uint32_t c;
107 uint8_t cmp_id, ocu_len;
108 int i;
109
110 ocu = ocu_i->u_name;
111
112 ocu_len = ocu_i->u_len;
113 cmp_id = ocu_i->u_cmpID;
114 utf_o->u_len = 0;
115
116 if (ocu_len == 0)
117 {
118 memset(utf_o, 0, sizeof(struct ustr));
119 utf_o->u_cmpID = 0;
120 utf_o->u_len = 0;
121 return 0;
122 }
123
124 if ((cmp_id != 8) && (cmp_id != 16))
125 {
126 printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", cmp_id, ocu_i->u_name);
127 return 0;
128 }
129
130 for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN-3)) ;)
131 {
132
133 /* Expand OSTA compressed Unicode to Unicode */
134 c = ocu[i++];
135 if (cmp_id == 16)
136 c = (c << 8) | ocu[i++];
137
138 /* Compress Unicode to UTF-8 */
139 if (c < 0x80U)
140 utf_o->u_name[utf_o->u_len++] = (uint8_t)c;
141 else if (c < 0x800U)
142 {
143 utf_o->u_name[utf_o->u_len++] = (uint8_t)(0xc0 | (c >> 6));
144 utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | (c & 0x3f));
145 }
146 else
147 {
148 utf_o->u_name[utf_o->u_len++] = (uint8_t)(0xe0 | (c >> 12));
149 utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | ((c >> 6) & 0x3f));
150 utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | (c & 0x3f));
151 }
152 }
153 utf_o->u_cmpID=8;
154
155 return utf_o->u_len;
156}
157
158/*
159 *
160 * udf_utf8_to_ocu
161 *
162 * PURPOSE
163 * Convert UTF-8 to the OSTA Compressed Unicode equivalent.
164 *
165 * DESCRIPTION
166 * This routine is only called by udf_lookup().
167 *
168 * PRE-CONDITIONS
169 * ocu Pointer to OSTA Compressed Unicode output
170 * buffer of size UDF_NAME_LEN bytes.
171 * utf Pointer to UTF-8 input buffer.
172 * utf_len Length of UTF-8 input buffer in bytes.
173 *
174 * POST-CONDITIONS
175 * <return> Zero on success.
176 *
177 * HISTORY
178 * November 12, 1997 - Andrew E. Mileski
179 * Written, tested, and released.
180 */
181static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length)
182{
183 unsigned c, i, max_val, utf_char;
184 int utf_cnt, u_len;
185
186 memset(ocu, 0, sizeof(dstring) * length);
187 ocu[0] = 8;
188 max_val = 0xffU;
189
190try_again:
191 u_len = 0U;
192 utf_char = 0U;
193 utf_cnt = 0U;
194 for (i = 0U; i < utf->u_len; i++)
195 {
196 c = (uint8_t)utf->u_name[i];
197
198 /* Complete a multi-byte UTF-8 character */
199 if (utf_cnt)
200 {
201 utf_char = (utf_char << 6) | (c & 0x3fU);
202 if (--utf_cnt)
203 continue;
204 }
205 else
206 {
207 /* Check for a multi-byte UTF-8 character */
208 if (c & 0x80U)
209 {
210 /* Start a multi-byte UTF-8 character */
211 if ((c & 0xe0U) == 0xc0U)
212 {
213 utf_char = c & 0x1fU;
214 utf_cnt = 1;
215 }
216 else if ((c & 0xf0U) == 0xe0U)
217 {
218 utf_char = c & 0x0fU;
219 utf_cnt = 2;
220 }
221 else if ((c & 0xf8U) == 0xf0U)
222 {
223 utf_char = c & 0x07U;
224 utf_cnt = 3;
225 }
226 else if ((c & 0xfcU) == 0xf8U)
227 {
228 utf_char = c & 0x03U;
229 utf_cnt = 4;
230 }
231 else if ((c & 0xfeU) == 0xfcU)
232 {
233 utf_char = c & 0x01U;
234 utf_cnt = 5;
235 }
236 else
237 goto error_out;
238 continue;
239 } else
240 /* Single byte UTF-8 character (most common) */
241 utf_char = c;
242 }
243
244 /* Choose no compression if necessary */
245 if (utf_char > max_val)
246 {
247 if ( 0xffU == max_val )
248 {
249 max_val = 0xffffU;
250 ocu[0] = (uint8_t)0x10U;
251 goto try_again;
252 }
253 goto error_out;
254 }
255
256 if (max_val == 0xffffU)
257 {
258 ocu[++u_len] = (uint8_t)(utf_char >> 8);
259 }
260 ocu[++u_len] = (uint8_t)(utf_char & 0xffU);
261 }
262
263
264 if (utf_cnt)
265 {
266error_out:
267 ocu[++u_len] = '?';
268 printk(KERN_DEBUG "udf: bad UTF-8 character\n");
269 }
270
271 ocu[length - 1] = (uint8_t)u_len + 1;
272 return u_len + 1;
273}
274
275static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, struct ustr *ocu_i)
276{
277 uint8_t *ocu;
278 uint32_t c;
279 uint8_t cmp_id, ocu_len;
280 int i;
281
282 ocu = ocu_i->u_name;
283
284 ocu_len = ocu_i->u_len;
285 cmp_id = ocu_i->u_cmpID;
286 utf_o->u_len = 0;
287
288 if (ocu_len == 0)
289 {
290 memset(utf_o, 0, sizeof(struct ustr));
291 utf_o->u_cmpID = 0;
292 utf_o->u_len = 0;
293 return 0;
294 }
295
296 if ((cmp_id != 8) && (cmp_id != 16))
297 {
298 printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", cmp_id, ocu_i->u_name);
299 return 0;
300 }
301
302 for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN-3)) ;)
303 {
304 /* Expand OSTA compressed Unicode to Unicode */
305 c = ocu[i++];
306 if (cmp_id == 16)
307 c = (c << 8) | ocu[i++];
308
309 utf_o->u_len += nls->uni2char(c, &utf_o->u_name[utf_o->u_len],
310 UDF_NAME_LEN - utf_o->u_len);
311 }
312 utf_o->u_cmpID=8;
313
314 return utf_o->u_len;
315}
316
317static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, int length)
318{
319 unsigned len, i, max_val;
320 uint16_t uni_char;
321 int u_len;
322
323 memset(ocu, 0, sizeof(dstring) * length);
324 ocu[0] = 8;
325 max_val = 0xffU;
326
327try_again:
328 u_len = 0U;
329 for (i = 0U; i < uni->u_len; i++)
330 {
331 len = nls->char2uni(&uni->u_name[i], uni->u_len-i, &uni_char);
332 if (len <= 0)
333 continue;
334
335 if (uni_char > max_val)
336 {
337 max_val = 0xffffU;
338 ocu[0] = (uint8_t)0x10U;
339 goto try_again;
340 }
341
342 if (max_val == 0xffffU)
343 ocu[++u_len] = (uint8_t)(uni_char >> 8);
344 ocu[++u_len] = (uint8_t)(uni_char & 0xffU);
345 i += len - 1;
346 }
347
348 ocu[length - 1] = (uint8_t)u_len + 1;
349 return u_len + 1;
350}
351
352int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, int flen)
353{
354 struct ustr filename, unifilename;
355 int len;
356
357 if (udf_build_ustr_exact(&unifilename, sname, flen))
358 {
359 return 0;
360 }
361
362 if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8))
363 {
364 if (!udf_CS0toUTF8(&filename, &unifilename) )
365 {
366 udf_debug("Failed in udf_get_filename: sname = %s\n", sname);
367 return 0;
368 }
369 }
370 else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
371 {
372 if (!udf_CS0toNLS(UDF_SB(sb)->s_nls_map, &filename, &unifilename) )
373 {
374 udf_debug("Failed in udf_get_filename: sname = %s\n", sname);
375 return 0;
376 }
377 }
378 else
379 return 0;
380
381 if ((len = udf_translate_to_linux(dname, filename.u_name, filename.u_len,
382 unifilename.u_name, unifilename.u_len)))
383 {
384 return len;
385 }
386 return 0;
387}
388
389int udf_put_filename(struct super_block *sb, const uint8_t *sname, uint8_t *dname, int flen)
390{
391 struct ustr unifilename;
392 int namelen;
393
394 if ( !(udf_char_to_ustr(&unifilename, sname, flen)) )
395 {
396 return 0;
397 }
398
399 if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8))
400 {
401 if ( !(namelen = udf_UTF8toCS0(dname, &unifilename, UDF_NAME_LEN)) )
402 {
403 return 0;
404 }
405 }
406 else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
407 {
408 if ( !(namelen = udf_NLStoCS0(UDF_SB(sb)->s_nls_map, dname, &unifilename, UDF_NAME_LEN)) )
409 {
410 return 0;
411 }
412 }
413 else
414 return 0;
415
416 return namelen;
417}
418
419#define ILLEGAL_CHAR_MARK '_'
420#define EXT_MARK '.'
421#define CRC_MARK '#'
422#define EXT_SIZE 5
423
424static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, int udfLen, uint8_t *fidName, int fidNameLen)
425{
426 int index, newIndex = 0, needsCRC = 0;
427 int extIndex = 0, newExtIndex = 0, hasExt = 0;
428 unsigned short valueCRC;
429 uint8_t curr;
430 const uint8_t hexChar[] = "0123456789ABCDEF";
431
432 if (udfName[0] == '.' && (udfLen == 1 ||
433 (udfLen == 2 && udfName[1] == '.')))
434 {
435 needsCRC = 1;
436 newIndex = udfLen;
437 memcpy(newName, udfName, udfLen);
438 }
439 else
440 {
441 for (index = 0; index < udfLen; index++)
442 {
443 curr = udfName[index];
444 if (curr == '/' || curr == 0)
445 {
446 needsCRC = 1;
447 curr = ILLEGAL_CHAR_MARK;
448 while (index+1 < udfLen && (udfName[index+1] == '/' ||
449 udfName[index+1] == 0))
450 index++;
451 }
452 if (curr == EXT_MARK && (udfLen - index - 1) <= EXT_SIZE)
453 {
454 if (udfLen == index + 1)
455 hasExt = 0;
456 else
457 {
458 hasExt = 1;
459 extIndex = index;
460 newExtIndex = newIndex;
461 }
462 }
463 if (newIndex < 256)
464 newName[newIndex++] = curr;
465 else
466 needsCRC = 1;
467 }
468 }
469 if (needsCRC)
470 {
471 uint8_t ext[EXT_SIZE];
472 int localExtIndex = 0;
473
474 if (hasExt)
475 {
476 int maxFilenameLen;
477 for(index = 0; index<EXT_SIZE && extIndex + index +1 < udfLen;
478 index++ )
479 {
480 curr = udfName[extIndex + index + 1];
481
482 if (curr == '/' || curr == 0)
483 {
484 needsCRC = 1;
485 curr = ILLEGAL_CHAR_MARK;
486 while(extIndex + index + 2 < udfLen && (index + 1 < EXT_SIZE
487 && (udfName[extIndex + index + 2] == '/' ||
488 udfName[extIndex + index + 2] == 0)))
489 index++;
490 }
491 ext[localExtIndex++] = curr;
492 }
493 maxFilenameLen = 250 - localExtIndex;
494 if (newIndex > maxFilenameLen)
495 newIndex = maxFilenameLen;
496 else
497 newIndex = newExtIndex;
498 }
499 else if (newIndex > 250)
500 newIndex = 250;
501 newName[newIndex++] = CRC_MARK;
502 valueCRC = udf_crc(fidName, fidNameLen, 0);
503 newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12];
504 newName[newIndex++] = hexChar[(valueCRC & 0x0f00) >> 8];
505 newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4];
506 newName[newIndex++] = hexChar[(valueCRC & 0x000f)];
507
508 if (hasExt)
509 {
510 newName[newIndex++] = EXT_MARK;
511 for (index = 0;index < localExtIndex ;index++ )
512 newName[newIndex++] = ext[index];
513 }
514 }
515 return newIndex;
516}